@workos/oagen-emitters 0.12.5 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.release-please-manifest.json +1 -1
- package/CHANGELOG.md +14 -0
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{plugin-Ca9LUkWW.mjs → plugin-BxVeu2v9.mjs} +2064 -1293
- package/dist/plugin-BxVeu2v9.mjs.map +1 -0
- package/dist/plugin.mjs +1 -1
- package/package.json +7 -7
- package/src/kotlin/client.ts +3 -2
- package/src/kotlin/naming.ts +34 -0
- package/src/kotlin/resources.ts +5 -3
- package/src/kotlin/tests.ts +12 -3
- package/src/node/client.ts +11 -2
- package/src/node/discriminated-models.ts +735 -0
- package/src/node/index.ts +56 -5
- package/src/node/manifest.ts +5 -3
- package/src/node/models.ts +15 -1
- package/src/node/naming.ts +24 -0
- package/src/node/node-overrides.ts +49 -6
- package/src/node/resources.ts +21 -9
- package/src/node/tests.ts +4 -1
- package/src/php/client.ts +3 -2
- package/src/php/index.ts +25 -2
- package/src/php/naming.ts +22 -0
- package/src/php/resources.ts +3 -2
- package/src/python/client.ts +16 -5
- package/src/python/naming.ts +25 -0
- package/src/python/resources.ts +4 -1
- package/src/ruby/client.ts +18 -5
- package/src/ruby/index.ts +27 -2
- package/src/ruby/manifest.ts +5 -0
- package/src/ruby/naming.ts +30 -0
- package/src/ruby/rbi.ts +15 -8
- package/src/ruby/resources.ts +10 -3
- package/src/ruby/tests.ts +22 -5
- package/src/rust/index.ts +26 -2
- package/src/shared/model-utils.ts +15 -5
- package/src/shared/service-name-collision.ts +56 -0
- package/dist/plugin-Ca9LUkWW.mjs.map +0 -1
|
@@ -291,806 +291,533 @@ function lowerFirstForDoc(s) {
|
|
|
291
291
|
return s.charAt(0).toLowerCase() + s.slice(1);
|
|
292
292
|
}
|
|
293
293
|
//#endregion
|
|
294
|
-
//#region
|
|
295
|
-
|
|
296
|
-
function
|
|
297
|
-
return
|
|
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
|
-
|
|
300
|
-
|
|
301
|
-
return toKebabCase(stripUrnPrefix(name));
|
|
299
|
+
function isObject(subject) {
|
|
300
|
+
return typeof subject === "object" && subject !== null;
|
|
302
301
|
}
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
302
|
+
function toArray(sequence) {
|
|
303
|
+
if (Array.isArray(sequence)) return sequence;
|
|
304
|
+
else if (isNothing(sequence)) return [];
|
|
305
|
+
return [sequence];
|
|
306
306
|
}
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
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
|
-
|
|
313
|
-
|
|
314
|
-
|
|
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
|
-
|
|
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
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
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
|
|
342
|
-
|
|
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
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
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
|
-
|
|
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
|
-
|
|
373
|
-
|
|
374
|
-
return toKebabCase(name);
|
|
374
|
+
function padStart(string, max) {
|
|
375
|
+
return common.repeat(" ", max - string.length) + string;
|
|
375
376
|
}
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
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
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
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
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
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
|
-
|
|
396
|
-
function
|
|
397
|
-
|
|
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
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
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
|
-
|
|
494
|
+
for (index = 0, length = arguments.length; index < length; index += 1) arguments[index].forEach(collectType);
|
|
495
|
+
return result;
|
|
417
496
|
}
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
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
|
-
|
|
443
|
-
|
|
444
|
-
|
|
531
|
+
}),
|
|
532
|
+
new type("tag:yaml.org,2002:seq", {
|
|
533
|
+
kind: "sequence",
|
|
534
|
+
construct: function(data) {
|
|
535
|
+
return data !== null ? data : [];
|
|
445
536
|
}
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
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
|
-
|
|
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
|
-
|
|
466
|
-
|
|
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
|
|
481
|
-
return
|
|
553
|
+
function isNull(object) {
|
|
554
|
+
return object === null;
|
|
482
555
|
}
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
function
|
|
496
|
-
|
|
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
|
|
499
|
-
return
|
|
585
|
+
function constructYamlBoolean(data) {
|
|
586
|
+
return data === "true" || data === "True" || data === "TRUE";
|
|
500
587
|
}
|
|
501
|
-
|
|
502
|
-
|
|
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
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
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
|
|
536
|
-
|
|
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
|
|
576
|
-
|
|
577
|
-
else if (isNothing(sequence)) return [];
|
|
578
|
-
return [sequence];
|
|
615
|
+
function isDecCode(c) {
|
|
616
|
+
return 48 <= c && c <= 57;
|
|
579
617
|
}
|
|
580
|
-
function
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
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
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
return
|
|
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
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
if (
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
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
|
|
616
|
-
|
|
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
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
function
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
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
|
-
|
|
643
|
-
|
|
644
|
-
|
|
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
|
|
648
|
-
|
|
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
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
if (
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
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 (
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
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
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
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
|
-
|
|
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
|
-
|
|
687
|
-
|
|
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
|
|
753
|
+
var float = new type("tag:yaml.org,2002:float", {
|
|
830
754
|
kind: "scalar",
|
|
831
|
-
resolve:
|
|
832
|
-
construct:
|
|
833
|
-
predicate:
|
|
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
|
-
|
|
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
|
-
|
|
856
|
-
|
|
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
|
|
859
|
-
|
|
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
|
|
862
|
-
return
|
|
802
|
+
function representYamlTimestamp(object) {
|
|
803
|
+
return object.toISOString();
|
|
863
804
|
}
|
|
864
|
-
var
|
|
805
|
+
var timestamp = new type("tag:yaml.org,2002:timestamp", {
|
|
865
806
|
kind: "scalar",
|
|
866
|
-
resolve:
|
|
867
|
-
construct:
|
|
868
|
-
|
|
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
|
|
883
|
-
return
|
|
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
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
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++) {
|
|
@@ -2426,552 +2153,895 @@ function writeFlowMapping(state, level, object) {
|
|
|
2426
2153
|
state.tag = _tag;
|
|
2427
2154
|
state.dump = "{" + _result + "}";
|
|
2428
2155
|
}
|
|
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;
|
|
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;
|
|
2451
2589
|
}
|
|
2452
|
-
|
|
2453
|
-
state.dump = _result || "{}";
|
|
2590
|
+
return mapping;
|
|
2454
2591
|
}
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
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
|
|
2469
2619
|
}
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
return false;
|
|
2620
|
+
};
|
|
2621
|
+
});
|
|
2622
|
+
return changed ? result : models;
|
|
2474
2623
|
}
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
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;
|
|
2487
2643
|
}
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
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
|
-
}
|
|
2644
|
+
const collector = createCollector();
|
|
2645
|
+
for (const m of models) {
|
|
2646
|
+
collector.usedNames.add(m.name);
|
|
2647
|
+
collector.usedNames.add(toSnakeCase(m.name));
|
|
2521
2648
|
}
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
objectKeyList = Object.keys(object);
|
|
2541
|
-
for (index = 0, length = objectKeyList.length; index < length; index += 1) inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes);
|
|
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
|
+
};
|
|
2542
2667
|
}
|
|
2543
2668
|
}
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
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
|
+
name: toUpperSnakeCase(String(v.value)),
|
|
2696
|
+
value: v.value,
|
|
2697
|
+
description: v.description
|
|
2698
|
+
}))
|
|
2699
|
+
}));
|
|
2700
|
+
const existingSnakeNames = new Set(enriched2.map((m) => toSnakeCase(m.name)));
|
|
2701
|
+
const filteredSynthetic = collector.models.filter((m) => !existingSnakeNames.has(toSnakeCase(m.name)));
|
|
2702
|
+
return [...enriched2, ...filteredSynthetic];
|
|
2554
2703
|
}
|
|
2555
|
-
var dumper = { dump: dump$1 };
|
|
2556
|
-
var load = loader.load;
|
|
2557
|
-
loader.loadAll;
|
|
2558
|
-
dumper.dump;
|
|
2559
2704
|
//#endregion
|
|
2560
|
-
//#region src/shared/
|
|
2705
|
+
//#region src/shared/service-name-collision.ts
|
|
2561
2706
|
/**
|
|
2562
|
-
*
|
|
2563
|
-
*
|
|
2707
|
+
* Suffix applied to an operation-client class name when it collides with an
|
|
2708
|
+
* exported model/enum class name in the same SDK namespace. Standardized
|
|
2709
|
+
* across emitters so colliding services look the same in every language —
|
|
2710
|
+
* e.g. `OrganizationMembershipService` regardless of language.
|
|
2564
2711
|
*
|
|
2565
|
-
*
|
|
2566
|
-
*
|
|
2712
|
+
* Languages whose operation clients already carry a unique suffix (Go's
|
|
2713
|
+
* `…Service`, Rust's `…Api`, .NET's `…Service`) skip this helper entirely.
|
|
2567
2714
|
*/
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2715
|
+
const SERVICE_COLLISION_SUFFIX = "Service";
|
|
2716
|
+
/**
|
|
2717
|
+
* Build the set of model + enum class names that the SDK exports under its
|
|
2718
|
+
* top-level namespace. Each emitter passes its own `classNameFn` so the
|
|
2719
|
+
* comparison happens on the language-specific class-name form (e.g. Ruby's
|
|
2720
|
+
* `RoleList`, Python's `RoleList`).
|
|
2721
|
+
*
|
|
2722
|
+
* List-wrapper and list-metadata models are excluded — they aren't exposed
|
|
2723
|
+
* as user-facing types.
|
|
2724
|
+
*/
|
|
2725
|
+
function buildExportedClassNameSet$5(ctx, classNameFn) {
|
|
2726
|
+
const out = /* @__PURE__ */ new Set();
|
|
2727
|
+
for (const model of ctx.spec.models) {
|
|
2728
|
+
if (isListWrapperModel(model) || isListMetadataModel(model)) continue;
|
|
2729
|
+
out.add(classNameFn(model.name));
|
|
2577
2730
|
}
|
|
2578
|
-
|
|
2731
|
+
for (const enumDef of ctx.spec.enums) out.add(classNameFn(enumDef.name));
|
|
2732
|
+
return out;
|
|
2579
2733
|
}
|
|
2580
2734
|
/**
|
|
2581
|
-
*
|
|
2582
|
-
*
|
|
2735
|
+
* Resolve the PascalCase mount-target identifier for an operation client,
|
|
2736
|
+
* appending `Service` when the un-suffixed class name would shadow an
|
|
2737
|
+
* exported model or enum.
|
|
2738
|
+
*
|
|
2739
|
+
* Operates on the PascalCase target (the mount-target string the IR carries),
|
|
2740
|
+
* so the returned value feeds cleanly into each language's `className` and
|
|
2741
|
+
* `fileName` helpers — e.g. `OrganizationMembership` → `OrganizationMembershipService`,
|
|
2742
|
+
* then `fileName` → `organization_membership_service` / `organization-membership-service`.
|
|
2743
|
+
*
|
|
2744
|
+
* The accessor on the client (`client.organization_membership`) is intentionally
|
|
2745
|
+
* NOT suffixed — callers should keep using the raw target for `servicePropertyName`
|
|
2746
|
+
* so the accessor reads naturally.
|
|
2583
2747
|
*/
|
|
2584
|
-
function
|
|
2585
|
-
|
|
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);
|
|
2748
|
+
function resolveServiceTarget$5(target, exportedClasses, classNameFn) {
|
|
2749
|
+
return exportedClasses.has(classNameFn(target)) ? `${target}${SERVICE_COLLISION_SUFFIX}` : target;
|
|
2591
2750
|
}
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
return
|
|
2751
|
+
//#endregion
|
|
2752
|
+
//#region src/node/naming.ts
|
|
2753
|
+
/** Strip spec-noise suffixes (e.g., "Dto") from an IR name. */
|
|
2754
|
+
function stripNoiseSuffixes(name) {
|
|
2755
|
+
return name.replace(/Dto$/i, "");
|
|
2597
2756
|
}
|
|
2598
|
-
/**
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
*/
|
|
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;
|
|
2757
|
+
/** PascalCase class/interface name. */
|
|
2758
|
+
function className$6(name) {
|
|
2759
|
+
return toPascalCase(stripUrnPrefix(name));
|
|
2610
2760
|
}
|
|
2611
|
-
/**
|
|
2612
|
-
|
|
2613
|
-
|
|
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
|
-
}
|
|
2761
|
+
/** kebab-case file name (without extension). */
|
|
2762
|
+
function fileName$3(name) {
|
|
2763
|
+
return toKebabCase(stripUrnPrefix(name));
|
|
2625
2764
|
}
|
|
2626
|
-
/**
|
|
2627
|
-
function
|
|
2628
|
-
|
|
2629
|
-
if (!spec) return null;
|
|
2630
|
-
return spec?.components?.schemas?.[name] ?? null;
|
|
2765
|
+
/** camelCase field name for domain interfaces. */
|
|
2766
|
+
function fieldName$6(name) {
|
|
2767
|
+
return toCamelCase(name);
|
|
2631
2768
|
}
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
enums: [],
|
|
2636
|
-
usedNames: /* @__PURE__ */ new Set()
|
|
2637
|
-
};
|
|
2769
|
+
/** snake_case field name for wire/response interfaces. */
|
|
2770
|
+
function wireFieldName(name) {
|
|
2771
|
+
return toSnakeCase(name);
|
|
2638
2772
|
}
|
|
2639
2773
|
/**
|
|
2640
|
-
*
|
|
2641
|
-
* `
|
|
2774
|
+
* Active set of `Serialized${Name}` interfaces in the live SDK, harvested
|
|
2775
|
+
* from `ctx.apiSurface` once per generation run. When non-empty, the
|
|
2776
|
+
* legacy wire-naming scheme wins so existing hand-written serializer files
|
|
2777
|
+
* continue to compile.
|
|
2778
|
+
*
|
|
2779
|
+
* Set by `index.ts` immediately after `getSurface(ctx)` runs.
|
|
2642
2780
|
*/
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
return name;
|
|
2781
|
+
let baselineSerializedNames = /* @__PURE__ */ new Set();
|
|
2782
|
+
function setBaselineSerializedNames(names) {
|
|
2783
|
+
baselineSerializedNames = names;
|
|
2647
2784
|
}
|
|
2648
2785
|
/**
|
|
2649
|
-
*
|
|
2786
|
+
* Set of every interface name present in the baseline live SDK, regardless
|
|
2787
|
+
* of naming convention. Used to detect single-form baselines (where one
|
|
2788
|
+
* `*Response`-suffixed interface stands for both the domain and wire shape)
|
|
2789
|
+
* so we don't synthesize a non-existent `*Wire` variant.
|
|
2790
|
+
*/
|
|
2791
|
+
let baselineInterfaceNames = /* @__PURE__ */ new Set();
|
|
2792
|
+
function setBaselineInterfaceNames(names) {
|
|
2793
|
+
baselineInterfaceNames = names;
|
|
2794
|
+
}
|
|
2795
|
+
/**
|
|
2796
|
+
* IR models that belong to newly-adopted services should not be renamed by
|
|
2797
|
+
* structural baseline matches from unrelated hand-written services.
|
|
2798
|
+
*/
|
|
2799
|
+
let adoptedModelNames = /* @__PURE__ */ new Set();
|
|
2800
|
+
function setAdoptedModelNames(names) {
|
|
2801
|
+
adoptedModelNames = names;
|
|
2802
|
+
}
|
|
2803
|
+
function isAdoptedModelName(name) {
|
|
2804
|
+
return adoptedModelNames.has(name);
|
|
2805
|
+
}
|
|
2806
|
+
/**
|
|
2807
|
+
* Wire/response interface name.
|
|
2650
2808
|
*
|
|
2651
|
-
*
|
|
2652
|
-
*
|
|
2653
|
-
*
|
|
2809
|
+
* Resolution order:
|
|
2810
|
+
* 1. `Serialized${domainName}` if it exists in the baseline (legacy
|
|
2811
|
+
* workos-node convention; lets hand-written serializer files keep
|
|
2812
|
+
* compiling).
|
|
2813
|
+
* 2. `${domainName}Wire` when the domain ends in `Response` AND the
|
|
2814
|
+
* baseline actually has a `*Wire` interface (avoids
|
|
2815
|
+
* `FooResponseResponse` stutter).
|
|
2816
|
+
* 3. The bare `domainName` itself when it already ends in `Response` and
|
|
2817
|
+
* no `*Wire` variant exists — this happens when the structural matcher
|
|
2818
|
+
* maps an IR model to a baseline-wire-shaped interface
|
|
2819
|
+
* (`AuditLogSchemaJson` → `AuditLogSchemaResponse`) and the baseline
|
|
2820
|
+
* has no separate domain/wire split.
|
|
2821
|
+
* 4. `${domainName}Response` for the standard fresh-emit case.
|
|
2654
2822
|
*/
|
|
2655
|
-
function
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
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";
|
|
2823
|
+
function wireInterfaceName(domainName) {
|
|
2824
|
+
const serialized = `Serialized${domainName}`;
|
|
2825
|
+
if (baselineSerializedNames.has(serialized)) return serialized;
|
|
2826
|
+
if (domainName.endsWith("Response")) {
|
|
2827
|
+
const wireForm = `${domainName}Wire`;
|
|
2828
|
+
if (baselineInterfaceNames.has(wireForm)) return wireForm;
|
|
2829
|
+
if (baselineInterfaceNames.has(domainName)) return domainName;
|
|
2830
|
+
return wireForm;
|
|
2692
2831
|
}
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
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;
|
|
2832
|
+
return `${domainName}Response`;
|
|
2833
|
+
}
|
|
2834
|
+
/** kebab-case service directory name. */
|
|
2835
|
+
function serviceDirName(name) {
|
|
2836
|
+
return toKebabCase(name);
|
|
2837
|
+
}
|
|
2838
|
+
/** camelCase property name for service accessors on the client. */
|
|
2839
|
+
function servicePropertyName$4(name) {
|
|
2840
|
+
return toCamelCase(name);
|
|
2744
2841
|
}
|
|
2745
2842
|
/**
|
|
2746
|
-
*
|
|
2747
|
-
*
|
|
2748
|
-
* oneOf variants where only one variant is active at a time.
|
|
2843
|
+
* Resolve the effective service name, using the overlay-resolved class name
|
|
2844
|
+
* when available.
|
|
2749
2845
|
*/
|
|
2750
|
-
function
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
return fields;
|
|
2846
|
+
function resolveServiceName(service, ctx) {
|
|
2847
|
+
return resolveClassName$5(service, ctx);
|
|
2848
|
+
}
|
|
2849
|
+
/**
|
|
2850
|
+
* Build the set of model + enum class names exported by the SDK. Used to
|
|
2851
|
+
* detect collisions with operation-client class names — a colliding service
|
|
2852
|
+
* gets a `Service` suffix appended.
|
|
2853
|
+
*/
|
|
2854
|
+
function buildExportedClassNameSet$4(ctx) {
|
|
2855
|
+
return buildExportedClassNameSet$5(ctx, className$6);
|
|
2761
2856
|
}
|
|
2762
2857
|
/**
|
|
2763
|
-
*
|
|
2764
|
-
*
|
|
2858
|
+
* Resolve a service's mount-target identifier, appending `Service` on
|
|
2859
|
+
* collision with an exported model/enum class. The result feeds `className`
|
|
2860
|
+
* and `fileName` so both the `export class` declaration and its file name
|
|
2861
|
+
* stay aligned (e.g. `OrganizationMembershipService` /
|
|
2862
|
+
* `organization-membership-service.ts`).
|
|
2765
2863
|
*/
|
|
2766
|
-
function
|
|
2767
|
-
|
|
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;
|
|
2864
|
+
function resolveServiceTarget$4(target, exportedClasses) {
|
|
2865
|
+
return resolveServiceTarget$5(target, exportedClasses, className$6);
|
|
2782
2866
|
}
|
|
2783
2867
|
/**
|
|
2784
|
-
*
|
|
2868
|
+
* Build a map from IR service name -> resolved service name.
|
|
2785
2869
|
*/
|
|
2786
|
-
function
|
|
2787
|
-
|
|
2870
|
+
function buildServiceNameMap(services, ctx) {
|
|
2871
|
+
const map = /* @__PURE__ */ new Map();
|
|
2872
|
+
for (const service of services) map.set(service.name, resolveServiceName(service, ctx));
|
|
2873
|
+
return map;
|
|
2874
|
+
}
|
|
2875
|
+
/** Resolve the output directory for a service. */
|
|
2876
|
+
function resolveServiceDir$1(resolvedServiceName) {
|
|
2877
|
+
return serviceDirName(resolvedServiceName);
|
|
2878
|
+
}
|
|
2879
|
+
/** Resolve the SDK method name for an operation, using resolved operations first. */
|
|
2880
|
+
function resolveMethodName$6(op, _service, ctx) {
|
|
2881
|
+
const resolved = lookupMethodName(op, buildResolvedLookup(ctx));
|
|
2882
|
+
if (resolved) return toCamelCase(resolved);
|
|
2883
|
+
const httpKey = `${op.httpMethod.toUpperCase()} ${op.path}`;
|
|
2884
|
+
const existing = ctx.overlayLookup?.methodByOperation?.get(httpKey);
|
|
2885
|
+
if (existing) return existing.methodName;
|
|
2886
|
+
return toCamelCase(op.name);
|
|
2887
|
+
}
|
|
2888
|
+
/** Resolve the SDK class name for a service, using resolved ops mountOn as canonical. */
|
|
2889
|
+
function resolveClassName$5(service, ctx) {
|
|
2890
|
+
for (const r of ctx.resolvedOperations ?? []) if (r.service.name === service.name) return r.mountOn;
|
|
2891
|
+
if (ctx.overlayLookup?.methodByOperation) for (const op of service.operations) {
|
|
2892
|
+
const httpKey = `${op.httpMethod.toUpperCase()} ${op.path}`;
|
|
2893
|
+
const existing = ctx.overlayLookup.methodByOperation.get(httpKey);
|
|
2894
|
+
if (existing) return existing.className;
|
|
2895
|
+
}
|
|
2896
|
+
return toPascalCase(service.name);
|
|
2788
2897
|
}
|
|
2789
2898
|
/**
|
|
2790
|
-
*
|
|
2791
|
-
*
|
|
2792
|
-
*
|
|
2793
|
-
*
|
|
2899
|
+
* Resolve the interface name for a model, checking overlay first.
|
|
2900
|
+
*
|
|
2901
|
+
* Lookup order:
|
|
2902
|
+
* 1. `overlayLookup.interfaceByName` — exact-name overrides from the live SDK.
|
|
2903
|
+
* 2. `overlayLookup.modelNameByIR` — structurally-inferred matches (e.g., IR
|
|
2904
|
+
* `ValidateApiKey` with one field `value: string` → live SDK interface
|
|
2905
|
+
* `ValidateApiKeyOptions`).
|
|
2906
|
+
* 3. Type-alias resolution (when an alias points to an interface).
|
|
2907
|
+
* 4. Suffix-fallback heuristic for the workos-node `*Options` convention:
|
|
2908
|
+
* when the IR name `X` has no baseline match but `XOptions` does, use
|
|
2909
|
+
* `XOptions`. The convention is widely used for request-body interfaces
|
|
2910
|
+
* in workos-node (CreateOrganizationOptions, ListUsersOptions, etc.).
|
|
2911
|
+
* 5. Default — clean and PascalCase the IR name.
|
|
2794
2912
|
*/
|
|
2795
|
-
function
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2913
|
+
function resolveInterfaceName(name, ctx, opts) {
|
|
2914
|
+
const existing = ctx.overlayLookup?.interfaceByName?.get(name);
|
|
2915
|
+
if (existing) return existing;
|
|
2916
|
+
let inferred = adoptedModelNames.has(name) ? void 0 : ctx.overlayLookup?.modelNameByIR?.get(name);
|
|
2917
|
+
if (inferred) {
|
|
2918
|
+
if (inferred.startsWith("Serialized")) {
|
|
2919
|
+
const stripped = inferred.slice(10);
|
|
2920
|
+
if (stripped && ctx.apiSurface?.interfaces?.[stripped]) inferred = stripped;
|
|
2921
|
+
}
|
|
2922
|
+
if (inferred.endsWith("Response") && ctx.apiSurface?.interfaces) {
|
|
2923
|
+
const stripped = inferred.slice(0, -8);
|
|
2924
|
+
if (stripped && ctx.apiSurface.interfaces[stripped]) inferred = stripped;
|
|
2925
|
+
}
|
|
2926
|
+
return inferred;
|
|
2802
2927
|
}
|
|
2803
|
-
if (!
|
|
2804
|
-
|
|
2805
|
-
|
|
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;
|
|
2928
|
+
if (!opts?.skipTypeAlias && ctx.apiSurface?.typeAliases) {
|
|
2929
|
+
const alias = ctx.apiSurface.typeAliases[name];
|
|
2930
|
+
if (alias?.value && ctx.apiSurface.interfaces?.[alias.value]) return alias.value;
|
|
2810
2931
|
}
|
|
2811
|
-
if (
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
} : newArrayRef;
|
|
2824
|
-
return {
|
|
2825
|
-
...field,
|
|
2826
|
-
type: newType
|
|
2827
|
-
};
|
|
2932
|
+
if (ctx.apiSurface?.interfaces) {
|
|
2933
|
+
const ifaces = ctx.apiSurface.interfaces;
|
|
2934
|
+
if (!ifaces[name]) {
|
|
2935
|
+
const optionsCandidate = `${name}Options`;
|
|
2936
|
+
const optionsInfo = ifaces[optionsCandidate];
|
|
2937
|
+
if (optionsInfo?.sourceFile) {
|
|
2938
|
+
const expectedStem = toKebabCase(stripUrnPrefix(name));
|
|
2939
|
+
if (optionsInfo.sourceFile.endsWith(`/${expectedStem}.interface.ts`)) return optionsCandidate;
|
|
2940
|
+
}
|
|
2941
|
+
}
|
|
2942
|
+
}
|
|
2943
|
+
return toPascalCase(stripUrnPrefix(ctx.apiSurface ? name : stripNoiseSuffixes(name)));
|
|
2828
2944
|
}
|
|
2829
|
-
|
|
2945
|
+
//#endregion
|
|
2946
|
+
//#region src/node/type-map.ts
|
|
2830
2947
|
/**
|
|
2831
|
-
*
|
|
2832
|
-
*
|
|
2833
|
-
*
|
|
2948
|
+
* Map of enum name → inlined string-union TS source.
|
|
2949
|
+
*
|
|
2950
|
+
* Set by `index.ts` once per generation run, sourced from `spec.enums` for
|
|
2951
|
+
* enums that have no baseline definition in the live SDK. When populated,
|
|
2952
|
+
* `mapTypeRef`/`mapWireTypeRef` substitute the union directly at the
|
|
2953
|
+
* reference site instead of emitting a separate import — this collapses
|
|
2954
|
+
* ~100 single-line enum files into inline literal types.
|
|
2834
2955
|
*/
|
|
2835
|
-
|
|
2836
|
-
|
|
2956
|
+
let inlineEnumUnions = /* @__PURE__ */ new Map();
|
|
2957
|
+
function setInlineEnumUnions(map) {
|
|
2958
|
+
inlineEnumUnions = map;
|
|
2837
2959
|
}
|
|
2838
|
-
|
|
2839
|
-
|
|
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;
|
|
2960
|
+
function isInlineEnum(name) {
|
|
2961
|
+
return inlineEnumUnions.has(name);
|
|
2849
2962
|
}
|
|
2850
2963
|
/**
|
|
2851
|
-
*
|
|
2852
|
-
*
|
|
2853
|
-
*
|
|
2964
|
+
* Optional callback that resolves an IR model name to its live-SDK interface
|
|
2965
|
+
* name. Set by `index.ts` once per run. When present, `mapTypeRef` and
|
|
2966
|
+
* `mapWireTypeRef` use it instead of the raw IR name in their `model:` cases
|
|
2967
|
+
* — keeping field-type references in sync with import statements that the
|
|
2968
|
+
* caller emits via the same resolver. Without this, a structural match like
|
|
2969
|
+
* IR `AuditLogSchemaJson` → live `AuditLogSchemaResponse` would produce
|
|
2970
|
+
* `schema: AuditLogSchemaJson` in the body but
|
|
2971
|
+
* `import type { AuditLogSchemaResponse }` in the imports, leaving
|
|
2972
|
+
* `AuditLogSchemaJson` unbound.
|
|
2854
2973
|
*/
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
if (variantModel) mapping[String(constValue)] = variantModel.name;
|
|
2862
|
-
}
|
|
2863
|
-
return mapping;
|
|
2974
|
+
let domainNameResolver = null;
|
|
2975
|
+
function setDomainNameResolver(fn) {
|
|
2976
|
+
domainNameResolver = fn;
|
|
2977
|
+
}
|
|
2978
|
+
function resolveDomainName(irName) {
|
|
2979
|
+
return domainNameResolver ? domainNameResolver(irName) : irName;
|
|
2864
2980
|
}
|
|
2865
2981
|
/**
|
|
2866
|
-
*
|
|
2867
|
-
*
|
|
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).
|
|
2982
|
+
* Map an IR TypeRef to a TypeScript domain type string.
|
|
2983
|
+
* Domain types use PascalCase model names (e.g., `Organization`).
|
|
2871
2984
|
*/
|
|
2872
|
-
function
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
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
|
-
};
|
|
2985
|
+
function mapTypeRef$7(ref, opts) {
|
|
2986
|
+
const genericDefaults = opts?.genericDefaults;
|
|
2987
|
+
return mapTypeRef(ref, {
|
|
2988
|
+
primitive: mapPrimitive$6,
|
|
2989
|
+
array: (_r, items) => `${parenthesizeUnion$1(items)}[]`,
|
|
2990
|
+
model: (r) => resolveDomainName(r.name) + (genericDefaults?.get(r.name) ?? ""),
|
|
2991
|
+
enum: (r) => inlineEnumUnions.get(r.name) ?? r.name,
|
|
2992
|
+
union: (r, variants) => joinUnionVariants$5(r, variants),
|
|
2993
|
+
nullable: (_r, inner) => `${inner} | null`,
|
|
2994
|
+
literal: (r) => typeof r.value === "string" ? `'${r.value}'` : String(r.value),
|
|
2995
|
+
map: (_r, value) => `Record<string, ${value}>`
|
|
2894
2996
|
});
|
|
2895
|
-
return changed ? result : models;
|
|
2896
2997
|
}
|
|
2897
2998
|
/**
|
|
2898
|
-
*
|
|
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()`.
|
|
2999
|
+
* Map an IR TypeRef to a TypeScript wire/response type string.
|
|
3000
|
+
* Model references get the `Response` suffix (e.g., `OrganizationResponse`).
|
|
2911
3001
|
*/
|
|
2912
|
-
function
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
3002
|
+
function mapWireTypeRef(ref, opts) {
|
|
3003
|
+
const genericDefaults = opts?.genericDefaults;
|
|
3004
|
+
return mapTypeRef(ref, {
|
|
3005
|
+
primitive: mapWirePrimitive,
|
|
3006
|
+
array: (_r, items) => `${parenthesizeUnion$1(items)}[]`,
|
|
3007
|
+
model: (r) => wireInterfaceName(resolveDomainName(r.name)) + (genericDefaults?.get(r.name) ?? ""),
|
|
3008
|
+
enum: (r) => inlineEnumUnions.get(r.name) ?? r.name,
|
|
3009
|
+
union: (r, variants) => joinUnionVariants$5(r, variants),
|
|
3010
|
+
nullable: (_r, inner) => `${inner} | null`,
|
|
3011
|
+
literal: (r) => typeof r.value === "string" ? `'${r.value}'` : String(r.value),
|
|
3012
|
+
map: (_r, value) => `Record<string, ${value}>`
|
|
3013
|
+
});
|
|
3014
|
+
}
|
|
3015
|
+
function mapPrimitive$6(ref) {
|
|
3016
|
+
if (ref.format) switch (ref.format) {
|
|
3017
|
+
case "date-time": return "Date";
|
|
3018
|
+
case "int64": return "bigint";
|
|
2916
3019
|
}
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
3020
|
+
switch (ref.type) {
|
|
3021
|
+
case "string": return "string";
|
|
3022
|
+
case "integer":
|
|
3023
|
+
case "number": return "number";
|
|
3024
|
+
case "boolean": return "boolean";
|
|
3025
|
+
case "unknown": return "any";
|
|
2921
3026
|
}
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
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];
|
|
3027
|
+
}
|
|
3028
|
+
function mapWirePrimitive(ref) {
|
|
3029
|
+
switch (ref.type) {
|
|
3030
|
+
case "string": return "string";
|
|
3031
|
+
case "integer":
|
|
3032
|
+
case "number": return "number";
|
|
3033
|
+
case "boolean": return "boolean";
|
|
3034
|
+
case "unknown": return "any";
|
|
3035
|
+
}
|
|
3036
|
+
}
|
|
3037
|
+
function joinUnionVariants$5(ref, variants) {
|
|
3038
|
+
const unique = [...new Set(variants)];
|
|
3039
|
+
if (ref.compositionKind === "allOf") return unique.join(" & ");
|
|
3040
|
+
if (unique.length === 1) return unique[0];
|
|
3041
|
+
return unique.join(" | ");
|
|
3042
|
+
}
|
|
3043
|
+
function parenthesizeUnion$1(type) {
|
|
3044
|
+
return type.includes(" | ") || type.includes(" & ") ? `(${type})` : type;
|
|
2975
3045
|
}
|
|
2976
3046
|
//#endregion
|
|
2977
3047
|
//#region src/node/utils.ts
|
|
@@ -4463,15 +4533,19 @@ function hasCompatibleConstructor(className, ctx) {
|
|
|
4463
4533
|
*/
|
|
4464
4534
|
function resolveResourceClassName$3(service, ctx) {
|
|
4465
4535
|
const overlayName = resolveServiceName(service, ctx);
|
|
4466
|
-
|
|
4467
|
-
|
|
4468
|
-
|
|
4469
|
-
|
|
4536
|
+
let base;
|
|
4537
|
+
if (hasCompatibleConstructor(overlayName, ctx)) base = overlayName;
|
|
4538
|
+
else {
|
|
4539
|
+
const irName = toPascalCase(service.name);
|
|
4540
|
+
base = irName === overlayName ? `${irName}Endpoints` : irName;
|
|
4541
|
+
}
|
|
4542
|
+
return resolveServiceTarget$4(base, buildExportedClassNameSet$4(ctx));
|
|
4470
4543
|
}
|
|
4471
4544
|
function resolveResourceDir(service, ctx) {
|
|
4472
4545
|
const resolvedName = resolveResourceClassName$3(service, ctx);
|
|
4473
4546
|
if (resolvedName === "WebhooksEndpoints") return "webhooks";
|
|
4474
|
-
|
|
4547
|
+
const overlayName = resolveServiceName(service, ctx);
|
|
4548
|
+
return resolveServiceDir$1(resolvedName === `${overlayName}Service` ? overlayName : resolvedName);
|
|
4475
4549
|
}
|
|
4476
4550
|
/** Standard pagination query params handled by PaginationOptions — not imported individually. */
|
|
4477
4551
|
const PAGINATION_PARAM_NAMES = new Set([
|
|
@@ -4554,7 +4628,7 @@ function splitCamelWords(name) {
|
|
|
4554
4628
|
return parts;
|
|
4555
4629
|
}
|
|
4556
4630
|
/** Naive singularize: strip trailing 's' unless it ends in 'ss'. */
|
|
4557
|
-
function singularize$
|
|
4631
|
+
function singularize$4(word) {
|
|
4558
4632
|
return word.endsWith("s") && !word.endsWith("ss") ? word.slice(0, -1) : word;
|
|
4559
4633
|
}
|
|
4560
4634
|
/**
|
|
@@ -4571,11 +4645,11 @@ function deduplicateMethodNames(plans, _ctx) {
|
|
|
4571
4645
|
if (count <= 1) continue;
|
|
4572
4646
|
const dupes = plans.filter((p) => p.method === name);
|
|
4573
4647
|
if (new Set(dupes.map((d) => d.op.path.replace(/\/\{[^}]+\}$/, ""))).size <= 1) continue;
|
|
4574
|
-
const nameWords = new Set(splitCamelWords(name).map(singularize$
|
|
4648
|
+
const nameWords = new Set(splitCamelWords(name).map(singularize$4));
|
|
4575
4649
|
const scored = dupes.map((d) => {
|
|
4576
4650
|
return {
|
|
4577
4651
|
plan: d,
|
|
4578
|
-
score: d.op.path.split("/").filter((s) => s && !s.startsWith("{")).flatMap((s) => s.split("_")).map(singularize$
|
|
4652
|
+
score: d.op.path.split("/").filter((s) => s && !s.startsWith("{")).flatMap((s) => s.split("_")).map(singularize$4).filter((w) => nameWords.has(w)).length
|
|
4579
4653
|
};
|
|
4580
4654
|
});
|
|
4581
4655
|
scored.sort((a, b) => b.score - a.score);
|
|
@@ -5869,6 +5943,7 @@ function isSupportedFieldType(ref, ownerModelName, shared, ctx) {
|
|
|
5869
5943
|
const resolvedName = resolveInterfaceName(ref.name, ctx);
|
|
5870
5944
|
if (ctx.apiSurface?.interfaces?.[resolvedName] || ctx.apiSurface?.typeAliases?.[resolvedName]) return true;
|
|
5871
5945
|
if (isAdoptedModelName(ref.name)) return true;
|
|
5946
|
+
if (shared.modelToService.has(ref.name)) return true;
|
|
5872
5947
|
return liveSurfaceHasManagedFile(`src/${shared.resolveDir(shared.modelToService.get(ref.name))}/interfaces/${fileName$3(ref.name)}.interface.ts`);
|
|
5873
5948
|
}
|
|
5874
5949
|
case "enum": {
|
|
@@ -5915,12 +5990,14 @@ function generateModels$7(models, ctx, shared) {
|
|
|
5915
5990
|
if ((ctx.apiSurface?.interfaces?.[depName])?.sourceFile === parentPath) forceGenerate.add(dep);
|
|
5916
5991
|
}
|
|
5917
5992
|
}
|
|
5993
|
+
const discriminatedSkip = ctx._discriminatedModelNames;
|
|
5918
5994
|
for (const originalModel of models) {
|
|
5919
5995
|
const model = projectedByName.get(originalModel.name) ?? originalModel;
|
|
5920
5996
|
if (!reachableModels.has(model.name)) continue;
|
|
5921
5997
|
if (interfaceEligibleModels && !interfaceEligibleModels.has(model.name)) continue;
|
|
5922
5998
|
if (isListMetadataModel(model)) continue;
|
|
5923
5999
|
if (isListWrapperModel(model)) continue;
|
|
6000
|
+
if (discriminatedSkip?.has(model.name)) continue;
|
|
5924
6001
|
const service = modelToService.get(model.name);
|
|
5925
6002
|
const isOwnedModel = isNodeOwnedService(ctx, service);
|
|
5926
6003
|
if (!isOwnedModel && !modelHasNewFields(model, ctx) && !forceGenerate.has(model.name)) continue;
|
|
@@ -6252,6 +6329,7 @@ function generateSerializers(models, ctx, shared) {
|
|
|
6252
6329
|
if ((ctx.apiSurface?.interfaces?.[depName])?.sourceFile === parentPath) forceGenerateSerializer.add(dep);
|
|
6253
6330
|
}
|
|
6254
6331
|
}
|
|
6332
|
+
const discriminatedSerializerSkip = ctx._discriminatedModelNames;
|
|
6255
6333
|
const eligibleModels = [];
|
|
6256
6334
|
for (const originalModel of models) {
|
|
6257
6335
|
const model = projectedByName.get(originalModel.name) ?? originalModel;
|
|
@@ -6259,6 +6337,7 @@ function generateSerializers(models, ctx, shared) {
|
|
|
6259
6337
|
if (serializerEligibleModels && !serializerEligibleModels.has(model.name)) continue;
|
|
6260
6338
|
if (isListMetadataModel(model)) continue;
|
|
6261
6339
|
if (isListWrapperModel(model)) continue;
|
|
6340
|
+
if (discriminatedSerializerSkip?.has(model.name)) continue;
|
|
6262
6341
|
if (!isNodeOwnedService(ctx, modelToService.get(model.name)) && !modelHasNewFields(model, ctx) && !forceGenerateSerializer.has(model.name)) continue;
|
|
6263
6342
|
eligibleModels.push(model);
|
|
6264
6343
|
}
|
|
@@ -6562,7 +6641,7 @@ function generateWorkOSClient$1(spec, ctx) {
|
|
|
6562
6641
|
for (const service of spec.services) {
|
|
6563
6642
|
if (coveredServices.has(service.name)) continue;
|
|
6564
6643
|
const resolvedName = resolveResourceClassName$3(service, ctx);
|
|
6565
|
-
const propName = servicePropertyName$4(
|
|
6644
|
+
const propName = servicePropertyName$4(resolveServiceName(service, ctx));
|
|
6566
6645
|
if (existingProps.has(propName)) continue;
|
|
6567
6646
|
const classDeprecation = ctx.apiSurface?.classes?.[resolvedName]?.deprecationMessage;
|
|
6568
6647
|
if (classDeprecation !== void 0) {
|
|
@@ -6988,7 +7067,7 @@ function generateServiceTest$3(service, spec, ctx, modelMap, mountAccessors) {
|
|
|
6988
7067
|
const resolvedName = resolveResourceClassName$3(service, ctx);
|
|
6989
7068
|
const serviceDir = resolveResourceDir(service, ctx);
|
|
6990
7069
|
const serviceClass = resolvedName;
|
|
6991
|
-
const serviceProp = mountAccessors?.get(service.name) ?? servicePropertyName$4(
|
|
7070
|
+
const serviceProp = mountAccessors?.get(service.name) ?? servicePropertyName$4(resolveServiceName(service, ctx));
|
|
6992
7071
|
const testPath = `src/${serviceDir}/${fileName$3(resolvedName)}.spec.ts`;
|
|
6993
7072
|
const plans = service.operations.map((op) => ({
|
|
6994
7073
|
op,
|
|
@@ -7570,6 +7649,445 @@ function generateSerializerTests(spec, ctx) {
|
|
|
7570
7649
|
return files;
|
|
7571
7650
|
}
|
|
7572
7651
|
//#endregion
|
|
7652
|
+
//#region src/node/discriminated-models.ts
|
|
7653
|
+
function detectDiscriminatedShape(modelName, rawSchemas) {
|
|
7654
|
+
const schema = rawSchemas[modelName];
|
|
7655
|
+
if (!schema?.allOf) return null;
|
|
7656
|
+
let baseObject = null;
|
|
7657
|
+
let oneOfVariants = null;
|
|
7658
|
+
for (const member of schema.allOf) {
|
|
7659
|
+
const resolved = resolveRef(member, rawSchemas);
|
|
7660
|
+
if (resolved.oneOf) {
|
|
7661
|
+
if (oneOfVariants) return null;
|
|
7662
|
+
oneOfVariants = resolved.oneOf;
|
|
7663
|
+
} else if (resolved.properties) baseObject = mergeBase(baseObject, resolved);
|
|
7664
|
+
else if (resolved.allOf) {
|
|
7665
|
+
const nestedBase = flattenObjectAllOf(resolved, rawSchemas);
|
|
7666
|
+
baseObject = mergeBase(baseObject, nestedBase);
|
|
7667
|
+
}
|
|
7668
|
+
}
|
|
7669
|
+
if (!oneOfVariants || oneOfVariants.length < 2) return null;
|
|
7670
|
+
const flattenedVariants = oneOfVariants.map((v) => flattenVariant(v, rawSchemas));
|
|
7671
|
+
const discProp = findSharedDiscriminator(flattenedVariants);
|
|
7672
|
+
if (!discProp) return null;
|
|
7673
|
+
const variants = flattenedVariants.map((fv) => {
|
|
7674
|
+
const discValue = readConstString(fv.alwaysProperties.get(discProp));
|
|
7675
|
+
if (!discValue) return null;
|
|
7676
|
+
return {
|
|
7677
|
+
nameSuffix: variantNameSuffix(discValue),
|
|
7678
|
+
discriminatorValue: discValue,
|
|
7679
|
+
fields: variantFields(fv, discProp, modelName, rawSchemas)
|
|
7680
|
+
};
|
|
7681
|
+
}).filter((v) => v !== null);
|
|
7682
|
+
if (variants.length !== flattenedVariants.length) return null;
|
|
7683
|
+
return {
|
|
7684
|
+
modelName,
|
|
7685
|
+
baseFields: baseObject ? collectObjectFields(baseObject, modelName, rawSchemas) : [],
|
|
7686
|
+
discriminatorProperty: discProp,
|
|
7687
|
+
discriminatorPropertyDomain: toCamelCase(discProp),
|
|
7688
|
+
variants
|
|
7689
|
+
};
|
|
7690
|
+
}
|
|
7691
|
+
function mergeBase(prev, next) {
|
|
7692
|
+
if (!prev) return next;
|
|
7693
|
+
return {
|
|
7694
|
+
type: "object",
|
|
7695
|
+
properties: {
|
|
7696
|
+
...prev.properties ?? {},
|
|
7697
|
+
...next.properties ?? {}
|
|
7698
|
+
},
|
|
7699
|
+
required: [...new Set([...prev.required ?? [], ...next.required ?? []])]
|
|
7700
|
+
};
|
|
7701
|
+
}
|
|
7702
|
+
function flattenObjectAllOf(schema, rawSchemas) {
|
|
7703
|
+
let merged = {
|
|
7704
|
+
type: "object",
|
|
7705
|
+
properties: {},
|
|
7706
|
+
required: []
|
|
7707
|
+
};
|
|
7708
|
+
for (const sub of schema.allOf ?? []) {
|
|
7709
|
+
const resolved = resolveRef(sub, rawSchemas);
|
|
7710
|
+
if (resolved.properties) merged = mergeBase(merged, resolved);
|
|
7711
|
+
else if (resolved.allOf) merged = mergeBase(merged, flattenObjectAllOf(resolved, rawSchemas));
|
|
7712
|
+
}
|
|
7713
|
+
return merged;
|
|
7714
|
+
}
|
|
7715
|
+
function flattenVariant(variant, rawSchemas) {
|
|
7716
|
+
const resolved = resolveRef(variant, rawSchemas);
|
|
7717
|
+
if (resolved.properties && !resolved.allOf && !resolved.oneOf) {
|
|
7718
|
+
const props = /* @__PURE__ */ new Map();
|
|
7719
|
+
for (const [k, v] of Object.entries(resolved.properties)) props.set(k, v);
|
|
7720
|
+
return {
|
|
7721
|
+
alwaysProperties: props,
|
|
7722
|
+
optionalProperties: /* @__PURE__ */ new Map(),
|
|
7723
|
+
required: new Set(resolved.required ?? [])
|
|
7724
|
+
};
|
|
7725
|
+
}
|
|
7726
|
+
if (resolved.allOf) {
|
|
7727
|
+
let agg = {
|
|
7728
|
+
alwaysProperties: /* @__PURE__ */ new Map(),
|
|
7729
|
+
optionalProperties: /* @__PURE__ */ new Map(),
|
|
7730
|
+
required: /* @__PURE__ */ new Set()
|
|
7731
|
+
};
|
|
7732
|
+
let initialized = false;
|
|
7733
|
+
for (const member of resolved.allOf) {
|
|
7734
|
+
const memberView = flattenVariant(member, rawSchemas);
|
|
7735
|
+
if (!initialized) {
|
|
7736
|
+
agg = {
|
|
7737
|
+
alwaysProperties: new Map(memberView.alwaysProperties),
|
|
7738
|
+
optionalProperties: new Map(memberView.optionalProperties),
|
|
7739
|
+
required: new Set(memberView.required)
|
|
7740
|
+
};
|
|
7741
|
+
initialized = true;
|
|
7742
|
+
continue;
|
|
7743
|
+
}
|
|
7744
|
+
for (const [k, v] of memberView.alwaysProperties) if (!agg.alwaysProperties.has(k) && !agg.optionalProperties.has(k)) agg.alwaysProperties.set(k, v);
|
|
7745
|
+
for (const [k, v] of memberView.optionalProperties) if (!agg.alwaysProperties.has(k) && !agg.optionalProperties.has(k)) agg.optionalProperties.set(k, v);
|
|
7746
|
+
for (const r of memberView.required) agg.required.add(r);
|
|
7747
|
+
}
|
|
7748
|
+
return agg;
|
|
7749
|
+
}
|
|
7750
|
+
if (resolved.oneOf) {
|
|
7751
|
+
const memberViews = resolved.oneOf.map((m) => flattenVariant(m, rawSchemas));
|
|
7752
|
+
const allKeys = /* @__PURE__ */ new Set();
|
|
7753
|
+
for (const view of memberViews) {
|
|
7754
|
+
for (const k of view.alwaysProperties.keys()) allKeys.add(k);
|
|
7755
|
+
for (const k of view.optionalProperties.keys()) allKeys.add(k);
|
|
7756
|
+
}
|
|
7757
|
+
const always = /* @__PURE__ */ new Map();
|
|
7758
|
+
const optional = /* @__PURE__ */ new Map();
|
|
7759
|
+
const requiredEverywhere = /* @__PURE__ */ new Set();
|
|
7760
|
+
for (const key of allKeys) {
|
|
7761
|
+
const inAll = memberViews.every((v) => v.alwaysProperties.has(key) || v.optionalProperties.has(key));
|
|
7762
|
+
const merged = mergeFieldSchemas(memberViews.map((v) => v.alwaysProperties.get(key) ?? v.optionalProperties.get(key)).filter((s) => Boolean(s)));
|
|
7763
|
+
if (inAll) always.set(key, merged);
|
|
7764
|
+
else optional.set(key, merged);
|
|
7765
|
+
if (inAll && memberViews.every((v) => v.required.has(key))) requiredEverywhere.add(key);
|
|
7766
|
+
}
|
|
7767
|
+
return {
|
|
7768
|
+
alwaysProperties: always,
|
|
7769
|
+
optionalProperties: optional,
|
|
7770
|
+
required: requiredEverywhere
|
|
7771
|
+
};
|
|
7772
|
+
}
|
|
7773
|
+
return {
|
|
7774
|
+
alwaysProperties: /* @__PURE__ */ new Map(),
|
|
7775
|
+
optionalProperties: /* @__PURE__ */ new Map(),
|
|
7776
|
+
required: /* @__PURE__ */ new Set()
|
|
7777
|
+
};
|
|
7778
|
+
}
|
|
7779
|
+
function mergeFieldSchemas(schemas) {
|
|
7780
|
+
if (schemas.length === 0) return {};
|
|
7781
|
+
if (schemas.length === 1) return schemas[0];
|
|
7782
|
+
if (schemas.every((s) => s.type === "boolean" && typeof s.const === "boolean")) return {
|
|
7783
|
+
type: "boolean",
|
|
7784
|
+
description: schemas[0].description
|
|
7785
|
+
};
|
|
7786
|
+
if (schemas.every((s) => s.type === "string" && typeof s.const === "string")) {
|
|
7787
|
+
const values = schemas.map((s) => s.const);
|
|
7788
|
+
if (new Set(values).size === 1) return schemas[0];
|
|
7789
|
+
return {
|
|
7790
|
+
type: "string",
|
|
7791
|
+
description: schemas[0].description
|
|
7792
|
+
};
|
|
7793
|
+
}
|
|
7794
|
+
return schemas[0];
|
|
7795
|
+
}
|
|
7796
|
+
function findSharedDiscriminator(variants) {
|
|
7797
|
+
if (variants.length < 2) return null;
|
|
7798
|
+
const firstAlways = variants[0].alwaysProperties;
|
|
7799
|
+
for (const propName of firstAlways.keys()) {
|
|
7800
|
+
let allConst = true;
|
|
7801
|
+
const values = [];
|
|
7802
|
+
for (const v of variants) {
|
|
7803
|
+
const val = readConstString(v.alwaysProperties.get(propName));
|
|
7804
|
+
if (val === null) {
|
|
7805
|
+
allConst = false;
|
|
7806
|
+
break;
|
|
7807
|
+
}
|
|
7808
|
+
values.push(val);
|
|
7809
|
+
}
|
|
7810
|
+
if (allConst && new Set(values).size === values.length) return propName;
|
|
7811
|
+
}
|
|
7812
|
+
return null;
|
|
7813
|
+
}
|
|
7814
|
+
function readConstString(schema) {
|
|
7815
|
+
if (!schema) return null;
|
|
7816
|
+
if (typeof schema.const === "string") return schema.const;
|
|
7817
|
+
if (Array.isArray(schema.enum) && schema.enum.length === 1 && typeof schema.enum[0] === "string") return schema.enum[0];
|
|
7818
|
+
return null;
|
|
7819
|
+
}
|
|
7820
|
+
function variantNameSuffix(constValue) {
|
|
7821
|
+
return toPascalCase(constValue);
|
|
7822
|
+
}
|
|
7823
|
+
function collectObjectFields(schema, parentName, rawSchemas) {
|
|
7824
|
+
const props = schema.properties ?? {};
|
|
7825
|
+
const required = new Set(schema.required ?? []);
|
|
7826
|
+
const fields = [];
|
|
7827
|
+
for (const [name, propSchema] of Object.entries(props)) fields.push(buildField(name, propSchema, required.has(name), parentName, rawSchemas));
|
|
7828
|
+
return fields;
|
|
7829
|
+
}
|
|
7830
|
+
function variantFields(fv, discriminatorProperty, parentName, rawSchemas) {
|
|
7831
|
+
const fields = [];
|
|
7832
|
+
for (const [name, propSchema] of fv.alwaysProperties) {
|
|
7833
|
+
if (name === discriminatorProperty) continue;
|
|
7834
|
+
fields.push(buildField(name, propSchema, fv.required.has(name), parentName, rawSchemas));
|
|
7835
|
+
}
|
|
7836
|
+
for (const [name, propSchema] of fv.optionalProperties) {
|
|
7837
|
+
if (name === discriminatorProperty) continue;
|
|
7838
|
+
fields.push(buildField(name, propSchema, false, parentName, rawSchemas));
|
|
7839
|
+
}
|
|
7840
|
+
return fields;
|
|
7841
|
+
}
|
|
7842
|
+
function buildField(rawName, schema, required, parentName, rawSchemas) {
|
|
7843
|
+
const modelDeps = /* @__PURE__ */ new Set();
|
|
7844
|
+
const domainType = rawSchemaToTS(schema, parentName, rawName, false, modelDeps, rawSchemas);
|
|
7845
|
+
const wireType = rawSchemaToTS(schema, parentName, rawName, true, modelDeps, rawSchemas);
|
|
7846
|
+
return {
|
|
7847
|
+
name: rawName,
|
|
7848
|
+
description: schema.description,
|
|
7849
|
+
required,
|
|
7850
|
+
domainType,
|
|
7851
|
+
wireType,
|
|
7852
|
+
modelDeps,
|
|
7853
|
+
hasDateTime: schemaHasDateTime(schema)
|
|
7854
|
+
};
|
|
7855
|
+
}
|
|
7856
|
+
function schemaHasDateTime(schema) {
|
|
7857
|
+
if (schema.format === "date-time" && typeOf(schema) === "string") return true;
|
|
7858
|
+
if (schema.items && schemaHasDateTime(schema.items)) return true;
|
|
7859
|
+
return false;
|
|
7860
|
+
}
|
|
7861
|
+
function typeOf(schema) {
|
|
7862
|
+
if (Array.isArray(schema.type)) return schema.type.find((t) => t !== "null");
|
|
7863
|
+
return schema.type;
|
|
7864
|
+
}
|
|
7865
|
+
function isNullable(schema) {
|
|
7866
|
+
return Array.isArray(schema.type) && schema.type.includes("null");
|
|
7867
|
+
}
|
|
7868
|
+
function rawSchemaToTS(schema, parentName, fieldName, isWire, modelDeps, rawSchemas) {
|
|
7869
|
+
if (schema.$ref) {
|
|
7870
|
+
const refName = schema.$ref.split("/").pop();
|
|
7871
|
+
modelDeps.add(refName);
|
|
7872
|
+
const domain = toPascalCase(refName);
|
|
7873
|
+
return isWire ? wireInterfaceName(domain) : domain;
|
|
7874
|
+
}
|
|
7875
|
+
if (typeof schema.const === "string") return `'${schema.const}'`;
|
|
7876
|
+
if (typeof schema.const === "boolean") return String(schema.const);
|
|
7877
|
+
const baseType = typeOf(schema);
|
|
7878
|
+
const nullable = isNullable(schema);
|
|
7879
|
+
let core;
|
|
7880
|
+
if (baseType === "string") core = !isWire && schema.format === "date-time" ? "Date" : "string";
|
|
7881
|
+
else if (baseType === "integer" || baseType === "number") core = "number";
|
|
7882
|
+
else if (baseType === "boolean") core = "boolean";
|
|
7883
|
+
else if (baseType === "array" && schema.items) core = `${parenthesizeUnion(rawSchemaToTS(schema.items, parentName, singularize$3(fieldName), isWire, modelDeps, rawSchemas))}[]`;
|
|
7884
|
+
else if (baseType === "object" && schema.properties) {
|
|
7885
|
+
const synthName = `${parentName}_${singularize$3(fieldName)}`;
|
|
7886
|
+
modelDeps.add(synthName);
|
|
7887
|
+
const domain = toPascalCase(synthName);
|
|
7888
|
+
return isWire ? wireInterfaceName(domain) : domain;
|
|
7889
|
+
} else core = "unknown";
|
|
7890
|
+
return nullable ? `${core} | null` : core;
|
|
7891
|
+
}
|
|
7892
|
+
function parenthesizeUnion(t) {
|
|
7893
|
+
return /\s\|\s/.test(t) ? `(${t})` : t;
|
|
7894
|
+
}
|
|
7895
|
+
function singularize$3(name) {
|
|
7896
|
+
if (name.endsWith("ies") && name.length > 3) return `${name.slice(0, -3)}y`;
|
|
7897
|
+
if (name.endsWith("s") && !name.endsWith("ss")) return name.slice(0, -1);
|
|
7898
|
+
return name;
|
|
7899
|
+
}
|
|
7900
|
+
function resolveRef(schema, rawSchemas) {
|
|
7901
|
+
if (!schema.$ref) return schema;
|
|
7902
|
+
const segments = schema.$ref.split("/");
|
|
7903
|
+
return rawSchemas[segments[segments.length - 1]] ?? schema;
|
|
7904
|
+
}
|
|
7905
|
+
function planDiscriminatedModels(models, ctx) {
|
|
7906
|
+
const plans = /* @__PURE__ */ new Map();
|
|
7907
|
+
const spec = loadRawSpec();
|
|
7908
|
+
if (!spec?.components?.schemas) return plans;
|
|
7909
|
+
const rawSchemas = spec.components.schemas;
|
|
7910
|
+
const { modelToService, resolveDir } = createServiceDirResolver(models, ctx.spec.services, ctx);
|
|
7911
|
+
for (const model of models) {
|
|
7912
|
+
const shape = detectDiscriminatedShape(model.name, rawSchemas);
|
|
7913
|
+
if (!shape) continue;
|
|
7914
|
+
const modelDir = resolveDir(modelToService.get(model.name));
|
|
7915
|
+
plans.set(model.name, {
|
|
7916
|
+
shape,
|
|
7917
|
+
modelDir
|
|
7918
|
+
});
|
|
7919
|
+
}
|
|
7920
|
+
return plans;
|
|
7921
|
+
}
|
|
7922
|
+
function generateDiscriminatedFiles(plans, ctx) {
|
|
7923
|
+
const files = [];
|
|
7924
|
+
for (const plan of plans.values()) {
|
|
7925
|
+
files.push(buildInterfaceFile(plan, ctx));
|
|
7926
|
+
files.push(buildSerializerFile(plan, ctx));
|
|
7927
|
+
}
|
|
7928
|
+
return files;
|
|
7929
|
+
}
|
|
7930
|
+
function buildInterfaceFile(plan, _ctx) {
|
|
7931
|
+
const { shape, modelDir } = plan;
|
|
7932
|
+
const domain = toPascalCase(shape.modelName);
|
|
7933
|
+
const wire = wireInterfaceName(domain);
|
|
7934
|
+
const lines = [];
|
|
7935
|
+
const imports = collectImports$2(plan);
|
|
7936
|
+
if (imports.length > 0) {
|
|
7937
|
+
for (const imp of imports) lines.push(`import type { ${imp.symbols.join(", ")} } from '${imp.path}';`);
|
|
7938
|
+
lines.push("");
|
|
7939
|
+
}
|
|
7940
|
+
for (const variant of shape.variants) {
|
|
7941
|
+
const variantDomain = `${domain}${variant.nameSuffix}`;
|
|
7942
|
+
const variantWire = `${variantDomain}Response`;
|
|
7943
|
+
lines.push(...buildInterfaceBody(variantDomain, shape, variant, false));
|
|
7944
|
+
lines.push("");
|
|
7945
|
+
lines.push(...buildInterfaceBody(variantWire, shape, variant, true));
|
|
7946
|
+
lines.push("");
|
|
7947
|
+
}
|
|
7948
|
+
const variantNames = shape.variants.map((v) => `${domain}${v.nameSuffix}`);
|
|
7949
|
+
lines.push(`export type ${domain} = ${variantNames.join(" | ")};`);
|
|
7950
|
+
lines.push("");
|
|
7951
|
+
const wireVariantNames = shape.variants.map((v) => `${domain}${v.nameSuffix}Response`);
|
|
7952
|
+
lines.push(`export type ${wire} = ${wireVariantNames.join(" | ")};`);
|
|
7953
|
+
return {
|
|
7954
|
+
path: `src/${modelDir}/interfaces/${fileName$3(shape.modelName)}.interface.ts`,
|
|
7955
|
+
content: lines.join("\n") + "\n",
|
|
7956
|
+
overwriteExisting: true
|
|
7957
|
+
};
|
|
7958
|
+
}
|
|
7959
|
+
function buildInterfaceBody(name, shape, variant, isWire) {
|
|
7960
|
+
const lines = [];
|
|
7961
|
+
lines.push(`export interface ${name} {`);
|
|
7962
|
+
for (const field of shape.baseFields) pushFieldLine(lines, field, isWire);
|
|
7963
|
+
const discKey = isWire ? shape.discriminatorProperty : shape.discriminatorPropertyDomain;
|
|
7964
|
+
lines.push(` ${discKey}: '${variant.discriminatorValue}';`);
|
|
7965
|
+
for (const field of variant.fields) pushFieldLine(lines, field, isWire);
|
|
7966
|
+
lines.push("}");
|
|
7967
|
+
return lines;
|
|
7968
|
+
}
|
|
7969
|
+
function pushFieldLine(lines, field, isWire) {
|
|
7970
|
+
const key = isWire ? field.name : toCamelCase(field.name);
|
|
7971
|
+
const opt = field.required ? "" : "?";
|
|
7972
|
+
const type = isWire ? field.wireType : field.domainType;
|
|
7973
|
+
if (field.description) lines.push(` /** ${field.description} */`);
|
|
7974
|
+
lines.push(` ${key}${opt}: ${type};`);
|
|
7975
|
+
}
|
|
7976
|
+
function collectImports$2(plan) {
|
|
7977
|
+
const deps = /* @__PURE__ */ new Set();
|
|
7978
|
+
for (const field of plan.shape.baseFields) for (const d of field.modelDeps) deps.add(d);
|
|
7979
|
+
for (const variant of plan.shape.variants) for (const field of variant.fields) for (const d of field.modelDeps) deps.add(d);
|
|
7980
|
+
const symbols = [];
|
|
7981
|
+
for (const dep of [...deps].sort()) {
|
|
7982
|
+
const domain = toPascalCase(dep);
|
|
7983
|
+
symbols.push(domain);
|
|
7984
|
+
const wire = wireInterfaceName(domain);
|
|
7985
|
+
if (wire !== domain) symbols.push(wire);
|
|
7986
|
+
}
|
|
7987
|
+
if (symbols.length === 0) return [];
|
|
7988
|
+
return symbols.map((sym) => {
|
|
7989
|
+
return {
|
|
7990
|
+
path: `./${fileName$3(toSnakeFromPascal(sym.replace(/Response$/, "")))}.interface`,
|
|
7991
|
+
symbols: [sym]
|
|
7992
|
+
};
|
|
7993
|
+
}).reduce((acc, cur) => {
|
|
7994
|
+
const existing = acc.find((a) => a.path === cur.path);
|
|
7995
|
+
if (existing) existing.symbols.push(...cur.symbols);
|
|
7996
|
+
else acc.push(cur);
|
|
7997
|
+
return acc;
|
|
7998
|
+
}, []);
|
|
7999
|
+
}
|
|
8000
|
+
function toSnakeFromPascal(s) {
|
|
8001
|
+
return s.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2").toLowerCase();
|
|
8002
|
+
}
|
|
8003
|
+
function buildSerializerFile(plan, _ctx) {
|
|
8004
|
+
const { shape, modelDir } = plan;
|
|
8005
|
+
const domain = toPascalCase(shape.modelName);
|
|
8006
|
+
const wire = wireInterfaceName(domain);
|
|
8007
|
+
const lines = [];
|
|
8008
|
+
const interfaceImportPath = `../interfaces/${fileName$3(shape.modelName)}.interface`;
|
|
8009
|
+
lines.push(`import type { ${domain}, ${wire} } from '${interfaceImportPath}';`);
|
|
8010
|
+
const allDeps = /* @__PURE__ */ new Set();
|
|
8011
|
+
for (const field of shape.baseFields) for (const d of field.modelDeps) allDeps.add(d);
|
|
8012
|
+
for (const variant of shape.variants) for (const field of variant.fields) for (const d of field.modelDeps) allDeps.add(d);
|
|
8013
|
+
for (const dep of [...allDeps].sort()) {
|
|
8014
|
+
const depDomain = toPascalCase(dep);
|
|
8015
|
+
const depFile = fileName$3(toSnakeFromPascal(depDomain));
|
|
8016
|
+
lines.push(`import { deserialize${depDomain}, serialize${depDomain} } from './${depFile}.serializer';`);
|
|
8017
|
+
}
|
|
8018
|
+
lines.push("");
|
|
8019
|
+
lines.push(`export const deserialize${domain} = (response: ${wire}): ${domain} => {`);
|
|
8020
|
+
lines.push(` switch (response.${shape.discriminatorProperty}) {`);
|
|
8021
|
+
for (const variant of shape.variants) {
|
|
8022
|
+
lines.push(` case '${variant.discriminatorValue}':`);
|
|
8023
|
+
lines.push(` return {`);
|
|
8024
|
+
for (const field of shape.baseFields) lines.push(` ${assignmentLine(field, false, allDeps)},`);
|
|
8025
|
+
lines.push(` ${shape.discriminatorPropertyDomain}: '${variant.discriminatorValue}',`);
|
|
8026
|
+
for (const field of variant.fields) lines.push(` ${assignmentLine(field, false, allDeps)},`);
|
|
8027
|
+
lines.push(` };`);
|
|
8028
|
+
}
|
|
8029
|
+
lines.push(` default:`);
|
|
8030
|
+
lines.push(` throw new Error(\`Unknown ${shape.discriminatorProperty}: \${(response as { ${shape.discriminatorProperty}: string }).${shape.discriminatorProperty}}\`);`);
|
|
8031
|
+
lines.push(` }`);
|
|
8032
|
+
lines.push(`};`);
|
|
8033
|
+
lines.push("");
|
|
8034
|
+
lines.push(`export const serialize${domain} = (model: ${domain}): ${wire} => {`);
|
|
8035
|
+
lines.push(` switch (model.${shape.discriminatorPropertyDomain}) {`);
|
|
8036
|
+
for (const variant of shape.variants) {
|
|
8037
|
+
lines.push(` case '${variant.discriminatorValue}':`);
|
|
8038
|
+
lines.push(` return {`);
|
|
8039
|
+
for (const field of shape.baseFields) lines.push(` ${assignmentLine(field, true, allDeps)},`);
|
|
8040
|
+
lines.push(` ${shape.discriminatorProperty}: '${variant.discriminatorValue}',`);
|
|
8041
|
+
for (const field of variant.fields) lines.push(` ${assignmentLine(field, true, allDeps)},`);
|
|
8042
|
+
lines.push(` };`);
|
|
8043
|
+
}
|
|
8044
|
+
lines.push(` }`);
|
|
8045
|
+
lines.push(`};`);
|
|
8046
|
+
return {
|
|
8047
|
+
path: `src/${modelDir}/serializers/${fileName$3(shape.modelName)}.serializer.ts`,
|
|
8048
|
+
content: lines.join("\n") + "\n",
|
|
8049
|
+
overwriteExisting: true
|
|
8050
|
+
};
|
|
8051
|
+
}
|
|
8052
|
+
function assignmentLine(field, serialize, _allDeps) {
|
|
8053
|
+
const camel = toCamelCase(field.name);
|
|
8054
|
+
const snake = field.name;
|
|
8055
|
+
const lhs = serialize ? snake : camel;
|
|
8056
|
+
const rhsKey = serialize ? camel : snake;
|
|
8057
|
+
const source = serialize ? `model.${rhsKey}` : `response.${rhsKey}`;
|
|
8058
|
+
if (field.hasDateTime) {
|
|
8059
|
+
if (serialize) {
|
|
8060
|
+
if (field.required) return `${lhs}: ${source}.toISOString()`;
|
|
8061
|
+
return `${lhs}: ${source} != null ? ${source}.toISOString() : undefined`;
|
|
8062
|
+
}
|
|
8063
|
+
if (field.required) return `${lhs}: new Date(${source})`;
|
|
8064
|
+
return `${lhs}: ${source} != null ? new Date(${source}) : undefined`;
|
|
8065
|
+
}
|
|
8066
|
+
const arrayDep = arrayItemModelDep(field);
|
|
8067
|
+
if (arrayDep) {
|
|
8068
|
+
const fn = serialize ? `serialize${arrayDep}` : `deserialize${arrayDep}`;
|
|
8069
|
+
if (field.required) return `${lhs}: ${source}.map(${fn})`;
|
|
8070
|
+
return `${lhs}: ${source} != null ? ${source}.map(${fn}) : undefined`;
|
|
8071
|
+
}
|
|
8072
|
+
const scalarDep = scalarModelDepName(field);
|
|
8073
|
+
if (scalarDep) {
|
|
8074
|
+
const fn = serialize ? `serialize${scalarDep}` : `deserialize${scalarDep}`;
|
|
8075
|
+
if (field.required) return `${lhs}: ${fn}(${source})`;
|
|
8076
|
+
return `${lhs}: ${source} != null ? ${fn}(${source}) : undefined`;
|
|
8077
|
+
}
|
|
8078
|
+
return `${lhs}: ${source}`;
|
|
8079
|
+
}
|
|
8080
|
+
function arrayItemModelDep(field) {
|
|
8081
|
+
const m = field.domainType.match(/^([A-Z]\w*)\[\]$/);
|
|
8082
|
+
if (m && field.modelDeps.size > 0) return m[1];
|
|
8083
|
+
return null;
|
|
8084
|
+
}
|
|
8085
|
+
function scalarModelDepName(field) {
|
|
8086
|
+
const stripped = field.domainType.replace(/\s*\|\s*null$/, "");
|
|
8087
|
+
if (/^[A-Z]\w*$/.test(stripped) && field.modelDeps.size === 1) return toPascalCase([...field.modelDeps][0]);
|
|
8088
|
+
return null;
|
|
8089
|
+
}
|
|
8090
|
+
//#endregion
|
|
7573
8091
|
//#region src/node/node-overrides.ts
|
|
7574
8092
|
const OPERATION_OVERRIDES = {
|
|
7575
8093
|
"POST /organizations/{organizationId}/groups": { methodName: "create_group" },
|
|
@@ -7589,31 +8107,71 @@ const contextCache = /* @__PURE__ */ new WeakMap();
|
|
|
7589
8107
|
function operationKey(resolved) {
|
|
7590
8108
|
return `${resolved.operation.httpMethod.toUpperCase()} ${resolved.operation.path}`;
|
|
7591
8109
|
}
|
|
8110
|
+
/**
|
|
8111
|
+
* Apply oneOf / allOf+oneOf enrichment (flattening variant fields onto the
|
|
8112
|
+
* parent model, plus synthetic models/enums for inline shapes) so the rest
|
|
8113
|
+
* of the Node emitter sees a richer `spec.models`.
|
|
8114
|
+
*
|
|
8115
|
+
* Without this, `ConnectApplication` (and any other `allOf [base, oneOf [...]]`
|
|
8116
|
+
* schema whose first variant is itself wrapped in `allOf`) loses every
|
|
8117
|
+
* non-M2M field — the IR parser's discriminator detection silently skips
|
|
8118
|
+
* variants whose properties live behind another `allOf`. Mirrors what the
|
|
8119
|
+
* Go / Kotlin / .NET emitters already do.
|
|
8120
|
+
*
|
|
8121
|
+
* Discriminated bases produced by `enrichModelsFromSpec` get their original
|
|
8122
|
+
* fields restored — Node emits flat interfaces today, not TS sum types, so
|
|
8123
|
+
* an empty base would otherwise drop the common fields.
|
|
8124
|
+
*/
|
|
8125
|
+
function enrichSpecModels(models) {
|
|
8126
|
+
const enriched = enrichModelsFromSpec(models);
|
|
8127
|
+
const originalByName = new Map(models.map((m) => [m.name, m]));
|
|
8128
|
+
return enriched.map((m) => {
|
|
8129
|
+
if (m.discriminator && m.fields.length === 0) {
|
|
8130
|
+
const original = originalByName.get(m.name);
|
|
8131
|
+
if (original && original.fields.length > 0) return {
|
|
8132
|
+
...m,
|
|
8133
|
+
fields: original.fields
|
|
8134
|
+
};
|
|
8135
|
+
}
|
|
8136
|
+
return m;
|
|
8137
|
+
});
|
|
8138
|
+
}
|
|
7592
8139
|
function withNodeOperationOverrides(ctx) {
|
|
7593
8140
|
const cached = contextCache.get(ctx);
|
|
7594
8141
|
if (cached) return cached;
|
|
8142
|
+
const enrichedModels = enrichSpecModels(ctx.spec.models);
|
|
8143
|
+
const specChanged = enrichedModels.length !== ctx.spec.models.length || enrichedModels.some((m, i) => m !== ctx.spec.models[i]);
|
|
8144
|
+
const enrichedSpec = specChanged ? {
|
|
8145
|
+
...ctx.spec,
|
|
8146
|
+
models: enrichedModels
|
|
8147
|
+
} : ctx.spec;
|
|
7595
8148
|
const resolvedOperations = ctx.resolvedOperations;
|
|
7596
8149
|
if (!resolvedOperations?.length) {
|
|
7597
|
-
|
|
7598
|
-
|
|
8150
|
+
const next = specChanged ? {
|
|
8151
|
+
...ctx,
|
|
8152
|
+
spec: enrichedSpec
|
|
8153
|
+
} : ctx;
|
|
8154
|
+
contextCache.set(ctx, next);
|
|
8155
|
+
return next;
|
|
7599
8156
|
}
|
|
7600
|
-
let
|
|
8157
|
+
let opsChanged = false;
|
|
7601
8158
|
const nextResolved = resolvedOperations.map((resolved) => {
|
|
7602
8159
|
const override = OPERATION_OVERRIDES[operationKey(resolved)];
|
|
7603
8160
|
if (!override) return resolved;
|
|
7604
8161
|
const methodName = override.methodName ?? resolved.methodName;
|
|
7605
8162
|
const mountOn = override.mountOn ?? resolved.mountOn;
|
|
7606
8163
|
if (methodName === resolved.methodName && mountOn === resolved.mountOn) return resolved;
|
|
7607
|
-
|
|
8164
|
+
opsChanged = true;
|
|
7608
8165
|
return {
|
|
7609
8166
|
...resolved,
|
|
7610
8167
|
methodName,
|
|
7611
8168
|
mountOn
|
|
7612
8169
|
};
|
|
7613
8170
|
});
|
|
7614
|
-
const next =
|
|
8171
|
+
const next = opsChanged || specChanged ? {
|
|
7615
8172
|
...ctx,
|
|
7616
|
-
resolvedOperations: nextResolved
|
|
8173
|
+
...opsChanged ? { resolvedOperations: nextResolved } : {},
|
|
8174
|
+
...specChanged ? { spec: enrichedSpec } : {}
|
|
7617
8175
|
} : ctx;
|
|
7618
8176
|
contextCache.set(ctx, next);
|
|
7619
8177
|
return next;
|
|
@@ -7824,17 +8382,51 @@ function applyLiveSurface(files, ctx, surface) {
|
|
|
7824
8382
|
}
|
|
7825
8383
|
return out;
|
|
7826
8384
|
}
|
|
8385
|
+
/**
|
|
8386
|
+
* Flatten oneOf / allOf+oneOf variant fields from the raw spec onto each
|
|
8387
|
+
* model. `enrichModelsFromSpec` produces (a) extra optional fields on models
|
|
8388
|
+
* whose schema is `allOf [base, oneOf [...]]`, and (b) synthetic models /
|
|
8389
|
+
* enums for inline objects encountered inside variants (e.g. the inline
|
|
8390
|
+
* `redirect_uris` item shape on `ConnectApplication`).
|
|
8391
|
+
*
|
|
8392
|
+
* Node, like Go / Kotlin / .NET, emits flat interfaces rather than a sum
|
|
8393
|
+
* type, so on `enrichModelsFromSpec`-marked discriminated bases we restore
|
|
8394
|
+
* the original IR fields — otherwise the base interface would be empty.
|
|
8395
|
+
* A future change can emit a real TS discriminated union; for now the goal
|
|
8396
|
+
* is parity with the other flat-emit languages so every variant field is
|
|
8397
|
+
* at least reachable.
|
|
8398
|
+
*/
|
|
8399
|
+
function enrichModelsForNode(models) {
|
|
8400
|
+
const enriched = enrichModelsFromSpec(models);
|
|
8401
|
+
const originalByName = new Map(models.map((m) => [m.name, m]));
|
|
8402
|
+
return enriched.map((m) => {
|
|
8403
|
+
if (m.discriminator && m.fields.length === 0) {
|
|
8404
|
+
const original = originalByName.get(m.name);
|
|
8405
|
+
if (original && original.fields.length > 0) return {
|
|
8406
|
+
...m,
|
|
8407
|
+
fields: original.fields
|
|
8408
|
+
};
|
|
8409
|
+
}
|
|
8410
|
+
return m;
|
|
8411
|
+
});
|
|
8412
|
+
}
|
|
7827
8413
|
const nodeEmitter = {
|
|
7828
8414
|
language: "node",
|
|
7829
8415
|
generateModels(models, ctx) {
|
|
7830
8416
|
const nodeCtx = withNodeOperationOverrides(ctx);
|
|
7831
8417
|
const surface = getSurface(nodeCtx);
|
|
7832
|
-
|
|
8418
|
+
const enriched = enrichModelsForNode(models);
|
|
8419
|
+
const discPlans = planDiscriminatedModels(enriched, nodeCtx);
|
|
8420
|
+
nodeCtx._discriminatedModelNames = new Set(discPlans.keys());
|
|
8421
|
+
const standardFiles = generateModelsAndSerializers(enriched, nodeCtx);
|
|
8422
|
+
const discFiles = generateDiscriminatedFiles(discPlans, nodeCtx);
|
|
8423
|
+
return applyLiveSurface([...standardFiles, ...discFiles], nodeCtx, surface);
|
|
7833
8424
|
},
|
|
7834
8425
|
generateEnums(enums, ctx) {
|
|
7835
8426
|
const nodeCtx = withNodeOperationOverrides(ctx);
|
|
7836
8427
|
const surface = getSurface(nodeCtx);
|
|
7837
|
-
|
|
8428
|
+
const syntheticEnums = getSyntheticEnums();
|
|
8429
|
+
return applyLiveSurface(generateEnums$7([...enums, ...syntheticEnums], nodeCtx), nodeCtx, surface);
|
|
7838
8430
|
},
|
|
7839
8431
|
generateResources(services, ctx) {
|
|
7840
8432
|
const nodeCtx = withNodeOperationOverrides(ctx);
|
|
@@ -7844,7 +8436,7 @@ const nodeEmitter = {
|
|
|
7844
8436
|
generateClient(spec, ctx) {
|
|
7845
8437
|
const nodeCtx = withNodeOperationOverrides(ctx);
|
|
7846
8438
|
const surface = getSurface(nodeCtx);
|
|
7847
|
-
return applyLiveSurface(generateClient$7(spec, nodeCtx), nodeCtx, surface);
|
|
8439
|
+
return applyLiveSurface(generateClient$7(nodeCtx.spec, nodeCtx), nodeCtx, surface);
|
|
7848
8440
|
},
|
|
7849
8441
|
generateErrors(_ctx) {
|
|
7850
8442
|
return [];
|
|
@@ -7952,6 +8544,25 @@ function resolveMethodName$5(op, _service, ctx) {
|
|
|
7952
8544
|
if (existing) return toSnakeCase(existing.methodName);
|
|
7953
8545
|
return toSnakeCase(op.name);
|
|
7954
8546
|
}
|
|
8547
|
+
/**
|
|
8548
|
+
* Build the set of model + enum class names exported by the SDK. Used to
|
|
8549
|
+
* detect collisions with operation-client class names — a colliding service
|
|
8550
|
+
* gets a `Service` suffix appended.
|
|
8551
|
+
*/
|
|
8552
|
+
function buildExportedClassNameSet$3(ctx) {
|
|
8553
|
+
return buildExportedClassNameSet$5(ctx, className$5);
|
|
8554
|
+
}
|
|
8555
|
+
/**
|
|
8556
|
+
* Resolve a service's mount-target identifier, appending `Service` on
|
|
8557
|
+
* collision with an exported model/enum class. Feeds `className`/`fileName`
|
|
8558
|
+
* so the class declaration, file, and any qualified references stay aligned.
|
|
8559
|
+
*
|
|
8560
|
+
* Accessor names (`servicePropertyName`) intentionally use the RAW target —
|
|
8561
|
+
* `client.organization_membership` reads better than the suffixed form.
|
|
8562
|
+
*/
|
|
8563
|
+
function resolveServiceTarget$3(target, exportedClasses) {
|
|
8564
|
+
return resolveServiceTarget$5(target, exportedClasses, className$5);
|
|
8565
|
+
}
|
|
7955
8566
|
/** Resolve the SDK class name for a service, using resolved operations' mountOn. */
|
|
7956
8567
|
function resolveClassName$4(service, ctx) {
|
|
7957
8568
|
for (const r of ctx.resolvedOperations ?? []) if (r.service.name === service.name) return r.mountOn;
|
|
@@ -10001,10 +10612,11 @@ function generateResources$6(services, ctx) {
|
|
|
10001
10612
|
name: resolveClassName$4(s, ctx),
|
|
10002
10613
|
operations: s.operations
|
|
10003
10614
|
}));
|
|
10615
|
+
const exportedClasses = buildExportedClassNameSet$3(ctx);
|
|
10004
10616
|
for (const { name: mountName, operations: allOperations } of entries) {
|
|
10005
10617
|
if (allOperations.length === 0) continue;
|
|
10006
10618
|
const dirName = moduleName$2(mountName);
|
|
10007
|
-
const resourceClassName = className$5(mountName);
|
|
10619
|
+
const resourceClassName = className$5(resolveServiceTarget$3(mountName, exportedClasses));
|
|
10008
10620
|
const importPrefix = relativeImportPrefix(dirName);
|
|
10009
10621
|
const lines = [];
|
|
10010
10622
|
lines.push("from __future__ import annotations");
|
|
@@ -10450,9 +11062,10 @@ function generateWorkOSClient(spec, ctx) {
|
|
|
10450
11062
|
lines.push(" AsyncWorkOSClient as _AsyncBase,");
|
|
10451
11063
|
lines.push(")");
|
|
10452
11064
|
const serviceDirMap = buildMountDirMap$1(ctx);
|
|
11065
|
+
const exportedClasses = buildExportedClassNameSet$3(ctx);
|
|
10453
11066
|
for (const service of topLevelServices) {
|
|
10454
11067
|
const resolvedName = resolveResourceClassName$2(service, ctx);
|
|
10455
|
-
const clsName = className$5(resolvedName);
|
|
11068
|
+
const clsName = className$5(resolveServiceTarget$3(resolvedName, exportedClasses));
|
|
10456
11069
|
const dirName = serviceDirMap.get(service.name) ?? resolveServiceDir(resolvedName);
|
|
10457
11070
|
const importLine = `from .${dirToModule(dirName)}._resource import ${clsName}, Async${clsName}`;
|
|
10458
11071
|
if (importLine.length > 88) {
|
|
@@ -10473,7 +11086,7 @@ function generateWorkOSClient(spec, ctx) {
|
|
|
10473
11086
|
const generatedProps = /* @__PURE__ */ new Set();
|
|
10474
11087
|
for (const service of topLevelServices) {
|
|
10475
11088
|
const resolvedName = resolveResourceClassName$2(service, ctx);
|
|
10476
|
-
const clsName = className$5(resolvedName);
|
|
11089
|
+
const clsName = className$5(resolveServiceTarget$3(resolvedName, exportedClasses));
|
|
10477
11090
|
const prop = servicePropertyName$3(resolvedName);
|
|
10478
11091
|
const readable = clsName.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2");
|
|
10479
11092
|
lines.push("");
|
|
@@ -10492,7 +11105,7 @@ function generateWorkOSClient(spec, ctx) {
|
|
|
10492
11105
|
const asyncGeneratedProps = /* @__PURE__ */ new Set();
|
|
10493
11106
|
for (const service of topLevelServices) {
|
|
10494
11107
|
const resolvedName = resolveResourceClassName$2(service, ctx);
|
|
10495
|
-
const clsName = className$5(resolvedName);
|
|
11108
|
+
const clsName = className$5(resolveServiceTarget$3(resolvedName, exportedClasses));
|
|
10496
11109
|
const prop = servicePropertyName$3(resolvedName);
|
|
10497
11110
|
const readable = clsName.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2");
|
|
10498
11111
|
lines.push("");
|
|
@@ -10531,16 +11144,18 @@ function generateServiceInits(spec, ctx) {
|
|
|
10531
11144
|
const files = [];
|
|
10532
11145
|
const topLevel = deduplicateByMount$4(spec.services, ctx);
|
|
10533
11146
|
const serviceDirMap = buildMountDirMap$1(ctx);
|
|
11147
|
+
const exportedClasses = buildExportedClassNameSet$3(ctx);
|
|
10534
11148
|
const mountGroups = groupByMount(ctx);
|
|
10535
11149
|
for (const service of topLevel) {
|
|
10536
11150
|
const resolvedName = resolveResourceClassName$2(service, ctx);
|
|
11151
|
+
const clsName = className$5(resolveServiceTarget$3(resolvedName, exportedClasses));
|
|
10537
11152
|
const dirName = serviceDirMap.get(service.name) ?? resolveServiceDir(resolvedName);
|
|
10538
11153
|
const lines = [];
|
|
10539
11154
|
const mountTarget = getMountTarget(service, ctx);
|
|
10540
11155
|
const groupClassNames = collectParameterGroupClassNames(mountGroups.get(mountTarget)?.operations ?? service.operations);
|
|
10541
11156
|
const aliasedImports = [
|
|
10542
|
-
|
|
10543
|
-
`Async${
|
|
11157
|
+
clsName,
|
|
11158
|
+
`Async${clsName}`,
|
|
10544
11159
|
...groupClassNames
|
|
10545
11160
|
].map((n) => `${n} as ${n}`);
|
|
10546
11161
|
lines.push(`from ._resource import ${aliasedImports.join(", ")}`);
|
|
@@ -12010,6 +12625,22 @@ function className$4(name) {
|
|
|
12010
12625
|
if (PHP_RESERVED_CLASS_NAMES.has(result)) result += "Model";
|
|
12011
12626
|
return result;
|
|
12012
12627
|
}
|
|
12628
|
+
/**
|
|
12629
|
+
* Build the set of model + enum class names exported by the SDK. Used to
|
|
12630
|
+
* detect collisions with operation-client class names — a colliding service
|
|
12631
|
+
* gets a `Service` suffix appended.
|
|
12632
|
+
*/
|
|
12633
|
+
function buildExportedClassNameSet$2(ctx) {
|
|
12634
|
+
return buildExportedClassNameSet$5(ctx, className$4);
|
|
12635
|
+
}
|
|
12636
|
+
/**
|
|
12637
|
+
* Resolve a service's mount-target identifier, appending `Service` on
|
|
12638
|
+
* collision with an exported model/enum class. Used in `\Service\…` files
|
|
12639
|
+
* to avoid `use WorkOS\Resource\X; class X` PHP fatal errors.
|
|
12640
|
+
*/
|
|
12641
|
+
function resolveServiceTarget$2(target, exportedClasses) {
|
|
12642
|
+
return resolveServiceTarget$5(target, exportedClasses, className$4);
|
|
12643
|
+
}
|
|
12013
12644
|
/** Resolve the SDK method name for an operation, using resolved operations first. */
|
|
12014
12645
|
function resolveMethodName$4(op, _service, ctx) {
|
|
12015
12646
|
const resolved = lookupMethodName(op, buildResolvedLookup(ctx));
|
|
@@ -12542,9 +13173,10 @@ function generateResources$5(services, ctx) {
|
|
|
12542
13173
|
name: className$4(s.name),
|
|
12543
13174
|
operations: s.operations
|
|
12544
13175
|
}));
|
|
13176
|
+
const exportedClasses = buildExportedClassNameSet$2(ctx);
|
|
12545
13177
|
for (const { name: mountName, operations } of entries) {
|
|
12546
13178
|
if (operations.length === 0) continue;
|
|
12547
|
-
const resourceName = className$4(mountName);
|
|
13179
|
+
const resourceName = className$4(resolveServiceTarget$2(mountName, exportedClasses));
|
|
12548
13180
|
const mergedService = {
|
|
12549
13181
|
name: mountName,
|
|
12550
13182
|
operations
|
|
@@ -13080,10 +13712,11 @@ function buildServiceAccessPaths$2(services, ctx) {
|
|
|
13080
13712
|
}
|
|
13081
13713
|
function deduplicateByMount$3(services, ctx) {
|
|
13082
13714
|
const seen = /* @__PURE__ */ new Map();
|
|
13715
|
+
const exportedClasses = buildExportedClassNameSet$2(ctx);
|
|
13083
13716
|
for (const service of services) {
|
|
13084
13717
|
const target = getMountTarget(service, ctx);
|
|
13085
13718
|
if (!seen.has(target)) seen.set(target, {
|
|
13086
|
-
name: className$4(target),
|
|
13719
|
+
name: className$4(resolveServiceTarget$2(target, exportedClasses)),
|
|
13087
13720
|
propName: servicePropertyName$2(target)
|
|
13088
13721
|
});
|
|
13089
13722
|
}
|
|
@@ -13731,15 +14364,37 @@ function ensureTrailingNewlines$5(files) {
|
|
|
13731
14364
|
for (const f of files) if (f.content && !f.content.endsWith("\n")) f.content += "\n";
|
|
13732
14365
|
return files;
|
|
13733
14366
|
}
|
|
14367
|
+
/**
|
|
14368
|
+
* Flatten oneOf / allOf+oneOf variant fields onto each base model and pull
|
|
14369
|
+
* in synthetic models / enums for inline variant shapes. PHP emits flat
|
|
14370
|
+
* classes (no sum types), so a discriminated base whose IR fields the
|
|
14371
|
+
* parser stripped (post-allOf-aware detection) gets its original fields
|
|
14372
|
+
* restored to avoid silently dropping variant data.
|
|
14373
|
+
*/
|
|
14374
|
+
function enrichModelsForPhp(models) {
|
|
14375
|
+
const enriched = enrichModelsFromSpec(models);
|
|
14376
|
+
const originalByName = new Map(models.map((m) => [m.name, m]));
|
|
14377
|
+
return enriched.map((m) => {
|
|
14378
|
+
if (m.discriminator && m.fields.length === 0) {
|
|
14379
|
+
const original = originalByName.get(m.name);
|
|
14380
|
+
if (original && original.fields.length > 0) return {
|
|
14381
|
+
...m,
|
|
14382
|
+
fields: original.fields
|
|
14383
|
+
};
|
|
14384
|
+
}
|
|
14385
|
+
return m;
|
|
14386
|
+
});
|
|
14387
|
+
}
|
|
13734
14388
|
const phpEmitter = {
|
|
13735
14389
|
language: "php",
|
|
13736
14390
|
generateModels(models, ctx) {
|
|
13737
14391
|
ensureNamingInitialized(ctx);
|
|
13738
|
-
return ensureTrailingNewlines$5(generateModels$5(models, ctx));
|
|
14392
|
+
return ensureTrailingNewlines$5(generateModels$5(enrichModelsForPhp(models), ctx));
|
|
13739
14393
|
},
|
|
13740
14394
|
generateEnums(enums, ctx) {
|
|
13741
14395
|
ensureNamingInitialized(ctx);
|
|
13742
|
-
|
|
14396
|
+
const syntheticEnums = getSyntheticEnums();
|
|
14397
|
+
return ensureTrailingNewlines$5(generateEnums$5([...enums, ...syntheticEnums], ctx));
|
|
13743
14398
|
},
|
|
13744
14399
|
generateResources(services, ctx) {
|
|
13745
14400
|
ensureNamingInitialized(ctx);
|
|
@@ -18965,6 +19620,33 @@ function packageSegment(name) {
|
|
|
18965
19620
|
function apiClassName(name) {
|
|
18966
19621
|
return className$1(name);
|
|
18967
19622
|
}
|
|
19623
|
+
/**
|
|
19624
|
+
* Resolve the Kotlin service class name with the collision suffix applied
|
|
19625
|
+
* when needed. Wraps `apiClassName` so callers don't need to thread the
|
|
19626
|
+
* exported-classes set through unrelated emission logic.
|
|
19627
|
+
*/
|
|
19628
|
+
function resolveApiClassName(name, exportedClasses) {
|
|
19629
|
+
return apiClassName(resolveServiceTarget$1(name, exportedClasses));
|
|
19630
|
+
}
|
|
19631
|
+
/**
|
|
19632
|
+
* Build the set of model + enum class names exported by the SDK. Used to
|
|
19633
|
+
* detect collisions with operation-client class names — a colliding service
|
|
19634
|
+
* gets a `Service` suffix appended.
|
|
19635
|
+
*/
|
|
19636
|
+
function buildExportedClassNameSet$1(ctx) {
|
|
19637
|
+
return buildExportedClassNameSet$5(ctx, className$1);
|
|
19638
|
+
}
|
|
19639
|
+
/**
|
|
19640
|
+
* Resolve a service's mount-target identifier, appending `Service` on
|
|
19641
|
+
* collision with an exported model/enum class. Kotlin sees the collision
|
|
19642
|
+
* when a service class shares a simple name with an imported model class
|
|
19643
|
+
* (e.g. `com.workos.models.OrganizationMembership` vs
|
|
19644
|
+
* `com.workos.organizationmembership.OrganizationMembership`) — the file's
|
|
19645
|
+
* local declaration shadows the import for unqualified references.
|
|
19646
|
+
*/
|
|
19647
|
+
function resolveServiceTarget$1(target, exportedClasses) {
|
|
19648
|
+
return resolveServiceTarget$5(target, exportedClasses, className$1);
|
|
19649
|
+
}
|
|
18968
19650
|
/** Accessor property exposed on the WorkOS client (camelCase). */
|
|
18969
19651
|
function servicePropertyName$1(name) {
|
|
18970
19652
|
return toCamelCase(name);
|
|
@@ -20134,12 +20816,13 @@ function generateResources$2(services, ctx) {
|
|
|
20134
20816
|
if (mountGroups.size === 0) return [];
|
|
20135
20817
|
const files = [];
|
|
20136
20818
|
const resolvedLookup = buildResolvedLookup(ctx);
|
|
20819
|
+
const exportedClasses = buildExportedClassNameSet$1(ctx);
|
|
20137
20820
|
for (const [mountName, group] of mountGroups) {
|
|
20138
20821
|
const classCode = generateApiClass(mountName, group.operations, ctx, resolvedLookup);
|
|
20139
20822
|
if (!classCode) continue;
|
|
20140
20823
|
const pkg = packageSegment(mountName);
|
|
20141
20824
|
files.push({
|
|
20142
|
-
path: `${KOTLIN_SRC_PREFIX$1}com/workos/${pkg}/${
|
|
20825
|
+
path: `${KOTLIN_SRC_PREFIX$1}com/workos/${pkg}/${resolveApiClassName(mountName, exportedClasses)}.kt`,
|
|
20143
20826
|
content: classCode,
|
|
20144
20827
|
overwriteExisting: true
|
|
20145
20828
|
});
|
|
@@ -20148,7 +20831,7 @@ function generateResources$2(services, ctx) {
|
|
|
20148
20831
|
}
|
|
20149
20832
|
function generateApiClass(mountName, operations, ctx, resolvedLookup) {
|
|
20150
20833
|
if (operations.length === 0) return null;
|
|
20151
|
-
const apiClass =
|
|
20834
|
+
const apiClass = resolveApiClassName(mountName, buildExportedClassNameSet$1(ctx));
|
|
20152
20835
|
const pkg = `com.workos.${packageSegment(mountName)}`;
|
|
20153
20836
|
const imports = /* @__PURE__ */ new Set();
|
|
20154
20837
|
imports.add("com.workos.WorkOS");
|
|
@@ -20949,8 +21632,9 @@ function generateClient$2(spec, ctx) {
|
|
|
20949
21632
|
if (targets.length === 0) return [];
|
|
20950
21633
|
const imports = /* @__PURE__ */ new Set();
|
|
20951
21634
|
const accessorLines = [];
|
|
21635
|
+
const exportedClasses = buildExportedClassNameSet$1(ctx);
|
|
20952
21636
|
for (const mount of targets) {
|
|
20953
|
-
const apiCls =
|
|
21637
|
+
const apiCls = resolveApiClassName(mount, exportedClasses);
|
|
20954
21638
|
const fqn = `com.workos.${packageSegment(mount)}.${apiCls}`;
|
|
20955
21639
|
imports.add(fqn);
|
|
20956
21640
|
const prop = servicePropertyName$1(mount);
|
|
@@ -21032,12 +21716,13 @@ function generateTests$2(spec, ctx) {
|
|
|
21032
21716
|
const files = [];
|
|
21033
21717
|
const mountGroups = groupByMount(ctx);
|
|
21034
21718
|
const resolvedLookup = buildResolvedLookup(ctx);
|
|
21719
|
+
const exportedClasses = buildExportedClassNameSet$1(ctx);
|
|
21035
21720
|
for (const [mountName, group] of mountGroups) {
|
|
21036
21721
|
const content = generateServiceTestClass(mountName, group.operations, ctx, resolvedLookup);
|
|
21037
21722
|
if (!content) continue;
|
|
21038
21723
|
const pkg = packageSegment(mountName);
|
|
21039
21724
|
files.push({
|
|
21040
|
-
path: `${TEST_PREFIX}com/workos/${pkg}/${
|
|
21725
|
+
path: `${TEST_PREFIX}com/workos/${pkg}/${resolveApiClassName(mountName, exportedClasses)}Test.kt`,
|
|
21041
21726
|
content,
|
|
21042
21727
|
overwriteExisting: true
|
|
21043
21728
|
});
|
|
@@ -21106,7 +21791,7 @@ function generateServiceTestClass(mountName, operations, ctx, resolvedLookup) {
|
|
|
21106
21791
|
if (anyForbidden) imports.add("com.github.tomakehurst.wiremock.client.WireMock.absent");
|
|
21107
21792
|
if (uniqueTests.some((t) => t.canEmitHappyPath && t.responseAssertions.length > 0)) imports.add("org.junit.jupiter.api.Assertions.assertEquals");
|
|
21108
21793
|
const pkg = packageSegment(mountName);
|
|
21109
|
-
const apiCls =
|
|
21794
|
+
const apiCls = resolveApiClassName(mountName, buildExportedClassNameSet$1(ctx));
|
|
21110
21795
|
if (uniqueTests.some((t) => !t.canEmitHappyPath)) imports.add("org.junit.jupiter.api.Disabled");
|
|
21111
21796
|
const lines = [];
|
|
21112
21797
|
lines.push(`package com.workos.${pkg}`);
|
|
@@ -22022,6 +22707,30 @@ function moduleName$1(name) {
|
|
|
22022
22707
|
return toSnakeCase(name);
|
|
22023
22708
|
}
|
|
22024
22709
|
/**
|
|
22710
|
+
* Build the set of model + enum Ruby class names that the SDK exposes under
|
|
22711
|
+
* `WorkOS::`. Used to detect collisions with operation-client class names —
|
|
22712
|
+
* a colliding service gets a `Service` suffix (`OrganizationMembershipService`)
|
|
22713
|
+
* so it doesn't shadow the model class under Zeitwerk's collapsed namespace.
|
|
22714
|
+
*/
|
|
22715
|
+
function buildExportedClassNameSet(ctx) {
|
|
22716
|
+
return buildExportedClassNameSet$5(ctx, className);
|
|
22717
|
+
}
|
|
22718
|
+
/**
|
|
22719
|
+
* Resolve a service's mount-target identifier, appending `Service` on
|
|
22720
|
+
* collision with an exported model/enum class name. The returned PascalCase
|
|
22721
|
+
* value feeds `className`/`fileName` to derive matching class + file names
|
|
22722
|
+
* (e.g. `OrganizationMembershipService` / `organization_membership_service`).
|
|
22723
|
+
*
|
|
22724
|
+
* Accessor names (`servicePropertyName`) intentionally use the RAW target —
|
|
22725
|
+
* `client.organization_membership` is more readable than the suffixed form.
|
|
22726
|
+
*
|
|
22727
|
+
* The directory used by `loader.collapse` (the model home) likewise uses the
|
|
22728
|
+
* raw target.
|
|
22729
|
+
*/
|
|
22730
|
+
function resolveServiceTarget(target, exportedClasses) {
|
|
22731
|
+
return resolveServiceTarget$5(target, exportedClasses, className);
|
|
22732
|
+
}
|
|
22733
|
+
/**
|
|
22025
22734
|
* PascalCase class name for a parameter-group variant. Mirrors the Python
|
|
22026
22735
|
* convention: group "password" + variant "plaintext" → `PasswordPlaintext`.
|
|
22027
22736
|
* Used as the Ruby constant under the WorkOS module.
|
|
@@ -22796,9 +23505,11 @@ function generateResources$1(services, ctx) {
|
|
|
22796
23505
|
const listWrapperModels = /* @__PURE__ */ new Map();
|
|
22797
23506
|
for (const m of ctx.spec.models) if (isListWrapperModel(m)) listWrapperModels.set(m.name, m);
|
|
22798
23507
|
const groupOwners = buildGroupOwnerMap(ctx);
|
|
23508
|
+
const exportedClasses = buildExportedClassNameSet(ctx);
|
|
22799
23509
|
for (const [mountTarget, group] of groups) {
|
|
22800
|
-
const
|
|
22801
|
-
const
|
|
23510
|
+
const resolvedTarget = resolveServiceTarget(mountTarget, exportedClasses);
|
|
23511
|
+
const cls = className(resolvedTarget);
|
|
23512
|
+
const file = fileName(resolvedTarget);
|
|
22802
23513
|
const operations = group.operations;
|
|
22803
23514
|
if (operations.length === 0) continue;
|
|
22804
23515
|
const requires = /* @__PURE__ */ new Set();
|
|
@@ -22826,7 +23537,8 @@ function generateResources$1(services, ctx) {
|
|
|
22826
23537
|
modelByName,
|
|
22827
23538
|
listWrapperModels,
|
|
22828
23539
|
requires,
|
|
22829
|
-
groupOwners
|
|
23540
|
+
groupOwners,
|
|
23541
|
+
exportedClasses
|
|
22830
23542
|
});
|
|
22831
23543
|
methodBodies.push(body);
|
|
22832
23544
|
if (resolved?.wrappers && resolved.wrappers.length > 0) {
|
|
@@ -22872,12 +23584,12 @@ function generateResources$1(services, ctx) {
|
|
|
22872
23584
|
}
|
|
22873
23585
|
/** Build a single Ruby method from an Operation. */
|
|
22874
23586
|
function emitMethod(args) {
|
|
22875
|
-
const { op, method, defaults, inferFromClient, hiddenParams, enumNames, modelNames, modelByName, listWrapperModels, requires, groupOwners } = args;
|
|
23587
|
+
const { op, method, defaults, inferFromClient, hiddenParams, enumNames, modelNames, modelByName, listWrapperModels, requires, groupOwners, exportedClasses } = args;
|
|
22876
23588
|
/** Fully-qualified Ruby constant for a variant (e.g. WorkOS::UserManagement::PasswordPlaintext). */
|
|
22877
23589
|
const variantClassRef = (group, variantName) => {
|
|
22878
23590
|
const owner = groupOwners.get(group.name);
|
|
22879
23591
|
if (!owner) throw new Error(`No owner mount target found for parameter group '${group.name}'`);
|
|
22880
|
-
return scopedGroupVariantClassName(owner, group.name, variantName);
|
|
23592
|
+
return scopedGroupVariantClassName(resolveServiceTarget(owner, exportedClasses), group.name, variantName);
|
|
22881
23593
|
};
|
|
22882
23594
|
planOperation(op);
|
|
22883
23595
|
const lines = [];
|
|
@@ -23429,8 +24141,9 @@ function rubyCamelize(basename) {
|
|
|
23429
24141
|
function buildInflectionMap(spec, ctx) {
|
|
23430
24142
|
const inflections = /* @__PURE__ */ new Map();
|
|
23431
24143
|
inflections.set("workos", "WorkOS");
|
|
24144
|
+
const exportedClasses = buildExportedClassNameSet(ctx);
|
|
23432
24145
|
for (const service of buildTopLevelServices(spec, ctx)) {
|
|
23433
|
-
const target = getMountTarget(service, ctx) || resolveClassName(service, ctx);
|
|
24146
|
+
const target = resolveServiceTarget(getMountTarget(service, ctx) || resolveClassName(service, ctx), exportedClasses);
|
|
23434
24147
|
const cls = className(target);
|
|
23435
24148
|
const file = fileName(target);
|
|
23436
24149
|
if (rubyCamelize(file) !== cls) inflections.set(file, cls);
|
|
@@ -23522,10 +24235,11 @@ function generateClientClass(spec, ctx) {
|
|
|
23522
24235
|
lines.push("module WorkOS");
|
|
23523
24236
|
lines.push(" class Client < BaseClient");
|
|
23524
24237
|
const topLevelServices = buildTopLevelServices(spec, ctx);
|
|
24238
|
+
const exportedClasses = buildExportedClassNameSet(ctx);
|
|
23525
24239
|
for (const service of topLevelServices) {
|
|
23526
|
-
const
|
|
23527
|
-
const cls = className(
|
|
23528
|
-
const prop = servicePropertyName(
|
|
24240
|
+
const rawTarget = getMountTarget(service, ctx) || resolveClassName(service, ctx);
|
|
24241
|
+
const cls = className(resolveServiceTarget(rawTarget, exportedClasses));
|
|
24242
|
+
const prop = servicePropertyName(rawTarget);
|
|
23529
24243
|
lines.push("");
|
|
23530
24244
|
lines.push(` def ${prop}`);
|
|
23531
24245
|
lines.push(` @${prop} ||= WorkOS::${cls}.new(self)`);
|
|
@@ -23571,10 +24285,12 @@ function generateTests$1(spec, ctx) {
|
|
|
23571
24285
|
for (const m of models) modelByName.set(m.name, m);
|
|
23572
24286
|
const lookup = buildResolvedLookup(ctx);
|
|
23573
24287
|
const groupOwners = buildGroupOwnerMap(ctx);
|
|
24288
|
+
const exportedClasses = buildExportedClassNameSet(ctx);
|
|
23574
24289
|
for (const [mountTarget, group] of groups) {
|
|
23575
|
-
const
|
|
24290
|
+
const resolvedTarget = resolveServiceTarget(mountTarget, exportedClasses);
|
|
24291
|
+
const cls = className(resolvedTarget);
|
|
23576
24292
|
const prop = servicePropertyName(mountTarget);
|
|
23577
|
-
const file = fileName(
|
|
24293
|
+
const file = fileName(resolvedTarget);
|
|
23578
24294
|
const lines = [];
|
|
23579
24295
|
lines.push(`require 'test_helper'`);
|
|
23580
24296
|
lines.push("");
|
|
@@ -23600,7 +24316,7 @@ function generateTests$1(spec, ctx) {
|
|
|
23600
24316
|
const httpMethodSym = `:${op.httpMethod.toLowerCase()}`;
|
|
23601
24317
|
const resolved = lookupResolved(op, lookup);
|
|
23602
24318
|
const hiddenParams = buildHiddenParams$1(resolved);
|
|
23603
|
-
const callArgs = buildCallArgsStub(op, modelByName, hiddenParams, groupOwners, models);
|
|
24319
|
+
const callArgs = buildCallArgsStub(op, modelByName, hiddenParams, groupOwners, models, exportedClasses);
|
|
23604
24320
|
const bodyMatcher = buildBodyMatcher(op, modelByName, hiddenParams, models);
|
|
23605
24321
|
authMethodManifest.push({
|
|
23606
24322
|
method,
|
|
@@ -23629,7 +24345,7 @@ function generateTests$1(spec, ctx) {
|
|
|
23629
24345
|
for (const group of op.parameterGroups ?? []) for (let vi = 1; vi < group.variants.length; vi++) {
|
|
23630
24346
|
const variant = group.variants[vi];
|
|
23631
24347
|
const overrides = new Map([[group.name, vi]]);
|
|
23632
|
-
const variantCallArgs = buildCallArgsStub(op, modelByName, hiddenParams, groupOwners, models, overrides);
|
|
24348
|
+
const variantCallArgs = buildCallArgsStub(op, modelByName, hiddenParams, groupOwners, models, exportedClasses, overrides);
|
|
23633
24349
|
const variantBodyMatcher = buildBodyMatcher(op, modelByName, hiddenParams, models, overrides);
|
|
23634
24350
|
const suffix = `with_${fieldName$1(group.name)}_${fieldName$1(variant.name)}`;
|
|
23635
24351
|
lines.push("");
|
|
@@ -23786,7 +24502,7 @@ function roundTripStub(ref, enumNames) {
|
|
|
23786
24502
|
* default to variant 0. Used to emit per-variant test cases that exercise the
|
|
23787
24503
|
* second/third arm of each parameter-group dispatcher.
|
|
23788
24504
|
*/
|
|
23789
|
-
function buildCallArgsStub(op, modelByName, hiddenParams, groupOwners, models, variantOverrides = /* @__PURE__ */ new Map()) {
|
|
24505
|
+
function buildCallArgsStub(op, modelByName, hiddenParams, groupOwners, models, exportedClasses, variantOverrides = /* @__PURE__ */ new Map()) {
|
|
23790
24506
|
const parts = [];
|
|
23791
24507
|
const seen = /* @__PURE__ */ new Set();
|
|
23792
24508
|
const pathParamNames = /* @__PURE__ */ new Set();
|
|
@@ -23828,7 +24544,7 @@ function buildCallArgsStub(op, modelByName, hiddenParams, groupOwners, models, v
|
|
|
23828
24544
|
if (variant) {
|
|
23829
24545
|
const owner = groupOwners.get(group.name);
|
|
23830
24546
|
if (!owner) throw new Error(`No owner mount target found for parameter group '${group.name}'`);
|
|
23831
|
-
const variantClass = scopedGroupVariantClassName(owner, group.name, variant.name);
|
|
24547
|
+
const variantClass = scopedGroupVariantClassName(resolveServiceTarget(owner, exportedClasses), group.name, variant.name);
|
|
23832
24548
|
const fieldStubs = variant.parameters.map((p) => `${fieldName$1(p.name)}: ${stubValueFor(pickVariantParamType(p.type, bodyFieldTypes.get(p.name)))}`).join(", ");
|
|
23833
24549
|
parts.push(`${name}: ${variantClass}.new(${fieldStubs})`);
|
|
23834
24550
|
}
|
|
@@ -23969,6 +24685,10 @@ function stubUrlRegex(escaped) {
|
|
|
23969
24685
|
* Uses each resolved operation's actual mountOn (not the service default) so
|
|
23970
24686
|
* operations remounted via operationHints land on the correct service prop.
|
|
23971
24687
|
* Split operations emit one entry per wrapper (keyed by wrapper name + variant).
|
|
24688
|
+
*
|
|
24689
|
+
* The accessor (`service` field) uses the raw mountOn — accessor names stay
|
|
24690
|
+
* unsuffixed even when the underlying service class gets a `Service` suffix
|
|
24691
|
+
* on collision.
|
|
23972
24692
|
*/
|
|
23973
24693
|
function buildOperationsMap$1(spec, ctx) {
|
|
23974
24694
|
const manifest = {};
|
|
@@ -24069,8 +24789,10 @@ function generateRbiFiles(spec, ctx) {
|
|
|
24069
24789
|
const listWrapperModels = /* @__PURE__ */ new Map();
|
|
24070
24790
|
for (const m of spec.models) if (isListWrapperModel(m)) listWrapperModels.set(m.name, m);
|
|
24071
24791
|
const groupOwners = buildGroupOwnerMap(ctx);
|
|
24792
|
+
const exportedClasses = buildExportedClassNameSet(ctx);
|
|
24072
24793
|
for (const [mountTarget, group] of groups) {
|
|
24073
|
-
const
|
|
24794
|
+
const resolvedTarget = resolveServiceTarget(mountTarget, exportedClasses);
|
|
24795
|
+
const cls = className(resolvedTarget);
|
|
24074
24796
|
const lines = [];
|
|
24075
24797
|
lines.push("# typed: strong");
|
|
24076
24798
|
lines.push("");
|
|
@@ -24078,6 +24800,7 @@ function generateRbiFiles(spec, ctx) {
|
|
|
24078
24800
|
lines.push(` class ${cls}`);
|
|
24079
24801
|
const variants = collectVariantsForMountTarget(ctx, spec.models, mountTarget);
|
|
24080
24802
|
for (const v of variants) {
|
|
24803
|
+
v.mountTarget = resolvedTarget;
|
|
24081
24804
|
for (const line of emitInlineVariantRbi(v)) lines.push(line);
|
|
24082
24805
|
lines.push("");
|
|
24083
24806
|
}
|
|
@@ -24102,7 +24825,8 @@ function generateRbiFiles(spec, ctx) {
|
|
|
24102
24825
|
const groupSorbetType = (group) => {
|
|
24103
24826
|
const owner = groupOwners.get(group.name);
|
|
24104
24827
|
if (!owner) throw new Error(`No owner mount target found for parameter group '${group.name}'`);
|
|
24105
|
-
const
|
|
24828
|
+
const resolvedOwner = resolveServiceTarget(owner, exportedClasses);
|
|
24829
|
+
const variants = group.variants.map((v) => scopedGroupVariantClassName(resolvedOwner, group.name, v.name));
|
|
24106
24830
|
if (variants.length === 1) return variants[0];
|
|
24107
24831
|
return `T.any(${variants.join(", ")})`;
|
|
24108
24832
|
};
|
|
@@ -24176,7 +24900,7 @@ function generateRbiFiles(spec, ctx) {
|
|
|
24176
24900
|
lines.push(" end");
|
|
24177
24901
|
lines.push("end");
|
|
24178
24902
|
files.push({
|
|
24179
|
-
path: `rbi/workos/${fileName(
|
|
24903
|
+
path: `rbi/workos/${fileName(resolvedTarget)}.rbi`,
|
|
24180
24904
|
content: lines.join("\n"),
|
|
24181
24905
|
integrateTarget: true,
|
|
24182
24906
|
overwriteExisting: true
|
|
@@ -24189,8 +24913,8 @@ function generateRbiFiles(spec, ctx) {
|
|
|
24189
24913
|
lines.push("module WorkOS");
|
|
24190
24914
|
lines.push(" class Client < BaseClient");
|
|
24191
24915
|
for (const [mountTarget] of groups) {
|
|
24192
|
-
const cls = className(mountTarget);
|
|
24193
|
-
const prop = mountTarget
|
|
24916
|
+
const cls = className(resolveServiceTarget(mountTarget, exportedClasses));
|
|
24917
|
+
const prop = servicePropertyName(mountTarget);
|
|
24194
24918
|
lines.push(` sig { returns(WorkOS::${cls}) }`);
|
|
24195
24919
|
lines.push(` def ${prop}; end`);
|
|
24196
24920
|
lines.push("");
|
|
@@ -24253,13 +24977,37 @@ function ensureTrailingNewlines$1(files) {
|
|
|
24253
24977
|
for (const f of files) if (f.content && !f.content.endsWith("\n")) f.content += "\n";
|
|
24254
24978
|
return files;
|
|
24255
24979
|
}
|
|
24980
|
+
/**
|
|
24981
|
+
* Flatten oneOf / allOf+oneOf variant fields onto each base model and pick
|
|
24982
|
+
* up the synthetic models / enums `enrichModelsFromSpec` produces for inline
|
|
24983
|
+
* variant shapes. Ruby emits flat hash-backed models, not sum types, so a
|
|
24984
|
+
* discriminated base whose IR fields were stripped (the new EventSchema-
|
|
24985
|
+
* style behaviour after the parser learned to walk allOf-wrapped variants)
|
|
24986
|
+
* has its original fields restored — otherwise `ConnectApplication`-style
|
|
24987
|
+
* bases would silently lose every variant field they had previously.
|
|
24988
|
+
*/
|
|
24989
|
+
function enrichModelsForRuby(models) {
|
|
24990
|
+
const enriched = enrichModelsFromSpec(models);
|
|
24991
|
+
const originalByName = new Map(models.map((m) => [m.name, m]));
|
|
24992
|
+
return enriched.map((m) => {
|
|
24993
|
+
if (m.discriminator && m.fields.length === 0) {
|
|
24994
|
+
const original = originalByName.get(m.name);
|
|
24995
|
+
if (original && original.fields.length > 0) return {
|
|
24996
|
+
...m,
|
|
24997
|
+
fields: original.fields
|
|
24998
|
+
};
|
|
24999
|
+
}
|
|
25000
|
+
return m;
|
|
25001
|
+
});
|
|
25002
|
+
}
|
|
24256
25003
|
const rubyEmitter = {
|
|
24257
25004
|
language: "ruby",
|
|
24258
25005
|
generateModels(models, ctx) {
|
|
24259
|
-
return ensureTrailingNewlines$1(generateModels$1(models, ctx));
|
|
25006
|
+
return ensureTrailingNewlines$1(generateModels$1(enrichModelsForRuby(models), ctx));
|
|
24260
25007
|
},
|
|
24261
25008
|
generateEnums(enums, ctx) {
|
|
24262
|
-
|
|
25009
|
+
const syntheticEnums = getSyntheticEnums();
|
|
25010
|
+
return ensureTrailingNewlines$1(generateEnums$1([...enums, ...syntheticEnums], ctx));
|
|
24263
25011
|
},
|
|
24264
25012
|
generateResources(services, ctx) {
|
|
24265
25013
|
return ensureTrailingNewlines$1(generateResources$1(services, ctx));
|
|
@@ -26548,14 +27296,37 @@ function ensureTrailingNewlines(files) {
|
|
|
26548
27296
|
for (const f of files) if (f.content && !f.content.endsWith("\n")) f.content += "\n";
|
|
26549
27297
|
return files;
|
|
26550
27298
|
}
|
|
27299
|
+
/**
|
|
27300
|
+
* Flatten oneOf / allOf+oneOf variant fields onto each base model and pull
|
|
27301
|
+
* in synthetic models / enums for inline variant shapes. Rust emits flat
|
|
27302
|
+
* structs (a synthesised enum-union from `UnionRegistry` exists, but the
|
|
27303
|
+
* field-on-base pattern is what matches `ConnectApplication` today). A
|
|
27304
|
+
* discriminated base whose IR fields the parser stripped gets its original
|
|
27305
|
+
* fields restored to avoid losing variant data.
|
|
27306
|
+
*/
|
|
27307
|
+
function enrichModelsForRust(models) {
|
|
27308
|
+
const enriched = enrichModelsFromSpec(models);
|
|
27309
|
+
const originalByName = new Map(models.map((m) => [m.name, m]));
|
|
27310
|
+
return enriched.map((m) => {
|
|
27311
|
+
if (m.discriminator && m.fields.length === 0) {
|
|
27312
|
+
const original = originalByName.get(m.name);
|
|
27313
|
+
if (original && original.fields.length > 0) return {
|
|
27314
|
+
...m,
|
|
27315
|
+
fields: original.fields
|
|
27316
|
+
};
|
|
27317
|
+
}
|
|
27318
|
+
return m;
|
|
27319
|
+
});
|
|
27320
|
+
}
|
|
26551
27321
|
const rustEmitter = {
|
|
26552
27322
|
language: "rust",
|
|
26553
27323
|
generateModels(models, ctx) {
|
|
26554
27324
|
unionRegistry.reset();
|
|
26555
|
-
return ensureTrailingNewlines(generateModels(models, ctx, unionRegistry));
|
|
27325
|
+
return ensureTrailingNewlines(generateModels(enrichModelsForRust(models), ctx, unionRegistry));
|
|
26556
27326
|
},
|
|
26557
27327
|
generateEnums(enums, ctx) {
|
|
26558
|
-
|
|
27328
|
+
const syntheticEnums = getSyntheticEnums();
|
|
27329
|
+
return ensureTrailingNewlines(generateEnums([...enums, ...syntheticEnums], ctx));
|
|
26559
27330
|
},
|
|
26560
27331
|
generateResources(services, ctx) {
|
|
26561
27332
|
return ensureTrailingNewlines(generateResources(services, ctx, unionRegistry));
|
|
@@ -26631,4 +27402,4 @@ const workosEmittersPlugin = {
|
|
|
26631
27402
|
//#endregion
|
|
26632
27403
|
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
27404
|
|
|
26634
|
-
//# sourceMappingURL=plugin-
|
|
27405
|
+
//# sourceMappingURL=plugin-BxVeu2v9.mjs.map
|