@distilled.cloud/core 1.0.0-rc.7 → 1.0.0-rc.9

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 (57) hide show
  1. package/LICENSE +201 -0
  2. package/lib/codegen/cli.d.ts +8 -6
  3. package/lib/codegen/cli.d.ts.map +1 -1
  4. package/lib/codegen/cli.js +6 -62
  5. package/lib/codegen/cli.js.map +1 -1
  6. package/lib/codegen/graphql.d.ts +6 -0
  7. package/lib/codegen/graphql.d.ts.map +1 -1
  8. package/lib/codegen/graphql.js +14 -4
  9. package/lib/codegen/graphql.js.map +1 -1
  10. package/lib/codegen/openapi-cli.d.ts +17 -3
  11. package/lib/codegen/openapi-cli.d.ts.map +1 -1
  12. package/lib/codegen/openapi-cli.js +50 -48
  13. package/lib/codegen/openapi-cli.js.map +1 -1
  14. package/lib/codegen/openapi.d.ts +27 -1
  15. package/lib/codegen/openapi.d.ts.map +1 -1
  16. package/lib/codegen/openapi.js +81 -3
  17. package/lib/codegen/openapi.js.map +1 -1
  18. package/lib/codegen/patches.d.ts +65 -0
  19. package/lib/codegen/patches.d.ts.map +1 -0
  20. package/lib/codegen/patches.js +236 -0
  21. package/lib/codegen/patches.js.map +1 -0
  22. package/lib/codegen/patches.test.d.ts +2 -0
  23. package/lib/codegen/patches.test.d.ts.map +1 -0
  24. package/lib/codegen/patches.test.js +105 -0
  25. package/lib/codegen/patches.test.js.map +1 -0
  26. package/lib/codegen/proto.d.ts +121 -0
  27. package/lib/codegen/proto.d.ts.map +1 -0
  28. package/lib/codegen/proto.js +962 -0
  29. package/lib/codegen/proto.js.map +1 -0
  30. package/lib/codegen/rewrite-operation-ids.d.ts +131 -0
  31. package/lib/codegen/rewrite-operation-ids.d.ts.map +1 -0
  32. package/lib/codegen/rewrite-operation-ids.js +1079 -0
  33. package/lib/codegen/rewrite-operation-ids.js.map +1 -0
  34. package/lib/codegen/rewrite-operation-ids.test.d.ts +2 -0
  35. package/lib/codegen/rewrite-operation-ids.test.d.ts.map +1 -0
  36. package/lib/codegen/rewrite-operation-ids.test.js +533 -0
  37. package/lib/codegen/rewrite-operation-ids.test.js.map +1 -0
  38. package/lib/codegen/spec-path.d.ts +16 -0
  39. package/lib/codegen/spec-path.d.ts.map +1 -0
  40. package/lib/codegen/spec-path.js +101 -0
  41. package/lib/codegen/spec-path.js.map +1 -0
  42. package/lib/json-patch.d.ts +18 -11
  43. package/lib/json-patch.d.ts.map +1 -1
  44. package/lib/json-patch.js +63 -25
  45. package/lib/json-patch.js.map +1 -1
  46. package/package.json +4 -4
  47. package/src/codegen/cli.ts +14 -91
  48. package/src/codegen/graphql.ts +25 -3
  49. package/src/codegen/openapi-cli.ts +75 -59
  50. package/src/codegen/openapi.ts +118 -4
  51. package/src/codegen/patches.test.ts +130 -0
  52. package/src/codegen/patches.ts +291 -0
  53. package/src/codegen/proto.ts +1128 -0
  54. package/src/codegen/rewrite-operation-ids.test.ts +563 -0
  55. package/src/codegen/rewrite-operation-ids.ts +1206 -0
  56. package/src/codegen/spec-path.ts +115 -0
  57. package/src/json-patch.ts +82 -25
@@ -0,0 +1,65 @@
1
+ import { type JsonPatchOperation } from "../json-patch.ts";
2
+ export type OnStalePatch = "fail" | "warn";
3
+ export interface ApplyPatchesResult {
4
+ files: number;
5
+ applied: number;
6
+ stale: number;
7
+ errors: string[];
8
+ }
9
+ /** Smithy-model JSON pointers — OpenAPI has no `/shapes` tree. */
10
+ export declare const isSmithyPatchPath: (pointer: string) => boolean;
11
+ /**
12
+ * RFC-6902 files in `dir`: every `*.json`, `*.manual.json` last (those
13
+ * usually target post-rename shape names). Missing dir → `[]`.
14
+ */
15
+ export declare const listRfc6902PatchFiles: (dir: string) => Promise<string[]>;
16
+ export declare const applyRfc6902Files: (target: unknown, files: readonly string[], opts?: {
17
+ readonly onStalePatch?: OnStalePatch;
18
+ readonly include?: (op: JsonPatchOperation) => boolean;
19
+ readonly label?: (file: string) => string;
20
+ }) => Promise<ApplyPatchesResult>;
21
+ /**
22
+ * An RFC-6902 `move` that renames an operation shape leaves the service's
23
+ * `operations` list pointing at the old id. Drop entries whose target no
24
+ * longer exists and append operation shapes the list is missing, keeping
25
+ * the existing order. Returns the number of services whose list changed.
26
+ */
27
+ export declare const syncServiceOperations: (model: {
28
+ shapes?: Record<string, any>;
29
+ }) => number;
30
+ /**
31
+ * Every `target` in a Smithy model must resolve to a shape or a prelude
32
+ * (`smithy.api#…`) id. Returns the dangling ones as `"<owner> → <target>"`.
33
+ * A convert that produces any is broken — generate would emit references
34
+ * to types that do not exist.
35
+ */
36
+ export declare const danglingTargets: (model: {
37
+ shapes?: Record<string, any>;
38
+ }) => string[];
39
+ /**
40
+ * Last step of every convert: Smithy RFC-6902 patches, then verbNoun
41
+ * operation names, then an optional model transform, then a reference
42
+ * check. Writes models back so `.generated-specs` is what generate
43
+ * compiles. `outDir` may be nested (GCP `stable/` / `unstable/`).
44
+ *
45
+ * Input must be FRESHLY converted models. Smithy patches are `move`/`add`
46
+ * ops that are not idempotent, and a `transform` may not be either, so
47
+ * running this over a model that already went through it is an error —
48
+ * re-run the package's `convert` instead.
49
+ */
50
+ export declare const finalizeConvert: (o: {
51
+ readonly root: string;
52
+ readonly outDir?: string;
53
+ readonly patchesDir?: string | false;
54
+ readonly exclude?: (file: string) => boolean;
55
+ readonly include?: (resource: string) => boolean;
56
+ readonly transform?: (model: any, resource: string) => string | void;
57
+ readonly operationNaming?: "as-is" | "verbNoun";
58
+ readonly onStalePatch?: OnStalePatch;
59
+ }) => Promise<void>;
60
+ /**
61
+ * Metadata marker stamped by {@link finalizeConvert}. Guards against a
62
+ * second pass over the same file (see the note on finalizeConvert).
63
+ */
64
+ export declare const FINALIZED_KEY = "distilled.finalized";
65
+ //# sourceMappingURL=patches.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patches.d.ts","sourceRoot":"","sources":["../../src/codegen/patches.ts"],"names":[],"mappings":"AAUA,OAAO,EAGL,KAAK,kBAAkB,EAExB,MAAM,kBAAkB,CAAC;AAG1B,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,CAAC;AAE3C,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,kEAAkE;AAClE,eAAO,MAAM,iBAAiB,YAAa,MAAM,KAAG,OAGrB,CAAC;AAWhC;;;GAGG;AACH,eAAO,MAAM,qBAAqB,QAAe,MAAM,KAAG,OAAO,CAAC,MAAM,EAAE,CAUzE,CAAC;AAEF,eAAO,MAAM,iBAAiB,WACpB,OAAO,SACR,SAAS,MAAM,EAAE,SAClB;IACJ,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;IACrC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,kBAAkB,KAAK,OAAO,CAAC;IACvD,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CAC3C,KACA,OAAO,CAAC,kBAAkB,CAmC5B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,UAAW;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC9B,KAAG,MAqBH,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,eAAe,UAAW;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC9B,KAAG,MAAM,EAwBT,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,eAAe,MAAa;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACrC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IAC7C,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;IACjD,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IACrE,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IAChD,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;CACtC,KAAG,OAAO,CAAC,IAAI,CAgGf,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,wBAAwB,CAAC"}
@@ -0,0 +1,236 @@
1
+ /**
2
+ * RFC-6902 patch application for convert (dev-time only).
3
+ *
4
+ * OpenAPI ops (`/paths`, `/components`, …) apply to the spec before
5
+ * conversion; Smithy ops (`/shapes`, `/metadata`, `/smithy`) apply to the
6
+ * model after conversion. `.generated-specs` is the patched model.
7
+ * `scripts/generate.ts` does not apply patches.
8
+ */
9
+ import * as fs from "node:fs/promises";
10
+ import * as path from "node:path";
11
+ import { applyOperation, isStaleTargetError, } from "../json-patch.js";
12
+ import { verbNounSmithyModel } from "./rewrite-operation-ids.js";
13
+ /** Smithy-model JSON pointers — OpenAPI has no `/shapes` tree. */
14
+ export const isSmithyPatchPath = (pointer) => pointer.startsWith("/shapes") ||
15
+ pointer.startsWith("/metadata") ||
16
+ pointer.startsWith("/smithy");
17
+ const exists = async (p) => {
18
+ try {
19
+ await fs.access(p);
20
+ return true;
21
+ }
22
+ catch {
23
+ return false;
24
+ }
25
+ };
26
+ /**
27
+ * RFC-6902 files in `dir`: every `*.json`, `*.manual.json` last (those
28
+ * usually target post-rename shape names). Missing dir → `[]`.
29
+ */
30
+ export const listRfc6902PatchFiles = async (dir) => {
31
+ if (!(await exists(dir)))
32
+ return [];
33
+ return (await fs.readdir(dir))
34
+ .filter((f) => f.endsWith(".json"))
35
+ .sort((a, b) => Number(a.endsWith(".manual.json")) -
36
+ Number(b.endsWith(".manual.json")) || a.localeCompare(b))
37
+ .map((f) => path.join(dir, f));
38
+ };
39
+ export const applyRfc6902Files = async (target, files, opts = {}) => {
40
+ const onStalePatch = opts.onStalePatch ?? "fail";
41
+ const include = opts.include ?? (() => true);
42
+ const result = {
43
+ files: 0,
44
+ applied: 0,
45
+ stale: 0,
46
+ errors: [],
47
+ };
48
+ for (const file of files) {
49
+ const parsed = JSON.parse(await fs.readFile(file, "utf8"));
50
+ const label = opts.label?.(file) ?? path.basename(file);
51
+ result.files++;
52
+ for (const patchOp of parsed.patches ?? []) {
53
+ if (!include(patchOp))
54
+ continue;
55
+ try {
56
+ applyOperation(target, patchOp);
57
+ result.applied++;
58
+ }
59
+ catch (e) {
60
+ const msg = e instanceof Error ? e.message : String(e);
61
+ const line = `${label} [${patchOp.op} ${patchOp.path}]`;
62
+ if (isStaleTargetError(e)) {
63
+ result.stale++;
64
+ if (onStalePatch === "fail") {
65
+ result.errors.push(`${line}: stale target (${msg})`);
66
+ }
67
+ else {
68
+ console.warn(` ⚠️ stale: ${line}`);
69
+ }
70
+ }
71
+ else {
72
+ result.errors.push(`${line}: ${msg}`);
73
+ }
74
+ }
75
+ }
76
+ }
77
+ return result;
78
+ };
79
+ /**
80
+ * An RFC-6902 `move` that renames an operation shape leaves the service's
81
+ * `operations` list pointing at the old id. Drop entries whose target no
82
+ * longer exists and append operation shapes the list is missing, keeping
83
+ * the existing order. Returns the number of services whose list changed.
84
+ */
85
+ export const syncServiceOperations = (model) => {
86
+ const shapes = model.shapes ?? {};
87
+ const opIds = Object.keys(shapes).filter((id) => shapes[id]?.type === "operation");
88
+ let changed = 0;
89
+ for (const def of Object.values(shapes)) {
90
+ if (def?.type !== "service")
91
+ continue;
92
+ const current = def.operations ?? [];
93
+ const kept = current.filter((o) => shapes[o.target]?.type === "operation");
94
+ const listed = new Set(kept.map((o) => o.target));
95
+ const after = [
96
+ ...kept,
97
+ ...opIds.filter((id) => !listed.has(id)).map((target) => ({ target })),
98
+ ];
99
+ if (JSON.stringify(current) !== JSON.stringify(after)) {
100
+ def.operations = after;
101
+ changed++;
102
+ }
103
+ }
104
+ return changed;
105
+ };
106
+ /**
107
+ * Every `target` in a Smithy model must resolve to a shape or a prelude
108
+ * (`smithy.api#…`) id. Returns the dangling ones as `"<owner> → <target>"`.
109
+ * A convert that produces any is broken — generate would emit references
110
+ * to types that do not exist.
111
+ */
112
+ export const danglingTargets = (model) => {
113
+ const shapes = model.shapes ?? {};
114
+ const ids = new Set(Object.keys(shapes));
115
+ const out = [];
116
+ const walk = (owner, node) => {
117
+ if (Array.isArray(node)) {
118
+ for (const item of node)
119
+ walk(owner, item);
120
+ return;
121
+ }
122
+ if (node === null || typeof node !== "object")
123
+ return;
124
+ for (const [key, value] of Object.entries(node)) {
125
+ if (key === "target" && typeof value === "string") {
126
+ if (!value.startsWith("smithy.") && !ids.has(value)) {
127
+ out.push(`${owner} → ${value}`);
128
+ }
129
+ }
130
+ else {
131
+ walk(owner, value);
132
+ }
133
+ }
134
+ };
135
+ for (const [id, def] of Object.entries(shapes))
136
+ walk(id, def);
137
+ return out;
138
+ };
139
+ /**
140
+ * Last step of every convert: Smithy RFC-6902 patches, then verbNoun
141
+ * operation names, then an optional model transform, then a reference
142
+ * check. Writes models back so `.generated-specs` is what generate
143
+ * compiles. `outDir` may be nested (GCP `stable/` / `unstable/`).
144
+ *
145
+ * Input must be FRESHLY converted models. Smithy patches are `move`/`add`
146
+ * ops that are not idempotent, and a `transform` may not be either, so
147
+ * running this over a model that already went through it is an error —
148
+ * re-run the package's `convert` instead.
149
+ */
150
+ export const finalizeConvert = async (o) => {
151
+ const specsDir = path.resolve(o.root, o.outDir ?? ".generated-specs");
152
+ if (!(await exists(specsDir)))
153
+ return;
154
+ const patchesDir = o.patchesDir === false
155
+ ? undefined
156
+ : path.resolve(o.root, o.patchesDir ?? "patches");
157
+ const naming = o.operationNaming ?? "verbNoun";
158
+ const walk = async (dir) => {
159
+ const out = [];
160
+ for (const ent of await fs.readdir(dir, { withFileTypes: true })) {
161
+ const p = path.join(dir, ent.name);
162
+ if (ent.isDirectory()) {
163
+ out.push(...(await walk(p)));
164
+ }
165
+ else if (ent.name.endsWith(".json") &&
166
+ !(o.exclude?.(ent.name) ?? false)) {
167
+ out.push(p);
168
+ }
169
+ }
170
+ return out;
171
+ };
172
+ const files = (await walk(specsDir)).sort((a, b) => a.localeCompare(b));
173
+ const broken = [];
174
+ for (const modelPath of files) {
175
+ const resource = path.basename(modelPath, ".json");
176
+ if (o.include && !o.include(resource))
177
+ continue;
178
+ const model = JSON.parse(await fs.readFile(modelPath, "utf8"));
179
+ if (model.metadata?.[FINALIZED_KEY]) {
180
+ throw new Error(`${path.relative(o.root, modelPath)} was already finalized — finalizeConvert is not idempotent; re-run this package's convert from the spec instead`);
181
+ }
182
+ if (patchesDir) {
183
+ const patchFiles = await listRfc6902PatchFiles(path.join(patchesDir, resource));
184
+ const applied = await applyRfc6902Files(model, patchFiles, {
185
+ onStalePatch: o.onStalePatch,
186
+ include: (op) => isSmithyPatchPath(op.path),
187
+ label: (f) => `${resource}/${path.basename(f)}`,
188
+ });
189
+ if (applied.errors.length) {
190
+ for (const err of applied.errors)
191
+ console.error(`❌ bad patch: ${err}`);
192
+ throw new Error(`${applied.errors.length} patch operation(s) failed for ${resource} — fix the pointers or delete the patch`);
193
+ }
194
+ if (applied.applied > 0) {
195
+ console.log(` patched ${resource}: ${applied.files} file(s), ${applied.applied} op(s)` +
196
+ (applied.stale ? `, ${applied.stale} stale` : ""));
197
+ }
198
+ }
199
+ if (naming === "verbNoun") {
200
+ const { renamed, collisions } = verbNounSmithyModel(model);
201
+ if (renamed > 0) {
202
+ console.log(` verbNoun ${resource}: renamed ${renamed} operation(s)`);
203
+ }
204
+ for (const c of collisions) {
205
+ console.warn(` ⚠️ verbNoun collision ${resource}: ${c} (kept original)`);
206
+ }
207
+ }
208
+ const note = o.transform?.(model, resource);
209
+ if (note)
210
+ console.log(` ${note}`);
211
+ syncServiceOperations(model);
212
+ const dangling = danglingTargets(model);
213
+ if (dangling.length) {
214
+ broken.push(`${resource}: ${dangling.length} dangling target(s)`);
215
+ for (const d of dangling.slice(0, 5))
216
+ console.error(` ❌ ${d}`);
217
+ if (dangling.length > 5) {
218
+ console.error(` … ${dangling.length - 5} more`);
219
+ }
220
+ // Leave the unfinalized model on disk for inspection; never stamp
221
+ // a model that generate cannot compile.
222
+ continue;
223
+ }
224
+ model.metadata = { ...model.metadata, [FINALIZED_KEY]: true };
225
+ await fs.writeFile(modelPath, `${JSON.stringify(model, null, 2)}\n`);
226
+ }
227
+ if (broken.length) {
228
+ throw new Error(`finalizeConvert: ${broken.length} model(s) reference shapes that do not exist:\n ${broken.join("\n ")}`);
229
+ }
230
+ };
231
+ /**
232
+ * Metadata marker stamped by {@link finalizeConvert}. Guards against a
233
+ * second pass over the same file (see the note on finalizeConvert).
234
+ */
235
+ export const FINALIZED_KEY = "distilled.finalized";
236
+ //# sourceMappingURL=patches.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patches.js","sourceRoot":"","sources":["../../src/codegen/patches.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=patches.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patches.test.d.ts","sourceRoot":"","sources":["../../src/codegen/patches.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,105 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import { mkdtempSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { FINALIZED_KEY, danglingTargets, finalizeConvert, syncServiceOperations, } from "./patches.js";
6
+ const model = () => ({
7
+ smithy: "2.0",
8
+ shapes: {
9
+ "ns#Svc": {
10
+ type: "service",
11
+ operations: [{ target: "ns#AppsList" }, { target: "ns#AppsGet" }],
12
+ },
13
+ "ns#AppsList": {
14
+ type: "operation",
15
+ input: { target: "ns#AppsListRequest" },
16
+ output: { target: "smithy.api#Unit" },
17
+ },
18
+ "ns#AppsListRequest": { type: "structure", members: {} },
19
+ "ns#AppsGet": {
20
+ type: "operation",
21
+ input: { target: "smithy.api#Unit" },
22
+ output: { target: "smithy.api#Unit" },
23
+ },
24
+ },
25
+ });
26
+ const scaffold = (patches) => {
27
+ const root = mkdtempSync(join(tmpdir(), "finalize-"));
28
+ mkdirSync(join(root, ".generated-specs"));
29
+ writeFileSync(join(root, ".generated-specs", "svc.json"), JSON.stringify(model()));
30
+ if (patches) {
31
+ mkdirSync(join(root, "patches", "svc"), { recursive: true });
32
+ writeFileSync(join(root, "patches", "svc", "a.json"), JSON.stringify(patches));
33
+ }
34
+ return root;
35
+ };
36
+ const read = (root) => JSON.parse(readFileSync(join(root, ".generated-specs", "svc.json"), "utf8"));
37
+ describe("finalizeConvert", () => {
38
+ test("renames, syncs the service list, stamps the marker", async () => {
39
+ const root = scaffold();
40
+ await finalizeConvert({ root });
41
+ const m = read(root);
42
+ expect(Object.keys(m.shapes).sort()).toEqual(["ns#Svc", "ns#ListApps", "ns#ListAppsRequest", "ns#GetApp"].sort());
43
+ expect(m.shapes["ns#Svc"].operations).toEqual([
44
+ { target: "ns#ListApps" },
45
+ { target: "ns#GetApp" },
46
+ ]);
47
+ expect(m.metadata[FINALIZED_KEY]).toBe(true);
48
+ });
49
+ test("refuses a second pass", async () => {
50
+ const root = scaffold();
51
+ await finalizeConvert({ root });
52
+ await expect(finalizeConvert({ root })).rejects.toThrow(/already finalized/);
53
+ });
54
+ test("applies Smithy patches and repairs the service list after a move", async () => {
55
+ const root = scaffold({
56
+ patches: [
57
+ { op: "move", from: "/shapes/ns#AppsGet", path: "/shapes/ns#FetchApp" },
58
+ ],
59
+ });
60
+ await finalizeConvert({ root });
61
+ const m = read(root);
62
+ expect(m.shapes["ns#FetchApp"]).toBeDefined();
63
+ expect(m.shapes["ns#Svc"].operations.map((o) => o.target)).toEqual([
64
+ "ns#ListApps",
65
+ "ns#FetchApp",
66
+ ]);
67
+ });
68
+ test("fails on a stale patch pointer by default", async () => {
69
+ const root = scaffold({
70
+ patches: [{ op: "remove", path: "/shapes/ns#Missing" }],
71
+ });
72
+ await expect(finalizeConvert({ root })).rejects.toThrow(/failed/);
73
+ });
74
+ test("fails on dangling targets and leaves the model unstamped", async () => {
75
+ const root = scaffold({
76
+ patches: [
77
+ {
78
+ op: "replace",
79
+ path: "/shapes/ns#AppsList/output/target",
80
+ value: "ns#Nope",
81
+ },
82
+ ],
83
+ });
84
+ await expect(finalizeConvert({ root })).rejects.toThrow(/do not exist/);
85
+ expect(read(root).metadata?.[FINALIZED_KEY]).toBeUndefined();
86
+ });
87
+ });
88
+ describe("danglingTargets", () => {
89
+ test("ignores prelude ids", () => {
90
+ expect(danglingTargets(model())).toEqual([]);
91
+ });
92
+ });
93
+ describe("syncServiceOperations", () => {
94
+ test("drops missing and appends unlisted, keeping order", () => {
95
+ const m = model();
96
+ delete m.shapes["ns#AppsGet"];
97
+ m.shapes["ns#Zed"] = { type: "operation" };
98
+ expect(syncServiceOperations(m)).toBe(1);
99
+ expect(m.shapes["ns#Svc"].operations).toEqual([
100
+ { target: "ns#AppsList" },
101
+ { target: "ns#Zed" },
102
+ ]);
103
+ });
104
+ });
105
+ //# sourceMappingURL=patches.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patches.test.js","sourceRoot":"","sources":["../../src/codegen/patches.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Proto3 → Smithy 2.0 JSON converter (dev-time only, provider-agnostic).
3
+ *
4
+ * Turns one or more `.proto` files (a package of messages, enums, and gRPC
5
+ * services) into the same Smithy JSON model shape the other spec converters
6
+ * produce (`{ smithy: "2.0", metadata, shapes }`), so a proto-sourced
7
+ * provider flows through the shared `generateService` compiler.
8
+ *
9
+ * Mapping (proto3 JSON encoding on the wire):
10
+ *
11
+ * • each selected unary `rpc` → a Smithy operation, `POST /<package>.<Service>/<Method>`
12
+ * • request/response messages → structures; members are camelCase (proto3 JSON)
13
+ * • `repeated` → list, `map<k,v>` → map (JSON object keys are strings)
14
+ * • `oneof` fields flatten onto the parent (proto3 JSON is untagged)
15
+ * • enums → string enums (proto3 JSON emits the name)
16
+ * • 64-bit integers → `smithy.api#String` (proto3 JSON encodes them as strings)
17
+ * • `bytes` → `smithy.api#Blob` (base64 on the JSON wire)
18
+ * • `google.protobuf.Empty` I/O → `smithy.api#Unit`
19
+ * • streaming RPCs are skipped by default (they are not request/response POSTs)
20
+ *
21
+ * The converter does not speak binary protobuf. Generated SDKs send proto3
22
+ * JSON at the gRPC method path — Connect-JSON / grpc-JSON transcoding shape.
23
+ */
24
+ export declare const PRELUDE: {
25
+ readonly String: "smithy.api#String";
26
+ readonly Boolean: "smithy.api#Boolean";
27
+ readonly Integer: "smithy.api#Integer";
28
+ readonly Long: "smithy.api#Long";
29
+ readonly Float: "smithy.api#Float";
30
+ readonly Double: "smithy.api#Double";
31
+ readonly Timestamp: "smithy.api#Timestamp";
32
+ readonly Blob: "smithy.api#Blob";
33
+ readonly Document: "smithy.api#Document";
34
+ readonly Unit: "smithy.api#Unit";
35
+ };
36
+ export interface ProtoField {
37
+ readonly name: string;
38
+ readonly type: string;
39
+ readonly repeated: boolean;
40
+ readonly optional: boolean;
41
+ readonly mapKey?: string;
42
+ readonly mapValue?: string;
43
+ readonly jsonName?: string;
44
+ readonly deprecated: boolean;
45
+ readonly documentation?: string;
46
+ }
47
+ export interface ProtoEnumValue {
48
+ readonly name: string;
49
+ readonly number: number;
50
+ readonly deprecated: boolean;
51
+ readonly documentation?: string;
52
+ }
53
+ export interface ProtoEnum {
54
+ readonly name: string;
55
+ readonly fullName: string;
56
+ readonly values: ProtoEnumValue[];
57
+ readonly documentation?: string;
58
+ }
59
+ export interface ProtoMessage {
60
+ readonly name: string;
61
+ readonly fullName: string;
62
+ readonly fields: ProtoField[];
63
+ readonly messages: ProtoMessage[];
64
+ readonly enums: ProtoEnum[];
65
+ readonly documentation?: string;
66
+ }
67
+ export interface ProtoRpc {
68
+ readonly name: string;
69
+ readonly requestType: string;
70
+ readonly responseType: string;
71
+ readonly requestStream: boolean;
72
+ readonly responseStream: boolean;
73
+ readonly deprecated: boolean;
74
+ readonly documentation?: string;
75
+ }
76
+ export interface ProtoService {
77
+ readonly name: string;
78
+ readonly fullName: string;
79
+ readonly rpcs: ProtoRpc[];
80
+ readonly documentation?: string;
81
+ }
82
+ export interface ProtoFile {
83
+ readonly filename: string;
84
+ readonly package: string;
85
+ readonly syntax: string;
86
+ readonly imports: string[];
87
+ readonly messages: ProtoMessage[];
88
+ readonly enums: ProtoEnum[];
89
+ readonly services: ProtoService[];
90
+ }
91
+ export interface ProtoConvertOptions {
92
+ readonly files: readonly ProtoFile[];
93
+ readonly namespace: string;
94
+ readonly serviceName: string;
95
+ readonly serviceTitle?: string;
96
+ readonly serviceDocumentation?: string;
97
+ readonly serviceVersion?: string;
98
+ /** Fully-qualified proto service (`modal.client.ModalClient`). */
99
+ readonly protoService: string;
100
+ /** Keep only these RPC names. Default: every unary RPC. */
101
+ readonly rpcNames?: ReadonlySet<string>;
102
+ readonly skipStreaming?: boolean;
103
+ readonly skipDeprecated?: boolean;
104
+ }
105
+ export interface ProtoConvertResult {
106
+ readonly model: {
107
+ smithy: "2.0";
108
+ metadata: Record<string, unknown>;
109
+ shapes: Record<string, any>;
110
+ };
111
+ readonly converted: number;
112
+ readonly skippedStreaming: number;
113
+ readonly skippedDeprecated: number;
114
+ readonly shapeCount: number;
115
+ }
116
+ /** Parse a proto3 source file into an AST. */
117
+ export declare const parseProto: (text: string, filename?: string) => ProtoFile;
118
+ /** Leading PascalCase token of an RPC name (`AppCreate` → `App`). */
119
+ export declare const rpcGroupName: (rpcName: string) => string;
120
+ export declare const convertProtoToSmithy: (options: ProtoConvertOptions) => ProtoConvertResult;
121
+ //# sourceMappingURL=proto.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proto.d.ts","sourceRoot":"","sources":["../../src/codegen/proto.ts"],"names":[],"mappings":"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"}