Created
October 11, 2023 20:19
-
-
Save Chriscbr/58384bdd7b8ce5e8fedf24ddba55e103 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { Construct } = require("constructs"); | |
const { writeFileSync } = require("node:fs"); | |
class Lazy { | |
constructor(producer) { | |
this.producer = producer; | |
} | |
produce() { | |
return this.producer(); | |
} | |
} | |
function resolveLazies(value) { | |
switch (typeof value) { | |
case "object": | |
if (value instanceof Lazy) { | |
return value.produce(); | |
} else if (Array.isArray(value)) { | |
return value.map(resolveLazies); | |
} else { | |
const result = {}; | |
for (const [key, val] of Object.entries(value)) { | |
result[key] = resolveLazies(val); | |
} | |
return result; | |
} | |
default: | |
return value; | |
} | |
} | |
class Flower extends Construct { | |
constructor(scope, id, props) { | |
super(scope, id, props); | |
this.kind = props.kind; | |
this.color = props.color; | |
this._nativeRegions = props.nativeRegions ?? []; | |
} | |
get nativeRegions() { | |
return new Lazy(() => [...this._nativeRegions]); | |
} | |
addNativeRegion(region) { | |
this._nativeRegions.push(region); | |
} | |
toJson() { | |
return { | |
id: this.node.path, | |
kind: this.kind, | |
color: this.color, | |
nativeRegions: this.nativeRegions, | |
}; | |
} | |
} | |
class Garden extends Construct { | |
constructor(scope, id, props) { | |
super(scope, id, props); | |
} | |
synth() { | |
const hasToJson = (node) => typeof node.toJson === "function"; | |
const objects = this.node.findAll().filter(hasToJson).map((c) => resolveLazies(c.toJson())); | |
writeFileSync("garden.json", JSON.stringify(objects, null, 2)); | |
} | |
} | |
class Signpost extends Construct { | |
constructor(scope, id, props) { | |
super(scope, id); | |
this._message = new Lazy(() => { | |
const allRegions = new Set(props.flowers.flatMap((f) => f.nativeRegions.produce())); | |
let message = "Welcome to Tuple Trove, home to flowers from: "; | |
message += [...allRegions].join(", "); | |
message += "."; | |
return message; | |
}); | |
} | |
toJson() { | |
return { | |
id: this.node.path, | |
message: this._message, | |
}; | |
} | |
} | |
const garden = new Garden(undefined, "root"); | |
const rose = new Flower(garden, "rose", { kind: "rose", color: "red" }); | |
rose.addNativeRegion("Denmark"); | |
new Signpost(garden, "signpost", { flowers: [rose] }); | |
rose.addNativeRegion("Turkey"); | |
rose.addNativeRegion("Greece"); | |
garden.synth(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment