@workos/oagen-emitters 0.12.5 → 0.13.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.
@@ -291,806 +291,533 @@ function lowerFirstForDoc(s) {
291
291
  return s.charAt(0).toLowerCase() + s.slice(1);
292
292
  }
293
293
  //#endregion
294
- //#region src/node/naming.ts
295
- /** Strip spec-noise suffixes (e.g., "Dto") from an IR name. */
296
- function stripNoiseSuffixes(name) {
297
- return name.replace(/Dto$/i, "");
294
+ //#region node_modules/js-yaml/dist/js-yaml.mjs
295
+ /*! js-yaml 4.1.1 https://github.com/nodeca/js-yaml @license MIT */
296
+ function isNothing(subject) {
297
+ return typeof subject === "undefined" || subject === null;
298
298
  }
299
- /** kebab-case file name (without extension). */
300
- function fileName$3(name) {
301
- return toKebabCase(stripUrnPrefix(name));
299
+ function isObject(subject) {
300
+ return typeof subject === "object" && subject !== null;
302
301
  }
303
- /** camelCase field name for domain interfaces. */
304
- function fieldName$6(name) {
305
- return toCamelCase(name);
302
+ function toArray(sequence) {
303
+ if (Array.isArray(sequence)) return sequence;
304
+ else if (isNothing(sequence)) return [];
305
+ return [sequence];
306
306
  }
307
- /** snake_case field name for wire/response interfaces. */
308
- function wireFieldName(name) {
309
- return toSnakeCase(name);
307
+ function extend(target, source) {
308
+ var index, length, key, sourceKeys;
309
+ if (source) {
310
+ sourceKeys = Object.keys(source);
311
+ for (index = 0, length = sourceKeys.length; index < length; index += 1) {
312
+ key = sourceKeys[index];
313
+ target[key] = source[key];
314
+ }
315
+ }
316
+ return target;
310
317
  }
311
- /**
312
- * Active set of `Serialized${Name}` interfaces in the live SDK, harvested
313
- * from `ctx.apiSurface` once per generation run. When non-empty, the
314
- * legacy wire-naming scheme wins so existing hand-written serializer files
315
- * continue to compile.
316
- *
317
- * Set by `index.ts` immediately after `getSurface(ctx)` runs.
318
- */
319
- let baselineSerializedNames = /* @__PURE__ */ new Set();
320
- function setBaselineSerializedNames(names) {
321
- baselineSerializedNames = names;
318
+ function repeat(string, count) {
319
+ var result = "", cycle;
320
+ for (cycle = 0; cycle < count; cycle += 1) result += string;
321
+ return result;
322
322
  }
323
- /**
324
- * Set of every interface name present in the baseline live SDK, regardless
325
- * of naming convention. Used to detect single-form baselines (where one
326
- * `*Response`-suffixed interface stands for both the domain and wire shape)
327
- * so we don't synthesize a non-existent `*Wire` variant.
328
- */
329
- let baselineInterfaceNames = /* @__PURE__ */ new Set();
330
- function setBaselineInterfaceNames(names) {
331
- baselineInterfaceNames = names;
323
+ function isNegativeZero(number) {
324
+ return number === 0 && Number.NEGATIVE_INFINITY === 1 / number;
332
325
  }
333
- /**
334
- * IR models that belong to newly-adopted services should not be renamed by
335
- * structural baseline matches from unrelated hand-written services.
336
- */
337
- let adoptedModelNames = /* @__PURE__ */ new Set();
338
- function setAdoptedModelNames(names) {
339
- adoptedModelNames = names;
326
+ var common = {
327
+ isNothing,
328
+ isObject,
329
+ toArray,
330
+ repeat,
331
+ isNegativeZero,
332
+ extend
333
+ };
334
+ function formatError(exception, compact) {
335
+ var where = "", message = exception.reason || "(unknown reason)";
336
+ if (!exception.mark) return message;
337
+ if (exception.mark.name) where += "in \"" + exception.mark.name + "\" ";
338
+ where += "(" + (exception.mark.line + 1) + ":" + (exception.mark.column + 1) + ")";
339
+ if (!compact && exception.mark.snippet) where += "\n\n" + exception.mark.snippet;
340
+ return message + " " + where;
340
341
  }
341
- function isAdoptedModelName(name) {
342
- return adoptedModelNames.has(name);
342
+ function YAMLException$1(reason, mark) {
343
+ Error.call(this);
344
+ this.name = "YAMLException";
345
+ this.reason = reason;
346
+ this.mark = mark;
347
+ this.message = formatError(this, false);
348
+ if (Error.captureStackTrace) Error.captureStackTrace(this, this.constructor);
349
+ else this.stack = (/* @__PURE__ */ new Error()).stack || "";
343
350
  }
344
- /**
345
- * Wire/response interface name.
346
- *
347
- * Resolution order:
348
- * 1. `Serialized${domainName}` if it exists in the baseline (legacy
349
- * workos-node convention; lets hand-written serializer files keep
350
- * compiling).
351
- * 2. `${domainName}Wire` when the domain ends in `Response` AND the
352
- * baseline actually has a `*Wire` interface (avoids
353
- * `FooResponseResponse` stutter).
354
- * 3. The bare `domainName` itself when it already ends in `Response` and
355
- * no `*Wire` variant exists — this happens when the structural matcher
356
- * maps an IR model to a baseline-wire-shaped interface
357
- * (`AuditLogSchemaJson` → `AuditLogSchemaResponse`) and the baseline
358
- * has no separate domain/wire split.
359
- * 4. `${domainName}Response` for the standard fresh-emit case.
360
- */
361
- function wireInterfaceName(domainName) {
362
- const serialized = `Serialized${domainName}`;
363
- if (baselineSerializedNames.has(serialized)) return serialized;
364
- if (domainName.endsWith("Response")) {
365
- const wireForm = `${domainName}Wire`;
366
- if (baselineInterfaceNames.has(wireForm)) return wireForm;
367
- if (baselineInterfaceNames.has(domainName)) return domainName;
368
- return wireForm;
351
+ YAMLException$1.prototype = Object.create(Error.prototype);
352
+ YAMLException$1.prototype.constructor = YAMLException$1;
353
+ YAMLException$1.prototype.toString = function toString(compact) {
354
+ return this.name + ": " + formatError(this, compact);
355
+ };
356
+ var exception = YAMLException$1;
357
+ function getLine(buffer, lineStart, lineEnd, position, maxLineLength) {
358
+ var head = "";
359
+ var tail = "";
360
+ var maxHalfLength = Math.floor(maxLineLength / 2) - 1;
361
+ if (position - lineStart > maxHalfLength) {
362
+ head = " ... ";
363
+ lineStart = position - maxHalfLength + head.length;
369
364
  }
370
- return `${domainName}Response`;
365
+ if (lineEnd - position > maxHalfLength) {
366
+ tail = " ...";
367
+ lineEnd = position + maxHalfLength - tail.length;
368
+ }
369
+ return {
370
+ str: head + buffer.slice(lineStart, lineEnd).replace(/\t/g, "→") + tail,
371
+ pos: position - lineStart + head.length
372
+ };
371
373
  }
372
- /** kebab-case service directory name. */
373
- function serviceDirName(name) {
374
- return toKebabCase(name);
374
+ function padStart(string, max) {
375
+ return common.repeat(" ", max - string.length) + string;
375
376
  }
376
- /** camelCase property name for service accessors on the client. */
377
- function servicePropertyName$4(name) {
378
- return toCamelCase(name);
377
+ function makeSnippet(mark, options) {
378
+ options = Object.create(options || null);
379
+ if (!mark.buffer) return null;
380
+ if (!options.maxLength) options.maxLength = 79;
381
+ if (typeof options.indent !== "number") options.indent = 1;
382
+ if (typeof options.linesBefore !== "number") options.linesBefore = 3;
383
+ if (typeof options.linesAfter !== "number") options.linesAfter = 2;
384
+ var re = /\r?\n|\r|\0/g;
385
+ var lineStarts = [0];
386
+ var lineEnds = [];
387
+ var match;
388
+ var foundLineNo = -1;
389
+ while (match = re.exec(mark.buffer)) {
390
+ lineEnds.push(match.index);
391
+ lineStarts.push(match.index + match[0].length);
392
+ if (mark.position <= match.index && foundLineNo < 0) foundLineNo = lineStarts.length - 2;
393
+ }
394
+ if (foundLineNo < 0) foundLineNo = lineStarts.length - 1;
395
+ var result = "", i, line;
396
+ var lineNoLength = Math.min(mark.line + options.linesAfter, lineEnds.length).toString().length;
397
+ var maxLineLength = options.maxLength - (options.indent + lineNoLength + 3);
398
+ for (i = 1; i <= options.linesBefore; i++) {
399
+ if (foundLineNo - i < 0) break;
400
+ line = getLine(mark.buffer, lineStarts[foundLineNo - i], lineEnds[foundLineNo - i], mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo - i]), maxLineLength);
401
+ result = common.repeat(" ", options.indent) + padStart((mark.line - i + 1).toString(), lineNoLength) + " | " + line.str + "\n" + result;
402
+ }
403
+ line = getLine(mark.buffer, lineStarts[foundLineNo], lineEnds[foundLineNo], mark.position, maxLineLength);
404
+ result += common.repeat(" ", options.indent) + padStart((mark.line + 1).toString(), lineNoLength) + " | " + line.str + "\n";
405
+ result += common.repeat("-", options.indent + lineNoLength + 3 + line.pos) + "^\n";
406
+ for (i = 1; i <= options.linesAfter; i++) {
407
+ if (foundLineNo + i >= lineEnds.length) break;
408
+ line = getLine(mark.buffer, lineStarts[foundLineNo + i], lineEnds[foundLineNo + i], mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo + i]), maxLineLength);
409
+ result += common.repeat(" ", options.indent) + padStart((mark.line + i + 1).toString(), lineNoLength) + " | " + line.str + "\n";
410
+ }
411
+ return result.replace(/\n$/, "");
379
412
  }
380
- /**
381
- * Resolve the effective service name, using the overlay-resolved class name
382
- * when available.
383
- */
384
- function resolveServiceName(service, ctx) {
385
- return resolveClassName$5(service, ctx);
413
+ var snippet = makeSnippet;
414
+ var TYPE_CONSTRUCTOR_OPTIONS = [
415
+ "kind",
416
+ "multi",
417
+ "resolve",
418
+ "construct",
419
+ "instanceOf",
420
+ "predicate",
421
+ "represent",
422
+ "representName",
423
+ "defaultStyle",
424
+ "styleAliases"
425
+ ];
426
+ var YAML_NODE_KINDS = [
427
+ "scalar",
428
+ "sequence",
429
+ "mapping"
430
+ ];
431
+ function compileStyleAliases(map) {
432
+ var result = {};
433
+ if (map !== null) Object.keys(map).forEach(function(style) {
434
+ map[style].forEach(function(alias) {
435
+ result[String(alias)] = style;
436
+ });
437
+ });
438
+ return result;
386
439
  }
387
- /**
388
- * Build a map from IR service name -> resolved service name.
389
- */
390
- function buildServiceNameMap(services, ctx) {
391
- const map = /* @__PURE__ */ new Map();
392
- for (const service of services) map.set(service.name, resolveServiceName(service, ctx));
393
- return map;
440
+ function Type$1(tag, options) {
441
+ options = options || {};
442
+ Object.keys(options).forEach(function(name) {
443
+ if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) throw new exception("Unknown option \"" + name + "\" is met in definition of \"" + tag + "\" YAML type.");
444
+ });
445
+ this.options = options;
446
+ this.tag = tag;
447
+ this.kind = options["kind"] || null;
448
+ this.resolve = options["resolve"] || function() {
449
+ return true;
450
+ };
451
+ this.construct = options["construct"] || function(data) {
452
+ return data;
453
+ };
454
+ this.instanceOf = options["instanceOf"] || null;
455
+ this.predicate = options["predicate"] || null;
456
+ this.represent = options["represent"] || null;
457
+ this.representName = options["representName"] || null;
458
+ this.defaultStyle = options["defaultStyle"] || null;
459
+ this.multi = options["multi"] || false;
460
+ this.styleAliases = compileStyleAliases(options["styleAliases"] || null);
461
+ if (YAML_NODE_KINDS.indexOf(this.kind) === -1) throw new exception("Unknown kind \"" + this.kind + "\" is specified for \"" + tag + "\" YAML type.");
394
462
  }
395
- /** Resolve the output directory for a service. */
396
- function resolveServiceDir$1(resolvedServiceName) {
397
- return serviceDirName(resolvedServiceName);
463
+ var type = Type$1;
464
+ function compileList(schema, name) {
465
+ var result = [];
466
+ schema[name].forEach(function(currentType) {
467
+ var newIndex = result.length;
468
+ result.forEach(function(previousType, previousIndex) {
469
+ if (previousType.tag === currentType.tag && previousType.kind === currentType.kind && previousType.multi === currentType.multi) newIndex = previousIndex;
470
+ });
471
+ result[newIndex] = currentType;
472
+ });
473
+ return result;
398
474
  }
399
- /** Resolve the SDK method name for an operation, using resolved operations first. */
400
- function resolveMethodName$6(op, _service, ctx) {
401
- const resolved = lookupMethodName(op, buildResolvedLookup(ctx));
402
- if (resolved) return toCamelCase(resolved);
403
- const httpKey = `${op.httpMethod.toUpperCase()} ${op.path}`;
404
- const existing = ctx.overlayLookup?.methodByOperation?.get(httpKey);
405
- if (existing) return existing.methodName;
406
- return toCamelCase(op.name);
407
- }
408
- /** Resolve the SDK class name for a service, using resolved ops mountOn as canonical. */
409
- function resolveClassName$5(service, ctx) {
410
- for (const r of ctx.resolvedOperations ?? []) if (r.service.name === service.name) return r.mountOn;
411
- if (ctx.overlayLookup?.methodByOperation) for (const op of service.operations) {
412
- const httpKey = `${op.httpMethod.toUpperCase()} ${op.path}`;
413
- const existing = ctx.overlayLookup.methodByOperation.get(httpKey);
414
- if (existing) return existing.className;
475
+ function compileMap() {
476
+ var result = {
477
+ scalar: {},
478
+ sequence: {},
479
+ mapping: {},
480
+ fallback: {},
481
+ multi: {
482
+ scalar: [],
483
+ sequence: [],
484
+ mapping: [],
485
+ fallback: []
486
+ }
487
+ }, index, length;
488
+ function collectType(type) {
489
+ if (type.multi) {
490
+ result.multi[type.kind].push(type);
491
+ result.multi["fallback"].push(type);
492
+ } else result[type.kind][type.tag] = result["fallback"][type.tag] = type;
415
493
  }
416
- return toPascalCase(service.name);
494
+ for (index = 0, length = arguments.length; index < length; index += 1) arguments[index].forEach(collectType);
495
+ return result;
417
496
  }
418
- /**
419
- * Resolve the interface name for a model, checking overlay first.
420
- *
421
- * Lookup order:
422
- * 1. `overlayLookup.interfaceByName` exact-name overrides from the live SDK.
423
- * 2. `overlayLookup.modelNameByIR` structurally-inferred matches (e.g., IR
424
- * `ValidateApiKey` with one field `value: string` → live SDK interface
425
- * `ValidateApiKeyOptions`).
426
- * 3. Type-alias resolution (when an alias points to an interface).
427
- * 4. Suffix-fallback heuristic for the workos-node `*Options` convention:
428
- * when the IR name `X` has no baseline match but `XOptions` does, use
429
- * `XOptions`. The convention is widely used for request-body interfaces
430
- * in workos-node (CreateOrganizationOptions, ListUsersOptions, etc.).
431
- * 5. Default clean and PascalCase the IR name.
432
- */
433
- function resolveInterfaceName(name, ctx, opts) {
434
- const existing = ctx.overlayLookup?.interfaceByName?.get(name);
435
- if (existing) return existing;
436
- let inferred = adoptedModelNames.has(name) ? void 0 : ctx.overlayLookup?.modelNameByIR?.get(name);
437
- if (inferred) {
438
- if (inferred.startsWith("Serialized")) {
439
- const stripped = inferred.slice(10);
440
- if (stripped && ctx.apiSurface?.interfaces?.[stripped]) inferred = stripped;
497
+ function Schema$1(definition) {
498
+ return this.extend(definition);
499
+ }
500
+ Schema$1.prototype.extend = function extend(definition) {
501
+ var implicit = [];
502
+ var explicit = [];
503
+ if (definition instanceof type) explicit.push(definition);
504
+ else if (Array.isArray(definition)) explicit = explicit.concat(definition);
505
+ else if (definition && (Array.isArray(definition.implicit) || Array.isArray(definition.explicit))) {
506
+ if (definition.implicit) implicit = implicit.concat(definition.implicit);
507
+ if (definition.explicit) explicit = explicit.concat(definition.explicit);
508
+ } else throw new exception("Schema.extend argument should be a Type, [ Type ], or a schema definition ({ implicit: [...], explicit: [...] })");
509
+ implicit.forEach(function(type$1) {
510
+ if (!(type$1 instanceof type)) throw new exception("Specified list of YAML types (or a single Type object) contains a non-Type object.");
511
+ if (type$1.loadKind && type$1.loadKind !== "scalar") throw new exception("There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.");
512
+ if (type$1.multi) throw new exception("There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.");
513
+ });
514
+ explicit.forEach(function(type$1) {
515
+ if (!(type$1 instanceof type)) throw new exception("Specified list of YAML types (or a single Type object) contains a non-Type object.");
516
+ });
517
+ var result = Object.create(Schema$1.prototype);
518
+ result.implicit = (this.implicit || []).concat(implicit);
519
+ result.explicit = (this.explicit || []).concat(explicit);
520
+ result.compiledImplicit = compileList(result, "implicit");
521
+ result.compiledExplicit = compileList(result, "explicit");
522
+ result.compiledTypeMap = compileMap(result.compiledImplicit, result.compiledExplicit);
523
+ return result;
524
+ };
525
+ var failsafe = new Schema$1({ explicit: [
526
+ new type("tag:yaml.org,2002:str", {
527
+ kind: "scalar",
528
+ construct: function(data) {
529
+ return data !== null ? data : "";
441
530
  }
442
- if (inferred.endsWith("Response") && ctx.apiSurface?.interfaces) {
443
- const stripped = inferred.slice(0, -8);
444
- if (stripped && ctx.apiSurface.interfaces[stripped]) inferred = stripped;
531
+ }),
532
+ new type("tag:yaml.org,2002:seq", {
533
+ kind: "sequence",
534
+ construct: function(data) {
535
+ return data !== null ? data : [];
445
536
  }
446
- return inferred;
447
- }
448
- if (!opts?.skipTypeAlias && ctx.apiSurface?.typeAliases) {
449
- const alias = ctx.apiSurface.typeAliases[name];
450
- if (alias?.value && ctx.apiSurface.interfaces?.[alias.value]) return alias.value;
451
- }
452
- if (ctx.apiSurface?.interfaces) {
453
- const ifaces = ctx.apiSurface.interfaces;
454
- if (!ifaces[name]) {
455
- const optionsCandidate = `${name}Options`;
456
- const optionsInfo = ifaces[optionsCandidate];
457
- if (optionsInfo?.sourceFile) {
458
- const expectedStem = toKebabCase(stripUrnPrefix(name));
459
- if (optionsInfo.sourceFile.endsWith(`/${expectedStem}.interface.ts`)) return optionsCandidate;
460
- }
537
+ }),
538
+ new type("tag:yaml.org,2002:map", {
539
+ kind: "mapping",
540
+ construct: function(data) {
541
+ return data !== null ? data : {};
461
542
  }
462
- }
463
- return toPascalCase(stripUrnPrefix(ctx.apiSurface ? name : stripNoiseSuffixes(name)));
543
+ })
544
+ ] });
545
+ function resolveYamlNull(data) {
546
+ if (data === null) return true;
547
+ var max = data.length;
548
+ return max === 1 && data === "~" || max === 4 && (data === "null" || data === "Null" || data === "NULL");
464
549
  }
465
- //#endregion
466
- //#region src/node/type-map.ts
467
- /**
468
- * Map of enum name → inlined string-union TS source.
469
- *
470
- * Set by `index.ts` once per generation run, sourced from `spec.enums` for
471
- * enums that have no baseline definition in the live SDK. When populated,
472
- * `mapTypeRef`/`mapWireTypeRef` substitute the union directly at the
473
- * reference site instead of emitting a separate import — this collapses
474
- * ~100 single-line enum files into inline literal types.
475
- */
476
- let inlineEnumUnions = /* @__PURE__ */ new Map();
477
- function setInlineEnumUnions(map) {
478
- inlineEnumUnions = map;
550
+ function constructYamlNull() {
551
+ return null;
479
552
  }
480
- function isInlineEnum(name) {
481
- return inlineEnumUnions.has(name);
553
+ function isNull(object) {
554
+ return object === null;
482
555
  }
483
- /**
484
- * Optional callback that resolves an IR model name to its live-SDK interface
485
- * name. Set by `index.ts` once per run. When present, `mapTypeRef` and
486
- * `mapWireTypeRef` use it instead of the raw IR name in their `model:` cases
487
- * — keeping field-type references in sync with import statements that the
488
- * caller emits via the same resolver. Without this, a structural match like
489
- * IR `AuditLogSchemaJson` → live `AuditLogSchemaResponse` would produce
490
- * `schema: AuditLogSchemaJson` in the body but
491
- * `import type { AuditLogSchemaResponse }` in the imports, leaving
492
- * `AuditLogSchemaJson` unbound.
493
- */
494
- let domainNameResolver = null;
495
- function setDomainNameResolver(fn) {
496
- domainNameResolver = fn;
556
+ var _null = new type("tag:yaml.org,2002:null", {
557
+ kind: "scalar",
558
+ resolve: resolveYamlNull,
559
+ construct: constructYamlNull,
560
+ predicate: isNull,
561
+ represent: {
562
+ canonical: function() {
563
+ return "~";
564
+ },
565
+ lowercase: function() {
566
+ return "null";
567
+ },
568
+ uppercase: function() {
569
+ return "NULL";
570
+ },
571
+ camelcase: function() {
572
+ return "Null";
573
+ },
574
+ empty: function() {
575
+ return "";
576
+ }
577
+ },
578
+ defaultStyle: "lowercase"
579
+ });
580
+ function resolveYamlBoolean(data) {
581
+ if (data === null) return false;
582
+ var max = data.length;
583
+ return max === 4 && (data === "true" || data === "True" || data === "TRUE") || max === 5 && (data === "false" || data === "False" || data === "FALSE");
497
584
  }
498
- function resolveDomainName(irName) {
499
- return domainNameResolver ? domainNameResolver(irName) : irName;
585
+ function constructYamlBoolean(data) {
586
+ return data === "true" || data === "True" || data === "TRUE";
500
587
  }
501
- /**
502
- * Map an IR TypeRef to a TypeScript domain type string.
503
- * Domain types use PascalCase model names (e.g., `Organization`).
504
- */
505
- function mapTypeRef$7(ref, opts) {
506
- const genericDefaults = opts?.genericDefaults;
507
- return mapTypeRef(ref, {
508
- primitive: mapPrimitive$6,
509
- array: (_r, items) => `${parenthesizeUnion(items)}[]`,
510
- model: (r) => resolveDomainName(r.name) + (genericDefaults?.get(r.name) ?? ""),
511
- enum: (r) => inlineEnumUnions.get(r.name) ?? r.name,
512
- union: (r, variants) => joinUnionVariants$5(r, variants),
513
- nullable: (_r, inner) => `${inner} | null`,
514
- literal: (r) => typeof r.value === "string" ? `'${r.value}'` : String(r.value),
515
- map: (_r, value) => `Record<string, ${value}>`
516
- });
588
+ function isBoolean(object) {
589
+ return Object.prototype.toString.call(object) === "[object Boolean]";
517
590
  }
518
- /**
519
- * Map an IR TypeRef to a TypeScript wire/response type string.
520
- * Model references get the `Response` suffix (e.g., `OrganizationResponse`).
521
- */
522
- function mapWireTypeRef(ref, opts) {
523
- const genericDefaults = opts?.genericDefaults;
524
- return mapTypeRef(ref, {
525
- primitive: mapWirePrimitive,
526
- array: (_r, items) => `${parenthesizeUnion(items)}[]`,
527
- model: (r) => wireInterfaceName(resolveDomainName(r.name)) + (genericDefaults?.get(r.name) ?? ""),
528
- enum: (r) => inlineEnumUnions.get(r.name) ?? r.name,
529
- union: (r, variants) => joinUnionVariants$5(r, variants),
530
- nullable: (_r, inner) => `${inner} | null`,
531
- literal: (r) => typeof r.value === "string" ? `'${r.value}'` : String(r.value),
532
- map: (_r, value) => `Record<string, ${value}>`
533
- });
591
+ var bool = new type("tag:yaml.org,2002:bool", {
592
+ kind: "scalar",
593
+ resolve: resolveYamlBoolean,
594
+ construct: constructYamlBoolean,
595
+ predicate: isBoolean,
596
+ represent: {
597
+ lowercase: function(object) {
598
+ return object ? "true" : "false";
599
+ },
600
+ uppercase: function(object) {
601
+ return object ? "TRUE" : "FALSE";
602
+ },
603
+ camelcase: function(object) {
604
+ return object ? "True" : "False";
605
+ }
606
+ },
607
+ defaultStyle: "lowercase"
608
+ });
609
+ function isHexCode(c) {
610
+ return 48 <= c && c <= 57 || 65 <= c && c <= 70 || 97 <= c && c <= 102;
534
611
  }
535
- function mapPrimitive$6(ref) {
536
- if (ref.format) switch (ref.format) {
537
- case "date-time": return "Date";
538
- case "int64": return "bigint";
539
- }
540
- switch (ref.type) {
541
- case "string": return "string";
542
- case "integer":
543
- case "number": return "number";
544
- case "boolean": return "boolean";
545
- case "unknown": return "any";
546
- }
547
- }
548
- function mapWirePrimitive(ref) {
549
- switch (ref.type) {
550
- case "string": return "string";
551
- case "integer":
552
- case "number": return "number";
553
- case "boolean": return "boolean";
554
- case "unknown": return "any";
555
- }
556
- }
557
- function joinUnionVariants$5(ref, variants) {
558
- const unique = [...new Set(variants)];
559
- if (ref.compositionKind === "allOf") return unique.join(" & ");
560
- if (unique.length === 1) return unique[0];
561
- return unique.join(" | ");
562
- }
563
- function parenthesizeUnion(type) {
564
- return type.includes(" | ") || type.includes(" & ") ? `(${type})` : type;
565
- }
566
- //#endregion
567
- //#region node_modules/js-yaml/dist/js-yaml.mjs
568
- /*! js-yaml 4.1.1 https://github.com/nodeca/js-yaml @license MIT */
569
- function isNothing(subject) {
570
- return typeof subject === "undefined" || subject === null;
571
- }
572
- function isObject(subject) {
573
- return typeof subject === "object" && subject !== null;
612
+ function isOctCode(c) {
613
+ return 48 <= c && c <= 55;
574
614
  }
575
- function toArray(sequence) {
576
- if (Array.isArray(sequence)) return sequence;
577
- else if (isNothing(sequence)) return [];
578
- return [sequence];
615
+ function isDecCode(c) {
616
+ return 48 <= c && c <= 57;
579
617
  }
580
- function extend(target, source) {
581
- var index, length, key, sourceKeys;
582
- if (source) {
583
- sourceKeys = Object.keys(source);
584
- for (index = 0, length = sourceKeys.length; index < length; index += 1) {
585
- key = sourceKeys[index];
586
- target[key] = source[key];
618
+ function resolveYamlInteger(data) {
619
+ if (data === null) return false;
620
+ var max = data.length, index = 0, hasDigits = false, ch;
621
+ if (!max) return false;
622
+ ch = data[index];
623
+ if (ch === "-" || ch === "+") ch = data[++index];
624
+ if (ch === "0") {
625
+ if (index + 1 === max) return true;
626
+ ch = data[++index];
627
+ if (ch === "b") {
628
+ index++;
629
+ for (; index < max; index++) {
630
+ ch = data[index];
631
+ if (ch === "_") continue;
632
+ if (ch !== "0" && ch !== "1") return false;
633
+ hasDigits = true;
634
+ }
635
+ return hasDigits && ch !== "_";
636
+ }
637
+ if (ch === "x") {
638
+ index++;
639
+ for (; index < max; index++) {
640
+ ch = data[index];
641
+ if (ch === "_") continue;
642
+ if (!isHexCode(data.charCodeAt(index))) return false;
643
+ hasDigits = true;
644
+ }
645
+ return hasDigits && ch !== "_";
646
+ }
647
+ if (ch === "o") {
648
+ index++;
649
+ for (; index < max; index++) {
650
+ ch = data[index];
651
+ if (ch === "_") continue;
652
+ if (!isOctCode(data.charCodeAt(index))) return false;
653
+ hasDigits = true;
654
+ }
655
+ return hasDigits && ch !== "_";
587
656
  }
588
657
  }
589
- return target;
590
- }
591
- function repeat(string, count) {
592
- var result = "", cycle;
593
- for (cycle = 0; cycle < count; cycle += 1) result += string;
594
- return result;
595
- }
596
- function isNegativeZero(number) {
597
- return number === 0 && Number.NEGATIVE_INFINITY === 1 / number;
658
+ if (ch === "_") return false;
659
+ for (; index < max; index++) {
660
+ ch = data[index];
661
+ if (ch === "_") continue;
662
+ if (!isDecCode(data.charCodeAt(index))) return false;
663
+ hasDigits = true;
664
+ }
665
+ if (!hasDigits || ch === "_") return false;
666
+ return true;
598
667
  }
599
- var common = {
600
- isNothing,
601
- isObject,
602
- toArray,
603
- repeat,
604
- isNegativeZero,
605
- extend
606
- };
607
- function formatError(exception, compact) {
608
- var where = "", message = exception.reason || "(unknown reason)";
609
- if (!exception.mark) return message;
610
- if (exception.mark.name) where += "in \"" + exception.mark.name + "\" ";
611
- where += "(" + (exception.mark.line + 1) + ":" + (exception.mark.column + 1) + ")";
612
- if (!compact && exception.mark.snippet) where += "\n\n" + exception.mark.snippet;
613
- return message + " " + where;
668
+ function constructYamlInteger(data) {
669
+ var value = data, sign = 1, ch;
670
+ if (value.indexOf("_") !== -1) value = value.replace(/_/g, "");
671
+ ch = value[0];
672
+ if (ch === "-" || ch === "+") {
673
+ if (ch === "-") sign = -1;
674
+ value = value.slice(1);
675
+ ch = value[0];
676
+ }
677
+ if (value === "0") return 0;
678
+ if (ch === "0") {
679
+ if (value[1] === "b") return sign * parseInt(value.slice(2), 2);
680
+ if (value[1] === "x") return sign * parseInt(value.slice(2), 16);
681
+ if (value[1] === "o") return sign * parseInt(value.slice(2), 8);
682
+ }
683
+ return sign * parseInt(value, 10);
614
684
  }
615
- function YAMLException$1(reason, mark) {
616
- Error.call(this);
617
- this.name = "YAMLException";
618
- this.reason = reason;
619
- this.mark = mark;
620
- this.message = formatError(this, false);
621
- if (Error.captureStackTrace) Error.captureStackTrace(this, this.constructor);
622
- else this.stack = (/* @__PURE__ */ new Error()).stack || "";
685
+ function isInteger(object) {
686
+ return Object.prototype.toString.call(object) === "[object Number]" && object % 1 === 0 && !common.isNegativeZero(object);
623
687
  }
624
- YAMLException$1.prototype = Object.create(Error.prototype);
625
- YAMLException$1.prototype.constructor = YAMLException$1;
626
- YAMLException$1.prototype.toString = function toString(compact) {
627
- return this.name + ": " + formatError(this, compact);
628
- };
629
- var exception = YAMLException$1;
630
- function getLine(buffer, lineStart, lineEnd, position, maxLineLength) {
631
- var head = "";
632
- var tail = "";
633
- var maxHalfLength = Math.floor(maxLineLength / 2) - 1;
634
- if (position - lineStart > maxHalfLength) {
635
- head = " ... ";
636
- lineStart = position - maxHalfLength + head.length;
637
- }
638
- if (lineEnd - position > maxHalfLength) {
639
- tail = " ...";
640
- lineEnd = position + maxHalfLength - tail.length;
688
+ var int = new type("tag:yaml.org,2002:int", {
689
+ kind: "scalar",
690
+ resolve: resolveYamlInteger,
691
+ construct: constructYamlInteger,
692
+ predicate: isInteger,
693
+ represent: {
694
+ binary: function(obj) {
695
+ return obj >= 0 ? "0b" + obj.toString(2) : "-0b" + obj.toString(2).slice(1);
696
+ },
697
+ octal: function(obj) {
698
+ return obj >= 0 ? "0o" + obj.toString(8) : "-0o" + obj.toString(8).slice(1);
699
+ },
700
+ decimal: function(obj) {
701
+ return obj.toString(10);
702
+ },
703
+ hexadecimal: function(obj) {
704
+ return obj >= 0 ? "0x" + obj.toString(16).toUpperCase() : "-0x" + obj.toString(16).toUpperCase().slice(1);
705
+ }
706
+ },
707
+ defaultStyle: "decimal",
708
+ styleAliases: {
709
+ binary: [2, "bin"],
710
+ octal: [8, "oct"],
711
+ decimal: [10, "dec"],
712
+ hexadecimal: [16, "hex"]
641
713
  }
642
- return {
643
- str: head + buffer.slice(lineStart, lineEnd).replace(/\t/g, "→") + tail,
644
- pos: position - lineStart + head.length
645
- };
714
+ });
715
+ var YAML_FLOAT_PATTERN = /* @__PURE__ */ new RegExp("^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$");
716
+ function resolveYamlFloat(data) {
717
+ if (data === null) return false;
718
+ if (!YAML_FLOAT_PATTERN.test(data) || data[data.length - 1] === "_") return false;
719
+ return true;
646
720
  }
647
- function padStart(string, max) {
648
- return common.repeat(" ", max - string.length) + string;
721
+ function constructYamlFloat(data) {
722
+ var value = data.replace(/_/g, "").toLowerCase(), sign = value[0] === "-" ? -1 : 1;
723
+ if ("+-".indexOf(value[0]) >= 0) value = value.slice(1);
724
+ if (value === ".inf") return sign === 1 ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;
725
+ else if (value === ".nan") return NaN;
726
+ return sign * parseFloat(value, 10);
649
727
  }
650
- function makeSnippet(mark, options) {
651
- options = Object.create(options || null);
652
- if (!mark.buffer) return null;
653
- if (!options.maxLength) options.maxLength = 79;
654
- if (typeof options.indent !== "number") options.indent = 1;
655
- if (typeof options.linesBefore !== "number") options.linesBefore = 3;
656
- if (typeof options.linesAfter !== "number") options.linesAfter = 2;
657
- var re = /\r?\n|\r|\0/g;
658
- var lineStarts = [0];
659
- var lineEnds = [];
660
- var match;
661
- var foundLineNo = -1;
662
- while (match = re.exec(mark.buffer)) {
663
- lineEnds.push(match.index);
664
- lineStarts.push(match.index + match[0].length);
665
- if (mark.position <= match.index && foundLineNo < 0) foundLineNo = lineStarts.length - 2;
728
+ var SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/;
729
+ function representYamlFloat(object, style) {
730
+ var res;
731
+ if (isNaN(object)) switch (style) {
732
+ case "lowercase": return ".nan";
733
+ case "uppercase": return ".NAN";
734
+ case "camelcase": return ".NaN";
666
735
  }
667
- if (foundLineNo < 0) foundLineNo = lineStarts.length - 1;
668
- var result = "", i, line;
669
- var lineNoLength = Math.min(mark.line + options.linesAfter, lineEnds.length).toString().length;
670
- var maxLineLength = options.maxLength - (options.indent + lineNoLength + 3);
671
- for (i = 1; i <= options.linesBefore; i++) {
672
- if (foundLineNo - i < 0) break;
673
- line = getLine(mark.buffer, lineStarts[foundLineNo - i], lineEnds[foundLineNo - i], mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo - i]), maxLineLength);
674
- result = common.repeat(" ", options.indent) + padStart((mark.line - i + 1).toString(), lineNoLength) + " | " + line.str + "\n" + result;
736
+ else if (Number.POSITIVE_INFINITY === object) switch (style) {
737
+ case "lowercase": return ".inf";
738
+ case "uppercase": return ".INF";
739
+ case "camelcase": return ".Inf";
675
740
  }
676
- line = getLine(mark.buffer, lineStarts[foundLineNo], lineEnds[foundLineNo], mark.position, maxLineLength);
677
- result += common.repeat(" ", options.indent) + padStart((mark.line + 1).toString(), lineNoLength) + " | " + line.str + "\n";
678
- result += common.repeat("-", options.indent + lineNoLength + 3 + line.pos) + "^\n";
679
- for (i = 1; i <= options.linesAfter; i++) {
680
- if (foundLineNo + i >= lineEnds.length) break;
681
- line = getLine(mark.buffer, lineStarts[foundLineNo + i], lineEnds[foundLineNo + i], mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo + i]), maxLineLength);
682
- result += common.repeat(" ", options.indent) + padStart((mark.line + i + 1).toString(), lineNoLength) + " | " + line.str + "\n";
741
+ else if (Number.NEGATIVE_INFINITY === object) switch (style) {
742
+ case "lowercase": return "-.inf";
743
+ case "uppercase": return "-.INF";
744
+ case "camelcase": return "-.Inf";
683
745
  }
684
- return result.replace(/\n$/, "");
746
+ else if (common.isNegativeZero(object)) return "-0.0";
747
+ res = object.toString(10);
748
+ return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace("e", ".e") : res;
685
749
  }
686
- var snippet = makeSnippet;
687
- var TYPE_CONSTRUCTOR_OPTIONS = [
688
- "kind",
689
- "multi",
690
- "resolve",
691
- "construct",
692
- "instanceOf",
693
- "predicate",
694
- "represent",
695
- "representName",
696
- "defaultStyle",
697
- "styleAliases"
698
- ];
699
- var YAML_NODE_KINDS = [
700
- "scalar",
701
- "sequence",
702
- "mapping"
703
- ];
704
- function compileStyleAliases(map) {
705
- var result = {};
706
- if (map !== null) Object.keys(map).forEach(function(style) {
707
- map[style].forEach(function(alias) {
708
- result[String(alias)] = style;
709
- });
710
- });
711
- return result;
712
- }
713
- function Type$1(tag, options) {
714
- options = options || {};
715
- Object.keys(options).forEach(function(name) {
716
- if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) throw new exception("Unknown option \"" + name + "\" is met in definition of \"" + tag + "\" YAML type.");
717
- });
718
- this.options = options;
719
- this.tag = tag;
720
- this.kind = options["kind"] || null;
721
- this.resolve = options["resolve"] || function() {
722
- return true;
723
- };
724
- this.construct = options["construct"] || function(data) {
725
- return data;
726
- };
727
- this.instanceOf = options["instanceOf"] || null;
728
- this.predicate = options["predicate"] || null;
729
- this.represent = options["represent"] || null;
730
- this.representName = options["representName"] || null;
731
- this.defaultStyle = options["defaultStyle"] || null;
732
- this.multi = options["multi"] || false;
733
- this.styleAliases = compileStyleAliases(options["styleAliases"] || null);
734
- if (YAML_NODE_KINDS.indexOf(this.kind) === -1) throw new exception("Unknown kind \"" + this.kind + "\" is specified for \"" + tag + "\" YAML type.");
735
- }
736
- var type = Type$1;
737
- function compileList(schema, name) {
738
- var result = [];
739
- schema[name].forEach(function(currentType) {
740
- var newIndex = result.length;
741
- result.forEach(function(previousType, previousIndex) {
742
- if (previousType.tag === currentType.tag && previousType.kind === currentType.kind && previousType.multi === currentType.multi) newIndex = previousIndex;
743
- });
744
- result[newIndex] = currentType;
745
- });
746
- return result;
747
- }
748
- function compileMap() {
749
- var result = {
750
- scalar: {},
751
- sequence: {},
752
- mapping: {},
753
- fallback: {},
754
- multi: {
755
- scalar: [],
756
- sequence: [],
757
- mapping: [],
758
- fallback: []
759
- }
760
- }, index, length;
761
- function collectType(type) {
762
- if (type.multi) {
763
- result.multi[type.kind].push(type);
764
- result.multi["fallback"].push(type);
765
- } else result[type.kind][type.tag] = result["fallback"][type.tag] = type;
766
- }
767
- for (index = 0, length = arguments.length; index < length; index += 1) arguments[index].forEach(collectType);
768
- return result;
769
- }
770
- function Schema$1(definition) {
771
- return this.extend(definition);
772
- }
773
- Schema$1.prototype.extend = function extend(definition) {
774
- var implicit = [];
775
- var explicit = [];
776
- if (definition instanceof type) explicit.push(definition);
777
- else if (Array.isArray(definition)) explicit = explicit.concat(definition);
778
- else if (definition && (Array.isArray(definition.implicit) || Array.isArray(definition.explicit))) {
779
- if (definition.implicit) implicit = implicit.concat(definition.implicit);
780
- if (definition.explicit) explicit = explicit.concat(definition.explicit);
781
- } else throw new exception("Schema.extend argument should be a Type, [ Type ], or a schema definition ({ implicit: [...], explicit: [...] })");
782
- implicit.forEach(function(type$1) {
783
- if (!(type$1 instanceof type)) throw new exception("Specified list of YAML types (or a single Type object) contains a non-Type object.");
784
- if (type$1.loadKind && type$1.loadKind !== "scalar") throw new exception("There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.");
785
- if (type$1.multi) throw new exception("There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.");
786
- });
787
- explicit.forEach(function(type$1) {
788
- if (!(type$1 instanceof type)) throw new exception("Specified list of YAML types (or a single Type object) contains a non-Type object.");
789
- });
790
- var result = Object.create(Schema$1.prototype);
791
- result.implicit = (this.implicit || []).concat(implicit);
792
- result.explicit = (this.explicit || []).concat(explicit);
793
- result.compiledImplicit = compileList(result, "implicit");
794
- result.compiledExplicit = compileList(result, "explicit");
795
- result.compiledTypeMap = compileMap(result.compiledImplicit, result.compiledExplicit);
796
- return result;
797
- };
798
- var failsafe = new Schema$1({ explicit: [
799
- new type("tag:yaml.org,2002:str", {
800
- kind: "scalar",
801
- construct: function(data) {
802
- return data !== null ? data : "";
803
- }
804
- }),
805
- new type("tag:yaml.org,2002:seq", {
806
- kind: "sequence",
807
- construct: function(data) {
808
- return data !== null ? data : [];
809
- }
810
- }),
811
- new type("tag:yaml.org,2002:map", {
812
- kind: "mapping",
813
- construct: function(data) {
814
- return data !== null ? data : {};
815
- }
816
- })
817
- ] });
818
- function resolveYamlNull(data) {
819
- if (data === null) return true;
820
- var max = data.length;
821
- return max === 1 && data === "~" || max === 4 && (data === "null" || data === "Null" || data === "NULL");
822
- }
823
- function constructYamlNull() {
824
- return null;
825
- }
826
- function isNull(object) {
827
- return object === null;
750
+ function isFloat(object) {
751
+ return Object.prototype.toString.call(object) === "[object Number]" && (object % 1 !== 0 || common.isNegativeZero(object));
828
752
  }
829
- var _null = new type("tag:yaml.org,2002:null", {
753
+ var float = new type("tag:yaml.org,2002:float", {
830
754
  kind: "scalar",
831
- resolve: resolveYamlNull,
832
- construct: constructYamlNull,
833
- predicate: isNull,
834
- represent: {
835
- canonical: function() {
836
- return "~";
837
- },
838
- lowercase: function() {
839
- return "null";
840
- },
841
- uppercase: function() {
842
- return "NULL";
843
- },
844
- camelcase: function() {
845
- return "Null";
846
- },
847
- empty: function() {
848
- return "";
849
- }
850
- },
755
+ resolve: resolveYamlFloat,
756
+ construct: constructYamlFloat,
757
+ predicate: isFloat,
758
+ represent: representYamlFloat,
851
759
  defaultStyle: "lowercase"
852
760
  });
853
- function resolveYamlBoolean(data) {
761
+ var core = failsafe.extend({ implicit: [
762
+ _null,
763
+ bool,
764
+ int,
765
+ float
766
+ ] });
767
+ var YAML_DATE_REGEXP = /* @__PURE__ */ new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$");
768
+ var YAML_TIMESTAMP_REGEXP = /* @__PURE__ */ new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$");
769
+ function resolveYamlTimestamp(data) {
854
770
  if (data === null) return false;
855
- var max = data.length;
856
- return max === 4 && (data === "true" || data === "True" || data === "TRUE") || max === 5 && (data === "false" || data === "False" || data === "FALSE");
771
+ if (YAML_DATE_REGEXP.exec(data) !== null) return true;
772
+ if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true;
773
+ return false;
857
774
  }
858
- function constructYamlBoolean(data) {
859
- return data === "true" || data === "True" || data === "TRUE";
775
+ function constructYamlTimestamp(data) {
776
+ var match, year, month, day, hour, minute, second, fraction = 0, delta = null, tz_hour, tz_minute, date;
777
+ match = YAML_DATE_REGEXP.exec(data);
778
+ if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data);
779
+ if (match === null) throw new Error("Date resolve error");
780
+ year = +match[1];
781
+ month = +match[2] - 1;
782
+ day = +match[3];
783
+ if (!match[4]) return new Date(Date.UTC(year, month, day));
784
+ hour = +match[4];
785
+ minute = +match[5];
786
+ second = +match[6];
787
+ if (match[7]) {
788
+ fraction = match[7].slice(0, 3);
789
+ while (fraction.length < 3) fraction += "0";
790
+ fraction = +fraction;
791
+ }
792
+ if (match[9]) {
793
+ tz_hour = +match[10];
794
+ tz_minute = +(match[11] || 0);
795
+ delta = (tz_hour * 60 + tz_minute) * 6e4;
796
+ if (match[9] === "-") delta = -delta;
797
+ }
798
+ date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction));
799
+ if (delta) date.setTime(date.getTime() - delta);
800
+ return date;
860
801
  }
861
- function isBoolean(object) {
862
- return Object.prototype.toString.call(object) === "[object Boolean]";
802
+ function representYamlTimestamp(object) {
803
+ return object.toISOString();
863
804
  }
864
- var bool = new type("tag:yaml.org,2002:bool", {
805
+ var timestamp = new type("tag:yaml.org,2002:timestamp", {
865
806
  kind: "scalar",
866
- resolve: resolveYamlBoolean,
867
- construct: constructYamlBoolean,
868
- predicate: isBoolean,
869
- represent: {
870
- lowercase: function(object) {
871
- return object ? "true" : "false";
872
- },
873
- uppercase: function(object) {
874
- return object ? "TRUE" : "FALSE";
875
- },
876
- camelcase: function(object) {
877
- return object ? "True" : "False";
878
- }
879
- },
880
- defaultStyle: "lowercase"
807
+ resolve: resolveYamlTimestamp,
808
+ construct: constructYamlTimestamp,
809
+ instanceOf: Date,
810
+ represent: representYamlTimestamp
881
811
  });
882
- function isHexCode(c) {
883
- return 48 <= c && c <= 57 || 65 <= c && c <= 70 || 97 <= c && c <= 102;
884
- }
885
- function isOctCode(c) {
886
- return 48 <= c && c <= 55;
887
- }
888
- function isDecCode(c) {
889
- return 48 <= c && c <= 57;
812
+ function resolveYamlMerge(data) {
813
+ return data === "<<" || data === null;
890
814
  }
891
- function resolveYamlInteger(data) {
892
- if (data === null) return false;
893
- var max = data.length, index = 0, hasDigits = false, ch;
894
- if (!max) return false;
895
- ch = data[index];
896
- if (ch === "-" || ch === "+") ch = data[++index];
897
- if (ch === "0") {
898
- if (index + 1 === max) return true;
899
- ch = data[++index];
900
- if (ch === "b") {
901
- index++;
902
- for (; index < max; index++) {
903
- ch = data[index];
904
- if (ch === "_") continue;
905
- if (ch !== "0" && ch !== "1") return false;
906
- hasDigits = true;
907
- }
908
- return hasDigits && ch !== "_";
909
- }
910
- if (ch === "x") {
911
- index++;
912
- for (; index < max; index++) {
913
- ch = data[index];
914
- if (ch === "_") continue;
915
- if (!isHexCode(data.charCodeAt(index))) return false;
916
- hasDigits = true;
917
- }
918
- return hasDigits && ch !== "_";
919
- }
920
- if (ch === "o") {
921
- index++;
922
- for (; index < max; index++) {
923
- ch = data[index];
924
- if (ch === "_") continue;
925
- if (!isOctCode(data.charCodeAt(index))) return false;
926
- hasDigits = true;
927
- }
928
- return hasDigits && ch !== "_";
929
- }
930
- }
931
- if (ch === "_") return false;
932
- for (; index < max; index++) {
933
- ch = data[index];
934
- if (ch === "_") continue;
935
- if (!isDecCode(data.charCodeAt(index))) return false;
936
- hasDigits = true;
937
- }
938
- if (!hasDigits || ch === "_") return false;
939
- return true;
940
- }
941
- function constructYamlInteger(data) {
942
- var value = data, sign = 1, ch;
943
- if (value.indexOf("_") !== -1) value = value.replace(/_/g, "");
944
- ch = value[0];
945
- if (ch === "-" || ch === "+") {
946
- if (ch === "-") sign = -1;
947
- value = value.slice(1);
948
- ch = value[0];
949
- }
950
- if (value === "0") return 0;
951
- if (ch === "0") {
952
- if (value[1] === "b") return sign * parseInt(value.slice(2), 2);
953
- if (value[1] === "x") return sign * parseInt(value.slice(2), 16);
954
- if (value[1] === "o") return sign * parseInt(value.slice(2), 8);
955
- }
956
- return sign * parseInt(value, 10);
957
- }
958
- function isInteger(object) {
959
- return Object.prototype.toString.call(object) === "[object Number]" && object % 1 === 0 && !common.isNegativeZero(object);
960
- }
961
- var int = new type("tag:yaml.org,2002:int", {
962
- kind: "scalar",
963
- resolve: resolveYamlInteger,
964
- construct: constructYamlInteger,
965
- predicate: isInteger,
966
- represent: {
967
- binary: function(obj) {
968
- return obj >= 0 ? "0b" + obj.toString(2) : "-0b" + obj.toString(2).slice(1);
969
- },
970
- octal: function(obj) {
971
- return obj >= 0 ? "0o" + obj.toString(8) : "-0o" + obj.toString(8).slice(1);
972
- },
973
- decimal: function(obj) {
974
- return obj.toString(10);
975
- },
976
- hexadecimal: function(obj) {
977
- return obj >= 0 ? "0x" + obj.toString(16).toUpperCase() : "-0x" + obj.toString(16).toUpperCase().slice(1);
978
- }
979
- },
980
- defaultStyle: "decimal",
981
- styleAliases: {
982
- binary: [2, "bin"],
983
- octal: [8, "oct"],
984
- decimal: [10, "dec"],
985
- hexadecimal: [16, "hex"]
986
- }
987
- });
988
- var YAML_FLOAT_PATTERN = /* @__PURE__ */ new RegExp("^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$");
989
- function resolveYamlFloat(data) {
990
- if (data === null) return false;
991
- if (!YAML_FLOAT_PATTERN.test(data) || data[data.length - 1] === "_") return false;
992
- return true;
993
- }
994
- function constructYamlFloat(data) {
995
- var value = data.replace(/_/g, "").toLowerCase(), sign = value[0] === "-" ? -1 : 1;
996
- if ("+-".indexOf(value[0]) >= 0) value = value.slice(1);
997
- if (value === ".inf") return sign === 1 ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;
998
- else if (value === ".nan") return NaN;
999
- return sign * parseFloat(value, 10);
1000
- }
1001
- var SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/;
1002
- function representYamlFloat(object, style) {
1003
- var res;
1004
- if (isNaN(object)) switch (style) {
1005
- case "lowercase": return ".nan";
1006
- case "uppercase": return ".NAN";
1007
- case "camelcase": return ".NaN";
1008
- }
1009
- else if (Number.POSITIVE_INFINITY === object) switch (style) {
1010
- case "lowercase": return ".inf";
1011
- case "uppercase": return ".INF";
1012
- case "camelcase": return ".Inf";
1013
- }
1014
- else if (Number.NEGATIVE_INFINITY === object) switch (style) {
1015
- case "lowercase": return "-.inf";
1016
- case "uppercase": return "-.INF";
1017
- case "camelcase": return "-.Inf";
1018
- }
1019
- else if (common.isNegativeZero(object)) return "-0.0";
1020
- res = object.toString(10);
1021
- return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace("e", ".e") : res;
1022
- }
1023
- function isFloat(object) {
1024
- return Object.prototype.toString.call(object) === "[object Number]" && (object % 1 !== 0 || common.isNegativeZero(object));
1025
- }
1026
- var float = new type("tag:yaml.org,2002:float", {
1027
- kind: "scalar",
1028
- resolve: resolveYamlFloat,
1029
- construct: constructYamlFloat,
1030
- predicate: isFloat,
1031
- represent: representYamlFloat,
1032
- defaultStyle: "lowercase"
1033
- });
1034
- var core = failsafe.extend({ implicit: [
1035
- _null,
1036
- bool,
1037
- int,
1038
- float
1039
- ] });
1040
- var YAML_DATE_REGEXP = /* @__PURE__ */ new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$");
1041
- var YAML_TIMESTAMP_REGEXP = /* @__PURE__ */ new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$");
1042
- function resolveYamlTimestamp(data) {
1043
- if (data === null) return false;
1044
- if (YAML_DATE_REGEXP.exec(data) !== null) return true;
1045
- if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true;
1046
- return false;
1047
- }
1048
- function constructYamlTimestamp(data) {
1049
- var match, year, month, day, hour, minute, second, fraction = 0, delta = null, tz_hour, tz_minute, date;
1050
- match = YAML_DATE_REGEXP.exec(data);
1051
- if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data);
1052
- if (match === null) throw new Error("Date resolve error");
1053
- year = +match[1];
1054
- month = +match[2] - 1;
1055
- day = +match[3];
1056
- if (!match[4]) return new Date(Date.UTC(year, month, day));
1057
- hour = +match[4];
1058
- minute = +match[5];
1059
- second = +match[6];
1060
- if (match[7]) {
1061
- fraction = match[7].slice(0, 3);
1062
- while (fraction.length < 3) fraction += "0";
1063
- fraction = +fraction;
1064
- }
1065
- if (match[9]) {
1066
- tz_hour = +match[10];
1067
- tz_minute = +(match[11] || 0);
1068
- delta = (tz_hour * 60 + tz_minute) * 6e4;
1069
- if (match[9] === "-") delta = -delta;
1070
- }
1071
- date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction));
1072
- if (delta) date.setTime(date.getTime() - delta);
1073
- return date;
1074
- }
1075
- function representYamlTimestamp(object) {
1076
- return object.toISOString();
1077
- }
1078
- var timestamp = new type("tag:yaml.org,2002:timestamp", {
1079
- kind: "scalar",
1080
- resolve: resolveYamlTimestamp,
1081
- construct: constructYamlTimestamp,
1082
- instanceOf: Date,
1083
- represent: representYamlTimestamp
1084
- });
1085
- function resolveYamlMerge(data) {
1086
- return data === "<<" || data === null;
1087
- }
1088
- var merge = new type("tag:yaml.org,2002:merge", {
1089
- kind: "scalar",
1090
- resolve: resolveYamlMerge
1091
- });
1092
- var BASE64_MAP = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r";
1093
- function resolveYamlBinary(data) {
815
+ var merge = new type("tag:yaml.org,2002:merge", {
816
+ kind: "scalar",
817
+ resolve: resolveYamlMerge
818
+ });
819
+ var BASE64_MAP = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r";
820
+ function resolveYamlBinary(data) {
1094
821
  if (data === null) return false;
1095
822
  var code, idx, bitlen = 0, max = data.length, map = BASE64_MAP;
1096
823
  for (idx = 0; idx < max; idx++) {
@@ -2423,555 +2150,897 @@ function writeFlowMapping(state, level, object) {
2423
2150
  pairBuffer += state.dump;
2424
2151
  _result += pairBuffer;
2425
2152
  }
2426
- state.tag = _tag;
2427
- state.dump = "{" + _result + "}";
2153
+ state.tag = _tag;
2154
+ state.dump = "{" + _result + "}";
2155
+ }
2156
+ function writeBlockMapping(state, level, object, compact) {
2157
+ var _result = "", _tag = state.tag, objectKeyList = Object.keys(object), index, length, objectKey, objectValue, explicitPair, pairBuffer;
2158
+ if (state.sortKeys === true) objectKeyList.sort();
2159
+ else if (typeof state.sortKeys === "function") objectKeyList.sort(state.sortKeys);
2160
+ else if (state.sortKeys) throw new exception("sortKeys must be a boolean or a function");
2161
+ for (index = 0, length = objectKeyList.length; index < length; index += 1) {
2162
+ pairBuffer = "";
2163
+ if (!compact || _result !== "") pairBuffer += generateNextLine(state, level);
2164
+ objectKey = objectKeyList[index];
2165
+ objectValue = object[objectKey];
2166
+ if (state.replacer) objectValue = state.replacer.call(object, objectKey, objectValue);
2167
+ if (!writeNode(state, level + 1, objectKey, true, true, true)) continue;
2168
+ explicitPair = state.tag !== null && state.tag !== "?" || state.dump && state.dump.length > 1024;
2169
+ if (explicitPair) if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) pairBuffer += "?";
2170
+ else pairBuffer += "? ";
2171
+ pairBuffer += state.dump;
2172
+ if (explicitPair) pairBuffer += generateNextLine(state, level);
2173
+ if (!writeNode(state, level + 1, objectValue, true, explicitPair)) continue;
2174
+ if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) pairBuffer += ":";
2175
+ else pairBuffer += ": ";
2176
+ pairBuffer += state.dump;
2177
+ _result += pairBuffer;
2178
+ }
2179
+ state.tag = _tag;
2180
+ state.dump = _result || "{}";
2181
+ }
2182
+ function detectType(state, object, explicit) {
2183
+ var _result, typeList = explicit ? state.explicitTypes : state.implicitTypes, index, length, type, style;
2184
+ for (index = 0, length = typeList.length; index < length; index += 1) {
2185
+ type = typeList[index];
2186
+ if ((type.instanceOf || type.predicate) && (!type.instanceOf || typeof object === "object" && object instanceof type.instanceOf) && (!type.predicate || type.predicate(object))) {
2187
+ if (explicit) if (type.multi && type.representName) state.tag = type.representName(object);
2188
+ else state.tag = type.tag;
2189
+ else state.tag = "?";
2190
+ if (type.represent) {
2191
+ style = state.styleMap[type.tag] || type.defaultStyle;
2192
+ if (_toString.call(type.represent) === "[object Function]") _result = type.represent(object, style);
2193
+ else if (_hasOwnProperty.call(type.represent, style)) _result = type.represent[style](object, style);
2194
+ else throw new exception("!<" + type.tag + "> tag resolver accepts not \"" + style + "\" style");
2195
+ state.dump = _result;
2196
+ }
2197
+ return true;
2198
+ }
2199
+ }
2200
+ return false;
2201
+ }
2202
+ function writeNode(state, level, object, block, compact, iskey, isblockseq) {
2203
+ state.tag = null;
2204
+ state.dump = object;
2205
+ if (!detectType(state, object, false)) detectType(state, object, true);
2206
+ var type = _toString.call(state.dump);
2207
+ var inblock = block;
2208
+ var tagStr;
2209
+ if (block) block = state.flowLevel < 0 || state.flowLevel > level;
2210
+ var objectOrArray = type === "[object Object]" || type === "[object Array]", duplicateIndex, duplicate;
2211
+ if (objectOrArray) {
2212
+ duplicateIndex = state.duplicates.indexOf(object);
2213
+ duplicate = duplicateIndex !== -1;
2214
+ }
2215
+ if (state.tag !== null && state.tag !== "?" || duplicate || state.indent !== 2 && level > 0) compact = false;
2216
+ if (duplicate && state.usedDuplicates[duplicateIndex]) state.dump = "*ref_" + duplicateIndex;
2217
+ else {
2218
+ if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) state.usedDuplicates[duplicateIndex] = true;
2219
+ if (type === "[object Object]") if (block && Object.keys(state.dump).length !== 0) {
2220
+ writeBlockMapping(state, level, state.dump, compact);
2221
+ if (duplicate) state.dump = "&ref_" + duplicateIndex + state.dump;
2222
+ } else {
2223
+ writeFlowMapping(state, level, state.dump);
2224
+ if (duplicate) state.dump = "&ref_" + duplicateIndex + " " + state.dump;
2225
+ }
2226
+ else if (type === "[object Array]") if (block && state.dump.length !== 0) {
2227
+ if (state.noArrayIndent && !isblockseq && level > 0) writeBlockSequence(state, level - 1, state.dump, compact);
2228
+ else writeBlockSequence(state, level, state.dump, compact);
2229
+ if (duplicate) state.dump = "&ref_" + duplicateIndex + state.dump;
2230
+ } else {
2231
+ writeFlowSequence(state, level, state.dump);
2232
+ if (duplicate) state.dump = "&ref_" + duplicateIndex + " " + state.dump;
2233
+ }
2234
+ else if (type === "[object String]") {
2235
+ if (state.tag !== "?") writeScalar(state, state.dump, level, iskey, inblock);
2236
+ } else if (type === "[object Undefined]") return false;
2237
+ else {
2238
+ if (state.skipInvalid) return false;
2239
+ throw new exception("unacceptable kind of an object to dump " + type);
2240
+ }
2241
+ if (state.tag !== null && state.tag !== "?") {
2242
+ tagStr = encodeURI(state.tag[0] === "!" ? state.tag.slice(1) : state.tag).replace(/!/g, "%21");
2243
+ if (state.tag[0] === "!") tagStr = "!" + tagStr;
2244
+ else if (tagStr.slice(0, 18) === "tag:yaml.org,2002:") tagStr = "!!" + tagStr.slice(18);
2245
+ else tagStr = "!<" + tagStr + ">";
2246
+ state.dump = tagStr + " " + state.dump;
2247
+ }
2248
+ }
2249
+ return true;
2250
+ }
2251
+ function getDuplicateReferences(object, state) {
2252
+ var objects = [], duplicatesIndexes = [], index, length;
2253
+ inspectNode(object, objects, duplicatesIndexes);
2254
+ for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) state.duplicates.push(objects[duplicatesIndexes[index]]);
2255
+ state.usedDuplicates = new Array(length);
2256
+ }
2257
+ function inspectNode(object, objects, duplicatesIndexes) {
2258
+ var objectKeyList, index, length;
2259
+ if (object !== null && typeof object === "object") {
2260
+ index = objects.indexOf(object);
2261
+ if (index !== -1) {
2262
+ if (duplicatesIndexes.indexOf(index) === -1) duplicatesIndexes.push(index);
2263
+ } else {
2264
+ objects.push(object);
2265
+ if (Array.isArray(object)) for (index = 0, length = object.length; index < length; index += 1) inspectNode(object[index], objects, duplicatesIndexes);
2266
+ else {
2267
+ objectKeyList = Object.keys(object);
2268
+ for (index = 0, length = objectKeyList.length; index < length; index += 1) inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes);
2269
+ }
2270
+ }
2271
+ }
2272
+ }
2273
+ function dump$1(input, options) {
2274
+ options = options || {};
2275
+ var state = new State(options);
2276
+ if (!state.noRefs) getDuplicateReferences(input, state);
2277
+ var value = input;
2278
+ if (state.replacer) value = state.replacer.call({ "": value }, "", value);
2279
+ if (writeNode(state, 0, value, true, true)) return state.dump + "\n";
2280
+ return "";
2281
+ }
2282
+ var dumper = { dump: dump$1 };
2283
+ var load = loader.load;
2284
+ loader.loadAll;
2285
+ dumper.dump;
2286
+ //#endregion
2287
+ //#region src/shared/model-utils.ts
2288
+ /**
2289
+ * Detect whether a model is a list wrapper -- the standard paginated
2290
+ * list envelope with `data` (array), `list_metadata`, and optionally `object: 'list'`.
2291
+ *
2292
+ * These models are redundant because each language SDK already has its own
2293
+ * pagination wrapper, and the runtime handles deserialization.
2294
+ */
2295
+ function isListWrapperModel(model) {
2296
+ const fieldsByName = new Map(model.fields.map((f) => [f.name, f]));
2297
+ const dataField = fieldsByName.get("data");
2298
+ if (!dataField) return false;
2299
+ if (dataField.type.kind !== "array") return false;
2300
+ if (!(fieldsByName.get("list_metadata") ?? fieldsByName.get("listMetadata"))) return false;
2301
+ const objectField = fieldsByName.get("object");
2302
+ if (objectField) {
2303
+ if (objectField.type.kind !== "literal" || objectField.type.value !== "list") return false;
2304
+ }
2305
+ return true;
2306
+ }
2307
+ /**
2308
+ * Detect whether a model is a list metadata model (e.g., ListMetadata).
2309
+ * These models typically have exactly `before` and `after` nullable string fields.
2310
+ */
2311
+ function isListMetadataModel(model) {
2312
+ if (model.fields.length !== 2) return false;
2313
+ const fieldsByName = new Map(model.fields.map((f) => [f.name, f]));
2314
+ const before = fieldsByName.get("before");
2315
+ const after = fieldsByName.get("after");
2316
+ if (!before || !after) return false;
2317
+ return isNullableString(before) && isNullableString(after);
2318
+ }
2319
+ /** Check if a field type is nullable string (nullable<string> or just string). */
2320
+ function isNullableString(field) {
2321
+ if (field.type.kind === "primitive" && field.type.type === "string") return true;
2322
+ if (field.type.kind === "nullable" && field.type.inner.kind === "primitive" && field.type.inner.type === "string") return true;
2323
+ return false;
2324
+ }
2325
+ /**
2326
+ * Discover the OpenAPI spec path from CLI args or environment.
2327
+ * Returns null if not found.
2328
+ */
2329
+ function discoverSpecPath() {
2330
+ const args = process.argv;
2331
+ for (let i = 0; i < args.length; i++) {
2332
+ if (args[i] === "--spec" && args[i + 1]) return resolve(args[i + 1]);
2333
+ if (args[i]?.startsWith("--spec=")) return resolve(args[i].slice(7));
2334
+ }
2335
+ if (process.env.OPENAPI_SPEC_PATH) return resolve(process.env.OPENAPI_SPEC_PATH);
2336
+ return null;
2337
+ }
2338
+ /** Cached raw spec to avoid re-reading on multiple calls. */
2339
+ let _rawSpecCache = null;
2340
+ let _rawSpecLoaded = false;
2341
+ function loadRawSpec() {
2342
+ if (_rawSpecLoaded) return _rawSpecCache;
2343
+ _rawSpecLoaded = true;
2344
+ const specPath = discoverSpecPath();
2345
+ if (!specPath || !existsSync(specPath)) return null;
2346
+ try {
2347
+ _rawSpecCache = load(readFileSync(specPath, "utf-8"));
2348
+ return _rawSpecCache;
2349
+ } catch {
2350
+ return null;
2351
+ }
2352
+ }
2353
+ /** Look up a schema by name in the raw spec's components/schemas. */
2354
+ function lookupRawSchema(name) {
2355
+ const spec = loadRawSpec();
2356
+ if (!spec) return null;
2357
+ return spec?.components?.schemas?.[name] ?? null;
2358
+ }
2359
+ function createCollector() {
2360
+ return {
2361
+ models: [],
2362
+ enums: [],
2363
+ usedNames: /* @__PURE__ */ new Set()
2364
+ };
2365
+ }
2366
+ /**
2367
+ * Singularize a snake_case name for use as an array-item model name.
2368
+ * `redirect_uris` -> `redirect_uri`, `scopes` -> `scope`.
2369
+ */
2370
+ function singularizeSnake(name) {
2371
+ if (name.endsWith("ies") && name.length > 3) return `${name.slice(0, -3)}y`;
2372
+ if (name.endsWith("s") && !name.endsWith("ss")) return name.slice(0, -1);
2373
+ return name;
2374
+ }
2375
+ /**
2376
+ * Convert a raw OpenAPI type+format to an IR TypeRef.
2377
+ *
2378
+ * When `parentModelName` and `fieldName` are provided, inline objects and
2379
+ * enums generate synthetic models/enums instead of degrading to `unknown`
2380
+ * or `string`.
2381
+ */
2382
+ function rawSchemaToTypeRef(schema, parentModelName, fName, collector) {
2383
+ if (schema.const !== void 0) return {
2384
+ kind: "literal",
2385
+ value: schema.const
2386
+ };
2387
+ if (schema.enum && collector && parentModelName && fName) {
2388
+ const syntheticName = `${parentModelName}_${fName}`;
2389
+ if (!collector.usedNames.has(syntheticName) && !collector.usedNames.has(toSnakeCase(syntheticName))) {
2390
+ collector.usedNames.add(syntheticName);
2391
+ collector.enums.push({
2392
+ name: syntheticName,
2393
+ values: schema.enum.map((v) => ({
2394
+ value: v,
2395
+ description: void 0
2396
+ }))
2397
+ });
2398
+ }
2399
+ return {
2400
+ kind: "enum",
2401
+ name: syntheticName,
2402
+ values: schema.enum
2403
+ };
2404
+ }
2405
+ if (schema.enum) return {
2406
+ kind: "primitive",
2407
+ type: "string"
2408
+ };
2409
+ if (schema.$ref) return {
2410
+ kind: "model",
2411
+ name: schema.$ref.split("/").pop()
2412
+ };
2413
+ let baseType = schema.type;
2414
+ let isNullable = false;
2415
+ if (Array.isArray(baseType)) {
2416
+ const nonNull = baseType.filter((t) => t !== "null");
2417
+ isNullable = baseType.includes("null");
2418
+ baseType = nonNull[0] ?? "string";
2419
+ }
2420
+ let ref;
2421
+ if (baseType === "object" && schema.properties && collector && parentModelName && fName) {
2422
+ const syntheticName = `${parentModelName}_${fName}`;
2423
+ if (!collector.usedNames.has(syntheticName) && !collector.usedNames.has(toSnakeCase(syntheticName))) {
2424
+ collector.usedNames.add(syntheticName);
2425
+ const fields = [];
2426
+ const requiredSet = new Set(schema.required ?? []);
2427
+ for (const [propName, propSchema] of Object.entries(schema.properties)) fields.push({
2428
+ name: propName,
2429
+ type: rawSchemaToTypeRef(propSchema, syntheticName, propName, collector),
2430
+ required: requiredSet.has(propName),
2431
+ description: propSchema.description,
2432
+ deprecated: propSchema.deprecated
2433
+ });
2434
+ collector.models.push({
2435
+ name: syntheticName,
2436
+ fields,
2437
+ description: schema.description
2438
+ });
2439
+ }
2440
+ ref = {
2441
+ kind: "model",
2442
+ name: syntheticName
2443
+ };
2444
+ } else if (baseType === "object" && schema.properties) ref = {
2445
+ kind: "primitive",
2446
+ type: "unknown"
2447
+ };
2448
+ else if (baseType === "array" && schema.items) {
2449
+ const itemFieldName = fName ? singularizeSnake(fName) : void 0;
2450
+ ref = {
2451
+ kind: "array",
2452
+ items: rawSchemaToTypeRef(schema.items, parentModelName, itemFieldName, collector)
2453
+ };
2454
+ } else if (baseType === "boolean") ref = {
2455
+ kind: "primitive",
2456
+ type: "boolean"
2457
+ };
2458
+ else if (baseType === "integer" || baseType === "number") ref = {
2459
+ kind: "primitive",
2460
+ type: baseType
2461
+ };
2462
+ else ref = {
2463
+ kind: "primitive",
2464
+ type: "string"
2465
+ };
2466
+ if (isNullable) return {
2467
+ kind: "nullable",
2468
+ inner: ref
2469
+ };
2470
+ return ref;
2471
+ }
2472
+ /**
2473
+ * Extract fields from a raw OpenAPI object schema.
2474
+ * All fields are returned as optional (not required) since they come from
2475
+ * oneOf variants where only one variant is active at a time.
2476
+ */
2477
+ function extractFieldsFromRawSchema(schema, parentModelName, collector) {
2478
+ const fields = [];
2479
+ const props = schema.properties ?? {};
2480
+ for (const [name, propSchema] of Object.entries(props)) fields.push({
2481
+ name,
2482
+ type: rawSchemaToTypeRef(propSchema, parentModelName, name, collector),
2483
+ required: false,
2484
+ description: propSchema.description,
2485
+ deprecated: propSchema.deprecated
2486
+ });
2487
+ return fields;
2488
+ }
2489
+ /**
2490
+ * Recursively collect all fields from a oneOf schema, flattening nested
2491
+ * allOf+oneOf compositions. All fields are marked optional.
2492
+ */
2493
+ function collectOneOfFields(schema, parentModelName, collector) {
2494
+ const allFields = [];
2495
+ const seenFieldNames = /* @__PURE__ */ new Set();
2496
+ function walkSchema(s) {
2497
+ if (s.properties) {
2498
+ for (const f of extractFieldsFromRawSchema(s, parentModelName, collector)) if (!seenFieldNames.has(f.name)) {
2499
+ seenFieldNames.add(f.name);
2500
+ allFields.push(f);
2501
+ }
2502
+ }
2503
+ if (s.allOf) for (const sub of s.allOf) walkSchema(sub);
2504
+ if (s.oneOf) for (const variant of s.oneOf) walkSchema(variant);
2505
+ if (s.anyOf) for (const variant of s.anyOf) walkSchema(variant);
2506
+ }
2507
+ walkSchema(schema);
2508
+ return allFields;
2509
+ }
2510
+ /**
2511
+ * Check if a TypeRef is `unknown` (the degraded type for inline objects).
2512
+ */
2513
+ function isUnknownType(ref) {
2514
+ return ref.kind === "primitive" && ref.type === "unknown";
2515
+ }
2516
+ /**
2517
+ * If a field is an `array<unknown>` (or `nullable<array<unknown>>`) and the
2518
+ * raw spec defines inline object/enum items, replace the item type with a
2519
+ * synthetic model/enum. Returns the original field unchanged when no upgrade
2520
+ * is needed.
2521
+ */
2522
+ function upgradeArrayItemType(field, rawSchema, parentModelName, collector) {
2523
+ let arrayRef = null;
2524
+ let isNullableWrapper = false;
2525
+ if (field.type.kind === "array") arrayRef = field.type;
2526
+ else if (field.type.kind === "nullable" && field.type.inner.kind === "array") {
2527
+ arrayRef = field.type.inner;
2528
+ isNullableWrapper = true;
2529
+ }
2530
+ if (!arrayRef || arrayRef.kind !== "array") return field;
2531
+ if (!isUnknownType(arrayRef.items)) return field;
2532
+ const rawProp = rawSchema.properties?.[field.name];
2533
+ if (!rawProp) return field;
2534
+ let rawArraySchema = rawProp;
2535
+ if (Array.isArray(rawProp.type)) {
2536
+ if (rawProp.type.filter((t) => t !== "null")[0] === "array") rawArraySchema = rawProp;
2537
+ }
2538
+ if (rawArraySchema.type !== "array" && !(Array.isArray(rawArraySchema.type) && rawArraySchema.type.includes("array"))) return field;
2539
+ if (!rawArraySchema.items) return field;
2540
+ const itemFieldName = singularizeSnake(field.name);
2541
+ const newItemRef = rawSchemaToTypeRef(rawArraySchema.items, parentModelName, itemFieldName, collector);
2542
+ if (isUnknownType(newItemRef)) return field;
2543
+ const newArrayRef = {
2544
+ kind: "array",
2545
+ items: newItemRef
2546
+ };
2547
+ const newType = isNullableWrapper ? {
2548
+ kind: "nullable",
2549
+ inner: newArrayRef
2550
+ } : newArrayRef;
2551
+ return {
2552
+ ...field,
2553
+ type: newType
2554
+ };
2555
+ }
2556
+ let _lastSyntheticEnums = [];
2557
+ /**
2558
+ * Return the synthetic enums generated during the last call to
2559
+ * `enrichModelsFromSpec`. Call this after enrichment to merge them into the
2560
+ * enum generation phase.
2561
+ */
2562
+ function getSyntheticEnums() {
2563
+ return _lastSyntheticEnums;
2564
+ }
2565
+ /**
2566
+ * Find a property name that has a `const` value in ALL oneOf variants.
2567
+ * Returns null if no shared const property is found.
2568
+ */
2569
+ function findSharedConstProperty(oneOfSchemas) {
2570
+ if (oneOfSchemas.length === 0) return null;
2571
+ const first = oneOfSchemas[0];
2572
+ if (!first.properties) return null;
2573
+ const candidates = Object.keys(first.properties).filter((name) => first.properties[name].const !== void 0);
2574
+ for (const candidate of candidates) if (oneOfSchemas.every((variant) => variant.properties?.[candidate]?.const !== void 0)) return candidate;
2575
+ return null;
2576
+ }
2577
+ /**
2578
+ * Build a discriminator mapping from const values to IR model names.
2579
+ * For each oneOf variant's const value on `discProperty`, find the IR model
2580
+ * whose field with the same name is a Literal type with that value.
2581
+ */
2582
+ function buildDiscriminatorMapping(discProperty, oneOfSchemas, models, parentModelName) {
2583
+ const mapping = {};
2584
+ for (const variant of oneOfSchemas) {
2585
+ const constValue = variant.properties?.[discProperty]?.const;
2586
+ if (constValue === void 0) continue;
2587
+ const variantModel = models.find((m) => m.name !== parentModelName && m.fields.some((f) => f.name === discProperty && f.type.kind === "literal" && f.type.value === constValue));
2588
+ if (variantModel) mapping[String(constValue)] = variantModel.name;
2589
+ }
2590
+ return mapping;
2591
+ }
2592
+ /**
2593
+ * Detect implicit discriminators on models without full oneOf flattening.
2594
+ * Returns a new array with discriminator annotations; models without
2595
+ * discriminators are returned as-is. Use this when you need discriminator
2596
+ * info but don't want the side-effects of full enrichment (synthetic
2597
+ * models/enums, field flattening).
2598
+ */
2599
+ function detectDiscriminators(models) {
2600
+ if (!loadRawSpec()) return models;
2601
+ let changed = false;
2602
+ const result = models.map((model) => {
2603
+ if (model.discriminator) return model;
2604
+ const rawSchema = lookupRawSchema(model.name);
2605
+ if (!rawSchema) return model;
2606
+ const oneOfContainer = rawSchema.allOf?.find((s) => s.oneOf);
2607
+ if (!oneOfContainer?.oneOf || oneOfContainer.oneOf.length === 0) return model;
2608
+ const discProperty = findSharedConstProperty(oneOfContainer.oneOf);
2609
+ if (!discProperty) return model;
2610
+ const mapping = buildDiscriminatorMapping(discProperty, oneOfContainer.oneOf, models, model.name);
2611
+ if (Object.keys(mapping).length === 0) return model;
2612
+ changed = true;
2613
+ return {
2614
+ ...model,
2615
+ fields: [],
2616
+ discriminator: {
2617
+ property: discProperty,
2618
+ mapping
2619
+ }
2620
+ };
2621
+ });
2622
+ return changed ? result : models;
2623
+ }
2624
+ /**
2625
+ * Enrich IR models by flattening oneOf/allOf+oneOf variant fields from the raw spec.
2626
+ *
2627
+ * For models with 0 fields whose raw spec schema is a pure oneOf:
2628
+ * - Collect all variant fields and add them as optional fields.
2629
+ *
2630
+ * For models whose raw spec schema has allOf containing a oneOf:
2631
+ * - Collect the missing variant fields and add them as optional.
2632
+ *
2633
+ * Inline objects and enums in oneOf branches are promoted to synthetic
2634
+ * models/enums instead of degrading to `object` / `string`.
2635
+ *
2636
+ * Returns a new array of enriched models (original models are not mutated).
2637
+ * Synthetic enums are stored internally; retrieve them via `getSyntheticEnums()`.
2638
+ */
2639
+ function enrichModelsFromSpec(models) {
2640
+ if (!loadRawSpec()) {
2641
+ _lastSyntheticEnums = [];
2642
+ return models;
2643
+ }
2644
+ const collector = createCollector();
2645
+ for (const m of models) {
2646
+ collector.usedNames.add(m.name);
2647
+ collector.usedNames.add(toSnakeCase(m.name));
2648
+ }
2649
+ const enriched2 = models.map((model) => {
2650
+ const rawSchema = lookupRawSchema(model.name);
2651
+ if (!rawSchema) return model;
2652
+ if (!(rawSchema.oneOf || rawSchema.allOf?.some((s) => s.oneOf))) return model;
2653
+ if (rawSchema.discriminator || rawSchema.oneOf?.some((v) => v.discriminator) || rawSchema.allOf?.some((s) => s.discriminator || s.oneOf?.some((v) => v.discriminator))) return model;
2654
+ const oneOfContainer = rawSchema.allOf?.find((s) => s.oneOf);
2655
+ if (oneOfContainer?.oneOf && oneOfContainer.oneOf.length > 0) {
2656
+ const discProperty = findSharedConstProperty(oneOfContainer.oneOf);
2657
+ if (discProperty) {
2658
+ const mapping = buildDiscriminatorMapping(discProperty, oneOfContainer.oneOf, models, model.name);
2659
+ if (Object.keys(mapping).length > 0) return {
2660
+ ...model,
2661
+ fields: [],
2662
+ discriminator: {
2663
+ property: discProperty,
2664
+ mapping
2665
+ }
2666
+ };
2667
+ }
2668
+ }
2669
+ const variantFields = collectOneOfFields(rawSchema, model.name, collector);
2670
+ if (variantFields.length === 0) return model;
2671
+ const existingNames = new Set(model.fields.map((f) => f.name));
2672
+ const newFields = variantFields.filter((f) => !existingNames.has(f.name));
2673
+ if (newFields.length === 0) return model;
2674
+ return {
2675
+ ...model,
2676
+ fields: [...model.fields, ...newFields]
2677
+ };
2678
+ }).map((model) => {
2679
+ const rawSchema = lookupRawSchema(model.name);
2680
+ if (!rawSchema?.properties) return model;
2681
+ let modified = false;
2682
+ const newFields = model.fields.map((field) => {
2683
+ const upgraded = upgradeArrayItemType(field, rawSchema, model.name, collector);
2684
+ if (upgraded !== field) modified = true;
2685
+ return upgraded;
2686
+ });
2687
+ return modified ? {
2688
+ ...model,
2689
+ fields: newFields
2690
+ } : model;
2691
+ });
2692
+ _lastSyntheticEnums = collector.enums.map((e) => ({
2693
+ name: e.name,
2694
+ values: e.values.map((v) => ({
2695
+ value: v.value,
2696
+ description: v.description
2697
+ }))
2698
+ }));
2699
+ const existingSnakeNames = new Set(enriched2.map((m) => toSnakeCase(m.name)));
2700
+ const filteredSynthetic = collector.models.filter((m) => !existingSnakeNames.has(toSnakeCase(m.name)));
2701
+ return [...enriched2, ...filteredSynthetic];
2702
+ }
2703
+ //#endregion
2704
+ //#region src/shared/service-name-collision.ts
2705
+ /**
2706
+ * Suffix applied to an operation-client class name when it collides with an
2707
+ * exported model/enum class name in the same SDK namespace. Standardized
2708
+ * across emitters so colliding services look the same in every language —
2709
+ * e.g. `OrganizationMembershipService` regardless of language.
2710
+ *
2711
+ * Languages whose operation clients already carry a unique suffix (Go's
2712
+ * `…Service`, Rust's `…Api`, .NET's `…Service`) skip this helper entirely.
2713
+ */
2714
+ const SERVICE_COLLISION_SUFFIX = "Service";
2715
+ /**
2716
+ * Build the set of model + enum class names that the SDK exports under its
2717
+ * top-level namespace. Each emitter passes its own `classNameFn` so the
2718
+ * comparison happens on the language-specific class-name form (e.g. Ruby's
2719
+ * `RoleList`, Python's `RoleList`).
2720
+ *
2721
+ * List-wrapper and list-metadata models are excluded — they aren't exposed
2722
+ * as user-facing types.
2723
+ */
2724
+ function buildExportedClassNameSet$5(ctx, classNameFn) {
2725
+ const out = /* @__PURE__ */ new Set();
2726
+ for (const model of ctx.spec.models) {
2727
+ if (isListWrapperModel(model) || isListMetadataModel(model)) continue;
2728
+ out.add(classNameFn(model.name));
2729
+ }
2730
+ for (const enumDef of ctx.spec.enums) out.add(classNameFn(enumDef.name));
2731
+ return out;
2428
2732
  }
2429
- function writeBlockMapping(state, level, object, compact) {
2430
- var _result = "", _tag = state.tag, objectKeyList = Object.keys(object), index, length, objectKey, objectValue, explicitPair, pairBuffer;
2431
- if (state.sortKeys === true) objectKeyList.sort();
2432
- else if (typeof state.sortKeys === "function") objectKeyList.sort(state.sortKeys);
2433
- else if (state.sortKeys) throw new exception("sortKeys must be a boolean or a function");
2434
- for (index = 0, length = objectKeyList.length; index < length; index += 1) {
2435
- pairBuffer = "";
2436
- if (!compact || _result !== "") pairBuffer += generateNextLine(state, level);
2437
- objectKey = objectKeyList[index];
2438
- objectValue = object[objectKey];
2439
- if (state.replacer) objectValue = state.replacer.call(object, objectKey, objectValue);
2440
- if (!writeNode(state, level + 1, objectKey, true, true, true)) continue;
2441
- explicitPair = state.tag !== null && state.tag !== "?" || state.dump && state.dump.length > 1024;
2442
- if (explicitPair) if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) pairBuffer += "?";
2443
- else pairBuffer += "? ";
2444
- pairBuffer += state.dump;
2445
- if (explicitPair) pairBuffer += generateNextLine(state, level);
2446
- if (!writeNode(state, level + 1, objectValue, true, explicitPair)) continue;
2447
- if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) pairBuffer += ":";
2448
- else pairBuffer += ": ";
2449
- pairBuffer += state.dump;
2450
- _result += pairBuffer;
2451
- }
2452
- state.tag = _tag;
2453
- state.dump = _result || "{}";
2733
+ /**
2734
+ * Resolve the PascalCase mount-target identifier for an operation client,
2735
+ * appending `Service` when the un-suffixed class name would shadow an
2736
+ * exported model or enum.
2737
+ *
2738
+ * Operates on the PascalCase target (the mount-target string the IR carries),
2739
+ * so the returned value feeds cleanly into each language's `className` and
2740
+ * `fileName` helpers e.g. `OrganizationMembership` `OrganizationMembershipService`,
2741
+ * then `fileName` → `organization_membership_service` / `organization-membership-service`.
2742
+ *
2743
+ * The accessor on the client (`client.organization_membership`) is intentionally
2744
+ * NOT suffixed callers should keep using the raw target for `servicePropertyName`
2745
+ * so the accessor reads naturally.
2746
+ */
2747
+ function resolveServiceTarget$5(target, exportedClasses, classNameFn) {
2748
+ return exportedClasses.has(classNameFn(target)) ? `${target}${SERVICE_COLLISION_SUFFIX}` : target;
2454
2749
  }
2455
- function detectType(state, object, explicit) {
2456
- var _result, typeList = explicit ? state.explicitTypes : state.implicitTypes, index, length, type, style;
2457
- for (index = 0, length = typeList.length; index < length; index += 1) {
2458
- type = typeList[index];
2459
- if ((type.instanceOf || type.predicate) && (!type.instanceOf || typeof object === "object" && object instanceof type.instanceOf) && (!type.predicate || type.predicate(object))) {
2460
- if (explicit) if (type.multi && type.representName) state.tag = type.representName(object);
2461
- else state.tag = type.tag;
2462
- else state.tag = "?";
2463
- if (type.represent) {
2464
- style = state.styleMap[type.tag] || type.defaultStyle;
2465
- if (_toString.call(type.represent) === "[object Function]") _result = type.represent(object, style);
2466
- else if (_hasOwnProperty.call(type.represent, style)) _result = type.represent[style](object, style);
2467
- else throw new exception("!<" + type.tag + "> tag resolver accepts not \"" + style + "\" style");
2468
- state.dump = _result;
2469
- }
2470
- return true;
2471
- }
2472
- }
2473
- return false;
2750
+ //#endregion
2751
+ //#region src/node/naming.ts
2752
+ /** Strip spec-noise suffixes (e.g., "Dto") from an IR name. */
2753
+ function stripNoiseSuffixes(name) {
2754
+ return name.replace(/Dto$/i, "");
2474
2755
  }
2475
- function writeNode(state, level, object, block, compact, iskey, isblockseq) {
2476
- state.tag = null;
2477
- state.dump = object;
2478
- if (!detectType(state, object, false)) detectType(state, object, true);
2479
- var type = _toString.call(state.dump);
2480
- var inblock = block;
2481
- var tagStr;
2482
- if (block) block = state.flowLevel < 0 || state.flowLevel > level;
2483
- var objectOrArray = type === "[object Object]" || type === "[object Array]", duplicateIndex, duplicate;
2484
- if (objectOrArray) {
2485
- duplicateIndex = state.duplicates.indexOf(object);
2486
- duplicate = duplicateIndex !== -1;
2487
- }
2488
- if (state.tag !== null && state.tag !== "?" || duplicate || state.indent !== 2 && level > 0) compact = false;
2489
- if (duplicate && state.usedDuplicates[duplicateIndex]) state.dump = "*ref_" + duplicateIndex;
2490
- else {
2491
- if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) state.usedDuplicates[duplicateIndex] = true;
2492
- if (type === "[object Object]") if (block && Object.keys(state.dump).length !== 0) {
2493
- writeBlockMapping(state, level, state.dump, compact);
2494
- if (duplicate) state.dump = "&ref_" + duplicateIndex + state.dump;
2495
- } else {
2496
- writeFlowMapping(state, level, state.dump);
2497
- if (duplicate) state.dump = "&ref_" + duplicateIndex + " " + state.dump;
2498
- }
2499
- else if (type === "[object Array]") if (block && state.dump.length !== 0) {
2500
- if (state.noArrayIndent && !isblockseq && level > 0) writeBlockSequence(state, level - 1, state.dump, compact);
2501
- else writeBlockSequence(state, level, state.dump, compact);
2502
- if (duplicate) state.dump = "&ref_" + duplicateIndex + state.dump;
2503
- } else {
2504
- writeFlowSequence(state, level, state.dump);
2505
- if (duplicate) state.dump = "&ref_" + duplicateIndex + " " + state.dump;
2506
- }
2507
- else if (type === "[object String]") {
2508
- if (state.tag !== "?") writeScalar(state, state.dump, level, iskey, inblock);
2509
- } else if (type === "[object Undefined]") return false;
2510
- else {
2511
- if (state.skipInvalid) return false;
2512
- throw new exception("unacceptable kind of an object to dump " + type);
2513
- }
2514
- if (state.tag !== null && state.tag !== "?") {
2515
- tagStr = encodeURI(state.tag[0] === "!" ? state.tag.slice(1) : state.tag).replace(/!/g, "%21");
2516
- if (state.tag[0] === "!") tagStr = "!" + tagStr;
2517
- else if (tagStr.slice(0, 18) === "tag:yaml.org,2002:") tagStr = "!!" + tagStr.slice(18);
2518
- else tagStr = "!<" + tagStr + ">";
2519
- state.dump = tagStr + " " + state.dump;
2520
- }
2521
- }
2522
- return true;
2756
+ /** PascalCase class/interface name. */
2757
+ function className$6(name) {
2758
+ return toPascalCase(stripUrnPrefix(name));
2523
2759
  }
2524
- function getDuplicateReferences(object, state) {
2525
- var objects = [], duplicatesIndexes = [], index, length;
2526
- inspectNode(object, objects, duplicatesIndexes);
2527
- for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) state.duplicates.push(objects[duplicatesIndexes[index]]);
2528
- state.usedDuplicates = new Array(length);
2760
+ /** kebab-case file name (without extension). */
2761
+ function fileName$3(name) {
2762
+ return toKebabCase(stripUrnPrefix(name));
2529
2763
  }
2530
- function inspectNode(object, objects, duplicatesIndexes) {
2531
- var objectKeyList, index, length;
2532
- if (object !== null && typeof object === "object") {
2533
- index = objects.indexOf(object);
2534
- if (index !== -1) {
2535
- if (duplicatesIndexes.indexOf(index) === -1) duplicatesIndexes.push(index);
2536
- } else {
2537
- objects.push(object);
2538
- if (Array.isArray(object)) for (index = 0, length = object.length; index < length; index += 1) inspectNode(object[index], objects, duplicatesIndexes);
2539
- else {
2540
- objectKeyList = Object.keys(object);
2541
- for (index = 0, length = objectKeyList.length; index < length; index += 1) inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes);
2542
- }
2543
- }
2544
- }
2764
+ /** camelCase field name for domain interfaces. */
2765
+ function fieldName$6(name) {
2766
+ return toCamelCase(name);
2545
2767
  }
2546
- function dump$1(input, options) {
2547
- options = options || {};
2548
- var state = new State(options);
2549
- if (!state.noRefs) getDuplicateReferences(input, state);
2550
- var value = input;
2551
- if (state.replacer) value = state.replacer.call({ "": value }, "", value);
2552
- if (writeNode(state, 0, value, true, true)) return state.dump + "\n";
2553
- return "";
2768
+ /** snake_case field name for wire/response interfaces. */
2769
+ function wireFieldName(name) {
2770
+ return toSnakeCase(name);
2554
2771
  }
2555
- var dumper = { dump: dump$1 };
2556
- var load = loader.load;
2557
- loader.loadAll;
2558
- dumper.dump;
2559
- //#endregion
2560
- //#region src/shared/model-utils.ts
2561
2772
  /**
2562
- * Detect whether a model is a list wrapper -- the standard paginated
2563
- * list envelope with `data` (array), `list_metadata`, and optionally `object: 'list'`.
2773
+ * Active set of `Serialized${Name}` interfaces in the live SDK, harvested
2774
+ * from `ctx.apiSurface` once per generation run. When non-empty, the
2775
+ * legacy wire-naming scheme wins so existing hand-written serializer files
2776
+ * continue to compile.
2564
2777
  *
2565
- * These models are redundant because each language SDK already has its own
2566
- * pagination wrapper, and the runtime handles deserialization.
2778
+ * Set by `index.ts` immediately after `getSurface(ctx)` runs.
2567
2779
  */
2568
- function isListWrapperModel(model) {
2569
- const fieldsByName = new Map(model.fields.map((f) => [f.name, f]));
2570
- const dataField = fieldsByName.get("data");
2571
- if (!dataField) return false;
2572
- if (dataField.type.kind !== "array") return false;
2573
- if (!(fieldsByName.get("list_metadata") ?? fieldsByName.get("listMetadata"))) return false;
2574
- const objectField = fieldsByName.get("object");
2575
- if (objectField) {
2576
- if (objectField.type.kind !== "literal" || objectField.type.value !== "list") return false;
2577
- }
2578
- return true;
2780
+ let baselineSerializedNames = /* @__PURE__ */ new Set();
2781
+ function setBaselineSerializedNames(names) {
2782
+ baselineSerializedNames = names;
2579
2783
  }
2580
2784
  /**
2581
- * Detect whether a model is a list metadata model (e.g., ListMetadata).
2582
- * These models typically have exactly `before` and `after` nullable string fields.
2785
+ * Set of every interface name present in the baseline live SDK, regardless
2786
+ * of naming convention. Used to detect single-form baselines (where one
2787
+ * `*Response`-suffixed interface stands for both the domain and wire shape)
2788
+ * so we don't synthesize a non-existent `*Wire` variant.
2583
2789
  */
2584
- function isListMetadataModel(model) {
2585
- if (model.fields.length !== 2) return false;
2586
- const fieldsByName = new Map(model.fields.map((f) => [f.name, f]));
2587
- const before = fieldsByName.get("before");
2588
- const after = fieldsByName.get("after");
2589
- if (!before || !after) return false;
2590
- return isNullableString(before) && isNullableString(after);
2591
- }
2592
- /** Check if a field type is nullable string (nullable<string> or just string). */
2593
- function isNullableString(field) {
2594
- if (field.type.kind === "primitive" && field.type.type === "string") return true;
2595
- if (field.type.kind === "nullable" && field.type.inner.kind === "primitive" && field.type.inner.type === "string") return true;
2596
- return false;
2790
+ let baselineInterfaceNames = /* @__PURE__ */ new Set();
2791
+ function setBaselineInterfaceNames(names) {
2792
+ baselineInterfaceNames = names;
2597
2793
  }
2598
2794
  /**
2599
- * Discover the OpenAPI spec path from CLI args or environment.
2600
- * Returns null if not found.
2795
+ * IR models that belong to newly-adopted services should not be renamed by
2796
+ * structural baseline matches from unrelated hand-written services.
2601
2797
  */
2602
- function discoverSpecPath() {
2603
- const args = process.argv;
2604
- for (let i = 0; i < args.length; i++) {
2605
- if (args[i] === "--spec" && args[i + 1]) return resolve(args[i + 1]);
2606
- if (args[i]?.startsWith("--spec=")) return resolve(args[i].slice(7));
2607
- }
2608
- if (process.env.OPENAPI_SPEC_PATH) return resolve(process.env.OPENAPI_SPEC_PATH);
2609
- return null;
2798
+ let adoptedModelNames = /* @__PURE__ */ new Set();
2799
+ function setAdoptedModelNames(names) {
2800
+ adoptedModelNames = names;
2610
2801
  }
2611
- /** Cached raw spec to avoid re-reading on multiple calls. */
2612
- let _rawSpecCache = null;
2613
- let _rawSpecLoaded = false;
2614
- function loadRawSpec() {
2615
- if (_rawSpecLoaded) return _rawSpecCache;
2616
- _rawSpecLoaded = true;
2617
- const specPath = discoverSpecPath();
2618
- if (!specPath || !existsSync(specPath)) return null;
2619
- try {
2620
- _rawSpecCache = load(readFileSync(specPath, "utf-8"));
2621
- return _rawSpecCache;
2622
- } catch {
2623
- return null;
2624
- }
2802
+ function isAdoptedModelName(name) {
2803
+ return adoptedModelNames.has(name);
2625
2804
  }
2626
- /** Look up a schema by name in the raw spec's components/schemas. */
2627
- function lookupRawSchema(name) {
2628
- const spec = loadRawSpec();
2629
- if (!spec) return null;
2630
- return spec?.components?.schemas?.[name] ?? null;
2805
+ /**
2806
+ * Wire/response interface name.
2807
+ *
2808
+ * Resolution order:
2809
+ * 1. `Serialized${domainName}` if it exists in the baseline (legacy
2810
+ * workos-node convention; lets hand-written serializer files keep
2811
+ * compiling).
2812
+ * 2. `${domainName}Wire` when the domain ends in `Response` AND the
2813
+ * baseline actually has a `*Wire` interface (avoids
2814
+ * `FooResponseResponse` stutter).
2815
+ * 3. The bare `domainName` itself when it already ends in `Response` and
2816
+ * no `*Wire` variant exists — this happens when the structural matcher
2817
+ * maps an IR model to a baseline-wire-shaped interface
2818
+ * (`AuditLogSchemaJson` → `AuditLogSchemaResponse`) and the baseline
2819
+ * has no separate domain/wire split.
2820
+ * 4. `${domainName}Response` for the standard fresh-emit case.
2821
+ */
2822
+ function wireInterfaceName(domainName) {
2823
+ const serialized = `Serialized${domainName}`;
2824
+ if (baselineSerializedNames.has(serialized)) return serialized;
2825
+ if (domainName.endsWith("Response")) {
2826
+ const wireForm = `${domainName}Wire`;
2827
+ if (baselineInterfaceNames.has(wireForm)) return wireForm;
2828
+ if (baselineInterfaceNames.has(domainName)) return domainName;
2829
+ return wireForm;
2830
+ }
2831
+ return `${domainName}Response`;
2631
2832
  }
2632
- function createCollector() {
2633
- return {
2634
- models: [],
2635
- enums: [],
2636
- usedNames: /* @__PURE__ */ new Set()
2637
- };
2833
+ /** kebab-case service directory name. */
2834
+ function serviceDirName(name) {
2835
+ return toKebabCase(name);
2638
2836
  }
2639
- /**
2640
- * Singularize a snake_case name for use as an array-item model name.
2641
- * `redirect_uris` -> `redirect_uri`, `scopes` -> `scope`.
2642
- */
2643
- function singularizeSnake(name) {
2644
- if (name.endsWith("ies") && name.length > 3) return `${name.slice(0, -3)}y`;
2645
- if (name.endsWith("s") && !name.endsWith("ss")) return name.slice(0, -1);
2646
- return name;
2837
+ /** camelCase property name for service accessors on the client. */
2838
+ function servicePropertyName$4(name) {
2839
+ return toCamelCase(name);
2647
2840
  }
2648
2841
  /**
2649
- * Convert a raw OpenAPI type+format to an IR TypeRef.
2650
- *
2651
- * When `parentModelName` and `fieldName` are provided, inline objects and
2652
- * enums generate synthetic models/enums instead of degrading to `unknown`
2653
- * or `string`.
2842
+ * Resolve the effective service name, using the overlay-resolved class name
2843
+ * when available.
2654
2844
  */
2655
- function rawSchemaToTypeRef(schema, parentModelName, fName, collector) {
2656
- if (schema.const !== void 0) return {
2657
- kind: "literal",
2658
- value: schema.const
2659
- };
2660
- if (schema.enum && collector && parentModelName && fName) {
2661
- const syntheticName = `${parentModelName}_${fName}`;
2662
- if (!collector.usedNames.has(syntheticName) && !collector.usedNames.has(toSnakeCase(syntheticName))) {
2663
- collector.usedNames.add(syntheticName);
2664
- collector.enums.push({
2665
- name: syntheticName,
2666
- values: schema.enum.map((v) => ({
2667
- value: v,
2668
- description: void 0
2669
- }))
2670
- });
2671
- }
2672
- return {
2673
- kind: "enum",
2674
- name: syntheticName,
2675
- values: schema.enum
2676
- };
2677
- }
2678
- if (schema.enum) return {
2679
- kind: "primitive",
2680
- type: "string"
2681
- };
2682
- if (schema.$ref) return {
2683
- kind: "model",
2684
- name: schema.$ref.split("/").pop()
2685
- };
2686
- let baseType = schema.type;
2687
- let isNullable = false;
2688
- if (Array.isArray(baseType)) {
2689
- const nonNull = baseType.filter((t) => t !== "null");
2690
- isNullable = baseType.includes("null");
2691
- baseType = nonNull[0] ?? "string";
2692
- }
2693
- let ref;
2694
- if (baseType === "object" && schema.properties && collector && parentModelName && fName) {
2695
- const syntheticName = `${parentModelName}_${fName}`;
2696
- if (!collector.usedNames.has(syntheticName) && !collector.usedNames.has(toSnakeCase(syntheticName))) {
2697
- collector.usedNames.add(syntheticName);
2698
- const fields = [];
2699
- const requiredSet = new Set(schema.required ?? []);
2700
- for (const [propName, propSchema] of Object.entries(schema.properties)) fields.push({
2701
- name: propName,
2702
- type: rawSchemaToTypeRef(propSchema, syntheticName, propName, collector),
2703
- required: requiredSet.has(propName),
2704
- description: propSchema.description,
2705
- deprecated: propSchema.deprecated
2706
- });
2707
- collector.models.push({
2708
- name: syntheticName,
2709
- fields,
2710
- description: schema.description
2711
- });
2712
- }
2713
- ref = {
2714
- kind: "model",
2715
- name: syntheticName
2716
- };
2717
- } else if (baseType === "object" && schema.properties) ref = {
2718
- kind: "primitive",
2719
- type: "unknown"
2720
- };
2721
- else if (baseType === "array" && schema.items) {
2722
- const itemFieldName = fName ? singularizeSnake(fName) : void 0;
2723
- ref = {
2724
- kind: "array",
2725
- items: rawSchemaToTypeRef(schema.items, parentModelName, itemFieldName, collector)
2726
- };
2727
- } else if (baseType === "boolean") ref = {
2728
- kind: "primitive",
2729
- type: "boolean"
2730
- };
2731
- else if (baseType === "integer" || baseType === "number") ref = {
2732
- kind: "primitive",
2733
- type: baseType
2734
- };
2735
- else ref = {
2736
- kind: "primitive",
2737
- type: "string"
2738
- };
2739
- if (isNullable) return {
2740
- kind: "nullable",
2741
- inner: ref
2742
- };
2743
- return ref;
2845
+ function resolveServiceName(service, ctx) {
2846
+ return resolveClassName$5(service, ctx);
2744
2847
  }
2745
2848
  /**
2746
- * Extract fields from a raw OpenAPI object schema.
2747
- * All fields are returned as optional (not required) since they come from
2748
- * oneOf variants where only one variant is active at a time.
2849
+ * Build the set of model + enum class names exported by the SDK. Used to
2850
+ * detect collisions with operation-client class names a colliding service
2851
+ * gets a `Service` suffix appended.
2749
2852
  */
2750
- function extractFieldsFromRawSchema(schema, parentModelName, collector) {
2751
- const fields = [];
2752
- const props = schema.properties ?? {};
2753
- for (const [name, propSchema] of Object.entries(props)) fields.push({
2754
- name,
2755
- type: rawSchemaToTypeRef(propSchema, parentModelName, name, collector),
2756
- required: false,
2757
- description: propSchema.description,
2758
- deprecated: propSchema.deprecated
2759
- });
2760
- return fields;
2853
+ function buildExportedClassNameSet$4(ctx) {
2854
+ return buildExportedClassNameSet$5(ctx, className$6);
2761
2855
  }
2762
2856
  /**
2763
- * Recursively collect all fields from a oneOf schema, flattening nested
2764
- * allOf+oneOf compositions. All fields are marked optional.
2857
+ * Resolve a service's mount-target identifier, appending `Service` on
2858
+ * collision with an exported model/enum class. The result feeds `className`
2859
+ * and `fileName` so both the `export class` declaration and its file name
2860
+ * stay aligned (e.g. `OrganizationMembershipService` /
2861
+ * `organization-membership-service.ts`).
2765
2862
  */
2766
- function collectOneOfFields(schema, parentModelName, collector) {
2767
- const allFields = [];
2768
- const seenFieldNames = /* @__PURE__ */ new Set();
2769
- function walkSchema(s) {
2770
- if (s.properties) {
2771
- for (const f of extractFieldsFromRawSchema(s, parentModelName, collector)) if (!seenFieldNames.has(f.name)) {
2772
- seenFieldNames.add(f.name);
2773
- allFields.push(f);
2774
- }
2775
- }
2776
- if (s.allOf) for (const sub of s.allOf) walkSchema(sub);
2777
- if (s.oneOf) for (const variant of s.oneOf) walkSchema(variant);
2778
- if (s.anyOf) for (const variant of s.anyOf) walkSchema(variant);
2779
- }
2780
- walkSchema(schema);
2781
- return allFields;
2863
+ function resolveServiceTarget$4(target, exportedClasses) {
2864
+ return resolveServiceTarget$5(target, exportedClasses, className$6);
2782
2865
  }
2783
2866
  /**
2784
- * Check if a TypeRef is `unknown` (the degraded type for inline objects).
2867
+ * Build a map from IR service name -> resolved service name.
2785
2868
  */
2786
- function isUnknownType(ref) {
2787
- return ref.kind === "primitive" && ref.type === "unknown";
2869
+ function buildServiceNameMap(services, ctx) {
2870
+ const map = /* @__PURE__ */ new Map();
2871
+ for (const service of services) map.set(service.name, resolveServiceName(service, ctx));
2872
+ return map;
2873
+ }
2874
+ /** Resolve the output directory for a service. */
2875
+ function resolveServiceDir$1(resolvedServiceName) {
2876
+ return serviceDirName(resolvedServiceName);
2877
+ }
2878
+ /** Resolve the SDK method name for an operation, using resolved operations first. */
2879
+ function resolveMethodName$6(op, _service, ctx) {
2880
+ const resolved = lookupMethodName(op, buildResolvedLookup(ctx));
2881
+ if (resolved) return toCamelCase(resolved);
2882
+ const httpKey = `${op.httpMethod.toUpperCase()} ${op.path}`;
2883
+ const existing = ctx.overlayLookup?.methodByOperation?.get(httpKey);
2884
+ if (existing) return existing.methodName;
2885
+ return toCamelCase(op.name);
2886
+ }
2887
+ /** Resolve the SDK class name for a service, using resolved ops mountOn as canonical. */
2888
+ function resolveClassName$5(service, ctx) {
2889
+ for (const r of ctx.resolvedOperations ?? []) if (r.service.name === service.name) return r.mountOn;
2890
+ if (ctx.overlayLookup?.methodByOperation) for (const op of service.operations) {
2891
+ const httpKey = `${op.httpMethod.toUpperCase()} ${op.path}`;
2892
+ const existing = ctx.overlayLookup.methodByOperation.get(httpKey);
2893
+ if (existing) return existing.className;
2894
+ }
2895
+ return toPascalCase(service.name);
2788
2896
  }
2789
2897
  /**
2790
- * If a field is an `array<unknown>` (or `nullable<array<unknown>>`) and the
2791
- * raw spec defines inline object/enum items, replace the item type with a
2792
- * synthetic model/enum. Returns the original field unchanged when no upgrade
2793
- * is needed.
2898
+ * Resolve the interface name for a model, checking overlay first.
2899
+ *
2900
+ * Lookup order:
2901
+ * 1. `overlayLookup.interfaceByName` — exact-name overrides from the live SDK.
2902
+ * 2. `overlayLookup.modelNameByIR` — structurally-inferred matches (e.g., IR
2903
+ * `ValidateApiKey` with one field `value: string` → live SDK interface
2904
+ * `ValidateApiKeyOptions`).
2905
+ * 3. Type-alias resolution (when an alias points to an interface).
2906
+ * 4. Suffix-fallback heuristic for the workos-node `*Options` convention:
2907
+ * when the IR name `X` has no baseline match but `XOptions` does, use
2908
+ * `XOptions`. The convention is widely used for request-body interfaces
2909
+ * in workos-node (CreateOrganizationOptions, ListUsersOptions, etc.).
2910
+ * 5. Default — clean and PascalCase the IR name.
2794
2911
  */
2795
- function upgradeArrayItemType(field, rawSchema, parentModelName, collector) {
2796
- let arrayRef = null;
2797
- let isNullableWrapper = false;
2798
- if (field.type.kind === "array") arrayRef = field.type;
2799
- else if (field.type.kind === "nullable" && field.type.inner.kind === "array") {
2800
- arrayRef = field.type.inner;
2801
- isNullableWrapper = true;
2912
+ function resolveInterfaceName(name, ctx, opts) {
2913
+ const existing = ctx.overlayLookup?.interfaceByName?.get(name);
2914
+ if (existing) return existing;
2915
+ let inferred = adoptedModelNames.has(name) ? void 0 : ctx.overlayLookup?.modelNameByIR?.get(name);
2916
+ if (inferred) {
2917
+ if (inferred.startsWith("Serialized")) {
2918
+ const stripped = inferred.slice(10);
2919
+ if (stripped && ctx.apiSurface?.interfaces?.[stripped]) inferred = stripped;
2920
+ }
2921
+ if (inferred.endsWith("Response") && ctx.apiSurface?.interfaces) {
2922
+ const stripped = inferred.slice(0, -8);
2923
+ if (stripped && ctx.apiSurface.interfaces[stripped]) inferred = stripped;
2924
+ }
2925
+ return inferred;
2802
2926
  }
2803
- if (!arrayRef || arrayRef.kind !== "array") return field;
2804
- if (!isUnknownType(arrayRef.items)) return field;
2805
- const rawProp = rawSchema.properties?.[field.name];
2806
- if (!rawProp) return field;
2807
- let rawArraySchema = rawProp;
2808
- if (Array.isArray(rawProp.type)) {
2809
- if (rawProp.type.filter((t) => t !== "null")[0] === "array") rawArraySchema = rawProp;
2927
+ if (!opts?.skipTypeAlias && ctx.apiSurface?.typeAliases) {
2928
+ const alias = ctx.apiSurface.typeAliases[name];
2929
+ if (alias?.value && ctx.apiSurface.interfaces?.[alias.value]) return alias.value;
2810
2930
  }
2811
- if (rawArraySchema.type !== "array" && !(Array.isArray(rawArraySchema.type) && rawArraySchema.type.includes("array"))) return field;
2812
- if (!rawArraySchema.items) return field;
2813
- const itemFieldName = singularizeSnake(field.name);
2814
- const newItemRef = rawSchemaToTypeRef(rawArraySchema.items, parentModelName, itemFieldName, collector);
2815
- if (isUnknownType(newItemRef)) return field;
2816
- const newArrayRef = {
2817
- kind: "array",
2818
- items: newItemRef
2819
- };
2820
- const newType = isNullableWrapper ? {
2821
- kind: "nullable",
2822
- inner: newArrayRef
2823
- } : newArrayRef;
2824
- return {
2825
- ...field,
2826
- type: newType
2827
- };
2931
+ if (ctx.apiSurface?.interfaces) {
2932
+ const ifaces = ctx.apiSurface.interfaces;
2933
+ if (!ifaces[name]) {
2934
+ const optionsCandidate = `${name}Options`;
2935
+ const optionsInfo = ifaces[optionsCandidate];
2936
+ if (optionsInfo?.sourceFile) {
2937
+ const expectedStem = toKebabCase(stripUrnPrefix(name));
2938
+ if (optionsInfo.sourceFile.endsWith(`/${expectedStem}.interface.ts`)) return optionsCandidate;
2939
+ }
2940
+ }
2941
+ }
2942
+ return toPascalCase(stripUrnPrefix(ctx.apiSurface ? name : stripNoiseSuffixes(name)));
2828
2943
  }
2829
- let _lastSyntheticEnums = [];
2944
+ //#endregion
2945
+ //#region src/node/type-map.ts
2830
2946
  /**
2831
- * Return the synthetic enums generated during the last call to
2832
- * `enrichModelsFromSpec`. Call this after enrichment to merge them into the
2833
- * enum generation phase.
2947
+ * Map of enum name inlined string-union TS source.
2948
+ *
2949
+ * Set by `index.ts` once per generation run, sourced from `spec.enums` for
2950
+ * enums that have no baseline definition in the live SDK. When populated,
2951
+ * `mapTypeRef`/`mapWireTypeRef` substitute the union directly at the
2952
+ * reference site instead of emitting a separate import — this collapses
2953
+ * ~100 single-line enum files into inline literal types.
2834
2954
  */
2835
- function getSyntheticEnums() {
2836
- return _lastSyntheticEnums;
2955
+ let inlineEnumUnions = /* @__PURE__ */ new Map();
2956
+ function setInlineEnumUnions(map) {
2957
+ inlineEnumUnions = map;
2837
2958
  }
2838
- /**
2839
- * Find a property name that has a `const` value in ALL oneOf variants.
2840
- * Returns null if no shared const property is found.
2841
- */
2842
- function findSharedConstProperty(oneOfSchemas) {
2843
- if (oneOfSchemas.length === 0) return null;
2844
- const first = oneOfSchemas[0];
2845
- if (!first.properties) return null;
2846
- const candidates = Object.keys(first.properties).filter((name) => first.properties[name].const !== void 0);
2847
- for (const candidate of candidates) if (oneOfSchemas.every((variant) => variant.properties?.[candidate]?.const !== void 0)) return candidate;
2848
- return null;
2959
+ function isInlineEnum(name) {
2960
+ return inlineEnumUnions.has(name);
2849
2961
  }
2850
2962
  /**
2851
- * Build a discriminator mapping from const values to IR model names.
2852
- * For each oneOf variant's const value on `discProperty`, find the IR model
2853
- * whose field with the same name is a Literal type with that value.
2963
+ * Optional callback that resolves an IR model name to its live-SDK interface
2964
+ * name. Set by `index.ts` once per run. When present, `mapTypeRef` and
2965
+ * `mapWireTypeRef` use it instead of the raw IR name in their `model:` cases
2966
+ * — keeping field-type references in sync with import statements that the
2967
+ * caller emits via the same resolver. Without this, a structural match like
2968
+ * IR `AuditLogSchemaJson` → live `AuditLogSchemaResponse` would produce
2969
+ * `schema: AuditLogSchemaJson` in the body but
2970
+ * `import type { AuditLogSchemaResponse }` in the imports, leaving
2971
+ * `AuditLogSchemaJson` unbound.
2854
2972
  */
2855
- function buildDiscriminatorMapping(discProperty, oneOfSchemas, models, parentModelName) {
2856
- const mapping = {};
2857
- for (const variant of oneOfSchemas) {
2858
- const constValue = variant.properties?.[discProperty]?.const;
2859
- if (constValue === void 0) continue;
2860
- const variantModel = models.find((m) => m.name !== parentModelName && m.fields.some((f) => f.name === discProperty && f.type.kind === "literal" && f.type.value === constValue));
2861
- if (variantModel) mapping[String(constValue)] = variantModel.name;
2862
- }
2863
- return mapping;
2973
+ let domainNameResolver = null;
2974
+ function setDomainNameResolver(fn) {
2975
+ domainNameResolver = fn;
2976
+ }
2977
+ function resolveDomainName(irName) {
2978
+ return domainNameResolver ? domainNameResolver(irName) : irName;
2864
2979
  }
2865
2980
  /**
2866
- * Detect implicit discriminators on models without full oneOf flattening.
2867
- * Returns a new array with discriminator annotations; models without
2868
- * discriminators are returned as-is. Use this when you need discriminator
2869
- * info but don't want the side-effects of full enrichment (synthetic
2870
- * models/enums, field flattening).
2981
+ * Map an IR TypeRef to a TypeScript domain type string.
2982
+ * Domain types use PascalCase model names (e.g., `Organization`).
2871
2983
  */
2872
- function detectDiscriminators(models) {
2873
- if (!loadRawSpec()) return models;
2874
- let changed = false;
2875
- const result = models.map((model) => {
2876
- if (model.discriminator) return model;
2877
- const rawSchema = lookupRawSchema(model.name);
2878
- if (!rawSchema) return model;
2879
- const oneOfContainer = rawSchema.allOf?.find((s) => s.oneOf);
2880
- if (!oneOfContainer?.oneOf || oneOfContainer.oneOf.length === 0) return model;
2881
- const discProperty = findSharedConstProperty(oneOfContainer.oneOf);
2882
- if (!discProperty) return model;
2883
- const mapping = buildDiscriminatorMapping(discProperty, oneOfContainer.oneOf, models, model.name);
2884
- if (Object.keys(mapping).length === 0) return model;
2885
- changed = true;
2886
- return {
2887
- ...model,
2888
- fields: [],
2889
- discriminator: {
2890
- property: discProperty,
2891
- mapping
2892
- }
2893
- };
2984
+ function mapTypeRef$7(ref, opts) {
2985
+ const genericDefaults = opts?.genericDefaults;
2986
+ return mapTypeRef(ref, {
2987
+ primitive: mapPrimitive$6,
2988
+ array: (_r, items) => `${parenthesizeUnion(items)}[]`,
2989
+ model: (r) => resolveDomainName(r.name) + (genericDefaults?.get(r.name) ?? ""),
2990
+ enum: (r) => inlineEnumUnions.get(r.name) ?? r.name,
2991
+ union: (r, variants) => joinUnionVariants$5(r, variants),
2992
+ nullable: (_r, inner) => `${inner} | null`,
2993
+ literal: (r) => typeof r.value === "string" ? `'${r.value}'` : String(r.value),
2994
+ map: (_r, value) => `Record<string, ${value}>`
2894
2995
  });
2895
- return changed ? result : models;
2896
2996
  }
2897
2997
  /**
2898
- * Enrich IR models by flattening oneOf/allOf+oneOf variant fields from the raw spec.
2899
- *
2900
- * For models with 0 fields whose raw spec schema is a pure oneOf:
2901
- * - Collect all variant fields and add them as optional fields.
2902
- *
2903
- * For models whose raw spec schema has allOf containing a oneOf:
2904
- * - Collect the missing variant fields and add them as optional.
2905
- *
2906
- * Inline objects and enums in oneOf branches are promoted to synthetic
2907
- * models/enums instead of degrading to `object` / `string`.
2908
- *
2909
- * Returns a new array of enriched models (original models are not mutated).
2910
- * Synthetic enums are stored internally; retrieve them via `getSyntheticEnums()`.
2998
+ * Map an IR TypeRef to a TypeScript wire/response type string.
2999
+ * Model references get the `Response` suffix (e.g., `OrganizationResponse`).
2911
3000
  */
2912
- function enrichModelsFromSpec(models) {
2913
- if (!loadRawSpec()) {
2914
- _lastSyntheticEnums = [];
2915
- return models;
3001
+ function mapWireTypeRef(ref, opts) {
3002
+ const genericDefaults = opts?.genericDefaults;
3003
+ return mapTypeRef(ref, {
3004
+ primitive: mapWirePrimitive,
3005
+ array: (_r, items) => `${parenthesizeUnion(items)}[]`,
3006
+ model: (r) => wireInterfaceName(resolveDomainName(r.name)) + (genericDefaults?.get(r.name) ?? ""),
3007
+ enum: (r) => inlineEnumUnions.get(r.name) ?? r.name,
3008
+ union: (r, variants) => joinUnionVariants$5(r, variants),
3009
+ nullable: (_r, inner) => `${inner} | null`,
3010
+ literal: (r) => typeof r.value === "string" ? `'${r.value}'` : String(r.value),
3011
+ map: (_r, value) => `Record<string, ${value}>`
3012
+ });
3013
+ }
3014
+ function mapPrimitive$6(ref) {
3015
+ if (ref.format) switch (ref.format) {
3016
+ case "date-time": return "Date";
3017
+ case "int64": return "bigint";
2916
3018
  }
2917
- const collector = createCollector();
2918
- for (const m of models) {
2919
- collector.usedNames.add(m.name);
2920
- collector.usedNames.add(toSnakeCase(m.name));
3019
+ switch (ref.type) {
3020
+ case "string": return "string";
3021
+ case "integer":
3022
+ case "number": return "number";
3023
+ case "boolean": return "boolean";
3024
+ case "unknown": return "any";
2921
3025
  }
2922
- const enriched2 = models.map((model) => {
2923
- const rawSchema = lookupRawSchema(model.name);
2924
- if (!rawSchema) return model;
2925
- if (!(rawSchema.oneOf || rawSchema.allOf?.some((s) => s.oneOf))) return model;
2926
- if (rawSchema.discriminator || rawSchema.oneOf?.some((v) => v.discriminator) || rawSchema.allOf?.some((s) => s.discriminator || s.oneOf?.some((v) => v.discriminator))) return model;
2927
- const oneOfContainer = rawSchema.allOf?.find((s) => s.oneOf);
2928
- if (oneOfContainer?.oneOf && oneOfContainer.oneOf.length > 0) {
2929
- const discProperty = findSharedConstProperty(oneOfContainer.oneOf);
2930
- if (discProperty) {
2931
- const mapping = buildDiscriminatorMapping(discProperty, oneOfContainer.oneOf, models, model.name);
2932
- if (Object.keys(mapping).length > 0) return {
2933
- ...model,
2934
- fields: [],
2935
- discriminator: {
2936
- property: discProperty,
2937
- mapping
2938
- }
2939
- };
2940
- }
2941
- }
2942
- const variantFields = collectOneOfFields(rawSchema, model.name, collector);
2943
- if (variantFields.length === 0) return model;
2944
- const existingNames = new Set(model.fields.map((f) => f.name));
2945
- const newFields = variantFields.filter((f) => !existingNames.has(f.name));
2946
- if (newFields.length === 0) return model;
2947
- return {
2948
- ...model,
2949
- fields: [...model.fields, ...newFields]
2950
- };
2951
- }).map((model) => {
2952
- const rawSchema = lookupRawSchema(model.name);
2953
- if (!rawSchema?.properties) return model;
2954
- let modified = false;
2955
- const newFields = model.fields.map((field) => {
2956
- const upgraded = upgradeArrayItemType(field, rawSchema, model.name, collector);
2957
- if (upgraded !== field) modified = true;
2958
- return upgraded;
2959
- });
2960
- return modified ? {
2961
- ...model,
2962
- fields: newFields
2963
- } : model;
2964
- });
2965
- _lastSyntheticEnums = collector.enums.map((e) => ({
2966
- name: e.name,
2967
- values: e.values.map((v) => ({
2968
- value: v.value,
2969
- description: v.description
2970
- }))
2971
- }));
2972
- const existingSnakeNames = new Set(enriched2.map((m) => toSnakeCase(m.name)));
2973
- const filteredSynthetic = collector.models.filter((m) => !existingSnakeNames.has(toSnakeCase(m.name)));
2974
- return [...enriched2, ...filteredSynthetic];
3026
+ }
3027
+ function mapWirePrimitive(ref) {
3028
+ switch (ref.type) {
3029
+ case "string": return "string";
3030
+ case "integer":
3031
+ case "number": return "number";
3032
+ case "boolean": return "boolean";
3033
+ case "unknown": return "any";
3034
+ }
3035
+ }
3036
+ function joinUnionVariants$5(ref, variants) {
3037
+ const unique = [...new Set(variants)];
3038
+ if (ref.compositionKind === "allOf") return unique.join(" & ");
3039
+ if (unique.length === 1) return unique[0];
3040
+ return unique.join(" | ");
3041
+ }
3042
+ function parenthesizeUnion(type) {
3043
+ return type.includes(" | ") || type.includes(" & ") ? `(${type})` : type;
2975
3044
  }
2976
3045
  //#endregion
2977
3046
  //#region src/node/utils.ts
@@ -4463,15 +4532,19 @@ function hasCompatibleConstructor(className, ctx) {
4463
4532
  */
4464
4533
  function resolveResourceClassName$3(service, ctx) {
4465
4534
  const overlayName = resolveServiceName(service, ctx);
4466
- if (hasCompatibleConstructor(overlayName, ctx)) return overlayName;
4467
- const irName = toPascalCase(service.name);
4468
- if (irName === overlayName) return irName + "Endpoints";
4469
- return irName;
4535
+ let base;
4536
+ if (hasCompatibleConstructor(overlayName, ctx)) base = overlayName;
4537
+ else {
4538
+ const irName = toPascalCase(service.name);
4539
+ base = irName === overlayName ? `${irName}Endpoints` : irName;
4540
+ }
4541
+ return resolveServiceTarget$4(base, buildExportedClassNameSet$4(ctx));
4470
4542
  }
4471
4543
  function resolveResourceDir(service, ctx) {
4472
4544
  const resolvedName = resolveResourceClassName$3(service, ctx);
4473
4545
  if (resolvedName === "WebhooksEndpoints") return "webhooks";
4474
- return resolveServiceDir$1(resolvedName);
4546
+ const overlayName = resolveServiceName(service, ctx);
4547
+ return resolveServiceDir$1(resolvedName === `${overlayName}Service` ? overlayName : resolvedName);
4475
4548
  }
4476
4549
  /** Standard pagination query params handled by PaginationOptions — not imported individually. */
4477
4550
  const PAGINATION_PARAM_NAMES = new Set([
@@ -6562,7 +6635,7 @@ function generateWorkOSClient$1(spec, ctx) {
6562
6635
  for (const service of spec.services) {
6563
6636
  if (coveredServices.has(service.name)) continue;
6564
6637
  const resolvedName = resolveResourceClassName$3(service, ctx);
6565
- const propName = servicePropertyName$4(resolvedName);
6638
+ const propName = servicePropertyName$4(resolveServiceName(service, ctx));
6566
6639
  if (existingProps.has(propName)) continue;
6567
6640
  const classDeprecation = ctx.apiSurface?.classes?.[resolvedName]?.deprecationMessage;
6568
6641
  if (classDeprecation !== void 0) {
@@ -6988,7 +7061,7 @@ function generateServiceTest$3(service, spec, ctx, modelMap, mountAccessors) {
6988
7061
  const resolvedName = resolveResourceClassName$3(service, ctx);
6989
7062
  const serviceDir = resolveResourceDir(service, ctx);
6990
7063
  const serviceClass = resolvedName;
6991
- const serviceProp = mountAccessors?.get(service.name) ?? servicePropertyName$4(resolvedName);
7064
+ const serviceProp = mountAccessors?.get(service.name) ?? servicePropertyName$4(resolveServiceName(service, ctx));
6992
7065
  const testPath = `src/${serviceDir}/${fileName$3(resolvedName)}.spec.ts`;
6993
7066
  const plans = service.operations.map((op) => ({
6994
7067
  op,
@@ -7952,6 +8025,25 @@ function resolveMethodName$5(op, _service, ctx) {
7952
8025
  if (existing) return toSnakeCase(existing.methodName);
7953
8026
  return toSnakeCase(op.name);
7954
8027
  }
8028
+ /**
8029
+ * Build the set of model + enum class names exported by the SDK. Used to
8030
+ * detect collisions with operation-client class names — a colliding service
8031
+ * gets a `Service` suffix appended.
8032
+ */
8033
+ function buildExportedClassNameSet$3(ctx) {
8034
+ return buildExportedClassNameSet$5(ctx, className$5);
8035
+ }
8036
+ /**
8037
+ * Resolve a service's mount-target identifier, appending `Service` on
8038
+ * collision with an exported model/enum class. Feeds `className`/`fileName`
8039
+ * so the class declaration, file, and any qualified references stay aligned.
8040
+ *
8041
+ * Accessor names (`servicePropertyName`) intentionally use the RAW target —
8042
+ * `client.organization_membership` reads better than the suffixed form.
8043
+ */
8044
+ function resolveServiceTarget$3(target, exportedClasses) {
8045
+ return resolveServiceTarget$5(target, exportedClasses, className$5);
8046
+ }
7955
8047
  /** Resolve the SDK class name for a service, using resolved operations' mountOn. */
7956
8048
  function resolveClassName$4(service, ctx) {
7957
8049
  for (const r of ctx.resolvedOperations ?? []) if (r.service.name === service.name) return r.mountOn;
@@ -10001,10 +10093,11 @@ function generateResources$6(services, ctx) {
10001
10093
  name: resolveClassName$4(s, ctx),
10002
10094
  operations: s.operations
10003
10095
  }));
10096
+ const exportedClasses = buildExportedClassNameSet$3(ctx);
10004
10097
  for (const { name: mountName, operations: allOperations } of entries) {
10005
10098
  if (allOperations.length === 0) continue;
10006
10099
  const dirName = moduleName$2(mountName);
10007
- const resourceClassName = className$5(mountName);
10100
+ const resourceClassName = className$5(resolveServiceTarget$3(mountName, exportedClasses));
10008
10101
  const importPrefix = relativeImportPrefix(dirName);
10009
10102
  const lines = [];
10010
10103
  lines.push("from __future__ import annotations");
@@ -10450,9 +10543,10 @@ function generateWorkOSClient(spec, ctx) {
10450
10543
  lines.push(" AsyncWorkOSClient as _AsyncBase,");
10451
10544
  lines.push(")");
10452
10545
  const serviceDirMap = buildMountDirMap$1(ctx);
10546
+ const exportedClasses = buildExportedClassNameSet$3(ctx);
10453
10547
  for (const service of topLevelServices) {
10454
10548
  const resolvedName = resolveResourceClassName$2(service, ctx);
10455
- const clsName = className$5(resolvedName);
10549
+ const clsName = className$5(resolveServiceTarget$3(resolvedName, exportedClasses));
10456
10550
  const dirName = serviceDirMap.get(service.name) ?? resolveServiceDir(resolvedName);
10457
10551
  const importLine = `from .${dirToModule(dirName)}._resource import ${clsName}, Async${clsName}`;
10458
10552
  if (importLine.length > 88) {
@@ -10473,7 +10567,7 @@ function generateWorkOSClient(spec, ctx) {
10473
10567
  const generatedProps = /* @__PURE__ */ new Set();
10474
10568
  for (const service of topLevelServices) {
10475
10569
  const resolvedName = resolveResourceClassName$2(service, ctx);
10476
- const clsName = className$5(resolvedName);
10570
+ const clsName = className$5(resolveServiceTarget$3(resolvedName, exportedClasses));
10477
10571
  const prop = servicePropertyName$3(resolvedName);
10478
10572
  const readable = clsName.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2");
10479
10573
  lines.push("");
@@ -10492,7 +10586,7 @@ function generateWorkOSClient(spec, ctx) {
10492
10586
  const asyncGeneratedProps = /* @__PURE__ */ new Set();
10493
10587
  for (const service of topLevelServices) {
10494
10588
  const resolvedName = resolveResourceClassName$2(service, ctx);
10495
- const clsName = className$5(resolvedName);
10589
+ const clsName = className$5(resolveServiceTarget$3(resolvedName, exportedClasses));
10496
10590
  const prop = servicePropertyName$3(resolvedName);
10497
10591
  const readable = clsName.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2");
10498
10592
  lines.push("");
@@ -10531,16 +10625,18 @@ function generateServiceInits(spec, ctx) {
10531
10625
  const files = [];
10532
10626
  const topLevel = deduplicateByMount$4(spec.services, ctx);
10533
10627
  const serviceDirMap = buildMountDirMap$1(ctx);
10628
+ const exportedClasses = buildExportedClassNameSet$3(ctx);
10534
10629
  const mountGroups = groupByMount(ctx);
10535
10630
  for (const service of topLevel) {
10536
10631
  const resolvedName = resolveResourceClassName$2(service, ctx);
10632
+ const clsName = className$5(resolveServiceTarget$3(resolvedName, exportedClasses));
10537
10633
  const dirName = serviceDirMap.get(service.name) ?? resolveServiceDir(resolvedName);
10538
10634
  const lines = [];
10539
10635
  const mountTarget = getMountTarget(service, ctx);
10540
10636
  const groupClassNames = collectParameterGroupClassNames(mountGroups.get(mountTarget)?.operations ?? service.operations);
10541
10637
  const aliasedImports = [
10542
- resolvedName,
10543
- `Async${resolvedName}`,
10638
+ clsName,
10639
+ `Async${clsName}`,
10544
10640
  ...groupClassNames
10545
10641
  ].map((n) => `${n} as ${n}`);
10546
10642
  lines.push(`from ._resource import ${aliasedImports.join(", ")}`);
@@ -12010,6 +12106,22 @@ function className$4(name) {
12010
12106
  if (PHP_RESERVED_CLASS_NAMES.has(result)) result += "Model";
12011
12107
  return result;
12012
12108
  }
12109
+ /**
12110
+ * Build the set of model + enum class names exported by the SDK. Used to
12111
+ * detect collisions with operation-client class names — a colliding service
12112
+ * gets a `Service` suffix appended.
12113
+ */
12114
+ function buildExportedClassNameSet$2(ctx) {
12115
+ return buildExportedClassNameSet$5(ctx, className$4);
12116
+ }
12117
+ /**
12118
+ * Resolve a service's mount-target identifier, appending `Service` on
12119
+ * collision with an exported model/enum class. Used in `\Service\…` files
12120
+ * to avoid `use WorkOS\Resource\X; class X` PHP fatal errors.
12121
+ */
12122
+ function resolveServiceTarget$2(target, exportedClasses) {
12123
+ return resolveServiceTarget$5(target, exportedClasses, className$4);
12124
+ }
12013
12125
  /** Resolve the SDK method name for an operation, using resolved operations first. */
12014
12126
  function resolveMethodName$4(op, _service, ctx) {
12015
12127
  const resolved = lookupMethodName(op, buildResolvedLookup(ctx));
@@ -12542,9 +12654,10 @@ function generateResources$5(services, ctx) {
12542
12654
  name: className$4(s.name),
12543
12655
  operations: s.operations
12544
12656
  }));
12657
+ const exportedClasses = buildExportedClassNameSet$2(ctx);
12545
12658
  for (const { name: mountName, operations } of entries) {
12546
12659
  if (operations.length === 0) continue;
12547
- const resourceName = className$4(mountName);
12660
+ const resourceName = className$4(resolveServiceTarget$2(mountName, exportedClasses));
12548
12661
  const mergedService = {
12549
12662
  name: mountName,
12550
12663
  operations
@@ -13080,10 +13193,11 @@ function buildServiceAccessPaths$2(services, ctx) {
13080
13193
  }
13081
13194
  function deduplicateByMount$3(services, ctx) {
13082
13195
  const seen = /* @__PURE__ */ new Map();
13196
+ const exportedClasses = buildExportedClassNameSet$2(ctx);
13083
13197
  for (const service of services) {
13084
13198
  const target = getMountTarget(service, ctx);
13085
13199
  if (!seen.has(target)) seen.set(target, {
13086
- name: className$4(target),
13200
+ name: className$4(resolveServiceTarget$2(target, exportedClasses)),
13087
13201
  propName: servicePropertyName$2(target)
13088
13202
  });
13089
13203
  }
@@ -18965,6 +19079,33 @@ function packageSegment(name) {
18965
19079
  function apiClassName(name) {
18966
19080
  return className$1(name);
18967
19081
  }
19082
+ /**
19083
+ * Resolve the Kotlin service class name with the collision suffix applied
19084
+ * when needed. Wraps `apiClassName` so callers don't need to thread the
19085
+ * exported-classes set through unrelated emission logic.
19086
+ */
19087
+ function resolveApiClassName(name, exportedClasses) {
19088
+ return apiClassName(resolveServiceTarget$1(name, exportedClasses));
19089
+ }
19090
+ /**
19091
+ * Build the set of model + enum class names exported by the SDK. Used to
19092
+ * detect collisions with operation-client class names — a colliding service
19093
+ * gets a `Service` suffix appended.
19094
+ */
19095
+ function buildExportedClassNameSet$1(ctx) {
19096
+ return buildExportedClassNameSet$5(ctx, className$1);
19097
+ }
19098
+ /**
19099
+ * Resolve a service's mount-target identifier, appending `Service` on
19100
+ * collision with an exported model/enum class. Kotlin sees the collision
19101
+ * when a service class shares a simple name with an imported model class
19102
+ * (e.g. `com.workos.models.OrganizationMembership` vs
19103
+ * `com.workos.organizationmembership.OrganizationMembership`) — the file's
19104
+ * local declaration shadows the import for unqualified references.
19105
+ */
19106
+ function resolveServiceTarget$1(target, exportedClasses) {
19107
+ return resolveServiceTarget$5(target, exportedClasses, className$1);
19108
+ }
18968
19109
  /** Accessor property exposed on the WorkOS client (camelCase). */
18969
19110
  function servicePropertyName$1(name) {
18970
19111
  return toCamelCase(name);
@@ -20134,12 +20275,13 @@ function generateResources$2(services, ctx) {
20134
20275
  if (mountGroups.size === 0) return [];
20135
20276
  const files = [];
20136
20277
  const resolvedLookup = buildResolvedLookup(ctx);
20278
+ const exportedClasses = buildExportedClassNameSet$1(ctx);
20137
20279
  for (const [mountName, group] of mountGroups) {
20138
20280
  const classCode = generateApiClass(mountName, group.operations, ctx, resolvedLookup);
20139
20281
  if (!classCode) continue;
20140
20282
  const pkg = packageSegment(mountName);
20141
20283
  files.push({
20142
- path: `${KOTLIN_SRC_PREFIX$1}com/workos/${pkg}/${apiClassName(mountName)}.kt`,
20284
+ path: `${KOTLIN_SRC_PREFIX$1}com/workos/${pkg}/${resolveApiClassName(mountName, exportedClasses)}.kt`,
20143
20285
  content: classCode,
20144
20286
  overwriteExisting: true
20145
20287
  });
@@ -20148,7 +20290,7 @@ function generateResources$2(services, ctx) {
20148
20290
  }
20149
20291
  function generateApiClass(mountName, operations, ctx, resolvedLookup) {
20150
20292
  if (operations.length === 0) return null;
20151
- const apiClass = apiClassName(mountName);
20293
+ const apiClass = resolveApiClassName(mountName, buildExportedClassNameSet$1(ctx));
20152
20294
  const pkg = `com.workos.${packageSegment(mountName)}`;
20153
20295
  const imports = /* @__PURE__ */ new Set();
20154
20296
  imports.add("com.workos.WorkOS");
@@ -20949,8 +21091,9 @@ function generateClient$2(spec, ctx) {
20949
21091
  if (targets.length === 0) return [];
20950
21092
  const imports = /* @__PURE__ */ new Set();
20951
21093
  const accessorLines = [];
21094
+ const exportedClasses = buildExportedClassNameSet$1(ctx);
20952
21095
  for (const mount of targets) {
20953
- const apiCls = apiClassName(mount);
21096
+ const apiCls = resolveApiClassName(mount, exportedClasses);
20954
21097
  const fqn = `com.workos.${packageSegment(mount)}.${apiCls}`;
20955
21098
  imports.add(fqn);
20956
21099
  const prop = servicePropertyName$1(mount);
@@ -21032,12 +21175,13 @@ function generateTests$2(spec, ctx) {
21032
21175
  const files = [];
21033
21176
  const mountGroups = groupByMount(ctx);
21034
21177
  const resolvedLookup = buildResolvedLookup(ctx);
21178
+ const exportedClasses = buildExportedClassNameSet$1(ctx);
21035
21179
  for (const [mountName, group] of mountGroups) {
21036
21180
  const content = generateServiceTestClass(mountName, group.operations, ctx, resolvedLookup);
21037
21181
  if (!content) continue;
21038
21182
  const pkg = packageSegment(mountName);
21039
21183
  files.push({
21040
- path: `${TEST_PREFIX}com/workos/${pkg}/${apiClassName(mountName)}Test.kt`,
21184
+ path: `${TEST_PREFIX}com/workos/${pkg}/${resolveApiClassName(mountName, exportedClasses)}Test.kt`,
21041
21185
  content,
21042
21186
  overwriteExisting: true
21043
21187
  });
@@ -21106,7 +21250,7 @@ function generateServiceTestClass(mountName, operations, ctx, resolvedLookup) {
21106
21250
  if (anyForbidden) imports.add("com.github.tomakehurst.wiremock.client.WireMock.absent");
21107
21251
  if (uniqueTests.some((t) => t.canEmitHappyPath && t.responseAssertions.length > 0)) imports.add("org.junit.jupiter.api.Assertions.assertEquals");
21108
21252
  const pkg = packageSegment(mountName);
21109
- const apiCls = apiClassName(mountName);
21253
+ const apiCls = resolveApiClassName(mountName, buildExportedClassNameSet$1(ctx));
21110
21254
  if (uniqueTests.some((t) => !t.canEmitHappyPath)) imports.add("org.junit.jupiter.api.Disabled");
21111
21255
  const lines = [];
21112
21256
  lines.push(`package com.workos.${pkg}`);
@@ -22022,6 +22166,30 @@ function moduleName$1(name) {
22022
22166
  return toSnakeCase(name);
22023
22167
  }
22024
22168
  /**
22169
+ * Build the set of model + enum Ruby class names that the SDK exposes under
22170
+ * `WorkOS::`. Used to detect collisions with operation-client class names —
22171
+ * a colliding service gets a `Service` suffix (`OrganizationMembershipService`)
22172
+ * so it doesn't shadow the model class under Zeitwerk's collapsed namespace.
22173
+ */
22174
+ function buildExportedClassNameSet(ctx) {
22175
+ return buildExportedClassNameSet$5(ctx, className);
22176
+ }
22177
+ /**
22178
+ * Resolve a service's mount-target identifier, appending `Service` on
22179
+ * collision with an exported model/enum class name. The returned PascalCase
22180
+ * value feeds `className`/`fileName` to derive matching class + file names
22181
+ * (e.g. `OrganizationMembershipService` / `organization_membership_service`).
22182
+ *
22183
+ * Accessor names (`servicePropertyName`) intentionally use the RAW target —
22184
+ * `client.organization_membership` is more readable than the suffixed form.
22185
+ *
22186
+ * The directory used by `loader.collapse` (the model home) likewise uses the
22187
+ * raw target.
22188
+ */
22189
+ function resolveServiceTarget(target, exportedClasses) {
22190
+ return resolveServiceTarget$5(target, exportedClasses, className);
22191
+ }
22192
+ /**
22025
22193
  * PascalCase class name for a parameter-group variant. Mirrors the Python
22026
22194
  * convention: group "password" + variant "plaintext" → `PasswordPlaintext`.
22027
22195
  * Used as the Ruby constant under the WorkOS module.
@@ -22796,9 +22964,11 @@ function generateResources$1(services, ctx) {
22796
22964
  const listWrapperModels = /* @__PURE__ */ new Map();
22797
22965
  for (const m of ctx.spec.models) if (isListWrapperModel(m)) listWrapperModels.set(m.name, m);
22798
22966
  const groupOwners = buildGroupOwnerMap(ctx);
22967
+ const exportedClasses = buildExportedClassNameSet(ctx);
22799
22968
  for (const [mountTarget, group] of groups) {
22800
- const cls = className(mountTarget);
22801
- const file = fileName(mountTarget);
22969
+ const resolvedTarget = resolveServiceTarget(mountTarget, exportedClasses);
22970
+ const cls = className(resolvedTarget);
22971
+ const file = fileName(resolvedTarget);
22802
22972
  const operations = group.operations;
22803
22973
  if (operations.length === 0) continue;
22804
22974
  const requires = /* @__PURE__ */ new Set();
@@ -22826,7 +22996,8 @@ function generateResources$1(services, ctx) {
22826
22996
  modelByName,
22827
22997
  listWrapperModels,
22828
22998
  requires,
22829
- groupOwners
22999
+ groupOwners,
23000
+ exportedClasses
22830
23001
  });
22831
23002
  methodBodies.push(body);
22832
23003
  if (resolved?.wrappers && resolved.wrappers.length > 0) {
@@ -22872,12 +23043,12 @@ function generateResources$1(services, ctx) {
22872
23043
  }
22873
23044
  /** Build a single Ruby method from an Operation. */
22874
23045
  function emitMethod(args) {
22875
- const { op, method, defaults, inferFromClient, hiddenParams, enumNames, modelNames, modelByName, listWrapperModels, requires, groupOwners } = args;
23046
+ const { op, method, defaults, inferFromClient, hiddenParams, enumNames, modelNames, modelByName, listWrapperModels, requires, groupOwners, exportedClasses } = args;
22876
23047
  /** Fully-qualified Ruby constant for a variant (e.g. WorkOS::UserManagement::PasswordPlaintext). */
22877
23048
  const variantClassRef = (group, variantName) => {
22878
23049
  const owner = groupOwners.get(group.name);
22879
23050
  if (!owner) throw new Error(`No owner mount target found for parameter group '${group.name}'`);
22880
- return scopedGroupVariantClassName(owner, group.name, variantName);
23051
+ return scopedGroupVariantClassName(resolveServiceTarget(owner, exportedClasses), group.name, variantName);
22881
23052
  };
22882
23053
  planOperation(op);
22883
23054
  const lines = [];
@@ -23429,8 +23600,9 @@ function rubyCamelize(basename) {
23429
23600
  function buildInflectionMap(spec, ctx) {
23430
23601
  const inflections = /* @__PURE__ */ new Map();
23431
23602
  inflections.set("workos", "WorkOS");
23603
+ const exportedClasses = buildExportedClassNameSet(ctx);
23432
23604
  for (const service of buildTopLevelServices(spec, ctx)) {
23433
- const target = getMountTarget(service, ctx) || resolveClassName(service, ctx);
23605
+ const target = resolveServiceTarget(getMountTarget(service, ctx) || resolveClassName(service, ctx), exportedClasses);
23434
23606
  const cls = className(target);
23435
23607
  const file = fileName(target);
23436
23608
  if (rubyCamelize(file) !== cls) inflections.set(file, cls);
@@ -23522,10 +23694,11 @@ function generateClientClass(spec, ctx) {
23522
23694
  lines.push("module WorkOS");
23523
23695
  lines.push(" class Client < BaseClient");
23524
23696
  const topLevelServices = buildTopLevelServices(spec, ctx);
23697
+ const exportedClasses = buildExportedClassNameSet(ctx);
23525
23698
  for (const service of topLevelServices) {
23526
- const target = getMountTarget(service, ctx) || resolveClassName(service, ctx);
23527
- const cls = className(target);
23528
- const prop = servicePropertyName(target);
23699
+ const rawTarget = getMountTarget(service, ctx) || resolveClassName(service, ctx);
23700
+ const cls = className(resolveServiceTarget(rawTarget, exportedClasses));
23701
+ const prop = servicePropertyName(rawTarget);
23529
23702
  lines.push("");
23530
23703
  lines.push(` def ${prop}`);
23531
23704
  lines.push(` @${prop} ||= WorkOS::${cls}.new(self)`);
@@ -23571,10 +23744,12 @@ function generateTests$1(spec, ctx) {
23571
23744
  for (const m of models) modelByName.set(m.name, m);
23572
23745
  const lookup = buildResolvedLookup(ctx);
23573
23746
  const groupOwners = buildGroupOwnerMap(ctx);
23747
+ const exportedClasses = buildExportedClassNameSet(ctx);
23574
23748
  for (const [mountTarget, group] of groups) {
23575
- const cls = className(mountTarget);
23749
+ const resolvedTarget = resolveServiceTarget(mountTarget, exportedClasses);
23750
+ const cls = className(resolvedTarget);
23576
23751
  const prop = servicePropertyName(mountTarget);
23577
- const file = fileName(mountTarget);
23752
+ const file = fileName(resolvedTarget);
23578
23753
  const lines = [];
23579
23754
  lines.push(`require 'test_helper'`);
23580
23755
  lines.push("");
@@ -23600,7 +23775,7 @@ function generateTests$1(spec, ctx) {
23600
23775
  const httpMethodSym = `:${op.httpMethod.toLowerCase()}`;
23601
23776
  const resolved = lookupResolved(op, lookup);
23602
23777
  const hiddenParams = buildHiddenParams$1(resolved);
23603
- const callArgs = buildCallArgsStub(op, modelByName, hiddenParams, groupOwners, models);
23778
+ const callArgs = buildCallArgsStub(op, modelByName, hiddenParams, groupOwners, models, exportedClasses);
23604
23779
  const bodyMatcher = buildBodyMatcher(op, modelByName, hiddenParams, models);
23605
23780
  authMethodManifest.push({
23606
23781
  method,
@@ -23629,7 +23804,7 @@ function generateTests$1(spec, ctx) {
23629
23804
  for (const group of op.parameterGroups ?? []) for (let vi = 1; vi < group.variants.length; vi++) {
23630
23805
  const variant = group.variants[vi];
23631
23806
  const overrides = new Map([[group.name, vi]]);
23632
- const variantCallArgs = buildCallArgsStub(op, modelByName, hiddenParams, groupOwners, models, overrides);
23807
+ const variantCallArgs = buildCallArgsStub(op, modelByName, hiddenParams, groupOwners, models, exportedClasses, overrides);
23633
23808
  const variantBodyMatcher = buildBodyMatcher(op, modelByName, hiddenParams, models, overrides);
23634
23809
  const suffix = `with_${fieldName$1(group.name)}_${fieldName$1(variant.name)}`;
23635
23810
  lines.push("");
@@ -23786,7 +23961,7 @@ function roundTripStub(ref, enumNames) {
23786
23961
  * default to variant 0. Used to emit per-variant test cases that exercise the
23787
23962
  * second/third arm of each parameter-group dispatcher.
23788
23963
  */
23789
- function buildCallArgsStub(op, modelByName, hiddenParams, groupOwners, models, variantOverrides = /* @__PURE__ */ new Map()) {
23964
+ function buildCallArgsStub(op, modelByName, hiddenParams, groupOwners, models, exportedClasses, variantOverrides = /* @__PURE__ */ new Map()) {
23790
23965
  const parts = [];
23791
23966
  const seen = /* @__PURE__ */ new Set();
23792
23967
  const pathParamNames = /* @__PURE__ */ new Set();
@@ -23828,7 +24003,7 @@ function buildCallArgsStub(op, modelByName, hiddenParams, groupOwners, models, v
23828
24003
  if (variant) {
23829
24004
  const owner = groupOwners.get(group.name);
23830
24005
  if (!owner) throw new Error(`No owner mount target found for parameter group '${group.name}'`);
23831
- const variantClass = scopedGroupVariantClassName(owner, group.name, variant.name);
24006
+ const variantClass = scopedGroupVariantClassName(resolveServiceTarget(owner, exportedClasses), group.name, variant.name);
23832
24007
  const fieldStubs = variant.parameters.map((p) => `${fieldName$1(p.name)}: ${stubValueFor(pickVariantParamType(p.type, bodyFieldTypes.get(p.name)))}`).join(", ");
23833
24008
  parts.push(`${name}: ${variantClass}.new(${fieldStubs})`);
23834
24009
  }
@@ -23969,6 +24144,10 @@ function stubUrlRegex(escaped) {
23969
24144
  * Uses each resolved operation's actual mountOn (not the service default) so
23970
24145
  * operations remounted via operationHints land on the correct service prop.
23971
24146
  * Split operations emit one entry per wrapper (keyed by wrapper name + variant).
24147
+ *
24148
+ * The accessor (`service` field) uses the raw mountOn — accessor names stay
24149
+ * unsuffixed even when the underlying service class gets a `Service` suffix
24150
+ * on collision.
23972
24151
  */
23973
24152
  function buildOperationsMap$1(spec, ctx) {
23974
24153
  const manifest = {};
@@ -24069,8 +24248,10 @@ function generateRbiFiles(spec, ctx) {
24069
24248
  const listWrapperModels = /* @__PURE__ */ new Map();
24070
24249
  for (const m of spec.models) if (isListWrapperModel(m)) listWrapperModels.set(m.name, m);
24071
24250
  const groupOwners = buildGroupOwnerMap(ctx);
24251
+ const exportedClasses = buildExportedClassNameSet(ctx);
24072
24252
  for (const [mountTarget, group] of groups) {
24073
- const cls = className(mountTarget);
24253
+ const resolvedTarget = resolveServiceTarget(mountTarget, exportedClasses);
24254
+ const cls = className(resolvedTarget);
24074
24255
  const lines = [];
24075
24256
  lines.push("# typed: strong");
24076
24257
  lines.push("");
@@ -24078,6 +24259,7 @@ function generateRbiFiles(spec, ctx) {
24078
24259
  lines.push(` class ${cls}`);
24079
24260
  const variants = collectVariantsForMountTarget(ctx, spec.models, mountTarget);
24080
24261
  for (const v of variants) {
24262
+ v.mountTarget = resolvedTarget;
24081
24263
  for (const line of emitInlineVariantRbi(v)) lines.push(line);
24082
24264
  lines.push("");
24083
24265
  }
@@ -24102,7 +24284,8 @@ function generateRbiFiles(spec, ctx) {
24102
24284
  const groupSorbetType = (group) => {
24103
24285
  const owner = groupOwners.get(group.name);
24104
24286
  if (!owner) throw new Error(`No owner mount target found for parameter group '${group.name}'`);
24105
- const variants = group.variants.map((v) => scopedGroupVariantClassName(owner, group.name, v.name));
24287
+ const resolvedOwner = resolveServiceTarget(owner, exportedClasses);
24288
+ const variants = group.variants.map((v) => scopedGroupVariantClassName(resolvedOwner, group.name, v.name));
24106
24289
  if (variants.length === 1) return variants[0];
24107
24290
  return `T.any(${variants.join(", ")})`;
24108
24291
  };
@@ -24176,7 +24359,7 @@ function generateRbiFiles(spec, ctx) {
24176
24359
  lines.push(" end");
24177
24360
  lines.push("end");
24178
24361
  files.push({
24179
- path: `rbi/workos/${fileName(mountTarget)}.rbi`,
24362
+ path: `rbi/workos/${fileName(resolvedTarget)}.rbi`,
24180
24363
  content: lines.join("\n"),
24181
24364
  integrateTarget: true,
24182
24365
  overwriteExisting: true
@@ -24189,8 +24372,8 @@ function generateRbiFiles(spec, ctx) {
24189
24372
  lines.push("module WorkOS");
24190
24373
  lines.push(" class Client < BaseClient");
24191
24374
  for (const [mountTarget] of groups) {
24192
- const cls = className(mountTarget);
24193
- const prop = mountTarget.replace(/-/g, "_").replace(/[A-Z]/g, (ch) => `_${ch.toLowerCase()}`).replace(/^_/, "");
24375
+ const cls = className(resolveServiceTarget(mountTarget, exportedClasses));
24376
+ const prop = servicePropertyName(mountTarget);
24194
24377
  lines.push(` sig { returns(WorkOS::${cls}) }`);
24195
24378
  lines.push(` def ${prop}; end`);
24196
24379
  lines.push("");
@@ -26631,4 +26814,4 @@ const workosEmittersPlugin = {
26631
26814
  //#endregion
26632
26815
  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 };
26633
26816
 
26634
- //# sourceMappingURL=plugin-Ca9LUkWW.mjs.map
26817
+ //# sourceMappingURL=plugin-B9F2jmwy.mjs.map