@workos/oagen-emitters 0.14.3 → 0.14.4

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/plugin.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { t as workosEmittersPlugin } from "./plugin-D0qLBiGv.mjs";
1
+ import { t as workosEmittersPlugin } from "./plugin-BGVaMGqe.mjs";
2
2
  export { workosEmittersPlugin };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@workos/oagen-emitters",
3
- "version": "0.14.3",
3
+ "version": "0.14.4",
4
4
  "description": "WorkOS' oagen emitters",
5
5
  "license": "MIT",
6
6
  "author": "WorkOS",
@@ -42,8 +42,8 @@
42
42
  "@commitlint/config-conventional": "^21.0.1",
43
43
  "@types/node": "^25.9.1",
44
44
  "husky": "^9.1.7",
45
- "oxfmt": "^0.51.0",
46
- "oxlint": "^1.66.0",
45
+ "oxfmt": "^0.52.0",
46
+ "oxlint": "^1.67.0",
47
47
  "prettier": "^3.8.3",
48
48
  "tsdown": "^0.22.0",
49
49
  "tsx": "^4.22.3",
@@ -54,6 +54,6 @@
54
54
  "node": ">=24.10.0"
55
55
  },
56
56
  "dependencies": {
57
- "@workos/oagen": "^0.20.0"
57
+ "@workos/oagen": "^0.21.0"
58
58
  }
59
59
  }
@@ -124,14 +124,14 @@ export function detectDiscriminatedShape(
124
124
  return {
125
125
  nameSuffix: variantNameSuffix(discValue),
126
126
  discriminatorValue: discValue,
127
- fields: variantFields(fv, discProp, modelName, rawSchemas),
127
+ fields: variantFields(fv, discProp, modelName),
128
128
  };
129
129
  })
130
130
  .filter((v): v is VariantSpec => v !== null);
131
131
 
132
132
  if (variants.length !== flattenedVariants.length) return null;
133
133
 
134
- const baseFields = baseObject ? collectObjectFields(baseObject, modelName, rawSchemas) : [];
134
+ const baseFields = baseObject ? collectObjectFields(baseObject, modelName) : [];
135
135
 
136
136
  return {
137
137
  modelName,
@@ -146,7 +146,7 @@ function mergeBase(prev: RawSchema | null, next: RawSchema): RawSchema {
146
146
  if (!prev) return next;
147
147
  return {
148
148
  type: 'object',
149
- properties: { ...(prev.properties ?? {}), ...(next.properties ?? {}) },
149
+ properties: { ...prev.properties, ...next.properties },
150
150
  required: [...new Set([...(prev.required ?? []), ...(next.required ?? [])])],
151
151
  };
152
152
  }
@@ -328,48 +328,33 @@ function variantNameSuffix(constValue: string): string {
328
328
  // Field extraction
329
329
  // ---------------------------------------------------------------------------
330
330
 
331
- function collectObjectFields(
332
- schema: RawSchema,
333
- parentName: string,
334
- rawSchemas: Record<string, RawSchema>,
335
- ): FieldSpec[] {
331
+ function collectObjectFields(schema: RawSchema, parentName: string): FieldSpec[] {
336
332
  const props = schema.properties ?? {};
337
333
  const required = new Set(schema.required ?? []);
338
334
  const fields: FieldSpec[] = [];
339
335
  for (const [name, propSchema] of Object.entries(props)) {
340
- fields.push(buildField(name, propSchema, required.has(name), parentName, rawSchemas));
336
+ fields.push(buildField(name, propSchema, required.has(name), parentName));
341
337
  }
342
338
  return fields;
343
339
  }
344
340
 
345
- function variantFields(
346
- fv: FlattenedVariant,
347
- discriminatorProperty: string,
348
- parentName: string,
349
- rawSchemas: Record<string, RawSchema>,
350
- ): FieldSpec[] {
341
+ function variantFields(fv: FlattenedVariant, discriminatorProperty: string, parentName: string): FieldSpec[] {
351
342
  const fields: FieldSpec[] = [];
352
343
  for (const [name, propSchema] of fv.alwaysProperties) {
353
344
  if (name === discriminatorProperty) continue;
354
- fields.push(buildField(name, propSchema, fv.required.has(name), parentName, rawSchemas));
345
+ fields.push(buildField(name, propSchema, fv.required.has(name), parentName));
355
346
  }
356
347
  for (const [name, propSchema] of fv.optionalProperties) {
357
348
  if (name === discriminatorProperty) continue;
358
- fields.push(buildField(name, propSchema, false, parentName, rawSchemas));
349
+ fields.push(buildField(name, propSchema, false, parentName));
359
350
  }
360
351
  return fields;
361
352
  }
362
353
 
363
- function buildField(
364
- rawName: string,
365
- schema: RawSchema,
366
- required: boolean,
367
- parentName: string,
368
- rawSchemas: Record<string, RawSchema>,
369
- ): FieldSpec {
354
+ function buildField(rawName: string, schema: RawSchema, required: boolean, parentName: string): FieldSpec {
370
355
  const modelDeps = new Set<string>();
371
- const domainType = rawSchemaToTS(schema, parentName, rawName, false, modelDeps, rawSchemas);
372
- const wireType = rawSchemaToTS(schema, parentName, rawName, true, modelDeps, rawSchemas);
356
+ const domainType = rawSchemaToTS(schema, parentName, rawName, false, modelDeps);
357
+ const wireType = rawSchemaToTS(schema, parentName, rawName, true, modelDeps);
373
358
  return {
374
359
  name: rawName,
375
360
  description: schema.description,
@@ -404,7 +389,6 @@ function rawSchemaToTS(
404
389
  fieldName: string,
405
390
  isWire: boolean,
406
391
  modelDeps: Set<string>,
407
- rawSchemas: Record<string, RawSchema>,
408
392
  ): string {
409
393
  if (schema.$ref) {
410
394
  const refName = schema.$ref.split('/').pop()!;
@@ -428,7 +412,7 @@ function rawSchemaToTS(
428
412
  } else if (baseType === 'boolean') {
429
413
  core = 'boolean';
430
414
  } else if (baseType === 'array' && schema.items) {
431
- const items = rawSchemaToTS(schema.items, parentName, singularize(fieldName), isWire, modelDeps, rawSchemas);
415
+ const items = rawSchemaToTS(schema.items, parentName, singularize(fieldName), isWire, modelDeps);
432
416
  core = `${parenthesizeUnion(items)}[]`;
433
417
  } else if (baseType === 'object' && schema.properties) {
434
418
  // Inline object — refer to the synthetic model name that
package/src/ruby/rbi.ts CHANGED
@@ -49,7 +49,7 @@ function mapSorbetType(ref: TypeRef): string {
49
49
  if (unique.length === 1) return unique[0];
50
50
  return `T.any(${unique.join(', ')})`;
51
51
  },
52
- nullable: (_ref, inner) => `T.nilable(${inner})`,
52
+ nullable: (_ref, inner) => wrapNilable(inner),
53
53
  literal: (r) =>
54
54
  typeof r.value === 'string'
55
55
  ? 'String'
@@ -95,7 +95,7 @@ export function generateRbiFiles(spec: ApiSpec, ctx: EmitterContext): GeneratedF
95
95
  const fname = fieldName(f.name);
96
96
  if (seenFieldNames.has(fname)) continue;
97
97
  seenFieldNames.add(fname);
98
- const sorbetType = f.required ? mapSorbetType(f.type) : `T.nilable(${unwrapNilable(mapSorbetType(f.type))})`;
98
+ const sorbetType = f.required ? mapSorbetType(f.type) : wrapNilable(mapSorbetType(f.type));
99
99
  lines.push(` sig { returns(${sorbetType}) }`);
100
100
  lines.push(` def ${fname}; end`);
101
101
  lines.push('');
@@ -238,7 +238,7 @@ export function generateRbiFiles(spec: ApiSpec, ctx: EmitterContext): GeneratedF
238
238
  const n = fieldName(f.name);
239
239
  if (seen.has(n)) continue;
240
240
  seen.add(n);
241
- sigParams.push(`${n}: T.nilable(${unwrapNilable(mapSorbetType(f.type))})`);
241
+ sigParams.push(`${n}: ${wrapNilable(mapSorbetType(f.type))}`);
242
242
  }
243
243
  for (const q of queryParams) {
244
244
  if (hiddenParams.has(q.name)) continue;
@@ -246,14 +246,14 @@ export function generateRbiFiles(spec: ApiSpec, ctx: EmitterContext): GeneratedF
246
246
  const n = safeParamName(q.name);
247
247
  if (seen.has(n)) continue;
248
248
  seen.add(n);
249
- sigParams.push(`${n}: T.nilable(${unwrapNilable(mapSorbetType(q.type))})`);
249
+ sigParams.push(`${n}: ${wrapNilable(mapSorbetType(q.type))}`);
250
250
  }
251
251
  for (const group of parameterGroups) {
252
252
  if (!group.optional) continue;
253
253
  const n = fieldName(group.name);
254
254
  if (seen.has(n)) continue;
255
255
  seen.add(n);
256
- sigParams.push(`${n}: T.nilable(${groupSorbetType(group)})`);
256
+ sigParams.push(`${n}: ${wrapNilable(groupSorbetType(group))}`);
257
257
  }
258
258
  sigParams.push('request_options: T::Hash[Symbol, T.untyped]');
259
259
 
@@ -321,6 +321,12 @@ function unwrapNilable(type: string): string {
321
321
  return match ? match[1] : type;
322
322
  }
323
323
 
324
+ /** Wrap a type in T.nilable(), skipping T.untyped (which already includes nil) and avoiding double-wrapping. */
325
+ function wrapNilable(type: string): string {
326
+ if (type === 'T.untyped') return type;
327
+ return `T.nilable(${unwrapNilable(type)})`;
328
+ }
329
+
324
330
  /** Map a response TypeRef to a Sorbet return type. */
325
331
  function mapSorbetReturnType(ref: TypeRef, listWrapperModels: Map<string, Model>, modelNames: Set<string>): string {
326
332
  if (ref.kind === 'model' && listWrapperModels.has(ref.name)) {
@@ -333,7 +339,7 @@ function mapSorbetReturnType(ref: TypeRef, listWrapperModels: Map<string, Model>
333
339
  return `T::Array[WorkOS::${className(ref.items.name)}]`;
334
340
  }
335
341
  if (ref.kind === 'nullable') {
336
- return `T.nilable(${mapSorbetReturnType(ref.inner, listWrapperModels, modelNames)})`;
342
+ return wrapNilable(mapSorbetReturnType(ref.inner, listWrapperModels, modelNames));
337
343
  }
338
344
  if (ref.kind === 'primitive' && ref.type === 'unknown') {
339
345
  return 'NilClass';