@workos/oagen-emitters 0.14.0 → 0.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.release-please-manifest.json +1 -1
- package/CHANGELOG.md +9 -0
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{plugin-BxVeu2v9.mjs → plugin-DRGwxN88.mjs} +148 -31
- package/dist/plugin-DRGwxN88.mjs.map +1 -0
- package/dist/plugin.mjs +1 -1
- package/package.json +1 -1
- package/src/dotnet/models.ts +31 -6
- package/src/dotnet/type-map.ts +18 -1
- package/src/go/models.ts +12 -3
- package/src/kotlin/models.ts +16 -6
- package/src/node/index.ts +78 -4
- package/src/node/models.ts +8 -2
- package/src/node/utils.ts +5 -1
- package/src/php/models.ts +11 -2
- package/src/python/models.ts +12 -2
- package/src/python/resources.ts +8 -2
- package/src/ruby/index.ts +3 -3
- package/src/ruby/models.ts +13 -3
- package/src/rust/models.ts +5 -1
- package/src/rust/resources.ts +4 -1
- package/src/shared/model-utils.ts +35 -3
- package/test/rust/models.test.ts +3 -3
- package/dist/plugin-BxVeu2v9.mjs.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.14.1](https://github.com/workos/oagen-emitters/compare/v0.14.0...v0.14.1) (2026-05-22)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* emit non-paginated list wrappers, dotnet member/class collisions, rust glob ambiguity ([#120](https://github.com/workos/oagen-emitters/issues/120)) ([6df9822](https://github.com/workos/oagen-emitters/commit/6df98221dfa707800babce0d6a4cf1a653923743))
|
|
9
|
+
* **node:** carry forward prior-manifest paths so prune diffs stay accurate ([#117](https://github.com/workos/oagen-emitters/issues/117)) ([a03e4db](https://github.com/workos/oagen-emitters/commit/a03e4dbf2733e33ae4c31be568c2a12ea8361be1))
|
|
10
|
+
* **shared:** prevent synthetic-enum collision with IR enums ([#119](https://github.com/workos/oagen-emitters/issues/119)) ([0211f66](https://github.com/workos/oagen-emitters/commit/0211f669b51da3a14717dfa61941c954dc7edaa6))
|
|
11
|
+
|
|
3
12
|
## [0.14.0](https://github.com/workos/oagen-emitters/compare/v0.13.0...v0.14.0) (2026-05-21)
|
|
4
13
|
|
|
5
14
|
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/node/index.ts","../src/python/index.ts","../src/php/index.ts","../src/go/index.ts","../src/dotnet/index.ts","../src/kotlin/index.ts","../src/ruby/index.ts","../src/rust/index.ts"],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/node/index.ts","../src/python/index.ts","../src/php/index.ts","../src/go/index.ts","../src/dotnet/index.ts","../src/kotlin/index.ts","../src/ruby/index.ts","../src/rust/index.ts"],"mappings":";;;;;cAyca,WAAA,EAAa,OA4GzB;;;cC9gBY,aAAA,EAAe,OA+D3B;;;cC5CY,UAAA,EAAY,OA4DxB;;;cCzFY,SAAA,EAAW,OAyEvB;;;cCnCY,aAAA,EAAe,OAiR3B;;;cCrTY,aAAA,EAAe,OA6E3B;;;cCxDY,WAAA,EAAa,OAmEzB;;;cC5DY,WAAA,EAAa,OA2DzB"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { _ as pythonEmitter, a as rustExtractor, c as pythonExtractor, d as rustEmitter, f as rubyEmitter, g as phpEmitter, h as goEmitter, i as kotlinExtractor, l as rubyExtractor, m as dotnetEmitter, n as elixirExtractor, o as goExtractor, p as kotlinEmitter, r as dotnetExtractor, s as phpExtractor, t as workosEmittersPlugin, u as nodeExtractor, v as nodeEmitter } from "./plugin-
|
|
1
|
+
import { _ as pythonEmitter, a as rustExtractor, c as pythonExtractor, d as rustEmitter, f as rubyEmitter, g as phpEmitter, h as goEmitter, i as kotlinExtractor, l as rubyExtractor, m as dotnetEmitter, n as elixirExtractor, o as goExtractor, p as kotlinEmitter, r as dotnetExtractor, s as phpExtractor, t as workosEmittersPlugin, u as nodeExtractor, v as nodeEmitter } from "./plugin-DRGwxN88.mjs";
|
|
2
2
|
export { dotnetEmitter, dotnetExtractor, elixirExtractor, goEmitter, goExtractor, kotlinEmitter, kotlinExtractor, nodeEmitter, nodeExtractor, phpEmitter, phpExtractor, pythonEmitter, pythonExtractor, rubyEmitter, rubyExtractor, rustEmitter, rustExtractor, workosEmittersPlugin };
|
|
@@ -2286,6 +2286,24 @@ dumper.dump;
|
|
|
2286
2286
|
//#endregion
|
|
2287
2287
|
//#region src/shared/model-utils.ts
|
|
2288
2288
|
/**
|
|
2289
|
+
* Collect model names referenced as the return type of any non-paginated
|
|
2290
|
+
* operation. The list-wrapper skip rule below assumes a wrapper is always
|
|
2291
|
+
* replaced by the SDK's pagination machinery — but a few endpoints
|
|
2292
|
+
* (e.g. `GET /vault/v1/kv/{id}/versions`) have a list-envelope response
|
|
2293
|
+
* shape with no pagination params, so the parser leaves them as a plain
|
|
2294
|
+
* model reference. We must still emit those wrappers as regular models;
|
|
2295
|
+
* otherwise the generated resource code references an undefined name.
|
|
2296
|
+
*/
|
|
2297
|
+
function collectNonPaginatedResponseModelNames(services) {
|
|
2298
|
+
const names = /* @__PURE__ */ new Set();
|
|
2299
|
+
for (const service of services) for (const op of service.operations) {
|
|
2300
|
+
if (op.pagination) continue;
|
|
2301
|
+
walkTypeRef(op.response, { model: (r) => names.add(r.name) });
|
|
2302
|
+
for (const sr of op.successResponses ?? []) walkTypeRef(sr.type, { model: (r) => names.add(r.name) });
|
|
2303
|
+
}
|
|
2304
|
+
return names;
|
|
2305
|
+
}
|
|
2306
|
+
/**
|
|
2289
2307
|
* Detect whether a model is a list wrapper -- the standard paginated
|
|
2290
2308
|
* list envelope with `data` (array), `list_metadata`, and optionally `object: 'list'`.
|
|
2291
2309
|
*
|
|
@@ -2636,7 +2654,7 @@ function detectDiscriminators(models) {
|
|
|
2636
2654
|
* Returns a new array of enriched models (original models are not mutated).
|
|
2637
2655
|
* Synthetic enums are stored internally; retrieve them via `getSyntheticEnums()`.
|
|
2638
2656
|
*/
|
|
2639
|
-
function enrichModelsFromSpec(models) {
|
|
2657
|
+
function enrichModelsFromSpec(models, enums = []) {
|
|
2640
2658
|
if (!loadRawSpec()) {
|
|
2641
2659
|
_lastSyntheticEnums = [];
|
|
2642
2660
|
return models;
|
|
@@ -2646,6 +2664,10 @@ function enrichModelsFromSpec(models) {
|
|
|
2646
2664
|
collector.usedNames.add(m.name);
|
|
2647
2665
|
collector.usedNames.add(toSnakeCase(m.name));
|
|
2648
2666
|
}
|
|
2667
|
+
for (const e of enums) {
|
|
2668
|
+
collector.usedNames.add(e.name);
|
|
2669
|
+
collector.usedNames.add(toSnakeCase(e.name));
|
|
2670
|
+
}
|
|
2649
2671
|
const enriched2 = models.map((model) => {
|
|
2650
2672
|
const rawSchema = lookupRawSchema(model.name);
|
|
2651
2673
|
if (!rawSchema) return model;
|
|
@@ -5991,12 +6013,13 @@ function generateModels$7(models, ctx, shared) {
|
|
|
5991
6013
|
}
|
|
5992
6014
|
}
|
|
5993
6015
|
const discriminatedSkip = ctx._discriminatedModelNames;
|
|
6016
|
+
const nonPaginatedRefs = collectNonPaginatedResponseModelNames(ctx.spec.services);
|
|
5994
6017
|
for (const originalModel of models) {
|
|
5995
6018
|
const model = projectedByName.get(originalModel.name) ?? originalModel;
|
|
5996
6019
|
if (!reachableModels.has(model.name)) continue;
|
|
5997
6020
|
if (interfaceEligibleModels && !interfaceEligibleModels.has(model.name)) continue;
|
|
5998
6021
|
if (isListMetadataModel(model)) continue;
|
|
5999
|
-
if (isListWrapperModel(model)) continue;
|
|
6022
|
+
if (isListWrapperModel(model) && !nonPaginatedRefs.has(model.name)) continue;
|
|
6000
6023
|
if (discriminatedSkip?.has(model.name)) continue;
|
|
6001
6024
|
const service = modelToService.get(model.name);
|
|
6002
6025
|
const isOwnedModel = isNodeOwnedService(ctx, service);
|
|
@@ -6330,13 +6353,14 @@ function generateSerializers(models, ctx, shared) {
|
|
|
6330
6353
|
}
|
|
6331
6354
|
}
|
|
6332
6355
|
const discriminatedSerializerSkip = ctx._discriminatedModelNames;
|
|
6356
|
+
const serializerNonPaginatedRefs = collectNonPaginatedResponseModelNames(ctx.spec.services);
|
|
6333
6357
|
const eligibleModels = [];
|
|
6334
6358
|
for (const originalModel of models) {
|
|
6335
6359
|
const model = projectedByName.get(originalModel.name) ?? originalModel;
|
|
6336
6360
|
if (!serializerReachable.has(model.name)) continue;
|
|
6337
6361
|
if (serializerEligibleModels && !serializerEligibleModels.has(model.name)) continue;
|
|
6338
6362
|
if (isListMetadataModel(model)) continue;
|
|
6339
|
-
if (isListWrapperModel(model)) continue;
|
|
6363
|
+
if (isListWrapperModel(model) && !serializerNonPaginatedRefs.has(model.name)) continue;
|
|
6340
6364
|
if (discriminatedSerializerSkip?.has(model.name)) continue;
|
|
6341
6365
|
if (!isNodeOwnedService(ctx, modelToService.get(model.name)) && !modelHasNewFields(model, ctx) && !forceGenerateSerializer.has(model.name)) continue;
|
|
6342
6366
|
eligibleModels.push(model);
|
|
@@ -8183,6 +8207,22 @@ function withNodeOperationOverrides(ctx) {
|
|
|
8183
8207
|
* one oagen run, so we walk the target SDK once and reuse it.
|
|
8184
8208
|
*/
|
|
8185
8209
|
const surfaceCache = /* @__PURE__ */ new WeakMap();
|
|
8210
|
+
/**
|
|
8211
|
+
* Paths the node emitter has produced so far in this ctx, accumulated across
|
|
8212
|
+
* `applyLiveSurface` calls. Drives `carryForwardManagedFiles` so files in the
|
|
8213
|
+
* prior manifest that we did not re-emit this run still land in the new
|
|
8214
|
+
* manifest as "still managed" — without that, the orchestrator's prune diff
|
|
8215
|
+
* treats every untouched autogen file as stale.
|
|
8216
|
+
*/
|
|
8217
|
+
const emittedPathsCache = /* @__PURE__ */ new WeakMap();
|
|
8218
|
+
function getEmittedPaths(ctx) {
|
|
8219
|
+
let set = emittedPathsCache.get(ctx);
|
|
8220
|
+
if (!set) {
|
|
8221
|
+
set = /* @__PURE__ */ new Set();
|
|
8222
|
+
emittedPathsCache.set(ctx, set);
|
|
8223
|
+
}
|
|
8224
|
+
return set;
|
|
8225
|
+
}
|
|
8186
8226
|
function getSurface(ctx) {
|
|
8187
8227
|
let surface = surfaceCache.get(ctx);
|
|
8188
8228
|
if (surface) return surface;
|
|
@@ -8229,8 +8269,10 @@ function getSurface(ctx) {
|
|
|
8229
8269
|
* `integrateTarget: false` files (smoke-manifest.json etc.) are also dropped:
|
|
8230
8270
|
* with no `--target` step they would otherwise land as untracked cruft.
|
|
8231
8271
|
*
|
|
8232
|
-
* Note:
|
|
8233
|
-
*
|
|
8272
|
+
* Note: the carry-forward step in `generateTests` re-declares prior-manifest
|
|
8273
|
+
* paths we didn't touch this run, so the orchestrator's prune diff stays
|
|
8274
|
+
* accurate without needing `--no-prune` at the call site. See
|
|
8275
|
+
* `carryForwardManagedFiles` below.
|
|
8234
8276
|
*/
|
|
8235
8277
|
/**
|
|
8236
8278
|
* `*.spec.ts`, `*.test.ts`, and JSON fixtures under `fixtures/` are owned by
|
|
@@ -8380,6 +8422,52 @@ function applyLiveSurface(files, ctx, surface) {
|
|
|
8380
8422
|
if (f.content && !f.content.endsWith("\n")) f.content += "\n";
|
|
8381
8423
|
out.push(f);
|
|
8382
8424
|
}
|
|
8425
|
+
const emitted = getEmittedPaths(ctx);
|
|
8426
|
+
for (const f of out) emitted.add(f.path);
|
|
8427
|
+
return out;
|
|
8428
|
+
}
|
|
8429
|
+
/**
|
|
8430
|
+
* Re-declare prior-manifest paths that we did not emit this run so manifest
|
|
8431
|
+
* pruning can tell "intentionally removed" from "untouched but still managed."
|
|
8432
|
+
*
|
|
8433
|
+
* The node emitter only outputs files it actually wants to write each run —
|
|
8434
|
+
* untouched-but-up-to-date autogen files don't come back through any
|
|
8435
|
+
* `generateXxx` method. Without this carry-forward, the orchestrator's
|
|
8436
|
+
* `prevManifest.files − currentEmission` diff treats every such file as stale
|
|
8437
|
+
* and prunes the whole tree on a regen. That's why `scripts/sdk-generate.sh`
|
|
8438
|
+
* historically paired the node emitter with `--no-prune` — at the cost of
|
|
8439
|
+
* never pruning legitimately-removed files (e.g. an enum file orphaned by a
|
|
8440
|
+
* `schemaNameTransform` rename like `RadarAction` → `RadarListAction`).
|
|
8441
|
+
*
|
|
8442
|
+
* The carry-forward entry uses `skipIfExists: true`, so writer.ts skips the
|
|
8443
|
+
* write and only ensures the header is present (no-op for files that already
|
|
8444
|
+
* have it). The path still lands in `outputEmittedPaths` and therefore in the
|
|
8445
|
+
* new manifest, which restores correct prune semantics.
|
|
8446
|
+
*
|
|
8447
|
+
* Files dropped from the carry-forward set:
|
|
8448
|
+
* - Not on disk anymore (file was hand-deleted — let prune confirm absence).
|
|
8449
|
+
* - `@oagen-ignore-file` protected (user has explicitly taken ownership).
|
|
8450
|
+
* - `.ts` files that no longer carry the auto-gen header (user has taken
|
|
8451
|
+
* ownership in-place; the next prune cycle will clear the manifest entry).
|
|
8452
|
+
*/
|
|
8453
|
+
function carryForwardManagedFiles(ctx, surface) {
|
|
8454
|
+
const priorPaths = ctx.priorTargetManifestPaths;
|
|
8455
|
+
if (!priorPaths || priorPaths.size === 0) return [];
|
|
8456
|
+
const emitted = getEmittedPaths(ctx);
|
|
8457
|
+
const out = [];
|
|
8458
|
+
for (const relPath of priorPaths) {
|
|
8459
|
+
if (emitted.has(relPath)) continue;
|
|
8460
|
+
if (!surface.files.has(relPath)) continue;
|
|
8461
|
+
if (surface.protectedFiles.has(relPath)) continue;
|
|
8462
|
+
if (relPath.endsWith(".ts") && !surface.autogenFiles.has(relPath)) continue;
|
|
8463
|
+
out.push({
|
|
8464
|
+
path: relPath,
|
|
8465
|
+
content: "",
|
|
8466
|
+
skipIfExists: true,
|
|
8467
|
+
headerPlacement: "skip"
|
|
8468
|
+
});
|
|
8469
|
+
emitted.add(relPath);
|
|
8470
|
+
}
|
|
8383
8471
|
return out;
|
|
8384
8472
|
}
|
|
8385
8473
|
/**
|
|
@@ -8446,9 +8534,8 @@ const nodeEmitter = {
|
|
|
8446
8534
|
},
|
|
8447
8535
|
generateTests(spec, ctx) {
|
|
8448
8536
|
const nodeCtx = withNodeOperationOverrides(ctx);
|
|
8449
|
-
if (!nodeOptions(nodeCtx).regenerateOwnedTests) return [];
|
|
8450
8537
|
const surface = getSurface(nodeCtx);
|
|
8451
|
-
return applyLiveSurface(generateTests$7(spec, nodeCtx), nodeCtx, surface);
|
|
8538
|
+
return [...nodeOptions(nodeCtx).regenerateOwnedTests ? applyLiveSurface(generateTests$7(spec, nodeCtx), nodeCtx, surface) : [], ...carryForwardManagedFiles(nodeCtx, surface)];
|
|
8452
8539
|
},
|
|
8453
8540
|
buildOperationsMap() {
|
|
8454
8541
|
return {};
|
|
@@ -9225,8 +9312,9 @@ function generateModels$6(models, ctx) {
|
|
|
9225
9312
|
const symbolToFile = /* @__PURE__ */ new Map();
|
|
9226
9313
|
const symbolToOriginalService = /* @__PURE__ */ new Map();
|
|
9227
9314
|
const emittedFilePaths = /* @__PURE__ */ new Set();
|
|
9315
|
+
const nonPaginatedRefs = collectNonPaginatedResponseModelNames(ctx.spec.services);
|
|
9228
9316
|
for (const model of models) {
|
|
9229
|
-
if (isListWrapperModel(model)) continue;
|
|
9317
|
+
if (isListWrapperModel(model) && !nonPaginatedRefs.has(model.name)) continue;
|
|
9230
9318
|
if (isListMetadataModel(model)) continue;
|
|
9231
9319
|
const dirName = resolveDir(modelToService.get(model.name));
|
|
9232
9320
|
const modelClassName = className$5(model.name);
|
|
@@ -10640,7 +10728,9 @@ function generateResources$6(services, ctx) {
|
|
|
10640
10728
|
}
|
|
10641
10729
|
for (const op of allOperations) {
|
|
10642
10730
|
const plan = planOperation(op);
|
|
10643
|
-
if (plan.responseModelName
|
|
10731
|
+
if (plan.responseModelName) {
|
|
10732
|
+
if (!listWrapperNames.has(plan.responseModelName) || !plan.isPaginated) modelImports.add(plan.responseModelName);
|
|
10733
|
+
}
|
|
10644
10734
|
if (op.requestBody?.kind === "model") {
|
|
10645
10735
|
const requestBodyRef = op.requestBody;
|
|
10646
10736
|
modelImports.add(requestBodyRef.name);
|
|
@@ -12769,9 +12859,10 @@ function generateModels$5(models, ctx) {
|
|
|
12769
12859
|
].join("\n"),
|
|
12770
12860
|
overwriteExisting: true
|
|
12771
12861
|
});
|
|
12862
|
+
const nonPaginatedRefs = collectNonPaginatedResponseModelNames(ctx.spec.services);
|
|
12772
12863
|
for (const model of models) {
|
|
12773
12864
|
if (isListMetadataModel(model)) continue;
|
|
12774
|
-
if (isListWrapperModel(model)) continue;
|
|
12865
|
+
if (isListWrapperModel(model) && !nonPaginatedRefs.has(model.name)) continue;
|
|
12775
12866
|
const name = className$4(model.name);
|
|
12776
12867
|
const lines = [];
|
|
12777
12868
|
lines.push(`namespace ${ctx.namespacePascal}\\Resource;`);
|
|
@@ -14671,10 +14762,12 @@ function generateModels$4(models, ctx) {
|
|
|
14671
14762
|
lines.push(`package ${ctx.namespace}`);
|
|
14672
14763
|
lines.push("");
|
|
14673
14764
|
const requestBodyOnly = collectRequestBodyOnlyModelNames$1(ctx.spec.services, models);
|
|
14765
|
+
const nonPaginatedRefs = collectNonPaginatedResponseModelNames(ctx.spec.services);
|
|
14766
|
+
const skipAsListWrapper = (m) => isListWrapperModel(m) && !nonPaginatedRefs.has(m.name);
|
|
14674
14767
|
const modelHashMap = /* @__PURE__ */ new Map();
|
|
14675
14768
|
const hashGroups = /* @__PURE__ */ new Map();
|
|
14676
14769
|
for (const model of models) {
|
|
14677
|
-
if (
|
|
14770
|
+
if (skipAsListWrapper(model) || isListMetadataModel(model)) continue;
|
|
14678
14771
|
if (requestBodyOnly.has(model.name)) continue;
|
|
14679
14772
|
const hash = structuralHash$2(model);
|
|
14680
14773
|
modelHashMap.set(model.name, hash);
|
|
@@ -14691,7 +14784,7 @@ function generateModels$4(models, ctx) {
|
|
|
14691
14784
|
}
|
|
14692
14785
|
const batchedAliases = /* @__PURE__ */ new Set();
|
|
14693
14786
|
for (const model of models) {
|
|
14694
|
-
if (
|
|
14787
|
+
if (skipAsListWrapper(model) || isListMetadataModel(model)) continue;
|
|
14695
14788
|
if (requestBodyOnly.has(model.name)) continue;
|
|
14696
14789
|
const structName = className$3(model.name);
|
|
14697
14790
|
const canonicalName = aliasOf.get(model.name);
|
|
@@ -17324,7 +17417,15 @@ function isEnumRef(ref) {
|
|
|
17324
17417
|
* omission so the API returns a clear `missing required field` error instead
|
|
17325
17418
|
* of a confusing 422.
|
|
17326
17419
|
*/
|
|
17327
|
-
function emitJsonPropertyAttributes(
|
|
17420
|
+
function emitJsonPropertyAttributes(wireName, options = {}) {
|
|
17421
|
+
if (options.explicitWireName) {
|
|
17422
|
+
if (options.isRequiredEnum) return [
|
|
17423
|
+
` [JsonProperty("${wireName}", DefaultValueHandling = DefaultValueHandling.Ignore)]`,
|
|
17424
|
+
` [STJS.JsonIgnore(Condition = STJS.JsonIgnoreCondition.WhenWritingDefault)]`,
|
|
17425
|
+
` [STJS.JsonPropertyName("${wireName}")]`
|
|
17426
|
+
];
|
|
17427
|
+
return [` [JsonProperty("${wireName}")]`, ` [STJS.JsonPropertyName("${wireName}")]`];
|
|
17428
|
+
}
|
|
17328
17429
|
if (options.isRequiredEnum) return [` [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]`, ` [STJS.JsonIgnore(Condition = STJS.JsonIgnoreCondition.WhenWritingDefault)]`];
|
|
17329
17430
|
return [];
|
|
17330
17431
|
}
|
|
@@ -17377,16 +17478,23 @@ function generateModels$3(models, ctx, discCtx) {
|
|
|
17377
17478
|
const files = [];
|
|
17378
17479
|
primeModelAliases(models);
|
|
17379
17480
|
const requestBodyOnlyNames = collectRequestBodyOnlyModelNames(ctx.spec.services, models);
|
|
17481
|
+
const nonPaginatedRefs = collectNonPaginatedResponseModelNames(ctx.spec.services);
|
|
17482
|
+
const skipAsListWrapper = (m) => isListWrapperModel(m) && !nonPaginatedRefs.has(m.name);
|
|
17380
17483
|
const baseFieldLookup = /* @__PURE__ */ new Map();
|
|
17381
17484
|
if (discCtx) {
|
|
17382
17485
|
for (const model of models) if (discCtx.discriminatorBases.has(model.name)) {
|
|
17486
|
+
const baseClassName = modelClassName(model.name);
|
|
17383
17487
|
const fieldMap = /* @__PURE__ */ new Map();
|
|
17384
|
-
for (const field of model.fields)
|
|
17488
|
+
for (const field of model.fields) {
|
|
17489
|
+
let csName = fieldName$2(field.name);
|
|
17490
|
+
if (csName === baseClassName) csName = `${csName}Value`;
|
|
17491
|
+
fieldMap.set(csName, mapTypeRef$3(field.type));
|
|
17492
|
+
}
|
|
17385
17493
|
baseFieldLookup.set(model.name, fieldMap);
|
|
17386
17494
|
}
|
|
17387
17495
|
}
|
|
17388
17496
|
for (const model of models) {
|
|
17389
|
-
if (
|
|
17497
|
+
if (skipAsListWrapper(model) || isListMetadataModel(model)) continue;
|
|
17390
17498
|
if (requestBodyOnlyNames.has(model.name)) continue;
|
|
17391
17499
|
const csClassName = modelClassName(model.name);
|
|
17392
17500
|
if (isModelAlias(model.name)) continue;
|
|
@@ -17394,7 +17502,7 @@ function generateModels$3(models, ctx, discCtx) {
|
|
|
17394
17502
|
const fieldTypes = model.fields.map((f) => mapTypeRef$3(f.type));
|
|
17395
17503
|
const needsCollections = fieldTypes.some((t) => t.startsWith("List<") || t.startsWith("Dictionary<"));
|
|
17396
17504
|
const needsSystem = fieldTypes.some((t) => t.includes("DateTimeOffset"));
|
|
17397
|
-
const needsJsonAttrs = model.fields.some((f) => f.required && isEnumRef(f.type));
|
|
17505
|
+
const needsJsonAttrs = model.fields.some((f) => fieldName$2(f.name) === csClassName) || model.fields.some((f) => f.required && isEnumRef(f.type));
|
|
17398
17506
|
lines.push(`namespace ${ctx.namespacePascal}`);
|
|
17399
17507
|
lines.push("{");
|
|
17400
17508
|
if (needsSystem) lines.push(" using System;");
|
|
@@ -17420,7 +17528,9 @@ function generateModels$3(models, ctx, discCtx) {
|
|
|
17420
17528
|
const dictObjectFields = [];
|
|
17421
17529
|
const seenFieldNames = /* @__PURE__ */ new Set();
|
|
17422
17530
|
for (const field of model.fields) {
|
|
17423
|
-
|
|
17531
|
+
let csFieldName = fieldName$2(field.name);
|
|
17532
|
+
const collidesWithClassName = csFieldName === csClassName;
|
|
17533
|
+
if (collidesWithClassName) csFieldName = `${csFieldName}Value`;
|
|
17424
17534
|
if (seenFieldNames.has(csFieldName)) continue;
|
|
17425
17535
|
seenFieldNames.add(csFieldName);
|
|
17426
17536
|
let useNewModifier = false;
|
|
@@ -17465,7 +17575,10 @@ function generateModels$3(models, ctx, discCtx) {
|
|
|
17465
17575
|
lines.push(` [System.Obsolete("${msg}")]`);
|
|
17466
17576
|
}
|
|
17467
17577
|
const isRequiredEnum = field.required && isEnumRef(field.type) && constInit === null;
|
|
17468
|
-
lines.push(...emitJsonPropertyAttributes(field.name, {
|
|
17578
|
+
lines.push(...emitJsonPropertyAttributes(field.name, {
|
|
17579
|
+
isRequiredEnum,
|
|
17580
|
+
explicitWireName: collidesWithClassName
|
|
17581
|
+
}));
|
|
17469
17582
|
const discriminatedUnionConverter = discriminatedUnionConverterName(field.type);
|
|
17470
17583
|
if (discriminatedUnionConverter) lines.push(` [Newtonsoft.Json.JsonConverter(typeof(${discriminatedUnionConverter}))]`);
|
|
17471
17584
|
const newMod = useNewModifier ? "new " : "";
|
|
@@ -20050,14 +20163,16 @@ function promoteFieldType$1(f) {
|
|
|
20050
20163
|
* List wrappers (`{ data, list_metadata }`) and the shared `ListMetadata`
|
|
20051
20164
|
* model are skipped — the hand-maintained runtime provides [Page]/[ListMetadata].
|
|
20052
20165
|
*/
|
|
20053
|
-
function generateModels$2(models,
|
|
20166
|
+
function generateModels$2(models, ctx) {
|
|
20054
20167
|
if (models.length === 0) return [];
|
|
20055
20168
|
for (const model of models) for (const field of model.fields) mapTypeRef$2(field.type);
|
|
20056
20169
|
const files = [];
|
|
20170
|
+
const nonPaginatedRefs = collectNonPaginatedResponseModelNames(ctx.spec.services);
|
|
20171
|
+
const skipAsListWrapper = (m) => isListWrapperModel(m) && !nonPaginatedRefs.has(m.name);
|
|
20057
20172
|
modelAliasMap = null;
|
|
20058
20173
|
const hashGroupsPass1 = /* @__PURE__ */ new Map();
|
|
20059
20174
|
for (const model of models) {
|
|
20060
|
-
if (
|
|
20175
|
+
if (skipAsListWrapper(model) || isListMetadataModel(model)) continue;
|
|
20061
20176
|
if (model.fields.length === 0 && discriminatedUnions.has(className$1(model.name))) continue;
|
|
20062
20177
|
const hash = structuralHash(model);
|
|
20063
20178
|
if (!hashGroupsPass1.has(hash)) hashGroupsPass1.set(hash, []);
|
|
@@ -20076,7 +20191,7 @@ function generateModels$2(models, _ctx) {
|
|
|
20076
20191
|
modelAliasMap = aliasOf;
|
|
20077
20192
|
const hashGroupsPass2 = /* @__PURE__ */ new Map();
|
|
20078
20193
|
for (const model of models) {
|
|
20079
|
-
if (
|
|
20194
|
+
if (skipAsListWrapper(model) || isListMetadataModel(model)) continue;
|
|
20080
20195
|
if (model.fields.length === 0 && discriminatedUnions.has(className$1(model.name))) continue;
|
|
20081
20196
|
if (aliasOf.has(model.name)) continue;
|
|
20082
20197
|
const hash = structuralHash(model);
|
|
@@ -20094,7 +20209,7 @@ function generateModels$2(models, _ctx) {
|
|
|
20094
20209
|
}
|
|
20095
20210
|
}
|
|
20096
20211
|
for (const model of models) {
|
|
20097
|
-
if (
|
|
20212
|
+
if (skipAsListWrapper(model) || isListMetadataModel(model)) continue;
|
|
20098
20213
|
const typeName = className$1(model.name);
|
|
20099
20214
|
if (model.fields.length === 0 && discriminatedUnions.has(typeName)) {
|
|
20100
20215
|
files.push(emitSealedUnion(typeName, discriminatedUnions.get(typeName)));
|
|
@@ -20122,7 +20237,7 @@ function generateModels$2(models, _ctx) {
|
|
|
20122
20237
|
}
|
|
20123
20238
|
const eventMapping = [];
|
|
20124
20239
|
for (const model of models) {
|
|
20125
|
-
if (
|
|
20240
|
+
if (skipAsListWrapper(model) || isListMetadataModel(model)) continue;
|
|
20126
20241
|
if (aliasOf.has(model.name)) continue;
|
|
20127
20242
|
if (!isEventEnvelopeModel(model)) continue;
|
|
20128
20243
|
const eventField = model.fields.find((f) => f.name === "event");
|
|
@@ -22839,10 +22954,12 @@ function generateModels$1(models, ctx) {
|
|
|
22839
22954
|
return mountDirMap.get(service) ?? classifyUnassignedModel(modelName);
|
|
22840
22955
|
};
|
|
22841
22956
|
const files = [];
|
|
22957
|
+
const nonPaginatedRefs = collectNonPaginatedResponseModelNames(ctx.spec.services);
|
|
22958
|
+
const skipAsListWrapper = (m) => isListWrapperModel(m) && !nonPaginatedRefs.has(m.name);
|
|
22842
22959
|
const recursiveHashes = buildRecursiveHashMap(models, enumNames);
|
|
22843
22960
|
const hashGroups = /* @__PURE__ */ new Map();
|
|
22844
22961
|
for (const m of models) {
|
|
22845
|
-
if (
|
|
22962
|
+
if (skipAsListWrapper(m) || isListMetadataModel(m)) continue;
|
|
22846
22963
|
const h = recursiveHashes.get(m.name) ?? "";
|
|
22847
22964
|
if (!hashGroups.has(h)) hashGroups.set(h, []);
|
|
22848
22965
|
hashGroups.get(h).push(m.name);
|
|
@@ -22855,7 +22972,7 @@ function generateModels$1(models, ctx) {
|
|
|
22855
22972
|
for (let i = 1; i < sorted.length; i++) aliasOf.set(sorted[i], canonical);
|
|
22856
22973
|
}
|
|
22857
22974
|
for (const model of models) {
|
|
22858
|
-
if (
|
|
22975
|
+
if (skipAsListWrapper(model) || isListMetadataModel(model)) continue;
|
|
22859
22976
|
const cls = className(model.name);
|
|
22860
22977
|
const file = fileName(model.name);
|
|
22861
22978
|
const canonical = aliasOf.get(model.name);
|
|
@@ -24986,8 +25103,8 @@ function ensureTrailingNewlines$1(files) {
|
|
|
24986
25103
|
* has its original fields restored — otherwise `ConnectApplication`-style
|
|
24987
25104
|
* bases would silently lose every variant field they had previously.
|
|
24988
25105
|
*/
|
|
24989
|
-
function enrichModelsForRuby(models) {
|
|
24990
|
-
const enriched = enrichModelsFromSpec(models);
|
|
25106
|
+
function enrichModelsForRuby(models, enums) {
|
|
25107
|
+
const enriched = enrichModelsFromSpec(models, enums);
|
|
24991
25108
|
const originalByName = new Map(models.map((m) => [m.name, m]));
|
|
24992
25109
|
return enriched.map((m) => {
|
|
24993
25110
|
if (m.discriminator && m.fields.length === 0) {
|
|
@@ -25003,7 +25120,7 @@ function enrichModelsForRuby(models) {
|
|
|
25003
25120
|
const rubyEmitter = {
|
|
25004
25121
|
language: "ruby",
|
|
25005
25122
|
generateModels(models, ctx) {
|
|
25006
|
-
return ensureTrailingNewlines$1(generateModels$1(enrichModelsForRuby(models), ctx));
|
|
25123
|
+
return ensureTrailingNewlines$1(generateModels$1(enrichModelsForRuby(models, ctx.spec.enums), ctx));
|
|
25007
25124
|
},
|
|
25008
25125
|
generateEnums(enums, ctx) {
|
|
25009
25126
|
const syntheticEnums = getSyntheticEnums();
|
|
@@ -25469,7 +25586,7 @@ function renderField(field, rustField, modelName, registry) {
|
|
|
25469
25586
|
function renderModelsBarrel(modules) {
|
|
25470
25587
|
const sorted = [...new Set(modules)].sort();
|
|
25471
25588
|
const lines = [];
|
|
25472
|
-
for (const m of sorted) lines.push(`
|
|
25589
|
+
for (const m of sorted) lines.push(`mod ${m};`);
|
|
25473
25590
|
lines.push("");
|
|
25474
25591
|
for (const m of sorted) lines.push(`pub use ${m}::*;`);
|
|
25475
25592
|
return lines.join("\n") + "\n";
|
|
@@ -26552,7 +26669,7 @@ function renderResourcesBarrel(exports) {
|
|
|
26552
26669
|
}
|
|
26553
26670
|
unique.sort((a, b) => a.module.localeCompare(b.module));
|
|
26554
26671
|
const lines = [];
|
|
26555
|
-
for (const { module } of unique) lines.push(`
|
|
26672
|
+
for (const { module } of unique) lines.push(`mod ${module};`);
|
|
26556
26673
|
lines.push("");
|
|
26557
26674
|
for (const { module, struct } of unique) lines.push(`pub use ${module}::${struct};`);
|
|
26558
26675
|
return lines.join("\n") + "\n";
|
|
@@ -27402,4 +27519,4 @@ const workosEmittersPlugin = {
|
|
|
27402
27519
|
//#endregion
|
|
27403
27520
|
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 };
|
|
27404
27521
|
|
|
27405
|
-
//# sourceMappingURL=plugin-
|
|
27522
|
+
//# sourceMappingURL=plugin-DRGwxN88.mjs.map
|