Skip to content

Commit

Permalink
Add jsonStringify to nodejs sdk
Browse files Browse the repository at this point in the history
This isn't _quite_ right, because you could possibly end up with an
output value being passed to stringify still via a custom replacer or
toJson method, and we don't handle that. But I don't think we _can_
handle that as we'd need async in sync to do it.
  • Loading branch information
Frassle committed Dec 9, 2022
1 parent 68308f5 commit a49cfa6
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 3 deletions.
@@ -0,0 +1,4 @@
changes:
- type: feat
scope: sdk/nodejs
description: Add output jsonStringify using JSON.stringify.
9 changes: 9 additions & 0 deletions sdk/nodejs/output.ts
Expand Up @@ -1013,3 +1013,12 @@ export function interpolate(literals: TemplateStringsArray, ...placeholders: Inp
return result;
});
}

/**
* [jsonStringify] Uses JSON.stringify to serialize the given Input value into a JSON string.
*/
export function jsonStringify(obj: Input<any>, replacer?: (this: any, key: string, value: any) => any | (number | string)[], space?: string | number): Output<string> {
return output(obj).apply(o => {
return JSON.stringify(o, replacer, space)
});
}
71 changes: 68 additions & 3 deletions sdk/nodejs/tests/output.spec.ts
Expand Up @@ -15,7 +15,7 @@
/* eslint-disable */

import * as assert from "assert";
import { Output, all, concat, interpolate, output, unknown, secret, unsecret, isSecret } from "../output";
import { Output, all, concat, interpolate, output, unknown, secret, unsecret, isSecret, jsonStringify } from "../output";
import { Resource } from "../resource";
import * as runtime from "../runtime";

Expand Down Expand Up @@ -138,8 +138,7 @@ describe("output", () => {

describe("apply", () => {
function createOutput<T>(val: T, isKnown: boolean, isSecret: boolean = false): Output<T> {
return new Output(new Set(), Promise.resolve(val), Promise.resolve(isKnown), Promise.resolve(isSecret),
Promise.resolve(new Set()));
return new Output<T>(new Set(), Promise.resolve(val), Promise.resolve(isKnown), Promise.resolve(isSecret), Promise.resolve(new Set()));
}

it("can run on known value during preview", async () => {
Expand Down Expand Up @@ -859,6 +858,72 @@ describe("output", () => {
});
});

describe("jsonStringify", () => {
it ("basic", async () => {
const x = output([0, 1])
const result = jsonStringify(x)
assert.strictEqual(await result.promise(), "[0,1]");
assert.strictEqual(await result.isKnown, true);
assert.strictEqual(await result.isSecret, false);
});

it ("nested", async () => {
const x = output([output(0), output(1)])
const result = jsonStringify(x)
assert.strictEqual(await result.promise(), "[0,1]");
assert.strictEqual(await result.isKnown, true);
assert.strictEqual(await result.isSecret, false);
});

it ("nested unknowns", async () => {
const x = output([
new Output(new Set(), Promise.resolve(undefined), Promise.resolve(false), Promise.resolve(false), Promise.resolve(new Set())),
output(1)])
const result = jsonStringify(x)
assert.strictEqual(await result.isKnown, false);
assert.strictEqual(await result.isSecret, false);
});

it ("nested secret", async () => {
const x = output([
new Output(new Set(), Promise.resolve(0), Promise.resolve(true), Promise.resolve(true), Promise.resolve(new Set())),
output(1)])
const result = jsonStringify(x)
assert.strictEqual(await result.promise(), "[0,1]");
assert.strictEqual(await result.isKnown, true);
assert.strictEqual(await result.isSecret, true);
});

it ("with options", async () => {
const x = output([0, 1])
const result = jsonStringify(x, undefined, " ")
assert.strictEqual(await result.promise(), "[\n 0,\n 1\n]");
assert.strictEqual(await result.isKnown, true);
assert.strictEqual(await result.isSecret, false);
});

it ("nested dependencies", async () => {
// Output's don't actually _look_ at the resources, they just need to keep a collection of them
const mockResource : Resource = {} as any
const mockResources : Resource[] = [mockResource]

const x = output([
new Output(new Set(mockResources), Promise.resolve(0), Promise.resolve(true), Promise.resolve(true), Promise.resolve(new Set())),
output(1)])
const result = jsonStringify(x)
assert.strictEqual(await result.promise(), "[0,1]");
assert.strictEqual(await result.isKnown, true);
assert.strictEqual(await result.isSecret, true);
if (result.allResources === undefined) {
assert.fail("Output.allResources was undefined")
}
const allResources = await result.allResources();
// We should have just the one mockResource in this set
assert.strictEqual(allResources.size, 1)
assert.ok(allResources.has(mockResource))
});
});

describe("secret operations", () => {
it("ensure secret", async () => {
const sec = secret("foo");
Expand Down

0 comments on commit a49cfa6

Please sign in to comment.