@intentius/chant-lexicon-aws 0.124.51 → 0.124.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/dist/codegen/generate-lexicon.d.ts +2 -0
  2. package/dist/codegen/generate-lexicon.d.ts.map +1 -1
  3. package/dist/codegen/generate-lexicon.js +1 -0
  4. package/dist/components/__tests__/mock-cloud-executor.d.ts +4 -0
  5. package/dist/components/__tests__/mock-cloud-executor.d.ts.map +1 -1
  6. package/dist/components/__tests__/mock-cloud-executor.js +18 -1
  7. package/dist/components/apply.d.ts +76 -3
  8. package/dist/components/apply.d.ts.map +1 -1
  9. package/dist/components/apply.js +488 -32
  10. package/dist/components/cfn-adopt.d.ts +99 -0
  11. package/dist/components/cfn-adopt.d.ts.map +1 -0
  12. package/dist/components/cfn-adopt.js +278 -0
  13. package/dist/components/cfn-imports.d.ts +84 -0
  14. package/dist/components/cfn-imports.d.ts.map +1 -0
  15. package/dist/components/cfn-imports.js +239 -0
  16. package/dist/components/cloud-executor.d.ts +44 -2
  17. package/dist/components/cloud-executor.d.ts.map +1 -1
  18. package/dist/components/cloud-executor.js +73 -2
  19. package/dist/importable.d.ts +30 -0
  20. package/dist/importable.d.ts.map +1 -0
  21. package/dist/importable.js +72 -0
  22. package/dist/index-identity.d.ts +19 -0
  23. package/dist/index-identity.d.ts.map +1 -0
  24. package/dist/index-identity.js +79 -0
  25. package/dist/index-import.d.ts +17 -0
  26. package/dist/index-import.d.ts.map +1 -0
  27. package/dist/index-import.js +115 -0
  28. package/dist/integrity.json +3 -3
  29. package/dist/listed-types.d.ts +11 -0
  30. package/dist/listed-types.d.ts.map +1 -0
  31. package/dist/listed-types.js +52 -0
  32. package/dist/manifest.json +1 -1
  33. package/dist/meta.json +13206 -1237
  34. package/dist/plugin.d.ts.map +1 -1
  35. package/dist/plugin.js +9 -0
  36. package/dist/reference-catalog.d.ts.map +1 -1
  37. package/dist/reference-catalog.js +62 -20
  38. package/dist/spec/fetch.d.ts +5 -0
  39. package/dist/spec/fetch.d.ts.map +1 -1
  40. package/dist/spec/parse.d.ts +8 -0
  41. package/dist/spec/parse.d.ts.map +1 -1
  42. package/dist/spec/parse.js +3 -0
  43. package/package.json +2 -2
  44. package/src/codegen/generate-lexicon.ts +3 -0
  45. package/src/components/__tests__/mock-cloud-executor.ts +20 -1
  46. package/src/components/apply.ts +546 -33
  47. package/src/components/cfn-adopt.test.ts +284 -0
  48. package/src/components/cfn-adopt.ts +340 -0
  49. package/src/components/cfn-exports-in-use.test.ts +146 -0
  50. package/src/components/cfn-imports-preview.test.ts +178 -0
  51. package/src/components/cfn-imports-three-stacks.test.ts +107 -0
  52. package/src/components/cfn-imports.test.ts +213 -0
  53. package/src/components/cfn-imports.ts +246 -0
  54. package/src/components/cfn-plan-floci.e2e.test.ts +53 -0
  55. package/src/components/cfn-plan-shape-conformance.test.ts +83 -0
  56. package/src/components/cfn-plan.test.ts +328 -9
  57. package/src/components/cloud-executor.ts +119 -6
  58. package/src/components/demo-composed-stacks-floci.e2e.test.ts +235 -0
  59. package/src/derived-edges.test.ts +142 -0
  60. package/src/generated/lexicon-aws.json +13206 -1237
  61. package/src/importable.test.ts +86 -0
  62. package/src/importable.ts +83 -0
  63. package/src/index-identity.test.ts +134 -0
  64. package/src/index-identity.ts +98 -0
  65. package/src/index-import.test.ts +242 -0
  66. package/src/index-import.ts +140 -0
  67. package/src/index-search.test.ts +87 -0
  68. package/src/listed-types.test.ts +97 -0
  69. package/src/listed-types.ts +56 -0
  70. package/src/plugin.ts +10 -0
  71. package/src/reference-catalog.ts +63 -20
  72. package/src/spec/fetch.ts +5 -0
  73. package/src/spec/parse.test.ts +15 -0
  74. package/src/spec/parse.ts +12 -0
  75. package/src/testdata/indexed/identity.listing.json +65 -0
  76. package/src/testdata/indexed/import.listing.json +126 -0
  77. package/src/testdata/indexed/listing.json +69 -0
  78. package/src/testdata/indexed/topology.listing.json +350 -0
  79. package/src/testdata/three-cloud/dns.graph.json +336 -0
  80. package/src/three-cloud-parity.test.ts +49 -0
@@ -0,0 +1,79 @@
1
+ /**
2
+ * The aws lexicon's identity rule for indexed resources (#4523, rule written
3
+ * out on INTENTIUS/behold#1025's design comment).
4
+ *
5
+ * The same evidence the stack read's identity fallback uses (#1647,
6
+ * ./identity-observe.ts): the CloudFormation schema's `primaryIdentifier`,
7
+ * which codegen compiled into `lexicon-aws.json`, read off the declared
8
+ * props and `|`-joined the way Cloud Control spells an identifier. behold's
9
+ * lister (behold#1029) writes that Cloud Control `Identifier` as each indexed
10
+ * node's `nativeId`, so a never-deployed bucket declared with `BucketName`
11
+ * and a role declared with `RoleName` match their indexed objects by value.
12
+ *
13
+ * What cannot match:
14
+ * - an identifier part the schema lists in `readOnlyProperties` is assigned
15
+ * by the service (`InstanceId` for `AWS::EC2::Instance`, `QueueUrl` for
16
+ * `AWS::SQS::Queue`), so no declaration states it: `no-binding`;
17
+ * - a part the declaration leaves out or spells with a Ref or an intrinsic:
18
+ * `no-binding`, "identity is not in the declaration";
19
+ * - a type with no primary identifier on record: `unsupported-kind`.
20
+ *
21
+ * Global types are the prefixes behold's aws lister lists once per account at
22
+ * location `global` (behold src/cloud-lister/aws.ts, `isGlobalAwsType`).
23
+ */
24
+ import { createRequire } from "module";
25
+ import { moduleSourceUrl } from "@intentius/chant/module-source";
26
+ const require = createRequire(moduleSourceUrl(import.meta.url));
27
+ const GLOBAL_TYPE_PREFIXES = ["AWS::IAM::", "AWS::CloudFront::", "AWS::Route53::", "AWS::Organizations::", "AWS::GlobalAccelerator::"];
28
+ /** True for a type behold's lister indexes at location `global`. */
29
+ export function isGlobalAwsType(type) {
30
+ return GLOBAL_TYPE_PREFIXES.some((p) => type.startsWith(p));
31
+ }
32
+ let cachedManifest;
33
+ /** The manifest keyed by type, or an empty one in a checkout that has not generated (every type is then `unsupported-kind`). */
34
+ function defaultManifest() {
35
+ if (cachedManifest)
36
+ return cachedManifest;
37
+ try {
38
+ const manifest = require("./generated/lexicon-aws.json");
39
+ cachedManifest = new Map(Object.values(manifest).filter((e) => e.kind === "resource").map((e) => [e.resourceType, e]));
40
+ }
41
+ catch {
42
+ cachedManifest = new Map();
43
+ }
44
+ return cachedManifest;
45
+ }
46
+ /**
47
+ * The identifier an aws declaration spells for the index, or why it spells
48
+ * none. `manifest` is the generated `lexicon-aws.json` keyed by type; a test
49
+ * passes a table.
50
+ */
51
+ export function awsDeclaredIdentity(entityType, props, manifest = defaultManifest()) {
52
+ const entry = manifest.get(entityType);
53
+ const parts = entry?.primaryIdentifier;
54
+ if (!entry || entry.kind !== "resource" || !parts || parts.length === 0) {
55
+ return { kind: "unmatchable", reason: "unsupported-kind", detail: `${entityType} has no primary identifier on record` };
56
+ }
57
+ const readOnly = new Set(Object.values(entry.attrs ?? {}));
58
+ const serverAssigned = parts.filter((p) => readOnly.has(p));
59
+ if (serverAssigned.length > 0) {
60
+ return {
61
+ kind: "unmatchable",
62
+ reason: "no-binding",
63
+ detail: `the identity of ${entityType} (${parts.join(", ")}) is assigned by the service (${serverAssigned.join(", ")}), so no declaration states it`,
64
+ };
65
+ }
66
+ const values = [];
67
+ for (const part of parts) {
68
+ const v = props[part];
69
+ if ((typeof v !== "string" && typeof v !== "number") || String(v) === "") {
70
+ return { kind: "unmatchable", reason: "no-binding", detail: `identity is not in the declaration (${entityType} ${part})` };
71
+ }
72
+ values.push(String(v));
73
+ }
74
+ return { kind: "identifier", listedType: entityType, identifier: values.join("|"), global: isGlobalAwsType(entityType) };
75
+ }
76
+ export const awsIndexIdentity = {
77
+ substrate: "aws",
78
+ declaredIdentity: (entityType, props) => awsDeclaredIdentity(entityType, props),
79
+ };
@@ -0,0 +1,17 @@
1
+ import type { IndexImportCodegen, IndexImportTarget } from "@intentius/chant/lifecycle/index-import";
2
+ /** One `lexicon-aws.json` entry, the fields this seam reads. */
3
+ export interface ImportManifestEntry {
4
+ resourceType: string;
5
+ kind: string;
6
+ /** GetAtt name -> CloudFormation attribute: the schema's `readOnlyProperties`. */
7
+ attrs?: Record<string, string>;
8
+ }
9
+ /** The properties a declaration of `type` can hold, from an indexed node's attrs. */
10
+ export declare function awsImportProperties(type: string, attrs: Record<string, unknown>, manifest?: ReadonlyMap<string, ImportManifestEntry>): Record<string, unknown>;
11
+ /** `value` as a reference to `target`, or undefined. */
12
+ export declare function awsImportReference(value: string, target: IndexImportTarget, manifest?: ReadonlyMap<string, ImportManifestEntry>): unknown | undefined;
13
+ /** The resource attributes `chant import --index` writes on every resource it imports (#4536). */
14
+ export declare const ADOPTED_RESOURCE_ATTRIBUTES: Readonly<Record<string, string>>;
15
+ export declare function createAwsIndexImport(manifest?: ReadonlyMap<string, ImportManifestEntry>): IndexImportCodegen;
16
+ export declare const awsIndexImport: IndexImportCodegen;
17
+ //# sourceMappingURL=index-import.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-import.d.ts","sourceRoot":"","sources":["../src/index-import.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAKrG,gEAAgE;AAChE,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,kFAAkF;IAClF,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAiCD,qFAAqF;AACrF,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,QAAQ,GAAE,WAAW,CAAC,MAAM,EAAE,mBAAmB,CAAqB,GACrE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAUzB;AAQD,wDAAwD;AACxD,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,iBAAiB,EACzB,QAAQ,GAAE,WAAW,CAAC,MAAM,EAAE,mBAAmB,CAAqB,GACrE,OAAO,GAAG,SAAS,CAUrB;AAED,kGAAkG;AAClG,eAAO,MAAM,2BAA2B,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAA+D,CAAC;AAEzI,wBAAgB,oBAAoB,CAAC,QAAQ,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,mBAAmB,CAAC,GAAG,kBAAkB,CA0B5G;AAED,eAAO,MAAM,cAAc,EAAE,kBAA2C,CAAC"}
@@ -0,0 +1,115 @@
1
+ /**
2
+ * The aws lexicon's index import seam (#4524, `chant import --index`).
3
+ *
4
+ * behold's lister reads AWS through Cloud Control, which returns each
5
+ * object's CloudFormation resource model, and #4521 normalizes it with this
6
+ * lexicon's deep hooks. So an indexed node's `attrs` already are
7
+ * CloudFormation properties, and the import IR is the one the CloudFormation
8
+ * template parser writes (`{ __intrinsic: "Ref" }` and so on), which
9
+ * `CFGenerator` turns into source.
10
+ *
11
+ * - Properties the schema lists in `readOnlyProperties` (the registry's
12
+ * `attrs`) are left out, because no declaration can set them. Tags whose
13
+ * key starts with `aws:` are left out too: CloudFormation sets them and
14
+ * refuses them in a template.
15
+ * - A value that names another imported resource becomes `Ref` when it is
16
+ * that resource's Cloud Control identifier (a single-part one; for the
17
+ * types the catalog joins, Ref returns that identifier), and
18
+ * `GetAtt(<id>, "Arn")` when it is the resource's ARN and the type has an
19
+ * `Arn` attribute. Anything else stays a literal.
20
+ * - A masked value becomes a `String` parameter with `NoEcho`.
21
+ */
22
+ import { createRequire } from "module";
23
+ import { moduleSourceUrl } from "@intentius/chant/module-source";
24
+ const require = createRequire(moduleSourceUrl(import.meta.url));
25
+ let cachedManifest;
26
+ /** The generated registry keyed by type, or an empty map in a checkout that has not generated. */
27
+ function defaultManifest() {
28
+ if (cachedManifest)
29
+ return cachedManifest;
30
+ try {
31
+ const manifest = require("./generated/lexicon-aws.json");
32
+ cachedManifest = new Map(Object.values(manifest).filter((e) => e.kind === "resource").map((e) => [e.resourceType, e]));
33
+ }
34
+ catch {
35
+ cachedManifest = new Map();
36
+ }
37
+ return cachedManifest;
38
+ }
39
+ const CFN_TYPE = /^AWS::[A-Za-z0-9]+::[A-Za-z0-9]+$/;
40
+ function isRecord(v) {
41
+ return typeof v === "object" && v !== null && !Array.isArray(v);
42
+ }
43
+ /** Tags without the `aws:` ones, in either shape CloudFormation uses (a Key/Value list or a map). */
44
+ function withoutAwsTags(tags) {
45
+ if (Array.isArray(tags)) {
46
+ return tags.filter((t) => !(isRecord(t) && typeof t.Key === "string" && t.Key.startsWith("aws:")));
47
+ }
48
+ if (isRecord(tags)) {
49
+ return Object.fromEntries(Object.entries(tags).filter(([k]) => !k.startsWith("aws:")));
50
+ }
51
+ return tags;
52
+ }
53
+ /** The properties a declaration of `type` can hold, from an indexed node's attrs. */
54
+ export function awsImportProperties(type, attrs, manifest = defaultManifest()) {
55
+ const readOnly = new Set(Object.values(manifest.get(type)?.attrs ?? {}).map((a) => a.split(".")[0]));
56
+ const out = {};
57
+ for (const key of Object.keys(attrs).sort()) {
58
+ if (readOnly.has(key))
59
+ continue;
60
+ const value = key === "Tags" ? withoutAwsTags(attrs[key]) : attrs[key];
61
+ if (key === "Tags" && ((Array.isArray(value) && value.length === 0) || (isRecord(value) && Object.keys(value).length === 0)))
62
+ continue;
63
+ out[key] = value;
64
+ }
65
+ return out;
66
+ }
67
+ /** True when `type` exposes `Arn` to GetAtt, or when there is no registry to ask. */
68
+ function hasArnAttribute(type, manifest) {
69
+ if (manifest.size === 0)
70
+ return true;
71
+ return Object.values(manifest.get(type)?.attrs ?? {}).includes("Arn");
72
+ }
73
+ /** `value` as a reference to `target`, or undefined. */
74
+ export function awsImportReference(value, target, manifest = defaultManifest()) {
75
+ const node = target.node;
76
+ if (node.nativeId !== undefined && value === node.nativeId && !value.includes("|")) {
77
+ return { __intrinsic: "Ref", name: target.logicalId };
78
+ }
79
+ const isArn = (node.facts?.cloudIds ?? []).some((c) => c.kind === "arn" && c.value === value);
80
+ if (isArn && hasArnAttribute(node.kind, manifest)) {
81
+ return { __intrinsic: "GetAtt", logicalId: target.logicalId, attribute: "Arn" };
82
+ }
83
+ return undefined;
84
+ }
85
+ /** The resource attributes `chant import --index` writes on every resource it imports (#4536). */
86
+ export const ADOPTED_RESOURCE_ATTRIBUTES = { DeletionPolicy: "Retain", UpdateReplacePolicy: "Retain" };
87
+ export function createAwsIndexImport(manifest) {
88
+ const m = () => manifest ?? defaultManifest();
89
+ return {
90
+ resource(node) {
91
+ if (!CFN_TYPE.test(node.kind))
92
+ return { unsupported: `${node.kind} is not a CloudFormation resource type` };
93
+ // Retain on every imported resource until a person changes it in source
94
+ // (#4536, ruled on choudoufu#2284 Q4): CloudFormation deletes at stack
95
+ // level and reads no per-resource marker, so an adopted object is never
96
+ // deleted on the stack's word alone. Import requires a DeletionPolicy.
97
+ return { type: node.kind, properties: awsImportProperties(node.kind, node.attrs ?? {}, m()), attributes: { ...ADOPTED_RESOURCE_ATTRIBUTES } };
98
+ },
99
+ reference: (value, target) => awsImportReference(value, target, m()),
100
+ secretParameter(name, context) {
101
+ return {
102
+ name,
103
+ type: "String",
104
+ description: `${context.path} of ${context.node.id}, masked in the index`,
105
+ constraints: { NoEcho: true },
106
+ };
107
+ },
108
+ parameterReference: (name) => ({ __intrinsic: "Ref", name }),
109
+ typeLabel(node) {
110
+ const last = node.kind.split("::").pop() ?? "Resource";
111
+ return last.charAt(0).toUpperCase() + last.slice(1);
112
+ },
113
+ };
114
+ }
115
+ export const awsIndexImport = createAwsIndexImport();
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "algorithm": "sha256",
3
3
  "artifacts": {
4
- "manifest.json": "c32fdc442ad95fe1498bf3b3f185bd992e31930166bb0a95cb3e5b45cd7ae71f",
5
- "meta.json": "6f48557ed4203cbdeafdb47e7270fdf3533f6d6e6189987246301ed8e72170e9",
4
+ "manifest.json": "ce95b454998a3f0d965ce16cb3ff3063159ea5505535e05a86e311988c8f163a",
5
+ "meta.json": "5a61f147f0c79262967f826c69a53b8b21fe6c41c6142e6c6c235b595482357f",
6
6
  "types/index.d.ts": "8651f9ae166668f4311eea1fe61c3fe235f345947951c1d23d1df24a4fd3384f",
7
7
  "rules/hardcoded-region.ts": "957eadcaa9f39cc17d21437565d7a94607d9b082cf28918b178fa067f07498a9",
8
8
  "rules/iam-wildcard.ts": "10f5065fa2bbf2c8ce23dfb475a56df33f280df87784e44fec641b2584cbf333",
@@ -75,5 +75,5 @@
75
75
  "skills/chant-aws-eks.md": "8789255709ff004ad0a875fd5999edcdc66fc6e33d710db058d9f42703bcfdfe",
76
76
  "skills/chant-aws-carve-terraform.md": "8780b94ce60aded935938d5ef20ea667738354051da1bf9ca6d70d9886f65d21"
77
77
  },
78
- "composite": "8ee7219a12f52d63705c15d96a7f2b1d5dfdbab8612241e884d8a8a159e67d56"
78
+ "composite": "e81efc6cc87353d56bddf1aa86498a99f27a75992d078ce95e8e18691101d16b"
79
79
  }
@@ -0,0 +1,11 @@
1
+ import type { ListedTypeMapping } from "@intentius/chant/lifecycle/type-listing";
2
+ /**
3
+ * The aws kind for a Cloud Control type, or undefined. With no kind set (no
4
+ * generated registry) every well-formed CloudFormation type maps, which is
5
+ * what the rest of the lexicon assumes before `chant generate` has run.
6
+ */
7
+ export declare function awsKindForListedType(listedType: string, kinds?: ReadonlySet<string> | null): string | undefined;
8
+ /** The inverse, for tests and for a reader naming what to list: the same name. */
9
+ export declare function awsListedTypeForKind(kind: string): string;
10
+ export declare const awsListedTypes: ListedTypeMapping;
11
+ //# sourceMappingURL=listed-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listed-types.d.ts","sourceRoot":"","sources":["../src/listed-types.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAsBjF;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,GAAE,WAAW,CAAC,MAAM,CAAC,GAAG,IAAuB,GAAG,MAAM,GAAG,SAAS,CAIjI;AAED,kFAAkF;AAClF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,eAAO,MAAM,cAAc,EAAE,iBAG5B,CAAC"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Cloud Control's type names as aws lexicon kinds (#4521).
3
+ *
4
+ * behold#1029 lists AWS through Cloud Control `ListResources`, which names
5
+ * each object by its CloudFormation type (`AWS::S3::Bucket`), and the aws
6
+ * lexicon's kinds are those same names. So the mapping is the identity, kept
7
+ * to the types the lexicon generated: a type outside `lexicon-aws.json` (one
8
+ * newer than the pinned registry, or a third-party type) has no kind here and
9
+ * stays an unknown-kind node. Cloud Control returns the CloudFormation
10
+ * resource model, which is the tree the deep reader returns too
11
+ * (./deep-observe.ts), so no reshaping.
12
+ */
13
+ import { createRequire } from "module";
14
+ import { moduleSourceUrl } from "@intentius/chant/module-source";
15
+ const require = createRequire(moduleSourceUrl(import.meta.url));
16
+ // A CloudFormation type name: `<Organization>::<Service>::<Resource>`. The
17
+ // organization is not always AWS (`Alexa::ASK::Skill`), so it is not pinned.
18
+ const CFN_TYPE = /^[A-Za-z0-9]+::[A-Za-z0-9]+::[A-Za-z0-9]+$/;
19
+ let cachedKinds;
20
+ /** The resource kinds `chant generate` wrote, or null in a checkout that has not generated. */
21
+ function generatedKinds() {
22
+ if (cachedKinds !== undefined)
23
+ return cachedKinds;
24
+ try {
25
+ const manifest = require("./generated/lexicon-aws.json");
26
+ cachedKinds = new Set(Object.values(manifest).filter((e) => e.kind === "resource").map((e) => e.resourceType));
27
+ }
28
+ catch {
29
+ cachedKinds = null;
30
+ }
31
+ return cachedKinds;
32
+ }
33
+ /**
34
+ * The aws kind for a Cloud Control type, or undefined. With no kind set (no
35
+ * generated registry) every well-formed CloudFormation type maps, which is
36
+ * what the rest of the lexicon assumes before `chant generate` has run.
37
+ */
38
+ export function awsKindForListedType(listedType, kinds = generatedKinds()) {
39
+ if (!CFN_TYPE.test(listedType))
40
+ return undefined;
41
+ if (kinds && !kinds.has(listedType))
42
+ return undefined;
43
+ return listedType;
44
+ }
45
+ /** The inverse, for tests and for a reader naming what to list: the same name. */
46
+ export function awsListedTypeForKind(kind) {
47
+ return kind;
48
+ }
49
+ export const awsListedTypes = {
50
+ substrate: "aws",
51
+ kindFor: (listedType) => awsKindForListedType(listedType),
52
+ };
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aws",
3
- "version": "0.124.51",
3
+ "version": "0.124.54",
4
4
  "chantVersion": ">=0.1.0",
5
5
  "namespace": "AWS",
6
6
  "intrinsics": [