@intentius/chant-lexicon-aws 0.1.4 → 0.1.8

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 (71) hide show
  1. package/dist/integrity.json +40 -40
  2. package/dist/manifest.json +1 -1
  3. package/dist/meta.json +3578 -783
  4. package/dist/types/index.d.ts +4363 -700
  5. package/package.json +7 -7
  6. package/src/actions/actions.test.ts +1 -1
  7. package/src/codegen/__snapshots__/snapshot.test.ts.snap +45 -45
  8. package/src/codegen/docs-links.test.ts +3 -3
  9. package/src/codegen/docs.ts +15 -10
  10. package/src/codegen/generate-cli.ts +2 -2
  11. package/src/codegen/generate.test.ts +1 -1
  12. package/src/codegen/idempotency.test.ts +1 -1
  13. package/src/codegen/package.test.ts +1 -1
  14. package/src/codegen/package.ts +2 -7
  15. package/src/codegen/snapshot.test.ts +1 -1
  16. package/src/codegen/typecheck.test.ts +1 -1
  17. package/src/composites/composites.test.ts +1 -1
  18. package/src/coverage.test.ts +1 -1
  19. package/src/default-tags.test.ts +1 -1
  20. package/src/generated/index.d.ts +4363 -700
  21. package/src/generated/index.ts +368 -48
  22. package/src/generated/lexicon-aws.json +3578 -783
  23. package/src/import/generator.test.ts +1 -1
  24. package/src/import/generator.ts +1 -1
  25. package/src/import/parser.test.ts +1 -1
  26. package/src/import/roundtrip-fixtures.test.ts +4 -4
  27. package/src/import/roundtrip.test.ts +1 -1
  28. package/src/integration.test.ts +1 -1
  29. package/src/intrinsics.test.ts +1 -1
  30. package/src/lint/post-synth/ext001.test.ts +1 -1
  31. package/src/lint/post-synth/post-synth.test.ts +1 -1
  32. package/src/lint/post-synth/waw013.test.ts +1 -1
  33. package/src/lint/post-synth/waw014.test.ts +1 -1
  34. package/src/lint/post-synth/waw015.test.ts +1 -1
  35. package/src/lint/post-synth/waw016.test.ts +1 -1
  36. package/src/lint/post-synth/waw017.test.ts +1 -1
  37. package/src/lint/post-synth/waw018.test.ts +1 -1
  38. package/src/lint/post-synth/waw019.test.ts +1 -1
  39. package/src/lint/post-synth/waw020.test.ts +1 -1
  40. package/src/lint/post-synth/waw021.test.ts +1 -1
  41. package/src/lint/post-synth/waw022.test.ts +1 -1
  42. package/src/lint/post-synth/waw023.test.ts +1 -1
  43. package/src/lint/post-synth/waw024.test.ts +1 -1
  44. package/src/lint/post-synth/waw025.test.ts +1 -1
  45. package/src/lint/post-synth/waw026.test.ts +1 -1
  46. package/src/lint/post-synth/waw027.test.ts +1 -1
  47. package/src/lint/post-synth/waw028.test.ts +1 -1
  48. package/src/lint/post-synth/waw029.test.ts +1 -1
  49. package/src/lint/post-synth/waw030.test.ts +1 -1
  50. package/src/lint/post-synth/waw031.test.ts +1 -1
  51. package/src/lint/post-synth/waw032.test.ts +1 -1
  52. package/src/lint/post-synth/waw033.test.ts +1 -1
  53. package/src/lint/post-synth/waw034.test.ts +1 -1
  54. package/src/lint/post-synth/waw035.test.ts +1 -1
  55. package/src/lint/post-synth/waw036.test.ts +1 -1
  56. package/src/lint/post-synth/waw037.test.ts +1 -1
  57. package/src/lint/rules/rules.test.ts +1 -1
  58. package/src/lsp/completions.test.ts +1 -1
  59. package/src/lsp/hover.test.ts +1 -1
  60. package/src/nested-stack-integration.test.ts +2 -2
  61. package/src/nested-stack.test.ts +1 -1
  62. package/src/package-cli.ts +3 -3
  63. package/src/plugin.test.ts +5 -5
  64. package/src/plugin.ts +6 -6
  65. package/src/pseudo.test.ts +1 -1
  66. package/src/serializer.test.ts +1 -1
  67. package/src/spec/fetch.test.ts +1 -1
  68. package/src/spec/parse.test.ts +1 -1
  69. package/src/spec/parse.ts +6 -0
  70. package/src/validate-cli.ts +2 -2
  71. package/src/validate.test.ts +1 -1
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { CFGenerator } from "./generator";
3
3
  import type { TemplateIR } from "@intentius/chant/import/parser";
4
4
 
@@ -15,7 +15,7 @@ export class CFGenerator implements TypeScriptGenerator {
15
15
 
16
16
  constructor() {
17
17
  // Build reverse lookup from dist/meta.json: resourceType → className
18
- const metaPath = join(import.meta.dir, "../../dist/meta.json");
18
+ const metaPath = join(import.meta.dirname, "../../dist/meta.json");
19
19
  const meta: Record<string, { resourceType: string; kind: string }> =
20
20
  require(metaPath);
21
21
  this.typeToClass = new Map();
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { CFParser } from "./parser";
3
3
 
4
4
  describe("CFParser", () => {
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { readdirSync, readFileSync, mkdtempSync, writeFileSync, mkdirSync, rmSync } from "fs";
3
3
  import { join } from "path";
4
4
  import { CFParser } from "./parser";
@@ -11,8 +11,8 @@ const awsLexicon = await import("../index");
11
11
  const parser = new CFParser();
12
12
  const generator = new CFGenerator();
13
13
 
14
- const roundtripDir = join(import.meta.dir, "../testdata/roundtrip");
15
- const samDir = join(import.meta.dir, "../testdata/sam-fixtures");
14
+ const roundtripDir = join(import.meta.dirname, "../testdata/roundtrip");
15
+ const samDir = join(import.meta.dirname, "../testdata/sam-fixtures");
16
16
 
17
17
  /** Extract imported symbols from `import { A, B } from "..."` statements */
18
18
  function extractImportedSymbols(code: string): string[] {
@@ -75,7 +75,7 @@ describe("parameters.json build roundtrip", () => {
75
75
  const mainFile = files.find((f) => f.path === "main.ts")!;
76
76
 
77
77
  // Write generated code to a temp directory inside the monorepo (so workspace packages resolve)
78
- const dir = mkdtempSync(join(import.meta.dir, "../../.roundtrip-tmp-"));
78
+ const dir = mkdtempSync(join(import.meta.dirname, "../../.roundtrip-tmp-"));
79
79
  try {
80
80
  const srcDir = join(dir, "src");
81
81
  mkdirSync(srcDir);
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { CFParser } from "./parser";
3
3
  import { CFGenerator } from "./generator";
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { awsSerializer } from "./serializer";
3
3
  import { Sub, If, Join, AWS } from "./index";
4
4
  import { Bucket, Function, Role } from "./generated/index";
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { Sub, Ref, GetAtt, If, Join, Select, Split, Base64 } from "./intrinsics";
3
3
  import { AWS } from "./pseudo";
4
4
  import { AttrRef } from "@intentius/chant/attrref";
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { createPostSynthContext } from "@intentius/chant-test-utils";
3
3
  import { ext001, checkExtensionConstraints, type ExtensionConstraint } from "./ext001";
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, expect, test } from "bun:test";
1
+ import { describe, expect, test } from "vitest";
2
2
  import { createPostSynthContext } from "@intentius/chant-test-utils";
3
3
  import { waw010 } from "./waw010";
4
4
  import { waw011 } from "./waw011";
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import type { PostSynthContext } from "@intentius/chant/lint/post-synth";
3
3
  import type { Declarable } from "@intentius/chant/declarable";
4
4
  import { CHILD_PROJECT_MARKER, type ChildProjectInstance } from "@intentius/chant/child-project";
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import type { PostSynthContext } from "@intentius/chant/lint/post-synth";
3
3
  import type { Declarable } from "@intentius/chant/declarable";
4
4
  import { CHILD_PROJECT_MARKER, type ChildProjectInstance } from "@intentius/chant/child-project";
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import type { PostSynthContext } from "@intentius/chant/lint/post-synth";
3
3
  import type { Declarable } from "@intentius/chant/declarable";
4
4
  import { CHILD_PROJECT_MARKER, type ChildProjectInstance } from "@intentius/chant/child-project";
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { createPostSynthContext } from "@intentius/chant-test-utils";
3
3
  import { waw016, checkDeprecatedProperties } from "./waw016";
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { createPostSynthContext } from "@intentius/chant-test-utils";
3
3
  import { waw017, checkMissingTags } from "./waw017";
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { createPostSynthContext } from "@intentius/chant-test-utils";
3
3
  import { waw018, checkS3PublicAccess } from "./waw018";
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { createPostSynthContext } from "@intentius/chant-test-utils";
3
3
  import { waw019, checkUnrestrictedIngress } from "./waw019";
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { createPostSynthContext } from "@intentius/chant-test-utils";
3
3
  import { waw020, checkIamWildcardAction } from "./waw020";
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { createPostSynthContext } from "@intentius/chant-test-utils";
3
3
  import { waw021, checkRdsEncryption } from "./waw021";
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { createPostSynthContext } from "@intentius/chant-test-utils";
3
3
  import { waw022, checkLambdaVpc } from "./waw022";
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { createPostSynthContext } from "@intentius/chant-test-utils";
3
3
  import { waw023, checkCloudFrontWaf } from "./waw023";
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { createPostSynthContext } from "@intentius/chant-test-utils";
3
3
  import { waw024, checkAlbAccessLogs } from "./waw024";
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { createPostSynthContext } from "@intentius/chant-test-utils";
3
3
  import { waw025, checkSnsEncryption } from "./waw025";
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { createPostSynthContext } from "@intentius/chant-test-utils";
3
3
  import { waw026, checkSqsEncryption } from "./waw026";
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { createPostSynthContext } from "@intentius/chant-test-utils";
3
3
  import { waw027, checkDynamoDbPitr } from "./waw027";
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { createPostSynthContext } from "@intentius/chant-test-utils";
3
3
  import { waw028, checkEbsEncryption } from "./waw028";
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { createPostSynthContext } from "@intentius/chant-test-utils";
3
3
  import { waw029, checkInvalidDependsOn } from "./waw029";
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { createPostSynthContext } from "@intentius/chant-test-utils";
3
3
  import { waw030, checkMissingDependsOn } from "./waw030";
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { createPostSynthContext } from "@intentius/chant-test-utils";
3
3
  import { waw031, checkAddonMissingRole } from "./waw031";
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { createPostSynthContext } from "@intentius/chant-test-utils";
3
3
  import { waw032, checkEfsTransitEncryption } from "./waw032";
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { createPostSynthContext } from "@intentius/chant-test-utils";
3
3
  import { waw033, checkSolrHeapRatio } from "./waw033";
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { createPostSynthContext } from "@intentius/chant-test-utils";
3
3
  import { waw034, checkSolrMemoryMinimum } from "./waw034";
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { createPostSynthContext } from "@intentius/chant-test-utils";
3
3
  import { waw035, checkSolrUlimits } from "./waw035";
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { createPostSynthContext } from "@intentius/chant-test-utils";
3
3
  import { waw036, checkNonAsciiProps } from "./waw036";
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { createPostSynthContext } from "@intentius/chant-test-utils";
3
3
  import { waw037, checkNullProperties } from "./waw037";
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import * as ts from "typescript";
3
3
  import { hardcodedRegionRule } from "./hardcoded-region";
4
4
  import { s3EncryptionRule } from "./s3-encryption";
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { awsCompletions } from "./completions";
3
3
  import type { CompletionContext } from "@intentius/chant/lsp/types";
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { awsHover } from "./hover";
3
3
  import type { HoverContext } from "@intentius/chant/lsp/types";
4
4
 
@@ -1,10 +1,10 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { build } from "../../../packages/core/src/build";
3
3
  import { resolve } from "path";
4
4
  import { awsSerializer } from "./serializer";
5
5
  import type { SerializerResult } from "../../../packages/core/src/serializer";
6
6
 
7
- const srcDir = resolve(import.meta.dir, "testdata/nested-stacks");
7
+ const srcDir = resolve(import.meta.dirname, "testdata/nested-stacks");
8
8
 
9
9
  describe("nested-stacks integration", () => {
10
10
  test("build produces valid CloudFormation with nested stack", async () => {
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { nestedStack, isNestedStackInstance, NestedStackOutputRef, NESTED_STACK_MARKER } from "./nested-stack";
3
3
  import { DECLARABLE_MARKER, isDeclarable } from "@intentius/chant/declarable";
4
4
  import { CHILD_PROJECT_MARKER, isChildProject } from "@intentius/chant/child-project";
@@ -1,10 +1,10 @@
1
- #!/usr/bin/env bun
1
+ #!/usr/bin/env tsx
2
2
  /**
3
- * Thin entry point for `bun run bundle` in lexicon-aws.
3
+ * Thin entry point for `npm run bundle` in lexicon-aws.
4
4
  * Generates src/generated/ files and writes dist/ bundle.
5
5
  *
6
6
  * NOTE: Does NOT call plugin.package() because that internally spawns
7
- * `bun pm pack`, which would cause infinite recursion when invoked
7
+ * `npm pack`, which would cause infinite recursion when invoked
8
8
  * from a prepack lifecycle script.
9
9
  */
10
10
  import { generate, writeGeneratedFiles } from "./codegen/generate";
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { awsPlugin } from "./plugin";
3
3
  import { isLexiconPlugin } from "@intentius/chant/lexicon";
4
4
 
@@ -189,7 +189,7 @@ describe("awsPlugin", () => {
189
189
 
190
190
  test("diff tool has correct structure", () => {
191
191
  const tools = awsPlugin.mcpTools!();
192
- const diffTool = tools.find((t) => t.name === "diff");
192
+ const diffTool = tools.find((t) => t.name === "aws:diff");
193
193
  expect(diffTool).toBeDefined();
194
194
  expect(diffTool!.description.length).toBeGreaterThan(0);
195
195
  expect(diffTool!.inputSchema.type).toBe("object");
@@ -199,7 +199,7 @@ describe("awsPlugin", () => {
199
199
 
200
200
  test("diff tool schema has path as required", () => {
201
201
  const tools = awsPlugin.mcpTools!();
202
- const diffTool = tools.find((t) => t.name === "diff")!;
202
+ const diffTool = tools.find((t) => t.name === "aws:diff")!;
203
203
  expect(diffTool.inputSchema.required).toContain("path");
204
204
  });
205
205
  });
@@ -216,7 +216,7 @@ describe("awsPlugin", () => {
216
216
 
217
217
  test("resource-catalog has correct structure", () => {
218
218
  const resources = awsPlugin.mcpResources!();
219
- const catalog = resources.find((r) => r.uri === "resource-catalog");
219
+ const catalog = resources.find((r) => r.uri === "aws:resource-catalog");
220
220
  expect(catalog).toBeDefined();
221
221
  expect(catalog!.name.length).toBeGreaterThan(0);
222
222
  expect(catalog!.description.length).toBeGreaterThan(0);
@@ -226,7 +226,7 @@ describe("awsPlugin", () => {
226
226
 
227
227
  test("resource-catalog handler returns JSON array of resources", async () => {
228
228
  const resources = awsPlugin.mcpResources!();
229
- const catalog = resources.find((r) => r.uri === "resource-catalog")!;
229
+ const catalog = resources.find((r) => r.uri === "aws:resource-catalog")!;
230
230
  const content = await catalog.handler();
231
231
 
232
232
  const parsed = JSON.parse(content) as Array<{ className: string; resourceType: string }>;
package/src/plugin.ts CHANGED
@@ -11,6 +11,10 @@ import { readFileSync } from "fs";
11
11
  import { join, dirname } from "path";
12
12
  import { fileURLToPath } from "url";
13
13
  import { awsSerializer } from "./serializer";
14
+ import { CFParser } from "./import/parser";
15
+ import { CFGenerator } from "./import/generator";
16
+ import { awsCompletions } from "./lsp/completions";
17
+ import { awsHover } from "./lsp/hover";
14
18
 
15
19
  /**
16
20
  * AWS CloudFormation lexicon plugin.
@@ -252,12 +256,10 @@ export const logsBucket = new Bucket({
252
256
  },
253
257
 
254
258
  templateParser(): TemplateParser {
255
- const { CFParser } = require("./import/parser");
256
259
  return new CFParser();
257
260
  },
258
261
 
259
262
  templateGenerator(): TypeScriptGenerator {
260
- const { CFGenerator } = require("./import/generator");
261
263
  return new CFGenerator();
262
264
  },
263
265
 
@@ -462,12 +464,10 @@ aws cloudformation wait stack-update-complete --stack-name my-app-prod`,
462
464
  ]),
463
465
 
464
466
  completionProvider(ctx: CompletionContext): CompletionItem[] {
465
- const { awsCompletions } = require("./lsp/completions");
466
467
  return awsCompletions(ctx);
467
468
  },
468
469
 
469
470
  hoverProvider(ctx: HoverContext): HoverInfo | undefined {
470
- const { awsHover } = require("./lsp/hover");
471
471
  return awsHover(ctx);
472
472
  },
473
473
 
@@ -559,7 +559,7 @@ aws cloudformation wait stack-update-complete --stack-name my-app-prod`,
559
559
  mcpTools() {
560
560
  return [
561
561
  {
562
- name: "diff",
562
+ name: "aws:diff",
563
563
  description: "Compare current build output against previous output for AWS CloudFormation",
564
564
  inputSchema: {
565
565
  type: "object" as const,
@@ -591,7 +591,7 @@ aws cloudformation wait stack-update-complete --stack-name my-app-prod`,
591
591
  mcpResources() {
592
592
  return [
593
593
  {
594
- uri: "resource-catalog",
594
+ uri: "aws:resource-catalog",
595
595
  name: "AWS Resource Catalog",
596
596
  description: "JSON list of all supported AWS CloudFormation resource types",
597
597
  mimeType: "application/json",
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import {
3
3
  AWS,
4
4
  StackName,
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { awsSerializer } from "./serializer";
3
3
  import { AttrRef } from "@intentius/chant/attrref";
4
4
  import { DECLARABLE_MARKER, type Declarable } from "@intentius/chant/declarable";
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { fetchSchemaZip } from "./fetch";
3
3
 
4
4
  describe("fetchSchemaZip", () => {
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import {
3
3
  parseCFNSchema,
4
4
  cfnShortName,
package/src/spec/parse.ts CHANGED
@@ -90,13 +90,19 @@ export function parseCFNSchema(data: string | Buffer): SchemaParseResult {
90
90
  }
91
91
 
92
92
  // Parse readOnlyProperties as attributes
93
+ // Deduplicate — some upstream schemas (e.g. aws-s3files-filesystem) list the same
94
+ // property twice in readOnlyProperties, which would produce duplicate class members.
93
95
  const attrs: ParsedAttribute[] = [];
96
+ const seenAttrs = new Set<string>();
94
97
  for (const path of schema.readOnlyProperties ?? []) {
95
98
  const attrName = stripPointerPath(path);
96
99
 
97
100
  // Flatten nested paths: "Endpoint/Address" → attr name "Endpoint.Address"
98
101
  const cfnAttr = attrName.replace(/\//g, ".");
99
102
 
103
+ if (seenAttrs.has(cfnAttr)) continue;
104
+ seenAttrs.add(cfnAttr);
105
+
100
106
  let tsType = "string";
101
107
  // For top-level attrs, look up type from properties
102
108
  if (!cfnAttr.includes(".") && schema.properties?.[cfnAttr]) {
@@ -1,6 +1,6 @@
1
- #!/usr/bin/env bun
1
+ #!/usr/bin/env tsx
2
2
  /**
3
- * Thin entry point for `bun run validate` in lexicon-aws.
3
+ * Thin entry point for `npm run validate` in lexicon-aws.
4
4
  */
5
5
  import { validate } from "./validate";
6
6
 
@@ -1,4 +1,4 @@
1
- import { describe, test, expect } from "bun:test";
1
+ import { describe, test, expect } from "vitest";
2
2
  import { validate } from "./validate";
3
3
  import { dirname } from "path";
4
4
  import { fileURLToPath } from "url";