@postman-cse/onboarding-bootstrap 1.1.0 → 1.2.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/README.md +205 -443
- package/action.yml +2 -2
- package/dist/action.cjs +308 -49
- package/dist/cli.cjs +308 -49
- package/dist/index.cjs +308 -49
- package/package.json +2 -1
package/dist/cli.cjs
CHANGED
|
@@ -48107,6 +48107,38 @@ function normalizeSchema(ctx, schema2, options) {
|
|
|
48107
48107
|
const sourceSchema = { ...record };
|
|
48108
48108
|
const nullable = sourceSchema.nullable === true && ctx.version === "3.0";
|
|
48109
48109
|
delete sourceSchema.nullable;
|
|
48110
|
+
const discriminator = asRecord3(sourceSchema.discriminator);
|
|
48111
|
+
if (discriminator && typeof discriminator.propertyName === "string" && discriminator.propertyName) {
|
|
48112
|
+
const propertyName = discriminator.propertyName;
|
|
48113
|
+
const branchKey = Array.isArray(sourceSchema.oneOf) ? "oneOf" : Array.isArray(sourceSchema.anyOf) ? "anyOf" : "";
|
|
48114
|
+
const members = branchKey ? sourceSchema[branchKey] : [];
|
|
48115
|
+
const memberRefs = members.map((member) => {
|
|
48116
|
+
const memberRecord = asRecord3(member);
|
|
48117
|
+
const memberRef = memberRecord && Object.keys(memberRecord).length === 1 && typeof memberRecord.$ref === "string" ? memberRecord.$ref : "";
|
|
48118
|
+
return memberRef.startsWith("#/") ? memberRef : "";
|
|
48119
|
+
});
|
|
48120
|
+
if (branchKey && members.length > 0 && memberRefs.every(Boolean)) {
|
|
48121
|
+
const valuesByRef = /* @__PURE__ */ new Map();
|
|
48122
|
+
const refByMappingKey = /* @__PURE__ */ new Map();
|
|
48123
|
+
for (const [value, target] of Object.entries(asRecord3(discriminator.mapping) ?? {})) {
|
|
48124
|
+
if (typeof target !== "string" || !target) continue;
|
|
48125
|
+
const targetRef = target.startsWith("#/") ? target : `#/components/schemas/${target}`;
|
|
48126
|
+
valuesByRef.set(targetRef, [...valuesByRef.get(targetRef) ?? [], value]);
|
|
48127
|
+
refByMappingKey.set(value, targetRef);
|
|
48128
|
+
}
|
|
48129
|
+
sourceSchema[branchKey] = members.map((member, index) => {
|
|
48130
|
+
const memberRef = memberRefs[index] ?? "";
|
|
48131
|
+
const tail = (memberRef.split("/").pop() ?? "").replace(/~1/g, "/").replace(/~0/g, "~");
|
|
48132
|
+
const values = [...valuesByRef.get(memberRef) ?? []];
|
|
48133
|
+
const tailClaimedElsewhere = refByMappingKey.has(tail) && refByMappingKey.get(tail) !== memberRef;
|
|
48134
|
+
if (tail && !tailClaimedElsewhere && !values.includes(tail)) values.push(tail);
|
|
48135
|
+
const dispatch = values.length === 1 ? { const: values[0] } : { enum: values };
|
|
48136
|
+
return { allOf: [member, { type: "object", required: [propertyName], properties: { [propertyName]: dispatch } }] };
|
|
48137
|
+
});
|
|
48138
|
+
} else {
|
|
48139
|
+
ctx.notes.add("discriminator");
|
|
48140
|
+
}
|
|
48141
|
+
}
|
|
48110
48142
|
const directionStrippedFlag = ctx.direction === "request" ? "readOnly" : "writeOnly";
|
|
48111
48143
|
const strippedProperties = /* @__PURE__ */ new Set();
|
|
48112
48144
|
const rawProperties = asRecord3(sourceSchema.properties);
|
|
@@ -48279,7 +48311,7 @@ function packSchema(root, schema2, version, direction = "response") {
|
|
|
48279
48311
|
if (schema2 === true) return { schema: { $schema: rootDialect(root, version) } };
|
|
48280
48312
|
if (schema2 === false) return unsupported("Boolean false JSON Schema rejects every instance and is unsupported");
|
|
48281
48313
|
const dialect = rootDialect(root, version, asRecord3(schema2) ?? void 0);
|
|
48282
|
-
const ctx = { root, version, direction, dialect, defs: /* @__PURE__ */ new Map() };
|
|
48314
|
+
const ctx = { root, version, direction, dialect, defs: /* @__PURE__ */ new Map(), notes: /* @__PURE__ */ new Set() };
|
|
48283
48315
|
const normalized = normalizeSchema(ctx, schema2, { depth: 0, rootSchema: true });
|
|
48284
48316
|
const message = hasUnsupported(normalized);
|
|
48285
48317
|
if (message) return unsupported(message);
|
|
@@ -48304,7 +48336,9 @@ function packSchema(root, schema2, version, direction = "response") {
|
|
|
48304
48336
|
if (!normalizedRecord) return unsupported("Referenced schemas require an object root schema");
|
|
48305
48337
|
normalizedRecord.$defs = Object.fromEntries([...ctx.defs.values()].map((entry) => [entry.name, entry.schema]));
|
|
48306
48338
|
}
|
|
48307
|
-
|
|
48339
|
+
const packed = { schema: normalized };
|
|
48340
|
+
if (ctx.notes.size > 0) packed.notes = [...ctx.notes].sort();
|
|
48341
|
+
return packed;
|
|
48308
48342
|
} catch (error) {
|
|
48309
48343
|
return unsupported(error instanceof Error ? error.message : String(error));
|
|
48310
48344
|
}
|
|
@@ -48477,6 +48511,7 @@ function securityCheckFor(schemeName, scheme) {
|
|
|
48477
48511
|
const httpScheme = String(scheme.scheme || "").toLowerCase();
|
|
48478
48512
|
if (httpScheme === "basic") return { scheme: schemeName, kind, checkable: true, prefix: "Basic " };
|
|
48479
48513
|
if (httpScheme === "bearer") return { scheme: schemeName, kind, checkable: true, prefix: "Bearer " };
|
|
48514
|
+
if (httpScheme) return { scheme: schemeName, kind, checkable: true, prefix: `${httpScheme.charAt(0).toUpperCase()}${httpScheme.slice(1)} ` };
|
|
48480
48515
|
return { scheme: schemeName, kind, checkable: true, in: "header", name: "Authorization" };
|
|
48481
48516
|
}
|
|
48482
48517
|
if (scheme?.type === "oauth2" || scheme?.type === "openIdConnect") {
|
|
@@ -48510,7 +48545,18 @@ var IGNORED_HEADER_PARAMS = /* @__PURE__ */ new Set(["accept", "content-type", "
|
|
|
48510
48545
|
function isIgnoredParameter(location2, name) {
|
|
48511
48546
|
return location2 === "header" && IGNORED_HEADER_PARAMS.has(name.toLowerCase());
|
|
48512
48547
|
}
|
|
48513
|
-
function
|
|
48548
|
+
function jsonContentParameterMedia(param) {
|
|
48549
|
+
const content = asRecord4(param.content);
|
|
48550
|
+
if (!content) return void 0;
|
|
48551
|
+
const entries = Object.entries(content);
|
|
48552
|
+
if (entries.length !== 1) return void 0;
|
|
48553
|
+
const [contentType, mediaObject] = entries[0];
|
|
48554
|
+
const base = contentType.toLowerCase().split(";")[0]?.trim() ?? "";
|
|
48555
|
+
if (!isJsonBaseType(base)) return void 0;
|
|
48556
|
+
const schema2 = asRecord4(mediaObject)?.schema;
|
|
48557
|
+
return schema2 === void 0 ? void 0 : schema2;
|
|
48558
|
+
}
|
|
48559
|
+
function collectSerializationWarnings(root, pathItem, operation, decodedKeys) {
|
|
48514
48560
|
const warnings = [];
|
|
48515
48561
|
for (const param of resolvedParameters(root, pathItem, operation)) {
|
|
48516
48562
|
const location2 = String(param.in || "").toLowerCase();
|
|
@@ -48520,7 +48566,9 @@ function collectSerializationWarnings(root, pathItem, operation) {
|
|
|
48520
48566
|
const style = typeof param.style === "string" ? param.style : defaultStyle;
|
|
48521
48567
|
const defaultExplode = style === "form";
|
|
48522
48568
|
const explode = typeof param.explode === "boolean" ? param.explode : defaultExplode;
|
|
48523
|
-
|
|
48569
|
+
const unvalidatedContent = param.content !== void 0 && (jsonContentParameterMedia(param) === void 0 || location2 !== "query" && location2 !== "header");
|
|
48570
|
+
if (style !== defaultStyle || explode !== defaultExplode || param.allowReserved === true || unvalidatedContent) {
|
|
48571
|
+
if (decodedKeys.has(`${location2}:${name.toLowerCase()}`) && param.allowReserved !== true && param.content === void 0) continue;
|
|
48524
48572
|
warnings.push(`CONTRACT_PARAM_SERIALIZATION_NOT_VALIDATED: parameter ${location2}:${name} declares non-default style, explode, allowReserved, or content and its serialization is not validated`);
|
|
48525
48573
|
}
|
|
48526
48574
|
}
|
|
@@ -48535,7 +48583,27 @@ function packedScalarSchema(packed) {
|
|
|
48535
48583
|
if (!types2.every((entry) => typeof entry === "string" && SCALAR_SCHEMA_TYPES.has(entry))) return void 0;
|
|
48536
48584
|
return packed.schema;
|
|
48537
48585
|
}
|
|
48538
|
-
function
|
|
48586
|
+
function packedArrayItemsSchema(packed) {
|
|
48587
|
+
if (packed.unsupported || packed.schema === void 0) return void 0;
|
|
48588
|
+
const record = asRecord4(packed.schema);
|
|
48589
|
+
if (!record) return void 0;
|
|
48590
|
+
const types2 = Array.isArray(record.type) ? record.type : [record.type];
|
|
48591
|
+
if (types2.length !== 1 || types2[0] !== "array") return void 0;
|
|
48592
|
+
if (record.prefixItems !== void 0 || Array.isArray(record.items)) return void 0;
|
|
48593
|
+
if (record.items === void 0) return {};
|
|
48594
|
+
const items = asRecord4(record.items);
|
|
48595
|
+
if (!items || typeof items.$ref === "string") return void 0;
|
|
48596
|
+
const itemTypes = Array.isArray(items.type) ? items.type : [items.type];
|
|
48597
|
+
if (!itemTypes.every((entry) => typeof entry === "string" && SCALAR_SCHEMA_TYPES.has(entry))) return void 0;
|
|
48598
|
+
return items;
|
|
48599
|
+
}
|
|
48600
|
+
var QUERY_ARRAY_DECODES = {
|
|
48601
|
+
"form:true": "multi",
|
|
48602
|
+
"form:false": "csv",
|
|
48603
|
+
"spaceDelimited:false": "ssv",
|
|
48604
|
+
"pipeDelimited:false": "pipes"
|
|
48605
|
+
};
|
|
48606
|
+
function collectParameterChecks(root, pathItem, operation, version, operationId, pathTemplate, warnings) {
|
|
48539
48607
|
const securityKeys = collectSecurityApiKeys(root, operation);
|
|
48540
48608
|
const checks = [];
|
|
48541
48609
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -48548,32 +48616,65 @@ function collectParameterChecks(root, pathItem, operation, version, operationId,
|
|
|
48548
48616
|
}).filter((param) => Boolean(param));
|
|
48549
48617
|
for (const param of orderedParams) {
|
|
48550
48618
|
const location2 = String(param.in || "").toLowerCase();
|
|
48551
|
-
if (location2 !== "query" && location2 !== "header") continue;
|
|
48619
|
+
if (location2 !== "query" && location2 !== "header" && location2 !== "path" && location2 !== "cookie") continue;
|
|
48552
48620
|
const name = String(param.name || "");
|
|
48553
48621
|
if (!name || isIgnoredParameter(location2, name)) continue;
|
|
48554
48622
|
const key = `${location2}:${name.toLowerCase()}`;
|
|
48555
48623
|
if (seen.has(key)) continue;
|
|
48556
48624
|
seen.add(key);
|
|
48557
48625
|
if (securityKeys.has(key)) continue;
|
|
48626
|
+
const contentMedia = jsonContentParameterMedia(param);
|
|
48627
|
+
if (contentMedia !== void 0 && (location2 === "query" || location2 === "header")) {
|
|
48628
|
+
const packed2 = packSchema(root, contentMedia, version, "request");
|
|
48629
|
+
warnings.push(...packNoteWarnings(packed2, `parameter ${location2}:${name} of ${operationId}`));
|
|
48630
|
+
if (packed2.unsupported) {
|
|
48631
|
+
warnings.push(`CONTRACT_SCHEMA_NOT_COMPILED: parameter ${location2}:${name} schema on ${operationId} skipped (${packed2.unsupported})`);
|
|
48632
|
+
} else if (packed2.schema !== void 0) {
|
|
48633
|
+
const check2 = { in: location2, name, required: param.required === true, content: true, schema: packed2.schema };
|
|
48634
|
+
if (location2 === "query" && param.allowEmptyValue === true) check2.allowEmptyValue = true;
|
|
48635
|
+
checks.push(check2);
|
|
48636
|
+
}
|
|
48637
|
+
continue;
|
|
48638
|
+
}
|
|
48558
48639
|
if (param.content !== void 0 || param.schema === void 0) continue;
|
|
48559
48640
|
const defaultStyle = DEFAULT_PARAM_STYLES[location2];
|
|
48560
48641
|
const style = typeof param.style === "string" ? param.style : defaultStyle;
|
|
48561
48642
|
const defaultExplode = style === "form";
|
|
48562
48643
|
const explode = typeof param.explode === "boolean" ? param.explode : defaultExplode;
|
|
48563
|
-
|
|
48644
|
+
const defaultSerialization = style === defaultStyle && explode === defaultExplode;
|
|
48564
48645
|
const packed = packSchema(root, param.schema, version);
|
|
48646
|
+
const noteWarnings = packNoteWarnings(packed, `parameter ${location2}:${name} of ${operationId}`);
|
|
48647
|
+
if (defaultSerialization) warnings.push(...noteWarnings);
|
|
48565
48648
|
if (packed.unsupported) {
|
|
48566
|
-
warnings.push(`CONTRACT_SCHEMA_NOT_COMPILED: parameter ${location2}:${name} schema on ${operationId} skipped (${packed.unsupported})`);
|
|
48649
|
+
if (defaultSerialization) warnings.push(`CONTRACT_SCHEMA_NOT_COMPILED: parameter ${location2}:${name} schema on ${operationId} skipped (${packed.unsupported})`);
|
|
48567
48650
|
continue;
|
|
48568
48651
|
}
|
|
48569
|
-
|
|
48570
|
-
|
|
48571
|
-
|
|
48652
|
+
if (location2 === "path" && !pathTemplate.split("/").includes(`{${name}}`)) continue;
|
|
48653
|
+
const scalarSchema = packedScalarSchema(packed);
|
|
48654
|
+
if (scalarSchema !== void 0) {
|
|
48655
|
+
if (!defaultSerialization) continue;
|
|
48656
|
+
const check2 = { in: location2, name, required: param.required === true, schema: scalarSchema };
|
|
48657
|
+
if (location2 === "query" && param.allowEmptyValue === true) check2.allowEmptyValue = true;
|
|
48658
|
+
checks.push(check2);
|
|
48659
|
+
continue;
|
|
48660
|
+
}
|
|
48661
|
+
if (location2 !== "query" && location2 !== "header") continue;
|
|
48662
|
+
const items = packedArrayItemsSchema(packed);
|
|
48663
|
+
if (items === void 0) continue;
|
|
48664
|
+
const decode = location2 === "query" ? QUERY_ARRAY_DECODES[`${style}:${explode}`] : style === "simple" && !explode ? "csv" : void 0;
|
|
48665
|
+
if (!decode) continue;
|
|
48666
|
+
if (!defaultSerialization) warnings.push(...noteWarnings);
|
|
48667
|
+
const check = { in: location2, name, required: param.required === true, schema: packed.schema, decode, items };
|
|
48572
48668
|
if (location2 === "query" && param.allowEmptyValue === true) check.allowEmptyValue = true;
|
|
48573
48669
|
checks.push(check);
|
|
48574
48670
|
}
|
|
48575
48671
|
return checks.length > 0 ? checks : void 0;
|
|
48576
48672
|
}
|
|
48673
|
+
function packNoteWarnings(packed, context) {
|
|
48674
|
+
return (packed.notes ?? []).map(
|
|
48675
|
+
(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`
|
|
48676
|
+
);
|
|
48677
|
+
}
|
|
48577
48678
|
function collectDeclaredQueryParameters(root, pathItem, operation) {
|
|
48578
48679
|
const names = /* @__PURE__ */ new Set();
|
|
48579
48680
|
for (const param of resolvedParameters(root, pathItem, operation)) {
|
|
@@ -48651,7 +48752,10 @@ function propertyIsBinary(root, properties, name) {
|
|
|
48651
48752
|
}
|
|
48652
48753
|
if (!schema2) return false;
|
|
48653
48754
|
if (schema2.format === "binary") return true;
|
|
48654
|
-
|
|
48755
|
+
if (typeof schema2.contentMediaType !== "string" || typeof schema2.contentEncoding === "string") return false;
|
|
48756
|
+
const media = schema2.contentMediaType.toLowerCase().split(";")[0]?.trim() ?? "";
|
|
48757
|
+
if (!media) return false;
|
|
48758
|
+
return media !== "application/json" && !media.endsWith("+json") && !media.startsWith("text/");
|
|
48655
48759
|
}
|
|
48656
48760
|
function fieldEncodings(root, base, mediaObject, properties) {
|
|
48657
48761
|
const declared = asRecord4(mediaObject?.encoding);
|
|
@@ -48669,6 +48773,9 @@ function fieldEncodings(root, base, mediaObject, properties) {
|
|
|
48669
48773
|
if (typeof encoding.contentType === "string" && encoding.contentType.trim()) {
|
|
48670
48774
|
entry.contentType = encoding.contentType.toLowerCase();
|
|
48671
48775
|
}
|
|
48776
|
+
if (base === "multipart/form-data" && asRecord4(encoding.headers)) {
|
|
48777
|
+
entry.hasHeaders = true;
|
|
48778
|
+
}
|
|
48672
48779
|
if (base === "application/x-www-form-urlencoded") {
|
|
48673
48780
|
const style = typeof encoding.style === "string" ? encoding.style : "form";
|
|
48674
48781
|
const explode = typeof encoding.explode === "boolean" ? encoding.explode : style === "form";
|
|
@@ -48681,7 +48788,22 @@ function fieldEncodings(root, base, mediaObject, properties) {
|
|
|
48681
48788
|
}
|
|
48682
48789
|
return Object.keys(encodings).length > 0 ? encodings : void 0;
|
|
48683
48790
|
}
|
|
48684
|
-
function
|
|
48791
|
+
function formFieldSchemas(root, version, properties, context, warnings) {
|
|
48792
|
+
const schemas = {};
|
|
48793
|
+
for (const name of Object.keys(properties)) {
|
|
48794
|
+
const packed = packSchema(root, properties[name], version, "request");
|
|
48795
|
+
warnings.push(...packNoteWarnings(packed, `field ${name} of ${context}`));
|
|
48796
|
+
if (packed.unsupported) {
|
|
48797
|
+
warnings.push(`CONTRACT_SCHEMA_NOT_COMPILED: field ${name} of ${context} skipped (${packed.unsupported})`);
|
|
48798
|
+
continue;
|
|
48799
|
+
}
|
|
48800
|
+
if (packed.schema === void 0) continue;
|
|
48801
|
+
const schema2 = packedScalarSchema(packed);
|
|
48802
|
+
if (schema2 !== void 0) schemas[name] = schema2;
|
|
48803
|
+
}
|
|
48804
|
+
return Object.keys(schemas).length > 0 ? schemas : void 0;
|
|
48805
|
+
}
|
|
48806
|
+
function requestBodyFieldRules(root, content, version, operationId, warnings) {
|
|
48685
48807
|
const rules = {};
|
|
48686
48808
|
for (const [contentType, mediaObject] of Object.entries(content)) {
|
|
48687
48809
|
const base = contentType.toLowerCase().split(";")[0]?.trim() ?? "";
|
|
@@ -48691,10 +48813,13 @@ function requestBodyFieldRules(root, content) {
|
|
|
48691
48813
|
if (!merged) continue;
|
|
48692
48814
|
const readOnly = Object.keys(merged.properties).filter((name) => propertyIsReadOnly(root, merged.properties, name));
|
|
48693
48815
|
const required = merged.required.filter((name) => !propertyIsReadOnly(root, merged.properties, name));
|
|
48694
|
-
const
|
|
48695
|
-
|
|
48816
|
+
const formRules = BODY_FIELD_RULE_TYPES.has(base);
|
|
48817
|
+
const encodings = formRules ? fieldEncodings(root, base, mediaRecord, merged.properties) : void 0;
|
|
48818
|
+
const fieldSchemas = formRules ? formFieldSchemas(root, version, merged.properties, `request body ${contentType} of ${operationId}`, warnings) : void 0;
|
|
48819
|
+
if (required.length > 0 || readOnly.length > 0 || encodings || fieldSchemas) {
|
|
48696
48820
|
const rule = { required, readOnly };
|
|
48697
48821
|
if (encodings) rule.encodings = encodings;
|
|
48822
|
+
if (fieldSchemas) rule.fieldSchemas = fieldSchemas;
|
|
48698
48823
|
rules[base] = rule;
|
|
48699
48824
|
}
|
|
48700
48825
|
}
|
|
@@ -48715,6 +48840,7 @@ function requestBodyJsonSchemas(root, content, version, operationId, warnings) {
|
|
|
48715
48840
|
}
|
|
48716
48841
|
if (schema2 === void 0) continue;
|
|
48717
48842
|
const packed = packSchema(root, schema2, version, "request");
|
|
48843
|
+
warnings.push(...packNoteWarnings(packed, `request body ${contentType} of ${operationId}`));
|
|
48718
48844
|
if (mediaRecord) validateExamples(root, mediaRecord, packed, contentType, operationId, exampleWarnings);
|
|
48719
48845
|
if (packed.unsupported) {
|
|
48720
48846
|
warnings.push(`CONTRACT_REQUEST_SCHEMA_NOT_VALIDATED: request body schema for ${contentType} on ${operationId} is not validated (${packed.unsupported})`);
|
|
@@ -48729,7 +48855,7 @@ function collectRequestBody(root, operation, version, operationId, warnings) {
|
|
|
48729
48855
|
const body = resolveInternalRef(root, operation.requestBody);
|
|
48730
48856
|
if (!body) return void 0;
|
|
48731
48857
|
const content = asRecord4(body.content);
|
|
48732
|
-
const fieldRules = content ? requestBodyFieldRules(root, content) : void 0;
|
|
48858
|
+
const fieldRules = content ? requestBodyFieldRules(root, content, version, operationId, warnings) : void 0;
|
|
48733
48859
|
if (fieldRules) {
|
|
48734
48860
|
for (const [base, rule] of Object.entries(fieldRules)) {
|
|
48735
48861
|
for (const [field, encoding] of Object.entries(rule.encodings ?? {})) {
|
|
@@ -48738,6 +48864,11 @@ function collectRequestBody(root, operation, version, operationId, warnings) {
|
|
|
48738
48864
|
`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`
|
|
48739
48865
|
);
|
|
48740
48866
|
}
|
|
48867
|
+
if (encoding.hasHeaders) {
|
|
48868
|
+
warnings.push(
|
|
48869
|
+
`CONTRACT_ENCODING_HEADERS_NOT_VALIDATED: ${base} request body field ${field} on ${operationId} declares per-part headers that generated formdata entries cannot carry`
|
|
48870
|
+
);
|
|
48871
|
+
}
|
|
48741
48872
|
}
|
|
48742
48873
|
}
|
|
48743
48874
|
}
|
|
@@ -48785,6 +48916,7 @@ function responseContent(root, version, response, context, warnings) {
|
|
|
48785
48916
|
const mediaRecord = asRecord4(mediaObject);
|
|
48786
48917
|
const schema2 = mediaRecord?.schema;
|
|
48787
48918
|
let packed = schema2 === void 0 ? {} : packSchema(root, schema2, version);
|
|
48919
|
+
for (const warning of packNoteWarnings(packed, `response ${contentType} of ${context}`)) warnings.add(warning);
|
|
48788
48920
|
if (isSchemaGraphOverflow(packed)) {
|
|
48789
48921
|
warnings.add(`CONTRACT_SCHEMA_NOT_COMPILED: response schema for ${contentType} on ${context} skipped (${packed.unsupported})`);
|
|
48790
48922
|
packed = {};
|
|
@@ -48816,12 +48948,18 @@ function responseHeaders(root, version, response, context, warnings) {
|
|
|
48816
48948
|
continue;
|
|
48817
48949
|
}
|
|
48818
48950
|
const packed = packSchema(root, header.schema, version);
|
|
48951
|
+
for (const warning of packNoteWarnings(packed, `response header ${name} of ${context}`)) warnings.add(warning);
|
|
48819
48952
|
if (isSchemaGraphOverflow(packed)) {
|
|
48820
48953
|
warnings.add(`CONTRACT_SCHEMA_NOT_COMPILED: response header ${name} schema on ${context} skipped (${packed.unsupported})`);
|
|
48821
48954
|
entries.push({ name, required });
|
|
48822
48955
|
continue;
|
|
48823
48956
|
}
|
|
48824
48957
|
if (!packed.unsupported && packed.schema !== void 0 && packedScalarSchema(packed) === void 0) {
|
|
48958
|
+
const items = packedArrayItemsSchema(packed);
|
|
48959
|
+
if (items !== void 0) {
|
|
48960
|
+
entries.push({ name, required, schema: packed.schema, items });
|
|
48961
|
+
continue;
|
|
48962
|
+
}
|
|
48825
48963
|
warnings.add(`CONTRACT_HEADER_SCHEMA_NOT_VALIDATED: response header ${name} on ${context} declares a non-scalar schema and its value is not validated`);
|
|
48826
48964
|
entries.push({ name, required });
|
|
48827
48965
|
continue;
|
|
@@ -48880,10 +49018,14 @@ function buildContractIndex(root) {
|
|
|
48880
49018
|
path6,
|
|
48881
49019
|
...operationServers(root, pathItem, operation).map((server) => joinPaths(serverPathPrefix(server), path6))
|
|
48882
49020
|
].map(normalizePath))];
|
|
49021
|
+
const operationId = `${lowerMethod.toUpperCase()} ${path6}`;
|
|
48883
49022
|
const opWarnings = [];
|
|
48884
49023
|
opWarnings.push(...responseWarnings);
|
|
48885
49024
|
opWarnings.push(...collectSecuritySchemeWarnings(root, operation));
|
|
48886
|
-
|
|
49025
|
+
const parameterChecks = collectParameterChecks(root, pathItem, operation, version, operationId, path6, opWarnings);
|
|
49026
|
+
const checkedKeys = new Set((parameterChecks ?? []).map((check) => `${check.in}:${check.name.toLowerCase()}`));
|
|
49027
|
+
const decodedKeys = new Set((parameterChecks ?? []).filter((check) => check.decode).map((check) => `${check.in}:${check.name.toLowerCase()}`));
|
|
49028
|
+
opWarnings.push(...collectSerializationWarnings(root, pathItem, operation, decodedKeys));
|
|
48887
49029
|
if (operation.deprecated === true) {
|
|
48888
49030
|
opWarnings.push(`CONTRACT_OPERATION_DEPRECATED: ${lowerMethod.toUpperCase()} ${path6} is marked deprecated in the OpenAPI document`);
|
|
48889
49031
|
}
|
|
@@ -48892,17 +49034,19 @@ function buildContractIndex(root) {
|
|
|
48892
49034
|
opWarnings.push(`CONTRACT_SECURITY_NOT_VALIDATED: security parameter ${parameter.in}:${parameter.name} is not statically required in generated requests`);
|
|
48893
49035
|
}
|
|
48894
49036
|
for (const parameter of requiredParameters.filter((entry) => entry.in === "cookie" && !entry.securityDerived)) {
|
|
48895
|
-
opWarnings.push(`CONTRACT_COOKIE_PARAM_NOT_VALIDATED: required cookie parameter ${parameter.name} is not
|
|
49037
|
+
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`);
|
|
48896
49038
|
}
|
|
48897
49039
|
const pathParamWarnings = /* @__PURE__ */ new Set();
|
|
48898
49040
|
for (const param of resolvedParameters(root, pathItem, operation)) {
|
|
48899
49041
|
if (String(param.in || "").toLowerCase() !== "path") continue;
|
|
48900
49042
|
const name = String(param.name || "");
|
|
48901
|
-
if (name
|
|
49043
|
+
if (name && !checkedKeys.has(`path:${name.toLowerCase()}`)) {
|
|
49044
|
+
pathParamWarnings.add(`CONTRACT_PATH_PARAM_NOT_VALIDATED: path parameter ${name} value is not validated at runtime`);
|
|
49045
|
+
}
|
|
48902
49046
|
}
|
|
48903
49047
|
opWarnings.push(...pathParamWarnings);
|
|
48904
49048
|
operations.push({
|
|
48905
|
-
id:
|
|
49049
|
+
id: operationId,
|
|
48906
49050
|
method: lowerMethod.toUpperCase(),
|
|
48907
49051
|
path: path6,
|
|
48908
49052
|
pointer: `/paths/${path6.replace(/~/g, "~0").replace(/\//g, "~1")}/${lowerMethod}`,
|
|
@@ -48910,8 +49054,8 @@ function buildContractIndex(root) {
|
|
|
48910
49054
|
responses: contractResponses,
|
|
48911
49055
|
requiredParameters,
|
|
48912
49056
|
declaredQueryParameters: collectDeclaredQueryParameters(root, pathItem, operation),
|
|
48913
|
-
parameterChecks
|
|
48914
|
-
requestBody: collectRequestBody(root, operation, version,
|
|
49057
|
+
parameterChecks,
|
|
49058
|
+
requestBody: collectRequestBody(root, operation, version, operationId, opWarnings),
|
|
48915
49059
|
security: collectSecurityRuntimeChecks(root, operation),
|
|
48916
49060
|
warnings: opWarnings
|
|
48917
49061
|
});
|
|
@@ -49118,8 +49262,11 @@ function createContractScript(operation, warnings = []) {
|
|
|
49118
49262
|
" if (!actual) return;",
|
|
49119
49263
|
' if (header.unsupported) pm.expect.fail("OpenAPI response header unsupported for " + contract.method + " " + contract.path + ": " + header.unsupported);',
|
|
49120
49264
|
" var headerValidator = validators[selected.key] && validators[selected.key].__headers && validators[selected.key].__headers[String(header.name).toLowerCase()];",
|
|
49121
|
-
" if (headerValidator
|
|
49122
|
-
|
|
49265
|
+
" if (!headerValidator || headerValidator.skip) return;",
|
|
49266
|
+
" var expected;",
|
|
49267
|
+
' if (header.items) { var joined = String(actual).trim(); expected = joined === "" ? [] : joined.split(",").map(function (entry) { return coerceBySchema(entry.trim(), header.items); }); }',
|
|
49268
|
+
" else expected = coerceBySchema(actual, header.schema);",
|
|
49269
|
+
' if (!headerValidator(expected)) pm.expect.fail("OpenAPI response header validation failed for " + header.name + ": " + JSON.stringify(headerValidator.errors || []));',
|
|
49123
49270
|
" });",
|
|
49124
49271
|
"});",
|
|
49125
49272
|
"pm.test('Response body matches OpenAPI body contract', function () {",
|
|
@@ -49175,17 +49322,64 @@ function createContractScript(operation, warnings = []) {
|
|
|
49175
49322
|
...operation.parameterChecks && operation.parameterChecks.length > 0 ? [
|
|
49176
49323
|
"pm.test('Request parameters match OpenAPI schemas', function () {",
|
|
49177
49324
|
' 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; }',
|
|
49325
|
+
' 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; }',
|
|
49178
49326
|
' 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; }',
|
|
49327
|
+
' 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; }',
|
|
49328
|
+
' 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; }); }',
|
|
49329
|
+
// Server path prefixes sit ahead of the template segments, so the
|
|
49330
|
+
// template aligns against the trailing request segments.
|
|
49331
|
+
' 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; }',
|
|
49179
49332
|
' function isPlaceholder(value) { var text = String(value).trim(); return /^<[^<>]*>$/.test(text) || text.indexOf("{{") !== -1; }',
|
|
49333
|
+
' function splitDelimited(value, decode) { if (decode === "csv") return value.split(","); if (decode === "ssv") return value.split(/%20| /); return value.split(/%7C|\\|/i); }',
|
|
49334
|
+
" function decodeComponent(value) { try { return decodeURIComponent(value); } catch (ignored) { return value; } }",
|
|
49180
49335
|
" (contract.parameters || []).forEach(function (param) {",
|
|
49181
49336
|
' var key = param.in + ":" + String(param.name).toLowerCase();',
|
|
49182
49337
|
" var validate = paramValidators[key];",
|
|
49183
49338
|
" if (!validate || validate.skip) return;",
|
|
49184
|
-
|
|
49185
|
-
' if (
|
|
49186
|
-
|
|
49187
|
-
|
|
49188
|
-
'
|
|
49339
|
+
" var value;",
|
|
49340
|
+
' if (param.decode === "multi") {',
|
|
49341
|
+
" var entries = queryValues(String(param.name).toLowerCase());",
|
|
49342
|
+
' 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; }',
|
|
49343
|
+
' if (param.allowEmptyValue && entries.length === 1 && entries[0] === "") return;',
|
|
49344
|
+
" if (entries.some(isPlaceholder)) return;",
|
|
49345
|
+
" value = entries.map(function (entry) { return coerceBySchema(decodeComponent(entry), param.items); });",
|
|
49346
|
+
" } else if (param.decode) {",
|
|
49347
|
+
' var joined = param.in === "query" ? queryValue(String(param.name).toLowerCase()) : headerValue(param.name);',
|
|
49348
|
+
' if (joined === undefined) { if (param.required) pm.expect.fail("Required parameter " + param.in + ":" + param.name + " was not sent for " + contract.method + " " + contract.path); return; }',
|
|
49349
|
+
' if (joined === "" && param.allowEmptyValue) return;',
|
|
49350
|
+
" if (isPlaceholder(joined)) return;",
|
|
49351
|
+
' var parts = joined === "" ? [] : splitDelimited(String(joined), param.decode);',
|
|
49352
|
+
// HTTP header lists allow optional whitespace after the comma, so
|
|
49353
|
+
// header-sourced items are trimmed; query values stay literal.
|
|
49354
|
+
' if (param.in === "header") parts = parts.map(function (entry) { return entry.trim(); });',
|
|
49355
|
+
" if (parts.some(isPlaceholder)) return;",
|
|
49356
|
+
// Query values arrive percent-encoded while the server validates the
|
|
49357
|
+
// decoded form; header values are never percent-encoded.
|
|
49358
|
+
' value = parts.map(function (entry) { return coerceBySchema(param.in === "query" ? decodeComponent(entry) : entry, param.items); });',
|
|
49359
|
+
' } else if (param.in === "path") {',
|
|
49360
|
+
" value = pathParamValue(param.name);",
|
|
49361
|
+
" if (value === undefined) return;",
|
|
49362
|
+
' if (isPlaceholder(value) || value.charAt(0) === ":" || value.charAt(0) === "{") return;',
|
|
49363
|
+
" value = coerceBySchema(value, param.schema);",
|
|
49364
|
+
' } else if (param.in === "cookie") {',
|
|
49365
|
+
" value = cookieValue(param.name);",
|
|
49366
|
+
' if (value === undefined) { if (param.required) pm.expect.fail("Required cookie parameter " + param.name + " was not sent for " + contract.method + " " + contract.path); return; }',
|
|
49367
|
+
" if (isPlaceholder(value)) return;",
|
|
49368
|
+
" value = coerceBySchema(value, param.schema);",
|
|
49369
|
+
" } else {",
|
|
49370
|
+
' value = param.in === "query" ? queryValue(String(param.name).toLowerCase()) : headerValue(param.name);',
|
|
49371
|
+
' if (value === undefined) { if (param.required) pm.expect.fail("Required parameter " + param.in + ":" + param.name + " was not sent for " + contract.method + " " + contract.path); return; }',
|
|
49372
|
+
' if (value === "" && param.allowEmptyValue) return;',
|
|
49373
|
+
" if (isPlaceholder(value)) return;",
|
|
49374
|
+
" if (param.content) {",
|
|
49375
|
+
" var parsed;",
|
|
49376
|
+
' 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; }',
|
|
49377
|
+
' if (!validate(parsed)) pm.expect.fail("Parameter " + param.in + ":" + param.name + " failed OpenAPI schema validation for " + contract.method + " " + contract.path + ": " + JSON.stringify(validate.errors || []));',
|
|
49378
|
+
" return;",
|
|
49379
|
+
" }",
|
|
49380
|
+
" value = coerceBySchema(value, param.schema);",
|
|
49381
|
+
" }",
|
|
49382
|
+
' if (!validate(value)) pm.expect.fail("Parameter " + param.in + ":" + param.name + " failed OpenAPI schema validation for " + contract.method + " " + contract.path + ": " + JSON.stringify(validate.errors || []));',
|
|
49189
49383
|
" });",
|
|
49190
49384
|
"});"
|
|
49191
49385
|
] : [],
|
|
@@ -49308,15 +49502,25 @@ function assertStaticRequestShape(operation, request) {
|
|
|
49308
49502
|
if (!contentType) {
|
|
49309
49503
|
throw new Error(`CONTRACT_STATIC_REQUEST_CHECK_FAILED: ${operation.id} missing required request Content-Type`);
|
|
49310
49504
|
}
|
|
49311
|
-
const actual = contentType.toLowerCase().split(";")[0]?.trim();
|
|
49312
|
-
const matches = operation.requestBody.contentTypes.some((expected) => expected.toLowerCase()
|
|
49505
|
+
const actual = contentType.toLowerCase().split(";")[0]?.trim() ?? "";
|
|
49506
|
+
const matches = operation.requestBody.contentTypes.some((expected) => mediaTypeMatchesPattern(expected.toLowerCase(), actual));
|
|
49313
49507
|
if (!matches) {
|
|
49314
49508
|
throw new Error(
|
|
49315
49509
|
`CONTRACT_STATIC_REQUEST_CHECK_FAILED: ${operation.id} request Content-Type ${contentType} does not match ${operation.requestBody.contentTypes.join(", ")}`
|
|
49316
49510
|
);
|
|
49317
49511
|
}
|
|
49318
49512
|
}
|
|
49319
|
-
|
|
49513
|
+
const warnings = collectStaticBodyWarnings(operation, request, contentType);
|
|
49514
|
+
if (operation.requestBody && !operation.requestBody.required && operation.requestBody.contentTypes.length > 0 && hasRequestBody(request) && contentType) {
|
|
49515
|
+
const actual = contentType.toLowerCase().split(";")[0]?.trim() ?? "";
|
|
49516
|
+
const matches = operation.requestBody.contentTypes.some((expected) => mediaTypeMatchesPattern(expected.toLowerCase(), actual));
|
|
49517
|
+
if (!matches) {
|
|
49518
|
+
warnings.push(
|
|
49519
|
+
`CONTRACT_STATIC_REQUEST_CHECK_FAILED: ${operation.id} optional request body Content-Type ${contentType} does not match ${operation.requestBody.contentTypes.join(", ")}`
|
|
49520
|
+
);
|
|
49521
|
+
}
|
|
49522
|
+
}
|
|
49523
|
+
return warnings;
|
|
49320
49524
|
}
|
|
49321
49525
|
function requestBodyFieldNames(request, base) {
|
|
49322
49526
|
const body = asRecord5(request.body);
|
|
@@ -49351,28 +49555,80 @@ function mediaTypeMatchesPattern(pattern, actual) {
|
|
|
49351
49555
|
return false;
|
|
49352
49556
|
});
|
|
49353
49557
|
}
|
|
49558
|
+
function isJsonEncodingContentType(declared) {
|
|
49559
|
+
return declared.split(",").some((candidate) => {
|
|
49560
|
+
const entry = (candidate.split(";")[0] ?? "").trim();
|
|
49561
|
+
return entry === "application/json" || entry.endsWith("+json");
|
|
49562
|
+
});
|
|
49563
|
+
}
|
|
49564
|
+
function isPlaceholderValue(value) {
|
|
49565
|
+
return /^<[^>]*>$/.test(value.trim()) || value.includes("{{");
|
|
49566
|
+
}
|
|
49354
49567
|
function collectStaticEncodingWarnings(operation, request, base, rule) {
|
|
49355
49568
|
const encodings = rule.encodings;
|
|
49356
|
-
if (!encodings
|
|
49569
|
+
if (!encodings) return [];
|
|
49570
|
+
const multipart = base === "multipart/form-data";
|
|
49357
49571
|
const entries = requestBodyEntries(request, base);
|
|
49358
49572
|
if (!entries) return [];
|
|
49359
49573
|
const warnings = [];
|
|
49574
|
+
const part = multipart ? "multipart" : "urlencoded";
|
|
49360
49575
|
for (const [field, encoding] of Object.entries(encodings)) {
|
|
49361
|
-
const entry
|
|
49362
|
-
|
|
49363
|
-
|
|
49364
|
-
|
|
49365
|
-
|
|
49366
|
-
|
|
49367
|
-
|
|
49368
|
-
|
|
49369
|
-
|
|
49370
|
-
|
|
49371
|
-
)
|
|
49372
|
-
|
|
49373
|
-
|
|
49374
|
-
|
|
49375
|
-
|
|
49576
|
+
for (const entry of entries.filter((candidate) => String(candidate.key || "") === field)) {
|
|
49577
|
+
if (multipart && encoding.binary && String(entry.type || "") !== "file") {
|
|
49578
|
+
warnings.push(`CONTRACT_ENCODING_MISMATCH: ${operation.id} generated multipart field ${field} should be a file part per its binary schema`);
|
|
49579
|
+
}
|
|
49580
|
+
if (multipart && encoding.contentType) {
|
|
49581
|
+
const actual = typeof entry.contentType === "string" ? (entry.contentType.toLowerCase().split(";")[0] ?? "").trim() : "";
|
|
49582
|
+
if (!actual) {
|
|
49583
|
+
warnings.push(
|
|
49584
|
+
`CONTRACT_ENCODING_MISMATCH: ${operation.id} generated multipart field ${field} does not declare Content-Type ${encoding.contentType} from its encoding object`
|
|
49585
|
+
);
|
|
49586
|
+
} else if (!mediaTypeMatchesPattern(encoding.contentType, actual)) {
|
|
49587
|
+
warnings.push(
|
|
49588
|
+
`CONTRACT_ENCODING_MISMATCH: ${operation.id} generated multipart field ${field} Content-Type ${actual} does not match declared encoding ${encoding.contentType}`
|
|
49589
|
+
);
|
|
49590
|
+
}
|
|
49591
|
+
}
|
|
49592
|
+
if (encoding.contentType && isJsonEncodingContentType(encoding.contentType) && String(entry.type || "text") !== "file") {
|
|
49593
|
+
const value = typeof entry.value === "string" ? entry.value : "";
|
|
49594
|
+
if (value.trim() && !isPlaceholderValue(value)) {
|
|
49595
|
+
try {
|
|
49596
|
+
JSON.parse(value);
|
|
49597
|
+
} catch {
|
|
49598
|
+
warnings.push(
|
|
49599
|
+
`CONTRACT_ENCODING_MISMATCH: ${operation.id} generated ${part} field ${field} declares JSON encoding ${encoding.contentType} but its value is not parseable JSON`
|
|
49600
|
+
);
|
|
49601
|
+
}
|
|
49602
|
+
}
|
|
49603
|
+
}
|
|
49604
|
+
}
|
|
49605
|
+
}
|
|
49606
|
+
return warnings;
|
|
49607
|
+
}
|
|
49608
|
+
function coerceFormValue(value, schema2) {
|
|
49609
|
+
const record = asRecord5(schema2);
|
|
49610
|
+
const type2 = record?.type;
|
|
49611
|
+
const types2 = Array.isArray(type2) ? type2 : [type2];
|
|
49612
|
+
if ((types2.includes("integer") || types2.includes("number")) && /^-?[0-9]+([.][0-9]+)?([eE][+-]?[0-9]+)?$/.test(value.trim())) return Number(value);
|
|
49613
|
+
if (types2.includes("boolean") && (value === "true" || value === "false")) return value === "true";
|
|
49614
|
+
return value;
|
|
49615
|
+
}
|
|
49616
|
+
function collectStaticFieldSchemaWarnings(operation, request, base, rule) {
|
|
49617
|
+
const fieldSchemas = rule.fieldSchemas;
|
|
49618
|
+
if (!fieldSchemas) return [];
|
|
49619
|
+
const entries = requestBodyEntries(request, base);
|
|
49620
|
+
if (!entries) return [];
|
|
49621
|
+
const part = base === "multipart/form-data" ? "multipart" : "urlencoded";
|
|
49622
|
+
const warnings = [];
|
|
49623
|
+
for (const [field, schema2] of Object.entries(fieldSchemas)) {
|
|
49624
|
+
const validate2 = compileSchemaValidator(schema2);
|
|
49625
|
+
if (!validate2) continue;
|
|
49626
|
+
for (const entry of entries.filter((candidate) => String(candidate.key || "") === field)) {
|
|
49627
|
+
if (String(entry.type || "text") === "file") continue;
|
|
49628
|
+
const value = typeof entry.value === "string" ? entry.value : "";
|
|
49629
|
+
if (!value.trim() || isPlaceholderValue(value)) continue;
|
|
49630
|
+
if (!validate2(coerceFormValue(value, schema2))) {
|
|
49631
|
+
warnings.push(`CONTRACT_FORM_FIELD_SCHEMA_MISMATCH: ${operation.id} generated ${part} field ${field} value does not match its schema`);
|
|
49376
49632
|
}
|
|
49377
49633
|
}
|
|
49378
49634
|
}
|
|
@@ -49384,7 +49640,10 @@ function collectStaticBodyWarnings(operation, request, contentType) {
|
|
|
49384
49640
|
const base = (contentType || "").toLowerCase().split(";")[0]?.trim() ?? "";
|
|
49385
49641
|
const rule = rules[base];
|
|
49386
49642
|
if (!rule) return [];
|
|
49387
|
-
const warnings = [
|
|
49643
|
+
const warnings = [
|
|
49644
|
+
...collectStaticEncodingWarnings(operation, request, base, rule),
|
|
49645
|
+
...collectStaticFieldSchemaWarnings(operation, request, base, rule)
|
|
49646
|
+
];
|
|
49388
49647
|
const names = requestBodyFieldNames(request, base);
|
|
49389
49648
|
if (!names) return warnings;
|
|
49390
49649
|
const present = new Set(names);
|