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;