@workos/oagen 0.28.0 → 0.29.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/dist/cli/index.mjs +126 -23
- package/dist/cli/index.mjs.map +1 -1
- package/dist/compat/index.d.mts +2 -2
- package/dist/{diff-B9wlNAVX.mjs → diff-DqnHHXvr.mjs} +112 -13
- package/dist/diff-DqnHHXvr.mjs.map +1 -0
- package/dist/{differ-BoYl2n6Y.d.mts → differ-Co0fRniL.d.mts} +2 -2
- package/dist/{differ-BoYl2n6Y.d.mts.map → differ-Co0fRniL.d.mts.map} +1 -1
- package/dist/index.d.mts +28 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +18 -14
- package/dist/index.mjs.map +1 -1
- package/dist/scripts/smoke/baseline.mjs +16 -12
- package/dist/scripts/smoke/baseline.mjs.map +1 -1
- package/dist/smoke.d.mts +7 -0
- package/dist/smoke.d.mts.map +1 -1
- package/dist/smoke.mjs +16 -12
- package/dist/smoke.mjs.map +1 -1
- package/dist/tree-sitter-C6HB4OrC.mjs.map +1 -1
- package/dist/{types-CIAqYpcV.d.mts → types-DqKSnLBP.d.mts} +8 -1
- package/dist/{types-CIAqYpcV.d.mts.map → types-DqKSnLBP.d.mts.map} +1 -1
- package/dist/verify/index.d.mts +2 -2
- package/dist/verify/index.mjs +1 -1
- package/package.json +1 -1
- package/dist/diff-B9wlNAVX.mjs.map +0 -1
package/dist/cli/index.mjs
CHANGED
|
@@ -2255,20 +2255,24 @@ function extractBodyParameterGroups(op, operationContext) {
|
|
|
2255
2255
|
if (Object.keys(groupDef.variants).length === 0) continue;
|
|
2256
2256
|
const variants = Object.entries(groupDef.variants).map(([variantName, paramNames]) => {
|
|
2257
2257
|
if (!Array.isArray(paramNames) || paramNames.length === 0) throw new Error(`Malformed x-mutually-exclusive-body-groups.${groupName}.variants.${variantName} in ${operationContext}: expected a non-empty array of parameter names.`);
|
|
2258
|
+
const parameters = paramNames.map((pName) => {
|
|
2259
|
+
const fieldSchema = variantFieldSchemas.get(pName);
|
|
2260
|
+
return {
|
|
2261
|
+
name: pName,
|
|
2262
|
+
type: fieldSchema ? schemaToTypeRef(fieldSchema, toPascalCase(pName)) : {
|
|
2263
|
+
kind: "primitive",
|
|
2264
|
+
type: "string"
|
|
2265
|
+
},
|
|
2266
|
+
required: false,
|
|
2267
|
+
description: fieldSchema?.description
|
|
2268
|
+
};
|
|
2269
|
+
});
|
|
2270
|
+
const rawOptionalFields = groupDef.optionalFields && typeof groupDef.optionalFields === "object" ? groupDef.optionalFields[variantName] : void 0;
|
|
2271
|
+
const optionalParameters = Array.isArray(rawOptionalFields) ? rawOptionalFields.filter((name) => typeof name === "string" && paramNames.includes(name)) : [];
|
|
2258
2272
|
return {
|
|
2259
2273
|
name: variantName,
|
|
2260
|
-
parameters
|
|
2261
|
-
|
|
2262
|
-
return {
|
|
2263
|
-
name: pName,
|
|
2264
|
-
type: fieldSchema ? schemaToTypeRef(fieldSchema, toPascalCase(pName)) : {
|
|
2265
|
-
kind: "primitive",
|
|
2266
|
-
type: "string"
|
|
2267
|
-
},
|
|
2268
|
-
required: false,
|
|
2269
|
-
description: fieldSchema?.description
|
|
2270
|
-
};
|
|
2271
|
-
})
|
|
2274
|
+
parameters,
|
|
2275
|
+
...optionalParameters.length > 0 ? { optionalParameters } : {}
|
|
2272
2276
|
};
|
|
2273
2277
|
});
|
|
2274
2278
|
groups.push({
|
|
@@ -7360,14 +7364,107 @@ async function generateCommand(opts) {
|
|
|
7360
7364
|
}
|
|
7361
7365
|
}
|
|
7362
7366
|
//#endregion
|
|
7367
|
+
//#region src/differ/direction.ts
|
|
7368
|
+
/**
|
|
7369
|
+
* Classify every model in `specs` as request-facing, response-facing, both, or
|
|
7370
|
+
* unknown.
|
|
7371
|
+
*
|
|
7372
|
+
* Pass both the baseline and the candidate spec: a model that was request-facing
|
|
7373
|
+
* in either one keeps its request direction for the whole diff, so a schema that
|
|
7374
|
+
* moves request → response mid-release doesn't get that release's requiredness
|
|
7375
|
+
* changes silently downgraded.
|
|
7376
|
+
*
|
|
7377
|
+
* Models reachable from neither side (unreferenced schemas, or a spec whose
|
|
7378
|
+
* operations weren't supplied) stay `unknown`, which preserves the conservative
|
|
7379
|
+
* pre-direction classification.
|
|
7380
|
+
*/
|
|
7381
|
+
function buildDirectionIndex(...specs) {
|
|
7382
|
+
const models = /* @__PURE__ */ new Map();
|
|
7383
|
+
for (const spec of specs) for (const model of spec.models) if (!models.has(model.name)) models.set(model.name, model);
|
|
7384
|
+
const requestSeeds = [];
|
|
7385
|
+
const responseSeeds = [];
|
|
7386
|
+
for (const spec of specs) for (const service of spec.services) for (const op of service.operations) {
|
|
7387
|
+
if (op.requestBody) requestSeeds.push(op.requestBody);
|
|
7388
|
+
for (const param of [
|
|
7389
|
+
...op.pathParams,
|
|
7390
|
+
...op.queryParams,
|
|
7391
|
+
...op.headerParams,
|
|
7392
|
+
...op.cookieParams ?? []
|
|
7393
|
+
]) requestSeeds.push(param.type);
|
|
7394
|
+
responseSeeds.push(op.response);
|
|
7395
|
+
for (const success of op.successResponses ?? []) responseSeeds.push(success.type);
|
|
7396
|
+
for (const error of op.errors) if (error.type) responseSeeds.push(error.type);
|
|
7397
|
+
}
|
|
7398
|
+
const request = reachableModels(requestSeeds, models);
|
|
7399
|
+
const response = reachableModels(responseSeeds, models);
|
|
7400
|
+
const index = /* @__PURE__ */ new Map();
|
|
7401
|
+
for (const name of models.keys()) {
|
|
7402
|
+
const inRequest = request.has(name);
|
|
7403
|
+
const inResponse = response.has(name);
|
|
7404
|
+
index.set(name, inRequest && inResponse ? "both" : inRequest ? "request" : inResponse ? "response" : "unknown");
|
|
7405
|
+
}
|
|
7406
|
+
return index;
|
|
7407
|
+
}
|
|
7408
|
+
function directionOf(index, modelName) {
|
|
7409
|
+
return index?.get(modelName) ?? "unknown";
|
|
7410
|
+
}
|
|
7411
|
+
/**
|
|
7412
|
+
* Every model name reachable from `seeds`, following model fields (and
|
|
7413
|
+
* discriminated-union variants) transitively.
|
|
7414
|
+
*/
|
|
7415
|
+
function reachableModels(seeds, models) {
|
|
7416
|
+
const found = /* @__PURE__ */ new Set();
|
|
7417
|
+
const queue = [...seeds];
|
|
7418
|
+
while (queue.length > 0) {
|
|
7419
|
+
const ref = queue.pop();
|
|
7420
|
+
switch (ref.kind) {
|
|
7421
|
+
case "model": {
|
|
7422
|
+
if (found.has(ref.name)) break;
|
|
7423
|
+
found.add(ref.name);
|
|
7424
|
+
const model = models.get(ref.name);
|
|
7425
|
+
if (!model) break;
|
|
7426
|
+
for (const field of model.fields) queue.push(field.type);
|
|
7427
|
+
for (const variant of Object.values(model.discriminator?.mapping ?? {})) queue.push({
|
|
7428
|
+
kind: "model",
|
|
7429
|
+
name: variant
|
|
7430
|
+
});
|
|
7431
|
+
break;
|
|
7432
|
+
}
|
|
7433
|
+
case "array":
|
|
7434
|
+
queue.push(ref.items);
|
|
7435
|
+
break;
|
|
7436
|
+
case "nullable":
|
|
7437
|
+
queue.push(ref.inner);
|
|
7438
|
+
break;
|
|
7439
|
+
case "map":
|
|
7440
|
+
queue.push(ref.valueType);
|
|
7441
|
+
break;
|
|
7442
|
+
case "union":
|
|
7443
|
+
queue.push(...ref.variants);
|
|
7444
|
+
break;
|
|
7445
|
+
case "primitive":
|
|
7446
|
+
case "enum":
|
|
7447
|
+
case "literal": break;
|
|
7448
|
+
}
|
|
7449
|
+
}
|
|
7450
|
+
return found;
|
|
7451
|
+
}
|
|
7452
|
+
//#endregion
|
|
7363
7453
|
//#region src/differ/classify.ts
|
|
7364
|
-
function classifyFieldChange(kind, fieldName, isRequired) {
|
|
7454
|
+
function classifyFieldChange(kind, fieldName, isRequired, direction = "unknown") {
|
|
7365
7455
|
switch (kind) {
|
|
7366
|
-
case "field-added":
|
|
7367
|
-
|
|
7368
|
-
|
|
7369
|
-
|
|
7370
|
-
|
|
7456
|
+
case "field-added":
|
|
7457
|
+
if (isRequired && direction === "response") return {
|
|
7458
|
+
kind,
|
|
7459
|
+
fieldName,
|
|
7460
|
+
classification: "additive",
|
|
7461
|
+
details: "required on a response-only model"
|
|
7462
|
+
};
|
|
7463
|
+
return {
|
|
7464
|
+
kind,
|
|
7465
|
+
fieldName,
|
|
7466
|
+
classification: isRequired ? "breaking" : "additive"
|
|
7467
|
+
};
|
|
7371
7468
|
case "field-removed": return {
|
|
7372
7469
|
kind,
|
|
7373
7470
|
fieldName,
|
|
@@ -7432,7 +7529,12 @@ function classifyParamChange(kind, paramName, isRequired) {
|
|
|
7432
7529
|
}
|
|
7433
7530
|
//#endregion
|
|
7434
7531
|
//#region src/differ/models.ts
|
|
7435
|
-
|
|
7532
|
+
/**
|
|
7533
|
+
* `directions` (from `buildDirectionIndex`) lets requiredness changes be judged
|
|
7534
|
+
* against the side of the wire each model is used on. Omit it and every model is
|
|
7535
|
+
* treated as unknown-direction, i.e. the conservative classification.
|
|
7536
|
+
*/
|
|
7537
|
+
function diffModels(oldModels, newModels, directions) {
|
|
7436
7538
|
const changes = [];
|
|
7437
7539
|
const oldByName = new Map(oldModels.map((m) => [m.name, m]));
|
|
7438
7540
|
const newByName = new Map(newModels.map((m) => [m.name, m]));
|
|
@@ -7449,7 +7551,7 @@ function diffModels(oldModels, newModels) {
|
|
|
7449
7551
|
for (const [name, newModel] of newByName) {
|
|
7450
7552
|
const oldModel = oldByName.get(name);
|
|
7451
7553
|
if (!oldModel) continue;
|
|
7452
|
-
const fieldChanges = diffFields(oldModel, newModel);
|
|
7554
|
+
const fieldChanges = diffFields(oldModel, newModel, directionOf(directions, name));
|
|
7453
7555
|
if (fieldChanges.length > 0) {
|
|
7454
7556
|
const hasBreaking = fieldChanges.some((fc) => fc.classification === "breaking");
|
|
7455
7557
|
changes.push({
|
|
@@ -7462,11 +7564,11 @@ function diffModels(oldModels, newModels) {
|
|
|
7462
7564
|
}
|
|
7463
7565
|
return changes;
|
|
7464
7566
|
}
|
|
7465
|
-
function diffFields(oldModel, newModel) {
|
|
7567
|
+
function diffFields(oldModel, newModel, direction = "unknown") {
|
|
7466
7568
|
const changes = [];
|
|
7467
7569
|
const oldByName = new Map(oldModel.fields.map((f) => [f.name, f]));
|
|
7468
7570
|
const newByName = new Map(newModel.fields.map((f) => [f.name, f]));
|
|
7469
|
-
for (const [name, field] of newByName) if (!oldByName.has(name)) changes.push(classifyFieldChange("field-added", name, field.required));
|
|
7571
|
+
for (const [name, field] of newByName) if (!oldByName.has(name)) changes.push(classifyFieldChange("field-added", name, field.required, direction));
|
|
7470
7572
|
for (const [name] of oldByName) if (!newByName.has(name)) changes.push(classifyFieldChange("field-removed", name));
|
|
7471
7573
|
for (const [name, newField] of newByName) {
|
|
7472
7574
|
const oldField = oldByName.get(name);
|
|
@@ -7681,8 +7783,9 @@ function diffServices(oldServices, newServices) {
|
|
|
7681
7783
|
//#endregion
|
|
7682
7784
|
//#region src/differ/diff.ts
|
|
7683
7785
|
function diffSpecs(oldSpec, newSpec) {
|
|
7786
|
+
const directions = buildDirectionIndex(oldSpec, newSpec);
|
|
7684
7787
|
const changes = [
|
|
7685
|
-
...diffModels(oldSpec.models, newSpec.models),
|
|
7788
|
+
...diffModels(oldSpec.models, newSpec.models, directions),
|
|
7686
7789
|
...diffEnums(oldSpec.enums, newSpec.enums),
|
|
7687
7790
|
...diffServices(oldSpec.services, newSpec.services)
|
|
7688
7791
|
];
|