@workos/oagen-emitters 0.12.4 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.release-please-manifest.json +1 -1
- package/CHANGELOG.md +14 -0
- package/dist/index.mjs +1 -1
- package/dist/{plugin-nmiHN7Ko.mjs → plugin-B9F2jmwy.mjs} +1432 -1203
- package/dist/plugin-B9F2jmwy.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/field-plan.ts +27 -13
- package/src/node/manifest.ts +5 -3
- package/src/node/models.ts +52 -6
- package/src/node/naming.ts +24 -0
- package/src/node/resources.ts +21 -9
- package/src/node/tests.ts +52 -9
- package/src/php/client.ts +3 -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/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/shared/service-name-collision.ts +56 -0
- package/test/node/models.test.ts +56 -0
- package/test/node/tests.test.ts +57 -0
- package/dist/plugin-nmiHN7Ko.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++) {
|
|
@@ -2527,451 +2254,793 @@ function getDuplicateReferences(object, state) {
|
|
|
2527
2254
|
for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) state.duplicates.push(objects[duplicatesIndexes[index]]);
|
|
2528
2255
|
state.usedDuplicates = new Array(length);
|
|
2529
2256
|
}
|
|
2530
|
-
function inspectNode(object, objects, duplicatesIndexes) {
|
|
2531
|
-
var objectKeyList, index, length;
|
|
2532
|
-
if (object !== null && typeof object === "object") {
|
|
2533
|
-
index = objects.indexOf(object);
|
|
2534
|
-
if (index !== -1) {
|
|
2535
|
-
if (duplicatesIndexes.indexOf(index) === -1) duplicatesIndexes.push(index);
|
|
2536
|
-
} else {
|
|
2537
|
-
objects.push(object);
|
|
2538
|
-
if (Array.isArray(object)) for (index = 0, length = object.length; index < length; index += 1) inspectNode(object[index], objects, duplicatesIndexes);
|
|
2539
|
-
else {
|
|
2540
|
-
objectKeyList = Object.keys(object);
|
|
2541
|
-
for (index = 0, length = objectKeyList.length; index < length; index += 1) inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes);
|
|
2257
|
+
function inspectNode(object, objects, duplicatesIndexes) {
|
|
2258
|
+
var objectKeyList, index, length;
|
|
2259
|
+
if (object !== null && typeof object === "object") {
|
|
2260
|
+
index = objects.indexOf(object);
|
|
2261
|
+
if (index !== -1) {
|
|
2262
|
+
if (duplicatesIndexes.indexOf(index) === -1) duplicatesIndexes.push(index);
|
|
2263
|
+
} else {
|
|
2264
|
+
objects.push(object);
|
|
2265
|
+
if (Array.isArray(object)) for (index = 0, length = object.length; index < length; index += 1) inspectNode(object[index], objects, duplicatesIndexes);
|
|
2266
|
+
else {
|
|
2267
|
+
objectKeyList = Object.keys(object);
|
|
2268
|
+
for (index = 0, length = objectKeyList.length; index < length; index += 1) inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes);
|
|
2269
|
+
}
|
|
2270
|
+
}
|
|
2271
|
+
}
|
|
2272
|
+
}
|
|
2273
|
+
function dump$1(input, options) {
|
|
2274
|
+
options = options || {};
|
|
2275
|
+
var state = new State(options);
|
|
2276
|
+
if (!state.noRefs) getDuplicateReferences(input, state);
|
|
2277
|
+
var value = input;
|
|
2278
|
+
if (state.replacer) value = state.replacer.call({ "": value }, "", value);
|
|
2279
|
+
if (writeNode(state, 0, value, true, true)) return state.dump + "\n";
|
|
2280
|
+
return "";
|
|
2281
|
+
}
|
|
2282
|
+
var dumper = { dump: dump$1 };
|
|
2283
|
+
var load = loader.load;
|
|
2284
|
+
loader.loadAll;
|
|
2285
|
+
dumper.dump;
|
|
2286
|
+
//#endregion
|
|
2287
|
+
//#region src/shared/model-utils.ts
|
|
2288
|
+
/**
|
|
2289
|
+
* Detect whether a model is a list wrapper -- the standard paginated
|
|
2290
|
+
* list envelope with `data` (array), `list_metadata`, and optionally `object: 'list'`.
|
|
2291
|
+
*
|
|
2292
|
+
* These models are redundant because each language SDK already has its own
|
|
2293
|
+
* pagination wrapper, and the runtime handles deserialization.
|
|
2294
|
+
*/
|
|
2295
|
+
function isListWrapperModel(model) {
|
|
2296
|
+
const fieldsByName = new Map(model.fields.map((f) => [f.name, f]));
|
|
2297
|
+
const dataField = fieldsByName.get("data");
|
|
2298
|
+
if (!dataField) return false;
|
|
2299
|
+
if (dataField.type.kind !== "array") return false;
|
|
2300
|
+
if (!(fieldsByName.get("list_metadata") ?? fieldsByName.get("listMetadata"))) return false;
|
|
2301
|
+
const objectField = fieldsByName.get("object");
|
|
2302
|
+
if (objectField) {
|
|
2303
|
+
if (objectField.type.kind !== "literal" || objectField.type.value !== "list") return false;
|
|
2304
|
+
}
|
|
2305
|
+
return true;
|
|
2306
|
+
}
|
|
2307
|
+
/**
|
|
2308
|
+
* Detect whether a model is a list metadata model (e.g., ListMetadata).
|
|
2309
|
+
* These models typically have exactly `before` and `after` nullable string fields.
|
|
2310
|
+
*/
|
|
2311
|
+
function isListMetadataModel(model) {
|
|
2312
|
+
if (model.fields.length !== 2) return false;
|
|
2313
|
+
const fieldsByName = new Map(model.fields.map((f) => [f.name, f]));
|
|
2314
|
+
const before = fieldsByName.get("before");
|
|
2315
|
+
const after = fieldsByName.get("after");
|
|
2316
|
+
if (!before || !after) return false;
|
|
2317
|
+
return isNullableString(before) && isNullableString(after);
|
|
2318
|
+
}
|
|
2319
|
+
/** Check if a field type is nullable string (nullable<string> or just string). */
|
|
2320
|
+
function isNullableString(field) {
|
|
2321
|
+
if (field.type.kind === "primitive" && field.type.type === "string") return true;
|
|
2322
|
+
if (field.type.kind === "nullable" && field.type.inner.kind === "primitive" && field.type.inner.type === "string") return true;
|
|
2323
|
+
return false;
|
|
2324
|
+
}
|
|
2325
|
+
/**
|
|
2326
|
+
* Discover the OpenAPI spec path from CLI args or environment.
|
|
2327
|
+
* Returns null if not found.
|
|
2328
|
+
*/
|
|
2329
|
+
function discoverSpecPath() {
|
|
2330
|
+
const args = process.argv;
|
|
2331
|
+
for (let i = 0; i < args.length; i++) {
|
|
2332
|
+
if (args[i] === "--spec" && args[i + 1]) return resolve(args[i + 1]);
|
|
2333
|
+
if (args[i]?.startsWith("--spec=")) return resolve(args[i].slice(7));
|
|
2334
|
+
}
|
|
2335
|
+
if (process.env.OPENAPI_SPEC_PATH) return resolve(process.env.OPENAPI_SPEC_PATH);
|
|
2336
|
+
return null;
|
|
2337
|
+
}
|
|
2338
|
+
/** Cached raw spec to avoid re-reading on multiple calls. */
|
|
2339
|
+
let _rawSpecCache = null;
|
|
2340
|
+
let _rawSpecLoaded = false;
|
|
2341
|
+
function loadRawSpec() {
|
|
2342
|
+
if (_rawSpecLoaded) return _rawSpecCache;
|
|
2343
|
+
_rawSpecLoaded = true;
|
|
2344
|
+
const specPath = discoverSpecPath();
|
|
2345
|
+
if (!specPath || !existsSync(specPath)) return null;
|
|
2346
|
+
try {
|
|
2347
|
+
_rawSpecCache = load(readFileSync(specPath, "utf-8"));
|
|
2348
|
+
return _rawSpecCache;
|
|
2349
|
+
} catch {
|
|
2350
|
+
return null;
|
|
2351
|
+
}
|
|
2352
|
+
}
|
|
2353
|
+
/** Look up a schema by name in the raw spec's components/schemas. */
|
|
2354
|
+
function lookupRawSchema(name) {
|
|
2355
|
+
const spec = loadRawSpec();
|
|
2356
|
+
if (!spec) return null;
|
|
2357
|
+
return spec?.components?.schemas?.[name] ?? null;
|
|
2358
|
+
}
|
|
2359
|
+
function createCollector() {
|
|
2360
|
+
return {
|
|
2361
|
+
models: [],
|
|
2362
|
+
enums: [],
|
|
2363
|
+
usedNames: /* @__PURE__ */ new Set()
|
|
2364
|
+
};
|
|
2365
|
+
}
|
|
2366
|
+
/**
|
|
2367
|
+
* Singularize a snake_case name for use as an array-item model name.
|
|
2368
|
+
* `redirect_uris` -> `redirect_uri`, `scopes` -> `scope`.
|
|
2369
|
+
*/
|
|
2370
|
+
function singularizeSnake(name) {
|
|
2371
|
+
if (name.endsWith("ies") && name.length > 3) return `${name.slice(0, -3)}y`;
|
|
2372
|
+
if (name.endsWith("s") && !name.endsWith("ss")) return name.slice(0, -1);
|
|
2373
|
+
return name;
|
|
2374
|
+
}
|
|
2375
|
+
/**
|
|
2376
|
+
* Convert a raw OpenAPI type+format to an IR TypeRef.
|
|
2377
|
+
*
|
|
2378
|
+
* When `parentModelName` and `fieldName` are provided, inline objects and
|
|
2379
|
+
* enums generate synthetic models/enums instead of degrading to `unknown`
|
|
2380
|
+
* or `string`.
|
|
2381
|
+
*/
|
|
2382
|
+
function rawSchemaToTypeRef(schema, parentModelName, fName, collector) {
|
|
2383
|
+
if (schema.const !== void 0) return {
|
|
2384
|
+
kind: "literal",
|
|
2385
|
+
value: schema.const
|
|
2386
|
+
};
|
|
2387
|
+
if (schema.enum && collector && parentModelName && fName) {
|
|
2388
|
+
const syntheticName = `${parentModelName}_${fName}`;
|
|
2389
|
+
if (!collector.usedNames.has(syntheticName) && !collector.usedNames.has(toSnakeCase(syntheticName))) {
|
|
2390
|
+
collector.usedNames.add(syntheticName);
|
|
2391
|
+
collector.enums.push({
|
|
2392
|
+
name: syntheticName,
|
|
2393
|
+
values: schema.enum.map((v) => ({
|
|
2394
|
+
value: v,
|
|
2395
|
+
description: void 0
|
|
2396
|
+
}))
|
|
2397
|
+
});
|
|
2398
|
+
}
|
|
2399
|
+
return {
|
|
2400
|
+
kind: "enum",
|
|
2401
|
+
name: syntheticName,
|
|
2402
|
+
values: schema.enum
|
|
2403
|
+
};
|
|
2404
|
+
}
|
|
2405
|
+
if (schema.enum) return {
|
|
2406
|
+
kind: "primitive",
|
|
2407
|
+
type: "string"
|
|
2408
|
+
};
|
|
2409
|
+
if (schema.$ref) return {
|
|
2410
|
+
kind: "model",
|
|
2411
|
+
name: schema.$ref.split("/").pop()
|
|
2412
|
+
};
|
|
2413
|
+
let baseType = schema.type;
|
|
2414
|
+
let isNullable = false;
|
|
2415
|
+
if (Array.isArray(baseType)) {
|
|
2416
|
+
const nonNull = baseType.filter((t) => t !== "null");
|
|
2417
|
+
isNullable = baseType.includes("null");
|
|
2418
|
+
baseType = nonNull[0] ?? "string";
|
|
2419
|
+
}
|
|
2420
|
+
let ref;
|
|
2421
|
+
if (baseType === "object" && schema.properties && collector && parentModelName && fName) {
|
|
2422
|
+
const syntheticName = `${parentModelName}_${fName}`;
|
|
2423
|
+
if (!collector.usedNames.has(syntheticName) && !collector.usedNames.has(toSnakeCase(syntheticName))) {
|
|
2424
|
+
collector.usedNames.add(syntheticName);
|
|
2425
|
+
const fields = [];
|
|
2426
|
+
const requiredSet = new Set(schema.required ?? []);
|
|
2427
|
+
for (const [propName, propSchema] of Object.entries(schema.properties)) fields.push({
|
|
2428
|
+
name: propName,
|
|
2429
|
+
type: rawSchemaToTypeRef(propSchema, syntheticName, propName, collector),
|
|
2430
|
+
required: requiredSet.has(propName),
|
|
2431
|
+
description: propSchema.description,
|
|
2432
|
+
deprecated: propSchema.deprecated
|
|
2433
|
+
});
|
|
2434
|
+
collector.models.push({
|
|
2435
|
+
name: syntheticName,
|
|
2436
|
+
fields,
|
|
2437
|
+
description: schema.description
|
|
2438
|
+
});
|
|
2439
|
+
}
|
|
2440
|
+
ref = {
|
|
2441
|
+
kind: "model",
|
|
2442
|
+
name: syntheticName
|
|
2443
|
+
};
|
|
2444
|
+
} else if (baseType === "object" && schema.properties) ref = {
|
|
2445
|
+
kind: "primitive",
|
|
2446
|
+
type: "unknown"
|
|
2447
|
+
};
|
|
2448
|
+
else if (baseType === "array" && schema.items) {
|
|
2449
|
+
const itemFieldName = fName ? singularizeSnake(fName) : void 0;
|
|
2450
|
+
ref = {
|
|
2451
|
+
kind: "array",
|
|
2452
|
+
items: rawSchemaToTypeRef(schema.items, parentModelName, itemFieldName, collector)
|
|
2453
|
+
};
|
|
2454
|
+
} else if (baseType === "boolean") ref = {
|
|
2455
|
+
kind: "primitive",
|
|
2456
|
+
type: "boolean"
|
|
2457
|
+
};
|
|
2458
|
+
else if (baseType === "integer" || baseType === "number") ref = {
|
|
2459
|
+
kind: "primitive",
|
|
2460
|
+
type: baseType
|
|
2461
|
+
};
|
|
2462
|
+
else ref = {
|
|
2463
|
+
kind: "primitive",
|
|
2464
|
+
type: "string"
|
|
2465
|
+
};
|
|
2466
|
+
if (isNullable) return {
|
|
2467
|
+
kind: "nullable",
|
|
2468
|
+
inner: ref
|
|
2469
|
+
};
|
|
2470
|
+
return ref;
|
|
2471
|
+
}
|
|
2472
|
+
/**
|
|
2473
|
+
* Extract fields from a raw OpenAPI object schema.
|
|
2474
|
+
* All fields are returned as optional (not required) since they come from
|
|
2475
|
+
* oneOf variants where only one variant is active at a time.
|
|
2476
|
+
*/
|
|
2477
|
+
function extractFieldsFromRawSchema(schema, parentModelName, collector) {
|
|
2478
|
+
const fields = [];
|
|
2479
|
+
const props = schema.properties ?? {};
|
|
2480
|
+
for (const [name, propSchema] of Object.entries(props)) fields.push({
|
|
2481
|
+
name,
|
|
2482
|
+
type: rawSchemaToTypeRef(propSchema, parentModelName, name, collector),
|
|
2483
|
+
required: false,
|
|
2484
|
+
description: propSchema.description,
|
|
2485
|
+
deprecated: propSchema.deprecated
|
|
2486
|
+
});
|
|
2487
|
+
return fields;
|
|
2488
|
+
}
|
|
2489
|
+
/**
|
|
2490
|
+
* Recursively collect all fields from a oneOf schema, flattening nested
|
|
2491
|
+
* allOf+oneOf compositions. All fields are marked optional.
|
|
2492
|
+
*/
|
|
2493
|
+
function collectOneOfFields(schema, parentModelName, collector) {
|
|
2494
|
+
const allFields = [];
|
|
2495
|
+
const seenFieldNames = /* @__PURE__ */ new Set();
|
|
2496
|
+
function walkSchema(s) {
|
|
2497
|
+
if (s.properties) {
|
|
2498
|
+
for (const f of extractFieldsFromRawSchema(s, parentModelName, collector)) if (!seenFieldNames.has(f.name)) {
|
|
2499
|
+
seenFieldNames.add(f.name);
|
|
2500
|
+
allFields.push(f);
|
|
2501
|
+
}
|
|
2502
|
+
}
|
|
2503
|
+
if (s.allOf) for (const sub of s.allOf) walkSchema(sub);
|
|
2504
|
+
if (s.oneOf) for (const variant of s.oneOf) walkSchema(variant);
|
|
2505
|
+
if (s.anyOf) for (const variant of s.anyOf) walkSchema(variant);
|
|
2506
|
+
}
|
|
2507
|
+
walkSchema(schema);
|
|
2508
|
+
return allFields;
|
|
2509
|
+
}
|
|
2510
|
+
/**
|
|
2511
|
+
* Check if a TypeRef is `unknown` (the degraded type for inline objects).
|
|
2512
|
+
*/
|
|
2513
|
+
function isUnknownType(ref) {
|
|
2514
|
+
return ref.kind === "primitive" && ref.type === "unknown";
|
|
2515
|
+
}
|
|
2516
|
+
/**
|
|
2517
|
+
* If a field is an `array<unknown>` (or `nullable<array<unknown>>`) and the
|
|
2518
|
+
* raw spec defines inline object/enum items, replace the item type with a
|
|
2519
|
+
* synthetic model/enum. Returns the original field unchanged when no upgrade
|
|
2520
|
+
* is needed.
|
|
2521
|
+
*/
|
|
2522
|
+
function upgradeArrayItemType(field, rawSchema, parentModelName, collector) {
|
|
2523
|
+
let arrayRef = null;
|
|
2524
|
+
let isNullableWrapper = false;
|
|
2525
|
+
if (field.type.kind === "array") arrayRef = field.type;
|
|
2526
|
+
else if (field.type.kind === "nullable" && field.type.inner.kind === "array") {
|
|
2527
|
+
arrayRef = field.type.inner;
|
|
2528
|
+
isNullableWrapper = true;
|
|
2529
|
+
}
|
|
2530
|
+
if (!arrayRef || arrayRef.kind !== "array") return field;
|
|
2531
|
+
if (!isUnknownType(arrayRef.items)) return field;
|
|
2532
|
+
const rawProp = rawSchema.properties?.[field.name];
|
|
2533
|
+
if (!rawProp) return field;
|
|
2534
|
+
let rawArraySchema = rawProp;
|
|
2535
|
+
if (Array.isArray(rawProp.type)) {
|
|
2536
|
+
if (rawProp.type.filter((t) => t !== "null")[0] === "array") rawArraySchema = rawProp;
|
|
2537
|
+
}
|
|
2538
|
+
if (rawArraySchema.type !== "array" && !(Array.isArray(rawArraySchema.type) && rawArraySchema.type.includes("array"))) return field;
|
|
2539
|
+
if (!rawArraySchema.items) return field;
|
|
2540
|
+
const itemFieldName = singularizeSnake(field.name);
|
|
2541
|
+
const newItemRef = rawSchemaToTypeRef(rawArraySchema.items, parentModelName, itemFieldName, collector);
|
|
2542
|
+
if (isUnknownType(newItemRef)) return field;
|
|
2543
|
+
const newArrayRef = {
|
|
2544
|
+
kind: "array",
|
|
2545
|
+
items: newItemRef
|
|
2546
|
+
};
|
|
2547
|
+
const newType = isNullableWrapper ? {
|
|
2548
|
+
kind: "nullable",
|
|
2549
|
+
inner: newArrayRef
|
|
2550
|
+
} : newArrayRef;
|
|
2551
|
+
return {
|
|
2552
|
+
...field,
|
|
2553
|
+
type: newType
|
|
2554
|
+
};
|
|
2555
|
+
}
|
|
2556
|
+
let _lastSyntheticEnums = [];
|
|
2557
|
+
/**
|
|
2558
|
+
* Return the synthetic enums generated during the last call to
|
|
2559
|
+
* `enrichModelsFromSpec`. Call this after enrichment to merge them into the
|
|
2560
|
+
* enum generation phase.
|
|
2561
|
+
*/
|
|
2562
|
+
function getSyntheticEnums() {
|
|
2563
|
+
return _lastSyntheticEnums;
|
|
2564
|
+
}
|
|
2565
|
+
/**
|
|
2566
|
+
* Find a property name that has a `const` value in ALL oneOf variants.
|
|
2567
|
+
* Returns null if no shared const property is found.
|
|
2568
|
+
*/
|
|
2569
|
+
function findSharedConstProperty(oneOfSchemas) {
|
|
2570
|
+
if (oneOfSchemas.length === 0) return null;
|
|
2571
|
+
const first = oneOfSchemas[0];
|
|
2572
|
+
if (!first.properties) return null;
|
|
2573
|
+
const candidates = Object.keys(first.properties).filter((name) => first.properties[name].const !== void 0);
|
|
2574
|
+
for (const candidate of candidates) if (oneOfSchemas.every((variant) => variant.properties?.[candidate]?.const !== void 0)) return candidate;
|
|
2575
|
+
return null;
|
|
2576
|
+
}
|
|
2577
|
+
/**
|
|
2578
|
+
* Build a discriminator mapping from const values to IR model names.
|
|
2579
|
+
* For each oneOf variant's const value on `discProperty`, find the IR model
|
|
2580
|
+
* whose field with the same name is a Literal type with that value.
|
|
2581
|
+
*/
|
|
2582
|
+
function buildDiscriminatorMapping(discProperty, oneOfSchemas, models, parentModelName) {
|
|
2583
|
+
const mapping = {};
|
|
2584
|
+
for (const variant of oneOfSchemas) {
|
|
2585
|
+
const constValue = variant.properties?.[discProperty]?.const;
|
|
2586
|
+
if (constValue === void 0) continue;
|
|
2587
|
+
const variantModel = models.find((m) => m.name !== parentModelName && m.fields.some((f) => f.name === discProperty && f.type.kind === "literal" && f.type.value === constValue));
|
|
2588
|
+
if (variantModel) mapping[String(constValue)] = variantModel.name;
|
|
2589
|
+
}
|
|
2590
|
+
return mapping;
|
|
2591
|
+
}
|
|
2592
|
+
/**
|
|
2593
|
+
* Detect implicit discriminators on models without full oneOf flattening.
|
|
2594
|
+
* Returns a new array with discriminator annotations; models without
|
|
2595
|
+
* discriminators are returned as-is. Use this when you need discriminator
|
|
2596
|
+
* info but don't want the side-effects of full enrichment (synthetic
|
|
2597
|
+
* models/enums, field flattening).
|
|
2598
|
+
*/
|
|
2599
|
+
function detectDiscriminators(models) {
|
|
2600
|
+
if (!loadRawSpec()) return models;
|
|
2601
|
+
let changed = false;
|
|
2602
|
+
const result = models.map((model) => {
|
|
2603
|
+
if (model.discriminator) return model;
|
|
2604
|
+
const rawSchema = lookupRawSchema(model.name);
|
|
2605
|
+
if (!rawSchema) return model;
|
|
2606
|
+
const oneOfContainer = rawSchema.allOf?.find((s) => s.oneOf);
|
|
2607
|
+
if (!oneOfContainer?.oneOf || oneOfContainer.oneOf.length === 0) return model;
|
|
2608
|
+
const discProperty = findSharedConstProperty(oneOfContainer.oneOf);
|
|
2609
|
+
if (!discProperty) return model;
|
|
2610
|
+
const mapping = buildDiscriminatorMapping(discProperty, oneOfContainer.oneOf, models, model.name);
|
|
2611
|
+
if (Object.keys(mapping).length === 0) return model;
|
|
2612
|
+
changed = true;
|
|
2613
|
+
return {
|
|
2614
|
+
...model,
|
|
2615
|
+
fields: [],
|
|
2616
|
+
discriminator: {
|
|
2617
|
+
property: discProperty,
|
|
2618
|
+
mapping
|
|
2619
|
+
}
|
|
2620
|
+
};
|
|
2621
|
+
});
|
|
2622
|
+
return changed ? result : models;
|
|
2623
|
+
}
|
|
2624
|
+
/**
|
|
2625
|
+
* Enrich IR models by flattening oneOf/allOf+oneOf variant fields from the raw spec.
|
|
2626
|
+
*
|
|
2627
|
+
* For models with 0 fields whose raw spec schema is a pure oneOf:
|
|
2628
|
+
* - Collect all variant fields and add them as optional fields.
|
|
2629
|
+
*
|
|
2630
|
+
* For models whose raw spec schema has allOf containing a oneOf:
|
|
2631
|
+
* - Collect the missing variant fields and add them as optional.
|
|
2632
|
+
*
|
|
2633
|
+
* Inline objects and enums in oneOf branches are promoted to synthetic
|
|
2634
|
+
* models/enums instead of degrading to `object` / `string`.
|
|
2635
|
+
*
|
|
2636
|
+
* Returns a new array of enriched models (original models are not mutated).
|
|
2637
|
+
* Synthetic enums are stored internally; retrieve them via `getSyntheticEnums()`.
|
|
2638
|
+
*/
|
|
2639
|
+
function enrichModelsFromSpec(models) {
|
|
2640
|
+
if (!loadRawSpec()) {
|
|
2641
|
+
_lastSyntheticEnums = [];
|
|
2642
|
+
return models;
|
|
2643
|
+
}
|
|
2644
|
+
const collector = createCollector();
|
|
2645
|
+
for (const m of models) {
|
|
2646
|
+
collector.usedNames.add(m.name);
|
|
2647
|
+
collector.usedNames.add(toSnakeCase(m.name));
|
|
2648
|
+
}
|
|
2649
|
+
const enriched2 = models.map((model) => {
|
|
2650
|
+
const rawSchema = lookupRawSchema(model.name);
|
|
2651
|
+
if (!rawSchema) return model;
|
|
2652
|
+
if (!(rawSchema.oneOf || rawSchema.allOf?.some((s) => s.oneOf))) return model;
|
|
2653
|
+
if (rawSchema.discriminator || rawSchema.oneOf?.some((v) => v.discriminator) || rawSchema.allOf?.some((s) => s.discriminator || s.oneOf?.some((v) => v.discriminator))) return model;
|
|
2654
|
+
const oneOfContainer = rawSchema.allOf?.find((s) => s.oneOf);
|
|
2655
|
+
if (oneOfContainer?.oneOf && oneOfContainer.oneOf.length > 0) {
|
|
2656
|
+
const discProperty = findSharedConstProperty(oneOfContainer.oneOf);
|
|
2657
|
+
if (discProperty) {
|
|
2658
|
+
const mapping = buildDiscriminatorMapping(discProperty, oneOfContainer.oneOf, models, model.name);
|
|
2659
|
+
if (Object.keys(mapping).length > 0) return {
|
|
2660
|
+
...model,
|
|
2661
|
+
fields: [],
|
|
2662
|
+
discriminator: {
|
|
2663
|
+
property: discProperty,
|
|
2664
|
+
mapping
|
|
2665
|
+
}
|
|
2666
|
+
};
|
|
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
|
+
value: v.value,
|
|
2696
|
+
description: v.description
|
|
2697
|
+
}))
|
|
2698
|
+
}));
|
|
2699
|
+
const existingSnakeNames = new Set(enriched2.map((m) => toSnakeCase(m.name)));
|
|
2700
|
+
const filteredSynthetic = collector.models.filter((m) => !existingSnakeNames.has(toSnakeCase(m.name)));
|
|
2701
|
+
return [...enriched2, ...filteredSynthetic];
|
|
2554
2702
|
}
|
|
2555
|
-
var dumper = { dump: dump$1 };
|
|
2556
|
-
var load = loader.load;
|
|
2557
|
-
loader.loadAll;
|
|
2558
|
-
dumper.dump;
|
|
2559
2703
|
//#endregion
|
|
2560
|
-
//#region src/shared/
|
|
2704
|
+
//#region src/shared/service-name-collision.ts
|
|
2561
2705
|
/**
|
|
2562
|
-
*
|
|
2563
|
-
*
|
|
2706
|
+
* Suffix applied to an operation-client class name when it collides with an
|
|
2707
|
+
* exported model/enum class name in the same SDK namespace. Standardized
|
|
2708
|
+
* across emitters so colliding services look the same in every language —
|
|
2709
|
+
* e.g. `OrganizationMembershipService` regardless of language.
|
|
2564
2710
|
*
|
|
2565
|
-
*
|
|
2566
|
-
*
|
|
2711
|
+
* Languages whose operation clients already carry a unique suffix (Go's
|
|
2712
|
+
* `…Service`, Rust's `…Api`, .NET's `…Service`) skip this helper entirely.
|
|
2567
2713
|
*/
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2714
|
+
const SERVICE_COLLISION_SUFFIX = "Service";
|
|
2715
|
+
/**
|
|
2716
|
+
* Build the set of model + enum class names that the SDK exports under its
|
|
2717
|
+
* top-level namespace. Each emitter passes its own `classNameFn` so the
|
|
2718
|
+
* comparison happens on the language-specific class-name form (e.g. Ruby's
|
|
2719
|
+
* `RoleList`, Python's `RoleList`).
|
|
2720
|
+
*
|
|
2721
|
+
* List-wrapper and list-metadata models are excluded — they aren't exposed
|
|
2722
|
+
* as user-facing types.
|
|
2723
|
+
*/
|
|
2724
|
+
function buildExportedClassNameSet$5(ctx, classNameFn) {
|
|
2725
|
+
const out = /* @__PURE__ */ new Set();
|
|
2726
|
+
for (const model of ctx.spec.models) {
|
|
2727
|
+
if (isListWrapperModel(model) || isListMetadataModel(model)) continue;
|
|
2728
|
+
out.add(classNameFn(model.name));
|
|
2577
2729
|
}
|
|
2578
|
-
|
|
2730
|
+
for (const enumDef of ctx.spec.enums) out.add(classNameFn(enumDef.name));
|
|
2731
|
+
return out;
|
|
2579
2732
|
}
|
|
2580
2733
|
/**
|
|
2581
|
-
*
|
|
2582
|
-
*
|
|
2734
|
+
* Resolve the PascalCase mount-target identifier for an operation client,
|
|
2735
|
+
* appending `Service` when the un-suffixed class name would shadow an
|
|
2736
|
+
* exported model or enum.
|
|
2737
|
+
*
|
|
2738
|
+
* Operates on the PascalCase target (the mount-target string the IR carries),
|
|
2739
|
+
* so the returned value feeds cleanly into each language's `className` and
|
|
2740
|
+
* `fileName` helpers — e.g. `OrganizationMembership` → `OrganizationMembershipService`,
|
|
2741
|
+
* then `fileName` → `organization_membership_service` / `organization-membership-service`.
|
|
2742
|
+
*
|
|
2743
|
+
* The accessor on the client (`client.organization_membership`) is intentionally
|
|
2744
|
+
* NOT suffixed — callers should keep using the raw target for `servicePropertyName`
|
|
2745
|
+
* so the accessor reads naturally.
|
|
2583
2746
|
*/
|
|
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);
|
|
2747
|
+
function resolveServiceTarget$5(target, exportedClasses, classNameFn) {
|
|
2748
|
+
return exportedClasses.has(classNameFn(target)) ? `${target}${SERVICE_COLLISION_SUFFIX}` : target;
|
|
2591
2749
|
}
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
return
|
|
2750
|
+
//#endregion
|
|
2751
|
+
//#region src/node/naming.ts
|
|
2752
|
+
/** Strip spec-noise suffixes (e.g., "Dto") from an IR name. */
|
|
2753
|
+
function stripNoiseSuffixes(name) {
|
|
2754
|
+
return name.replace(/Dto$/i, "");
|
|
2755
|
+
}
|
|
2756
|
+
/** PascalCase class/interface name. */
|
|
2757
|
+
function className$6(name) {
|
|
2758
|
+
return toPascalCase(stripUrnPrefix(name));
|
|
2759
|
+
}
|
|
2760
|
+
/** kebab-case file name (without extension). */
|
|
2761
|
+
function fileName$3(name) {
|
|
2762
|
+
return toKebabCase(stripUrnPrefix(name));
|
|
2763
|
+
}
|
|
2764
|
+
/** camelCase field name for domain interfaces. */
|
|
2765
|
+
function fieldName$6(name) {
|
|
2766
|
+
return toCamelCase(name);
|
|
2767
|
+
}
|
|
2768
|
+
/** snake_case field name for wire/response interfaces. */
|
|
2769
|
+
function wireFieldName(name) {
|
|
2770
|
+
return toSnakeCase(name);
|
|
2597
2771
|
}
|
|
2598
2772
|
/**
|
|
2599
|
-
*
|
|
2600
|
-
*
|
|
2773
|
+
* Active set of `Serialized${Name}` interfaces in the live SDK, harvested
|
|
2774
|
+
* from `ctx.apiSurface` once per generation run. When non-empty, the
|
|
2775
|
+
* legacy wire-naming scheme wins so existing hand-written serializer files
|
|
2776
|
+
* continue to compile.
|
|
2777
|
+
*
|
|
2778
|
+
* Set by `index.ts` immediately after `getSurface(ctx)` runs.
|
|
2601
2779
|
*/
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
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;
|
|
2780
|
+
let baselineSerializedNames = /* @__PURE__ */ new Set();
|
|
2781
|
+
function setBaselineSerializedNames(names) {
|
|
2782
|
+
baselineSerializedNames = names;
|
|
2610
2783
|
}
|
|
2611
|
-
/**
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2784
|
+
/**
|
|
2785
|
+
* Set of every interface name present in the baseline live SDK, regardless
|
|
2786
|
+
* of naming convention. Used to detect single-form baselines (where one
|
|
2787
|
+
* `*Response`-suffixed interface stands for both the domain and wire shape)
|
|
2788
|
+
* so we don't synthesize a non-existent `*Wire` variant.
|
|
2789
|
+
*/
|
|
2790
|
+
let baselineInterfaceNames = /* @__PURE__ */ new Set();
|
|
2791
|
+
function setBaselineInterfaceNames(names) {
|
|
2792
|
+
baselineInterfaceNames = names;
|
|
2793
|
+
}
|
|
2794
|
+
/**
|
|
2795
|
+
* IR models that belong to newly-adopted services should not be renamed by
|
|
2796
|
+
* structural baseline matches from unrelated hand-written services.
|
|
2797
|
+
*/
|
|
2798
|
+
let adoptedModelNames = /* @__PURE__ */ new Set();
|
|
2799
|
+
function setAdoptedModelNames(names) {
|
|
2800
|
+
adoptedModelNames = names;
|
|
2801
|
+
}
|
|
2802
|
+
function isAdoptedModelName(name) {
|
|
2803
|
+
return adoptedModelNames.has(name);
|
|
2804
|
+
}
|
|
2805
|
+
/**
|
|
2806
|
+
* Wire/response interface name.
|
|
2807
|
+
*
|
|
2808
|
+
* Resolution order:
|
|
2809
|
+
* 1. `Serialized${domainName}` if it exists in the baseline (legacy
|
|
2810
|
+
* workos-node convention; lets hand-written serializer files keep
|
|
2811
|
+
* compiling).
|
|
2812
|
+
* 2. `${domainName}Wire` when the domain ends in `Response` AND the
|
|
2813
|
+
* baseline actually has a `*Wire` interface (avoids
|
|
2814
|
+
* `FooResponseResponse` stutter).
|
|
2815
|
+
* 3. The bare `domainName` itself when it already ends in `Response` and
|
|
2816
|
+
* no `*Wire` variant exists — this happens when the structural matcher
|
|
2817
|
+
* maps an IR model to a baseline-wire-shaped interface
|
|
2818
|
+
* (`AuditLogSchemaJson` → `AuditLogSchemaResponse`) and the baseline
|
|
2819
|
+
* has no separate domain/wire split.
|
|
2820
|
+
* 4. `${domainName}Response` for the standard fresh-emit case.
|
|
2821
|
+
*/
|
|
2822
|
+
function wireInterfaceName(domainName) {
|
|
2823
|
+
const serialized = `Serialized${domainName}`;
|
|
2824
|
+
if (baselineSerializedNames.has(serialized)) return serialized;
|
|
2825
|
+
if (domainName.endsWith("Response")) {
|
|
2826
|
+
const wireForm = `${domainName}Wire`;
|
|
2827
|
+
if (baselineInterfaceNames.has(wireForm)) return wireForm;
|
|
2828
|
+
if (baselineInterfaceNames.has(domainName)) return domainName;
|
|
2829
|
+
return wireForm;
|
|
2624
2830
|
}
|
|
2831
|
+
return `${domainName}Response`;
|
|
2625
2832
|
}
|
|
2626
|
-
/**
|
|
2627
|
-
function
|
|
2628
|
-
|
|
2629
|
-
if (!spec) return null;
|
|
2630
|
-
return spec?.components?.schemas?.[name] ?? null;
|
|
2833
|
+
/** kebab-case service directory name. */
|
|
2834
|
+
function serviceDirName(name) {
|
|
2835
|
+
return toKebabCase(name);
|
|
2631
2836
|
}
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
enums: [],
|
|
2636
|
-
usedNames: /* @__PURE__ */ new Set()
|
|
2637
|
-
};
|
|
2837
|
+
/** camelCase property name for service accessors on the client. */
|
|
2838
|
+
function servicePropertyName$4(name) {
|
|
2839
|
+
return toCamelCase(name);
|
|
2638
2840
|
}
|
|
2639
2841
|
/**
|
|
2640
|
-
*
|
|
2641
|
-
*
|
|
2842
|
+
* Resolve the effective service name, using the overlay-resolved class name
|
|
2843
|
+
* when available.
|
|
2642
2844
|
*/
|
|
2643
|
-
function
|
|
2644
|
-
|
|
2645
|
-
if (name.endsWith("s") && !name.endsWith("ss")) return name.slice(0, -1);
|
|
2646
|
-
return name;
|
|
2845
|
+
function resolveServiceName(service, ctx) {
|
|
2846
|
+
return resolveClassName$5(service, ctx);
|
|
2647
2847
|
}
|
|
2648
2848
|
/**
|
|
2649
|
-
*
|
|
2650
|
-
*
|
|
2651
|
-
*
|
|
2652
|
-
* enums generate synthetic models/enums instead of degrading to `unknown`
|
|
2653
|
-
* or `string`.
|
|
2849
|
+
* Build the set of model + enum class names exported by the SDK. Used to
|
|
2850
|
+
* detect collisions with operation-client class names — a colliding service
|
|
2851
|
+
* gets a `Service` suffix appended.
|
|
2654
2852
|
*/
|
|
2655
|
-
function
|
|
2656
|
-
|
|
2657
|
-
kind: "literal",
|
|
2658
|
-
value: schema.const
|
|
2659
|
-
};
|
|
2660
|
-
if (schema.enum && collector && parentModelName && fName) {
|
|
2661
|
-
const syntheticName = `${parentModelName}_${fName}`;
|
|
2662
|
-
if (!collector.usedNames.has(syntheticName) && !collector.usedNames.has(toSnakeCase(syntheticName))) {
|
|
2663
|
-
collector.usedNames.add(syntheticName);
|
|
2664
|
-
collector.enums.push({
|
|
2665
|
-
name: syntheticName,
|
|
2666
|
-
values: schema.enum.map((v) => ({
|
|
2667
|
-
value: v,
|
|
2668
|
-
description: void 0
|
|
2669
|
-
}))
|
|
2670
|
-
});
|
|
2671
|
-
}
|
|
2672
|
-
return {
|
|
2673
|
-
kind: "enum",
|
|
2674
|
-
name: syntheticName,
|
|
2675
|
-
values: schema.enum
|
|
2676
|
-
};
|
|
2677
|
-
}
|
|
2678
|
-
if (schema.enum) return {
|
|
2679
|
-
kind: "primitive",
|
|
2680
|
-
type: "string"
|
|
2681
|
-
};
|
|
2682
|
-
if (schema.$ref) return {
|
|
2683
|
-
kind: "model",
|
|
2684
|
-
name: schema.$ref.split("/").pop()
|
|
2685
|
-
};
|
|
2686
|
-
let baseType = schema.type;
|
|
2687
|
-
let isNullable = false;
|
|
2688
|
-
if (Array.isArray(baseType)) {
|
|
2689
|
-
const nonNull = baseType.filter((t) => t !== "null");
|
|
2690
|
-
isNullable = baseType.includes("null");
|
|
2691
|
-
baseType = nonNull[0] ?? "string";
|
|
2692
|
-
}
|
|
2693
|
-
let ref;
|
|
2694
|
-
if (baseType === "object" && schema.properties && collector && parentModelName && fName) {
|
|
2695
|
-
const syntheticName = `${parentModelName}_${fName}`;
|
|
2696
|
-
if (!collector.usedNames.has(syntheticName) && !collector.usedNames.has(toSnakeCase(syntheticName))) {
|
|
2697
|
-
collector.usedNames.add(syntheticName);
|
|
2698
|
-
const fields = [];
|
|
2699
|
-
const requiredSet = new Set(schema.required ?? []);
|
|
2700
|
-
for (const [propName, propSchema] of Object.entries(schema.properties)) fields.push({
|
|
2701
|
-
name: propName,
|
|
2702
|
-
type: rawSchemaToTypeRef(propSchema, syntheticName, propName, collector),
|
|
2703
|
-
required: requiredSet.has(propName),
|
|
2704
|
-
description: propSchema.description,
|
|
2705
|
-
deprecated: propSchema.deprecated
|
|
2706
|
-
});
|
|
2707
|
-
collector.models.push({
|
|
2708
|
-
name: syntheticName,
|
|
2709
|
-
fields,
|
|
2710
|
-
description: schema.description
|
|
2711
|
-
});
|
|
2712
|
-
}
|
|
2713
|
-
ref = {
|
|
2714
|
-
kind: "model",
|
|
2715
|
-
name: syntheticName
|
|
2716
|
-
};
|
|
2717
|
-
} else if (baseType === "object" && schema.properties) ref = {
|
|
2718
|
-
kind: "primitive",
|
|
2719
|
-
type: "unknown"
|
|
2720
|
-
};
|
|
2721
|
-
else if (baseType === "array" && schema.items) {
|
|
2722
|
-
const itemFieldName = fName ? singularizeSnake(fName) : void 0;
|
|
2723
|
-
ref = {
|
|
2724
|
-
kind: "array",
|
|
2725
|
-
items: rawSchemaToTypeRef(schema.items, parentModelName, itemFieldName, collector)
|
|
2726
|
-
};
|
|
2727
|
-
} else if (baseType === "boolean") ref = {
|
|
2728
|
-
kind: "primitive",
|
|
2729
|
-
type: "boolean"
|
|
2730
|
-
};
|
|
2731
|
-
else if (baseType === "integer" || baseType === "number") ref = {
|
|
2732
|
-
kind: "primitive",
|
|
2733
|
-
type: baseType
|
|
2734
|
-
};
|
|
2735
|
-
else ref = {
|
|
2736
|
-
kind: "primitive",
|
|
2737
|
-
type: "string"
|
|
2738
|
-
};
|
|
2739
|
-
if (isNullable) return {
|
|
2740
|
-
kind: "nullable",
|
|
2741
|
-
inner: ref
|
|
2742
|
-
};
|
|
2743
|
-
return ref;
|
|
2853
|
+
function buildExportedClassNameSet$4(ctx) {
|
|
2854
|
+
return buildExportedClassNameSet$5(ctx, className$6);
|
|
2744
2855
|
}
|
|
2745
2856
|
/**
|
|
2746
|
-
*
|
|
2747
|
-
*
|
|
2748
|
-
*
|
|
2857
|
+
* Resolve a service's mount-target identifier, appending `Service` on
|
|
2858
|
+
* collision with an exported model/enum class. The result feeds `className`
|
|
2859
|
+
* and `fileName` so both the `export class` declaration and its file name
|
|
2860
|
+
* stay aligned (e.g. `OrganizationMembershipService` /
|
|
2861
|
+
* `organization-membership-service.ts`).
|
|
2749
2862
|
*/
|
|
2750
|
-
function
|
|
2751
|
-
|
|
2752
|
-
const props = schema.properties ?? {};
|
|
2753
|
-
for (const [name, propSchema] of Object.entries(props)) fields.push({
|
|
2754
|
-
name,
|
|
2755
|
-
type: rawSchemaToTypeRef(propSchema, parentModelName, name, collector),
|
|
2756
|
-
required: false,
|
|
2757
|
-
description: propSchema.description,
|
|
2758
|
-
deprecated: propSchema.deprecated
|
|
2759
|
-
});
|
|
2760
|
-
return fields;
|
|
2863
|
+
function resolveServiceTarget$4(target, exportedClasses) {
|
|
2864
|
+
return resolveServiceTarget$5(target, exportedClasses, className$6);
|
|
2761
2865
|
}
|
|
2762
2866
|
/**
|
|
2763
|
-
*
|
|
2764
|
-
* allOf+oneOf compositions. All fields are marked optional.
|
|
2867
|
+
* Build a map from IR service name -> resolved service name.
|
|
2765
2868
|
*/
|
|
2766
|
-
function
|
|
2767
|
-
const
|
|
2768
|
-
const
|
|
2769
|
-
|
|
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;
|
|
2869
|
+
function buildServiceNameMap(services, ctx) {
|
|
2870
|
+
const map = /* @__PURE__ */ new Map();
|
|
2871
|
+
for (const service of services) map.set(service.name, resolveServiceName(service, ctx));
|
|
2872
|
+
return map;
|
|
2782
2873
|
}
|
|
2783
|
-
/**
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2874
|
+
/** Resolve the output directory for a service. */
|
|
2875
|
+
function resolveServiceDir$1(resolvedServiceName) {
|
|
2876
|
+
return serviceDirName(resolvedServiceName);
|
|
2877
|
+
}
|
|
2878
|
+
/** Resolve the SDK method name for an operation, using resolved operations first. */
|
|
2879
|
+
function resolveMethodName$6(op, _service, ctx) {
|
|
2880
|
+
const resolved = lookupMethodName(op, buildResolvedLookup(ctx));
|
|
2881
|
+
if (resolved) return toCamelCase(resolved);
|
|
2882
|
+
const httpKey = `${op.httpMethod.toUpperCase()} ${op.path}`;
|
|
2883
|
+
const existing = ctx.overlayLookup?.methodByOperation?.get(httpKey);
|
|
2884
|
+
if (existing) return existing.methodName;
|
|
2885
|
+
return toCamelCase(op.name);
|
|
2886
|
+
}
|
|
2887
|
+
/** Resolve the SDK class name for a service, using resolved ops mountOn as canonical. */
|
|
2888
|
+
function resolveClassName$5(service, ctx) {
|
|
2889
|
+
for (const r of ctx.resolvedOperations ?? []) if (r.service.name === service.name) return r.mountOn;
|
|
2890
|
+
if (ctx.overlayLookup?.methodByOperation) for (const op of service.operations) {
|
|
2891
|
+
const httpKey = `${op.httpMethod.toUpperCase()} ${op.path}`;
|
|
2892
|
+
const existing = ctx.overlayLookup.methodByOperation.get(httpKey);
|
|
2893
|
+
if (existing) return existing.className;
|
|
2894
|
+
}
|
|
2895
|
+
return toPascalCase(service.name);
|
|
2788
2896
|
}
|
|
2789
2897
|
/**
|
|
2790
|
-
*
|
|
2791
|
-
*
|
|
2792
|
-
*
|
|
2793
|
-
*
|
|
2898
|
+
* Resolve the interface name for a model, checking overlay first.
|
|
2899
|
+
*
|
|
2900
|
+
* Lookup order:
|
|
2901
|
+
* 1. `overlayLookup.interfaceByName` — exact-name overrides from the live SDK.
|
|
2902
|
+
* 2. `overlayLookup.modelNameByIR` — structurally-inferred matches (e.g., IR
|
|
2903
|
+
* `ValidateApiKey` with one field `value: string` → live SDK interface
|
|
2904
|
+
* `ValidateApiKeyOptions`).
|
|
2905
|
+
* 3. Type-alias resolution (when an alias points to an interface).
|
|
2906
|
+
* 4. Suffix-fallback heuristic for the workos-node `*Options` convention:
|
|
2907
|
+
* when the IR name `X` has no baseline match but `XOptions` does, use
|
|
2908
|
+
* `XOptions`. The convention is widely used for request-body interfaces
|
|
2909
|
+
* in workos-node (CreateOrganizationOptions, ListUsersOptions, etc.).
|
|
2910
|
+
* 5. Default — clean and PascalCase the IR name.
|
|
2794
2911
|
*/
|
|
2795
|
-
function
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2912
|
+
function resolveInterfaceName(name, ctx, opts) {
|
|
2913
|
+
const existing = ctx.overlayLookup?.interfaceByName?.get(name);
|
|
2914
|
+
if (existing) return existing;
|
|
2915
|
+
let inferred = adoptedModelNames.has(name) ? void 0 : ctx.overlayLookup?.modelNameByIR?.get(name);
|
|
2916
|
+
if (inferred) {
|
|
2917
|
+
if (inferred.startsWith("Serialized")) {
|
|
2918
|
+
const stripped = inferred.slice(10);
|
|
2919
|
+
if (stripped && ctx.apiSurface?.interfaces?.[stripped]) inferred = stripped;
|
|
2920
|
+
}
|
|
2921
|
+
if (inferred.endsWith("Response") && ctx.apiSurface?.interfaces) {
|
|
2922
|
+
const stripped = inferred.slice(0, -8);
|
|
2923
|
+
if (stripped && ctx.apiSurface.interfaces[stripped]) inferred = stripped;
|
|
2924
|
+
}
|
|
2925
|
+
return inferred;
|
|
2802
2926
|
}
|
|
2803
|
-
if (!
|
|
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;
|
|
2927
|
+
if (!opts?.skipTypeAlias && ctx.apiSurface?.typeAliases) {
|
|
2928
|
+
const alias = ctx.apiSurface.typeAliases[name];
|
|
2929
|
+
if (alias?.value && ctx.apiSurface.interfaces?.[alias.value]) return alias.value;
|
|
2810
2930
|
}
|
|
2811
|
-
if (
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
} : newArrayRef;
|
|
2824
|
-
return {
|
|
2825
|
-
...field,
|
|
2826
|
-
type: newType
|
|
2827
|
-
};
|
|
2931
|
+
if (ctx.apiSurface?.interfaces) {
|
|
2932
|
+
const ifaces = ctx.apiSurface.interfaces;
|
|
2933
|
+
if (!ifaces[name]) {
|
|
2934
|
+
const optionsCandidate = `${name}Options`;
|
|
2935
|
+
const optionsInfo = ifaces[optionsCandidate];
|
|
2936
|
+
if (optionsInfo?.sourceFile) {
|
|
2937
|
+
const expectedStem = toKebabCase(stripUrnPrefix(name));
|
|
2938
|
+
if (optionsInfo.sourceFile.endsWith(`/${expectedStem}.interface.ts`)) return optionsCandidate;
|
|
2939
|
+
}
|
|
2940
|
+
}
|
|
2941
|
+
}
|
|
2942
|
+
return toPascalCase(stripUrnPrefix(ctx.apiSurface ? name : stripNoiseSuffixes(name)));
|
|
2828
2943
|
}
|
|
2829
|
-
|
|
2944
|
+
//#endregion
|
|
2945
|
+
//#region src/node/type-map.ts
|
|
2830
2946
|
/**
|
|
2831
|
-
*
|
|
2832
|
-
*
|
|
2833
|
-
*
|
|
2947
|
+
* Map of enum name → inlined string-union TS source.
|
|
2948
|
+
*
|
|
2949
|
+
* Set by `index.ts` once per generation run, sourced from `spec.enums` for
|
|
2950
|
+
* enums that have no baseline definition in the live SDK. When populated,
|
|
2951
|
+
* `mapTypeRef`/`mapWireTypeRef` substitute the union directly at the
|
|
2952
|
+
* reference site instead of emitting a separate import — this collapses
|
|
2953
|
+
* ~100 single-line enum files into inline literal types.
|
|
2834
2954
|
*/
|
|
2835
|
-
|
|
2836
|
-
|
|
2955
|
+
let inlineEnumUnions = /* @__PURE__ */ new Map();
|
|
2956
|
+
function setInlineEnumUnions(map) {
|
|
2957
|
+
inlineEnumUnions = map;
|
|
2837
2958
|
}
|
|
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;
|
|
2959
|
+
function isInlineEnum(name) {
|
|
2960
|
+
return inlineEnumUnions.has(name);
|
|
2849
2961
|
}
|
|
2850
2962
|
/**
|
|
2851
|
-
*
|
|
2852
|
-
*
|
|
2853
|
-
*
|
|
2963
|
+
* Optional callback that resolves an IR model name to its live-SDK interface
|
|
2964
|
+
* name. Set by `index.ts` once per run. When present, `mapTypeRef` and
|
|
2965
|
+
* `mapWireTypeRef` use it instead of the raw IR name in their `model:` cases
|
|
2966
|
+
* — keeping field-type references in sync with import statements that the
|
|
2967
|
+
* caller emits via the same resolver. Without this, a structural match like
|
|
2968
|
+
* IR `AuditLogSchemaJson` → live `AuditLogSchemaResponse` would produce
|
|
2969
|
+
* `schema: AuditLogSchemaJson` in the body but
|
|
2970
|
+
* `import type { AuditLogSchemaResponse }` in the imports, leaving
|
|
2971
|
+
* `AuditLogSchemaJson` unbound.
|
|
2854
2972
|
*/
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
if (variantModel) mapping[String(constValue)] = variantModel.name;
|
|
2862
|
-
}
|
|
2863
|
-
return mapping;
|
|
2973
|
+
let domainNameResolver = null;
|
|
2974
|
+
function setDomainNameResolver(fn) {
|
|
2975
|
+
domainNameResolver = fn;
|
|
2976
|
+
}
|
|
2977
|
+
function resolveDomainName(irName) {
|
|
2978
|
+
return domainNameResolver ? domainNameResolver(irName) : irName;
|
|
2864
2979
|
}
|
|
2865
2980
|
/**
|
|
2866
|
-
*
|
|
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).
|
|
2981
|
+
* Map an IR TypeRef to a TypeScript domain type string.
|
|
2982
|
+
* Domain types use PascalCase model names (e.g., `Organization`).
|
|
2871
2983
|
*/
|
|
2872
|
-
function
|
|
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
|
-
};
|
|
2984
|
+
function mapTypeRef$7(ref, opts) {
|
|
2985
|
+
const genericDefaults = opts?.genericDefaults;
|
|
2986
|
+
return mapTypeRef(ref, {
|
|
2987
|
+
primitive: mapPrimitive$6,
|
|
2988
|
+
array: (_r, items) => `${parenthesizeUnion(items)}[]`,
|
|
2989
|
+
model: (r) => resolveDomainName(r.name) + (genericDefaults?.get(r.name) ?? ""),
|
|
2990
|
+
enum: (r) => inlineEnumUnions.get(r.name) ?? r.name,
|
|
2991
|
+
union: (r, variants) => joinUnionVariants$5(r, variants),
|
|
2992
|
+
nullable: (_r, inner) => `${inner} | null`,
|
|
2993
|
+
literal: (r) => typeof r.value === "string" ? `'${r.value}'` : String(r.value),
|
|
2994
|
+
map: (_r, value) => `Record<string, ${value}>`
|
|
2894
2995
|
});
|
|
2895
|
-
return changed ? result : models;
|
|
2896
2996
|
}
|
|
2897
2997
|
/**
|
|
2898
|
-
*
|
|
2899
|
-
*
|
|
2900
|
-
* For models with 0 fields whose raw spec schema is a pure oneOf:
|
|
2901
|
-
* - Collect all variant fields and add them as optional fields.
|
|
2902
|
-
*
|
|
2903
|
-
* For models whose raw spec schema has allOf containing a oneOf:
|
|
2904
|
-
* - Collect the missing variant fields and add them as optional.
|
|
2905
|
-
*
|
|
2906
|
-
* Inline objects and enums in oneOf branches are promoted to synthetic
|
|
2907
|
-
* models/enums instead of degrading to `object` / `string`.
|
|
2908
|
-
*
|
|
2909
|
-
* Returns a new array of enriched models (original models are not mutated).
|
|
2910
|
-
* Synthetic enums are stored internally; retrieve them via `getSyntheticEnums()`.
|
|
2998
|
+
* Map an IR TypeRef to a TypeScript wire/response type string.
|
|
2999
|
+
* Model references get the `Response` suffix (e.g., `OrganizationResponse`).
|
|
2911
3000
|
*/
|
|
2912
|
-
function
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
3001
|
+
function mapWireTypeRef(ref, opts) {
|
|
3002
|
+
const genericDefaults = opts?.genericDefaults;
|
|
3003
|
+
return mapTypeRef(ref, {
|
|
3004
|
+
primitive: mapWirePrimitive,
|
|
3005
|
+
array: (_r, items) => `${parenthesizeUnion(items)}[]`,
|
|
3006
|
+
model: (r) => wireInterfaceName(resolveDomainName(r.name)) + (genericDefaults?.get(r.name) ?? ""),
|
|
3007
|
+
enum: (r) => inlineEnumUnions.get(r.name) ?? r.name,
|
|
3008
|
+
union: (r, variants) => joinUnionVariants$5(r, variants),
|
|
3009
|
+
nullable: (_r, inner) => `${inner} | null`,
|
|
3010
|
+
literal: (r) => typeof r.value === "string" ? `'${r.value}'` : String(r.value),
|
|
3011
|
+
map: (_r, value) => `Record<string, ${value}>`
|
|
3012
|
+
});
|
|
3013
|
+
}
|
|
3014
|
+
function mapPrimitive$6(ref) {
|
|
3015
|
+
if (ref.format) switch (ref.format) {
|
|
3016
|
+
case "date-time": return "Date";
|
|
3017
|
+
case "int64": return "bigint";
|
|
2916
3018
|
}
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
3019
|
+
switch (ref.type) {
|
|
3020
|
+
case "string": return "string";
|
|
3021
|
+
case "integer":
|
|
3022
|
+
case "number": return "number";
|
|
3023
|
+
case "boolean": return "boolean";
|
|
3024
|
+
case "unknown": return "any";
|
|
2921
3025
|
}
|
|
2922
|
-
|
|
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];
|
|
3026
|
+
}
|
|
3027
|
+
function mapWirePrimitive(ref) {
|
|
3028
|
+
switch (ref.type) {
|
|
3029
|
+
case "string": return "string";
|
|
3030
|
+
case "integer":
|
|
3031
|
+
case "number": return "number";
|
|
3032
|
+
case "boolean": return "boolean";
|
|
3033
|
+
case "unknown": return "any";
|
|
3034
|
+
}
|
|
3035
|
+
}
|
|
3036
|
+
function joinUnionVariants$5(ref, variants) {
|
|
3037
|
+
const unique = [...new Set(variants)];
|
|
3038
|
+
if (ref.compositionKind === "allOf") return unique.join(" & ");
|
|
3039
|
+
if (unique.length === 1) return unique[0];
|
|
3040
|
+
return unique.join(" | ");
|
|
3041
|
+
}
|
|
3042
|
+
function parenthesizeUnion(type) {
|
|
3043
|
+
return type.includes(" | ") || type.includes(" & ") ? `(${type})` : type;
|
|
2975
3044
|
}
|
|
2976
3045
|
//#endregion
|
|
2977
3046
|
//#region src/node/utils.ts
|
|
@@ -4073,6 +4142,7 @@ function buildSerializerImports(model, serializerPath, dirName, domainName, resp
|
|
|
4073
4142
|
const rel = relativeImport(serializerPath, depSerializerPath);
|
|
4074
4143
|
const canon = sctx.dedup.get(dep);
|
|
4075
4144
|
const depSkipSerialize = sctx.skippedSerializeModels.has(dep) || canon != null && sctx.skippedSerializeModels.has(canon);
|
|
4145
|
+
const depSkipDeserialize = sctx.responseReachableModels !== void 0 && !sctx.responseReachableModels.has(dep) && (canon == null || !sctx.responseReachableModels.has(canon));
|
|
4076
4146
|
const hasDeser = liveSurfaceHasFunction(`deserialize${depName}`);
|
|
4077
4147
|
const hasSer = liveSurfaceHasFunction(`serialize${depName}`);
|
|
4078
4148
|
const fileExists = liveSurfaceHasFile(depSerializerPath);
|
|
@@ -4093,7 +4163,9 @@ function buildSerializerImports(model, serializerPath, dirName, domainName, resp
|
|
|
4093
4163
|
lines.push(`import { serialize${depName} } from '${rel}';`);
|
|
4094
4164
|
continue;
|
|
4095
4165
|
}
|
|
4166
|
+
if (depSkipSerialize && depSkipDeserialize) continue;
|
|
4096
4167
|
if (depSkipSerialize) lines.push(`import { deserialize${depName} } from '${rel}';`);
|
|
4168
|
+
else if (depSkipDeserialize) lines.push(`import { serialize${depName} } from '${rel}';`);
|
|
4097
4169
|
else lines.push(`import { deserialize${depName}, serialize${depName} } from '${rel}';`);
|
|
4098
4170
|
}
|
|
4099
4171
|
lines.push("");
|
|
@@ -4129,24 +4201,26 @@ function shouldSkipSerializeForModel(model, baselineResponse, baselineDomain, de
|
|
|
4129
4201
|
}
|
|
4130
4202
|
return shouldSkip;
|
|
4131
4203
|
}
|
|
4132
|
-
function emitSerializerBody(model, domainName, responseName, typeParams, baselineDomain, baselineResponse, skipFormatFields, shouldSkipSerialize, ctx) {
|
|
4204
|
+
function emitSerializerBody(model, domainName, responseName, typeParams, baselineDomain, baselineResponse, skipFormatFields, shouldSkipSerialize, shouldSkipDeserialize, ctx) {
|
|
4133
4205
|
const lines = [];
|
|
4134
|
-
|
|
4135
|
-
|
|
4136
|
-
|
|
4137
|
-
|
|
4138
|
-
|
|
4139
|
-
|
|
4140
|
-
const
|
|
4141
|
-
|
|
4142
|
-
|
|
4143
|
-
|
|
4144
|
-
|
|
4206
|
+
if (!shouldSkipDeserialize) {
|
|
4207
|
+
const seenDeserFields = /* @__PURE__ */ new Set();
|
|
4208
|
+
const deserParamPrefix = model.fields.length === 0 ? "_" : "";
|
|
4209
|
+
lines.push(`export const deserialize${domainName} = ${typeParams.decl}(`);
|
|
4210
|
+
lines.push(` ${deserParamPrefix}response: ${responseName}${typeParams.usage},`);
|
|
4211
|
+
lines.push(`): ${domainName}${typeParams.usage} => ({`);
|
|
4212
|
+
for (const field of model.fields) {
|
|
4213
|
+
const domain = fieldName$6(field.name);
|
|
4214
|
+
if (seenDeserFields.has(domain)) continue;
|
|
4215
|
+
seenDeserFields.add(domain);
|
|
4216
|
+
const plan = planDeserializeField(field, baselineDomain, baselineResponse, skipFormatFields, ctx);
|
|
4217
|
+
if (!plan.skip) lines.push(plan.line);
|
|
4218
|
+
}
|
|
4219
|
+
lines.push("});");
|
|
4145
4220
|
}
|
|
4146
|
-
lines.push("});");
|
|
4147
4221
|
if (!shouldSkipSerialize) {
|
|
4222
|
+
if (!shouldSkipDeserialize) lines.push("");
|
|
4148
4223
|
const serParamPrefix = model.fields.length === 0 ? "_" : "";
|
|
4149
|
-
lines.push("");
|
|
4150
4224
|
lines.push(`export const serialize${domainName} = ${typeParams.decl}(`);
|
|
4151
4225
|
lines.push(` ${serParamPrefix}model: ${domainName}${typeParams.usage},`);
|
|
4152
4226
|
lines.push(`): ${responseName}${typeParams.usage} => ({`);
|
|
@@ -4458,15 +4532,19 @@ function hasCompatibleConstructor(className, ctx) {
|
|
|
4458
4532
|
*/
|
|
4459
4533
|
function resolveResourceClassName$3(service, ctx) {
|
|
4460
4534
|
const overlayName = resolveServiceName(service, ctx);
|
|
4461
|
-
|
|
4462
|
-
|
|
4463
|
-
|
|
4464
|
-
|
|
4535
|
+
let base;
|
|
4536
|
+
if (hasCompatibleConstructor(overlayName, ctx)) base = overlayName;
|
|
4537
|
+
else {
|
|
4538
|
+
const irName = toPascalCase(service.name);
|
|
4539
|
+
base = irName === overlayName ? `${irName}Endpoints` : irName;
|
|
4540
|
+
}
|
|
4541
|
+
return resolveServiceTarget$4(base, buildExportedClassNameSet$4(ctx));
|
|
4465
4542
|
}
|
|
4466
4543
|
function resolveResourceDir(service, ctx) {
|
|
4467
4544
|
const resolvedName = resolveResourceClassName$3(service, ctx);
|
|
4468
4545
|
if (resolvedName === "WebhooksEndpoints") return "webhooks";
|
|
4469
|
-
|
|
4546
|
+
const overlayName = resolveServiceName(service, ctx);
|
|
4547
|
+
return resolveServiceDir$1(resolvedName === `${overlayName}Service` ? overlayName : resolvedName);
|
|
4470
4548
|
}
|
|
4471
4549
|
/** Standard pagination query params handled by PaginationOptions — not imported individually. */
|
|
4472
4550
|
const PAGINATION_PARAM_NAMES = new Set([
|
|
@@ -6217,6 +6295,7 @@ function generateSerializers(models, ctx, shared) {
|
|
|
6217
6295
|
const projectedByName = new Map(projectedModels.map((model) => [model.name, model]));
|
|
6218
6296
|
const resourceUsage = buildGeneratedResourceModelUsage(models, ctx);
|
|
6219
6297
|
const serializerEligibleModels = resourceUsage ? expandModelRoots(resourceUsage.serializerRoots, projectedByName) : void 0;
|
|
6298
|
+
const responseReachableModels = resourceUsage ? expandModelRoots(resourceUsage.responseRoots, projectedByName) : void 0;
|
|
6220
6299
|
const serializerReachable = computeNonEventReachable(ctx.spec.services, models);
|
|
6221
6300
|
const liveRoot = ctx.targetDir ?? ctx.outputDir;
|
|
6222
6301
|
if (liveRoot) for (const originalModel of models) {
|
|
@@ -6280,7 +6359,13 @@ function generateSerializers(models, ctx, shared) {
|
|
|
6280
6359
|
if (serializerPath === canonSerializerPath) continue;
|
|
6281
6360
|
if (domainName === canonDomainName) continue;
|
|
6282
6361
|
const rel = relativeImport(serializerPath, canonSerializerPath);
|
|
6283
|
-
const
|
|
6362
|
+
const canonSkipSerialize = skippedSerializeModels.has(canonicalName) || skippedSerializeModels.has(model.name);
|
|
6363
|
+
const canonSkipDeserialize = responseReachableModels !== void 0 && !responseReachableModels.has(canonicalName) && !responseReachableModels.has(model.name);
|
|
6364
|
+
if (canonSkipSerialize && canonSkipDeserialize) continue;
|
|
6365
|
+
const parts = [];
|
|
6366
|
+
if (!canonSkipDeserialize) parts.push(`deserialize${canonDomainName} as deserialize${domainName}`);
|
|
6367
|
+
if (!canonSkipSerialize) parts.push(`serialize${canonDomainName} as serialize${domainName}`);
|
|
6368
|
+
const reexportContent = `export { ${parts.join(", ")} } from '${rel}';`;
|
|
6284
6369
|
files.push({
|
|
6285
6370
|
path: serializerPath,
|
|
6286
6371
|
content: reexportContent,
|
|
@@ -6298,13 +6383,16 @@ function generateSerializers(models, ctx, shared) {
|
|
|
6298
6383
|
const baselineDomain = ctx.apiSurface?.interfaces?.[domainName];
|
|
6299
6384
|
const skipFormatFields = buildSkipFormatFields(model, baselineDomain);
|
|
6300
6385
|
const shouldSkipSerialize = skippedSerializeModels.has(model.name);
|
|
6386
|
+
const shouldSkipDeserialize = responseReachableModels !== void 0 && !responseReachableModels.has(model.name);
|
|
6387
|
+
if (shouldSkipSerialize && shouldSkipDeserialize) continue;
|
|
6301
6388
|
const lines = [...buildSerializerImports(model, serializerPath, dirName, domainName, responseName, {
|
|
6302
6389
|
modelToService,
|
|
6303
6390
|
resolveDir,
|
|
6304
6391
|
dedup,
|
|
6305
6392
|
skippedSerializeModels,
|
|
6393
|
+
responseReachableModels,
|
|
6306
6394
|
ctx
|
|
6307
|
-
}), ...emitSerializerBody(model, domainName, responseName, typeParams, baselineDomain, baselineResponse, skipFormatFields, shouldSkipSerialize, ctx)];
|
|
6395
|
+
}), ...emitSerializerBody(model, domainName, responseName, typeParams, baselineDomain, baselineResponse, skipFormatFields, shouldSkipSerialize, shouldSkipDeserialize, ctx)];
|
|
6308
6396
|
files.push({
|
|
6309
6397
|
path: serializerPath,
|
|
6310
6398
|
content: pruneUnusedImports(lines).join("\n"),
|
|
@@ -6312,6 +6400,7 @@ function generateSerializers(models, ctx, shared) {
|
|
|
6312
6400
|
});
|
|
6313
6401
|
}
|
|
6314
6402
|
ctx._skippedSerializeModels = skippedSerializeModels;
|
|
6403
|
+
ctx._responseReachableModels = responseReachableModels;
|
|
6315
6404
|
const serializersByDir = /* @__PURE__ */ new Map();
|
|
6316
6405
|
for (const f of files) {
|
|
6317
6406
|
const match = f.path.match(/^src\/([^/]+)\/serializers\/(.+)\.serializer\.ts$/);
|
|
@@ -6357,6 +6446,8 @@ function buildGeneratedResourceModelUsage(models, ctx) {
|
|
|
6357
6446
|
const modelMap = new Map(models.map((model) => [model.name, model]));
|
|
6358
6447
|
const interfaceRoots = /* @__PURE__ */ new Set();
|
|
6359
6448
|
const serializerRoots = /* @__PURE__ */ new Set();
|
|
6449
|
+
const requestRoots = /* @__PURE__ */ new Set();
|
|
6450
|
+
const responseRoots = /* @__PURE__ */ new Set();
|
|
6360
6451
|
const resolvedLookup = buildResolvedLookup(ctx);
|
|
6361
6452
|
const mountGroups = groupByMount(ctx);
|
|
6362
6453
|
const services = mountGroups.size > 0 ? [...mountGroups].map(([name, group]) => ({
|
|
@@ -6385,15 +6476,18 @@ function buildGeneratedResourceModelUsage(models, ctx) {
|
|
|
6385
6476
|
if (unwrapped) itemName = unwrapped.name;
|
|
6386
6477
|
interfaceRoots.add(itemName);
|
|
6387
6478
|
serializerRoots.add(itemName);
|
|
6479
|
+
responseRoots.add(itemName);
|
|
6388
6480
|
}
|
|
6389
6481
|
} else if (plan.responseModelName) {
|
|
6390
6482
|
interfaceRoots.add(plan.responseModelName);
|
|
6391
6483
|
serializerRoots.add(plan.responseModelName);
|
|
6484
|
+
responseRoots.add(plan.responseModelName);
|
|
6392
6485
|
}
|
|
6393
6486
|
const bodyInfo = extractRequestBodyModels(op, ctx);
|
|
6394
6487
|
for (const name of bodyInfo) {
|
|
6395
6488
|
interfaceRoots.add(name);
|
|
6396
6489
|
serializerRoots.add(name);
|
|
6490
|
+
requestRoots.add(name);
|
|
6397
6491
|
}
|
|
6398
6492
|
for (const param of [
|
|
6399
6493
|
...op.pathParams,
|
|
@@ -6405,6 +6499,7 @@ function buildGeneratedResourceModelUsage(models, ctx) {
|
|
|
6405
6499
|
for (const name of collectWrapperResponseModels$1(resolved)) {
|
|
6406
6500
|
interfaceRoots.add(name);
|
|
6407
6501
|
serializerRoots.add(name);
|
|
6502
|
+
responseRoots.add(name);
|
|
6408
6503
|
}
|
|
6409
6504
|
for (const wrapper of resolved.wrappers ?? []) for (const { field } of resolveWrapperParams(wrapper, ctx)) if (field) collectTypeRefModels(field.type, interfaceRoots);
|
|
6410
6505
|
}
|
|
@@ -6412,7 +6507,9 @@ function buildGeneratedResourceModelUsage(models, ctx) {
|
|
|
6412
6507
|
}
|
|
6413
6508
|
return {
|
|
6414
6509
|
interfaceRoots,
|
|
6415
|
-
serializerRoots
|
|
6510
|
+
serializerRoots,
|
|
6511
|
+
requestRoots,
|
|
6512
|
+
responseRoots
|
|
6416
6513
|
};
|
|
6417
6514
|
}
|
|
6418
6515
|
function extractRequestBodyModels(op, ctx) {
|
|
@@ -6538,7 +6635,7 @@ function generateWorkOSClient$1(spec, ctx) {
|
|
|
6538
6635
|
for (const service of spec.services) {
|
|
6539
6636
|
if (coveredServices.has(service.name)) continue;
|
|
6540
6637
|
const resolvedName = resolveResourceClassName$3(service, ctx);
|
|
6541
|
-
const propName = servicePropertyName$4(
|
|
6638
|
+
const propName = servicePropertyName$4(resolveServiceName(service, ctx));
|
|
6542
6639
|
if (existingProps.has(propName)) continue;
|
|
6543
6640
|
const classDeprecation = ctx.apiSurface?.classes?.[resolvedName]?.deprecationMessage;
|
|
6544
6641
|
if (classDeprecation !== void 0) {
|
|
@@ -6964,7 +7061,7 @@ function generateServiceTest$3(service, spec, ctx, modelMap, mountAccessors) {
|
|
|
6964
7061
|
const resolvedName = resolveResourceClassName$3(service, ctx);
|
|
6965
7062
|
const serviceDir = resolveResourceDir(service, ctx);
|
|
6966
7063
|
const serviceClass = resolvedName;
|
|
6967
|
-
const serviceProp = mountAccessors?.get(service.name) ?? servicePropertyName$4(
|
|
7064
|
+
const serviceProp = mountAccessors?.get(service.name) ?? servicePropertyName$4(resolveServiceName(service, ctx));
|
|
6968
7065
|
const testPath = `src/${serviceDir}/${fileName$3(resolvedName)}.spec.ts`;
|
|
6969
7066
|
const plans = service.operations.map((op) => ({
|
|
6970
7067
|
op,
|
|
@@ -7393,12 +7490,20 @@ function buildTestPayload(op, modelMap) {
|
|
|
7393
7490
|
model = modelMap.get(firstVariant.name);
|
|
7394
7491
|
} else if (op.requestBody.kind === "model") model = modelMap.get(op.requestBody.name);
|
|
7395
7492
|
if (!model) return null;
|
|
7396
|
-
const
|
|
7397
|
-
const
|
|
7398
|
-
|
|
7493
|
+
const requiredFields = model.fields.filter((f) => f.required);
|
|
7494
|
+
const usableRequired = requiredFields.filter((f) => fixtureValueForType(f.type, f.name, model.name, modelMap) !== null);
|
|
7495
|
+
let chosenFields;
|
|
7496
|
+
if (requiredFields.length > 0) {
|
|
7497
|
+
if (usableRequired.length < requiredFields.length) return null;
|
|
7498
|
+
chosenFields = usableRequired;
|
|
7499
|
+
} else {
|
|
7500
|
+
const usableOptional = model.fields.filter((f) => !f.required && fixtureValueForType(f.type, f.name, model.name, modelMap) !== null);
|
|
7501
|
+
if (usableOptional.length === 0) return null;
|
|
7502
|
+
chosenFields = usableOptional.slice(0, 2);
|
|
7503
|
+
}
|
|
7399
7504
|
const camelEntries = [];
|
|
7400
7505
|
const snakeEntries = [];
|
|
7401
|
-
for (const field of
|
|
7506
|
+
for (const field of chosenFields) {
|
|
7402
7507
|
const camelValue = fixtureValueForType(field.type, field.name, model.name, modelMap);
|
|
7403
7508
|
const wireValue = fixtureValueForType(field.type, field.name, model.name, modelMap, true);
|
|
7404
7509
|
const camelKey = fieldName$6(field.name);
|
|
@@ -7458,6 +7563,7 @@ function generateSerializerTests(spec, ctx) {
|
|
|
7458
7563
|
});
|
|
7459
7564
|
if (eligibleModels.length === 0) return files;
|
|
7460
7565
|
const serializeSkipped = ctx._skippedSerializeModels ?? /* @__PURE__ */ new Set();
|
|
7566
|
+
const responseReachableModels = ctx._responseReachableModels;
|
|
7461
7567
|
const modelsByDir = /* @__PURE__ */ new Map();
|
|
7462
7568
|
for (const model of eligibleModels) {
|
|
7463
7569
|
const dirName = resolveDir(modelToService.get(model.name));
|
|
@@ -7472,15 +7578,20 @@ function generateSerializerTests(spec, ctx) {
|
|
|
7472
7578
|
const interfaceImports = [];
|
|
7473
7579
|
const fixtureImports = [];
|
|
7474
7580
|
const deserializeOnlyModels = /* @__PURE__ */ new Set();
|
|
7581
|
+
const serializeOnlyModels = /* @__PURE__ */ new Set();
|
|
7475
7582
|
for (const model of models) {
|
|
7476
7583
|
const domainName = resolveInterfaceName(model.name, ctx);
|
|
7477
7584
|
const modelDir = resolveDir(modelToService.get(model.name));
|
|
7478
7585
|
const serializerPath = `src/${modelDir}/serializers/${fileName$3(model.name)}.serializer.ts`;
|
|
7479
7586
|
const interfacePath = `src/${modelDir}/interfaces/${fileName$3(model.name)}.interface.ts`;
|
|
7480
7587
|
const fixturePath = `src/${modelDir}/fixtures/${fileName$3(model.name)}.json`;
|
|
7481
|
-
const
|
|
7588
|
+
const isRequestOnly = responseReachableModels !== void 0 && !responseReachableModels.has(model.name);
|
|
7589
|
+
const deserializeOnly = !isRequestOnly && (serializeSkipped.has(model.name) || fixtureIsHandOwned(fixturePath, ctx));
|
|
7590
|
+
const serializeOnly = isRequestOnly;
|
|
7482
7591
|
if (deserializeOnly) deserializeOnlyModels.add(model.name);
|
|
7592
|
+
if (serializeOnly) serializeOnlyModels.add(model.name);
|
|
7483
7593
|
if (deserializeOnly) serializerImports.push(`import { deserialize${domainName} } from '${relativeImport(testPath, serializerPath)}';`);
|
|
7594
|
+
else if (serializeOnly) serializerImports.push(`import { serialize${domainName} } from '${relativeImport(testPath, serializerPath)}';`);
|
|
7484
7595
|
else serializerImports.push(`import { deserialize${domainName}, serialize${domainName} } from '${relativeImport(testPath, serializerPath)}';`);
|
|
7485
7596
|
const wireName = wireInterfaceName(domainName);
|
|
7486
7597
|
interfaceImports.push(`import type { ${wireName} } from '${relativeImport(testPath, interfacePath)}';`);
|
|
@@ -7503,6 +7614,14 @@ function generateSerializerTests(spec, ctx) {
|
|
|
7503
7614
|
lines.push(" expect(deserialized).toBeDefined();");
|
|
7504
7615
|
lines.push(" });");
|
|
7505
7616
|
lines.push("});");
|
|
7617
|
+
} else if (serializeOnlyModels.has(model.name)) {
|
|
7618
|
+
lines.push(`describe('${domainName}Serializer', () => {`);
|
|
7619
|
+
lines.push(" it('serializes correctly', () => {");
|
|
7620
|
+
lines.push(` const fixture = ${fixtureName} as ${wireName};`);
|
|
7621
|
+
lines.push(` const serialized = serialize${domainName}(fixture as any);`);
|
|
7622
|
+
lines.push(" expect(serialized).toBeDefined();");
|
|
7623
|
+
lines.push(" });");
|
|
7624
|
+
lines.push("});");
|
|
7506
7625
|
} else {
|
|
7507
7626
|
lines.push(`describe('${domainName}Serializer', () => {`);
|
|
7508
7627
|
lines.push(" it('round-trips through serialize/deserialize', () => {");
|
|
@@ -7906,6 +8025,25 @@ function resolveMethodName$5(op, _service, ctx) {
|
|
|
7906
8025
|
if (existing) return toSnakeCase(existing.methodName);
|
|
7907
8026
|
return toSnakeCase(op.name);
|
|
7908
8027
|
}
|
|
8028
|
+
/**
|
|
8029
|
+
* Build the set of model + enum class names exported by the SDK. Used to
|
|
8030
|
+
* detect collisions with operation-client class names — a colliding service
|
|
8031
|
+
* gets a `Service` suffix appended.
|
|
8032
|
+
*/
|
|
8033
|
+
function buildExportedClassNameSet$3(ctx) {
|
|
8034
|
+
return buildExportedClassNameSet$5(ctx, className$5);
|
|
8035
|
+
}
|
|
8036
|
+
/**
|
|
8037
|
+
* Resolve a service's mount-target identifier, appending `Service` on
|
|
8038
|
+
* collision with an exported model/enum class. Feeds `className`/`fileName`
|
|
8039
|
+
* so the class declaration, file, and any qualified references stay aligned.
|
|
8040
|
+
*
|
|
8041
|
+
* Accessor names (`servicePropertyName`) intentionally use the RAW target —
|
|
8042
|
+
* `client.organization_membership` reads better than the suffixed form.
|
|
8043
|
+
*/
|
|
8044
|
+
function resolveServiceTarget$3(target, exportedClasses) {
|
|
8045
|
+
return resolveServiceTarget$5(target, exportedClasses, className$5);
|
|
8046
|
+
}
|
|
7909
8047
|
/** Resolve the SDK class name for a service, using resolved operations' mountOn. */
|
|
7910
8048
|
function resolveClassName$4(service, ctx) {
|
|
7911
8049
|
for (const r of ctx.resolvedOperations ?? []) if (r.service.name === service.name) return r.mountOn;
|
|
@@ -9955,10 +10093,11 @@ function generateResources$6(services, ctx) {
|
|
|
9955
10093
|
name: resolveClassName$4(s, ctx),
|
|
9956
10094
|
operations: s.operations
|
|
9957
10095
|
}));
|
|
10096
|
+
const exportedClasses = buildExportedClassNameSet$3(ctx);
|
|
9958
10097
|
for (const { name: mountName, operations: allOperations } of entries) {
|
|
9959
10098
|
if (allOperations.length === 0) continue;
|
|
9960
10099
|
const dirName = moduleName$2(mountName);
|
|
9961
|
-
const resourceClassName = className$5(mountName);
|
|
10100
|
+
const resourceClassName = className$5(resolveServiceTarget$3(mountName, exportedClasses));
|
|
9962
10101
|
const importPrefix = relativeImportPrefix(dirName);
|
|
9963
10102
|
const lines = [];
|
|
9964
10103
|
lines.push("from __future__ import annotations");
|
|
@@ -10404,9 +10543,10 @@ function generateWorkOSClient(spec, ctx) {
|
|
|
10404
10543
|
lines.push(" AsyncWorkOSClient as _AsyncBase,");
|
|
10405
10544
|
lines.push(")");
|
|
10406
10545
|
const serviceDirMap = buildMountDirMap$1(ctx);
|
|
10546
|
+
const exportedClasses = buildExportedClassNameSet$3(ctx);
|
|
10407
10547
|
for (const service of topLevelServices) {
|
|
10408
10548
|
const resolvedName = resolveResourceClassName$2(service, ctx);
|
|
10409
|
-
const clsName = className$5(resolvedName);
|
|
10549
|
+
const clsName = className$5(resolveServiceTarget$3(resolvedName, exportedClasses));
|
|
10410
10550
|
const dirName = serviceDirMap.get(service.name) ?? resolveServiceDir(resolvedName);
|
|
10411
10551
|
const importLine = `from .${dirToModule(dirName)}._resource import ${clsName}, Async${clsName}`;
|
|
10412
10552
|
if (importLine.length > 88) {
|
|
@@ -10427,7 +10567,7 @@ function generateWorkOSClient(spec, ctx) {
|
|
|
10427
10567
|
const generatedProps = /* @__PURE__ */ new Set();
|
|
10428
10568
|
for (const service of topLevelServices) {
|
|
10429
10569
|
const resolvedName = resolveResourceClassName$2(service, ctx);
|
|
10430
|
-
const clsName = className$5(resolvedName);
|
|
10570
|
+
const clsName = className$5(resolveServiceTarget$3(resolvedName, exportedClasses));
|
|
10431
10571
|
const prop = servicePropertyName$3(resolvedName);
|
|
10432
10572
|
const readable = clsName.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2");
|
|
10433
10573
|
lines.push("");
|
|
@@ -10446,7 +10586,7 @@ function generateWorkOSClient(spec, ctx) {
|
|
|
10446
10586
|
const asyncGeneratedProps = /* @__PURE__ */ new Set();
|
|
10447
10587
|
for (const service of topLevelServices) {
|
|
10448
10588
|
const resolvedName = resolveResourceClassName$2(service, ctx);
|
|
10449
|
-
const clsName = className$5(resolvedName);
|
|
10589
|
+
const clsName = className$5(resolveServiceTarget$3(resolvedName, exportedClasses));
|
|
10450
10590
|
const prop = servicePropertyName$3(resolvedName);
|
|
10451
10591
|
const readable = clsName.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2");
|
|
10452
10592
|
lines.push("");
|
|
@@ -10485,16 +10625,18 @@ function generateServiceInits(spec, ctx) {
|
|
|
10485
10625
|
const files = [];
|
|
10486
10626
|
const topLevel = deduplicateByMount$4(spec.services, ctx);
|
|
10487
10627
|
const serviceDirMap = buildMountDirMap$1(ctx);
|
|
10628
|
+
const exportedClasses = buildExportedClassNameSet$3(ctx);
|
|
10488
10629
|
const mountGroups = groupByMount(ctx);
|
|
10489
10630
|
for (const service of topLevel) {
|
|
10490
10631
|
const resolvedName = resolveResourceClassName$2(service, ctx);
|
|
10632
|
+
const clsName = className$5(resolveServiceTarget$3(resolvedName, exportedClasses));
|
|
10491
10633
|
const dirName = serviceDirMap.get(service.name) ?? resolveServiceDir(resolvedName);
|
|
10492
10634
|
const lines = [];
|
|
10493
10635
|
const mountTarget = getMountTarget(service, ctx);
|
|
10494
10636
|
const groupClassNames = collectParameterGroupClassNames(mountGroups.get(mountTarget)?.operations ?? service.operations);
|
|
10495
10637
|
const aliasedImports = [
|
|
10496
|
-
|
|
10497
|
-
`Async${
|
|
10638
|
+
clsName,
|
|
10639
|
+
`Async${clsName}`,
|
|
10498
10640
|
...groupClassNames
|
|
10499
10641
|
].map((n) => `${n} as ${n}`);
|
|
10500
10642
|
lines.push(`from ._resource import ${aliasedImports.join(", ")}`);
|
|
@@ -11964,6 +12106,22 @@ function className$4(name) {
|
|
|
11964
12106
|
if (PHP_RESERVED_CLASS_NAMES.has(result)) result += "Model";
|
|
11965
12107
|
return result;
|
|
11966
12108
|
}
|
|
12109
|
+
/**
|
|
12110
|
+
* Build the set of model + enum class names exported by the SDK. Used to
|
|
12111
|
+
* detect collisions with operation-client class names — a colliding service
|
|
12112
|
+
* gets a `Service` suffix appended.
|
|
12113
|
+
*/
|
|
12114
|
+
function buildExportedClassNameSet$2(ctx) {
|
|
12115
|
+
return buildExportedClassNameSet$5(ctx, className$4);
|
|
12116
|
+
}
|
|
12117
|
+
/**
|
|
12118
|
+
* Resolve a service's mount-target identifier, appending `Service` on
|
|
12119
|
+
* collision with an exported model/enum class. Used in `\Service\…` files
|
|
12120
|
+
* to avoid `use WorkOS\Resource\X; class X` PHP fatal errors.
|
|
12121
|
+
*/
|
|
12122
|
+
function resolveServiceTarget$2(target, exportedClasses) {
|
|
12123
|
+
return resolveServiceTarget$5(target, exportedClasses, className$4);
|
|
12124
|
+
}
|
|
11967
12125
|
/** Resolve the SDK method name for an operation, using resolved operations first. */
|
|
11968
12126
|
function resolveMethodName$4(op, _service, ctx) {
|
|
11969
12127
|
const resolved = lookupMethodName(op, buildResolvedLookup(ctx));
|
|
@@ -12496,9 +12654,10 @@ function generateResources$5(services, ctx) {
|
|
|
12496
12654
|
name: className$4(s.name),
|
|
12497
12655
|
operations: s.operations
|
|
12498
12656
|
}));
|
|
12657
|
+
const exportedClasses = buildExportedClassNameSet$2(ctx);
|
|
12499
12658
|
for (const { name: mountName, operations } of entries) {
|
|
12500
12659
|
if (operations.length === 0) continue;
|
|
12501
|
-
const resourceName = className$4(mountName);
|
|
12660
|
+
const resourceName = className$4(resolveServiceTarget$2(mountName, exportedClasses));
|
|
12502
12661
|
const mergedService = {
|
|
12503
12662
|
name: mountName,
|
|
12504
12663
|
operations
|
|
@@ -13034,10 +13193,11 @@ function buildServiceAccessPaths$2(services, ctx) {
|
|
|
13034
13193
|
}
|
|
13035
13194
|
function deduplicateByMount$3(services, ctx) {
|
|
13036
13195
|
const seen = /* @__PURE__ */ new Map();
|
|
13196
|
+
const exportedClasses = buildExportedClassNameSet$2(ctx);
|
|
13037
13197
|
for (const service of services) {
|
|
13038
13198
|
const target = getMountTarget(service, ctx);
|
|
13039
13199
|
if (!seen.has(target)) seen.set(target, {
|
|
13040
|
-
name: className$4(target),
|
|
13200
|
+
name: className$4(resolveServiceTarget$2(target, exportedClasses)),
|
|
13041
13201
|
propName: servicePropertyName$2(target)
|
|
13042
13202
|
});
|
|
13043
13203
|
}
|
|
@@ -18919,6 +19079,33 @@ function packageSegment(name) {
|
|
|
18919
19079
|
function apiClassName(name) {
|
|
18920
19080
|
return className$1(name);
|
|
18921
19081
|
}
|
|
19082
|
+
/**
|
|
19083
|
+
* Resolve the Kotlin service class name with the collision suffix applied
|
|
19084
|
+
* when needed. Wraps `apiClassName` so callers don't need to thread the
|
|
19085
|
+
* exported-classes set through unrelated emission logic.
|
|
19086
|
+
*/
|
|
19087
|
+
function resolveApiClassName(name, exportedClasses) {
|
|
19088
|
+
return apiClassName(resolveServiceTarget$1(name, exportedClasses));
|
|
19089
|
+
}
|
|
19090
|
+
/**
|
|
19091
|
+
* Build the set of model + enum class names exported by the SDK. Used to
|
|
19092
|
+
* detect collisions with operation-client class names — a colliding service
|
|
19093
|
+
* gets a `Service` suffix appended.
|
|
19094
|
+
*/
|
|
19095
|
+
function buildExportedClassNameSet$1(ctx) {
|
|
19096
|
+
return buildExportedClassNameSet$5(ctx, className$1);
|
|
19097
|
+
}
|
|
19098
|
+
/**
|
|
19099
|
+
* Resolve a service's mount-target identifier, appending `Service` on
|
|
19100
|
+
* collision with an exported model/enum class. Kotlin sees the collision
|
|
19101
|
+
* when a service class shares a simple name with an imported model class
|
|
19102
|
+
* (e.g. `com.workos.models.OrganizationMembership` vs
|
|
19103
|
+
* `com.workos.organizationmembership.OrganizationMembership`) — the file's
|
|
19104
|
+
* local declaration shadows the import for unqualified references.
|
|
19105
|
+
*/
|
|
19106
|
+
function resolveServiceTarget$1(target, exportedClasses) {
|
|
19107
|
+
return resolveServiceTarget$5(target, exportedClasses, className$1);
|
|
19108
|
+
}
|
|
18922
19109
|
/** Accessor property exposed on the WorkOS client (camelCase). */
|
|
18923
19110
|
function servicePropertyName$1(name) {
|
|
18924
19111
|
return toCamelCase(name);
|
|
@@ -20088,12 +20275,13 @@ function generateResources$2(services, ctx) {
|
|
|
20088
20275
|
if (mountGroups.size === 0) return [];
|
|
20089
20276
|
const files = [];
|
|
20090
20277
|
const resolvedLookup = buildResolvedLookup(ctx);
|
|
20278
|
+
const exportedClasses = buildExportedClassNameSet$1(ctx);
|
|
20091
20279
|
for (const [mountName, group] of mountGroups) {
|
|
20092
20280
|
const classCode = generateApiClass(mountName, group.operations, ctx, resolvedLookup);
|
|
20093
20281
|
if (!classCode) continue;
|
|
20094
20282
|
const pkg = packageSegment(mountName);
|
|
20095
20283
|
files.push({
|
|
20096
|
-
path: `${KOTLIN_SRC_PREFIX$1}com/workos/${pkg}/${
|
|
20284
|
+
path: `${KOTLIN_SRC_PREFIX$1}com/workos/${pkg}/${resolveApiClassName(mountName, exportedClasses)}.kt`,
|
|
20097
20285
|
content: classCode,
|
|
20098
20286
|
overwriteExisting: true
|
|
20099
20287
|
});
|
|
@@ -20102,7 +20290,7 @@ function generateResources$2(services, ctx) {
|
|
|
20102
20290
|
}
|
|
20103
20291
|
function generateApiClass(mountName, operations, ctx, resolvedLookup) {
|
|
20104
20292
|
if (operations.length === 0) return null;
|
|
20105
|
-
const apiClass =
|
|
20293
|
+
const apiClass = resolveApiClassName(mountName, buildExportedClassNameSet$1(ctx));
|
|
20106
20294
|
const pkg = `com.workos.${packageSegment(mountName)}`;
|
|
20107
20295
|
const imports = /* @__PURE__ */ new Set();
|
|
20108
20296
|
imports.add("com.workos.WorkOS");
|
|
@@ -20903,8 +21091,9 @@ function generateClient$2(spec, ctx) {
|
|
|
20903
21091
|
if (targets.length === 0) return [];
|
|
20904
21092
|
const imports = /* @__PURE__ */ new Set();
|
|
20905
21093
|
const accessorLines = [];
|
|
21094
|
+
const exportedClasses = buildExportedClassNameSet$1(ctx);
|
|
20906
21095
|
for (const mount of targets) {
|
|
20907
|
-
const apiCls =
|
|
21096
|
+
const apiCls = resolveApiClassName(mount, exportedClasses);
|
|
20908
21097
|
const fqn = `com.workos.${packageSegment(mount)}.${apiCls}`;
|
|
20909
21098
|
imports.add(fqn);
|
|
20910
21099
|
const prop = servicePropertyName$1(mount);
|
|
@@ -20986,12 +21175,13 @@ function generateTests$2(spec, ctx) {
|
|
|
20986
21175
|
const files = [];
|
|
20987
21176
|
const mountGroups = groupByMount(ctx);
|
|
20988
21177
|
const resolvedLookup = buildResolvedLookup(ctx);
|
|
21178
|
+
const exportedClasses = buildExportedClassNameSet$1(ctx);
|
|
20989
21179
|
for (const [mountName, group] of mountGroups) {
|
|
20990
21180
|
const content = generateServiceTestClass(mountName, group.operations, ctx, resolvedLookup);
|
|
20991
21181
|
if (!content) continue;
|
|
20992
21182
|
const pkg = packageSegment(mountName);
|
|
20993
21183
|
files.push({
|
|
20994
|
-
path: `${TEST_PREFIX}com/workos/${pkg}/${
|
|
21184
|
+
path: `${TEST_PREFIX}com/workos/${pkg}/${resolveApiClassName(mountName, exportedClasses)}Test.kt`,
|
|
20995
21185
|
content,
|
|
20996
21186
|
overwriteExisting: true
|
|
20997
21187
|
});
|
|
@@ -21060,7 +21250,7 @@ function generateServiceTestClass(mountName, operations, ctx, resolvedLookup) {
|
|
|
21060
21250
|
if (anyForbidden) imports.add("com.github.tomakehurst.wiremock.client.WireMock.absent");
|
|
21061
21251
|
if (uniqueTests.some((t) => t.canEmitHappyPath && t.responseAssertions.length > 0)) imports.add("org.junit.jupiter.api.Assertions.assertEquals");
|
|
21062
21252
|
const pkg = packageSegment(mountName);
|
|
21063
|
-
const apiCls =
|
|
21253
|
+
const apiCls = resolveApiClassName(mountName, buildExportedClassNameSet$1(ctx));
|
|
21064
21254
|
if (uniqueTests.some((t) => !t.canEmitHappyPath)) imports.add("org.junit.jupiter.api.Disabled");
|
|
21065
21255
|
const lines = [];
|
|
21066
21256
|
lines.push(`package com.workos.${pkg}`);
|
|
@@ -21976,6 +22166,30 @@ function moduleName$1(name) {
|
|
|
21976
22166
|
return toSnakeCase(name);
|
|
21977
22167
|
}
|
|
21978
22168
|
/**
|
|
22169
|
+
* Build the set of model + enum Ruby class names that the SDK exposes under
|
|
22170
|
+
* `WorkOS::`. Used to detect collisions with operation-client class names —
|
|
22171
|
+
* a colliding service gets a `Service` suffix (`OrganizationMembershipService`)
|
|
22172
|
+
* so it doesn't shadow the model class under Zeitwerk's collapsed namespace.
|
|
22173
|
+
*/
|
|
22174
|
+
function buildExportedClassNameSet(ctx) {
|
|
22175
|
+
return buildExportedClassNameSet$5(ctx, className);
|
|
22176
|
+
}
|
|
22177
|
+
/**
|
|
22178
|
+
* Resolve a service's mount-target identifier, appending `Service` on
|
|
22179
|
+
* collision with an exported model/enum class name. The returned PascalCase
|
|
22180
|
+
* value feeds `className`/`fileName` to derive matching class + file names
|
|
22181
|
+
* (e.g. `OrganizationMembershipService` / `organization_membership_service`).
|
|
22182
|
+
*
|
|
22183
|
+
* Accessor names (`servicePropertyName`) intentionally use the RAW target —
|
|
22184
|
+
* `client.organization_membership` is more readable than the suffixed form.
|
|
22185
|
+
*
|
|
22186
|
+
* The directory used by `loader.collapse` (the model home) likewise uses the
|
|
22187
|
+
* raw target.
|
|
22188
|
+
*/
|
|
22189
|
+
function resolveServiceTarget(target, exportedClasses) {
|
|
22190
|
+
return resolveServiceTarget$5(target, exportedClasses, className);
|
|
22191
|
+
}
|
|
22192
|
+
/**
|
|
21979
22193
|
* PascalCase class name for a parameter-group variant. Mirrors the Python
|
|
21980
22194
|
* convention: group "password" + variant "plaintext" → `PasswordPlaintext`.
|
|
21981
22195
|
* Used as the Ruby constant under the WorkOS module.
|
|
@@ -22750,9 +22964,11 @@ function generateResources$1(services, ctx) {
|
|
|
22750
22964
|
const listWrapperModels = /* @__PURE__ */ new Map();
|
|
22751
22965
|
for (const m of ctx.spec.models) if (isListWrapperModel(m)) listWrapperModels.set(m.name, m);
|
|
22752
22966
|
const groupOwners = buildGroupOwnerMap(ctx);
|
|
22967
|
+
const exportedClasses = buildExportedClassNameSet(ctx);
|
|
22753
22968
|
for (const [mountTarget, group] of groups) {
|
|
22754
|
-
const
|
|
22755
|
-
const
|
|
22969
|
+
const resolvedTarget = resolveServiceTarget(mountTarget, exportedClasses);
|
|
22970
|
+
const cls = className(resolvedTarget);
|
|
22971
|
+
const file = fileName(resolvedTarget);
|
|
22756
22972
|
const operations = group.operations;
|
|
22757
22973
|
if (operations.length === 0) continue;
|
|
22758
22974
|
const requires = /* @__PURE__ */ new Set();
|
|
@@ -22780,7 +22996,8 @@ function generateResources$1(services, ctx) {
|
|
|
22780
22996
|
modelByName,
|
|
22781
22997
|
listWrapperModels,
|
|
22782
22998
|
requires,
|
|
22783
|
-
groupOwners
|
|
22999
|
+
groupOwners,
|
|
23000
|
+
exportedClasses
|
|
22784
23001
|
});
|
|
22785
23002
|
methodBodies.push(body);
|
|
22786
23003
|
if (resolved?.wrappers && resolved.wrappers.length > 0) {
|
|
@@ -22826,12 +23043,12 @@ function generateResources$1(services, ctx) {
|
|
|
22826
23043
|
}
|
|
22827
23044
|
/** Build a single Ruby method from an Operation. */
|
|
22828
23045
|
function emitMethod(args) {
|
|
22829
|
-
const { op, method, defaults, inferFromClient, hiddenParams, enumNames, modelNames, modelByName, listWrapperModels, requires, groupOwners } = args;
|
|
23046
|
+
const { op, method, defaults, inferFromClient, hiddenParams, enumNames, modelNames, modelByName, listWrapperModels, requires, groupOwners, exportedClasses } = args;
|
|
22830
23047
|
/** Fully-qualified Ruby constant for a variant (e.g. WorkOS::UserManagement::PasswordPlaintext). */
|
|
22831
23048
|
const variantClassRef = (group, variantName) => {
|
|
22832
23049
|
const owner = groupOwners.get(group.name);
|
|
22833
23050
|
if (!owner) throw new Error(`No owner mount target found for parameter group '${group.name}'`);
|
|
22834
|
-
return scopedGroupVariantClassName(owner, group.name, variantName);
|
|
23051
|
+
return scopedGroupVariantClassName(resolveServiceTarget(owner, exportedClasses), group.name, variantName);
|
|
22835
23052
|
};
|
|
22836
23053
|
planOperation(op);
|
|
22837
23054
|
const lines = [];
|
|
@@ -23383,8 +23600,9 @@ function rubyCamelize(basename) {
|
|
|
23383
23600
|
function buildInflectionMap(spec, ctx) {
|
|
23384
23601
|
const inflections = /* @__PURE__ */ new Map();
|
|
23385
23602
|
inflections.set("workos", "WorkOS");
|
|
23603
|
+
const exportedClasses = buildExportedClassNameSet(ctx);
|
|
23386
23604
|
for (const service of buildTopLevelServices(spec, ctx)) {
|
|
23387
|
-
const target = getMountTarget(service, ctx) || resolveClassName(service, ctx);
|
|
23605
|
+
const target = resolveServiceTarget(getMountTarget(service, ctx) || resolveClassName(service, ctx), exportedClasses);
|
|
23388
23606
|
const cls = className(target);
|
|
23389
23607
|
const file = fileName(target);
|
|
23390
23608
|
if (rubyCamelize(file) !== cls) inflections.set(file, cls);
|
|
@@ -23476,10 +23694,11 @@ function generateClientClass(spec, ctx) {
|
|
|
23476
23694
|
lines.push("module WorkOS");
|
|
23477
23695
|
lines.push(" class Client < BaseClient");
|
|
23478
23696
|
const topLevelServices = buildTopLevelServices(spec, ctx);
|
|
23697
|
+
const exportedClasses = buildExportedClassNameSet(ctx);
|
|
23479
23698
|
for (const service of topLevelServices) {
|
|
23480
|
-
const
|
|
23481
|
-
const cls = className(
|
|
23482
|
-
const prop = servicePropertyName(
|
|
23699
|
+
const rawTarget = getMountTarget(service, ctx) || resolveClassName(service, ctx);
|
|
23700
|
+
const cls = className(resolveServiceTarget(rawTarget, exportedClasses));
|
|
23701
|
+
const prop = servicePropertyName(rawTarget);
|
|
23483
23702
|
lines.push("");
|
|
23484
23703
|
lines.push(` def ${prop}`);
|
|
23485
23704
|
lines.push(` @${prop} ||= WorkOS::${cls}.new(self)`);
|
|
@@ -23525,10 +23744,12 @@ function generateTests$1(spec, ctx) {
|
|
|
23525
23744
|
for (const m of models) modelByName.set(m.name, m);
|
|
23526
23745
|
const lookup = buildResolvedLookup(ctx);
|
|
23527
23746
|
const groupOwners = buildGroupOwnerMap(ctx);
|
|
23747
|
+
const exportedClasses = buildExportedClassNameSet(ctx);
|
|
23528
23748
|
for (const [mountTarget, group] of groups) {
|
|
23529
|
-
const
|
|
23749
|
+
const resolvedTarget = resolveServiceTarget(mountTarget, exportedClasses);
|
|
23750
|
+
const cls = className(resolvedTarget);
|
|
23530
23751
|
const prop = servicePropertyName(mountTarget);
|
|
23531
|
-
const file = fileName(
|
|
23752
|
+
const file = fileName(resolvedTarget);
|
|
23532
23753
|
const lines = [];
|
|
23533
23754
|
lines.push(`require 'test_helper'`);
|
|
23534
23755
|
lines.push("");
|
|
@@ -23554,7 +23775,7 @@ function generateTests$1(spec, ctx) {
|
|
|
23554
23775
|
const httpMethodSym = `:${op.httpMethod.toLowerCase()}`;
|
|
23555
23776
|
const resolved = lookupResolved(op, lookup);
|
|
23556
23777
|
const hiddenParams = buildHiddenParams$1(resolved);
|
|
23557
|
-
const callArgs = buildCallArgsStub(op, modelByName, hiddenParams, groupOwners, models);
|
|
23778
|
+
const callArgs = buildCallArgsStub(op, modelByName, hiddenParams, groupOwners, models, exportedClasses);
|
|
23558
23779
|
const bodyMatcher = buildBodyMatcher(op, modelByName, hiddenParams, models);
|
|
23559
23780
|
authMethodManifest.push({
|
|
23560
23781
|
method,
|
|
@@ -23583,7 +23804,7 @@ function generateTests$1(spec, ctx) {
|
|
|
23583
23804
|
for (const group of op.parameterGroups ?? []) for (let vi = 1; vi < group.variants.length; vi++) {
|
|
23584
23805
|
const variant = group.variants[vi];
|
|
23585
23806
|
const overrides = new Map([[group.name, vi]]);
|
|
23586
|
-
const variantCallArgs = buildCallArgsStub(op, modelByName, hiddenParams, groupOwners, models, overrides);
|
|
23807
|
+
const variantCallArgs = buildCallArgsStub(op, modelByName, hiddenParams, groupOwners, models, exportedClasses, overrides);
|
|
23587
23808
|
const variantBodyMatcher = buildBodyMatcher(op, modelByName, hiddenParams, models, overrides);
|
|
23588
23809
|
const suffix = `with_${fieldName$1(group.name)}_${fieldName$1(variant.name)}`;
|
|
23589
23810
|
lines.push("");
|
|
@@ -23740,7 +23961,7 @@ function roundTripStub(ref, enumNames) {
|
|
|
23740
23961
|
* default to variant 0. Used to emit per-variant test cases that exercise the
|
|
23741
23962
|
* second/third arm of each parameter-group dispatcher.
|
|
23742
23963
|
*/
|
|
23743
|
-
function buildCallArgsStub(op, modelByName, hiddenParams, groupOwners, models, variantOverrides = /* @__PURE__ */ new Map()) {
|
|
23964
|
+
function buildCallArgsStub(op, modelByName, hiddenParams, groupOwners, models, exportedClasses, variantOverrides = /* @__PURE__ */ new Map()) {
|
|
23744
23965
|
const parts = [];
|
|
23745
23966
|
const seen = /* @__PURE__ */ new Set();
|
|
23746
23967
|
const pathParamNames = /* @__PURE__ */ new Set();
|
|
@@ -23782,7 +24003,7 @@ function buildCallArgsStub(op, modelByName, hiddenParams, groupOwners, models, v
|
|
|
23782
24003
|
if (variant) {
|
|
23783
24004
|
const owner = groupOwners.get(group.name);
|
|
23784
24005
|
if (!owner) throw new Error(`No owner mount target found for parameter group '${group.name}'`);
|
|
23785
|
-
const variantClass = scopedGroupVariantClassName(owner, group.name, variant.name);
|
|
24006
|
+
const variantClass = scopedGroupVariantClassName(resolveServiceTarget(owner, exportedClasses), group.name, variant.name);
|
|
23786
24007
|
const fieldStubs = variant.parameters.map((p) => `${fieldName$1(p.name)}: ${stubValueFor(pickVariantParamType(p.type, bodyFieldTypes.get(p.name)))}`).join(", ");
|
|
23787
24008
|
parts.push(`${name}: ${variantClass}.new(${fieldStubs})`);
|
|
23788
24009
|
}
|
|
@@ -23923,6 +24144,10 @@ function stubUrlRegex(escaped) {
|
|
|
23923
24144
|
* Uses each resolved operation's actual mountOn (not the service default) so
|
|
23924
24145
|
* operations remounted via operationHints land on the correct service prop.
|
|
23925
24146
|
* Split operations emit one entry per wrapper (keyed by wrapper name + variant).
|
|
24147
|
+
*
|
|
24148
|
+
* The accessor (`service` field) uses the raw mountOn — accessor names stay
|
|
24149
|
+
* unsuffixed even when the underlying service class gets a `Service` suffix
|
|
24150
|
+
* on collision.
|
|
23926
24151
|
*/
|
|
23927
24152
|
function buildOperationsMap$1(spec, ctx) {
|
|
23928
24153
|
const manifest = {};
|
|
@@ -24023,8 +24248,10 @@ function generateRbiFiles(spec, ctx) {
|
|
|
24023
24248
|
const listWrapperModels = /* @__PURE__ */ new Map();
|
|
24024
24249
|
for (const m of spec.models) if (isListWrapperModel(m)) listWrapperModels.set(m.name, m);
|
|
24025
24250
|
const groupOwners = buildGroupOwnerMap(ctx);
|
|
24251
|
+
const exportedClasses = buildExportedClassNameSet(ctx);
|
|
24026
24252
|
for (const [mountTarget, group] of groups) {
|
|
24027
|
-
const
|
|
24253
|
+
const resolvedTarget = resolveServiceTarget(mountTarget, exportedClasses);
|
|
24254
|
+
const cls = className(resolvedTarget);
|
|
24028
24255
|
const lines = [];
|
|
24029
24256
|
lines.push("# typed: strong");
|
|
24030
24257
|
lines.push("");
|
|
@@ -24032,6 +24259,7 @@ function generateRbiFiles(spec, ctx) {
|
|
|
24032
24259
|
lines.push(` class ${cls}`);
|
|
24033
24260
|
const variants = collectVariantsForMountTarget(ctx, spec.models, mountTarget);
|
|
24034
24261
|
for (const v of variants) {
|
|
24262
|
+
v.mountTarget = resolvedTarget;
|
|
24035
24263
|
for (const line of emitInlineVariantRbi(v)) lines.push(line);
|
|
24036
24264
|
lines.push("");
|
|
24037
24265
|
}
|
|
@@ -24056,7 +24284,8 @@ function generateRbiFiles(spec, ctx) {
|
|
|
24056
24284
|
const groupSorbetType = (group) => {
|
|
24057
24285
|
const owner = groupOwners.get(group.name);
|
|
24058
24286
|
if (!owner) throw new Error(`No owner mount target found for parameter group '${group.name}'`);
|
|
24059
|
-
const
|
|
24287
|
+
const resolvedOwner = resolveServiceTarget(owner, exportedClasses);
|
|
24288
|
+
const variants = group.variants.map((v) => scopedGroupVariantClassName(resolvedOwner, group.name, v.name));
|
|
24060
24289
|
if (variants.length === 1) return variants[0];
|
|
24061
24290
|
return `T.any(${variants.join(", ")})`;
|
|
24062
24291
|
};
|
|
@@ -24130,7 +24359,7 @@ function generateRbiFiles(spec, ctx) {
|
|
|
24130
24359
|
lines.push(" end");
|
|
24131
24360
|
lines.push("end");
|
|
24132
24361
|
files.push({
|
|
24133
|
-
path: `rbi/workos/${fileName(
|
|
24362
|
+
path: `rbi/workos/${fileName(resolvedTarget)}.rbi`,
|
|
24134
24363
|
content: lines.join("\n"),
|
|
24135
24364
|
integrateTarget: true,
|
|
24136
24365
|
overwriteExisting: true
|
|
@@ -24143,8 +24372,8 @@ function generateRbiFiles(spec, ctx) {
|
|
|
24143
24372
|
lines.push("module WorkOS");
|
|
24144
24373
|
lines.push(" class Client < BaseClient");
|
|
24145
24374
|
for (const [mountTarget] of groups) {
|
|
24146
|
-
const cls = className(mountTarget);
|
|
24147
|
-
const prop = mountTarget
|
|
24375
|
+
const cls = className(resolveServiceTarget(mountTarget, exportedClasses));
|
|
24376
|
+
const prop = servicePropertyName(mountTarget);
|
|
24148
24377
|
lines.push(` sig { returns(WorkOS::${cls}) }`);
|
|
24149
24378
|
lines.push(` def ${prop}; end`);
|
|
24150
24379
|
lines.push("");
|
|
@@ -26585,4 +26814,4 @@ const workosEmittersPlugin = {
|
|
|
26585
26814
|
//#endregion
|
|
26586
26815
|
export { pythonEmitter as _, rustExtractor as a, pythonExtractor as c, rustEmitter as d, rubyEmitter as f, phpEmitter as g, goEmitter as h, kotlinExtractor as i, rubyExtractor as l, dotnetEmitter as m, elixirExtractor as n, goExtractor as o, kotlinEmitter as p, dotnetExtractor as r, phpExtractor as s, workosEmittersPlugin as t, nodeExtractor as u, nodeEmitter as v };
|
|
26587
26816
|
|
|
26588
|
-
//# sourceMappingURL=plugin-
|
|
26817
|
+
//# sourceMappingURL=plugin-B9F2jmwy.mjs.map
|