From 5f56442a8f1c1b41371c7033e6dc50addab78ba5 Mon Sep 17 00:00:00 2001 From: Gary Sassano <10464497+garysassano@users.noreply.github.com> Date: Tue, 22 Aug 2023 17:20:48 +0200 Subject: [PATCH] fix(sdk): turn `indent` option of `json.stringify` into keyword argument (#3837) Closes #2246 *By submitting this pull request, I confirm that my contribution is made under the terms of the [Wing Cloud Contribution License](https://github.com/winglang/wing/blob/main/CONTRIBUTION_LICENSE.md)*. --- .../02-std/api-reference.md | 38 +++++- examples/tests/sdk_tests/std/json.w | 13 ++ examples/tests/valid/json_static.w | 2 +- libs/wingsdk/src/std/json.ts | 19 ++- .../sdk_tests/api/patch.w_compile_tf-aws.md | 6 +- .../sdk_tests/api/post.w_compile_tf-aws.md | 10 +- .../sdk_tests/api/put.w_compile_tf-aws.md | 6 +- .../bucket/add_object.w_compile_tf-aws.md | 4 +- .../bucket/try_get_json.w_compile_tf-aws.md | 4 +- .../sdk_tests/std/json.w_compile_tf-aws.md | 116 +++++++++++++++++- .../sdk_tests/std/json.w_test_sim.md | 7 +- .../website/website.w_compile_tf-aws.md | 2 +- .../test_corpus/valid/api.w_compile_tf-aws.md | 2 +- .../valid/api_path_vars.w_compile_tf-aws.md | 2 +- .../valid/doubler.w_compile_tf-aws.md | 2 +- .../valid/issue_2889.w_compile_tf-aws.md | 2 +- .../valid/json_static.w_compile_tf-aws.md | 6 +- .../website_with_api.w_compile_tf-aws.md | 10 +- 18 files changed, 208 insertions(+), 43 deletions(-) diff --git a/docs/docs/04-standard-library/02-std/api-reference.md b/docs/docs/04-standard-library/02-std/api-reference.md index 5ca1f9033e4..04f1df5ee88 100644 --- a/docs/docs/04-standard-library/02-std/api-reference.md +++ b/docs/docs/04-standard-library/02-std/api-reference.md @@ -940,13 +940,11 @@ to parse as Json. ##### `stringify` ```wing -Json.stringify(json: any, indent?: num); +Json.stringify(json: any, options?: JsonStringifyOptions); ``` Formats Json as string. -(JSON.stringify($args$)) - ###### `json`Required - *Type:* any @@ -955,9 +953,9 @@ to format as string. --- -###### `indent`Optional +###### `options`Optional -- *Type:* num +- *Type:* JsonStringifyOptions --- @@ -2285,4 +2283,34 @@ Year. --- +### JsonStringifyOptions + +Options for stringify() method. + +#### Initializer + +```wing +let JsonStringifyOptions = JsonStringifyOptions{ ... }; +``` + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| indent | num | Indentation spaces number. | + +--- + +##### `indent`Required + +```wing +indent: num; +``` + +- *Type:* num + +Indentation spaces number. + +--- + diff --git a/examples/tests/sdk_tests/std/json.w b/examples/tests/sdk_tests/std/json.w index 403b157ee38..22b4c99f6d0 100644 --- a/examples/tests/sdk_tests/std/json.w +++ b/examples/tests/sdk_tests/std/json.w @@ -54,3 +54,16 @@ try { assert(error == ""); } */ + +//----------------------------------------------------------------------------- +// stringify() + +test "stringify()" { + let obj = Json { a: 1, b: 2 }; + + let stringified = Json.stringify(obj); + let stringifiedIndent = Json.stringify(obj, indent: 2); + + assert(stringified == "{\"a\":1,\"b\":2}"); + assert(stringifiedIndent == "{\n \"a\": 1,\n \"b\": 2\n}"); +} \ No newline at end of file diff --git a/examples/tests/valid/json_static.w b/examples/tests/valid/json_static.w index 5a2b753a71a..305f49cde8d 100644 --- a/examples/tests/valid/json_static.w +++ b/examples/tests/valid/json_static.w @@ -40,7 +40,7 @@ let jj = Json {a: 123, b: {c : 456, d : 789}}; let ss = Json.stringify(jj); assert(ss == "{\"a\":123,\"b\":{\"c\":456,\"d\":789}}"); -let ss2 = Json.stringify(jj, 2); +let ss2 = Json.stringify(jj, indent: 2); assert(ss2 == "{\n \"a\": 123,\n \"b\": {\n \"c\": 456,\n \"d\": 789\n }\n}"); // From Json Methods diff --git a/libs/wingsdk/src/std/json.ts b/libs/wingsdk/src/std/json.ts index 74d869e64dc..27eed2aba79 100644 --- a/libs/wingsdk/src/std/json.ts +++ b/libs/wingsdk/src/std/json.ts @@ -1,5 +1,13 @@ import { Code, InflightClient } from "../core"; +/** + * Options for stringify() method. + */ +export interface JsonStringifyOptions { + /** Indentation spaces number */ + readonly indent: number; +} + /** * Immutable Json */ @@ -41,16 +49,17 @@ export class Json { /** * Formats Json as string * - * (JSON.stringify($args$)) - * - * @macro ((args) => { return JSON.stringify(args[0], null, args[1]) })([$args$]) + * @macro ((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([$args$]) * * @param json to format as string * @returns string representation of the Json */ - public static stringify(json: Json | MutJson, indent?: number): string { + public static stringify( + json: Json | MutJson, + options?: JsonStringifyOptions + ): string { json; - indent; + options; throw new Error("Macro"); } diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/patch.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/patch.w_compile_tf-aws.md index 93c27865474..47146f31b37 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/patch.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/patch.w_compile_tf-aws.md @@ -13,7 +13,7 @@ module.exports = function({ $_id, $body, $cloud_HttpMethod, $std_Json }) { {((cond) => {if (!cond) throw new Error("assertion failed: req.method == cloud.HttpMethod.PATCH")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(req.method,$cloud_HttpMethod.PATCH)))}; {((cond) => {if (!cond) throw new Error("assertion failed: req.vars?.get(\"id\") == _id")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })((req.vars)["id"],$_id)))}; {((cond) => {if (!cond) throw new Error("assertion failed: req.path == \"/path/\"+ _id")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(req.path,("/path/" + $_id))))}; - {((cond) => {if (!cond) throw new Error("assertion failed: req.body == Json.stringify(body)")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(req.body,((args) => { return JSON.stringify(args[0], null, args[1]) })([$body]))))}; + {((cond) => {if (!cond) throw new Error("assertion failed: req.body == Json.stringify(body)")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(req.body,((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([$body]))))}; {((cond) => {if (!cond) throw new Error("assertion failed: req.headers?.get(\"content-type\") == \"application/json\"")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })((req.headers)["content-type"],"application/json")))}; return ({"status": 200,"body": (req.vars)["id"]}); } @@ -34,8 +34,8 @@ module.exports = function({ $_id, $api_url, $body, $http_HttpMethod, $http_Util, } async handle() { const url = String.raw({ raw: ["", "/path/", ""] }, $api_url, $_id); - const response = (await $http_Util.patch(url,{ headers: ({"content-type": "application/json"}), body: ((args) => { return JSON.stringify(args[0], null, args[1]) })([$body]) })); - const fetchResponse = (await $http_Util.patch(url,{ method: $http_HttpMethod.PATCH, headers: ({"content-type": "application/json"}), body: ((args) => { return JSON.stringify(args[0], null, args[1]) })([$body]) })); + const response = (await $http_Util.patch(url,{ headers: ({"content-type": "application/json"}), body: ((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([$body]) })); + const fetchResponse = (await $http_Util.patch(url,{ method: $http_HttpMethod.PATCH, headers: ({"content-type": "application/json"}), body: ((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([$body]) })); {((cond) => {if (!cond) throw new Error("assertion failed: response.body == _id")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(response.body,$_id)))}; {((cond) => {if (!cond) throw new Error("assertion failed: response.status == 200")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(response.status,200)))}; {((cond) => {if (!cond) throw new Error("assertion failed: response.url == url")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(response.url,url)))}; diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/post.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/post.w_compile_tf-aws.md index 2c1287752e3..87a81be8597 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/post.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/post.w_compile_tf-aws.md @@ -12,7 +12,7 @@ module.exports = function({ $body, $cloud_HttpMethod, $std_Json }) { async handle(req) { {((cond) => {if (!cond) throw new Error("assertion failed: req.method == cloud.HttpMethod.POST")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(req.method,$cloud_HttpMethod.POST)))}; {((cond) => {if (!cond) throw new Error("assertion failed: req.path == \"/path\"")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(req.path,"/path")))}; - {((cond) => {if (!cond) throw new Error("assertion failed: req.body == Json.stringify(body)")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(req.body,((args) => { return JSON.stringify(args[0], null, args[1]) })([$body]))))}; + {((cond) => {if (!cond) throw new Error("assertion failed: req.body == Json.stringify(body)")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(req.body,((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([$body]))))}; {((cond) => {if (!cond) throw new Error("assertion failed: req.headers?.get(\"content-type\") == \"application/json\"")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })((req.headers)["content-type"],"application/json")))}; return ({"status": 200,"body": req.body}); } @@ -33,12 +33,12 @@ module.exports = function({ $api_url, $body, $http_HttpMethod, $http_Util, $std_ } async handle() { const url = ($api_url + "/path"); - const response = (await $http_Util.post(url,{ headers: ({"content-type": "application/json"}), body: ((args) => { return JSON.stringify(args[0], null, args[1]) })([$body]) })); - const fetchResponse = (await $http_Util.post(url,{ method: $http_HttpMethod.POST, headers: ({"content-type": "application/json"}), body: ((args) => { return JSON.stringify(args[0], null, args[1]) })([$body]) })); - {((cond) => {if (!cond) throw new Error("assertion failed: response.body == Json.stringify(body)")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(response.body,((args) => { return JSON.stringify(args[0], null, args[1]) })([$body]))))}; + const response = (await $http_Util.post(url,{ headers: ({"content-type": "application/json"}), body: ((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([$body]) })); + const fetchResponse = (await $http_Util.post(url,{ method: $http_HttpMethod.POST, headers: ({"content-type": "application/json"}), body: ((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([$body]) })); + {((cond) => {if (!cond) throw new Error("assertion failed: response.body == Json.stringify(body)")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(response.body,((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([$body]))))}; {((cond) => {if (!cond) throw new Error("assertion failed: response.status == 200")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(response.status,200)))}; {((cond) => {if (!cond) throw new Error("assertion failed: response.url == url")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(response.url,url)))}; - {((cond) => {if (!cond) throw new Error("assertion failed: fetchResponse.body == Json.stringify(body)")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(fetchResponse.body,((args) => { return JSON.stringify(args[0], null, args[1]) })([$body]))))}; + {((cond) => {if (!cond) throw new Error("assertion failed: fetchResponse.body == Json.stringify(body)")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(fetchResponse.body,((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([$body]))))}; {((cond) => {if (!cond) throw new Error("assertion failed: fetchResponse.status == 200")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(fetchResponse.status,200)))}; {((cond) => {if (!cond) throw new Error("assertion failed: fetchResponse.url == url")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(fetchResponse.url,url)))}; } diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/put.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/put.w_compile_tf-aws.md index bd7cf654bb0..66f674c076a 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/put.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/api/put.w_compile_tf-aws.md @@ -15,7 +15,7 @@ module.exports = function({ $_id, $body, $cloud_HttpMethod, $std_Json, $user }) {((cond) => {if (!cond) throw new Error("assertion failed: req.vars?.get(\"id\") == _id")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })((req.vars)["id"],$_id)))}; {((cond) => {if (!cond) throw new Error("assertion failed: req.vars?.get(\"user\") == user")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })((req.vars)["user"],$user)))}; {((cond) => {if (!cond) throw new Error("assertion failed: req.path == path")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(req.path,path)))}; - {((cond) => {if (!cond) throw new Error("assertion failed: req.body == Json.stringify(body)")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(req.body,((args) => { return JSON.stringify(args[0], null, args[1]) })([$body]))))}; + {((cond) => {if (!cond) throw new Error("assertion failed: req.body == Json.stringify(body)")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(req.body,((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([$body]))))}; {((cond) => {if (!cond) throw new Error("assertion failed: req.headers?.get(\"content-type\") == \"application/json\"")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })((req.headers)["content-type"],"application/json")))}; return ({"status": 200,"headers": ({"content-type": "application/json; charset=utf-8"}),"body": (req.vars)["id"]}); } @@ -36,8 +36,8 @@ module.exports = function({ $_id, $api_url, $body, $http_HttpMethod, $http_Util, } async handle() { const url = String.raw({ raw: ["", "/path/", "/nn/", ""] }, $api_url, $_id, $user); - const response = (await $http_Util.put(url,{ headers: ({"content-type": "application/json"}), body: ((args) => { return JSON.stringify(args[0], null, args[1]) })([$body]) })); - const fetchResponse = (await $http_Util.put(url,{ method: $http_HttpMethod.PUT, headers: ({"content-type": "application/json"}), body: ((args) => { return JSON.stringify(args[0], null, args[1]) })([$body]) })); + const response = (await $http_Util.put(url,{ headers: ({"content-type": "application/json"}), body: ((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([$body]) })); + const fetchResponse = (await $http_Util.put(url,{ method: $http_HttpMethod.PUT, headers: ({"content-type": "application/json"}), body: ((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([$body]) })); {((cond) => {if (!cond) throw new Error("assertion failed: response.headers.get(\"content-type\") == \"application/json; charset=utf-8\"")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })((response.headers)["content-type"],"application/json; charset=utf-8")))}; {((cond) => {if (!cond) throw new Error("assertion failed: response.body == _id")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(response.body,$_id)))}; {((cond) => {if (!cond) throw new Error("assertion failed: response.status == 200")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(response.status,200)))}; diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/add_object.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/add_object.w_compile_tf-aws.md index 35af2390e53..fa3763b5c38 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/add_object.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/add_object.w_compile_tf-aws.md @@ -11,7 +11,7 @@ module.exports = function({ $b, $jsonObj1, $std_Json }) { } async handle() { {((cond) => {if (!cond) throw new Error("assertion failed: b.list().length == 2")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })((await $b.list()).length,2)))}; - {((cond) => {if (!cond) throw new Error("assertion failed: Json.stringify(b.getJson(\"file1.json\")) == Json.stringify(jsonObj1)")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(((args) => { return JSON.stringify(args[0], null, args[1]) })([(await $b.getJson("file1.json"))]),((args) => { return JSON.stringify(args[0], null, args[1]) })([$jsonObj1]))))}; + {((cond) => {if (!cond) throw new Error("assertion failed: Json.stringify(b.getJson(\"file1.json\")) == Json.stringify(jsonObj1)")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([(await $b.getJson("file1.json"))]),((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([$jsonObj1]))))}; {((cond) => {if (!cond) throw new Error("assertion failed: b.get(\"file2.txt\") == \"Bar\"")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })((await $b.get("file2.txt")),"Bar")))}; } } @@ -253,7 +253,7 @@ class $Root extends $stdlib.std.Resource { } const b = this.node.root.newAbstract("@winglang/sdk.cloud.Bucket",this,"cloud.Bucket"); const jsonObj1 = ({"key1": "value1"}); - (b.addObject("file1.json",((args) => { return JSON.stringify(args[0], null, args[1]) })([jsonObj1]))); + (b.addObject("file1.json",((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([jsonObj1]))); (b.addObject("file2.txt","Bar")); this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:addObject",new $Closure1(this,"$Closure1")); } diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/try_get_json.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/try_get_json.w_compile_tf-aws.md index f5d992733c6..f1488177e1d 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/try_get_json.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/bucket/try_get_json.w_compile_tf-aws.md @@ -13,10 +13,10 @@ module.exports = function({ $b, $std_Json }) { const jsonObj1 = ({"key1": "value1"}); const jsonObj2 = ({"key2": "value2"}); (await $b.putJson("file1.json",jsonObj1)); - {((cond) => {if (!cond) throw new Error("assertion failed: Json.stringify(b.tryGetJson(\"file1.json\")) == Json.stringify(jsonObj1)")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(((args) => { return JSON.stringify(args[0], null, args[1]) })([(await $b.tryGetJson("file1.json"))]),((args) => { return JSON.stringify(args[0], null, args[1]) })([jsonObj1]))))}; + {((cond) => {if (!cond) throw new Error("assertion failed: Json.stringify(b.tryGetJson(\"file1.json\")) == Json.stringify(jsonObj1)")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([(await $b.tryGetJson("file1.json"))]),((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([jsonObj1]))))}; {((cond) => {if (!cond) throw new Error("assertion failed: b.tryGetJson(\"file2.json\") == nil")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })((await $b.tryGetJson("file2.json")),undefined)))}; (await $b.putJson("file2.json",jsonObj2)); - {((cond) => {if (!cond) throw new Error("assertion failed: Json.stringify(b.tryGetJson(\"file2.json\")) == Json.stringify(jsonObj2)")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(((args) => { return JSON.stringify(args[0], null, args[1]) })([(await $b.tryGetJson("file2.json"))]),((args) => { return JSON.stringify(args[0], null, args[1]) })([jsonObj2]))))}; + {((cond) => {if (!cond) throw new Error("assertion failed: Json.stringify(b.tryGetJson(\"file2.json\")) == Json.stringify(jsonObj2)")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([(await $b.tryGetJson("file2.json"))]),((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([jsonObj2]))))}; (await $b.delete("file1.json")); (await $b.delete("file2.json")); {((cond) => {if (!cond) throw new Error("assertion failed: b.tryGetJson(\"file1.json\") == nil")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })((await $b.tryGetJson("file1.json")),undefined)))}; diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/json.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/json.w_compile_tf-aws.md index d90dcc96f47..131134f416c 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/json.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/json.w_compile_tf-aws.md @@ -43,6 +43,28 @@ module.exports = function({ }) { ``` +## inflight.$Closure3-1.js +```js +module.exports = function({ $std_Json }) { + class $Closure3 { + constructor({ }) { + const $obj = (...args) => this.handle(...args); + Object.setPrototypeOf($obj, this); + return $obj; + } + async handle() { + const obj = ({"a": 1,"b": 2}); + const stringified = ((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([obj]); + const stringifiedIndent = ((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([obj,{ indent: 2 }]); + {((cond) => {if (!cond) throw new Error("assertion failed: stringified == \"{\\\"a\\\":1,\\\"b\\\":2}\"")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(stringified,"{\"a\":1,\"b\":2}")))}; + {((cond) => {if (!cond) throw new Error("assertion failed: stringifiedIndent == \"{\\n \\\"a\\\": 1,\\n \\\"b\\\": 2\\n}\"")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(stringifiedIndent,"{\n \"a\": 1,\n \"b\": 2\n}")))}; + } + } + return $Closure3; +} + +``` + ## main.tf.json ```json { @@ -64,7 +86,7 @@ module.exports = function({ }) { }, "output": { "WING_TEST_RUNNER_FUNCTION_ARNS": { - "value": "[[\"root/Default/Default/test:set()\",\"${aws_lambda_function.testset_Handler_ADDF1A01.arn}\"],[\"root/Default/Default/test:setAt()\",\"${aws_lambda_function.testsetAt_Handler_51015029.arn}\"]]" + "value": "[[\"root/Default/Default/test:set()\",\"${aws_lambda_function.testset_Handler_ADDF1A01.arn}\"],[\"root/Default/Default/test:setAt()\",\"${aws_lambda_function.testsetAt_Handler_51015029.arn}\"],[\"root/Default/Default/test:stringify()\",\"${aws_lambda_function.teststringify_Handler_2E93A8A7.arn}\"]]" } }, "provider": { @@ -91,6 +113,15 @@ module.exports = function({ }) { } }, "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Effect\":\"Allow\"}]}" + }, + "teststringify_Handler_IamRole_D79B403A": { + "//": { + "metadata": { + "path": "root/Default/Default/test:stringify()/Handler/IamRole", + "uniqueId": "teststringify_Handler_IamRole_D79B403A" + } + }, + "assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Effect\":\"Allow\"}]}" } }, "aws_iam_role_policy": { @@ -113,6 +144,16 @@ module.exports = function({ }) { }, "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"none:null\",\"Resource\":\"*\"}]}", "role": "${aws_iam_role.testset_Handler_IamRole_B9B79227.name}" + }, + "teststringify_Handler_IamRolePolicy_2C7E059D": { + "//": { + "metadata": { + "path": "root/Default/Default/test:stringify()/Handler/IamRolePolicy", + "uniqueId": "teststringify_Handler_IamRolePolicy_2C7E059D" + } + }, + "policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"none:null\",\"Resource\":\"*\"}]}", + "role": "${aws_iam_role.teststringify_Handler_IamRole_D79B403A.name}" } }, "aws_iam_role_policy_attachment": { @@ -135,6 +176,16 @@ module.exports = function({ }) { }, "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", "role": "${aws_iam_role.testset_Handler_IamRole_B9B79227.name}" + }, + "teststringify_Handler_IamRolePolicyAttachment_B6E5A35D": { + "//": { + "metadata": { + "path": "root/Default/Default/test:stringify()/Handler/IamRolePolicyAttachment", + "uniqueId": "teststringify_Handler_IamRolePolicyAttachment_B6E5A35D" + } + }, + "policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + "role": "${aws_iam_role.teststringify_Handler_IamRole_D79B403A.name}" } }, "aws_lambda_function": { @@ -189,6 +240,32 @@ module.exports = function({ }) { "security_group_ids": [], "subnet_ids": [] } + }, + "teststringify_Handler_2E93A8A7": { + "//": { + "metadata": { + "path": "root/Default/Default/test:stringify()/Handler/Default", + "uniqueId": "teststringify_Handler_2E93A8A7" + } + }, + "environment": { + "variables": { + "WING_FUNCTION_NAME": "Handler-c84b217d", + "WING_TARGET": "tf-aws" + } + }, + "function_name": "Handler-c84b217d", + "handler": "index.handler", + "publish": true, + "role": "${aws_iam_role.teststringify_Handler_IamRole_D79B403A.arn}", + "runtime": "nodejs18.x", + "s3_bucket": "${aws_s3_bucket.Code.bucket}", + "s3_key": "${aws_s3_object.teststringify_Handler_S3Object_938C4856.key}", + "timeout": 30, + "vpc_config": { + "security_group_ids": [], + "subnet_ids": [] + } } }, "aws_s3_bucket": { @@ -224,6 +301,17 @@ module.exports = function({ }) { "bucket": "${aws_s3_bucket.Code.bucket}", "key": "", "source": "" + }, + "teststringify_Handler_S3Object_938C4856": { + "//": { + "metadata": { + "path": "root/Default/Default/test:stringify()/Handler/S3Object", + "uniqueId": "teststringify_Handler_S3Object_938C4856" + } + }, + "bucket": "${aws_s3_bucket.Code.bucket}", + "key": "", + "source": "" } } } @@ -288,6 +376,31 @@ class $Root extends $stdlib.std.Resource { `); } } + class $Closure3 extends $stdlib.std.Resource { + constructor(scope, id, ) { + super(scope, id); + this._addInflightOps("handle", "$inflight_init"); + this.display.hidden = true; + } + static _toInflightType(context) { + return $stdlib.core.NodeJsCode.fromInline(` + require("./inflight.$Closure3-1.js")({ + $std_Json: ${context._lift(std.Json)}, + }) + `); + } + _toInflight() { + return $stdlib.core.NodeJsCode.fromInline(` + (await (async () => { + const $Closure3Client = ${$Closure3._toInflightType(this).text}; + const client = new $Closure3Client({ + }); + if (client.$inflight_init) { await client.$inflight_init(); } + return client; + })()) + `); + } + } const a = ({"a": 1}); const b = ({"b": 2}); ((obj, args) => { obj[args[0]] = args[1]; })(a, ["c",b]); @@ -302,6 +415,7 @@ class $Root extends $stdlib.std.Resource { {((cond) => {if (!cond) throw new Error("assertion failed: Json.tryParse(nil) == nil")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(((args) => { try { return (args === undefined) ? undefined : JSON.parse(args); } catch (err) { return undefined; } })(undefined),undefined)))}; {((cond) => {if (!cond) throw new Error("assertion failed: Json.tryParse(\"boom\") == nil")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(((args) => { try { return (args === undefined) ? undefined : JSON.parse(args); } catch (err) { return undefined; } })("boom"),undefined)))}; {((cond) => {if (!cond) throw new Error("assertion failed: Json.tryParse(\"\") == nil")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(((args) => { try { return (args === undefined) ? undefined : JSON.parse(args); } catch (err) { return undefined; } })(""),undefined)))}; + this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:stringify()",new $Closure3(this,"$Closure3")); } } const $App = $stdlib.core.App.for(process.env.WING_TARGET); diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/json.w_test_sim.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/json.w_test_sim.md index bf1c3c93e98..81f62e88c02 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/json.w_test_sim.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/std/json.w_test_sim.md @@ -2,11 +2,12 @@ ## stdout.log ```log -pass ─ json.wsim » root/env0/test:set() -pass ─ json.wsim » root/env1/test:setAt() +pass ─ json.wsim » root/env0/test:set() +pass ─ json.wsim » root/env1/test:setAt() +pass ─ json.wsim » root/env2/test:stringify() -Tests 2 passed (2) +Tests 3 passed (3) Test Files 1 passed (1) Duration ``` diff --git a/tools/hangar/__snapshots__/test_corpus/sdk_tests/website/website.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/sdk_tests/website/website.w_compile_tf-aws.md index 31cbdf4d941..659615e97f4 100644 --- a/tools/hangar/__snapshots__/test_corpus/sdk_tests/website/website.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/sdk_tests/website/website.w_compile_tf-aws.md @@ -12,7 +12,7 @@ module.exports = function({ $config, $http_Util, $indexFile, $otherFile, $std_Js async handle() { {((cond) => {if (!cond) throw new Error("assertion failed: http.get(w.url).body == indexFile")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })((await $http_Util.get($w_url)).body,$indexFile)))}; {((cond) => {if (!cond) throw new Error("assertion failed: http.get(w.url + \"/inner-folder/other.html\").body == otherFile")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })((await $http_Util.get(($w_url + "/inner-folder/other.html"))).body,$otherFile)))}; - {((cond) => {if (!cond) throw new Error("assertion failed: http.get(w.url + \"/config.json\").body == Json.stringify(config)")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })((await $http_Util.get(($w_url + "/config.json"))).body,((args) => { return JSON.stringify(args[0], null, args[1]) })([$config]))))}; + {((cond) => {if (!cond) throw new Error("assertion failed: http.get(w.url + \"/config.json\").body == Json.stringify(config)")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })((await $http_Util.get(($w_url + "/config.json"))).body,((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([$config]))))}; } } return $Closure1; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/api.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/api.w_compile_tf-aws.md index 3f2f3a620c3..a0513ee7043 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/api.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/api.w_compile_tf-aws.md @@ -12,7 +12,7 @@ module.exports = function({ $counter, $std_Json }) { async handle(request) { const count = (await $counter.inc()); const bodyResponse = ({"count": count}); - const resp = ({"body": ((args) => { return JSON.stringify(args[0], null, args[1]) })([bodyResponse]),"headers": ({"content-type": "application/json"}),"status": 200}); + const resp = ({"body": ((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([bodyResponse]),"headers": ({"content-type": "application/json"}),"status": 200}); return resp; } } diff --git a/tools/hangar/__snapshots__/test_corpus/valid/api_path_vars.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/api_path_vars.w_compile_tf-aws.md index b4abcad7121..b7d7577b30d 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/api_path_vars.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/api_path_vars.w_compile_tf-aws.md @@ -10,7 +10,7 @@ module.exports = function({ $std_Json }) { return $obj; } async handle(req) { - return ({"body": ((args) => { return JSON.stringify(args[0], null, args[1]) })([({"user": (req.vars)["name"]})]),"headers": ({"content-type": "application/json"}),"status": 200}); + return ({"body": ((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([({"user": (req.vars)["name"]})]),"headers": ({"content-type": "application/json"}),"status": 200}); } } return $Closure1; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/doubler.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/doubler.w_compile_tf-aws.md index c96e0156afa..65ee4e1e814 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/doubler.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/doubler.w_compile_tf-aws.md @@ -31,7 +31,7 @@ module.exports = function({ $handler, $std_Json, $std_Number }) { const xStr = ((args) => { if (isNaN(args)) {throw new Error("unable to parse \"" + args + "\" as a number")}; return parseInt(args) })(x); const y = (await $handler(xStr)); const z = (await $handler(y)); - return ((args) => { return JSON.stringify(args[0], null, args[1]) })([z]); + return ((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([z]); } } return $Closure2; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/issue_2889.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/issue_2889.w_compile_tf-aws.md index 44220f83751..7b0957b7ce5 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/issue_2889.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/issue_2889.w_compile_tf-aws.md @@ -11,7 +11,7 @@ module.exports = function({ $std_Json }) { } async handle(req) { const issues = (JSON.parse("[{\"foo\": \"bar\"}, {\"foo\": \"baz\"}, {\"foo\": \"qux\"}]")); - return ({"status": 200,"headers": ({"Content-Type": "application/json"}),"body": ((args) => { return JSON.stringify(args[0], null, args[1]) })([issues])}); + return ({"status": 200,"headers": ({"Content-Type": "application/json"}),"body": ((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([issues])}); } } return $Closure1; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/json_static.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/json_static.w_compile_tf-aws.md index fb852946d35..c6195e32840 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/json_static.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/json_static.w_compile_tf-aws.md @@ -10,7 +10,7 @@ module.exports = function({ $jj, $std_Json }) { return $obj; } async handle() { - const ss = ((args) => { return JSON.stringify(args[0], null, args[1]) })([$jj]); + const ss = ((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([$jj]); {((cond) => {if (!cond) throw new Error("assertion failed: ss == \"{\\\"a\\\":123,\\\"b\\\":{\\\"c\\\":456,\\\"d\\\":789}}\"")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(ss,"{\"a\":123,\"b\":{\"c\":456,\"d\":789}}")))}; } } @@ -315,9 +315,9 @@ class $Root extends $stdlib.std.Resource { const tryParsed = (((args) => { try { return (args === undefined) ? undefined : JSON.parse(args); } catch (err) { return undefined; } })(invalidJson) ?? ({"key": "value"})); {((cond) => {if (!cond) throw new Error("assertion failed: tryParsed.get(\"key\") == \"value\"")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })((tryParsed)["key"],"value")))}; const jj = ({"a": 123,"b": ({"c": 456,"d": 789})}); - const ss = ((args) => { return JSON.stringify(args[0], null, args[1]) })([jj]); + const ss = ((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([jj]); {((cond) => {if (!cond) throw new Error("assertion failed: ss == \"{\\\"a\\\":123,\\\"b\\\":{\\\"c\\\":456,\\\"d\\\":789}}\"")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(ss,"{\"a\":123,\"b\":{\"c\":456,\"d\":789}}")))}; - const ss2 = ((args) => { return JSON.stringify(args[0], null, args[1]) })([jj,2]); + const ss2 = ((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([jj,{ indent: 2 }]); {((cond) => {if (!cond) throw new Error("assertion failed: ss2 == \"{\\n \\\"a\\\": 123,\\n \\\"b\\\": {\\n \\\"c\\\": 456,\\n \\\"d\\\": 789\\n }\\n}\"")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(ss2,"{\n \"a\": 123,\n \"b\": {\n \"c\": 456,\n \"d\": 789\n }\n}")))}; const jsonOfMany = ({"a": 123,"b": "hello","c": true}); {((cond) => {if (!cond) throw new Error("assertion failed: str.fromJson(jsonOfMany.get(\"b\")) == \"hello\"")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(((args) => { if (typeof args !== "string") {throw new Error("unable to parse " + typeof args + " " + args + " as a string")}; return JSON.parse(JSON.stringify(args)) })((jsonOfMany)["b"]),"hello")))}; diff --git a/tools/hangar/__snapshots__/test_corpus/valid/website_with_api.w_compile_tf-aws.md b/tools/hangar/__snapshots__/test_corpus/valid/website_with_api.w_compile_tf-aws.md index a97c260ea86..022befab338 100644 --- a/tools/hangar/__snapshots__/test_corpus/valid/website_with_api.w_compile_tf-aws.md +++ b/tools/hangar/__snapshots__/test_corpus/valid/website_with_api.w_compile_tf-aws.md @@ -10,7 +10,7 @@ module.exports = function({ $std_Json, $usersTable }) { return $obj; } async handle(req) { - return ({"body": ((args) => { return JSON.stringify(args[0], null, args[1]) })([({"users": (await $usersTable.list())})]),"status": 200}); + return ({"body": ((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([({"users": (await $usersTable.list())})]),"status": 200}); } } return $Closure1; @@ -28,12 +28,12 @@ module.exports = function({ $std_Json, $usersTable }) { return $obj; } async handle(req) { - const body = (JSON.parse((req.body ?? ((args) => { return JSON.stringify(args[0], null, args[1]) })([({"name": "","age": "","id": ""})])))); + const body = (JSON.parse((req.body ?? ((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([({"name": "","age": "","id": ""})])))); if ((((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })((body)["name"],"")) || (((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })((body)["age"],""))) || (((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })((body)["id"],"")))) { - return ({"body": ((args) => { return JSON.stringify(args[0], null, args[1]) })([({"error": "incomplete details"})]),"status": 400}); + return ({"body": ((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([({"error": "incomplete details"})]),"status": 400}); } - (await $usersTable.insert(((args) => { return JSON.stringify(args[0], null, args[1]) })([(body)["id"]]),body)); - return ({"body": ((args) => { return JSON.stringify(args[0], null, args[1]) })([({"user": (body)["id"]})]),"status": 201}); + (await $usersTable.insert(((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([(body)["id"]]),body)); + return ({"body": ((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([({"user": (body)["id"]})]),"status": 201}); } } return $Closure2;