@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.
@@ -1,3 +1,3 @@
1
1
  {
2
- ".": "0.15.0"
2
+ ".": "0.15.1"
3
3
  }
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-CO4RFgAW.mjs";
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(/\bAutoPaginatable<\s*([A-Za-z_$][\w$]*)/)?.[1];
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 (!returnType || !itemType || !preferred || preferred === itemType) return returnType;
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
- for (const p of PAGINATION_PARAM_NAMES) lines.push(` ${p}: options.${p},`);
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 listOptionsExpr = op.queryParams.filter((p) => !PAGINATION_PARAM_NAMES.has(p.name)).some((p) => fieldName$6(p.name) !== wireFieldName(p.name)) ? `options ? serialize${optionParam.type}(options) : undefined` : "paginationOptions";
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(` paginationOptions,`);
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(` options,`);
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)) ownedDirNames.add(resolveDir(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
- for (const field of shape.baseFields) pushFieldLine(lines, field, isWire);
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 symbols = [];
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
- if (wire !== domain) symbols.push(wire);
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
- if (symbols.length === 0) return [];
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-CO4RFgAW.mjs.map
28418
+ //# sourceMappingURL=plugin-C2Hp2Vs2.mjs.map