@postman-cse/onboarding-bootstrap 1.1.0 → 1.2.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/README.md +11 -8
- package/dist/action.cjs +308 -49
- package/dist/cli.cjs +308 -49
- package/dist/index.cjs +308 -49
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -49804,6 +49804,38 @@ function normalizeSchema(ctx, schema2, options) {
|
|
|
49804
49804
|
const sourceSchema = { ...record };
|
|
49805
49805
|
const nullable = sourceSchema.nullable === true && ctx.version === "3.0";
|
|
49806
49806
|
delete sourceSchema.nullable;
|
|
49807
|
+
const discriminator = asRecord3(sourceSchema.discriminator);
|
|
49808
|
+
if (discriminator && typeof discriminator.propertyName === "string" && discriminator.propertyName) {
|
|
49809
|
+
const propertyName = discriminator.propertyName;
|
|
49810
|
+
const branchKey = Array.isArray(sourceSchema.oneOf) ? "oneOf" : Array.isArray(sourceSchema.anyOf) ? "anyOf" : "";
|
|
49811
|
+
const members = branchKey ? sourceSchema[branchKey] : [];
|
|
49812
|
+
const memberRefs = members.map((member) => {
|
|
49813
|
+
const memberRecord = asRecord3(member);
|
|
49814
|
+
const memberRef = memberRecord && Object.keys(memberRecord).length === 1 && typeof memberRecord.$ref === "string" ? memberRecord.$ref : "";
|
|
49815
|
+
return memberRef.startsWith("#/") ? memberRef : "";
|
|
49816
|
+
});
|
|
49817
|
+
if (branchKey && members.length > 0 && memberRefs.every(Boolean)) {
|
|
49818
|
+
const valuesByRef = /* @__PURE__ */ new Map();
|
|
49819
|
+
const refByMappingKey = /* @__PURE__ */ new Map();
|
|
49820
|
+
for (const [value, target] of Object.entries(asRecord3(discriminator.mapping) ?? {})) {
|
|
49821
|
+
if (typeof target !== "string" || !target) continue;
|
|
49822
|
+
const targetRef = target.startsWith("#/") ? target : `#/components/schemas/${target}`;
|
|
49823
|
+
valuesByRef.set(targetRef, [...valuesByRef.get(targetRef) ?? [], value]);
|
|
49824
|
+
refByMappingKey.set(value, targetRef);
|
|
49825
|
+
}
|
|
49826
|
+
sourceSchema[branchKey] = members.map((member, index) => {
|
|
49827
|
+
const memberRef = memberRefs[index] ?? "";
|
|
49828
|
+
const tail = (memberRef.split("/").pop() ?? "").replace(/~1/g, "/").replace(/~0/g, "~");
|
|
49829
|
+
const values = [...valuesByRef.get(memberRef) ?? []];
|
|
49830
|
+
const tailClaimedElsewhere = refByMappingKey.has(tail) && refByMappingKey.get(tail) !== memberRef;
|
|
49831
|
+
if (tail && !tailClaimedElsewhere && !values.includes(tail)) values.push(tail);
|
|
49832
|
+
const dispatch = values.length === 1 ? { const: values[0] } : { enum: values };
|
|
49833
|
+
return { allOf: [member, { type: "object", required: [propertyName], properties: { [propertyName]: dispatch } }] };
|
|
49834
|
+
});
|
|
49835
|
+
} else {
|
|
49836
|
+
ctx.notes.add("discriminator");
|
|
49837
|
+
}
|
|
49838
|
+
}
|
|
49807
49839
|
const directionStrippedFlag = ctx.direction === "request" ? "readOnly" : "writeOnly";
|
|
49808
49840
|
const strippedProperties = /* @__PURE__ */ new Set();
|
|
49809
49841
|
const rawProperties = asRecord3(sourceSchema.properties);
|
|
@@ -49976,7 +50008,7 @@ function packSchema(root, schema2, version, direction = "response") {
|
|
|
49976
50008
|
if (schema2 === true) return { schema: { $schema: rootDialect(root, version) } };
|
|
49977
50009
|
if (schema2 === false) return unsupported("Boolean false JSON Schema rejects every instance and is unsupported");
|
|
49978
50010
|
const dialect = rootDialect(root, version, asRecord3(schema2) ?? void 0);
|
|
49979
|
-
const ctx = { root, version, direction, dialect, defs: /* @__PURE__ */ new Map() };
|
|
50011
|
+
const ctx = { root, version, direction, dialect, defs: /* @__PURE__ */ new Map(), notes: /* @__PURE__ */ new Set() };
|
|
49980
50012
|
const normalized = normalizeSchema(ctx, schema2, { depth: 0, rootSchema: true });
|
|
49981
50013
|
const message = hasUnsupported(normalized);
|
|
49982
50014
|
if (message) return unsupported(message);
|
|
@@ -50001,7 +50033,9 @@ function packSchema(root, schema2, version, direction = "response") {
|
|
|
50001
50033
|
if (!normalizedRecord) return unsupported("Referenced schemas require an object root schema");
|
|
50002
50034
|
normalizedRecord.$defs = Object.fromEntries([...ctx.defs.values()].map((entry) => [entry.name, entry.schema]));
|
|
50003
50035
|
}
|
|
50004
|
-
|
|
50036
|
+
const packed = { schema: normalized };
|
|
50037
|
+
if (ctx.notes.size > 0) packed.notes = [...ctx.notes].sort();
|
|
50038
|
+
return packed;
|
|
50005
50039
|
} catch (error2) {
|
|
50006
50040
|
return unsupported(error2 instanceof Error ? error2.message : String(error2));
|
|
50007
50041
|
}
|
|
@@ -50174,6 +50208,7 @@ function securityCheckFor(schemeName, scheme) {
|
|
|
50174
50208
|
const httpScheme = String(scheme.scheme || "").toLowerCase();
|
|
50175
50209
|
if (httpScheme === "basic") return { scheme: schemeName, kind, checkable: true, prefix: "Basic " };
|
|
50176
50210
|
if (httpScheme === "bearer") return { scheme: schemeName, kind, checkable: true, prefix: "Bearer " };
|
|
50211
|
+
if (httpScheme) return { scheme: schemeName, kind, checkable: true, prefix: `${httpScheme.charAt(0).toUpperCase()}${httpScheme.slice(1)} ` };
|
|
50177
50212
|
return { scheme: schemeName, kind, checkable: true, in: "header", name: "Authorization" };
|
|
50178
50213
|
}
|
|
50179
50214
|
if (scheme?.type === "oauth2" || scheme?.type === "openIdConnect") {
|
|
@@ -50207,7 +50242,18 @@ var IGNORED_HEADER_PARAMS = /* @__PURE__ */ new Set(["accept", "content-type", "
|
|
|
50207
50242
|
function isIgnoredParameter(location2, name) {
|
|
50208
50243
|
return location2 === "header" && IGNORED_HEADER_PARAMS.has(name.toLowerCase());
|
|
50209
50244
|
}
|
|
50210
|
-
function
|
|
50245
|
+
function jsonContentParameterMedia(param) {
|
|
50246
|
+
const content = asRecord4(param.content);
|
|
50247
|
+
if (!content) return void 0;
|
|
50248
|
+
const entries = Object.entries(content);
|
|
50249
|
+
if (entries.length !== 1) return void 0;
|
|
50250
|
+
const [contentType, mediaObject] = entries[0];
|
|
50251
|
+
const base = contentType.toLowerCase().split(";")[0]?.trim() ?? "";
|
|
50252
|
+
if (!isJsonBaseType(base)) return void 0;
|
|
50253
|
+
const schema2 = asRecord4(mediaObject)?.schema;
|
|
50254
|
+
return schema2 === void 0 ? void 0 : schema2;
|
|
50255
|
+
}
|
|
50256
|
+
function collectSerializationWarnings(root, pathItem, operation, decodedKeys) {
|
|
50211
50257
|
const warnings = [];
|
|
50212
50258
|
for (const param of resolvedParameters(root, pathItem, operation)) {
|
|
50213
50259
|
const location2 = String(param.in || "").toLowerCase();
|
|
@@ -50217,7 +50263,9 @@ function collectSerializationWarnings(root, pathItem, operation) {
|
|
|
50217
50263
|
const style = typeof param.style === "string" ? param.style : defaultStyle;
|
|
50218
50264
|
const defaultExplode = style === "form";
|
|
50219
50265
|
const explode = typeof param.explode === "boolean" ? param.explode : defaultExplode;
|
|
50220
|
-
|
|
50266
|
+
const unvalidatedContent = param.content !== void 0 && (jsonContentParameterMedia(param) === void 0 || location2 !== "query" && location2 !== "header");
|
|
50267
|
+
if (style !== defaultStyle || explode !== defaultExplode || param.allowReserved === true || unvalidatedContent) {
|
|
50268
|
+
if (decodedKeys.has(`${location2}:${name.toLowerCase()}`) && param.allowReserved !== true && param.content === void 0) continue;
|
|
50221
50269
|
warnings.push(`CONTRACT_PARAM_SERIALIZATION_NOT_VALIDATED: parameter ${location2}:${name} declares non-default style, explode, allowReserved, or content and its serialization is not validated`);
|
|
50222
50270
|
}
|
|
50223
50271
|
}
|
|
@@ -50232,7 +50280,27 @@ function packedScalarSchema(packed) {
|
|
|
50232
50280
|
if (!types2.every((entry) => typeof entry === "string" && SCALAR_SCHEMA_TYPES.has(entry))) return void 0;
|
|
50233
50281
|
return packed.schema;
|
|
50234
50282
|
}
|
|
50235
|
-
function
|
|
50283
|
+
function packedArrayItemsSchema(packed) {
|
|
50284
|
+
if (packed.unsupported || packed.schema === void 0) return void 0;
|
|
50285
|
+
const record = asRecord4(packed.schema);
|
|
50286
|
+
if (!record) return void 0;
|
|
50287
|
+
const types2 = Array.isArray(record.type) ? record.type : [record.type];
|
|
50288
|
+
if (types2.length !== 1 || types2[0] !== "array") return void 0;
|
|
50289
|
+
if (record.prefixItems !== void 0 || Array.isArray(record.items)) return void 0;
|
|
50290
|
+
if (record.items === void 0) return {};
|
|
50291
|
+
const items = asRecord4(record.items);
|
|
50292
|
+
if (!items || typeof items.$ref === "string") return void 0;
|
|
50293
|
+
const itemTypes = Array.isArray(items.type) ? items.type : [items.type];
|
|
50294
|
+
if (!itemTypes.every((entry) => typeof entry === "string" && SCALAR_SCHEMA_TYPES.has(entry))) return void 0;
|
|
50295
|
+
return items;
|
|
50296
|
+
}
|
|
50297
|
+
var QUERY_ARRAY_DECODES = {
|
|
50298
|
+
"form:true": "multi",
|
|
50299
|
+
"form:false": "csv",
|
|
50300
|
+
"spaceDelimited:false": "ssv",
|
|
50301
|
+
"pipeDelimited:false": "pipes"
|
|
50302
|
+
};
|
|
50303
|
+
function collectParameterChecks(root, pathItem, operation, version, operationId, pathTemplate, warnings) {
|
|
50236
50304
|
const securityKeys = collectSecurityApiKeys(root, operation);
|
|
50237
50305
|
const checks = [];
|
|
50238
50306
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -50245,32 +50313,65 @@ function collectParameterChecks(root, pathItem, operation, version, operationId,
|
|
|
50245
50313
|
}).filter((param) => Boolean(param));
|
|
50246
50314
|
for (const param of orderedParams) {
|
|
50247
50315
|
const location2 = String(param.in || "").toLowerCase();
|
|
50248
|
-
if (location2 !== "query" && location2 !== "header") continue;
|
|
50316
|
+
if (location2 !== "query" && location2 !== "header" && location2 !== "path" && location2 !== "cookie") continue;
|
|
50249
50317
|
const name = String(param.name || "");
|
|
50250
50318
|
if (!name || isIgnoredParameter(location2, name)) continue;
|
|
50251
50319
|
const key = `${location2}:${name.toLowerCase()}`;
|
|
50252
50320
|
if (seen.has(key)) continue;
|
|
50253
50321
|
seen.add(key);
|
|
50254
50322
|
if (securityKeys.has(key)) continue;
|
|
50323
|
+
const contentMedia = jsonContentParameterMedia(param);
|
|
50324
|
+
if (contentMedia !== void 0 && (location2 === "query" || location2 === "header")) {
|
|
50325
|
+
const packed2 = packSchema(root, contentMedia, version, "request");
|
|
50326
|
+
warnings.push(...packNoteWarnings(packed2, `parameter ${location2}:${name} of ${operationId}`));
|
|
50327
|
+
if (packed2.unsupported) {
|
|
50328
|
+
warnings.push(`CONTRACT_SCHEMA_NOT_COMPILED: parameter ${location2}:${name} schema on ${operationId} skipped (${packed2.unsupported})`);
|
|
50329
|
+
} else if (packed2.schema !== void 0) {
|
|
50330
|
+
const check2 = { in: location2, name, required: param.required === true, content: true, schema: packed2.schema };
|
|
50331
|
+
if (location2 === "query" && param.allowEmptyValue === true) check2.allowEmptyValue = true;
|
|
50332
|
+
checks.push(check2);
|
|
50333
|
+
}
|
|
50334
|
+
continue;
|
|
50335
|
+
}
|
|
50255
50336
|
if (param.content !== void 0 || param.schema === void 0) continue;
|
|
50256
50337
|
const defaultStyle = DEFAULT_PARAM_STYLES[location2];
|
|
50257
50338
|
const style = typeof param.style === "string" ? param.style : defaultStyle;
|
|
50258
50339
|
const defaultExplode = style === "form";
|
|
50259
50340
|
const explode = typeof param.explode === "boolean" ? param.explode : defaultExplode;
|
|
50260
|
-
|
|
50341
|
+
const defaultSerialization = style === defaultStyle && explode === defaultExplode;
|
|
50261
50342
|
const packed = packSchema(root, param.schema, version);
|
|
50343
|
+
const noteWarnings = packNoteWarnings(packed, `parameter ${location2}:${name} of ${operationId}`);
|
|
50344
|
+
if (defaultSerialization) warnings.push(...noteWarnings);
|
|
50262
50345
|
if (packed.unsupported) {
|
|
50263
|
-
warnings.push(`CONTRACT_SCHEMA_NOT_COMPILED: parameter ${location2}:${name} schema on ${operationId} skipped (${packed.unsupported})`);
|
|
50346
|
+
if (defaultSerialization) warnings.push(`CONTRACT_SCHEMA_NOT_COMPILED: parameter ${location2}:${name} schema on ${operationId} skipped (${packed.unsupported})`);
|
|
50264
50347
|
continue;
|
|
50265
50348
|
}
|
|
50266
|
-
|
|
50267
|
-
|
|
50268
|
-
|
|
50349
|
+
if (location2 === "path" && !pathTemplate.split("/").includes(`{${name}}`)) continue;
|
|
50350
|
+
const scalarSchema = packedScalarSchema(packed);
|
|
50351
|
+
if (scalarSchema !== void 0) {
|
|
50352
|
+
if (!defaultSerialization) continue;
|
|
50353
|
+
const check2 = { in: location2, name, required: param.required === true, schema: scalarSchema };
|
|
50354
|
+
if (location2 === "query" && param.allowEmptyValue === true) check2.allowEmptyValue = true;
|
|
50355
|
+
checks.push(check2);
|
|
50356
|
+
continue;
|
|
50357
|
+
}
|
|
50358
|
+
if (location2 !== "query" && location2 !== "header") continue;
|
|
50359
|
+
const items = packedArrayItemsSchema(packed);
|
|
50360
|
+
if (items === void 0) continue;
|
|
50361
|
+
const decode = location2 === "query" ? QUERY_ARRAY_DECODES[`${style}:${explode}`] : style === "simple" && !explode ? "csv" : void 0;
|
|
50362
|
+
if (!decode) continue;
|
|
50363
|
+
if (!defaultSerialization) warnings.push(...noteWarnings);
|
|
50364
|
+
const check = { in: location2, name, required: param.required === true, schema: packed.schema, decode, items };
|
|
50269
50365
|
if (location2 === "query" && param.allowEmptyValue === true) check.allowEmptyValue = true;
|
|
50270
50366
|
checks.push(check);
|
|
50271
50367
|
}
|
|
50272
50368
|
return checks.length > 0 ? checks : void 0;
|
|
50273
50369
|
}
|
|
50370
|
+
function packNoteWarnings(packed, context) {
|
|
50371
|
+
return (packed.notes ?? []).map(
|
|
50372
|
+
(note) => note === "discriminator" ? `CONTRACT_DISCRIMINATOR_NOT_VALIDATED: discriminator on ${context} has no sibling oneOf/anyOf of internal $ref members and is not validated` : `CONTRACT_SCHEMA_NOT_COMPILED: ${note} on ${context} is not validated`
|
|
50373
|
+
);
|
|
50374
|
+
}
|
|
50274
50375
|
function collectDeclaredQueryParameters(root, pathItem, operation) {
|
|
50275
50376
|
const names = /* @__PURE__ */ new Set();
|
|
50276
50377
|
for (const param of resolvedParameters(root, pathItem, operation)) {
|
|
@@ -50348,7 +50449,10 @@ function propertyIsBinary(root, properties, name) {
|
|
|
50348
50449
|
}
|
|
50349
50450
|
if (!schema2) return false;
|
|
50350
50451
|
if (schema2.format === "binary") return true;
|
|
50351
|
-
|
|
50452
|
+
if (typeof schema2.contentMediaType !== "string" || typeof schema2.contentEncoding === "string") return false;
|
|
50453
|
+
const media = schema2.contentMediaType.toLowerCase().split(";")[0]?.trim() ?? "";
|
|
50454
|
+
if (!media) return false;
|
|
50455
|
+
return media !== "application/json" && !media.endsWith("+json") && !media.startsWith("text/");
|
|
50352
50456
|
}
|
|
50353
50457
|
function fieldEncodings(root, base, mediaObject, properties) {
|
|
50354
50458
|
const declared = asRecord4(mediaObject?.encoding);
|
|
@@ -50366,6 +50470,9 @@ function fieldEncodings(root, base, mediaObject, properties) {
|
|
|
50366
50470
|
if (typeof encoding.contentType === "string" && encoding.contentType.trim()) {
|
|
50367
50471
|
entry.contentType = encoding.contentType.toLowerCase();
|
|
50368
50472
|
}
|
|
50473
|
+
if (base === "multipart/form-data" && asRecord4(encoding.headers)) {
|
|
50474
|
+
entry.hasHeaders = true;
|
|
50475
|
+
}
|
|
50369
50476
|
if (base === "application/x-www-form-urlencoded") {
|
|
50370
50477
|
const style = typeof encoding.style === "string" ? encoding.style : "form";
|
|
50371
50478
|
const explode = typeof encoding.explode === "boolean" ? encoding.explode : style === "form";
|
|
@@ -50378,7 +50485,22 @@ function fieldEncodings(root, base, mediaObject, properties) {
|
|
|
50378
50485
|
}
|
|
50379
50486
|
return Object.keys(encodings).length > 0 ? encodings : void 0;
|
|
50380
50487
|
}
|
|
50381
|
-
function
|
|
50488
|
+
function formFieldSchemas(root, version, properties, context, warnings) {
|
|
50489
|
+
const schemas = {};
|
|
50490
|
+
for (const name of Object.keys(properties)) {
|
|
50491
|
+
const packed = packSchema(root, properties[name], version, "request");
|
|
50492
|
+
warnings.push(...packNoteWarnings(packed, `field ${name} of ${context}`));
|
|
50493
|
+
if (packed.unsupported) {
|
|
50494
|
+
warnings.push(`CONTRACT_SCHEMA_NOT_COMPILED: field ${name} of ${context} skipped (${packed.unsupported})`);
|
|
50495
|
+
continue;
|
|
50496
|
+
}
|
|
50497
|
+
if (packed.schema === void 0) continue;
|
|
50498
|
+
const schema2 = packedScalarSchema(packed);
|
|
50499
|
+
if (schema2 !== void 0) schemas[name] = schema2;
|
|
50500
|
+
}
|
|
50501
|
+
return Object.keys(schemas).length > 0 ? schemas : void 0;
|
|
50502
|
+
}
|
|
50503
|
+
function requestBodyFieldRules(root, content, version, operationId, warnings) {
|
|
50382
50504
|
const rules = {};
|
|
50383
50505
|
for (const [contentType, mediaObject] of Object.entries(content)) {
|
|
50384
50506
|
const base = contentType.toLowerCase().split(";")[0]?.trim() ?? "";
|
|
@@ -50388,10 +50510,13 @@ function requestBodyFieldRules(root, content) {
|
|
|
50388
50510
|
if (!merged) continue;
|
|
50389
50511
|
const readOnly = Object.keys(merged.properties).filter((name) => propertyIsReadOnly(root, merged.properties, name));
|
|
50390
50512
|
const required = merged.required.filter((name) => !propertyIsReadOnly(root, merged.properties, name));
|
|
50391
|
-
const
|
|
50392
|
-
|
|
50513
|
+
const formRules = BODY_FIELD_RULE_TYPES.has(base);
|
|
50514
|
+
const encodings = formRules ? fieldEncodings(root, base, mediaRecord, merged.properties) : void 0;
|
|
50515
|
+
const fieldSchemas = formRules ? formFieldSchemas(root, version, merged.properties, `request body ${contentType} of ${operationId}`, warnings) : void 0;
|
|
50516
|
+
if (required.length > 0 || readOnly.length > 0 || encodings || fieldSchemas) {
|
|
50393
50517
|
const rule = { required, readOnly };
|
|
50394
50518
|
if (encodings) rule.encodings = encodings;
|
|
50519
|
+
if (fieldSchemas) rule.fieldSchemas = fieldSchemas;
|
|
50395
50520
|
rules[base] = rule;
|
|
50396
50521
|
}
|
|
50397
50522
|
}
|
|
@@ -50412,6 +50537,7 @@ function requestBodyJsonSchemas(root, content, version, operationId, warnings) {
|
|
|
50412
50537
|
}
|
|
50413
50538
|
if (schema2 === void 0) continue;
|
|
50414
50539
|
const packed = packSchema(root, schema2, version, "request");
|
|
50540
|
+
warnings.push(...packNoteWarnings(packed, `request body ${contentType} of ${operationId}`));
|
|
50415
50541
|
if (mediaRecord) validateExamples(root, mediaRecord, packed, contentType, operationId, exampleWarnings);
|
|
50416
50542
|
if (packed.unsupported) {
|
|
50417
50543
|
warnings.push(`CONTRACT_REQUEST_SCHEMA_NOT_VALIDATED: request body schema for ${contentType} on ${operationId} is not validated (${packed.unsupported})`);
|
|
@@ -50426,7 +50552,7 @@ function collectRequestBody(root, operation, version, operationId, warnings) {
|
|
|
50426
50552
|
const body = resolveInternalRef(root, operation.requestBody);
|
|
50427
50553
|
if (!body) return void 0;
|
|
50428
50554
|
const content = asRecord4(body.content);
|
|
50429
|
-
const fieldRules = content ? requestBodyFieldRules(root, content) : void 0;
|
|
50555
|
+
const fieldRules = content ? requestBodyFieldRules(root, content, version, operationId, warnings) : void 0;
|
|
50430
50556
|
if (fieldRules) {
|
|
50431
50557
|
for (const [base, rule] of Object.entries(fieldRules)) {
|
|
50432
50558
|
for (const [field, encoding] of Object.entries(rule.encodings ?? {})) {
|
|
@@ -50435,6 +50561,11 @@ function collectRequestBody(root, operation, version, operationId, warnings) {
|
|
|
50435
50561
|
`CONTRACT_PARAM_SERIALIZATION_NOT_VALIDATED: ${base} request body field ${field} on ${operationId} declares non-default encoding style, explode, or allowReserved and its serialization is not validated`
|
|
50436
50562
|
);
|
|
50437
50563
|
}
|
|
50564
|
+
if (encoding.hasHeaders) {
|
|
50565
|
+
warnings.push(
|
|
50566
|
+
`CONTRACT_ENCODING_HEADERS_NOT_VALIDATED: ${base} request body field ${field} on ${operationId} declares per-part headers that generated formdata entries cannot carry`
|
|
50567
|
+
);
|
|
50568
|
+
}
|
|
50438
50569
|
}
|
|
50439
50570
|
}
|
|
50440
50571
|
}
|
|
@@ -50482,6 +50613,7 @@ function responseContent(root, version, response, context, warnings) {
|
|
|
50482
50613
|
const mediaRecord = asRecord4(mediaObject);
|
|
50483
50614
|
const schema2 = mediaRecord?.schema;
|
|
50484
50615
|
let packed = schema2 === void 0 ? {} : packSchema(root, schema2, version);
|
|
50616
|
+
for (const warning2 of packNoteWarnings(packed, `response ${contentType} of ${context}`)) warnings.add(warning2);
|
|
50485
50617
|
if (isSchemaGraphOverflow(packed)) {
|
|
50486
50618
|
warnings.add(`CONTRACT_SCHEMA_NOT_COMPILED: response schema for ${contentType} on ${context} skipped (${packed.unsupported})`);
|
|
50487
50619
|
packed = {};
|
|
@@ -50513,12 +50645,18 @@ function responseHeaders(root, version, response, context, warnings) {
|
|
|
50513
50645
|
continue;
|
|
50514
50646
|
}
|
|
50515
50647
|
const packed = packSchema(root, header.schema, version);
|
|
50648
|
+
for (const warning2 of packNoteWarnings(packed, `response header ${name} of ${context}`)) warnings.add(warning2);
|
|
50516
50649
|
if (isSchemaGraphOverflow(packed)) {
|
|
50517
50650
|
warnings.add(`CONTRACT_SCHEMA_NOT_COMPILED: response header ${name} schema on ${context} skipped (${packed.unsupported})`);
|
|
50518
50651
|
entries.push({ name, required });
|
|
50519
50652
|
continue;
|
|
50520
50653
|
}
|
|
50521
50654
|
if (!packed.unsupported && packed.schema !== void 0 && packedScalarSchema(packed) === void 0) {
|
|
50655
|
+
const items = packedArrayItemsSchema(packed);
|
|
50656
|
+
if (items !== void 0) {
|
|
50657
|
+
entries.push({ name, required, schema: packed.schema, items });
|
|
50658
|
+
continue;
|
|
50659
|
+
}
|
|
50522
50660
|
warnings.add(`CONTRACT_HEADER_SCHEMA_NOT_VALIDATED: response header ${name} on ${context} declares a non-scalar schema and its value is not validated`);
|
|
50523
50661
|
entries.push({ name, required });
|
|
50524
50662
|
continue;
|
|
@@ -50577,10 +50715,14 @@ function buildContractIndex(root) {
|
|
|
50577
50715
|
path8,
|
|
50578
50716
|
...operationServers(root, pathItem, operation).map((server) => joinPaths(serverPathPrefix(server), path8))
|
|
50579
50717
|
].map(normalizePath))];
|
|
50718
|
+
const operationId = `${lowerMethod.toUpperCase()} ${path8}`;
|
|
50580
50719
|
const opWarnings = [];
|
|
50581
50720
|
opWarnings.push(...responseWarnings);
|
|
50582
50721
|
opWarnings.push(...collectSecuritySchemeWarnings(root, operation));
|
|
50583
|
-
|
|
50722
|
+
const parameterChecks = collectParameterChecks(root, pathItem, operation, version, operationId, path8, opWarnings);
|
|
50723
|
+
const checkedKeys = new Set((parameterChecks ?? []).map((check) => `${check.in}:${check.name.toLowerCase()}`));
|
|
50724
|
+
const decodedKeys = new Set((parameterChecks ?? []).filter((check) => check.decode).map((check) => `${check.in}:${check.name.toLowerCase()}`));
|
|
50725
|
+
opWarnings.push(...collectSerializationWarnings(root, pathItem, operation, decodedKeys));
|
|
50584
50726
|
if (operation.deprecated === true) {
|
|
50585
50727
|
opWarnings.push(`CONTRACT_OPERATION_DEPRECATED: ${lowerMethod.toUpperCase()} ${path8} is marked deprecated in the OpenAPI document`);
|
|
50586
50728
|
}
|
|
@@ -50589,17 +50731,19 @@ function buildContractIndex(root) {
|
|
|
50589
50731
|
opWarnings.push(`CONTRACT_SECURITY_NOT_VALIDATED: security parameter ${parameter.in}:${parameter.name} is not statically required in generated requests`);
|
|
50590
50732
|
}
|
|
50591
50733
|
for (const parameter of requiredParameters.filter((entry) => entry.in === "cookie" && !entry.securityDerived)) {
|
|
50592
|
-
opWarnings.push(`CONTRACT_COOKIE_PARAM_NOT_VALIDATED: required cookie parameter ${parameter.name} is not
|
|
50734
|
+
opWarnings.push(checkedKeys.has(`cookie:${parameter.name.toLowerCase()}`) ? `CONTRACT_COOKIE_PARAM_NOT_VALIDATED: required cookie parameter ${parameter.name} is not included in generated requests; the runtime test fails until the cookie is supplied at send time` : `CONTRACT_COOKIE_PARAM_NOT_VALIDATED: required cookie parameter ${parameter.name} is not included in generated requests and its value is not runtime-validated`);
|
|
50593
50735
|
}
|
|
50594
50736
|
const pathParamWarnings = /* @__PURE__ */ new Set();
|
|
50595
50737
|
for (const param of resolvedParameters(root, pathItem, operation)) {
|
|
50596
50738
|
if (String(param.in || "").toLowerCase() !== "path") continue;
|
|
50597
50739
|
const name = String(param.name || "");
|
|
50598
|
-
if (name
|
|
50740
|
+
if (name && !checkedKeys.has(`path:${name.toLowerCase()}`)) {
|
|
50741
|
+
pathParamWarnings.add(`CONTRACT_PATH_PARAM_NOT_VALIDATED: path parameter ${name} value is not validated at runtime`);
|
|
50742
|
+
}
|
|
50599
50743
|
}
|
|
50600
50744
|
opWarnings.push(...pathParamWarnings);
|
|
50601
50745
|
operations.push({
|
|
50602
|
-
id:
|
|
50746
|
+
id: operationId,
|
|
50603
50747
|
method: lowerMethod.toUpperCase(),
|
|
50604
50748
|
path: path8,
|
|
50605
50749
|
pointer: `/paths/${path8.replace(/~/g, "~0").replace(/\//g, "~1")}/${lowerMethod}`,
|
|
@@ -50607,8 +50751,8 @@ function buildContractIndex(root) {
|
|
|
50607
50751
|
responses: contractResponses,
|
|
50608
50752
|
requiredParameters,
|
|
50609
50753
|
declaredQueryParameters: collectDeclaredQueryParameters(root, pathItem, operation),
|
|
50610
|
-
parameterChecks
|
|
50611
|
-
requestBody: collectRequestBody(root, operation, version,
|
|
50754
|
+
parameterChecks,
|
|
50755
|
+
requestBody: collectRequestBody(root, operation, version, operationId, opWarnings),
|
|
50612
50756
|
security: collectSecurityRuntimeChecks(root, operation),
|
|
50613
50757
|
warnings: opWarnings
|
|
50614
50758
|
});
|
|
@@ -50815,8 +50959,11 @@ function createContractScript(operation, warnings = []) {
|
|
|
50815
50959
|
" if (!actual) return;",
|
|
50816
50960
|
' if (header.unsupported) pm.expect.fail("OpenAPI response header unsupported for " + contract.method + " " + contract.path + ": " + header.unsupported);',
|
|
50817
50961
|
" var headerValidator = validators[selected.key] && validators[selected.key].__headers && validators[selected.key].__headers[String(header.name).toLowerCase()];",
|
|
50818
|
-
" if (headerValidator
|
|
50819
|
-
|
|
50962
|
+
" if (!headerValidator || headerValidator.skip) return;",
|
|
50963
|
+
" var expected;",
|
|
50964
|
+
' if (header.items) { var joined = String(actual).trim(); expected = joined === "" ? [] : joined.split(",").map(function (entry) { return coerceBySchema(entry.trim(), header.items); }); }',
|
|
50965
|
+
" else expected = coerceBySchema(actual, header.schema);",
|
|
50966
|
+
' if (!headerValidator(expected)) pm.expect.fail("OpenAPI response header validation failed for " + header.name + ": " + JSON.stringify(headerValidator.errors || []));',
|
|
50820
50967
|
" });",
|
|
50821
50968
|
"});",
|
|
50822
50969
|
"pm.test('Response body matches OpenAPI body contract', function () {",
|
|
@@ -50872,17 +51019,64 @@ function createContractScript(operation, warnings = []) {
|
|
|
50872
51019
|
...operation.parameterChecks && operation.parameterChecks.length > 0 ? [
|
|
50873
51020
|
"pm.test('Request parameters match OpenAPI schemas', function () {",
|
|
50874
51021
|
' function queryValue(name) { var value; pm.request.url.query.each(function (param) { if (param && param.disabled !== true && String(param.key).toLowerCase() === name) value = param.value === null || param.value === undefined ? "" : String(param.value); }); return value; }',
|
|
51022
|
+
' function queryValues(name) { var values = []; pm.request.url.query.each(function (param) { if (param && param.disabled !== true && String(param.key).toLowerCase() === name) values.push(param.value === null || param.value === undefined ? "" : String(param.value)); }); return values; }',
|
|
50875
51023
|
' function headerValue(name) { var value; pm.request.headers.each(function (header) { if (header && header.disabled !== true && String(header.key).toLowerCase() === String(name).toLowerCase()) value = header.value === null || header.value === undefined ? "" : String(header.value); }); return value; }',
|
|
51024
|
+
' function cookieValue(name) { try { if (pm.cookies && pm.cookies.get) { var jar = pm.cookies.get(String(name)); if (jar !== null && jar !== undefined) return String(jar); } } catch (ignored) {} var raw = requestHeader("Cookie"); if (!raw) return undefined; var found; raw.split(";").forEach(function (part) { var split = part.indexOf("="); if (split === -1) return; if (part.slice(0, split).trim() === String(name)) found = part.slice(split + 1).trim(); }); return found; }',
|
|
51025
|
+
' function requestPathSegments() { var raw = ""; try { raw = typeof pm.request.url.getPath === "function" ? String(pm.request.url.getPath() || "") : ""; } catch (ignored) {} if (!raw) { var path = pm.request.url.path; raw = Array.isArray(path) ? "/" + path.join("/") : String(path || ""); } return raw.split("?")[0].split("#")[0].split("/").filter(function (segment) { return segment.length > 0; }); }',
|
|
51026
|
+
// Server path prefixes sit ahead of the template segments, so the
|
|
51027
|
+
// template aligns against the trailing request segments.
|
|
51028
|
+
' function pathParamValue(name) { var template = String(contract.path).split("/").filter(function (segment) { return segment.length > 0; }); var actual = requestPathSegments(); var offset = actual.length - template.length; if (offset < 0) return undefined; for (var i = 0; i < template.length; i += 1) { if (template[i] === "{" + name + "}") { var segment = actual[offset + i]; try { return decodeURIComponent(segment); } catch (ignored) { return segment; } } } return undefined; }',
|
|
50876
51029
|
' function isPlaceholder(value) { var text = String(value).trim(); return /^<[^<>]*>$/.test(text) || text.indexOf("{{") !== -1; }',
|
|
51030
|
+
' function splitDelimited(value, decode) { if (decode === "csv") return value.split(","); if (decode === "ssv") return value.split(/%20| /); return value.split(/%7C|\\|/i); }',
|
|
51031
|
+
" function decodeComponent(value) { try { return decodeURIComponent(value); } catch (ignored) { return value; } }",
|
|
50877
51032
|
" (contract.parameters || []).forEach(function (param) {",
|
|
50878
51033
|
' var key = param.in + ":" + String(param.name).toLowerCase();',
|
|
50879
51034
|
" var validate = paramValidators[key];",
|
|
50880
51035
|
" if (!validate || validate.skip) return;",
|
|
50881
|
-
|
|
50882
|
-
' if (
|
|
50883
|
-
|
|
50884
|
-
|
|
50885
|
-
'
|
|
51036
|
+
" var value;",
|
|
51037
|
+
' if (param.decode === "multi") {',
|
|
51038
|
+
" var entries = queryValues(String(param.name).toLowerCase());",
|
|
51039
|
+
' if (entries.length === 0) { if (param.required) pm.expect.fail("Required parameter " + param.in + ":" + param.name + " was not sent for " + contract.method + " " + contract.path); return; }',
|
|
51040
|
+
' if (param.allowEmptyValue && entries.length === 1 && entries[0] === "") return;',
|
|
51041
|
+
" if (entries.some(isPlaceholder)) return;",
|
|
51042
|
+
" value = entries.map(function (entry) { return coerceBySchema(decodeComponent(entry), param.items); });",
|
|
51043
|
+
" } else if (param.decode) {",
|
|
51044
|
+
' var joined = param.in === "query" ? queryValue(String(param.name).toLowerCase()) : headerValue(param.name);',
|
|
51045
|
+
' if (joined === undefined) { if (param.required) pm.expect.fail("Required parameter " + param.in + ":" + param.name + " was not sent for " + contract.method + " " + contract.path); return; }',
|
|
51046
|
+
' if (joined === "" && param.allowEmptyValue) return;',
|
|
51047
|
+
" if (isPlaceholder(joined)) return;",
|
|
51048
|
+
' var parts = joined === "" ? [] : splitDelimited(String(joined), param.decode);',
|
|
51049
|
+
// HTTP header lists allow optional whitespace after the comma, so
|
|
51050
|
+
// header-sourced items are trimmed; query values stay literal.
|
|
51051
|
+
' if (param.in === "header") parts = parts.map(function (entry) { return entry.trim(); });',
|
|
51052
|
+
" if (parts.some(isPlaceholder)) return;",
|
|
51053
|
+
// Query values arrive percent-encoded while the server validates the
|
|
51054
|
+
// decoded form; header values are never percent-encoded.
|
|
51055
|
+
' value = parts.map(function (entry) { return coerceBySchema(param.in === "query" ? decodeComponent(entry) : entry, param.items); });',
|
|
51056
|
+
' } else if (param.in === "path") {',
|
|
51057
|
+
" value = pathParamValue(param.name);",
|
|
51058
|
+
" if (value === undefined) return;",
|
|
51059
|
+
' if (isPlaceholder(value) || value.charAt(0) === ":" || value.charAt(0) === "{") return;',
|
|
51060
|
+
" value = coerceBySchema(value, param.schema);",
|
|
51061
|
+
' } else if (param.in === "cookie") {',
|
|
51062
|
+
" value = cookieValue(param.name);",
|
|
51063
|
+
' if (value === undefined) { if (param.required) pm.expect.fail("Required cookie parameter " + param.name + " was not sent for " + contract.method + " " + contract.path); return; }',
|
|
51064
|
+
" if (isPlaceholder(value)) return;",
|
|
51065
|
+
" value = coerceBySchema(value, param.schema);",
|
|
51066
|
+
" } else {",
|
|
51067
|
+
' value = param.in === "query" ? queryValue(String(param.name).toLowerCase()) : headerValue(param.name);',
|
|
51068
|
+
' if (value === undefined) { if (param.required) pm.expect.fail("Required parameter " + param.in + ":" + param.name + " was not sent for " + contract.method + " " + contract.path); return; }',
|
|
51069
|
+
' if (value === "" && param.allowEmptyValue) return;',
|
|
51070
|
+
" if (isPlaceholder(value)) return;",
|
|
51071
|
+
" if (param.content) {",
|
|
51072
|
+
" var parsed;",
|
|
51073
|
+
' try { parsed = JSON.parse(value); } catch (parseError) { pm.expect.fail("Parameter " + param.in + ":" + param.name + " declares JSON content but its value is not parseable JSON for " + contract.method + " " + contract.path); return; }',
|
|
51074
|
+
' if (!validate(parsed)) pm.expect.fail("Parameter " + param.in + ":" + param.name + " failed OpenAPI schema validation for " + contract.method + " " + contract.path + ": " + JSON.stringify(validate.errors || []));',
|
|
51075
|
+
" return;",
|
|
51076
|
+
" }",
|
|
51077
|
+
" value = coerceBySchema(value, param.schema);",
|
|
51078
|
+
" }",
|
|
51079
|
+
' if (!validate(value)) pm.expect.fail("Parameter " + param.in + ":" + param.name + " failed OpenAPI schema validation for " + contract.method + " " + contract.path + ": " + JSON.stringify(validate.errors || []));',
|
|
50886
51080
|
" });",
|
|
50887
51081
|
"});"
|
|
50888
51082
|
] : [],
|
|
@@ -51005,15 +51199,25 @@ function assertStaticRequestShape(operation, request) {
|
|
|
51005
51199
|
if (!contentType) {
|
|
51006
51200
|
throw new Error(`CONTRACT_STATIC_REQUEST_CHECK_FAILED: ${operation.id} missing required request Content-Type`);
|
|
51007
51201
|
}
|
|
51008
|
-
const actual = contentType.toLowerCase().split(";")[0]?.trim();
|
|
51009
|
-
const matches = operation.requestBody.contentTypes.some((expected) => expected.toLowerCase()
|
|
51202
|
+
const actual = contentType.toLowerCase().split(";")[0]?.trim() ?? "";
|
|
51203
|
+
const matches = operation.requestBody.contentTypes.some((expected) => mediaTypeMatchesPattern(expected.toLowerCase(), actual));
|
|
51010
51204
|
if (!matches) {
|
|
51011
51205
|
throw new Error(
|
|
51012
51206
|
`CONTRACT_STATIC_REQUEST_CHECK_FAILED: ${operation.id} request Content-Type ${contentType} does not match ${operation.requestBody.contentTypes.join(", ")}`
|
|
51013
51207
|
);
|
|
51014
51208
|
}
|
|
51015
51209
|
}
|
|
51016
|
-
|
|
51210
|
+
const warnings = collectStaticBodyWarnings(operation, request, contentType);
|
|
51211
|
+
if (operation.requestBody && !operation.requestBody.required && operation.requestBody.contentTypes.length > 0 && hasRequestBody(request) && contentType) {
|
|
51212
|
+
const actual = contentType.toLowerCase().split(";")[0]?.trim() ?? "";
|
|
51213
|
+
const matches = operation.requestBody.contentTypes.some((expected) => mediaTypeMatchesPattern(expected.toLowerCase(), actual));
|
|
51214
|
+
if (!matches) {
|
|
51215
|
+
warnings.push(
|
|
51216
|
+
`CONTRACT_STATIC_REQUEST_CHECK_FAILED: ${operation.id} optional request body Content-Type ${contentType} does not match ${operation.requestBody.contentTypes.join(", ")}`
|
|
51217
|
+
);
|
|
51218
|
+
}
|
|
51219
|
+
}
|
|
51220
|
+
return warnings;
|
|
51017
51221
|
}
|
|
51018
51222
|
function requestBodyFieldNames(request, base) {
|
|
51019
51223
|
const body = asRecord5(request.body);
|
|
@@ -51048,28 +51252,80 @@ function mediaTypeMatchesPattern(pattern, actual) {
|
|
|
51048
51252
|
return false;
|
|
51049
51253
|
});
|
|
51050
51254
|
}
|
|
51255
|
+
function isJsonEncodingContentType(declared) {
|
|
51256
|
+
return declared.split(",").some((candidate) => {
|
|
51257
|
+
const entry = (candidate.split(";")[0] ?? "").trim();
|
|
51258
|
+
return entry === "application/json" || entry.endsWith("+json");
|
|
51259
|
+
});
|
|
51260
|
+
}
|
|
51261
|
+
function isPlaceholderValue(value) {
|
|
51262
|
+
return /^<[^>]*>$/.test(value.trim()) || value.includes("{{");
|
|
51263
|
+
}
|
|
51051
51264
|
function collectStaticEncodingWarnings(operation, request, base, rule) {
|
|
51052
51265
|
const encodings = rule.encodings;
|
|
51053
|
-
if (!encodings
|
|
51266
|
+
if (!encodings) return [];
|
|
51267
|
+
const multipart = base === "multipart/form-data";
|
|
51054
51268
|
const entries = requestBodyEntries(request, base);
|
|
51055
51269
|
if (!entries) return [];
|
|
51056
51270
|
const warnings = [];
|
|
51271
|
+
const part = multipart ? "multipart" : "urlencoded";
|
|
51057
51272
|
for (const [field, encoding] of Object.entries(encodings)) {
|
|
51058
|
-
const entry
|
|
51059
|
-
|
|
51060
|
-
|
|
51061
|
-
|
|
51062
|
-
|
|
51063
|
-
|
|
51064
|
-
|
|
51065
|
-
|
|
51066
|
-
|
|
51067
|
-
|
|
51068
|
-
)
|
|
51069
|
-
|
|
51070
|
-
|
|
51071
|
-
|
|
51072
|
-
|
|
51273
|
+
for (const entry of entries.filter((candidate) => String(candidate.key || "") === field)) {
|
|
51274
|
+
if (multipart && encoding.binary && String(entry.type || "") !== "file") {
|
|
51275
|
+
warnings.push(`CONTRACT_ENCODING_MISMATCH: ${operation.id} generated multipart field ${field} should be a file part per its binary schema`);
|
|
51276
|
+
}
|
|
51277
|
+
if (multipart && encoding.contentType) {
|
|
51278
|
+
const actual = typeof entry.contentType === "string" ? (entry.contentType.toLowerCase().split(";")[0] ?? "").trim() : "";
|
|
51279
|
+
if (!actual) {
|
|
51280
|
+
warnings.push(
|
|
51281
|
+
`CONTRACT_ENCODING_MISMATCH: ${operation.id} generated multipart field ${field} does not declare Content-Type ${encoding.contentType} from its encoding object`
|
|
51282
|
+
);
|
|
51283
|
+
} else if (!mediaTypeMatchesPattern(encoding.contentType, actual)) {
|
|
51284
|
+
warnings.push(
|
|
51285
|
+
`CONTRACT_ENCODING_MISMATCH: ${operation.id} generated multipart field ${field} Content-Type ${actual} does not match declared encoding ${encoding.contentType}`
|
|
51286
|
+
);
|
|
51287
|
+
}
|
|
51288
|
+
}
|
|
51289
|
+
if (encoding.contentType && isJsonEncodingContentType(encoding.contentType) && String(entry.type || "text") !== "file") {
|
|
51290
|
+
const value = typeof entry.value === "string" ? entry.value : "";
|
|
51291
|
+
if (value.trim() && !isPlaceholderValue(value)) {
|
|
51292
|
+
try {
|
|
51293
|
+
JSON.parse(value);
|
|
51294
|
+
} catch {
|
|
51295
|
+
warnings.push(
|
|
51296
|
+
`CONTRACT_ENCODING_MISMATCH: ${operation.id} generated ${part} field ${field} declares JSON encoding ${encoding.contentType} but its value is not parseable JSON`
|
|
51297
|
+
);
|
|
51298
|
+
}
|
|
51299
|
+
}
|
|
51300
|
+
}
|
|
51301
|
+
}
|
|
51302
|
+
}
|
|
51303
|
+
return warnings;
|
|
51304
|
+
}
|
|
51305
|
+
function coerceFormValue(value, schema2) {
|
|
51306
|
+
const record = asRecord5(schema2);
|
|
51307
|
+
const type2 = record?.type;
|
|
51308
|
+
const types2 = Array.isArray(type2) ? type2 : [type2];
|
|
51309
|
+
if ((types2.includes("integer") || types2.includes("number")) && /^-?[0-9]+([.][0-9]+)?([eE][+-]?[0-9]+)?$/.test(value.trim())) return Number(value);
|
|
51310
|
+
if (types2.includes("boolean") && (value === "true" || value === "false")) return value === "true";
|
|
51311
|
+
return value;
|
|
51312
|
+
}
|
|
51313
|
+
function collectStaticFieldSchemaWarnings(operation, request, base, rule) {
|
|
51314
|
+
const fieldSchemas = rule.fieldSchemas;
|
|
51315
|
+
if (!fieldSchemas) return [];
|
|
51316
|
+
const entries = requestBodyEntries(request, base);
|
|
51317
|
+
if (!entries) return [];
|
|
51318
|
+
const part = base === "multipart/form-data" ? "multipart" : "urlencoded";
|
|
51319
|
+
const warnings = [];
|
|
51320
|
+
for (const [field, schema2] of Object.entries(fieldSchemas)) {
|
|
51321
|
+
const validate2 = compileSchemaValidator(schema2);
|
|
51322
|
+
if (!validate2) continue;
|
|
51323
|
+
for (const entry of entries.filter((candidate) => String(candidate.key || "") === field)) {
|
|
51324
|
+
if (String(entry.type || "text") === "file") continue;
|
|
51325
|
+
const value = typeof entry.value === "string" ? entry.value : "";
|
|
51326
|
+
if (!value.trim() || isPlaceholderValue(value)) continue;
|
|
51327
|
+
if (!validate2(coerceFormValue(value, schema2))) {
|
|
51328
|
+
warnings.push(`CONTRACT_FORM_FIELD_SCHEMA_MISMATCH: ${operation.id} generated ${part} field ${field} value does not match its schema`);
|
|
51073
51329
|
}
|
|
51074
51330
|
}
|
|
51075
51331
|
}
|
|
@@ -51081,7 +51337,10 @@ function collectStaticBodyWarnings(operation, request, contentType) {
|
|
|
51081
51337
|
const base = (contentType || "").toLowerCase().split(";")[0]?.trim() ?? "";
|
|
51082
51338
|
const rule = rules[base];
|
|
51083
51339
|
if (!rule) return [];
|
|
51084
|
-
const warnings = [
|
|
51340
|
+
const warnings = [
|
|
51341
|
+
...collectStaticEncodingWarnings(operation, request, base, rule),
|
|
51342
|
+
...collectStaticFieldSchemaWarnings(operation, request, base, rule)
|
|
51343
|
+
];
|
|
51085
51344
|
const names = requestBodyFieldNames(request, base);
|
|
51086
51345
|
if (!names) return warnings;
|
|
51087
51346
|
const present = new Set(names);
|