@workos/oagen 0.1.1 → 0.2.0
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.
- package/dist/cli/index.d.mts +2 -0
- package/dist/cli/index.mjs +6018 -0
- package/dist/cli/index.mjs.map +1 -0
- package/dist/compat/{index.d.ts → index.d.mts} +43 -114
- package/dist/compat/index.d.mts.map +1 -0
- package/dist/compat/index.mjs +4562 -0
- package/dist/compat/index.mjs.map +1 -0
- package/dist/diff-DyQF4sel.mjs +2250 -0
- package/dist/diff-DyQF4sel.mjs.map +1 -0
- package/dist/differ-BwelBJN0.mjs +1100 -0
- package/dist/differ-BwelBJN0.mjs.map +1 -0
- package/dist/index.d.mts +295 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +1553 -0
- package/dist/index.mjs.map +1 -0
- package/dist/scripts/smoke/baseline.d.mts +1 -0
- package/dist/scripts/smoke/baseline.mjs +1916 -0
- package/dist/scripts/smoke/baseline.mjs.map +1 -0
- package/dist/scripts/smoke/sdk-test.d.mts +1 -0
- package/dist/scripts/smoke/sdk-test.mjs +111 -0
- package/dist/scripts/smoke/sdk-test.mjs.map +1 -0
- package/dist/smoke.d.mts +331 -0
- package/dist/smoke.d.mts.map +1 -0
- package/dist/smoke.mjs +2084 -0
- package/dist/smoke.mjs.map +1 -0
- package/dist/tree-sitter-BPNfbEzY.mjs +359 -0
- package/dist/tree-sitter-BPNfbEzY.mjs.map +1 -0
- package/dist/types-O25qZxMl.d.mts +397 -0
- package/dist/types-O25qZxMl.d.mts.map +1 -0
- package/dist/verify/index.d.mts +82 -0
- package/dist/verify/index.d.mts.map +1 -0
- package/dist/verify/index.mjs +327 -0
- package/dist/verify/index.mjs.map +1 -0
- package/package.json +19 -16
- package/dist/chunk-2JXFTDTO.js +0 -1669
- package/dist/chunk-CIX5NOBF.js +0 -263
- package/dist/chunk-IJ5E5AE7.js +0 -1040
- package/dist/cli/index.js +0 -5322
- package/dist/compat/index.js +0 -4491
- package/dist/index.d.ts +0 -277
- package/dist/index.js +0 -1565
- package/dist/scripts/smoke/baseline.js +0 -1813
- package/dist/scripts/smoke/sdk-test.js +0 -93
- package/dist/smoke.js +0 -2025
- package/dist/types-B5t9O9Wm.d.ts +0 -367
- package/dist/verify/index.d.ts +0 -76
- package/dist/verify/index.js +0 -336
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
//#region src/ir/types.ts
|
|
2
|
+
/**
|
|
3
|
+
* Exhaustive check helper for TypeRef switches.
|
|
4
|
+
* If a new kind is added to TypeRef, any switch that doesn't handle it
|
|
5
|
+
* will fail to compile because `never` won't accept the unhandled variant.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* switch (ref.kind) {
|
|
9
|
+
* case 'primitive': ...
|
|
10
|
+
* case 'array': ...
|
|
11
|
+
* // If you forget 'literal', TypeScript errors here:
|
|
12
|
+
* default: assertNever(ref);
|
|
13
|
+
* }
|
|
14
|
+
*/
|
|
15
|
+
function assertNever(x) {
|
|
16
|
+
const kind = x.kind;
|
|
17
|
+
const err = /* @__PURE__ */ new Error(`Unexpected TypeRef kind: ${kind}\nHint: If you added a new TypeRef variant, handle it in every switch/case that calls assertNever.`);
|
|
18
|
+
err.name = "InternalError";
|
|
19
|
+
throw err;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Generic depth-first walker for TypeRef trees.
|
|
23
|
+
* Handles recursion into array/nullable/union/map children and provides
|
|
24
|
+
* an exhaustive `assertNever` check so callers don't need to repeat the
|
|
25
|
+
* switch boilerplate. Supply callbacks only for the leaf kinds you care about.
|
|
26
|
+
*/
|
|
27
|
+
function walkTypeRef(ref, visitor) {
|
|
28
|
+
switch (ref.kind) {
|
|
29
|
+
case "model":
|
|
30
|
+
visitor.model?.(ref);
|
|
31
|
+
break;
|
|
32
|
+
case "enum":
|
|
33
|
+
visitor.enum?.(ref);
|
|
34
|
+
break;
|
|
35
|
+
case "array":
|
|
36
|
+
walkTypeRef(ref.items, visitor);
|
|
37
|
+
break;
|
|
38
|
+
case "nullable":
|
|
39
|
+
walkTypeRef(ref.inner, visitor);
|
|
40
|
+
break;
|
|
41
|
+
case "union":
|
|
42
|
+
for (const v of ref.variants) walkTypeRef(v, visitor);
|
|
43
|
+
break;
|
|
44
|
+
case "map":
|
|
45
|
+
if (ref.keyType) walkTypeRef(ref.keyType, visitor);
|
|
46
|
+
walkTypeRef(ref.valueType, visitor);
|
|
47
|
+
break;
|
|
48
|
+
case "literal":
|
|
49
|
+
visitor.literal?.(ref);
|
|
50
|
+
break;
|
|
51
|
+
case "primitive":
|
|
52
|
+
visitor.primitive?.(ref);
|
|
53
|
+
break;
|
|
54
|
+
default: assertNever(ref);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Generic depth-first mapper for TypeRef trees.
|
|
59
|
+
* Like walkTypeRef but returns a transformed value instead of void.
|
|
60
|
+
* Handles recursion into array/nullable/union/map children, passing
|
|
61
|
+
* already-mapped child values to the parent callback.
|
|
62
|
+
*/
|
|
63
|
+
function mapTypeRef(ref, mapper) {
|
|
64
|
+
switch (ref.kind) {
|
|
65
|
+
case "primitive": return mapper.primitive(ref);
|
|
66
|
+
case "array": return mapper.array(ref, mapTypeRef(ref.items, mapper));
|
|
67
|
+
case "model": return mapper.model(ref);
|
|
68
|
+
case "enum": return mapper.enum(ref);
|
|
69
|
+
case "union": return mapper.union(ref, ref.variants.map((v) => mapTypeRef(v, mapper)));
|
|
70
|
+
case "nullable": return mapper.nullable(ref, mapTypeRef(ref.inner, mapper));
|
|
71
|
+
case "literal": return mapper.literal(ref);
|
|
72
|
+
case "map": return mapper.map(ref, mapTypeRef(ref.valueType, mapper), ref.keyType ? mapTypeRef(ref.keyType, mapper) : void 0);
|
|
73
|
+
default: return assertNever(ref);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Collect all model names referenced (directly or transitively) by a TypeRef.
|
|
78
|
+
*/
|
|
79
|
+
function collectModelRefs(ref) {
|
|
80
|
+
const names = [];
|
|
81
|
+
walkTypeRef(ref, { model: (r) => names.push(r.name) });
|
|
82
|
+
return names;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Collect all enum names referenced by a TypeRef.
|
|
86
|
+
*/
|
|
87
|
+
function collectEnumRefs(ref) {
|
|
88
|
+
const names = [];
|
|
89
|
+
walkTypeRef(ref, { enum: (r) => names.push(r.name) });
|
|
90
|
+
return names;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Collect all TypeRef-referenced model and enum names from a model's fields.
|
|
94
|
+
* Returns { models, enums } sets for generating import statements.
|
|
95
|
+
*/
|
|
96
|
+
function collectFieldDependencies(model) {
|
|
97
|
+
const models = /* @__PURE__ */ new Set();
|
|
98
|
+
const enums = /* @__PURE__ */ new Set();
|
|
99
|
+
for (const field of model.fields) {
|
|
100
|
+
for (const name of collectModelRefs(field.type)) if (name !== model.name) models.add(name);
|
|
101
|
+
for (const name of collectEnumRefs(field.type)) enums.add(name);
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
models,
|
|
105
|
+
enums
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Assign each model to the service that first references it.
|
|
110
|
+
* Models referenced by multiple services are assigned to the first.
|
|
111
|
+
* Models not referenced by any service are unassigned (absent from the map).
|
|
112
|
+
*/
|
|
113
|
+
function assignModelsToServices(models, services) {
|
|
114
|
+
const modelToService = /* @__PURE__ */ new Map();
|
|
115
|
+
const modelNames = new Set(models.map((m) => m.name));
|
|
116
|
+
for (const service of services) {
|
|
117
|
+
const referencedModels = /* @__PURE__ */ new Set();
|
|
118
|
+
for (const op of service.operations) {
|
|
119
|
+
if (op.requestBody) for (const name of collectModelRefs(op.requestBody)) referencedModels.add(name);
|
|
120
|
+
for (const name of collectModelRefs(op.response)) referencedModels.add(name);
|
|
121
|
+
for (const param of [
|
|
122
|
+
...op.pathParams,
|
|
123
|
+
...op.queryParams,
|
|
124
|
+
...op.headerParams,
|
|
125
|
+
...op.cookieParams ?? []
|
|
126
|
+
]) for (const name of collectModelRefs(param.type)) referencedModels.add(name);
|
|
127
|
+
if (op.pagination) for (const name of collectModelRefs(op.pagination.itemType)) referencedModels.add(name);
|
|
128
|
+
}
|
|
129
|
+
const toVisit = [...referencedModels];
|
|
130
|
+
while (toVisit.length > 0) {
|
|
131
|
+
const name = toVisit.pop();
|
|
132
|
+
const model = models.find((m) => m.name === name);
|
|
133
|
+
if (!model) continue;
|
|
134
|
+
for (const field of model.fields) for (const ref of collectModelRefs(field.type)) if (!referencedModels.has(ref) && modelNames.has(ref)) {
|
|
135
|
+
referencedModels.add(ref);
|
|
136
|
+
toVisit.push(ref);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
for (const name of referencedModels) if (!modelToService.has(name)) modelToService.set(name, service.name);
|
|
140
|
+
}
|
|
141
|
+
return modelToService;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Collect all model names referenced as request bodies across all services.
|
|
145
|
+
*/
|
|
146
|
+
function collectRequestBodyModels(services) {
|
|
147
|
+
const result = /* @__PURE__ */ new Set();
|
|
148
|
+
for (const service of services) for (const op of service.operations) if (op.requestBody) for (const name of collectModelRefs(op.requestBody)) result.add(name);
|
|
149
|
+
return result;
|
|
150
|
+
}
|
|
151
|
+
//#endregion
|
|
152
|
+
//#region src/errors.ts
|
|
153
|
+
/**
|
|
154
|
+
* Structured error hierarchy for oagen.
|
|
155
|
+
*
|
|
156
|
+
* Every error carries a human-readable `hint` that suggests a recovery action.
|
|
157
|
+
* The hint is appended to the `message` so it appears in stack traces and logs.
|
|
158
|
+
*/
|
|
159
|
+
/** Base class for all oagen errors. */
|
|
160
|
+
var OagenError = class extends Error {
|
|
161
|
+
hint;
|
|
162
|
+
constructor(message, hint) {
|
|
163
|
+
const fullMessage = hint ? `${message}\nHint: ${hint}` : message;
|
|
164
|
+
super(fullMessage);
|
|
165
|
+
this.name = "OagenError";
|
|
166
|
+
this.hint = hint;
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
/** Thrown when a command should terminate with a specific exit code. */
|
|
170
|
+
var CommandError = class extends OagenError {
|
|
171
|
+
exitCode;
|
|
172
|
+
constructor(message, hint, exitCode) {
|
|
173
|
+
super(message, hint);
|
|
174
|
+
this.name = "CommandError";
|
|
175
|
+
this.exitCode = exitCode;
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
/** Thrown when an OpenAPI spec cannot be parsed or has an unsupported version. */
|
|
179
|
+
var SpecParseError = class extends OagenError {
|
|
180
|
+
constructor(message, hint) {
|
|
181
|
+
super(message, hint);
|
|
182
|
+
this.name = "SpecParseError";
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
/** Thrown when configuration files (manifests, API surfaces, overlays) are missing or malformed. */
|
|
186
|
+
var ConfigError = class extends OagenError {
|
|
187
|
+
constructor(message, hint) {
|
|
188
|
+
super(message, hint);
|
|
189
|
+
this.name = "ConfigError";
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
/** Thrown when a config file exists but cannot be loaded or evaluated. */
|
|
193
|
+
var ConfigLoadError = class extends ConfigError {
|
|
194
|
+
constructor(message, hint) {
|
|
195
|
+
super(message, hint);
|
|
196
|
+
this.name = "ConfigLoadError";
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
/** Thrown when a config targets a different IR version than the installed package. */
|
|
200
|
+
var ConfigVersionMismatchError = class extends ConfigError {
|
|
201
|
+
constructor(message, hint) {
|
|
202
|
+
super(message, hint);
|
|
203
|
+
this.name = "ConfigVersionMismatchError";
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
/** Thrown when an API surface extractor encounters a problem. */
|
|
207
|
+
var ExtractorError = class extends OagenError {
|
|
208
|
+
constructor(message, hint) {
|
|
209
|
+
super(message, hint);
|
|
210
|
+
this.name = "ExtractorError";
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
/** Thrown when a requested language or extractor is not found in a registry. */
|
|
214
|
+
var RegistryError = class extends OagenError {
|
|
215
|
+
constructor(message, hint) {
|
|
216
|
+
super(message, hint);
|
|
217
|
+
this.name = "RegistryError";
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
/** Thrown for internal invariant violations that indicate a bug. */
|
|
221
|
+
var InternalError = class extends OagenError {
|
|
222
|
+
constructor(message, hint) {
|
|
223
|
+
super(message, hint);
|
|
224
|
+
this.name = "InternalError";
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
//#endregion
|
|
228
|
+
//#region src/utils/naming.ts
|
|
229
|
+
/**
|
|
230
|
+
* Split a string into words, handling:
|
|
231
|
+
* - camelCase / PascalCase boundaries
|
|
232
|
+
* - snake_case / kebab-case separators
|
|
233
|
+
* - Consecutive capitals (e.g., "HTTPClient" → ["HTTP", "Client"])
|
|
234
|
+
* - Numbers as word boundaries (e.g., "OAuth2Token" → ["OAuth", "2", "Token"])
|
|
235
|
+
*/
|
|
236
|
+
function splitWords(s) {
|
|
237
|
+
if (!s) return [];
|
|
238
|
+
return s.replace(/[^a-zA-Z0-9_\-\s.]/g, "_").replace(/([a-z])([A-Z])/g, "$1\0$2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1\0$2").replace(/([a-zA-Z])(\d)/g, "$1\0$2").replace(/(\d)([a-zA-Z])/g, "$1\0$2").split(/[\0_\-\s.]+/).filter((w) => w.length > 0);
|
|
239
|
+
}
|
|
240
|
+
const ACRONYM_SET = new Set([
|
|
241
|
+
"SSO",
|
|
242
|
+
"FGA",
|
|
243
|
+
"SAML",
|
|
244
|
+
"SCIM",
|
|
245
|
+
"JWT",
|
|
246
|
+
"HMAC"
|
|
247
|
+
]);
|
|
248
|
+
function toPascalCase(s, acronyms) {
|
|
249
|
+
const merged = acronyms ? new Set([...ACRONYM_SET, ...acronyms]) : ACRONYM_SET;
|
|
250
|
+
return splitWords(s).map((w) => {
|
|
251
|
+
const upper = w.toUpperCase();
|
|
252
|
+
if (merged.has(upper)) return upper;
|
|
253
|
+
if (upper === "OAUTH") return "OAuth";
|
|
254
|
+
return w.charAt(0).toUpperCase() + w.slice(1).toLowerCase();
|
|
255
|
+
}).join("");
|
|
256
|
+
}
|
|
257
|
+
function toCamelCase(s, acronyms) {
|
|
258
|
+
const merged = acronyms ? new Set([...ACRONYM_SET, ...acronyms]) : ACRONYM_SET;
|
|
259
|
+
const words = splitWords(s);
|
|
260
|
+
if (words.length === 0) return "";
|
|
261
|
+
return words.map((w, i) => {
|
|
262
|
+
if (i === 0) return w.toLowerCase();
|
|
263
|
+
const upper = w.toUpperCase();
|
|
264
|
+
if (merged.has(upper)) return upper;
|
|
265
|
+
if (upper === "OAUTH") return "OAuth";
|
|
266
|
+
return w.charAt(0).toUpperCase() + w.slice(1).toLowerCase();
|
|
267
|
+
}).join("");
|
|
268
|
+
}
|
|
269
|
+
function toSnakeCase(s) {
|
|
270
|
+
return splitWords(s).map((w) => w.toLowerCase()).join("_");
|
|
271
|
+
}
|
|
272
|
+
function toKebabCase(s) {
|
|
273
|
+
return splitWords(s).map((w) => w.toLowerCase()).join("-");
|
|
274
|
+
}
|
|
275
|
+
function toUpperSnakeCase(s) {
|
|
276
|
+
return splitWords(s).map((w) => w.toUpperCase()).join("_");
|
|
277
|
+
}
|
|
278
|
+
const BACKEND_SUFFIXES = [
|
|
279
|
+
"Dto",
|
|
280
|
+
"DTO",
|
|
281
|
+
"Controller"
|
|
282
|
+
];
|
|
283
|
+
function stripBackendSuffixes(name) {
|
|
284
|
+
for (const suffix of BACKEND_SUFFIXES) if (name.endsWith(suffix) && name.length > suffix.length) return name.slice(0, -suffix.length);
|
|
285
|
+
return name;
|
|
286
|
+
}
|
|
287
|
+
function stripBackendPrefixes(name) {
|
|
288
|
+
return name.replace(/Userland/g, "").replace(/Controller/g, "");
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Remove ListItem / ByExternalId / ByResourceId / ForResource markers from PascalCase names.
|
|
292
|
+
* E.g. "DirectoriesListItemState" → "DirectoriesState"
|
|
293
|
+
*/
|
|
294
|
+
function stripListItemMarkers(name) {
|
|
295
|
+
return name.replace(/ListItem/g, "").replace(/ByExternalId/g, "").replace(/ByResourceId/g, "").replace(/ForResource/g, "");
|
|
296
|
+
}
|
|
297
|
+
/** Words that look plural but must NOT be singularized. */
|
|
298
|
+
const SINGULAR_SAFE_LIST = new Set([
|
|
299
|
+
"Status",
|
|
300
|
+
"Address",
|
|
301
|
+
"Access",
|
|
302
|
+
"Process",
|
|
303
|
+
"Progress",
|
|
304
|
+
"Success",
|
|
305
|
+
"Radius",
|
|
306
|
+
"Canvas",
|
|
307
|
+
"Alias",
|
|
308
|
+
"Basis",
|
|
309
|
+
"Bus"
|
|
310
|
+
]);
|
|
311
|
+
/**
|
|
312
|
+
* Conservative singularize for the leading PascalCase word.
|
|
313
|
+
* Only applied to the first word of a PascalCase name (the resource word).
|
|
314
|
+
* - `ies` → `y` (e.g. Directories → Directory)
|
|
315
|
+
* - trailing `s` for words >4 chars (e.g. Organizations → Organization)
|
|
316
|
+
* Safe-listed words are never singularized.
|
|
317
|
+
*/
|
|
318
|
+
function singularize(word) {
|
|
319
|
+
if (SINGULAR_SAFE_LIST.has(word)) return word;
|
|
320
|
+
if (word.endsWith("ies") && word.length > 4) return word.slice(0, -3) + "y";
|
|
321
|
+
if (word.endsWith("ses") && word.length > 4) return word.slice(0, -2);
|
|
322
|
+
if (word.endsWith("s") && !word.endsWith("ss") && word.length > 4) return word.slice(0, -1);
|
|
323
|
+
return word;
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Compose all backend name cleaning transforms in order:
|
|
327
|
+
* 1. Strip backend prefixes (Userland, Controller)
|
|
328
|
+
* 2. Strip backend suffixes (Dto, DTO, Controller)
|
|
329
|
+
* 3. Strip ListItem / ByExternalId markers
|
|
330
|
+
* 4. Singularize leading resource word
|
|
331
|
+
*
|
|
332
|
+
* Must be idempotent: `cleanSchemaName(cleanSchemaName(x)) === cleanSchemaName(x)`
|
|
333
|
+
*/
|
|
334
|
+
/** Strip `.js` extensions from import/export specifiers for dedup comparison. */
|
|
335
|
+
function normalizeJsExtension(text) {
|
|
336
|
+
return text.replace(/\.js(['"])/g, "$1");
|
|
337
|
+
}
|
|
338
|
+
function cleanSchemaName(name) {
|
|
339
|
+
let result = stripBackendPrefixes(stripBackendSuffixes(name));
|
|
340
|
+
result = stripListItemMarkers(result);
|
|
341
|
+
const match = result.match(/^([A-Z][a-z]*)/);
|
|
342
|
+
if (match) {
|
|
343
|
+
const leadWord = match[1];
|
|
344
|
+
const singular = singularize(leadWord);
|
|
345
|
+
if (singular !== leadWord) result = singular + result.slice(leadWord.length);
|
|
346
|
+
}
|
|
347
|
+
return result;
|
|
348
|
+
}
|
|
349
|
+
//#endregion
|
|
350
|
+
//#region src/utils/tree-sitter.ts
|
|
351
|
+
const TS_SAFE_CHUNK = 32767;
|
|
352
|
+
function safeParse(parser, source) {
|
|
353
|
+
if (source.length < TS_SAFE_CHUNK) return parser.parse(source);
|
|
354
|
+
return parser.parse((offset) => source.slice(offset, offset + TS_SAFE_CHUNK));
|
|
355
|
+
}
|
|
356
|
+
//#endregion
|
|
357
|
+
export { walkTypeRef as A, assertNever as C, collectModelRefs as D, collectFieldDependencies as E, collectRequestBodyModels as O, SpecParseError as S, collectEnumRefs as T, ConfigVersionMismatchError as _, singularize as a, OagenError as b, stripListItemMarkers as c, toPascalCase as d, toSnakeCase as f, ConfigLoadError as g, ConfigError as h, normalizeJsExtension as i, mapTypeRef as k, toCamelCase as l, CommandError as m, ACRONYM_SET as n, splitWords as o, toUpperSnakeCase as p, cleanSchemaName as r, stripBackendPrefixes as s, safeParse as t, toKebabCase as u, ExtractorError as v, assignModelsToServices as w, RegistryError as x, InternalError as y };
|
|
358
|
+
|
|
359
|
+
//# sourceMappingURL=tree-sitter-BPNfbEzY.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tree-sitter-BPNfbEzY.mjs","names":[],"sources":["../src/ir/types.ts","../src/errors.ts","../src/utils/naming.ts","../src/utils/tree-sitter.ts"],"sourcesContent":["/** Authentication scheme extracted from OpenAPI securitySchemes */\nexport type AuthScheme =\n | { kind: 'bearer' }\n | { kind: 'apiKey'; in: 'header' | 'query' | 'cookie'; name: string }\n | { kind: 'oauth2'; flows: Record<string, unknown> };\n\n/** Root IR node representing the full API surface */\n/** A server entry from the OpenAPI servers array */\nexport interface ServerEntry {\n url: string;\n description?: string;\n}\n\n/** Root IR node representing the full API surface */\nexport interface ApiSpec {\n name: string;\n version: string;\n description?: string;\n baseUrl: string;\n servers?: ServerEntry[];\n services: Service[];\n models: Model[];\n enums: Enum[];\n auth?: AuthScheme[];\n}\n\n/** A service groups related operations (maps to an SDK resource class) */\nexport interface Service {\n name: string;\n description?: string;\n operations: Operation[];\n}\n\n/** A single API operation (maps to an SDK method) */\nexport interface Operation {\n name: string;\n description?: string;\n httpMethod: HttpMethod;\n path: string;\n pathParams: Parameter[];\n queryParams: Parameter[];\n headerParams: Parameter[];\n cookieParams?: Parameter[];\n requestBody?: TypeRef;\n requestBodyEncoding?: 'json' | 'form-data' | 'form-urlencoded' | 'binary' | 'text';\n response: TypeRef;\n successResponses?: SuccessResponse[];\n errors: ErrorResponse[];\n pagination?: PaginationMeta;\n injectIdempotencyKey: boolean;\n deprecated?: boolean;\n async?: boolean;\n}\n\n/** Structured pagination metadata for auto-paging iterator generation */\nexport interface PaginationMeta {\n strategy: 'cursor' | 'offset' | 'link-header';\n param: string;\n limitParam?: string;\n dataPath?: string;\n itemType: TypeRef;\n}\n\nexport type HttpMethod = 'get' | 'post' | 'put' | 'patch' | 'delete' | 'head' | 'options' | 'trace';\n\nexport interface Parameter {\n name: string;\n type: TypeRef;\n required: boolean;\n description?: string;\n deprecated?: boolean;\n default?: unknown;\n example?: unknown;\n}\n\n/** Type reference — the core type system of the IR */\nexport type TypeRef = PrimitiveType | ArrayType | ModelRef | EnumRef | UnionType | NullableType | LiteralType | MapType;\n\nexport interface PrimitiveType {\n kind: 'primitive';\n type: 'string' | 'integer' | 'number' | 'boolean' | 'unknown';\n format?: string;\n}\n\nexport interface ArrayType {\n kind: 'array';\n items: TypeRef;\n}\n\nexport interface ModelRef {\n kind: 'model';\n name: string;\n}\n\nexport interface EnumRef {\n kind: 'enum';\n name: string;\n values?: (string | number)[];\n}\n\nexport interface LiteralType {\n kind: 'literal';\n value: string | number | boolean | null;\n}\n\nexport interface UnionType {\n kind: 'union';\n variants: TypeRef[];\n discriminator?: { property: string; mapping: Record<string, string> };\n /** Which OAS composition keyword produced this union. Emitters can use this to\n * distinguish inheritance (allOf) from exclusive union (oneOf) from open union (anyOf). */\n compositionKind?: 'allOf' | 'oneOf' | 'anyOf';\n}\n\nexport interface NullableType {\n kind: 'nullable';\n inner: TypeRef;\n}\n\nexport interface MapType {\n kind: 'map';\n valueType: TypeRef;\n keyType?: TypeRef;\n}\n\n/**\n * A generic type parameter on a model.\n * Example: `DirectoryUser<TCustomAttributes = Record<string, unknown>>`\n * → `{ name: 'TCustomAttributes', default: { kind: 'map', valueType: { kind: 'primitive', type: 'unknown' } } }`\n */\nexport interface TypeParam {\n name: string;\n /** Default type when the param is not specified. */\n default?: TypeRef;\n}\n\n/** Model definition (maps to an SDK model/data class) */\nexport interface Model {\n name: string;\n description?: string;\n fields: Field[];\n /** Generic type parameters. Empty/undefined for non-generic models. */\n typeParams?: TypeParam[];\n}\n\nexport interface Field {\n name: string;\n type: TypeRef;\n required: boolean;\n description?: string;\n readOnly?: boolean;\n writeOnly?: boolean;\n deprecated?: boolean;\n default?: unknown;\n example?: unknown;\n}\n\n/** Enum definition */\nexport interface Enum {\n name: string;\n values: EnumValue[];\n}\n\nexport interface EnumValue {\n name: string;\n value: string | number;\n description?: string;\n deprecated?: boolean;\n}\n\n/**\n * Exhaustive check helper for TypeRef switches.\n * If a new kind is added to TypeRef, any switch that doesn't handle it\n * will fail to compile because `never` won't accept the unhandled variant.\n *\n * Usage:\n * switch (ref.kind) {\n * case 'primitive': ...\n * case 'array': ...\n * // If you forget 'literal', TypeScript errors here:\n * default: assertNever(ref);\n * }\n */\nexport function assertNever(x: never): never {\n // Inline to avoid importing from ../errors.js (ir/ is layer 0, must not import upward)\n const kind = (x as TypeRef).kind;\n const err = new Error(\n `Unexpected TypeRef kind: ${kind}\\nHint: If you added a new TypeRef variant, handle it in every switch/case that calls assertNever.`,\n );\n err.name = 'InternalError';\n throw err;\n}\n\n/**\n * Generic depth-first walker for TypeRef trees.\n * Handles recursion into array/nullable/union/map children and provides\n * an exhaustive `assertNever` check so callers don't need to repeat the\n * switch boilerplate. Supply callbacks only for the leaf kinds you care about.\n */\nexport function walkTypeRef(\n ref: TypeRef,\n visitor: {\n model?: (ref: ModelRef) => void;\n enum?: (ref: EnumRef) => void;\n primitive?: (ref: PrimitiveType) => void;\n literal?: (ref: LiteralType) => void;\n },\n): void {\n switch (ref.kind) {\n case 'model':\n visitor.model?.(ref);\n break;\n case 'enum':\n visitor.enum?.(ref);\n break;\n case 'array':\n walkTypeRef(ref.items, visitor);\n break;\n case 'nullable':\n walkTypeRef(ref.inner, visitor);\n break;\n case 'union':\n for (const v of ref.variants) walkTypeRef(v, visitor);\n break;\n case 'map':\n if (ref.keyType) walkTypeRef(ref.keyType, visitor);\n walkTypeRef(ref.valueType, visitor);\n break;\n case 'literal':\n visitor.literal?.(ref);\n break;\n case 'primitive':\n visitor.primitive?.(ref);\n break;\n default:\n assertNever(ref);\n }\n}\n\n/**\n * Generic depth-first mapper for TypeRef trees.\n * Like walkTypeRef but returns a transformed value instead of void.\n * Handles recursion into array/nullable/union/map children, passing\n * already-mapped child values to the parent callback.\n */\nexport function mapTypeRef<T>(\n ref: TypeRef,\n mapper: {\n primitive: (ref: PrimitiveType) => T;\n array: (ref: ArrayType, mappedItems: T) => T;\n model: (ref: ModelRef) => T;\n enum: (ref: EnumRef) => T;\n union: (ref: UnionType, mappedVariants: T[]) => T;\n nullable: (ref: NullableType, mappedInner: T) => T;\n literal: (ref: LiteralType) => T;\n map: (ref: MapType, mappedValue: T, mappedKey?: T) => T;\n },\n): T {\n switch (ref.kind) {\n case 'primitive':\n return mapper.primitive(ref);\n case 'array':\n return mapper.array(ref, mapTypeRef(ref.items, mapper));\n case 'model':\n return mapper.model(ref);\n case 'enum':\n return mapper.enum(ref);\n case 'union':\n return mapper.union(\n ref,\n ref.variants.map((v) => mapTypeRef(v, mapper)),\n );\n case 'nullable':\n return mapper.nullable(ref, mapTypeRef(ref.inner, mapper));\n case 'literal':\n return mapper.literal(ref);\n case 'map':\n return mapper.map(\n ref,\n mapTypeRef(ref.valueType, mapper),\n ref.keyType ? mapTypeRef(ref.keyType, mapper) : undefined,\n );\n default:\n return assertNever(ref);\n }\n}\n\n// --- IR traversal utilities ---\n\n/**\n * Collect all model names referenced (directly or transitively) by a TypeRef.\n */\nexport function collectModelRefs(ref: TypeRef): string[] {\n const names: string[] = [];\n walkTypeRef(ref, { model: (r) => names.push(r.name) });\n return names;\n}\n\n/**\n * Collect all enum names referenced by a TypeRef.\n */\nexport function collectEnumRefs(ref: TypeRef): string[] {\n const names: string[] = [];\n walkTypeRef(ref, { enum: (r) => names.push(r.name) });\n return names;\n}\n\n/**\n * Collect all TypeRef-referenced model and enum names from a model's fields.\n * Returns { models, enums } sets for generating import statements.\n */\nexport function collectFieldDependencies(model: Model): {\n models: Set<string>;\n enums: Set<string>;\n} {\n const models = new Set<string>();\n const enums = new Set<string>();\n\n for (const field of model.fields) {\n for (const name of collectModelRefs(field.type)) {\n if (name !== model.name) models.add(name);\n }\n for (const name of collectEnumRefs(field.type)) {\n enums.add(name);\n }\n }\n\n return { models, enums };\n}\n\n/**\n * Assign each model to the service that first references it.\n * Models referenced by multiple services are assigned to the first.\n * Models not referenced by any service are unassigned (absent from the map).\n */\nexport function assignModelsToServices(models: Model[], services: Service[]): Map<string, string> {\n const modelToService = new Map<string, string>();\n const modelNames = new Set(models.map((m) => m.name));\n\n for (const service of services) {\n const referencedModels = new Set<string>();\n\n for (const op of service.operations) {\n if (op.requestBody) {\n for (const name of collectModelRefs(op.requestBody)) {\n referencedModels.add(name);\n }\n }\n for (const name of collectModelRefs(op.response)) {\n referencedModels.add(name);\n }\n for (const param of [...op.pathParams, ...op.queryParams, ...op.headerParams, ...(op.cookieParams ?? [])]) {\n for (const name of collectModelRefs(param.type)) {\n referencedModels.add(name);\n }\n }\n if (op.pagination) {\n for (const name of collectModelRefs(op.pagination.itemType)) {\n referencedModels.add(name);\n }\n }\n }\n\n // Transitively collect models referenced by the directly-referenced models\n const toVisit = [...referencedModels];\n while (toVisit.length > 0) {\n const name = toVisit.pop()!;\n const model = models.find((m) => m.name === name);\n if (!model) continue;\n for (const field of model.fields) {\n for (const ref of collectModelRefs(field.type)) {\n if (!referencedModels.has(ref) && modelNames.has(ref)) {\n referencedModels.add(ref);\n toVisit.push(ref);\n }\n }\n }\n }\n\n for (const name of referencedModels) {\n if (!modelToService.has(name)) {\n modelToService.set(name, service.name);\n }\n }\n }\n\n return modelToService;\n}\n\n/**\n * Collect all model names referenced as request bodies across all services.\n */\nexport function collectRequestBodyModels(services: Service[]): Set<string> {\n const result = new Set<string>();\n for (const service of services) {\n for (const op of service.operations) {\n if (op.requestBody) {\n for (const name of collectModelRefs(op.requestBody)) {\n result.add(name);\n }\n }\n }\n }\n return result;\n}\n\nexport interface ErrorResponse {\n statusCode: number;\n type?: TypeRef;\n}\n\n/** A successful response entry from a 2xx status code */\nexport interface SuccessResponse {\n statusCode: number;\n type: TypeRef;\n}\n","/**\n * Structured error hierarchy for oagen.\n *\n * Every error carries a human-readable `hint` that suggests a recovery action.\n * The hint is appended to the `message` so it appears in stack traces and logs.\n */\n\n/** Base class for all oagen errors. */\nexport class OagenError extends Error {\n readonly hint: string;\n\n constructor(message: string, hint: string) {\n const fullMessage = hint ? `${message}\\nHint: ${hint}` : message;\n super(fullMessage);\n this.name = 'OagenError';\n this.hint = hint;\n }\n}\n\n/** Thrown when a command should terminate with a specific exit code. */\nexport class CommandError extends OagenError {\n readonly exitCode: number;\n\n constructor(message: string, hint: string, exitCode: number) {\n super(message, hint);\n this.name = 'CommandError';\n this.exitCode = exitCode;\n }\n}\n\n/** Thrown when an OpenAPI spec cannot be parsed or has an unsupported version. */\nexport class SpecParseError extends OagenError {\n constructor(message: string, hint: string) {\n super(message, hint);\n this.name = 'SpecParseError';\n }\n}\n\n/** Thrown when configuration files (manifests, API surfaces, overlays) are missing or malformed. */\nexport class ConfigError extends OagenError {\n constructor(message: string, hint: string) {\n super(message, hint);\n this.name = 'ConfigError';\n }\n}\n\n/** Thrown when a config file exists but cannot be loaded or evaluated. */\nexport class ConfigLoadError extends ConfigError {\n constructor(message: string, hint: string) {\n super(message, hint);\n this.name = 'ConfigLoadError';\n }\n}\n\n/** Thrown when a config targets a different IR version than the installed package. */\nexport class ConfigVersionMismatchError extends ConfigError {\n constructor(message: string, hint: string) {\n super(message, hint);\n this.name = 'ConfigVersionMismatchError';\n }\n}\n\n/** Thrown when an API surface extractor encounters a problem. */\nexport class ExtractorError extends OagenError {\n constructor(message: string, hint: string) {\n super(message, hint);\n this.name = 'ExtractorError';\n }\n}\n\n/** Thrown when a requested language or extractor is not found in a registry. */\nexport class RegistryError extends OagenError {\n constructor(message: string, hint: string) {\n super(message, hint);\n this.name = 'RegistryError';\n }\n}\n\n/** Thrown for internal invariant violations that indicate a bug. */\nexport class InternalError extends OagenError {\n constructor(message: string, hint: string) {\n super(message, hint);\n this.name = 'InternalError';\n }\n}\n","/**\n * Split a string into words, handling:\n * - camelCase / PascalCase boundaries\n * - snake_case / kebab-case separators\n * - Consecutive capitals (e.g., \"HTTPClient\" → [\"HTTP\", \"Client\"])\n * - Numbers as word boundaries (e.g., \"OAuth2Token\" → [\"OAuth\", \"2\", \"Token\"])\n */\nexport function splitWords(s: string): string[] {\n if (!s) return [];\n\n return s\n .replace(/[^a-zA-Z0-9_\\-\\s.]/g, '_') // replace non-alphanumeric chars with separator\n .replace(/([a-z])([A-Z])/g, '$1\\0$2') // camelCase boundary\n .replace(/([A-Z]+)([A-Z][a-z])/g, '$1\\0$2') // consecutive caps boundary\n .replace(/([a-zA-Z])(\\d)/g, '$1\\0$2') // letter to number\n .replace(/(\\d)([a-zA-Z])/g, '$1\\0$2') // number to letter\n .split(/[\\0_\\-\\s.]+/)\n .filter((w) => w.length > 0);\n}\n\nexport const ACRONYM_SET = new Set(['SSO', 'FGA', 'SAML', 'SCIM', 'JWT', 'HMAC']);\n\nexport function toPascalCase(s: string, acronyms?: Set<string>): string {\n const merged = acronyms ? new Set([...ACRONYM_SET, ...acronyms]) : ACRONYM_SET;\n return splitWords(s)\n .map((w) => {\n const upper = w.toUpperCase();\n if (merged.has(upper)) return upper;\n // Special case: OAuth should stay as OAuth, not OAUTH\n if (upper === 'OAUTH') return 'OAuth';\n return w.charAt(0).toUpperCase() + w.slice(1).toLowerCase();\n })\n .join('');\n}\n\nexport function toCamelCase(s: string, acronyms?: Set<string>): string {\n const merged = acronyms ? new Set([...ACRONYM_SET, ...acronyms]) : ACRONYM_SET;\n const words = splitWords(s);\n if (words.length === 0) return '';\n return words\n .map((w, i) => {\n if (i === 0) return w.toLowerCase();\n const upper = w.toUpperCase();\n if (merged.has(upper)) return upper;\n if (upper === 'OAUTH') return 'OAuth';\n return w.charAt(0).toUpperCase() + w.slice(1).toLowerCase();\n })\n .join('');\n}\n\nexport function toSnakeCase(s: string): string {\n return splitWords(s)\n .map((w) => w.toLowerCase())\n .join('_');\n}\n\nexport function toKebabCase(s: string): string {\n return splitWords(s)\n .map((w) => w.toLowerCase())\n .join('-');\n}\n\nexport function toUpperSnakeCase(s: string): string {\n return splitWords(s)\n .map((w) => w.toUpperCase())\n .join('_');\n}\n\nconst BACKEND_SUFFIXES = ['Dto', 'DTO', 'Controller'];\n\nexport function stripBackendSuffixes(name: string): string {\n for (const suffix of BACKEND_SUFFIXES) {\n if (name.endsWith(suffix) && name.length > suffix.length) {\n return name.slice(0, -suffix.length);\n }\n }\n return name;\n}\n\nexport function stripBackendPrefixes(name: string): string {\n return name.replace(/Userland/g, '').replace(/Controller/g, '');\n}\n\n/**\n * Remove ListItem / ByExternalId / ByResourceId / ForResource markers from PascalCase names.\n * E.g. \"DirectoriesListItemState\" → \"DirectoriesState\"\n */\nexport function stripListItemMarkers(name: string): string {\n return name\n .replace(/ListItem/g, '')\n .replace(/ByExternalId/g, '')\n .replace(/ByResourceId/g, '')\n .replace(/ForResource/g, '');\n}\n\n/** Words that look plural but must NOT be singularized. */\nconst SINGULAR_SAFE_LIST = new Set([\n 'Status',\n 'Address',\n 'Access',\n 'Process',\n 'Progress',\n 'Success',\n 'Radius',\n 'Canvas',\n 'Alias',\n 'Basis',\n 'Bus',\n]);\n\n/**\n * Conservative singularize for the leading PascalCase word.\n * Only applied to the first word of a PascalCase name (the resource word).\n * - `ies` → `y` (e.g. Directories → Directory)\n * - trailing `s` for words >4 chars (e.g. Organizations → Organization)\n * Safe-listed words are never singularized.\n */\nexport function singularize(word: string): string {\n if (SINGULAR_SAFE_LIST.has(word)) return word;\n if (word.endsWith('ies') && word.length > 4) {\n return word.slice(0, -3) + 'y';\n }\n if (word.endsWith('ses') && word.length > 4) {\n // e.g. \"Processes\" — but \"Process\" is safe-listed, this handles non-safe ones\n return word.slice(0, -2);\n }\n if (word.endsWith('s') && !word.endsWith('ss') && word.length > 4) {\n return word.slice(0, -1);\n }\n return word;\n}\n\n/**\n * Compose all backend name cleaning transforms in order:\n * 1. Strip backend prefixes (Userland, Controller)\n * 2. Strip backend suffixes (Dto, DTO, Controller)\n * 3. Strip ListItem / ByExternalId markers\n * 4. Singularize leading resource word\n *\n * Must be idempotent: `cleanSchemaName(cleanSchemaName(x)) === cleanSchemaName(x)`\n */\n/** Strip `.js` extensions from import/export specifiers for dedup comparison. */\nexport function normalizeJsExtension(text: string): string {\n return text.replace(/\\.js(['\"])/g, '$1');\n}\n\nexport function cleanSchemaName(name: string): string {\n let result = stripBackendPrefixes(stripBackendSuffixes(name));\n result = stripListItemMarkers(result);\n\n // Singularize the leading PascalCase word\n const match = result.match(/^([A-Z][a-z]*)/);\n if (match) {\n const leadWord = match[1];\n const singular = singularize(leadWord);\n if (singular !== leadWord) {\n result = singular + result.slice(leadWord.length);\n }\n }\n\n return result;\n}\n","/**\n * Shared tree-sitter utilities.\n *\n * tree-sitter 0.21.x has a native binding bug: its internal UTF-16 buffer is\n * 32 768 uint16 units (32 768 characters for BMP text). When the JS input\n * callback returns a string >= 32 768 chars, `napi_get_value_string_utf16`\n * overflows and the C layer throws \"Invalid argument\". Work around this by\n * supplying a chunked callback for large sources instead of a raw string.\n */\n\nimport type Parser from 'tree-sitter';\n\nconst TS_SAFE_CHUNK = 32_767;\n\nexport function safeParse(parser: Parser, source: string): Parser.Tree {\n if (source.length < TS_SAFE_CHUNK) {\n return parser.parse(source);\n }\n return parser.parse((offset: number) => source.slice(offset, offset + TS_SAFE_CHUNK));\n}\n"],"mappings":"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"}
|