@workos/oagen-emitters 0.15.0 → 0.15.1
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/.release-please-manifest.json +1 -1
- package/CHANGELOG.md +7 -0
- package/dist/index.mjs +1 -1
- package/dist/{plugin-CO4RFgAW.mjs → plugin-C2Hp2Vs2.mjs} +84 -27
- package/dist/plugin-C2Hp2Vs2.mjs.map +1 -0
- package/dist/plugin.mjs +1 -1
- package/package.json +1 -1
- package/src/node/client.ts +40 -1
- package/src/node/discriminated-models.ts +60 -24
- package/src/node/resources.ts +20 -6
- package/dist/plugin-CO4RFgAW.mjs.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.15.1](https://github.com/workos/oagen-emitters/compare/v0.15.0...v0.15.1) (2026-06-01)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* **node:** resolve emitter bugs blocking service ownership migration ([#132](https://github.com/workos/oagen-emitters/issues/132)) ([e63cc06](https://github.com/workos/oagen-emitters/commit/e63cc06f948657965563a0d582ebbd9bedb1eb5f))
|
|
9
|
+
|
|
3
10
|
## [0.15.0](https://github.com/workos/oagen-emitters/compare/v0.14.4...v0.15.0) (2026-06-01)
|
|
4
11
|
|
|
5
12
|
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { _ as pythonEmitter, a as rustExtractor, c as pythonExtractor, d as rustEmitter, f as rubyEmitter, g as phpEmitter, h as goEmitter, i as kotlinExtractor, l as rubyExtractor, m as dotnetEmitter, n as elixirExtractor, o as goExtractor, p as kotlinEmitter, r as dotnetExtractor, s as phpExtractor, t as workosEmittersPlugin, u as nodeExtractor, v as nodeEmitter } from "./plugin-
|
|
1
|
+
import { _ as pythonEmitter, a as rustExtractor, c as pythonExtractor, d as rustEmitter, f as rubyEmitter, g as phpEmitter, h as goEmitter, i as kotlinExtractor, l as rubyExtractor, m as dotnetEmitter, n as elixirExtractor, o as goExtractor, p as kotlinEmitter, r as dotnetExtractor, s as phpExtractor, t as workosEmittersPlugin, u as nodeExtractor, v as nodeEmitter } from "./plugin-C2Hp2Vs2.mjs";
|
|
2
2
|
export { dotnetEmitter, dotnetExtractor, elixirExtractor, goEmitter, goExtractor, kotlinEmitter, kotlinExtractor, nodeEmitter, nodeExtractor, phpEmitter, phpExtractor, pythonEmitter, pythonExtractor, rubyEmitter, rubyExtractor, rustEmitter, rustExtractor, workosEmittersPlugin };
|
|
@@ -4781,7 +4781,7 @@ function renderOptionsParam(param) {
|
|
|
4781
4781
|
return `options${param.optional ? "?" : ""}: ${param.type}`;
|
|
4782
4782
|
}
|
|
4783
4783
|
function autoPaginatableItemType$1(returnType) {
|
|
4784
|
-
return returnType?.match(/\
|
|
4784
|
+
return returnType?.match(/\b(?:AutoPaginatable|List)<\s*([A-Za-z_$][\w$]*)/)?.[1];
|
|
4785
4785
|
}
|
|
4786
4786
|
function baselineTypeSourceFile(ctx, typeName) {
|
|
4787
4787
|
const surface = ctx.apiSurface;
|
|
@@ -4799,9 +4799,12 @@ function preferredBaselineTypeName(ctx, typeName) {
|
|
|
4799
4799
|
return typeName;
|
|
4800
4800
|
}
|
|
4801
4801
|
function preferredBaselineReturnType(ctx, returnType) {
|
|
4802
|
+
if (!returnType) return void 0;
|
|
4803
|
+
if (!/\bAutoPaginatable\b/.test(returnType)) return void 0;
|
|
4802
4804
|
const itemType = autoPaginatableItemType$1(returnType);
|
|
4805
|
+
if (!itemType) return void 0;
|
|
4803
4806
|
const preferred = preferredBaselineTypeName(ctx, itemType);
|
|
4804
|
-
if (!
|
|
4807
|
+
if (!preferred || preferred === itemType) return returnType;
|
|
4805
4808
|
return returnType.replace(new RegExp(`\\b${itemType}\\b`, "g"), preferred);
|
|
4806
4809
|
}
|
|
4807
4810
|
function requestEntityType(bodyExpr, requestType) {
|
|
@@ -5233,7 +5236,11 @@ function generateResourceClass(service, ctx) {
|
|
|
5233
5236
|
const serializerName = `serialize${optionsName}`;
|
|
5234
5237
|
lines.push(`const ${serializerName} = (options: ${optionsName}): PaginationOptions => {`);
|
|
5235
5238
|
lines.push(" const wire: Record<string, unknown> = {");
|
|
5236
|
-
|
|
5239
|
+
const baselineFields = (ctx.apiSurface?.interfaces)?.[optionsName]?.fields;
|
|
5240
|
+
for (const p of PAGINATION_PARAM_NAMES) {
|
|
5241
|
+
if (baselineFields && !(p in baselineFields) && !baselineFields[toCamelCase(p)]) continue;
|
|
5242
|
+
lines.push(` ${p}: options.${p},`);
|
|
5243
|
+
}
|
|
5237
5244
|
lines.push(" };");
|
|
5238
5245
|
for (const param of extraParams) {
|
|
5239
5246
|
const camel = fieldName$6(param.name);
|
|
@@ -5466,7 +5473,7 @@ function renderMethod$2(op, plan, method, service, ctx, modelMap, specEnumNames,
|
|
|
5466
5473
|
const unwrapped = unwrapListModel$4(pModel, modelMap);
|
|
5467
5474
|
if (unwrapped) itemRawName = unwrapped.name;
|
|
5468
5475
|
}
|
|
5469
|
-
const itemTypeName = resolveInterfaceName(itemRawName, ctx);
|
|
5476
|
+
const itemTypeName = preferredBaselineTypeName(ctx, autoPaginatableItemType$1(baselineClassMethod?.returnType) ?? autoPaginatableItemType$1(overlayMethod?.returnType)) ?? resolveInterfaceName(itemRawName, ctx);
|
|
5470
5477
|
docParts.push(`@returns {Promise<AutoPaginatable<${itemTypeName}>>}`);
|
|
5471
5478
|
} else if (responseModel) {
|
|
5472
5479
|
const returnTypeDoc = plan.isArrayResponse ? `${responseModel}[]` : responseModel;
|
|
@@ -5539,9 +5546,10 @@ function renderOptionsObjectMethod(lines, op, plan, method, service, ctx, modelM
|
|
|
5539
5546
|
if (!itemType) return false;
|
|
5540
5547
|
const wireType = wireInterfaceName(itemType);
|
|
5541
5548
|
const returnType = preferredBaselineReturnType(ctx, baselineMethod?.returnType) ?? `Promise<AutoPaginatable<${itemType}>>`;
|
|
5542
|
-
const
|
|
5549
|
+
const needsWireSerializer = op.queryParams.filter((p) => !PAGINATION_PARAM_NAMES.has(p.name)).some((p) => fieldName$6(p.name) !== wireFieldName(p.name));
|
|
5550
|
+
const listOptionsExpr = needsWireSerializer ? `options ? serialize${optionParam.type}(options) : undefined` : "paginationOptions";
|
|
5543
5551
|
lines.push(` async ${method}(${renderOptionsParam(optionParam)}): ${returnType} {`);
|
|
5544
|
-
renderOptionsObjectDestructure(lines, pathBindings, "paginationOptions");
|
|
5552
|
+
renderOptionsObjectDestructure(lines, pathBindings, needsWireSerializer ? void 0 : "paginationOptions");
|
|
5545
5553
|
lines.push(` return new AutoPaginatable(`);
|
|
5546
5554
|
lines.push(` await fetchAndDeserialize<${wireType}, ${itemType}>(`);
|
|
5547
5555
|
lines.push(` this.workos,`);
|
|
@@ -5556,7 +5564,7 @@ function renderOptionsObjectMethod(lines, op, plan, method, service, ctx, modelM
|
|
|
5556
5564
|
lines.push(` deserialize${itemType},`);
|
|
5557
5565
|
lines.push(` params,`);
|
|
5558
5566
|
lines.push(` ),`);
|
|
5559
|
-
lines.push(`
|
|
5567
|
+
lines.push(` ${listOptionsExpr},`);
|
|
5560
5568
|
lines.push(` );`);
|
|
5561
5569
|
lines.push(" }");
|
|
5562
5570
|
return true;
|
|
@@ -5708,7 +5716,7 @@ function renderPaginatedMethod(lines, op, plan, method, itemType, pathStr, resol
|
|
|
5708
5716
|
lines.push(` deserialize${itemType},`);
|
|
5709
5717
|
lines.push(` params,`);
|
|
5710
5718
|
lines.push(` ),`);
|
|
5711
|
-
lines.push(`
|
|
5719
|
+
lines.push(` ${serializeCall},`);
|
|
5712
5720
|
lines.push(` );`);
|
|
5713
5721
|
lines.push(" }");
|
|
5714
5722
|
}
|
|
@@ -7128,7 +7136,14 @@ function generateServiceBarrels(spec, ctx) {
|
|
|
7128
7136
|
const dirExports = /* @__PURE__ */ new Map();
|
|
7129
7137
|
const dirSymbols = /* @__PURE__ */ new Map();
|
|
7130
7138
|
const ownedDirNames = /* @__PURE__ */ new Set();
|
|
7131
|
-
for (const service of spec.services) if (isNodeOwnedService(ctx, service.name))
|
|
7139
|
+
for (const service of spec.services) if (isNodeOwnedService(ctx, service.name)) {
|
|
7140
|
+
const dir = resolveDir(service.name);
|
|
7141
|
+
ownedDirNames.add(dir);
|
|
7142
|
+
if (!dirExports.has(dir)) {
|
|
7143
|
+
dirExports.set(dir, []);
|
|
7144
|
+
if (!dirSymbols.has(dir)) dirSymbols.set(dir, /* @__PURE__ */ new Set());
|
|
7145
|
+
}
|
|
7146
|
+
}
|
|
7132
7147
|
const dirSymbolsFromBaseline = /* @__PURE__ */ new Map();
|
|
7133
7148
|
const seedFromBaseline = (sourceFile, name) => {
|
|
7134
7149
|
const match = sourceFile.match(/^src\/([^/]+)\/interfaces\/(.+)\.ts$/);
|
|
@@ -7294,6 +7309,28 @@ function generateServiceBarrels(spec, ctx) {
|
|
|
7294
7309
|
} catch {}
|
|
7295
7310
|
}
|
|
7296
7311
|
}
|
|
7312
|
+
const ownedScanRoot = ctx.targetDir ?? ctx.outputDir;
|
|
7313
|
+
if (ownedScanRoot && isDirOwned) {
|
|
7314
|
+
const interfacesDir = path.join(ownedScanRoot, "src", dirName, "interfaces");
|
|
7315
|
+
const symbols = dirSymbols.get(dirName) ?? /* @__PURE__ */ new Set();
|
|
7316
|
+
try {
|
|
7317
|
+
for (const entry of fs.readdirSync(interfacesDir)) {
|
|
7318
|
+
if (entry === "index.ts") continue;
|
|
7319
|
+
if (!entry.endsWith(".ts")) continue;
|
|
7320
|
+
const exportLine = `export * from './${entry.replace(/\.ts$/, "")}';`;
|
|
7321
|
+
if (exportSet.has(exportLine)) continue;
|
|
7322
|
+
const content = fs.readFileSync(path.join(interfacesDir, entry), "utf-8");
|
|
7323
|
+
const exportedNames = [];
|
|
7324
|
+
for (const m of content.matchAll(/export\s+(?:interface|type|enum|class|const|function)\s+(\w+)/g)) exportedNames.push(m[1]);
|
|
7325
|
+
if (exportedNames.some((name) => globalExistingSymbols.has(name))) continue;
|
|
7326
|
+
for (const name of exportedNames) {
|
|
7327
|
+
symbols.add(name);
|
|
7328
|
+
globalExistingSymbols.add(name);
|
|
7329
|
+
}
|
|
7330
|
+
exportSet.add(exportLine);
|
|
7331
|
+
}
|
|
7332
|
+
} catch {}
|
|
7333
|
+
}
|
|
7297
7334
|
const uniqueExports = [...exportSet];
|
|
7298
7335
|
uniqueExports.sort();
|
|
7299
7336
|
if (ctx.apiSurface) files.push({
|
|
@@ -8494,13 +8531,29 @@ function planDiscriminatedModels(models, ctx) {
|
|
|
8494
8531
|
if (!spec?.components?.schemas) return plans;
|
|
8495
8532
|
const rawSchemas = spec.components.schemas;
|
|
8496
8533
|
const { modelToService, resolveDir } = createServiceDirResolver(models, ctx.spec.services, ctx);
|
|
8534
|
+
const irModelDir = /* @__PURE__ */ new Map();
|
|
8535
|
+
for (const model of models) irModelDir.set(model.name, resolveDir(modelToService.get(model.name)));
|
|
8536
|
+
const depDirMap = /* @__PURE__ */ new Map();
|
|
8537
|
+
for (const rawName of Object.keys(rawSchemas)) {
|
|
8538
|
+
if (irModelDir.has(rawName)) {
|
|
8539
|
+
depDirMap.set(rawName, irModelDir.get(rawName));
|
|
8540
|
+
continue;
|
|
8541
|
+
}
|
|
8542
|
+
const stripped = rawName.replace(/Dto/g, "").replace(/DTO/g, "").replace(/Json$/, "");
|
|
8543
|
+
if (stripped !== rawName && irModelDir.has(stripped)) depDirMap.set(rawName, irModelDir.get(stripped));
|
|
8544
|
+
}
|
|
8497
8545
|
for (const model of models) {
|
|
8498
8546
|
const shape = detectDiscriminatedShape(model.name, rawSchemas);
|
|
8499
8547
|
if (!shape) continue;
|
|
8548
|
+
const allDeps = /* @__PURE__ */ new Set();
|
|
8549
|
+
for (const field of shape.baseFields) for (const d of field.modelDeps) allDeps.add(d);
|
|
8550
|
+
for (const variant of shape.variants) for (const field of variant.fields) for (const d of field.modelDeps) allDeps.add(d);
|
|
8551
|
+
if ([...allDeps].some((dep) => !depDirMap.has(dep) && !irModelDir.has(dep))) continue;
|
|
8500
8552
|
const modelDir = resolveDir(modelToService.get(model.name));
|
|
8501
8553
|
plans.set(model.name, {
|
|
8502
8554
|
shape,
|
|
8503
|
-
modelDir
|
|
8555
|
+
modelDir,
|
|
8556
|
+
depDirMap
|
|
8504
8557
|
});
|
|
8505
8558
|
}
|
|
8506
8559
|
return plans;
|
|
@@ -8545,7 +8598,12 @@ function buildInterfaceFile(plan, _ctx) {
|
|
|
8545
8598
|
function buildInterfaceBody(name, shape, variant, isWire) {
|
|
8546
8599
|
const lines = [];
|
|
8547
8600
|
lines.push(`export interface ${name} {`);
|
|
8548
|
-
|
|
8601
|
+
const variantFieldNames = new Set(variant.fields.map((f) => f.name));
|
|
8602
|
+
for (const field of shape.baseFields) {
|
|
8603
|
+
if (variantFieldNames.has(field.name)) continue;
|
|
8604
|
+
if (field.name === shape.discriminatorProperty) continue;
|
|
8605
|
+
pushFieldLine(lines, field, isWire);
|
|
8606
|
+
}
|
|
8549
8607
|
const discKey = isWire ? shape.discriminatorProperty : shape.discriminatorPropertyDomain;
|
|
8550
8608
|
if (shape.discriminatorDescription) lines.push(` /** ${shape.discriminatorDescription} */`);
|
|
8551
8609
|
lines.push(` ${discKey}: '${variant.discriminatorValue}';`);
|
|
@@ -8564,25 +8622,24 @@ function collectImports$2(plan) {
|
|
|
8564
8622
|
const deps = /* @__PURE__ */ new Set();
|
|
8565
8623
|
for (const field of plan.shape.baseFields) for (const d of field.modelDeps) deps.add(d);
|
|
8566
8624
|
for (const variant of plan.shape.variants) for (const field of variant.fields) for (const d of field.modelDeps) deps.add(d);
|
|
8567
|
-
const
|
|
8625
|
+
const result = [];
|
|
8568
8626
|
for (const dep of [...deps].sort()) {
|
|
8569
8627
|
const domain = toPascalCase(dep);
|
|
8570
|
-
symbols.push(domain);
|
|
8571
8628
|
const wire = wireInterfaceName(domain);
|
|
8572
|
-
|
|
8629
|
+
const symbols = wire !== domain ? [domain, wire] : [domain];
|
|
8630
|
+
const depDir = plan.depDirMap.get(dep);
|
|
8631
|
+
const baseName = fileName$3(toSnakeFromPascal(domain));
|
|
8632
|
+
let importPath;
|
|
8633
|
+
if (!depDir || depDir === plan.modelDir) importPath = `./${baseName}.interface`;
|
|
8634
|
+
else importPath = `../../${depDir}/interfaces/${baseName}.interface`;
|
|
8635
|
+
const existing = result.find((a) => a.path === importPath);
|
|
8636
|
+
if (existing) existing.symbols.push(...symbols);
|
|
8637
|
+
else result.push({
|
|
8638
|
+
path: importPath,
|
|
8639
|
+
symbols
|
|
8640
|
+
});
|
|
8573
8641
|
}
|
|
8574
|
-
|
|
8575
|
-
return symbols.map((sym) => {
|
|
8576
|
-
return {
|
|
8577
|
-
path: `./${fileName$3(toSnakeFromPascal(sym.replace(/Response$/, "")))}.interface`,
|
|
8578
|
-
symbols: [sym]
|
|
8579
|
-
};
|
|
8580
|
-
}).reduce((acc, cur) => {
|
|
8581
|
-
const existing = acc.find((a) => a.path === cur.path);
|
|
8582
|
-
if (existing) existing.symbols.push(...cur.symbols);
|
|
8583
|
-
else acc.push(cur);
|
|
8584
|
-
return acc;
|
|
8585
|
-
}, []);
|
|
8642
|
+
return result;
|
|
8586
8643
|
}
|
|
8587
8644
|
function toSnakeFromPascal(s) {
|
|
8588
8645
|
return s.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2").toLowerCase();
|
|
@@ -28358,4 +28415,4 @@ const workosEmittersPlugin = {
|
|
|
28358
28415
|
//#endregion
|
|
28359
28416
|
export { pythonEmitter as _, rustExtractor as a, pythonExtractor as c, rustEmitter as d, rubyEmitter as f, phpEmitter as g, goEmitter as h, kotlinExtractor as i, rubyExtractor as l, dotnetEmitter as m, elixirExtractor as n, goExtractor as o, kotlinEmitter as p, dotnetExtractor as r, phpExtractor as s, workosEmittersPlugin as t, nodeExtractor as u, nodeEmitter as v };
|
|
28360
28417
|
|
|
28361
|
-
//# sourceMappingURL=plugin-
|
|
28418
|
+
//# sourceMappingURL=plugin-C2Hp2Vs2.mjs.map
|