@postman-cse/onboarding-bootstrap 2.1.2 → 2.3.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 +15 -1
- package/dist/action.cjs +934 -140
- package/dist/cli.cjs +952 -158
- package/dist/index.cjs +934 -140
- package/package.json +6 -5
package/dist/cli.cjs
CHANGED
|
@@ -55570,7 +55570,7 @@ var require_lodash = __commonJS({
|
|
|
55570
55570
|
}
|
|
55571
55571
|
return mapped.length && mapped[0] === arrays[0] ? baseIntersection(mapped, undefined2, comparator) : [];
|
|
55572
55572
|
});
|
|
55573
|
-
function
|
|
55573
|
+
function join4(array, separator) {
|
|
55574
55574
|
return array == null ? "" : nativeJoin.call(array, separator);
|
|
55575
55575
|
}
|
|
55576
55576
|
function last(array) {
|
|
@@ -57489,7 +57489,7 @@ var require_lodash = __commonJS({
|
|
|
57489
57489
|
lodash.isUndefined = isUndefined;
|
|
57490
57490
|
lodash.isWeakMap = isWeakMap;
|
|
57491
57491
|
lodash.isWeakSet = isWeakSet;
|
|
57492
|
-
lodash.join =
|
|
57492
|
+
lodash.join = join4;
|
|
57493
57493
|
lodash.kebabCase = kebabCase;
|
|
57494
57494
|
lodash.last = last;
|
|
57495
57495
|
lodash.lastIndexOf = lastIndexOf;
|
|
@@ -127436,16 +127436,16 @@ var require_printer = __commonJS({
|
|
|
127436
127436
|
},
|
|
127437
127437
|
// Document
|
|
127438
127438
|
Document: {
|
|
127439
|
-
leave: (node) =>
|
|
127439
|
+
leave: (node) => join4(node.definitions, "\n\n")
|
|
127440
127440
|
},
|
|
127441
127441
|
OperationDefinition: {
|
|
127442
127442
|
leave(node) {
|
|
127443
|
-
const varDefs = hasMultilineItems(node.variableDefinitions) ? wrap("(\n",
|
|
127444
|
-
const prefix = wrap("", node.description, "\n") +
|
|
127443
|
+
const varDefs = hasMultilineItems(node.variableDefinitions) ? wrap("(\n", join4(node.variableDefinitions, "\n"), "\n)") : wrap("(", join4(node.variableDefinitions, ", "), ")");
|
|
127444
|
+
const prefix = wrap("", node.description, "\n") + join4(
|
|
127445
127445
|
[
|
|
127446
127446
|
node.operation,
|
|
127447
|
-
|
|
127448
|
-
|
|
127447
|
+
join4([node.name, varDefs]),
|
|
127448
|
+
join4(node.directives, " ")
|
|
127449
127449
|
],
|
|
127450
127450
|
" "
|
|
127451
127451
|
);
|
|
@@ -127453,7 +127453,7 @@ var require_printer = __commonJS({
|
|
|
127453
127453
|
}
|
|
127454
127454
|
},
|
|
127455
127455
|
VariableDefinition: {
|
|
127456
|
-
leave: ({ variable, type, defaultValue, directives, description }) => wrap("", description, "\n") + variable + ": " + type + wrap(" = ", defaultValue) + wrap(" ",
|
|
127456
|
+
leave: ({ variable, type, defaultValue, directives, description }) => wrap("", description, "\n") + variable + ": " + type + wrap(" = ", defaultValue) + wrap(" ", join4(directives, " "))
|
|
127457
127457
|
},
|
|
127458
127458
|
SelectionSet: {
|
|
127459
127459
|
leave: ({ selections }) => block(selections)
|
|
@@ -127461,11 +127461,11 @@ var require_printer = __commonJS({
|
|
|
127461
127461
|
Field: {
|
|
127462
127462
|
leave({ alias, name, arguments: args, directives, selectionSet }) {
|
|
127463
127463
|
const prefix = wrap("", alias, ": ") + name;
|
|
127464
|
-
let argsLine = prefix + wrap("(",
|
|
127464
|
+
let argsLine = prefix + wrap("(", join4(args, ", "), ")");
|
|
127465
127465
|
if (argsLine.length > MAX_LINE_LENGTH) {
|
|
127466
|
-
argsLine = prefix + wrap("(\n", indent2(
|
|
127466
|
+
argsLine = prefix + wrap("(\n", indent2(join4(args, "\n")), "\n)");
|
|
127467
127467
|
}
|
|
127468
|
-
return
|
|
127468
|
+
return join4([argsLine, join4(directives, " "), selectionSet], " ");
|
|
127469
127469
|
}
|
|
127470
127470
|
},
|
|
127471
127471
|
Argument: {
|
|
@@ -127473,14 +127473,14 @@ var require_printer = __commonJS({
|
|
|
127473
127473
|
},
|
|
127474
127474
|
// Fragments
|
|
127475
127475
|
FragmentSpread: {
|
|
127476
|
-
leave: ({ name, directives }) => "..." + name + wrap(" ",
|
|
127476
|
+
leave: ({ name, directives }) => "..." + name + wrap(" ", join4(directives, " "))
|
|
127477
127477
|
},
|
|
127478
127478
|
InlineFragment: {
|
|
127479
|
-
leave: ({ typeCondition, directives, selectionSet }) =>
|
|
127479
|
+
leave: ({ typeCondition, directives, selectionSet }) => join4(
|
|
127480
127480
|
[
|
|
127481
127481
|
"...",
|
|
127482
127482
|
wrap("on ", typeCondition),
|
|
127483
|
-
|
|
127483
|
+
join4(directives, " "),
|
|
127484
127484
|
selectionSet
|
|
127485
127485
|
],
|
|
127486
127486
|
" "
|
|
@@ -127496,7 +127496,7 @@ var require_printer = __commonJS({
|
|
|
127496
127496
|
description
|
|
127497
127497
|
}) => wrap("", description, "\n") + // Note: fragment variable definitions are experimental and may be changed
|
|
127498
127498
|
// or removed in the future.
|
|
127499
|
-
`fragment ${name}${wrap("(",
|
|
127499
|
+
`fragment ${name}${wrap("(", join4(variableDefinitions, ", "), ")")} on ${typeCondition} ${wrap("", join4(directives, " "), " ")}` + selectionSet
|
|
127500
127500
|
},
|
|
127501
127501
|
// Value
|
|
127502
127502
|
IntValue: {
|
|
@@ -127518,17 +127518,17 @@ var require_printer = __commonJS({
|
|
|
127518
127518
|
leave: ({ value }) => value
|
|
127519
127519
|
},
|
|
127520
127520
|
ListValue: {
|
|
127521
|
-
leave: ({ values }) => "[" +
|
|
127521
|
+
leave: ({ values }) => "[" + join4(values, ", ") + "]"
|
|
127522
127522
|
},
|
|
127523
127523
|
ObjectValue: {
|
|
127524
|
-
leave: ({ fields }) => "{" +
|
|
127524
|
+
leave: ({ fields }) => "{" + join4(fields, ", ") + "}"
|
|
127525
127525
|
},
|
|
127526
127526
|
ObjectField: {
|
|
127527
127527
|
leave: ({ name, value }) => name + ": " + value
|
|
127528
127528
|
},
|
|
127529
127529
|
// Directive
|
|
127530
127530
|
Directive: {
|
|
127531
|
-
leave: ({ name, arguments: args }) => "@" + name + wrap("(",
|
|
127531
|
+
leave: ({ name, arguments: args }) => "@" + name + wrap("(", join4(args, ", "), ")")
|
|
127532
127532
|
},
|
|
127533
127533
|
// Type
|
|
127534
127534
|
NamedType: {
|
|
@@ -127542,61 +127542,61 @@ var require_printer = __commonJS({
|
|
|
127542
127542
|
},
|
|
127543
127543
|
// Type System Definitions
|
|
127544
127544
|
SchemaDefinition: {
|
|
127545
|
-
leave: ({ description, directives, operationTypes }) => wrap("", description, "\n") +
|
|
127545
|
+
leave: ({ description, directives, operationTypes }) => wrap("", description, "\n") + join4(["schema", join4(directives, " "), block(operationTypes)], " ")
|
|
127546
127546
|
},
|
|
127547
127547
|
OperationTypeDefinition: {
|
|
127548
127548
|
leave: ({ operation, type }) => operation + ": " + type
|
|
127549
127549
|
},
|
|
127550
127550
|
ScalarTypeDefinition: {
|
|
127551
|
-
leave: ({ description, name, directives }) => wrap("", description, "\n") +
|
|
127551
|
+
leave: ({ description, name, directives }) => wrap("", description, "\n") + join4(["scalar", name, join4(directives, " ")], " ")
|
|
127552
127552
|
},
|
|
127553
127553
|
ObjectTypeDefinition: {
|
|
127554
|
-
leave: ({ description, name, interfaces, directives, fields }) => wrap("", description, "\n") +
|
|
127554
|
+
leave: ({ description, name, interfaces, directives, fields }) => wrap("", description, "\n") + join4(
|
|
127555
127555
|
[
|
|
127556
127556
|
"type",
|
|
127557
127557
|
name,
|
|
127558
|
-
wrap("implements ",
|
|
127559
|
-
|
|
127558
|
+
wrap("implements ", join4(interfaces, " & ")),
|
|
127559
|
+
join4(directives, " "),
|
|
127560
127560
|
block(fields)
|
|
127561
127561
|
],
|
|
127562
127562
|
" "
|
|
127563
127563
|
)
|
|
127564
127564
|
},
|
|
127565
127565
|
FieldDefinition: {
|
|
127566
|
-
leave: ({ description, name, arguments: args, type, directives }) => wrap("", description, "\n") + name + (hasMultilineItems(args) ? wrap("(\n", indent2(
|
|
127566
|
+
leave: ({ description, name, arguments: args, type, directives }) => wrap("", description, "\n") + name + (hasMultilineItems(args) ? wrap("(\n", indent2(join4(args, "\n")), "\n)") : wrap("(", join4(args, ", "), ")")) + ": " + type + wrap(" ", join4(directives, " "))
|
|
127567
127567
|
},
|
|
127568
127568
|
InputValueDefinition: {
|
|
127569
|
-
leave: ({ description, name, type, defaultValue, directives }) => wrap("", description, "\n") +
|
|
127570
|
-
[name + ": " + type, wrap("= ", defaultValue),
|
|
127569
|
+
leave: ({ description, name, type, defaultValue, directives }) => wrap("", description, "\n") + join4(
|
|
127570
|
+
[name + ": " + type, wrap("= ", defaultValue), join4(directives, " ")],
|
|
127571
127571
|
" "
|
|
127572
127572
|
)
|
|
127573
127573
|
},
|
|
127574
127574
|
InterfaceTypeDefinition: {
|
|
127575
|
-
leave: ({ description, name, interfaces, directives, fields }) => wrap("", description, "\n") +
|
|
127575
|
+
leave: ({ description, name, interfaces, directives, fields }) => wrap("", description, "\n") + join4(
|
|
127576
127576
|
[
|
|
127577
127577
|
"interface",
|
|
127578
127578
|
name,
|
|
127579
|
-
wrap("implements ",
|
|
127580
|
-
|
|
127579
|
+
wrap("implements ", join4(interfaces, " & ")),
|
|
127580
|
+
join4(directives, " "),
|
|
127581
127581
|
block(fields)
|
|
127582
127582
|
],
|
|
127583
127583
|
" "
|
|
127584
127584
|
)
|
|
127585
127585
|
},
|
|
127586
127586
|
UnionTypeDefinition: {
|
|
127587
|
-
leave: ({ description, name, directives, types: types2 }) => wrap("", description, "\n") +
|
|
127588
|
-
["union", name,
|
|
127587
|
+
leave: ({ description, name, directives, types: types2 }) => wrap("", description, "\n") + join4(
|
|
127588
|
+
["union", name, join4(directives, " "), wrap("= ", join4(types2, " | "))],
|
|
127589
127589
|
" "
|
|
127590
127590
|
)
|
|
127591
127591
|
},
|
|
127592
127592
|
EnumTypeDefinition: {
|
|
127593
|
-
leave: ({ description, name, directives, values }) => wrap("", description, "\n") +
|
|
127593
|
+
leave: ({ description, name, directives, values }) => wrap("", description, "\n") + join4(["enum", name, join4(directives, " "), block(values)], " ")
|
|
127594
127594
|
},
|
|
127595
127595
|
EnumValueDefinition: {
|
|
127596
|
-
leave: ({ description, name, directives }) => wrap("", description, "\n") +
|
|
127596
|
+
leave: ({ description, name, directives }) => wrap("", description, "\n") + join4([name, join4(directives, " ")], " ")
|
|
127597
127597
|
},
|
|
127598
127598
|
InputObjectTypeDefinition: {
|
|
127599
|
-
leave: ({ description, name, directives, fields }) => wrap("", description, "\n") +
|
|
127599
|
+
leave: ({ description, name, directives, fields }) => wrap("", description, "\n") + join4(["input", name, join4(directives, " "), block(fields)], " ")
|
|
127600
127600
|
},
|
|
127601
127601
|
DirectiveDefinition: {
|
|
127602
127602
|
leave: ({
|
|
@@ -127606,84 +127606,84 @@ var require_printer = __commonJS({
|
|
|
127606
127606
|
directives,
|
|
127607
127607
|
repeatable,
|
|
127608
127608
|
locations
|
|
127609
|
-
}) => wrap("", description, "\n") + "directive @" + name + (hasMultilineItems(args) ? wrap("(\n", indent2(
|
|
127609
|
+
}) => wrap("", description, "\n") + "directive @" + name + (hasMultilineItems(args) ? wrap("(\n", indent2(join4(args, "\n")), "\n)") : wrap("(", join4(args, ", "), ")")) + wrap(" ", join4(directives, " ")) + (repeatable ? " repeatable" : "") + " on " + join4(locations, " | ")
|
|
127610
127610
|
},
|
|
127611
127611
|
SchemaExtension: {
|
|
127612
|
-
leave: ({ directives, operationTypes }) =>
|
|
127613
|
-
["extend schema",
|
|
127612
|
+
leave: ({ directives, operationTypes }) => join4(
|
|
127613
|
+
["extend schema", join4(directives, " "), block(operationTypes)],
|
|
127614
127614
|
" "
|
|
127615
127615
|
)
|
|
127616
127616
|
},
|
|
127617
127617
|
ScalarTypeExtension: {
|
|
127618
|
-
leave: ({ name, directives }) =>
|
|
127618
|
+
leave: ({ name, directives }) => join4(["extend scalar", name, join4(directives, " ")], " ")
|
|
127619
127619
|
},
|
|
127620
127620
|
ObjectTypeExtension: {
|
|
127621
|
-
leave: ({ name, interfaces, directives, fields }) =>
|
|
127621
|
+
leave: ({ name, interfaces, directives, fields }) => join4(
|
|
127622
127622
|
[
|
|
127623
127623
|
"extend type",
|
|
127624
127624
|
name,
|
|
127625
|
-
wrap("implements ",
|
|
127626
|
-
|
|
127625
|
+
wrap("implements ", join4(interfaces, " & ")),
|
|
127626
|
+
join4(directives, " "),
|
|
127627
127627
|
block(fields)
|
|
127628
127628
|
],
|
|
127629
127629
|
" "
|
|
127630
127630
|
)
|
|
127631
127631
|
},
|
|
127632
127632
|
InterfaceTypeExtension: {
|
|
127633
|
-
leave: ({ name, interfaces, directives, fields }) =>
|
|
127633
|
+
leave: ({ name, interfaces, directives, fields }) => join4(
|
|
127634
127634
|
[
|
|
127635
127635
|
"extend interface",
|
|
127636
127636
|
name,
|
|
127637
|
-
wrap("implements ",
|
|
127638
|
-
|
|
127637
|
+
wrap("implements ", join4(interfaces, " & ")),
|
|
127638
|
+
join4(directives, " "),
|
|
127639
127639
|
block(fields)
|
|
127640
127640
|
],
|
|
127641
127641
|
" "
|
|
127642
127642
|
)
|
|
127643
127643
|
},
|
|
127644
127644
|
UnionTypeExtension: {
|
|
127645
|
-
leave: ({ name, directives, types: types2 }) =>
|
|
127645
|
+
leave: ({ name, directives, types: types2 }) => join4(
|
|
127646
127646
|
[
|
|
127647
127647
|
"extend union",
|
|
127648
127648
|
name,
|
|
127649
|
-
|
|
127650
|
-
wrap("= ",
|
|
127649
|
+
join4(directives, " "),
|
|
127650
|
+
wrap("= ", join4(types2, " | "))
|
|
127651
127651
|
],
|
|
127652
127652
|
" "
|
|
127653
127653
|
)
|
|
127654
127654
|
},
|
|
127655
127655
|
EnumTypeExtension: {
|
|
127656
|
-
leave: ({ name, directives, values }) =>
|
|
127656
|
+
leave: ({ name, directives, values }) => join4(["extend enum", name, join4(directives, " "), block(values)], " ")
|
|
127657
127657
|
},
|
|
127658
127658
|
InputObjectTypeExtension: {
|
|
127659
|
-
leave: ({ name, directives, fields }) =>
|
|
127659
|
+
leave: ({ name, directives, fields }) => join4(["extend input", name, join4(directives, " "), block(fields)], " ")
|
|
127660
127660
|
},
|
|
127661
127661
|
DirectiveExtension: {
|
|
127662
|
-
leave: ({ name, directives }) =>
|
|
127662
|
+
leave: ({ name, directives }) => join4(["extend directive @" + name, join4(directives, " ")], " ")
|
|
127663
127663
|
},
|
|
127664
127664
|
// Schema Coordinates
|
|
127665
127665
|
TypeCoordinate: {
|
|
127666
127666
|
leave: ({ name }) => name
|
|
127667
127667
|
},
|
|
127668
127668
|
MemberCoordinate: {
|
|
127669
|
-
leave: ({ name, memberName }) =>
|
|
127669
|
+
leave: ({ name, memberName }) => join4([name, wrap(".", memberName)])
|
|
127670
127670
|
},
|
|
127671
127671
|
ArgumentCoordinate: {
|
|
127672
|
-
leave: ({ name, fieldName, argumentName }) =>
|
|
127672
|
+
leave: ({ name, fieldName, argumentName }) => join4([name, wrap(".", fieldName), wrap("(", argumentName, ":)")])
|
|
127673
127673
|
},
|
|
127674
127674
|
DirectiveCoordinate: {
|
|
127675
|
-
leave: ({ name }) =>
|
|
127675
|
+
leave: ({ name }) => join4(["@", name])
|
|
127676
127676
|
},
|
|
127677
127677
|
DirectiveArgumentCoordinate: {
|
|
127678
|
-
leave: ({ name, argumentName }) =>
|
|
127678
|
+
leave: ({ name, argumentName }) => join4(["@", name, wrap("(", argumentName, ":)")])
|
|
127679
127679
|
}
|
|
127680
127680
|
};
|
|
127681
|
-
function
|
|
127681
|
+
function join4(maybeArray, separator = "") {
|
|
127682
127682
|
var _maybeArray$filter$jo;
|
|
127683
127683
|
return (_maybeArray$filter$jo = maybeArray === null || maybeArray === void 0 ? void 0 : maybeArray.filter((x) => x).join(separator)) !== null && _maybeArray$filter$jo !== void 0 ? _maybeArray$filter$jo : "";
|
|
127684
127684
|
}
|
|
127685
127685
|
function block(array) {
|
|
127686
|
-
return wrap("{\n", indent2(
|
|
127686
|
+
return wrap("{\n", indent2(join4(array, "\n")), "\n}");
|
|
127687
127687
|
}
|
|
127688
127688
|
function wrap(start, maybeString, end = "") {
|
|
127689
127689
|
return maybeString != null && maybeString !== "" ? start + maybeString + end : "";
|
|
@@ -152317,7 +152317,7 @@ var require_index_cjs = __commonJS({
|
|
|
152317
152317
|
const t = parse10(r);
|
|
152318
152318
|
return "http" === t.protocol || "https" === t.protocol;
|
|
152319
152319
|
}
|
|
152320
|
-
var
|
|
152320
|
+
var join4 = (...r) => {
|
|
152321
152321
|
if (0 === r.length) return ".";
|
|
152322
152322
|
const t = r.map(parse10), e = Object.assign({}, t[0]);
|
|
152323
152323
|
for (let n = 1; n < t.length; n++) {
|
|
@@ -152341,7 +152341,7 @@ var require_index_cjs = __commonJS({
|
|
|
152341
152341
|
function resolve4(...r) {
|
|
152342
152342
|
if (0 === r.length) return ".";
|
|
152343
152343
|
const t = normalizeParsed(parse10(r[r.length - 1]));
|
|
152344
|
-
return t.absolute ? format3(t) :
|
|
152344
|
+
return t.absolute ? format3(t) : join4(...r);
|
|
152345
152345
|
}
|
|
152346
152346
|
var startsWithWindowsDrive = (r) => {
|
|
152347
152347
|
return null !== parse10(r).drive;
|
|
@@ -152355,7 +152355,7 @@ var require_index_cjs = __commonJS({
|
|
|
152355
152355
|
function serializeSrn({ shortcode: r, orgSlug: t, projectSlug: e, uri: n = "" }) {
|
|
152356
152356
|
return [r, t, e, n.replace(/^\//, "")].filter(Boolean).join("/");
|
|
152357
152357
|
}
|
|
152358
|
-
exports2.basename = basename3, exports2.deserializeSrn = deserializeSrn, exports2.dirname = dirname3, exports2.extname = extname2, exports2.format = format3, exports2.isAbsolute = isAbsolute, exports2.isURL = isURL, exports2.join =
|
|
152358
|
+
exports2.basename = basename3, exports2.deserializeSrn = deserializeSrn, exports2.dirname = dirname3, exports2.extname = extname2, exports2.format = format3, exports2.isAbsolute = isAbsolute, exports2.isURL = isURL, exports2.join = join4, exports2.normalize = normalize3, exports2.parse = parse10, exports2.relative = relative2, exports2.resolve = resolve4, exports2.sep = "/", exports2.serializeSrn = serializeSrn, exports2.startsWithWindowsDrive = startsWithWindowsDrive, exports2.stripRoot = stripRoot, exports2.toFSPath = normalize3;
|
|
152359
152359
|
}
|
|
152360
152360
|
});
|
|
152361
152361
|
|
|
@@ -154098,7 +154098,7 @@ var require_stable = __commonJS({
|
|
|
154098
154098
|
return result;
|
|
154099
154099
|
}
|
|
154100
154100
|
function stringifyFullFn(key, parent, stack, replacer, indent2) {
|
|
154101
|
-
var i, res,
|
|
154101
|
+
var i, res, join4;
|
|
154102
154102
|
const originalIndentation = indentation;
|
|
154103
154103
|
var value = parent[key];
|
|
154104
154104
|
if (typeof value === "object" && value !== null && typeof value.toJSON === "function") {
|
|
@@ -154124,12 +154124,12 @@ var require_stable = __commonJS({
|
|
|
154124
154124
|
indentation += indent2;
|
|
154125
154125
|
res += `
|
|
154126
154126
|
${indentation}`;
|
|
154127
|
-
|
|
154127
|
+
join4 = `,
|
|
154128
154128
|
${indentation}`;
|
|
154129
154129
|
for (i = 0; i < value.length - 1; i++) {
|
|
154130
154130
|
const tmp2 = stringifyFullFn(i, value, stack, replacer, indent2);
|
|
154131
154131
|
res += tmp2 !== void 0 ? tmp2 : "null";
|
|
154132
|
-
res +=
|
|
154132
|
+
res += join4;
|
|
154133
154133
|
}
|
|
154134
154134
|
const tmp = stringifyFullFn(i, value, stack, replacer, indent2);
|
|
154135
154135
|
res += tmp !== void 0 ? tmp : "null";
|
|
@@ -154151,7 +154151,7 @@ ${originalIndentation}`;
|
|
|
154151
154151
|
indentation += indent2;
|
|
154152
154152
|
res += `
|
|
154153
154153
|
${indentation}`;
|
|
154154
|
-
|
|
154154
|
+
join4 = `,
|
|
154155
154155
|
${indentation}`;
|
|
154156
154156
|
var separator = "";
|
|
154157
154157
|
for (i = 0; i < keys.length; i++) {
|
|
@@ -154159,7 +154159,7 @@ ${indentation}`;
|
|
|
154159
154159
|
const tmp = stringifyFullFn(key, value, stack, replacer, indent2);
|
|
154160
154160
|
if (tmp !== void 0) {
|
|
154161
154161
|
res += `${separator}"${strEscape(key)}": ${tmp}`;
|
|
154162
|
-
separator =
|
|
154162
|
+
separator = join4;
|
|
154163
154163
|
}
|
|
154164
154164
|
}
|
|
154165
154165
|
if (separator !== "") {
|
|
@@ -154181,7 +154181,7 @@ ${originalIndentation}`;
|
|
|
154181
154181
|
}
|
|
154182
154182
|
}
|
|
154183
154183
|
function stringifyFullArr(key, value, stack, replacer, indent2) {
|
|
154184
|
-
var i, res,
|
|
154184
|
+
var i, res, join4;
|
|
154185
154185
|
const originalIndentation = indentation;
|
|
154186
154186
|
if (typeof value === "object" && value !== null && typeof value.toJSON === "function") {
|
|
154187
154187
|
value = value.toJSON(key);
|
|
@@ -154205,12 +154205,12 @@ ${originalIndentation}`;
|
|
|
154205
154205
|
indentation += indent2;
|
|
154206
154206
|
res += `
|
|
154207
154207
|
${indentation}`;
|
|
154208
|
-
|
|
154208
|
+
join4 = `,
|
|
154209
154209
|
${indentation}`;
|
|
154210
154210
|
for (i = 0; i < value.length - 1; i++) {
|
|
154211
154211
|
const tmp2 = stringifyFullArr(i, value[i], stack, replacer, indent2);
|
|
154212
154212
|
res += tmp2 !== void 0 ? tmp2 : "null";
|
|
154213
|
-
res +=
|
|
154213
|
+
res += join4;
|
|
154214
154214
|
}
|
|
154215
154215
|
const tmp = stringifyFullArr(i, value[i], stack, replacer, indent2);
|
|
154216
154216
|
res += tmp !== void 0 ? tmp : "null";
|
|
@@ -154231,7 +154231,7 @@ ${originalIndentation}`;
|
|
|
154231
154231
|
indentation += indent2;
|
|
154232
154232
|
res += `
|
|
154233
154233
|
${indentation}`;
|
|
154234
|
-
|
|
154234
|
+
join4 = `,
|
|
154235
154235
|
${indentation}`;
|
|
154236
154236
|
var separator = "";
|
|
154237
154237
|
for (i = 0; i < replacer.length; i++) {
|
|
@@ -154240,7 +154240,7 @@ ${indentation}`;
|
|
|
154240
154240
|
const tmp = stringifyFullArr(key, value[key], stack, replacer, indent2);
|
|
154241
154241
|
if (tmp !== void 0) {
|
|
154242
154242
|
res += `${separator}"${strEscape(key)}": ${tmp}`;
|
|
154243
|
-
separator =
|
|
154243
|
+
separator = join4;
|
|
154244
154244
|
}
|
|
154245
154245
|
}
|
|
154246
154246
|
}
|
|
@@ -154263,7 +154263,7 @@ ${originalIndentation}`;
|
|
|
154263
154263
|
}
|
|
154264
154264
|
}
|
|
154265
154265
|
function stringifyIndent(key, value, stack, indent2) {
|
|
154266
|
-
var i, res,
|
|
154266
|
+
var i, res, join4;
|
|
154267
154267
|
const originalIndentation = indentation;
|
|
154268
154268
|
switch (typeof value) {
|
|
154269
154269
|
case "object":
|
|
@@ -154293,12 +154293,12 @@ ${originalIndentation}`;
|
|
|
154293
154293
|
indentation += indent2;
|
|
154294
154294
|
res += `
|
|
154295
154295
|
${indentation}`;
|
|
154296
|
-
|
|
154296
|
+
join4 = `,
|
|
154297
154297
|
${indentation}`;
|
|
154298
154298
|
for (i = 0; i < value.length - 1; i++) {
|
|
154299
154299
|
const tmp2 = stringifyIndent(i, value[i], stack, indent2);
|
|
154300
154300
|
res += tmp2 !== void 0 ? tmp2 : "null";
|
|
154301
|
-
res +=
|
|
154301
|
+
res += join4;
|
|
154302
154302
|
}
|
|
154303
154303
|
const tmp = stringifyIndent(i, value[i], stack, indent2);
|
|
154304
154304
|
res += tmp !== void 0 ? tmp : "null";
|
|
@@ -154320,7 +154320,7 @@ ${originalIndentation}`;
|
|
|
154320
154320
|
indentation += indent2;
|
|
154321
154321
|
res += `
|
|
154322
154322
|
${indentation}`;
|
|
154323
|
-
|
|
154323
|
+
join4 = `,
|
|
154324
154324
|
${indentation}`;
|
|
154325
154325
|
var separator = "";
|
|
154326
154326
|
for (i = 0; i < keys.length; i++) {
|
|
@@ -154328,7 +154328,7 @@ ${indentation}`;
|
|
|
154328
154328
|
const tmp = stringifyIndent(key, value[key], stack, indent2);
|
|
154329
154329
|
if (tmp !== void 0) {
|
|
154330
154330
|
res += `${separator}"${strEscape(key)}": ${tmp}`;
|
|
154331
|
-
separator =
|
|
154331
|
+
separator = join4;
|
|
154332
154332
|
}
|
|
154333
154333
|
}
|
|
154334
154334
|
if (separator !== "") {
|
|
@@ -172661,7 +172661,7 @@ var require_lodash2 = __commonJS({
|
|
|
172661
172661
|
}
|
|
172662
172662
|
return mapped.length && mapped[0] === arrays[0] ? baseIntersection(mapped, undefined2, comparator) : [];
|
|
172663
172663
|
});
|
|
172664
|
-
function
|
|
172664
|
+
function join4(array, separator) {
|
|
172665
172665
|
return array == null ? "" : nativeJoin.call(array, separator);
|
|
172666
172666
|
}
|
|
172667
172667
|
function last(array) {
|
|
@@ -174585,7 +174585,7 @@ var require_lodash2 = __commonJS({
|
|
|
174585
174585
|
lodash.isUndefined = isUndefined;
|
|
174586
174586
|
lodash.isWeakMap = isWeakMap;
|
|
174587
174587
|
lodash.isWeakSet = isWeakSet;
|
|
174588
|
-
lodash.join =
|
|
174588
|
+
lodash.join = join4;
|
|
174589
174589
|
lodash.kebabCase = kebabCase;
|
|
174590
174590
|
lodash.last = last;
|
|
174591
174591
|
lodash.lastIndexOf = lastIndexOf;
|
|
@@ -179719,7 +179719,7 @@ var require_lodash3 = __commonJS({
|
|
|
179719
179719
|
}
|
|
179720
179720
|
return mapped.length && mapped[0] === arrays[0] ? baseIntersection(mapped, undefined2, comparator) : [];
|
|
179721
179721
|
});
|
|
179722
|
-
function
|
|
179722
|
+
function join4(array, separator) {
|
|
179723
179723
|
return array == null ? "" : nativeJoin.call(array, separator);
|
|
179724
179724
|
}
|
|
179725
179725
|
function last(array) {
|
|
@@ -181643,7 +181643,7 @@ var require_lodash3 = __commonJS({
|
|
|
181643
181643
|
lodash.isUndefined = isUndefined;
|
|
181644
181644
|
lodash.isWeakMap = isWeakMap;
|
|
181645
181645
|
lodash.isWeakSet = isWeakSet;
|
|
181646
|
-
lodash.join =
|
|
181646
|
+
lodash.join = join4;
|
|
181647
181647
|
lodash.kebabCase = kebabCase;
|
|
181648
181648
|
lodash.last = last;
|
|
181649
181649
|
lodash.lastIndexOf = lastIndexOf;
|
|
@@ -283138,7 +283138,7 @@ var require_lodash5 = __commonJS({
|
|
|
283138
283138
|
}
|
|
283139
283139
|
return mapped.length && mapped[0] === arrays[0] ? baseIntersection(mapped, undefined2, comparator) : [];
|
|
283140
283140
|
});
|
|
283141
|
-
function
|
|
283141
|
+
function join4(array, separator) {
|
|
283142
283142
|
return array == null ? "" : nativeJoin.call(array, separator);
|
|
283143
283143
|
}
|
|
283144
283144
|
function last(array) {
|
|
@@ -285062,7 +285062,7 @@ var require_lodash5 = __commonJS({
|
|
|
285062
285062
|
lodash.isUndefined = isUndefined;
|
|
285063
285063
|
lodash.isWeakMap = isWeakMap;
|
|
285064
285064
|
lodash.isWeakSet = isWeakSet;
|
|
285065
|
-
lodash.join =
|
|
285065
|
+
lodash.join = join4;
|
|
285066
285066
|
lodash.kebabCase = kebabCase;
|
|
285067
285067
|
lodash.last = last;
|
|
285068
285068
|
lodash.lastIndexOf = lastIndexOf;
|
|
@@ -292261,10 +292261,10 @@ __export(cli_exports, {
|
|
|
292261
292261
|
toDotenv: () => toDotenv
|
|
292262
292262
|
});
|
|
292263
292263
|
module.exports = __toCommonJS(cli_exports);
|
|
292264
|
-
var
|
|
292264
|
+
var import_node_fs6 = require("node:fs");
|
|
292265
292265
|
var import_promises4 = require("node:fs/promises");
|
|
292266
292266
|
var import_node_child_process = require("node:child_process");
|
|
292267
|
-
var
|
|
292267
|
+
var import_node_path5 = __toESM(require("node:path"), 1);
|
|
292268
292268
|
var import_node_util = require("node:util");
|
|
292269
292269
|
|
|
292270
292270
|
// node_modules/@actions/io/lib/io.js
|
|
@@ -292988,7 +292988,7 @@ var ExitCode;
|
|
|
292988
292988
|
|
|
292989
292989
|
// src/index.ts
|
|
292990
292990
|
var import_node_crypto4 = require("node:crypto");
|
|
292991
|
-
var
|
|
292991
|
+
var import_node_fs5 = require("node:fs");
|
|
292992
292992
|
var path6 = __toESM(require("node:path"), 1);
|
|
292993
292993
|
var import_yaml4 = __toESM(require_dist(), 1);
|
|
292994
292994
|
|
|
@@ -294542,12 +294542,62 @@ function resolvePostmanEndpointProfile(stack, region = "us") {
|
|
|
294542
294542
|
|
|
294543
294543
|
// src/lib/postman/credential-identity.ts
|
|
294544
294544
|
var sessionPath = "/api/sessions/current";
|
|
294545
|
+
var SESSION_MAX_ATTEMPTS = 3;
|
|
294546
|
+
var SESSION_RETRY_BASE_DELAY_MS = 500;
|
|
294547
|
+
var SESSION_RETRY_MAX_DELAY_MS = 8e3;
|
|
294545
294548
|
var pmakMemo = /* @__PURE__ */ new Map();
|
|
294546
294549
|
var sessionMemo = /* @__PURE__ */ new Map();
|
|
294547
294550
|
var memoizedSessionIdentity;
|
|
294551
|
+
var memoizedSessionFailure;
|
|
294552
|
+
function defaultSessionSleep(ms) {
|
|
294553
|
+
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
294554
|
+
}
|
|
294555
|
+
function defaultRandom() {
|
|
294556
|
+
return Math.random();
|
|
294557
|
+
}
|
|
294558
|
+
function parseRetryAfterMs(value) {
|
|
294559
|
+
const trimmed = value?.trim();
|
|
294560
|
+
if (!trimmed) {
|
|
294561
|
+
return void 0;
|
|
294562
|
+
}
|
|
294563
|
+
if (/^\d+$/.test(trimmed)) {
|
|
294564
|
+
return Number(trimmed) * 1e3;
|
|
294565
|
+
}
|
|
294566
|
+
const dateMs = Date.parse(trimmed);
|
|
294567
|
+
if (!Number.isNaN(dateMs)) {
|
|
294568
|
+
return Math.max(0, dateMs - Date.now());
|
|
294569
|
+
}
|
|
294570
|
+
return void 0;
|
|
294571
|
+
}
|
|
294572
|
+
function parseRateLimitResetMs(value) {
|
|
294573
|
+
const trimmed = value?.trim();
|
|
294574
|
+
if (!trimmed || !/^\d+$/.test(trimmed)) {
|
|
294575
|
+
return void 0;
|
|
294576
|
+
}
|
|
294577
|
+
const seconds = Number(trimmed);
|
|
294578
|
+
const nowSeconds = Date.now() / 1e3;
|
|
294579
|
+
if (seconds > nowSeconds) {
|
|
294580
|
+
return Math.max(0, (seconds - nowSeconds) * 1e3);
|
|
294581
|
+
}
|
|
294582
|
+
return seconds * 1e3;
|
|
294583
|
+
}
|
|
294584
|
+
function computeSessionRetryDelayMs(response, attempt, random) {
|
|
294585
|
+
const headers = response?.headers;
|
|
294586
|
+
const signal = parseRetryAfterMs(headers?.get("retry-after") ?? null) ?? parseRateLimitResetMs(
|
|
294587
|
+
headers?.get("ratelimit-reset") ?? headers?.get("x-ratelimit-reset") ?? null
|
|
294588
|
+
);
|
|
294589
|
+
if (signal !== void 0) {
|
|
294590
|
+
return Math.min(Math.max(0, signal), SESSION_RETRY_MAX_DELAY_MS);
|
|
294591
|
+
}
|
|
294592
|
+
const ceiling = Math.min(SESSION_RETRY_MAX_DELAY_MS, SESSION_RETRY_BASE_DELAY_MS * 2 ** (attempt - 1));
|
|
294593
|
+
return Math.round(random() * ceiling);
|
|
294594
|
+
}
|
|
294548
294595
|
function getMemoizedSessionIdentity() {
|
|
294549
294596
|
return memoizedSessionIdentity;
|
|
294550
294597
|
}
|
|
294598
|
+
function getSessionResolutionFailure() {
|
|
294599
|
+
return memoizedSessionFailure;
|
|
294600
|
+
}
|
|
294551
294601
|
function asRecord2(value) {
|
|
294552
294602
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
294553
294603
|
return void 0;
|
|
@@ -294616,46 +294666,90 @@ async function resolveSessionIdentity(opts) {
|
|
|
294616
294666
|
const memoKey = `${baseUrl}::${accessToken}`;
|
|
294617
294667
|
let pending = sessionMemo.get(memoKey);
|
|
294618
294668
|
if (!pending) {
|
|
294619
|
-
pending = probeSessionIdentity(
|
|
294669
|
+
pending = probeSessionIdentity(
|
|
294670
|
+
baseUrl,
|
|
294671
|
+
accessToken,
|
|
294672
|
+
opts.fetchImpl ?? fetch,
|
|
294673
|
+
Math.max(1, opts.maxAttempts ?? SESSION_MAX_ATTEMPTS),
|
|
294674
|
+
opts.sleepImpl ?? defaultSessionSleep,
|
|
294675
|
+
opts.randomImpl ?? defaultRandom
|
|
294676
|
+
);
|
|
294620
294677
|
sessionMemo.set(memoKey, pending);
|
|
294621
294678
|
}
|
|
294622
294679
|
return pending;
|
|
294623
294680
|
}
|
|
294624
|
-
async function
|
|
294681
|
+
async function parseSessionResponse(response) {
|
|
294682
|
+
let payload;
|
|
294625
294683
|
try {
|
|
294626
|
-
|
|
294627
|
-
method: "GET",
|
|
294628
|
-
headers: { "x-access-token": accessToken }
|
|
294629
|
-
});
|
|
294630
|
-
if (!response.ok) {
|
|
294631
|
-
return void 0;
|
|
294632
|
-
}
|
|
294633
|
-
const payload = asRecord2(await response.json());
|
|
294634
|
-
if (!payload) {
|
|
294635
|
-
return void 0;
|
|
294636
|
-
}
|
|
294637
|
-
const root = asRecord2(payload.session) ?? payload;
|
|
294638
|
-
const identity = asRecord2(root.identity);
|
|
294639
|
-
const data = asRecord2(root.data);
|
|
294640
|
-
const user = asRecord2(data?.user);
|
|
294641
|
-
const roleEntries = Array.isArray(user?.roles) ? user.roles.map((entry) => coerceText(entry) ?? coerceId(entry)).filter((entry) => Boolean(entry)) : [];
|
|
294642
|
-
const singleRole = coerceText(user?.role);
|
|
294643
|
-
const roles = roleEntries.length > 0 ? roleEntries : singleRole ? [singleRole] : void 0;
|
|
294644
|
-
const resolved = {
|
|
294645
|
-
source: "iapub/sessions",
|
|
294646
|
-
userId: coerceId(identity?.user) ?? coerceId(user?.id),
|
|
294647
|
-
fullName: coerceText(user?.fullName) ?? coerceText(user?.name) ?? coerceText(user?.username),
|
|
294648
|
-
teamId: coerceId(identity?.team),
|
|
294649
|
-
teamName: coerceText(user?.teamName),
|
|
294650
|
-
teamDomain: coerceText(identity?.domain),
|
|
294651
|
-
...roles ? { roles } : {},
|
|
294652
|
-
consumerType: coerceText(root.consumerType) ?? coerceText(data?.consumerType) ?? coerceText(user?.consumerType)
|
|
294653
|
-
};
|
|
294654
|
-
memoizedSessionIdentity = resolved;
|
|
294655
|
-
return resolved;
|
|
294684
|
+
payload = asRecord2(await response.json());
|
|
294656
294685
|
} catch {
|
|
294657
294686
|
return void 0;
|
|
294658
294687
|
}
|
|
294688
|
+
if (!payload) {
|
|
294689
|
+
return void 0;
|
|
294690
|
+
}
|
|
294691
|
+
const root = asRecord2(payload.session) ?? payload;
|
|
294692
|
+
const identity = asRecord2(root.identity);
|
|
294693
|
+
const data = asRecord2(root.data);
|
|
294694
|
+
const user = asRecord2(data?.user);
|
|
294695
|
+
const roleEntries = Array.isArray(user?.roles) ? user.roles.map((entry) => coerceText(entry) ?? coerceId(entry)).filter((entry) => Boolean(entry)) : [];
|
|
294696
|
+
const singleRole = coerceText(user?.role);
|
|
294697
|
+
const roles = roleEntries.length > 0 ? roleEntries : singleRole ? [singleRole] : void 0;
|
|
294698
|
+
return {
|
|
294699
|
+
source: "iapub/sessions",
|
|
294700
|
+
userId: coerceId(identity?.user) ?? coerceId(user?.id),
|
|
294701
|
+
fullName: coerceText(user?.fullName) ?? coerceText(user?.name) ?? coerceText(user?.username),
|
|
294702
|
+
teamId: coerceId(identity?.team),
|
|
294703
|
+
teamName: coerceText(user?.teamName),
|
|
294704
|
+
teamDomain: coerceText(identity?.domain),
|
|
294705
|
+
...roles ? { roles } : {},
|
|
294706
|
+
consumerType: coerceText(root.consumerType) ?? coerceText(data?.consumerType) ?? coerceText(user?.consumerType)
|
|
294707
|
+
};
|
|
294708
|
+
}
|
|
294709
|
+
async function probeSessionIdentity(baseUrl, accessToken, fetchImpl, maxAttempts, sleepImpl, random) {
|
|
294710
|
+
let failure = "unavailable";
|
|
294711
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
|
|
294712
|
+
let response;
|
|
294713
|
+
try {
|
|
294714
|
+
response = await fetchImpl(`${baseUrl}${sessionPath}`, {
|
|
294715
|
+
method: "GET",
|
|
294716
|
+
headers: { "x-access-token": accessToken }
|
|
294717
|
+
});
|
|
294718
|
+
} catch {
|
|
294719
|
+
failure = "unavailable";
|
|
294720
|
+
if (attempt < maxAttempts) {
|
|
294721
|
+
await sleepImpl(computeSessionRetryDelayMs(void 0, attempt, random));
|
|
294722
|
+
continue;
|
|
294723
|
+
}
|
|
294724
|
+
break;
|
|
294725
|
+
}
|
|
294726
|
+
if (response.ok) {
|
|
294727
|
+
const resolved = await parseSessionResponse(response);
|
|
294728
|
+
if (resolved) {
|
|
294729
|
+
memoizedSessionIdentity = resolved;
|
|
294730
|
+
memoizedSessionFailure = void 0;
|
|
294731
|
+
return resolved;
|
|
294732
|
+
}
|
|
294733
|
+
failure = "unavailable";
|
|
294734
|
+
break;
|
|
294735
|
+
}
|
|
294736
|
+
if (response.status === 401 || response.status === 403) {
|
|
294737
|
+
failure = "auth";
|
|
294738
|
+
break;
|
|
294739
|
+
}
|
|
294740
|
+
if (response.status === 429 || response.status >= 500) {
|
|
294741
|
+
failure = "unavailable";
|
|
294742
|
+
if (attempt < maxAttempts) {
|
|
294743
|
+
await sleepImpl(computeSessionRetryDelayMs(response, attempt, random));
|
|
294744
|
+
continue;
|
|
294745
|
+
}
|
|
294746
|
+
break;
|
|
294747
|
+
}
|
|
294748
|
+
failure = "unavailable";
|
|
294749
|
+
break;
|
|
294750
|
+
}
|
|
294751
|
+
memoizedSessionFailure = failure;
|
|
294752
|
+
return void 0;
|
|
294659
294753
|
}
|
|
294660
294754
|
function describeTeam(id) {
|
|
294661
294755
|
const label = id?.teamName ?? id?.teamDomain;
|
|
@@ -294746,7 +294840,9 @@ async function runCredentialPreflight(args) {
|
|
|
294746
294840
|
session = await resolveSessionIdentity({
|
|
294747
294841
|
iapubBaseUrl: args.iapubBaseUrl,
|
|
294748
294842
|
accessToken,
|
|
294749
|
-
fetchImpl: args.fetchImpl
|
|
294843
|
+
fetchImpl: args.fetchImpl,
|
|
294844
|
+
...args.sleepImpl ? { sleepImpl: args.sleepImpl } : {},
|
|
294845
|
+
...args.randomImpl ? { randomImpl: args.randomImpl } : {}
|
|
294750
294846
|
});
|
|
294751
294847
|
} catch (error) {
|
|
294752
294848
|
args.log.warning(
|
|
@@ -294766,11 +294862,20 @@ async function runCredentialPreflight(args) {
|
|
|
294766
294862
|
);
|
|
294767
294863
|
}
|
|
294768
294864
|
} else {
|
|
294865
|
+
const failure = getSessionResolutionFailure();
|
|
294866
|
+
const detail = failure === "auth" ? "the access token was rejected by iapub (401/403), so it is invalid or expired. Re-mint it with postman-resolve-service-token-action (or POST https://api.getpostman.com/service-account-tokens) and re-run." : "iapub was unreachable after retries (network or 5xx). This is usually transient; re-run the job.";
|
|
294867
|
+
const base = "postman: credential preflight could not resolve the access-token session identity from iapub: " + detail;
|
|
294868
|
+
if (args.mode === "enforce") {
|
|
294869
|
+
throw new Error(
|
|
294870
|
+
mask(
|
|
294871
|
+
`${base} (credential-preflight: enforce requires a resolvable session identity; use credential-preflight: warn to continue with reactive error guidance only.)`
|
|
294872
|
+
)
|
|
294873
|
+
);
|
|
294874
|
+
}
|
|
294769
294875
|
args.log.warning(
|
|
294770
|
-
mask(
|
|
294771
|
-
"postman: credential preflight could not resolve the access-token session identity from iapub; continuing with reactive error guidance only"
|
|
294772
|
-
)
|
|
294876
|
+
mask(`${base} Continuing with reactive error guidance only (credential-preflight: warn).`)
|
|
294773
294877
|
);
|
|
294878
|
+
return;
|
|
294774
294879
|
}
|
|
294775
294880
|
const result = crossCheckIdentities({
|
|
294776
294881
|
pmak,
|
|
@@ -296537,7 +296642,11 @@ function securityCheckFor(schemeName, scheme) {
|
|
|
296537
296642
|
if (scheme?.type === "http") {
|
|
296538
296643
|
const httpScheme = String(scheme.scheme || "").toLowerCase();
|
|
296539
296644
|
if (httpScheme === "basic") return { scheme: schemeName, kind, checkable: true, prefix: "Basic " };
|
|
296540
|
-
if (httpScheme === "bearer")
|
|
296645
|
+
if (httpScheme === "bearer") {
|
|
296646
|
+
const check = { scheme: schemeName, kind, checkable: true, prefix: "Bearer " };
|
|
296647
|
+
if (typeof scheme.bearerFormat === "string" && scheme.bearerFormat) check.bearerFormat = scheme.bearerFormat;
|
|
296648
|
+
return check;
|
|
296649
|
+
}
|
|
296541
296650
|
if (httpScheme) return { scheme: schemeName, kind, checkable: true, prefix: `${httpScheme.charAt(0).toUpperCase()}${httpScheme.slice(1)} ` };
|
|
296542
296651
|
return { scheme: schemeName, kind, checkable: true, in: "header", name: "Authorization" };
|
|
296543
296652
|
}
|
|
@@ -296676,6 +296785,7 @@ function collectParameterChecks(root, pathItem, operation, version2, operationId
|
|
|
296676
296785
|
if (defaultSerialization) warnings.push(`CONTRACT_SCHEMA_NOT_COMPILED: parameter ${location2}:${name} schema on ${operationId} skipped (${packed.unsupported})`);
|
|
296677
296786
|
continue;
|
|
296678
296787
|
}
|
|
296788
|
+
validateParameterExamples(root, param, packed, `${location2}:${name} of ${operationId}`, warnings);
|
|
296679
296789
|
if (location2 === "path") {
|
|
296680
296790
|
const containingSegment = pathTemplate.split("/").find((segment) => segment.includes(`{${name}}`));
|
|
296681
296791
|
if (containingSegment !== void 0 && containingSegment !== `{${name}}`) {
|
|
@@ -296692,12 +296802,32 @@ function collectParameterChecks(root, pathItem, operation, version2, operationId
|
|
|
296692
296802
|
}
|
|
296693
296803
|
const scalarSchema = packedScalarSchema(packed);
|
|
296694
296804
|
if (scalarSchema !== void 0) {
|
|
296695
|
-
|
|
296805
|
+
const decodablePathStyle = location2 === "path" && (style === "label" || style === "matrix") && !explode ? style : void 0;
|
|
296806
|
+
if (!defaultSerialization && !decodablePathStyle) continue;
|
|
296807
|
+
if (!defaultSerialization) warnings.push(...noteWarnings);
|
|
296696
296808
|
const check2 = { in: location2, name, required: param.required === true, schema: scalarSchema };
|
|
296809
|
+
if (decodablePathStyle) check2.pathStyle = decodablePathStyle;
|
|
296697
296810
|
if (location2 === "query" && param.allowEmptyValue === true) check2.allowEmptyValue = true;
|
|
296698
296811
|
checks.push(check2);
|
|
296699
296812
|
continue;
|
|
296700
296813
|
}
|
|
296814
|
+
if (location2 === "query" && style === "deepObject" && explode) {
|
|
296815
|
+
const objectSchema = asRecord5(packed.schema);
|
|
296816
|
+
const properties = objectSchema ? asRecord5(objectSchema.properties) : null;
|
|
296817
|
+
const allScalar = properties !== null && Object.keys(properties).length > 0 && Object.values(properties).every((prop) => {
|
|
296818
|
+
const record = asRecord5(prop);
|
|
296819
|
+
if (!record) return false;
|
|
296820
|
+
const types2 = Array.isArray(record.type) ? record.type : [record.type];
|
|
296821
|
+
return types2.every((entry) => typeof entry === "string" && SCALAR_SCHEMA_TYPES.has(entry));
|
|
296822
|
+
});
|
|
296823
|
+
if (allScalar) {
|
|
296824
|
+
warnings.push(...noteWarnings);
|
|
296825
|
+
const check2 = { in: "query", name, required: param.required === true, schema: packed.schema, decode: "deepObject" };
|
|
296826
|
+
if (param.allowEmptyValue === true) check2.allowEmptyValue = true;
|
|
296827
|
+
checks.push(check2);
|
|
296828
|
+
continue;
|
|
296829
|
+
}
|
|
296830
|
+
}
|
|
296701
296831
|
if (location2 !== "query" && location2 !== "header") continue;
|
|
296702
296832
|
const items = packedArrayItemsSchema(packed);
|
|
296703
296833
|
if (items === void 0) continue;
|
|
@@ -297008,6 +297138,185 @@ function responseHeaders(root, version2, response, context, warnings) {
|
|
|
297008
297138
|
}
|
|
297009
297139
|
return entries;
|
|
297010
297140
|
}
|
|
297141
|
+
var IANA_HTTP_AUTH_SCHEMES = /* @__PURE__ */ new Set([
|
|
297142
|
+
"basic",
|
|
297143
|
+
"bearer",
|
|
297144
|
+
"concealed",
|
|
297145
|
+
"digest",
|
|
297146
|
+
"dpop",
|
|
297147
|
+
"gnap",
|
|
297148
|
+
"hoba",
|
|
297149
|
+
"mutual",
|
|
297150
|
+
"negotiate",
|
|
297151
|
+
"oauth",
|
|
297152
|
+
"privatetoken",
|
|
297153
|
+
"scram-sha-1",
|
|
297154
|
+
"scram-sha-256",
|
|
297155
|
+
"vapid"
|
|
297156
|
+
]);
|
|
297157
|
+
function httpsUrlLint(value, label, schemeName) {
|
|
297158
|
+
if (typeof value !== "string" || !value) return void 0;
|
|
297159
|
+
try {
|
|
297160
|
+
const parsed = new URL(value);
|
|
297161
|
+
if (parsed.protocol !== "https:") return `CONTRACT_SECURITY_SCHEME_URL: security scheme ${schemeName} ${label} ${value} is not an HTTPS URL`;
|
|
297162
|
+
} catch {
|
|
297163
|
+
return `CONTRACT_SECURITY_SCHEME_URL: security scheme ${schemeName} ${label} ${value} is not a valid URL`;
|
|
297164
|
+
}
|
|
297165
|
+
return void 0;
|
|
297166
|
+
}
|
|
297167
|
+
function collectSecurityStaticLints(root, operation) {
|
|
297168
|
+
const securitySchemes = asRecord5(asRecord5(root.components)?.securitySchemes);
|
|
297169
|
+
const requirements = operation.security === void 0 ? asArray3(root.security) : asArray3(operation.security);
|
|
297170
|
+
const warnings = /* @__PURE__ */ new Set();
|
|
297171
|
+
for (const requirement of requirements.map((entry) => asRecord5(entry)).filter((entry) => Boolean(entry))) {
|
|
297172
|
+
for (const [schemeName, requiredScopes] of Object.entries(requirement)) {
|
|
297173
|
+
let scheme;
|
|
297174
|
+
try {
|
|
297175
|
+
scheme = resolveInternalRef(root, securitySchemes?.[schemeName]);
|
|
297176
|
+
} catch {
|
|
297177
|
+
scheme = null;
|
|
297178
|
+
}
|
|
297179
|
+
if (!scheme) continue;
|
|
297180
|
+
if (scheme.type === "http") {
|
|
297181
|
+
const httpScheme = String(scheme.scheme || "").toLowerCase();
|
|
297182
|
+
if (httpScheme && !IANA_HTTP_AUTH_SCHEMES.has(httpScheme)) {
|
|
297183
|
+
warnings.add(`CONTRACT_UNKNOWN_HTTP_AUTH_SCHEME: security scheme ${schemeName} uses "${httpScheme}", which is not in the IANA HTTP Authentication Scheme registry`);
|
|
297184
|
+
}
|
|
297185
|
+
}
|
|
297186
|
+
if (scheme.type === "apiKey" && String(scheme.in) === "query") {
|
|
297187
|
+
warnings.add(`CONTRACT_CREDENTIALS_IN_QUERY: security scheme ${schemeName} sends credentials in the query string, which leaks into logs and referrers`);
|
|
297188
|
+
}
|
|
297189
|
+
if (scheme.type === "openIdConnect") {
|
|
297190
|
+
const urlWarning = httpsUrlLint(scheme.openIdConnectUrl, "openIdConnectUrl", schemeName);
|
|
297191
|
+
if (urlWarning) warnings.add(urlWarning);
|
|
297192
|
+
else if (typeof scheme.openIdConnectUrl === "string" && !scheme.openIdConnectUrl.endsWith("/.well-known/openid-configuration")) {
|
|
297193
|
+
warnings.add(`CONTRACT_SECURITY_SCHEME_URL: security scheme ${schemeName} openIdConnectUrl does not end in /.well-known/openid-configuration`);
|
|
297194
|
+
}
|
|
297195
|
+
}
|
|
297196
|
+
if (scheme.type === "oauth2") {
|
|
297197
|
+
const flows = asRecord5(scheme.flows) ?? {};
|
|
297198
|
+
const declaredScopes = /* @__PURE__ */ new Set();
|
|
297199
|
+
for (const [flowName, rawFlow] of Object.entries(flows)) {
|
|
297200
|
+
const flow = asRecord5(rawFlow);
|
|
297201
|
+
if (!flow) continue;
|
|
297202
|
+
for (const scope of Object.keys(asRecord5(flow.scopes) ?? {})) declaredScopes.add(scope);
|
|
297203
|
+
const urlFields = [["refreshUrl", flow.refreshUrl]];
|
|
297204
|
+
if (flowName === "implicit" || flowName === "authorizationCode") urlFields.push(["authorizationUrl", flow.authorizationUrl]);
|
|
297205
|
+
if (flowName === "password" || flowName === "clientCredentials" || flowName === "authorizationCode") urlFields.push(["tokenUrl", flow.tokenUrl]);
|
|
297206
|
+
for (const [label, value] of urlFields) {
|
|
297207
|
+
const urlWarning = httpsUrlLint(value, `${flowName} ${label}`, schemeName);
|
|
297208
|
+
if (urlWarning) warnings.add(urlWarning);
|
|
297209
|
+
}
|
|
297210
|
+
}
|
|
297211
|
+
for (const scope of asArray3(requiredScopes).filter((entry) => typeof entry === "string")) {
|
|
297212
|
+
if (!declaredScopes.has(scope)) {
|
|
297213
|
+
warnings.add(`CONTRACT_OAUTH2_UNDECLARED_SCOPE: operation requires scope "${scope}" of ${schemeName}, which no flow of the scheme declares`);
|
|
297214
|
+
}
|
|
297215
|
+
}
|
|
297216
|
+
}
|
|
297217
|
+
}
|
|
297218
|
+
}
|
|
297219
|
+
return [...warnings];
|
|
297220
|
+
}
|
|
297221
|
+
function collectSecurityResponseLints(root, operation, responses, operationId) {
|
|
297222
|
+
const warnings = [];
|
|
297223
|
+
const requirements = operation.security === void 0 ? asArray3(root.security) : asArray3(operation.security);
|
|
297224
|
+
const requirementRecords = requirements.map((entry) => asRecord5(entry)).filter((entry) => Boolean(entry));
|
|
297225
|
+
const secured = requirementRecords.length > 0 && requirementRecords.every((entry) => Object.keys(entry).length > 0);
|
|
297226
|
+
const statusKeys = new Set(Object.keys(responses));
|
|
297227
|
+
const hasCatchAll = statusKeys.has("default") || statusKeys.has("4XX");
|
|
297228
|
+
if (secured && !statusKeys.has("401") && !hasCatchAll) {
|
|
297229
|
+
warnings.push(`CONTRACT_SECURITY_RESPONSES_INCOMPLETE: ${operationId} requires authentication but documents no 401 (or 4XX/default) response`);
|
|
297230
|
+
}
|
|
297231
|
+
const usesScopes = requirementRecords.some((entry) => Object.values(entry).some((scopes) => Array.isArray(scopes) && scopes.length > 0));
|
|
297232
|
+
if (secured && usesScopes && !statusKeys.has("403") && !hasCatchAll) {
|
|
297233
|
+
warnings.push(`CONTRACT_SECURITY_RESPONSES_INCOMPLETE: ${operationId} requires scopes but documents no 403 (or 4XX/default) response`);
|
|
297234
|
+
}
|
|
297235
|
+
if (requirementRecords.length === 0) {
|
|
297236
|
+
for (const status of ["401", "403"]) {
|
|
297237
|
+
if (statusKeys.has(status)) warnings.push(`CONTRACT_UNSECURED_AUTH_RESPONSES: ${operationId} documents a ${status} response but declares no security requirement`);
|
|
297238
|
+
}
|
|
297239
|
+
}
|
|
297240
|
+
return warnings;
|
|
297241
|
+
}
|
|
297242
|
+
function collectLinkExpressions(root, response, operationId, warnings) {
|
|
297243
|
+
const links = asRecord5(response.links);
|
|
297244
|
+
if (!links) return [];
|
|
297245
|
+
const expressions = [];
|
|
297246
|
+
let unevaluated = false;
|
|
297247
|
+
for (const [linkName, rawLink] of Object.entries(links)) {
|
|
297248
|
+
let link;
|
|
297249
|
+
try {
|
|
297250
|
+
link = resolveInternalRef(root, rawLink);
|
|
297251
|
+
} catch {
|
|
297252
|
+
link = null;
|
|
297253
|
+
}
|
|
297254
|
+
if (!link) {
|
|
297255
|
+
unevaluated = true;
|
|
297256
|
+
continue;
|
|
297257
|
+
}
|
|
297258
|
+
const values = Object.values(asRecord5(link.parameters) ?? {});
|
|
297259
|
+
if (link.requestBody !== void 0) values.push(link.requestBody);
|
|
297260
|
+
if (values.length === 0) unevaluated = true;
|
|
297261
|
+
for (const value of values) {
|
|
297262
|
+
if (typeof value !== "string" || !value.startsWith("$")) continue;
|
|
297263
|
+
const bodyMatch = value.match(/^\$response\.body#(\/.*)$/);
|
|
297264
|
+
if (bodyMatch) {
|
|
297265
|
+
expressions.push({ link: linkName, kind: "body", pointer: bodyMatch[1] });
|
|
297266
|
+
continue;
|
|
297267
|
+
}
|
|
297268
|
+
const headerMatch = value.match(/^\$response\.header\.([!#$%&'*+.^_`|~0-9A-Za-z-]+)$/);
|
|
297269
|
+
if (headerMatch) {
|
|
297270
|
+
expressions.push({ link: linkName, kind: "header", header: headerMatch[1] });
|
|
297271
|
+
continue;
|
|
297272
|
+
}
|
|
297273
|
+
unevaluated = true;
|
|
297274
|
+
}
|
|
297275
|
+
}
|
|
297276
|
+
if (expressions.length === 0) {
|
|
297277
|
+
if (unevaluated) warnings.add(`CONTRACT_LINKS_NOT_VALIDATED: response links are not validated for ${operationId}`);
|
|
297278
|
+
} else if (unevaluated) {
|
|
297279
|
+
warnings.add(`CONTRACT_LINKS_PARTIALLY_VALIDATED: some link expressions for ${operationId} are not runtime-evaluable and are skipped`);
|
|
297280
|
+
}
|
|
297281
|
+
return expressions;
|
|
297282
|
+
}
|
|
297283
|
+
function escapeRegExpLiteral(value) {
|
|
297284
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
297285
|
+
}
|
|
297286
|
+
function serverAdvisoryPatterns(root, pathItem, operation) {
|
|
297287
|
+
const serverLists = [asArray3(operation.servers), asArray3(pathItem.servers), asArray3(root.servers)];
|
|
297288
|
+
const servers = serverLists.find((list) => list.length > 0) ?? [];
|
|
297289
|
+
const patterns = [];
|
|
297290
|
+
for (const rawServer of servers) {
|
|
297291
|
+
const server = asRecord5(rawServer);
|
|
297292
|
+
if (!server) continue;
|
|
297293
|
+
const url = typeof server.url === "string" ? server.url.trim() : "";
|
|
297294
|
+
if (!url || url === "/") continue;
|
|
297295
|
+
const variables = asRecord5(server.variables);
|
|
297296
|
+
const pattern = url.split(/(\{[^}]+\})/).map((part) => {
|
|
297297
|
+
const varMatch = part.match(/^\{([^}]+)\}$/);
|
|
297298
|
+
if (!varMatch) return escapeRegExpLiteral(part);
|
|
297299
|
+
const variable = asRecord5(variables?.[varMatch[1]]);
|
|
297300
|
+
const enumValues = asArray3(variable?.enum).filter((entry) => typeof entry === "string");
|
|
297301
|
+
if (enumValues.length > 0) return `(${enumValues.map(escapeRegExpLiteral).join("|")})`;
|
|
297302
|
+
return "[^/]*";
|
|
297303
|
+
}).join("");
|
|
297304
|
+
patterns.push(`^${pattern}`);
|
|
297305
|
+
}
|
|
297306
|
+
return patterns.length > 0 ? patterns : void 0;
|
|
297307
|
+
}
|
|
297308
|
+
function validateParameterExamples(root, param, packed, context, warnings) {
|
|
297309
|
+
if (packed.schema === void 0 || packed.unsupported) return;
|
|
297310
|
+
const candidates = exampleCandidates(root, param);
|
|
297311
|
+
if (candidates.length === 0) return;
|
|
297312
|
+
const validate3 = compileSchemaValidator(packed.schema);
|
|
297313
|
+
if (!validate3) return;
|
|
297314
|
+
for (const candidate of candidates) {
|
|
297315
|
+
if (!validate3(candidate.value)) {
|
|
297316
|
+
warnings.push(`CONTRACT_EXAMPLE_SCHEMA_MISMATCH: ${candidate.label} for parameter ${context} does not match its schema`);
|
|
297317
|
+
}
|
|
297318
|
+
}
|
|
297319
|
+
}
|
|
297011
297320
|
function buildContractIndex(root) {
|
|
297012
297321
|
if (root.swagger === "2.0") throw new Error("CONTRACT_UNSUPPORTED_OPENAPI_VERSION: Dynamic contract tests require OpenAPI 3.0 or 3.1 (found swagger 2.0)");
|
|
297013
297322
|
if (!("openapi" in root)) throw new Error("CONTRACT_UNSUPPORTED_OPENAPI_VERSION: Dynamic contract tests require OpenAPI 3.0 or 3.1 (missing openapi)");
|
|
@@ -297026,6 +297335,9 @@ function buildContractIndex(root) {
|
|
|
297026
297335
|
const operation = resolveInternalRef(root, rawOperation);
|
|
297027
297336
|
if (!operation) continue;
|
|
297028
297337
|
if (operation.callbacks) warnings.push(`CONTRACT_CALLBACKS_NOT_VALIDATED: callbacks are not validated for ${lowerMethod.toUpperCase()} ${path8}`);
|
|
297338
|
+
if (operation.requestBody !== void 0 && ["get", "head", "delete"].includes(lowerMethod)) {
|
|
297339
|
+
warnings.push(`CONTRACT_METHOD_BODY_SEMANTICS: ${lowerMethod.toUpperCase()} ${path8} declares a request body; RFC 9110 defines no request-body semantics for ${lowerMethod.toUpperCase()}`);
|
|
297340
|
+
}
|
|
297029
297341
|
const responses = asRecord5(operation.responses);
|
|
297030
297342
|
if (!responses || Object.keys(responses).length === 0) {
|
|
297031
297343
|
throw new Error(`CONTRACT_OPERATION_NO_RESPONSES: ${lowerMethod.toUpperCase()} ${path8} must define at least one response`);
|
|
@@ -297035,11 +297347,15 @@ function buildContractIndex(root) {
|
|
|
297035
297347
|
for (const [status, rawResponse] of Object.entries(responses)) {
|
|
297036
297348
|
const response = resolveInternalRef(root, rawResponse);
|
|
297037
297349
|
if (!response) continue;
|
|
297038
|
-
if (
|
|
297039
|
-
responseWarnings.add(`
|
|
297350
|
+
if (status !== "default" && !/^[1-5]XX$/.test(status) && !/^[1-5][0-9][0-9]$/.test(status)) {
|
|
297351
|
+
responseWarnings.add(`CONTRACT_INVALID_STATUS_CODE: ${lowerMethod.toUpperCase()} ${path8} declares response status "${status}" outside RFC 9110's 100-599, 1XX-5XX, or default forms`);
|
|
297040
297352
|
}
|
|
297353
|
+
const linkExpressions = collectLinkExpressions(root, response, `${lowerMethod.toUpperCase()} ${path8}`, responseWarnings);
|
|
297041
297354
|
const responseContext = `${lowerMethod.toUpperCase()} ${path8} status ${status}`;
|
|
297042
297355
|
const content = responseContent(root, version2, response, responseContext, responseWarnings);
|
|
297356
|
+
if ((status === "204" || status === "205" || status === "304") && Object.keys(content).length > 0) {
|
|
297357
|
+
responseWarnings.add(`CONTRACT_BODYLESS_STATUS_WITH_CONTENT: ${lowerMethod.toUpperCase()} ${path8} declares content for status ${status}, which RFC 9110 forbids on the wire`);
|
|
297358
|
+
}
|
|
297043
297359
|
for (const [contentType2, media] of Object.entries(content)) {
|
|
297044
297360
|
const base = contentType2.toLowerCase().split(";")[0]?.trim() ?? "";
|
|
297045
297361
|
const schemaType = asRecord5(media.schema)?.type;
|
|
@@ -297051,7 +297367,8 @@ function buildContractIndex(root) {
|
|
|
297051
297367
|
contractResponses[normalizeResponseKey(status)] = {
|
|
297052
297368
|
content,
|
|
297053
297369
|
hasBody: Object.keys(content).length > 0,
|
|
297054
|
-
headers
|
|
297370
|
+
headers,
|
|
297371
|
+
...linkExpressions.length > 0 ? { links: linkExpressions } : {}
|
|
297055
297372
|
};
|
|
297056
297373
|
}
|
|
297057
297374
|
const candidates = [...new Set([
|
|
@@ -297064,11 +297381,13 @@ function buildContractIndex(root) {
|
|
|
297064
297381
|
opWarnings.push(...collectSecuritySchemeWarnings(root, operation));
|
|
297065
297382
|
const parameterChecks = collectParameterChecks(root, pathItem, operation, version2, operationId, path8, opWarnings);
|
|
297066
297383
|
const checkedKeys = new Set((parameterChecks ?? []).map((check) => `${check.in}:${check.name.toLowerCase()}`));
|
|
297067
|
-
const decodedKeys = new Set((parameterChecks ?? []).filter((check) => check.decode).map((check) => `${check.in}:${check.name.toLowerCase()}`));
|
|
297384
|
+
const decodedKeys = new Set((parameterChecks ?? []).filter((check) => check.decode || check.pathStyle).map((check) => `${check.in}:${check.name.toLowerCase()}`));
|
|
297068
297385
|
opWarnings.push(...collectSerializationWarnings(root, pathItem, operation, decodedKeys));
|
|
297069
297386
|
if (operation.deprecated === true) {
|
|
297070
297387
|
opWarnings.push(`CONTRACT_OPERATION_DEPRECATED: ${lowerMethod.toUpperCase()} ${path8} is marked deprecated in the OpenAPI document`);
|
|
297071
297388
|
}
|
|
297389
|
+
opWarnings.push(...collectSecurityStaticLints(root, operation));
|
|
297390
|
+
opWarnings.push(...collectSecurityResponseLints(root, operation, responses, operationId));
|
|
297072
297391
|
const requiredParameters = collectParameters(root, pathItem, operation);
|
|
297073
297392
|
for (const parameter of requiredParameters.filter((entry) => entry.securityDerived)) {
|
|
297074
297393
|
opWarnings.push(`CONTRACT_SECURITY_NOT_VALIDATED: security parameter ${parameter.in}:${parameter.name} is not statically required in generated requests`);
|
|
@@ -297097,6 +297416,9 @@ function buildContractIndex(root) {
|
|
|
297097
297416
|
parameterChecks,
|
|
297098
297417
|
requestBody: collectRequestBody(root, operation, version2, operationId, opWarnings),
|
|
297099
297418
|
security: collectSecurityRuntimeChecks(root, operation),
|
|
297419
|
+
pathMethods: Object.keys(pathItem).filter((key) => HTTP_METHODS.has(key)).map((key) => key.toUpperCase()),
|
|
297420
|
+
deprecated: operation.deprecated === true || void 0,
|
|
297421
|
+
servers: serverAdvisoryPatterns(root, pathItem, operation),
|
|
297100
297422
|
warnings: opWarnings
|
|
297101
297423
|
});
|
|
297102
297424
|
}
|
|
@@ -297273,7 +297595,7 @@ function buildValidatorAssignments(operation, warnings, skipped) {
|
|
|
297273
297595
|
return lines;
|
|
297274
297596
|
}
|
|
297275
297597
|
function createContractScript(operation, warnings = []) {
|
|
297276
|
-
const contract = { method: operation.method, path: operation.path, responses: operation.responses, security: operation.security, parameters: operation.parameterChecks };
|
|
297598
|
+
const contract = { method: operation.method, path: operation.path, responses: operation.responses, security: operation.security, parameters: operation.parameterChecks, pathMethods: operation.pathMethods, deprecated: operation.deprecated, servers: operation.servers };
|
|
297277
297599
|
const skipped = [];
|
|
297278
297600
|
const validatorLines = buildValidatorAssignments(operation, warnings, skipped);
|
|
297279
297601
|
return [
|
|
@@ -297384,6 +297706,417 @@ function createContractScript(operation, warnings = []) {
|
|
|
297384
297706
|
' if (!isJsonSubtype(actual.subtype) && media.media.schema && media.media.schema.type !== "string") { return; }',
|
|
297385
297707
|
' if (!validate(value)) pm.expect.fail("OpenAPI schema validation failed for " + contract.method + " " + contract.path + " status " + pm.response.code + ": " + JSON.stringify(validate.errors || []));',
|
|
297386
297708
|
"});",
|
|
297709
|
+
"pm.test('Response satisfies RFC 9110 status-code requirements', function () {",
|
|
297710
|
+
" var code = pm.response.code;",
|
|
297711
|
+
' function respHeader(name) { return pm.response.headers.get(name) || ""; }',
|
|
297712
|
+
" if (code === 401) {",
|
|
297713
|
+
' var challenge = respHeader("WWW-Authenticate");',
|
|
297714
|
+
' if (!challenge) pm.expect.fail("RFC 9110 requires WWW-Authenticate on 401 responses");',
|
|
297715
|
+
' var wantsBearer = (contract.security || []).some(function (alternative) { return alternative.some(function (check) { return check.prefix && check.prefix.toLowerCase().indexOf("bearer") === 0; }); });',
|
|
297716
|
+
' if (wantsBearer && challenge && challenge.toLowerCase().indexOf("bearer") === -1) pm.expect.fail("RFC 6750 expects a Bearer challenge on 401 for bearer-secured operations; got: " + challenge);',
|
|
297717
|
+
' if (challenge && /\\bbasic\\b/i.test(challenge) && !/realm\\s*=/i.test(challenge)) pm.expect.fail("RFC 7617 requires a realm parameter on Basic challenges: " + challenge);',
|
|
297718
|
+
' if (challenge && /\\bdigest\\b/i.test(challenge) && (!/realm\\s*=/i.test(challenge) || !/nonce\\s*=/i.test(challenge))) pm.expect.fail("RFC 7616 requires realm and nonce on Digest challenges: " + challenge);',
|
|
297719
|
+
" }",
|
|
297720
|
+
" if (code === 401 || code === 403) {",
|
|
297721
|
+
' var authChallenge = respHeader("WWW-Authenticate");',
|
|
297722
|
+
' var bearerError = authChallenge && /\\bbearer\\b/i.test(authChallenge) ? authChallenge.match(/\\berror\\s*=\\s*"?([A-Za-z0-9_]+)"?/i) : null;',
|
|
297723
|
+
' if (bearerError && ["invalid_request", "invalid_token", "insufficient_scope"].indexOf(bearerError[1]) === -1) pm.expect.fail("RFC 6750 Bearer error code must be invalid_request, invalid_token, or insufficient_scope; got " + bearerError[1]);',
|
|
297724
|
+
" }",
|
|
297725
|
+
" if (code === 405) {",
|
|
297726
|
+
' var allow = respHeader("Allow");',
|
|
297727
|
+
' if (!allow) pm.expect.fail("RFC 9110 requires Allow on 405 responses");',
|
|
297728
|
+
' var allowed = allow.split(",").map(function (entry) { return entry.trim().toUpperCase(); });',
|
|
297729
|
+
' (contract.pathMethods || []).forEach(function (method) { if (allowed.indexOf(method) === -1) pm.expect.fail("Allow on 405 must list every method the OpenAPI path declares (RFC 9110); missing " + method + " in: " + allow); });',
|
|
297730
|
+
" }",
|
|
297731
|
+
' if (code === 304 && responseText().trim().length > 0) pm.expect.fail("RFC 9110 forbids content in a 304 response");',
|
|
297732
|
+
' var retryAfter = respHeader("Retry-After");',
|
|
297733
|
+
" if (retryAfter && (code === 429 || code === 503 || (code >= 300 && code < 400))) {",
|
|
297734
|
+
' if (!/^\\d+$/.test(retryAfter.trim()) && isNaN(Date.parse(retryAfter))) pm.expect.fail("Retry-After must be delay-seconds or an HTTP-date (RFC 9110): " + retryAfter);',
|
|
297735
|
+
" }",
|
|
297736
|
+
' var location = respHeader("Location");',
|
|
297737
|
+
" if (location && (code === 201 || (code >= 300 && code < 400))) {",
|
|
297738
|
+
' if (/\\s/.test(location.trim()) || location.trim().length === 0) pm.expect.fail("Location must be a valid URI-reference (RFC 9110 / RFC 3986): " + location);',
|
|
297739
|
+
" }",
|
|
297740
|
+
"});",
|
|
297741
|
+
"pm.test('Error and encoding conventions match RFC 9457 / RFC 8259 / RFC 8288', function () {",
|
|
297742
|
+
' var contentTypeRaw = pm.response.headers.get("Content-Type") || "";',
|
|
297743
|
+
" var ct = mediaParts(contentTypeRaw);",
|
|
297744
|
+
' if (ct.type === "application" && ct.subtype === "problem+json") {',
|
|
297745
|
+
" var problem;",
|
|
297746
|
+
' try { problem = pm.response.json(); } catch (error) { pm.expect.fail("application/problem+json body is not valid JSON (RFC 9457): " + error); }',
|
|
297747
|
+
' if (!problem || typeof problem !== "object" || Array.isArray(problem)) pm.expect.fail("problem details must be a JSON object (RFC 9457)");',
|
|
297748
|
+
' ["type", "title", "detail", "instance"].forEach(function (member) { if (problem[member] !== undefined && typeof problem[member] !== "string") pm.expect.fail("RFC 9457 " + member + " member must be a string; got " + typeof problem[member]); });',
|
|
297749
|
+
' ["type", "instance"].forEach(function (member) { if (typeof problem[member] === "string" && /\\s/.test(problem[member].trim())) pm.expect.fail("RFC 9457 " + member + " member must be a URI-reference (RFC 3986): " + problem[member]); });',
|
|
297750
|
+
" if (problem.status !== undefined) {",
|
|
297751
|
+
' if (typeof problem.status !== "number") pm.expect.fail("RFC 9457 status member must be a number; got " + typeof problem.status);',
|
|
297752
|
+
' else if (problem.status !== pm.response.code) pm.expect.fail("RFC 9457 status member (" + problem.status + ") must match the HTTP status code (" + pm.response.code + ")");',
|
|
297753
|
+
" }",
|
|
297754
|
+
" }",
|
|
297755
|
+
" if (isJsonSubtype(ct.subtype)) {",
|
|
297756
|
+
' var charsetMatch = contentTypeRaw.match(/charset\\s*=\\s*"?([^";\\s]+)"?/i);',
|
|
297757
|
+
' if (charsetMatch && charsetMatch[1].toLowerCase() !== "utf-8") pm.expect.fail("JSON interchange must be UTF-8 (RFC 8259); got charset=" + charsetMatch[1]);',
|
|
297758
|
+
" }",
|
|
297759
|
+
' var link = pm.response.headers.get("Link");',
|
|
297760
|
+
" if (link) {",
|
|
297761
|
+
" link.split(/,(?=\\s*<)/).forEach(function (value) {",
|
|
297762
|
+
' if (!/^\\s*<[^>]*>/.test(value)) pm.expect.fail("RFC 8288 link-value must start with a <URI-Reference>: " + value);',
|
|
297763
|
+
' if (!/;\\s*rel\\s*=/i.test(value)) pm.expect.fail("RFC 8288 link-value must carry a rel parameter: " + value);',
|
|
297764
|
+
" });",
|
|
297765
|
+
" }",
|
|
297766
|
+
"});",
|
|
297767
|
+
"var rfcAdvisories = [];",
|
|
297768
|
+
"function rfcAdvise(message) { if (rfcAdvisories.indexOf(message) === -1) rfcAdvisories.push(message); }",
|
|
297769
|
+
'function rfcRespHeader(name) { return pm.response.headers.get(name) || ""; }',
|
|
297770
|
+
"function rfcHeaderAll(name) { var out = []; pm.response.headers.each(function (header) { if (header && String(header.key).toLowerCase() === String(name).toLowerCase()) out.push(String(header.value)); }); return out; }",
|
|
297771
|
+
"function rfcIsHttpDate(value) { return /^(Mon|Tue|Wed|Thu|Fri|Sat|Sun), [0-3][0-9] (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) [0-9]{4} [0-2][0-9]:[0-5][0-9]:[0-5][0-9] GMT$/.test(String(value).trim()) && !isNaN(Date.parse(value)); }",
|
|
297772
|
+
"function rfcIsToken(value) { return /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/.test(String(value)); }",
|
|
297773
|
+
'function rfcIsEntityTag(value) { return /^(W\\/)?"[\\x21\\x23-\\x7e\\x80-\\xff]*"$/.test(String(value).trim()); }',
|
|
297774
|
+
"function rfcIsFieldContent(value) { return /^[\\t \\x21-\\x7e\\x80-\\xff]*$/.test(String(value)); }",
|
|
297775
|
+
'function rfcTokenList(value) { var parts = String(value).split(","); for (var i = 0; i < parts.length; i += 1) { if (!rfcIsToken(parts[i].trim())) return false; } return true; }',
|
|
297776
|
+
`function rfcSplitList(value) { var out = []; var current = ""; var inQuote = false; for (var i = 0; i < value.length; i += 1) { var ch = value.charAt(i); if (ch === "\\\\" && inQuote) { current += ch + (value.charAt(i + 1) || ""); i += 1; continue; } if (ch === '"') inQuote = !inQuote; if (ch === "," && !inQuote) { out.push(current); current = ""; continue; } current += ch; } out.push(current); return out; }`,
|
|
297777
|
+
'function rfcBase64Decode(value) { var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; var clean = String(value).replace(/=+$/, ""); if (clean.length === 0 || /[^A-Za-z0-9+\\/]/.test(clean)) return null; var bits = 0, buffer = 0, out = ""; for (var i = 0; i < clean.length; i += 1) { buffer = (buffer << 6) | alphabet.indexOf(clean.charAt(i)); bits += 6; if (bits >= 8) { bits -= 8; out += String.fromCharCode((buffer >> bits) & 255); } } return out; }',
|
|
297778
|
+
"function rfcSfParse(input, kind) {",
|
|
297779
|
+
" var s = String(input), i = 0;",
|
|
297780
|
+
' function ws() { while (i < s.length && (s.charAt(i) === " " || s.charAt(i) === "\\t")) i += 1; }',
|
|
297781
|
+
" function key() { if (!/[a-z*]/.test(s.charAt(i))) return null; var start = i; i += 1; while (i < s.length && /[a-z0-9_.*-]/.test(s.charAt(i))) i += 1; return s.slice(start, i); }",
|
|
297782
|
+
" function bareItem() {",
|
|
297783
|
+
" var ch = s.charAt(i);",
|
|
297784
|
+
` if (ch === '"') { i += 1; while (i < s.length) { var c = s.charAt(i); if (c === "\\\\") { if (!/["\\\\]/.test(s.charAt(i + 1))) return null; i += 2; continue; } if (c === '"') { i += 1; return true; } if (c < " " || c > "~") return null; i += 1; } return null; }`,
|
|
297785
|
+
' if (ch === ":") { i += 1; var start = i; while (i < s.length && s.charAt(i) !== ":") i += 1; if (s.charAt(i) !== ":") return null; var body = s.slice(start, i); i += 1; return /^[A-Za-z0-9+\\/=]*$/.test(body) ? true : null; }',
|
|
297786
|
+
' if (ch === "?") { i += 1; if (s.charAt(i) !== "0" && s.charAt(i) !== "1") return null; i += 1; return true; }',
|
|
297787
|
+
' if (ch === "@") { i += 1; if (s.charAt(i) === "-") i += 1; if (!/[0-9]/.test(s.charAt(i))) return null; while (i < s.length && /[0-9]/.test(s.charAt(i))) i += 1; return true; }',
|
|
297788
|
+
' if (/[-0-9]/.test(ch)) { if (ch === "-") i += 1; if (!/[0-9]/.test(s.charAt(i))) return null; while (i < s.length && /[0-9]/.test(s.charAt(i))) i += 1; if (s.charAt(i) === ".") { i += 1; if (!/[0-9]/.test(s.charAt(i))) return null; while (i < s.length && /[0-9]/.test(s.charAt(i))) i += 1; } return true; }',
|
|
297789
|
+
" if (/[A-Za-z*]/.test(ch)) { i += 1; while (i < s.length && /[!#$%&'*+.^_`|~:\\/0-9A-Za-z-]/.test(s.charAt(i))) i += 1; return true; }",
|
|
297790
|
+
" return null;",
|
|
297791
|
+
" }",
|
|
297792
|
+
' function params() { while (s.charAt(i) === ";") { i += 1; ws(); if (key() === null) return null; if (s.charAt(i) === "=") { i += 1; if (bareItem() === null) return null; } } return true; }',
|
|
297793
|
+
' function item() { if (s.charAt(i) === "(") { i += 1; ws(); while (s.charAt(i) !== ")") { if (i >= s.length) return null; if (bareItem() === null || params() === null) return null; ws(); } i += 1; return params(); } if (bareItem() === null) return null; return params(); }',
|
|
297794
|
+
" ws();",
|
|
297795
|
+
' if (kind === "item") { if (item() === null) return false; ws(); return i === s.length; }',
|
|
297796
|
+
" if (i === s.length) return true;",
|
|
297797
|
+
" while (i < s.length) {",
|
|
297798
|
+
' if (kind === "dict") { if (key() === null) return false; if (s.charAt(i) === "=") { i += 1; if (item() === null) return false; } else if (params() === null) return false; }',
|
|
297799
|
+
" else if (item() === null) return false;",
|
|
297800
|
+
" ws();",
|
|
297801
|
+
" if (i === s.length) return true;",
|
|
297802
|
+
' if (s.charAt(i) !== ",") return false;',
|
|
297803
|
+
" i += 1; ws();",
|
|
297804
|
+
" if (i === s.length) return false;",
|
|
297805
|
+
" }",
|
|
297806
|
+
" return true;",
|
|
297807
|
+
"}",
|
|
297808
|
+
"pm.test('Response header fields satisfy RFC 9110 field syntax', function () {",
|
|
297809
|
+
" pm.response.headers.each(function (header) {",
|
|
297810
|
+
" if (!header) return;",
|
|
297811
|
+
' if (!rfcIsToken(String(header.key))) pm.expect.fail("Response header name is not a valid RFC 9110 token: " + header.key);',
|
|
297812
|
+
' if (!rfcIsFieldContent(String(header.value))) pm.expect.fail("Response header value contains characters forbidden by RFC 9110 field-content: " + header.key);',
|
|
297813
|
+
" });",
|
|
297814
|
+
' ["content-type", "content-length", "etag", "location", "date", "age", "expires", "last-modified", "retry-after"].forEach(function (name) {',
|
|
297815
|
+
" var values = rfcHeaderAll(name);",
|
|
297816
|
+
' for (var i = 1; i < values.length; i += 1) { if (values[i] !== values[0]) pm.expect.fail("Singleton response header " + name + " appears " + values.length + " times with differing values (RFC 9110)"); }',
|
|
297817
|
+
" });",
|
|
297818
|
+
"});",
|
|
297819
|
+
"pm.test('Response header values satisfy their RFC grammars', function () {",
|
|
297820
|
+
' var date = rfcRespHeader("Date");',
|
|
297821
|
+
' if (date && !rfcIsHttpDate(date)) pm.expect.fail("Date must be an IMF-fixdate (RFC 9110): " + date);',
|
|
297822
|
+
' if (!date) rfcAdvise("RFC 9110: origin servers SHOULD send a Date header");',
|
|
297823
|
+
' var etag = rfcRespHeader("ETag");',
|
|
297824
|
+
' if (etag && !rfcIsEntityTag(etag)) pm.expect.fail("ETag is not a valid entity-tag (RFC 9110): " + etag);',
|
|
297825
|
+
' var lastModified = rfcRespHeader("Last-Modified");',
|
|
297826
|
+
" if (lastModified) {",
|
|
297827
|
+
' if (!rfcIsHttpDate(lastModified)) pm.expect.fail("Last-Modified must be a valid HTTP-date (RFC 9110): " + lastModified);',
|
|
297828
|
+
' else if (date && rfcIsHttpDate(date) && Date.parse(lastModified) > Date.parse(date)) pm.expect.fail("Last-Modified must not be later than Date (RFC 9110): " + lastModified + " > " + date);',
|
|
297829
|
+
" }",
|
|
297830
|
+
' var vary = rfcRespHeader("Vary");',
|
|
297831
|
+
" if (vary) {",
|
|
297832
|
+
' var varyMembers = vary.split(",").map(function (entry) { return entry.trim(); });',
|
|
297833
|
+
' if (varyMembers.indexOf("*") !== -1 && varyMembers.length > 1) pm.expect.fail("Vary: * must not be combined with other members (RFC 9110): " + vary);',
|
|
297834
|
+
' varyMembers.forEach(function (member) { if (member !== "*" && !rfcIsToken(member)) pm.expect.fail("Vary member is not a field-name token (RFC 9110): " + member); });',
|
|
297835
|
+
" }",
|
|
297836
|
+
' var contentLocation = rfcRespHeader("Content-Location");',
|
|
297837
|
+
' if (contentLocation && (/\\s/.test(contentLocation.trim()) || contentLocation.trim().length === 0)) pm.expect.fail("Content-Location must be a valid URI-reference (RFC 9110): " + contentLocation);',
|
|
297838
|
+
' var acceptRanges = rfcRespHeader("Accept-Ranges");',
|
|
297839
|
+
' if (acceptRanges && !rfcTokenList(acceptRanges)) pm.expect.fail("Accept-Ranges must be a list of range-unit tokens (RFC 9110): " + acceptRanges);',
|
|
297840
|
+
' var contentLanguage = rfcRespHeader("Content-Language");',
|
|
297841
|
+
' if (contentLanguage) contentLanguage.split(",").forEach(function (tag) { if (!/^[A-Za-z]{1,8}(-[A-Za-z0-9]{1,8})*$/.test(tag.trim())) pm.expect.fail("Content-Language carries a malformed BCP 47 language-tag (RFC 5646): " + tag.trim()); });',
|
|
297842
|
+
' var allow = rfcRespHeader("Allow");',
|
|
297843
|
+
' if (allow && allow.trim() && !rfcTokenList(allow)) pm.expect.fail("Allow must be a comma-separated list of method tokens (RFC 9110): " + allow);',
|
|
297844
|
+
' if (allow && contract.method === "OPTIONS" && pm.response.code >= 200 && pm.response.code < 300) {',
|
|
297845
|
+
' var optionsAllowed = allow.split(",").map(function (entry) { return entry.trim().toUpperCase(); });',
|
|
297846
|
+
' (contract.pathMethods || []).forEach(function (method) { if (optionsAllowed.indexOf(method) === -1) pm.expect.fail("Allow on an OPTIONS response must list every method the OpenAPI path declares (RFC 9110); missing " + method + " in: " + allow); });',
|
|
297847
|
+
" }",
|
|
297848
|
+
' var age = rfcRespHeader("Age");',
|
|
297849
|
+
' if (age && !/^[0-9]+$/.test(age.trim())) pm.expect.fail("Age must be a non-negative integer of delta-seconds (RFC 9111): " + age);',
|
|
297850
|
+
' var expires = rfcRespHeader("Expires");',
|
|
297851
|
+
' if (expires && !rfcIsHttpDate(expires)) rfcAdvise("RFC 9111: Expires is not a valid HTTP-date and will be treated as already expired: " + expires);',
|
|
297852
|
+
' if (rfcHeaderAll("warning").length > 0) rfcAdvise("RFC 9111 obsoleted the Warning header; the server still emits it");',
|
|
297853
|
+
' var cacheControl = rfcRespHeader("Cache-Control");',
|
|
297854
|
+
" if (cacheControl) {",
|
|
297855
|
+
" var seenDirectives = {};",
|
|
297856
|
+
" rfcSplitList(cacheControl).forEach(function (entry) {",
|
|
297857
|
+
" var directive = entry.trim();",
|
|
297858
|
+
' if (!directive) { pm.expect.fail("Cache-Control contains an empty directive (RFC 9111): " + cacheControl); return; }',
|
|
297859
|
+
' var eq = directive.indexOf("=");',
|
|
297860
|
+
" var name = (eq === -1 ? directive : directive.slice(0, eq)).trim().toLowerCase();",
|
|
297861
|
+
" var argument = eq === -1 ? undefined : directive.slice(eq + 1).trim();",
|
|
297862
|
+
' if (!rfcIsToken(name)) pm.expect.fail("Cache-Control directive name is not a token (RFC 9111): " + directive);',
|
|
297863
|
+
" seenDirectives[name] = argument === undefined ? true : argument;",
|
|
297864
|
+
' if (["max-age", "s-maxage", "stale-while-revalidate", "stale-if-error"].indexOf(name) !== -1 && (argument === undefined || !/^"?[0-9]+"?$/.test(argument))) pm.expect.fail("Cache-Control " + name + " requires a delta-seconds argument (RFC 9111): " + directive);',
|
|
297865
|
+
" });",
|
|
297866
|
+
' if (seenDirectives["no-store"] && seenDirectives["max-age"] !== undefined) pm.expect.fail("Cache-Control combines no-store with max-age; the directives contradict (RFC 9111): " + cacheControl);',
|
|
297867
|
+
" }",
|
|
297868
|
+
' var acceptPatch = rfcRespHeader("Accept-Patch");',
|
|
297869
|
+
' if (acceptPatch) acceptPatch.split(",").forEach(function (entry) { var parts = mediaParts(entry); if (!parts.type || !parts.subtype) pm.expect.fail("Accept-Patch must be a list of media types (RFC 5789): " + entry.trim()); });',
|
|
297870
|
+
' var deprecation = rfcRespHeader("Deprecation");',
|
|
297871
|
+
' if (deprecation && !/^@-?[0-9]+$/.test(deprecation.trim())) pm.expect.fail("Deprecation must be an RFC 9745 Date structured field (@unix-timestamp): " + deprecation);',
|
|
297872
|
+
' var sunset = rfcRespHeader("Sunset");',
|
|
297873
|
+
" if (sunset) {",
|
|
297874
|
+
' if (!rfcIsHttpDate(sunset)) pm.expect.fail("Sunset must be a valid HTTP-date (RFC 8594): " + sunset);',
|
|
297875
|
+
' else if (Date.parse(sunset) < Date.now()) rfcAdvise("RFC 8594: Sunset date is already in the past: " + sunset);',
|
|
297876
|
+
" }",
|
|
297877
|
+
' var preferenceApplied = rfcRespHeader("Preference-Applied");',
|
|
297878
|
+
" if (preferenceApplied) {",
|
|
297879
|
+
' var requestPrefer = requestHeader("Prefer").toLowerCase();',
|
|
297880
|
+
" rfcSplitList(preferenceApplied).forEach(function (entry) {",
|
|
297881
|
+
' var token = entry.split("=")[0].trim().toLowerCase();',
|
|
297882
|
+
' if (token && requestPrefer.indexOf(token) === -1) pm.expect.fail("Preference-Applied echoes a preference the request never sent (RFC 7240): " + entry.trim());',
|
|
297883
|
+
" });",
|
|
297884
|
+
" }",
|
|
297885
|
+
"});",
|
|
297886
|
+
"pm.test('Response satisfies RFC 9110 message framing requirements', function () {",
|
|
297887
|
+
" var code = pm.response.code;",
|
|
297888
|
+
' if ((code === 204 || code < 200) && rfcRespHeader("Content-Length")) pm.expect.fail("RFC 9110 forbids Content-Length on 1xx and 204 responses");',
|
|
297889
|
+
' if ([301, 302, 303, 307, 308].indexOf(code) !== -1 && !rfcRespHeader("Location")) pm.expect.fail("RFC 9110 expects Location on a " + code + " redirect response");',
|
|
297890
|
+
" if (code === 416) {",
|
|
297891
|
+
' var unsatisfiedRange = rfcRespHeader("Content-Range");',
|
|
297892
|
+
' if (!unsatisfiedRange) pm.expect.fail("RFC 9110 requires Content-Range (unsatisfied-range form) on 416 responses");',
|
|
297893
|
+
' else if (!/^\\S+ \\*\\/[0-9]+$/.test(unsatisfiedRange.trim())) pm.expect.fail("Content-Range on 416 must use the unsatisfied-range form <unit> */<complete-length> (RFC 9110): " + unsatisfiedRange);',
|
|
297894
|
+
" }",
|
|
297895
|
+
" if (code === 206) {",
|
|
297896
|
+
' var contentRange = rfcRespHeader("Content-Range");',
|
|
297897
|
+
' var responseMedia = mediaParts(rfcRespHeader("Content-Type"));',
|
|
297898
|
+
' var isByteranges = responseMedia.type === "multipart" && responseMedia.subtype === "byteranges";',
|
|
297899
|
+
' if (!contentRange && !isByteranges) pm.expect.fail("RFC 9110 requires Content-Range on a single-part 206 response (or multipart/byteranges for multi-range)");',
|
|
297900
|
+
' if (contentRange && isByteranges) pm.expect.fail("RFC 9110 forbids Content-Range on a multipart/byteranges 206 response");',
|
|
297901
|
+
" if (contentRange) {",
|
|
297902
|
+
" var rangeParts = contentRange.trim().match(/^(\\S+) (?:([0-9]+)-([0-9]+)|\\*)\\/([0-9]+|\\*)$/);",
|
|
297903
|
+
' if (!rangeParts) pm.expect.fail("Content-Range is not a valid RFC 9110 range: " + contentRange);',
|
|
297904
|
+
" else {",
|
|
297905
|
+
' if (rangeParts[1] !== "bytes") rfcAdvise("RFC 9110: 206 Content-Range uses a non-bytes range unit: " + rangeParts[1]);',
|
|
297906
|
+
" if (rangeParts[2] !== undefined) {",
|
|
297907
|
+
' if (Number(rangeParts[2]) > Number(rangeParts[3])) pm.expect.fail("Content-Range first-byte-pos must be <= last-byte-pos (RFC 9110): " + contentRange);',
|
|
297908
|
+
' if (rangeParts[4] !== "*" && Number(rangeParts[3]) >= Number(rangeParts[4])) pm.expect.fail("Content-Range last-byte-pos must be < complete-length (RFC 9110): " + contentRange);',
|
|
297909
|
+
" }",
|
|
297910
|
+
" }",
|
|
297911
|
+
" }",
|
|
297912
|
+
" }",
|
|
297913
|
+
' if (code === 407 && !rfcRespHeader("Proxy-Authenticate")) pm.expect.fail("RFC 9110 requires Proxy-Authenticate on 407 responses");',
|
|
297914
|
+
' if (code === 415 && contract.method === "PATCH" && !rfcRespHeader("Accept-Patch")) rfcAdvise("RFC 5789: a 415 response to PATCH SHOULD carry Accept-Patch");',
|
|
297915
|
+
"});",
|
|
297916
|
+
"pm.test('Response media type is acceptable under the request Accept header', function () {",
|
|
297917
|
+
" if (pm.response.code < 200 || pm.response.code >= 300 || isBodyless()) return;",
|
|
297918
|
+
' var accept = requestHeader("Accept");',
|
|
297919
|
+
' if (!accept || accept.indexOf("{{") !== -1) return;',
|
|
297920
|
+
' var actual = mediaParts(rfcRespHeader("Content-Type"));',
|
|
297921
|
+
" if (!actual.type) return;",
|
|
297922
|
+
" var acceptable = false;",
|
|
297923
|
+
" var jsonSoftened = false;",
|
|
297924
|
+
" rfcSplitList(accept).forEach(function (entry) {",
|
|
297925
|
+
" var range = mediaParts(entry);",
|
|
297926
|
+
' var qMatch = entry.match(/;\\s*q\\s*=\\s*"?([0-9.]+)"?/i);',
|
|
297927
|
+
" if (qMatch && Number(qMatch[1]) <= 0) return;",
|
|
297928
|
+
' if ((range.type === "*" && range.subtype === "*") || (range.type === actual.type && (range.subtype === "*" || range.subtype === actual.subtype))) acceptable = true;',
|
|
297929
|
+
' if (range.type === actual.type && range.subtype === "json" && isJsonSubtype(actual.subtype)) jsonSoftened = true;',
|
|
297930
|
+
" });",
|
|
297931
|
+
' if (!acceptable && jsonSoftened) { rfcAdvise("Content negotiation: response " + actual.raw + " is a +json type while the request only accepted application/json"); return; }',
|
|
297932
|
+
' if (!acceptable) pm.expect.fail("Response Content-Type " + actual.raw + " is not acceptable under the request Accept header (RFC 9110): " + accept);',
|
|
297933
|
+
"});",
|
|
297934
|
+
"pm.test('Response body satisfies its media type RFC conventions', function () {",
|
|
297935
|
+
' var contentTypeValue = rfcRespHeader("Content-Type");',
|
|
297936
|
+
" var media = mediaParts(contentTypeValue);",
|
|
297937
|
+
" var text = responseText();",
|
|
297938
|
+
' if (pm.response.code === 406 && !text.trim()) rfcAdvise("RFC 9110: a 406 response SHOULD include a list of available representations");',
|
|
297939
|
+
" if (!text) return;",
|
|
297940
|
+
" if (isJsonSubtype(media.subtype)) {",
|
|
297941
|
+
' if (text.charCodeAt(0) === 65279) pm.expect.fail("RFC 8259 forbids a byte order mark at the start of JSON text");',
|
|
297942
|
+
' var charsetParam = contentTypeValue.match(/charset\\s*=\\s*"?([^";\\s]+)"?/i);',
|
|
297943
|
+
' if (charsetParam) rfcAdvise("RFC 8259 defines no charset parameter for JSON media types; got charset=" + charsetParam[1]);',
|
|
297944
|
+
" }",
|
|
297945
|
+
' if (media.raw === "application/x-ndjson" || media.raw === "application/jsonl" || media.raw === "application/x-jsonlines") {',
|
|
297946
|
+
' text.split(/\\r?\\n/).forEach(function (line, lineNumber) { if (!line.trim()) return; try { JSON.parse(line); } catch (error) { pm.expect.fail("NDJSON line " + (lineNumber + 1) + " is not valid JSON: " + error); } });',
|
|
297947
|
+
" }",
|
|
297948
|
+
' if (media.raw === "text/event-stream") {',
|
|
297949
|
+
' text.split(/\\r?\\n/).forEach(function (line) { if (!line || line.charAt(0) === ":") return; var field = line.split(":")[0]; if (["data", "event", "id", "retry"].indexOf(field) === -1) pm.expect.fail("SSE line does not start with a known field or comment: " + line); if (field === "retry" && !/^retry:\\s*[0-9]+\\s*$/.test(line)) pm.expect.fail("SSE retry field must be an integer: " + line); });',
|
|
297950
|
+
" }",
|
|
297951
|
+
' if (media.type === "multipart") {',
|
|
297952
|
+
' var boundary = contentTypeValue.match(/;\\s*boundary=(?:"([^"]*)"|([^;]*))/i);',
|
|
297953
|
+
' var boundaryValue = boundary ? (boundary[1] !== undefined ? boundary[1] : boundary[2].trim()) : "";',
|
|
297954
|
+
' if (!boundaryValue) pm.expect.fail("multipart responses must carry a boundary parameter (RFC 2046): " + contentTypeValue);',
|
|
297955
|
+
" else {",
|
|
297956
|
+
' if (boundaryValue.length > 70) pm.expect.fail("multipart boundary must be 1-70 characters (RFC 2046): " + boundaryValue);',
|
|
297957
|
+
` if (!/^[0-9A-Za-z'()+_,\\-.\\/:=? ]*[0-9A-Za-z'()+_,\\-.\\/:=?]$/.test(boundaryValue)) pm.expect.fail("multipart boundary contains characters outside RFC 2046 bchars or ends with a space: " + boundaryValue);`,
|
|
297958
|
+
" }",
|
|
297959
|
+
" }",
|
|
297960
|
+
' if (media.raw === "application/hal+json") {',
|
|
297961
|
+
" var hal; try { hal = JSON.parse(text); } catch (error) { hal = null; }",
|
|
297962
|
+
' if (hal && typeof hal === "object" && !Array.isArray(hal)) {',
|
|
297963
|
+
" var halLinks = hal._links;",
|
|
297964
|
+
' if (halLinks !== undefined && (typeof halLinks !== "object" || Array.isArray(halLinks) || halLinks === null)) pm.expect.fail("HAL _links must be an object of link relations");',
|
|
297965
|
+
' if (halLinks) Object.keys(halLinks).forEach(function (rel) { var linkValue = halLinks[rel]; (Array.isArray(linkValue) ? linkValue : [linkValue]).forEach(function (linkObject) { if (!linkObject || typeof linkObject !== "object" || typeof linkObject.href !== "string") pm.expect.fail("HAL link relation " + rel + " must be a Link Object (or array of them) with a string href"); }); });',
|
|
297966
|
+
" var halEmbedded = hal._embedded;",
|
|
297967
|
+
' if (halEmbedded !== undefined && (typeof halEmbedded !== "object" || Array.isArray(halEmbedded) || halEmbedded === null)) pm.expect.fail("HAL _embedded must be an object of resource names");',
|
|
297968
|
+
" }",
|
|
297969
|
+
" }",
|
|
297970
|
+
' if (media.raw === "application/vnd.api+json") {',
|
|
297971
|
+
" var jsonApi; try { jsonApi = JSON.parse(text); } catch (error) { jsonApi = null; }",
|
|
297972
|
+
' if (jsonApi && typeof jsonApi === "object" && !Array.isArray(jsonApi)) {',
|
|
297973
|
+
' if (jsonApi.data === undefined && jsonApi.errors === undefined && jsonApi.meta === undefined) pm.expect.fail("JSON:API documents must contain at least one of data, errors, meta");',
|
|
297974
|
+
' if (jsonApi.data !== undefined && jsonApi.errors !== undefined) pm.expect.fail("JSON:API forbids data and errors in the same document");',
|
|
297975
|
+
" }",
|
|
297976
|
+
" }",
|
|
297977
|
+
' if (media.subtype === "problem+xml") {',
|
|
297978
|
+
' if (text.indexOf("urn:ietf:rfc:7807") === -1) rfcAdvise("application/problem+xml body does not reference the urn:ietf:rfc:7807 namespace");',
|
|
297979
|
+
" var xmlStatus = text.match(/<status[^>]*>\\s*([0-9]+)\\s*<\\/status>/);",
|
|
297980
|
+
' if (xmlStatus && Number(xmlStatus[1]) !== pm.response.code) pm.expect.fail("RFC 9457 status member (" + xmlStatus[1] + ") must match the HTTP status code (" + pm.response.code + ")");',
|
|
297981
|
+
" }",
|
|
297982
|
+
"});",
|
|
297983
|
+
"pm.test('Structured field response headers parse per RFC 8941', function () {",
|
|
297984
|
+
' [["Cache-Status", "list"], ["Proxy-Status", "list"], ["Priority", "dict"], ["RateLimit", "dict"], ["RateLimit-Policy", "dict"], ["Signature", "dict"], ["Signature-Input", "dict"]].forEach(function (pair) {',
|
|
297985
|
+
' var value = rfcHeaderAll(pair[0]).join(", ");',
|
|
297986
|
+
" if (!value) return;",
|
|
297987
|
+
' if (!rfcSfParse(value, pair[1])) pm.expect.fail(pair[0] + " is not a valid RFC 8941 structured field (" + pair[1] + "): " + value);',
|
|
297988
|
+
" });",
|
|
297989
|
+
"});",
|
|
297990
|
+
"pm.test('Content-Digest and Repr-Digest match the response body (RFC 9530)', function () {",
|
|
297991
|
+
" var cryptoLib = null;",
|
|
297992
|
+
' try { cryptoLib = require("crypto-js"); } catch (error) { cryptoLib = null; }',
|
|
297993
|
+
' ["Content-Digest", "Repr-Digest"].forEach(function (name) {',
|
|
297994
|
+
" var value = rfcRespHeader(name);",
|
|
297995
|
+
" if (!value) return;",
|
|
297996
|
+
' if (!rfcSfParse(value, "dict")) { pm.expect.fail(name + " is not a valid RFC 8941 dictionary (RFC 9530): " + value); return; }',
|
|
297997
|
+
' if (!cryptoLib || rfcRespHeader("Content-Encoding")) return;',
|
|
297998
|
+
' var media = mediaParts(rfcRespHeader("Content-Type"));',
|
|
297999
|
+
' if (media.type !== "text" && !isJsonSubtype(media.subtype) && !/xml$/.test(media.subtype)) return;',
|
|
298000
|
+
" rfcSplitList(value).forEach(function (entry) {",
|
|
298001
|
+
" var match = entry.trim().match(/^(sha-256|sha-512)=:([A-Za-z0-9+\\/=]+):$/);",
|
|
298002
|
+
" if (!match) return;",
|
|
298003
|
+
' var computed = match[1] === "sha-256" ? cryptoLib.SHA256(responseText()) : cryptoLib.SHA512(responseText());',
|
|
298004
|
+
" var encoded = cryptoLib.enc.Base64.stringify(computed);",
|
|
298005
|
+
' if (encoded !== match[2]) pm.expect.fail(name + " " + match[1] + " does not match the response body (RFC 9530): computed " + encoded + " but header carries " + match[2]);',
|
|
298006
|
+
" });",
|
|
298007
|
+
" });",
|
|
298008
|
+
"});",
|
|
298009
|
+
"pm.test('Request credentials are well-formed per their authentication scheme RFCs', function () {",
|
|
298010
|
+
' var authorization = requestHeader("Authorization");',
|
|
298011
|
+
' if (authorization && authorization.indexOf("{{") === -1) {',
|
|
298012
|
+
" var schemeMatch = authorization.match(/^(\\S+)(?:\\s+([\\s\\S]*))?$/);",
|
|
298013
|
+
' var authScheme = schemeMatch ? schemeMatch[1].toLowerCase() : "";',
|
|
298014
|
+
' var authParams = schemeMatch && schemeMatch[2] !== undefined ? schemeMatch[2].trim() : "";',
|
|
298015
|
+
' if (authScheme === "basic") {',
|
|
298016
|
+
" var decoded = rfcBase64Decode(authParams);",
|
|
298017
|
+
' if (decoded === null) pm.expect.fail("Basic credentials must be base64 (RFC 7617)");',
|
|
298018
|
+
' else if (decoded.indexOf(":") === -1) pm.expect.fail("Basic credentials must decode to user-id:password (RFC 7617)");',
|
|
298019
|
+
" }",
|
|
298020
|
+
' if (authScheme === "bearer" && !/^[A-Za-z0-9\\-._~+\\/]+=*$/.test(authParams)) pm.expect.fail("Bearer token does not match the b64token grammar (RFC 6750)");',
|
|
298021
|
+
' if (authScheme === "digest") {',
|
|
298022
|
+
' rfcSplitList(authParams).forEach(function (entry) { var param = entry.trim(); if (param && !/^[!#$%&\'*+.^_`|~0-9A-Za-z-]+\\s*=\\s*("([^"\\\\]|\\\\.)*"|[!#$%&\'*+.^_`|~0-9A-Za-z-]+)$/.test(param)) pm.expect.fail("Digest auth-param is malformed (RFC 7616): " + param); });',
|
|
298023
|
+
' var digestResponse = authParams.match(/\\bresponse\\s*=\\s*"?([^",\\s]+)"?/i);',
|
|
298024
|
+
' if (digestResponse && !/^[0-9a-fA-F]+$/.test(digestResponse[1])) pm.expect.fail("Digest response parameter must be hex (RFC 7616): " + digestResponse[1]);',
|
|
298025
|
+
" }",
|
|
298026
|
+
" }",
|
|
298027
|
+
' var wantsJwt = (contract.security || []).some(function (alternative) { return alternative.some(function (check) { return check.prefix === "Bearer " && String(check.bearerFormat || "").toUpperCase() === "JWT"; }); });',
|
|
298028
|
+
' if (wantsJwt && authorization && authorization.indexOf("{{") === -1 && authorization.toLowerCase().indexOf("bearer ") === 0) {',
|
|
298029
|
+
" var jwtToken = authorization.slice(7).trim();",
|
|
298030
|
+
' var jwtSegments = jwtToken.split(".");',
|
|
298031
|
+
' if (jwtSegments.length !== 3) pm.expect.fail("bearerFormat JWT tokens must have three base64url segments (RFC 7519); got " + jwtSegments.length);',
|
|
298032
|
+
' else if (!jwtSegments.every(function (segment) { return /^[A-Za-z0-9_-]+$/.test(segment); })) pm.expect.fail("JWT segments must be base64url (RFC 7515)");',
|
|
298033
|
+
" else {",
|
|
298034
|
+
' var jwtDecode = function (segment) { var padded = segment.replace(/-/g, "+").replace(/_/g, "/"); while (padded.length % 4 !== 0) padded += "="; return rfcBase64Decode(padded); };',
|
|
298035
|
+
" var jwtHeader = null; var jwtPayload = null;",
|
|
298036
|
+
' try { jwtHeader = JSON.parse(jwtDecode(jwtSegments[0])); } catch (error) { pm.expect.fail("JWT header segment does not decode to JSON (RFC 7515)"); }',
|
|
298037
|
+
' try { jwtPayload = JSON.parse(jwtDecode(jwtSegments[1])); } catch (error) { pm.expect.fail("JWT payload segment does not decode to JSON (RFC 7519)"); }',
|
|
298038
|
+
' if (jwtHeader && typeof jwtHeader.alg !== "string") pm.expect.fail("JWT header must carry a string alg member (RFC 7515)");',
|
|
298039
|
+
" if (jwtPayload) {",
|
|
298040
|
+
' ["exp", "nbf", "iat"].forEach(function (claim) { if (jwtPayload[claim] !== undefined && typeof jwtPayload[claim] !== "number") pm.expect.fail("JWT " + claim + " claim must be numeric (RFC 7519)"); });',
|
|
298041
|
+
' if (typeof jwtPayload.exp === "number" && jwtPayload.exp * 1000 < Date.now()) rfcAdvise("RFC 7519: the outgoing JWT exp claim is already in the past");',
|
|
298042
|
+
" }",
|
|
298043
|
+
" }",
|
|
298044
|
+
" }",
|
|
298045
|
+
' if (hasQueryParam("access_token")) rfcAdvise("RFC 6750: bearer tokens SHOULD NOT travel in the query string");',
|
|
298046
|
+
" (contract.security || []).forEach(function (alternative) {",
|
|
298047
|
+
" alternative.forEach(function (check) {",
|
|
298048
|
+
" if (!check.checkable || !check.name) return;",
|
|
298049
|
+
' if (check.in === "query") { if (hasQueryParam(check.name)) rfcAdvise("Security scheme " + check.scheme + " sends credentials in the query string"); return; }',
|
|
298050
|
+
' if (check.in !== "header" || String(check.name).toLowerCase() === "authorization") return;',
|
|
298051
|
+
" var apiKeyValue = requestHeader(check.name);",
|
|
298052
|
+
' if (!apiKeyValue || apiKeyValue.indexOf("{{") !== -1) return;',
|
|
298053
|
+
' if (apiKeyValue !== apiKeyValue.trim()) pm.expect.fail("API key header " + check.name + " carries leading or trailing whitespace");',
|
|
298054
|
+
' if (!rfcIsFieldContent(apiKeyValue)) pm.expect.fail("API key header " + check.name + " contains characters forbidden by RFC 9110 field-content");',
|
|
298055
|
+
" });",
|
|
298056
|
+
" });",
|
|
298057
|
+
"});",
|
|
298058
|
+
"pm.test('Request preconditions, preferences, and patch bodies follow their RFCs', function () {",
|
|
298059
|
+
' ["If-Match", "If-None-Match"].forEach(function (name) {',
|
|
298060
|
+
" var value = requestHeader(name);",
|
|
298061
|
+
' if (!value || value.indexOf("{{") !== -1 || value.trim() === "*") return;',
|
|
298062
|
+
' rfcSplitList(value).forEach(function (entry) { if (entry.trim() && !rfcIsEntityTag(entry.trim())) pm.expect.fail(name + " must be * or a list of entity-tags (RFC 9110): " + entry.trim()); });',
|
|
298063
|
+
" });",
|
|
298064
|
+
' var prefer = requestHeader("Prefer");',
|
|
298065
|
+
' if (prefer && prefer.indexOf("{{") === -1) {',
|
|
298066
|
+
' rfcSplitList(prefer).forEach(function (entry) { var token = entry.split("=")[0].split(";")[0].trim(); if (token && !rfcIsToken(token)) pm.expect.fail("Prefer preference name must be a token (RFC 7240): " + entry.trim()); });',
|
|
298067
|
+
" }",
|
|
298068
|
+
' var requestContentType = mediaBase(requestHeader("Content-Type"));',
|
|
298069
|
+
" var body = pm.request.body;",
|
|
298070
|
+
' var raw = body && body.mode === "raw" && typeof body.raw === "string" ? body.raw : "";',
|
|
298071
|
+
' if (!raw.trim() || raw.indexOf("{{") !== -1 || /"<[^"<>]*>"/.test(raw)) return;',
|
|
298072
|
+
' if (requestContentType === "application/json-patch+json") {',
|
|
298073
|
+
' var patch; try { patch = JSON.parse(raw); } catch (error) { if (/<[A-Za-z][A-Za-z0-9_ -]*>/.test(raw)) return; pm.expect.fail("application/json-patch+json request body is not valid JSON (RFC 6902): " + error); return; }',
|
|
298074
|
+
' if (!Array.isArray(patch)) { pm.expect.fail("A JSON Patch document must be an array of operations (RFC 6902)"); return; }',
|
|
298075
|
+
" patch.forEach(function (operation, operationIndex) {",
|
|
298076
|
+
' if (!operation || typeof operation !== "object" || Array.isArray(operation)) { pm.expect.fail("JSON Patch operation " + operationIndex + " must be an object (RFC 6902)"); return; }',
|
|
298077
|
+
' if (["add", "remove", "replace", "move", "copy", "test"].indexOf(operation.op) === -1) pm.expect.fail("JSON Patch operation " + operationIndex + " has an invalid op (RFC 6902): " + operation.op);',
|
|
298078
|
+
" var pointerPattern = /^(\\/([^\\/~]|~[01])*)*$/;",
|
|
298079
|
+
' if (typeof operation.path !== "string" || !pointerPattern.test(operation.path)) pm.expect.fail("JSON Patch operation " + operationIndex + " path must be an RFC 6901 JSON Pointer");',
|
|
298080
|
+
' if (["add", "replace", "test"].indexOf(operation.op) !== -1 && operation.value === undefined) pm.expect.fail("JSON Patch " + operation.op + " operation " + operationIndex + " requires a value member (RFC 6902)");',
|
|
298081
|
+
' if (["move", "copy"].indexOf(operation.op) !== -1 && (typeof operation.from !== "string" || !pointerPattern.test(operation.from))) pm.expect.fail("JSON Patch " + operation.op + " operation " + operationIndex + " requires an RFC 6901 from pointer (RFC 6902)");',
|
|
298082
|
+
" });",
|
|
298083
|
+
" }",
|
|
298084
|
+
' if (requestContentType === "application/merge-patch+json") {',
|
|
298085
|
+
' try { JSON.parse(raw); } catch (error) { if (/<[A-Za-z][A-Za-z0-9_ -]*>/.test(raw)) return; pm.expect.fail("application/merge-patch+json request body must be valid JSON (RFC 7386): " + error); }',
|
|
298086
|
+
" }",
|
|
298087
|
+
"});",
|
|
298088
|
+
"pm.test('Deprecated operation signals deprecation in the response', function () {",
|
|
298089
|
+
" if (!contract.deprecated) return;",
|
|
298090
|
+
' if (!rfcRespHeader("Deprecation") && !rfcRespHeader("Sunset")) rfcAdvise("RFC 9745: the OpenAPI document deprecates this operation but the response carries neither Deprecation nor Sunset");',
|
|
298091
|
+
"});",
|
|
298092
|
+
"pm.test('OpenAPI link expressions resolve against the response', function () {",
|
|
298093
|
+
" if (!selected || !selected.value.links || selected.value.links.length === 0) return;",
|
|
298094
|
+
" var linkBody = null; var linkBodyParsed = false;",
|
|
298095
|
+
" selected.value.links.forEach(function (expression) {",
|
|
298096
|
+
' if (expression.kind === "header") {',
|
|
298097
|
+
' if (!pm.response.headers.get(expression.header)) pm.expect.fail("OpenAPI link " + expression.link + " references response header " + expression.header + " which is absent");',
|
|
298098
|
+
" return;",
|
|
298099
|
+
" }",
|
|
298100
|
+
" if (!linkBodyParsed) { linkBodyParsed = true; try { linkBody = JSON.parse(responseText()); } catch (error) { linkBody = null; } }",
|
|
298101
|
+
' if (linkBody === null) { pm.expect.fail("OpenAPI link " + expression.link + " references the response body but the body is not JSON"); return; }',
|
|
298102
|
+
" var target = linkBody;",
|
|
298103
|
+
' var tokens = String(expression.pointer).split("/").slice(1).map(function (token) { return token.replace(/~1/g, "/").replace(/~0/g, "~"); });',
|
|
298104
|
+
" for (var t = 0; t < tokens.length; t += 1) {",
|
|
298105
|
+
' if (target !== null && typeof target === "object") target = Array.isArray(target) ? target[Number(tokens[t])] : target[tokens[t]];',
|
|
298106
|
+
" else { target = undefined; break; }",
|
|
298107
|
+
" }",
|
|
298108
|
+
' if (target === undefined) pm.expect.fail("OpenAPI link " + expression.link + " expression $response.body#" + expression.pointer + " does not resolve in the response body");',
|
|
298109
|
+
" });",
|
|
298110
|
+
"});",
|
|
298111
|
+
"pm.test('Request URL conforms to an OpenAPI servers entry', function () {",
|
|
298112
|
+
" if (!contract.servers || contract.servers.length === 0) return;",
|
|
298113
|
+
' var requestUrl = "";',
|
|
298114
|
+
' try { requestUrl = String(pm.request.url.toString()); } catch (ignored) { requestUrl = ""; }',
|
|
298115
|
+
' if (!requestUrl || requestUrl.indexOf("{{") !== -1) return;',
|
|
298116
|
+
' var pathOnly = requestUrl.replace(/^[a-z][a-z0-9+.-]*:\\/\\/[^\\/]+/i, "");',
|
|
298117
|
+
' var matched = contract.servers.some(function (pattern) { try { var serverPattern = new RegExp(pattern, "i"); return serverPattern.test(requestUrl) || serverPattern.test(pathOnly); } catch (ignored) { return true; } });',
|
|
298118
|
+
' if (!matched) rfcAdvise("Request URL does not match any OpenAPI servers entry: " + requestUrl);',
|
|
298119
|
+
"});",
|
|
297387
298120
|
...operation.security ? [
|
|
297388
298121
|
"pm.test('Request carries credentials required by OpenAPI security', function () {",
|
|
297389
298122
|
" function satisfied(check) {",
|
|
@@ -297423,6 +298156,12 @@ function createContractScript(operation, warnings = []) {
|
|
|
297423
298156
|
' if (param.allowEmptyValue && entries.length === 1 && entries[0] === "") return;',
|
|
297424
298157
|
" if (entries.some(isPlaceholder)) return;",
|
|
297425
298158
|
" value = entries.map(function (entry) { return coerceBySchema(decodeComponent(entry), param.items); });",
|
|
298159
|
+
' } else if (param.decode === "deepObject") {',
|
|
298160
|
+
" var deepValue = {}; var deepFound = false; var deepPlaceholder = false;",
|
|
298161
|
+
' pm.request.url.query.each(function (queryParam) { if (!queryParam || queryParam.disabled === true) return; var deepMatch = String(queryParam.key).match(/^([^\\[]+)\\[([^\\]]+)\\]$/); if (!deepMatch || deepMatch[1].toLowerCase() !== String(param.name).toLowerCase()) return; deepFound = true; var deepRaw = queryParam.value === null || queryParam.value === undefined ? "" : String(queryParam.value); if (isPlaceholder(deepRaw)) { deepPlaceholder = true; return; } deepValue[deepMatch[2]] = coerceBySchema(decodeComponent(deepRaw), (param.schema && param.schema.properties && param.schema.properties[deepMatch[2]]) || {}); });',
|
|
298162
|
+
' if (!deepFound) { if (param.required) pm.expect.fail("Required parameter " + param.in + ":" + param.name + " was not sent for " + contract.method + " " + contract.path); return; }',
|
|
298163
|
+
" if (deepPlaceholder) return;",
|
|
298164
|
+
" value = deepValue;",
|
|
297426
298165
|
" } else if (param.decode) {",
|
|
297427
298166
|
' var joined = param.in === "query" ? queryValue(String(param.name).toLowerCase()) : headerValue(param.name);',
|
|
297428
298167
|
' if (joined === undefined) { if (param.required) pm.expect.fail("Required parameter " + param.in + ":" + param.name + " was not sent for " + contract.method + " " + contract.path); return; }',
|
|
@@ -297439,6 +298178,8 @@ function createContractScript(operation, warnings = []) {
|
|
|
297439
298178
|
' } else if (param.in === "path") {',
|
|
297440
298179
|
" value = pathParamValue(param.name);",
|
|
297441
298180
|
" if (value === undefined) return;",
|
|
298181
|
+
' if (param.pathStyle === "label") { if (String(value).charAt(0) !== ".") return; value = String(value).slice(1); }',
|
|
298182
|
+
' if (param.pathStyle === "matrix") { var matrixPrefix = ";" + param.name + "="; if (String(value).indexOf(matrixPrefix) !== 0) return; value = String(value).slice(matrixPrefix.length); }',
|
|
297442
298183
|
' if (isPlaceholder(value) || value.charAt(0) === ":" || value.charAt(0) === "{") return;',
|
|
297443
298184
|
" value = coerceBySchema(value, param.schema);",
|
|
297444
298185
|
' } else if (param.in === "cookie") {',
|
|
@@ -297490,6 +298231,9 @@ function createContractScript(operation, warnings = []) {
|
|
|
297490
298231
|
' if (pm.response.headers.get("Content-Encoding")) return;',
|
|
297491
298232
|
" var mustBeEmpty = isBodyless() || (selected && Object.keys(selected.value.content || {}).length === 0);",
|
|
297492
298233
|
' if (mustBeEmpty && Number(String(raw).trim()) !== 0) pm.expect.fail("OpenAPI defines no response body for " + contract.method + " " + contract.path + " status " + pm.response.code + " but Content-Length was " + raw);',
|
|
298234
|
+
"});",
|
|
298235
|
+
"pm.test('RFC SHOULD-level advisories are documented', function () {",
|
|
298236
|
+
' pm.expect(rfcAdvisories, "SHOULD-level findings (advisory, non-failing): " + rfcAdvisories.join("; ")).to.be.an("array");',
|
|
297493
298237
|
"});"
|
|
297494
298238
|
];
|
|
297495
298239
|
}
|
|
@@ -297559,6 +298303,9 @@ function assertStaticRequestShape(operation, request) {
|
|
|
297559
298303
|
}
|
|
297560
298304
|
}
|
|
297561
298305
|
const warnings = collectStaticBodyWarnings(operation, request, contentType2);
|
|
298306
|
+
if (["GET", "HEAD", "DELETE"].includes(operation.method) && hasRequestBody(request)) {
|
|
298307
|
+
warnings.push(`CONTRACT_METHOD_BODY_SEMANTICS: ${operation.id} sends a request body with ${operation.method}; RFC 9110 defines no request-body semantics for this method`);
|
|
298308
|
+
}
|
|
297562
298309
|
if (operation.requestBody && !operation.requestBody.required && operation.requestBody.contentTypes.length > 0 && hasRequestBody(request) && contentType2) {
|
|
297563
298310
|
const actual = contentType2.toLowerCase().split(";")[0]?.trim() ?? "";
|
|
297564
298311
|
const matches = operation.requestBody.contentTypes.some((expected) => mediaTypeMatchesPattern(expected.toLowerCase(), actual));
|
|
@@ -297813,6 +298560,15 @@ function asRecord7(value) {
|
|
|
297813
298560
|
}
|
|
297814
298561
|
return value;
|
|
297815
298562
|
}
|
|
298563
|
+
function adviseWorkspaceFlipForbidden(error) {
|
|
298564
|
+
if (error instanceof HttpError && error.status === 403) {
|
|
298565
|
+
const body = error.responseBody || "";
|
|
298566
|
+
if (/addWorkspaceLevelTeamRoles/i.test(body) || /You are not authorized to perform this action/i.test(body)) {
|
|
298567
|
+
return new Error(WORKSPACE_PERSONAL_ONLY_ADVICE, { cause: error });
|
|
298568
|
+
}
|
|
298569
|
+
}
|
|
298570
|
+
return error;
|
|
298571
|
+
}
|
|
297816
298572
|
function extractGitRepoUrl(value) {
|
|
297817
298573
|
if (!value) return null;
|
|
297818
298574
|
if (typeof value === "string") {
|
|
@@ -298118,7 +298874,7 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
|
|
|
298118
298874
|
}
|
|
298119
298875
|
} catch (error) {
|
|
298120
298876
|
await this.deleteWorkspace(workspaceId).catch(() => void 0);
|
|
298121
|
-
throw error;
|
|
298877
|
+
throw adviseWorkspaceFlipForbidden(error);
|
|
298122
298878
|
}
|
|
298123
298879
|
return { id: workspaceId };
|
|
298124
298880
|
}
|
|
@@ -299375,7 +300131,7 @@ function resolveActionVersion(explicit) {
|
|
|
299375
300131
|
if (explicit) {
|
|
299376
300132
|
return explicit;
|
|
299377
300133
|
}
|
|
299378
|
-
return "
|
|
300134
|
+
return typeof __ACTION_VERSION__ !== "undefined" && __ACTION_VERSION__ ? __ACTION_VERSION__ : "unknown";
|
|
299379
300135
|
}
|
|
299380
300136
|
function telemetryDisabled(env) {
|
|
299381
300137
|
const flag = String(env.POSTMAN_ACTIONS_TELEMETRY ?? "").trim().toLowerCase();
|
|
@@ -299497,11 +300253,23 @@ function createTelemetryContext(options) {
|
|
|
299497
300253
|
};
|
|
299498
300254
|
}
|
|
299499
300255
|
|
|
299500
|
-
// src/
|
|
300256
|
+
// src/action-version.ts
|
|
299501
300257
|
var import_node_fs3 = require("node:fs");
|
|
300258
|
+
var import_node_path3 = require("node:path");
|
|
300259
|
+
function resolveActionVersion2() {
|
|
300260
|
+
try {
|
|
300261
|
+
const raw = (0, import_node_fs3.readFileSync)((0, import_node_path3.join)(__dirname, "..", "package.json"), "utf8");
|
|
300262
|
+
return JSON.parse(raw).version ?? "unknown";
|
|
300263
|
+
} catch {
|
|
300264
|
+
return "unknown";
|
|
300265
|
+
}
|
|
300266
|
+
}
|
|
300267
|
+
|
|
300268
|
+
// src/lib/spec/openapi-loader.ts
|
|
300269
|
+
var import_node_fs4 = require("node:fs");
|
|
299502
300270
|
var import_promises3 = require("node:fs/promises");
|
|
299503
300271
|
var import_node_url2 = require("node:url");
|
|
299504
|
-
var
|
|
300272
|
+
var import_node_path4 = __toESM(require("node:path"), 1);
|
|
299505
300273
|
|
|
299506
300274
|
// node_modules/@apidevtools/json-schema-ref-parser/dist/lib/util/convert-path-to-posix.js
|
|
299507
300275
|
var win32Sep = "\\";
|
|
@@ -299842,14 +300610,14 @@ function fromFileSystemPath(path8) {
|
|
|
299842
300610
|
const hasProjectUri = upperPath.includes(posixUpper);
|
|
299843
300611
|
const isAbsolutePath = isAbsoluteWin32Path.test(path8) || path8.startsWith("http://") || path8.startsWith("https://") || path8.startsWith("file://");
|
|
299844
300612
|
if (!(hasProjectDir || hasProjectUri || isAbsolutePath) && !projectDir.startsWith("http")) {
|
|
299845
|
-
const
|
|
300613
|
+
const join4 = (a, b) => {
|
|
299846
300614
|
if (a.endsWith("/") || a.endsWith("\\")) {
|
|
299847
300615
|
return a + b;
|
|
299848
300616
|
} else {
|
|
299849
300617
|
return a + "/" + b;
|
|
299850
300618
|
}
|
|
299851
300619
|
};
|
|
299852
|
-
path8 =
|
|
300620
|
+
path8 = join4(projectDir, path8);
|
|
299853
300621
|
}
|
|
299854
300622
|
path8 = convertPathToPosix(path8);
|
|
299855
300623
|
}
|
|
@@ -303964,6 +304732,7 @@ function inventory$Ref($refParent, $refKey, path8, scopeBase, dynamicIdScope, pa
|
|
|
303964
304732
|
const file = stripHash(pointer.path);
|
|
303965
304733
|
const hash = getHash(pointer.path);
|
|
303966
304734
|
const external = file !== $refs._root$Ref.path && !$refs._aliases[file];
|
|
304735
|
+
const nestedResource = Boolean($refs._aliases[file]) && pointer.$ref.value !== $refs._root$Ref.value;
|
|
303967
304736
|
const extended = ref_default.isExtended$Ref($ref);
|
|
303968
304737
|
indirections += pointer.indirections;
|
|
303969
304738
|
const existingEntry = findInInventory(inventory, $refParent, $refKey);
|
|
@@ -303997,6 +304766,8 @@ function inventory$Ref($refParent, $refKey, path8, scopeBase, dynamicIdScope, pa
|
|
|
303997
304766
|
// Does this $ref extend its resolved value? (i.e. it has extra properties, in addition to "$ref")
|
|
303998
304767
|
external,
|
|
303999
304768
|
// Does this $ref pointer point to a file other than the main JSON Schema file?
|
|
304769
|
+
nestedResource,
|
|
304770
|
+
// Does this $ref resolve to an embedded schema resource with its own $id?
|
|
304000
304771
|
indirections
|
|
304001
304772
|
// The number of indirect references that were traversed to resolve the value
|
|
304002
304773
|
});
|
|
@@ -304032,7 +304803,7 @@ function remap(inventory, options, rootId) {
|
|
|
304032
304803
|
for (const entry of inventory) {
|
|
304033
304804
|
const bundleOpts = options.bundle || {};
|
|
304034
304805
|
if (!entry.external) {
|
|
304035
|
-
if (bundleOpts.optimizeInternalRefs !== false) {
|
|
304806
|
+
if (bundleOpts.optimizeInternalRefs !== false && !entry.nestedResource) {
|
|
304036
304807
|
entry.$ref.$ref = entry.hash;
|
|
304037
304808
|
}
|
|
304038
304809
|
} else if (entry.file === file && entry.hash === hash) {
|
|
@@ -311836,22 +312607,22 @@ async function loadOpenApiContractSpec(specUrl, options = {}) {
|
|
|
311836
312607
|
async function loadOpenApiContractSpecFromPath(specPath, options = {}) {
|
|
311837
312608
|
if (!specPath) throw new Error("CONTRACT_SPEC_READ_FAILED: spec-path must not be empty");
|
|
311838
312609
|
const workspaceRoot = (() => {
|
|
311839
|
-
const root =
|
|
312610
|
+
const root = import_node_path4.default.resolve(process.env.GITHUB_WORKSPACE ?? process.cwd());
|
|
311840
312611
|
try {
|
|
311841
|
-
return (0,
|
|
312612
|
+
return (0, import_node_fs4.realpathSync)(root);
|
|
311842
312613
|
} catch {
|
|
311843
312614
|
return root;
|
|
311844
312615
|
}
|
|
311845
312616
|
})();
|
|
311846
|
-
const resolved =
|
|
312617
|
+
const resolved = import_node_path4.default.resolve(workspaceRoot, specPath);
|
|
311847
312618
|
let absolutePath;
|
|
311848
312619
|
try {
|
|
311849
|
-
absolutePath = (0,
|
|
312620
|
+
absolutePath = (0, import_node_fs4.realpathSync)(resolved);
|
|
311850
312621
|
} catch (error) {
|
|
311851
312622
|
throw new Error(`CONTRACT_SPEC_READ_FAILED: Unable to read spec at ${specPath}`, { cause: error });
|
|
311852
312623
|
}
|
|
311853
|
-
const rel =
|
|
311854
|
-
if (!rel || rel.startsWith("..") ||
|
|
312624
|
+
const rel = import_node_path4.default.relative(workspaceRoot, absolutePath);
|
|
312625
|
+
if (!rel || rel.startsWith("..") || import_node_path4.default.isAbsolute(rel)) {
|
|
311855
312626
|
throw new Error(`CONTRACT_SPEC_READ_FAILED: spec-path must resolve inside ${workspaceRoot}, got: ${specPath}`);
|
|
311856
312627
|
}
|
|
311857
312628
|
const maxBytes = options.maxBytesPerResource ?? SAFE_FETCH_LIMITS.maxBytesPerResource;
|
|
@@ -312265,6 +313036,17 @@ function buildOperationScript(operation, index, warnings) {
|
|
|
312265
313036
|
' pm.expect(pm.response.code, "GraphQL responses are HTTP 200 even when the data field carries errors").to.be.below(500);',
|
|
312266
313037
|
"});"
|
|
312267
313038
|
);
|
|
313039
|
+
lines.push(
|
|
313040
|
+
"pm.test(" + JSON.stringify("[" + label + "] GraphQL-over-HTTP media type and status are consistent") + ", function () {",
|
|
313041
|
+
' var contentType = ((pm.response.headers && pm.response.headers.get && pm.response.headers.get("Content-Type")) || "").toLowerCase();',
|
|
313042
|
+
' var mediaType = contentType.split(";")[0].trim();',
|
|
313043
|
+
" if (!mediaType) return;",
|
|
313044
|
+
' if (mediaType !== "application/graphql-response+json" && mediaType !== "application/json") { pm.expect.fail("GraphQL-over-HTTP responses use application/graphql-response+json or application/json; got: " + (mediaType || "<missing>")); }',
|
|
313045
|
+
" var wellFormed = gqlBody.data !== undefined || Array.isArray(gqlBody.errors);",
|
|
313046
|
+
' if (mediaType === "application/graphql-response+json" && pm.response.code >= 200 && pm.response.code < 300 && !wellFormed) { pm.expect.fail("application/graphql-response+json forbids a 2xx status when the body is not a well-formed GraphQL response"); }',
|
|
313047
|
+
' if (mediaType === "application/json" && gqlBody.data !== undefined && gqlBody.data !== null && pm.response.code !== 200) { pm.expect.fail("a GraphQL response carrying data over application/json must be HTTP 200; got " + pm.response.code); }',
|
|
313048
|
+
"});"
|
|
313049
|
+
);
|
|
312268
313050
|
lines.push(
|
|
312269
313051
|
`pm.test(${JSON.stringify(`[${label}] GraphQL errors are well-formed and not a total failure`)}, function () {`,
|
|
312270
313052
|
" var errors = gqlBody.errors;",
|
|
@@ -313805,6 +314587,8 @@ function createSoapScript(operation, warnings = []) {
|
|
|
313805
314587
|
hasOutput: Boolean(operation.output)
|
|
313806
314588
|
};
|
|
313807
314589
|
const responseRegex = operation.expectedResponseElement ? elementPresenceRegex(operation.expectedResponseElement) : "";
|
|
314590
|
+
const mediaType = operation.soapVersion === "1.2" ? "application/soap+xml" : "text/xml";
|
|
314591
|
+
const faultStatusLine = operation.soapVersion === "1.2" ? ' if (faulted && code !== 500 && code !== 400) pm.expect.fail("SOAP 1.2 Faults ride HTTP 500, or 400 for env:Sender faults (SOAP 1.2 Part 2 HTTP binding); got HTTP " + code);' : ' if (faulted && code !== 500) pm.expect.fail("SOAP 1.1 Faults must ride HTTP 500 (WS-I Basic Profile R1126); got HTTP " + code);';
|
|
313808
314592
|
const lines = [
|
|
313809
314593
|
`var soap = JSON.parse(${JSON.stringify(JSON.stringify(meta))});`,
|
|
313810
314594
|
'var bodyText = (pm.response.text && pm.response.text()) || "";',
|
|
@@ -313815,9 +314599,11 @@ function createSoapScript(operation, warnings = []) {
|
|
|
313815
314599
|
" pm.response.to.have.status(200);",
|
|
313816
314600
|
"});",
|
|
313817
314601
|
"",
|
|
313818
|
-
|
|
314602
|
+
// SOAP 1.1 responses bind to text/xml (SOAP 1.1 HTTP binding, WS-I Basic
|
|
314603
|
+
// Profile); SOAP 1.2 responses bind to application/soap+xml (RFC 3902).
|
|
314604
|
+
`pm.test('SOAP response Content-Type matches the SOAP ${operation.soapVersion} binding', function () {`,
|
|
313819
314605
|
' var ct = header("Content-Type").toLowerCase();',
|
|
313820
|
-
|
|
314606
|
+
` pm.expect(ct, "SOAP ${operation.soapVersion} responses use ${mediaType} (got: " + (ct || "<missing>") + ")").to.include("${mediaType}");`,
|
|
313821
314607
|
"});",
|
|
313822
314608
|
"",
|
|
313823
314609
|
"pm.test('SOAP Envelope element is present', function () {",
|
|
@@ -313834,6 +314620,13 @@ function createSoapScript(operation, warnings = []) {
|
|
|
313834
314620
|
' var detail = (bodyText.match(/<(?:[A-Za-z_][\\w.-]*:)?(?:faultstring|Reason|Text)[^>]*>([\\s\\S]*?)<\\//) || [])[1] || "";',
|
|
313835
314621
|
' pm.expect.fail("SOAP Fault returned for operation " + soap.name + (detail ? (": " + detail.trim()) : ""));',
|
|
313836
314622
|
" }",
|
|
314623
|
+
"});",
|
|
314624
|
+
"",
|
|
314625
|
+
"pm.test('SOAP Fault and HTTP status are consistent', function () {",
|
|
314626
|
+
' var faulted = matchTag("Fault").test(bodyText);',
|
|
314627
|
+
" var code = pm.response.code;",
|
|
314628
|
+
faultStatusLine,
|
|
314629
|
+
' if (!faulted && code === 500) pm.expect.fail("HTTP 500 from a SOAP endpoint must carry a SOAP Fault in the body");',
|
|
313837
314630
|
"});"
|
|
313838
314631
|
];
|
|
313839
314632
|
if (responseRegex) {
|
|
@@ -314991,6 +315784,7 @@ function normalizeSpecDocument(raw, warn) {
|
|
|
314991
315784
|
async function runBootstrap(inputs, dependencies) {
|
|
314992
315785
|
const telemetry = createTelemetryContext({
|
|
314993
315786
|
action: "postman-bootstrap-action",
|
|
315787
|
+
actionVersion: resolveActionVersion2(),
|
|
314994
315788
|
logger: dependencies.core
|
|
314995
315789
|
});
|
|
314996
315790
|
try {
|
|
@@ -315397,7 +316191,7 @@ async function runBootstrapInner(inputs, dependencies, telemetry) {
|
|
|
315397
316191
|
async () => {
|
|
315398
316192
|
if (inputs.specPath) {
|
|
315399
316193
|
const workspaceRoot = path6.resolve(process.env.GITHUB_WORKSPACE ?? process.cwd());
|
|
315400
|
-
return (0,
|
|
316194
|
+
return (0, import_node_fs5.readFileSync)(path6.resolve(workspaceRoot, inputs.specPath), "utf8");
|
|
315401
316195
|
}
|
|
315402
316196
|
if (dependencies.specFetcher === fetch) {
|
|
315403
316197
|
return safeFetchText(inputs.specUrl, { depth: 0 });
|
|
@@ -316208,15 +317002,15 @@ function shellQuote(value) {
|
|
|
316208
317002
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
316209
317003
|
}
|
|
316210
317004
|
function ensureInsideWorkspace(workspaceRoot, candidate) {
|
|
316211
|
-
const relative2 =
|
|
316212
|
-
if (relative2.startsWith("..") ||
|
|
317005
|
+
const relative2 = import_node_path5.default.relative(workspaceRoot, candidate);
|
|
317006
|
+
if (relative2.startsWith("..") || import_node_path5.default.isAbsolute(relative2)) {
|
|
316213
317007
|
throw new Error("Output path must stay within workspace");
|
|
316214
317008
|
}
|
|
316215
317009
|
}
|
|
316216
317010
|
function nearestExistingPath2(candidate) {
|
|
316217
317011
|
let current = candidate;
|
|
316218
317012
|
while (!pathExists(current)) {
|
|
316219
|
-
const parent =
|
|
317013
|
+
const parent = import_node_path5.default.dirname(current);
|
|
316220
317014
|
if (parent === current) {
|
|
316221
317015
|
return current;
|
|
316222
317016
|
}
|
|
@@ -316225,11 +317019,11 @@ function nearestExistingPath2(candidate) {
|
|
|
316225
317019
|
return current;
|
|
316226
317020
|
}
|
|
316227
317021
|
function pathExists(candidate) {
|
|
316228
|
-
if ((0,
|
|
317022
|
+
if ((0, import_node_fs6.existsSync)(candidate)) {
|
|
316229
317023
|
return true;
|
|
316230
317024
|
}
|
|
316231
317025
|
try {
|
|
316232
|
-
(0,
|
|
317026
|
+
(0, import_node_fs6.lstatSync)(candidate);
|
|
316233
317027
|
return true;
|
|
316234
317028
|
} catch {
|
|
316235
317029
|
return false;
|
|
@@ -316237,11 +317031,11 @@ function pathExists(candidate) {
|
|
|
316237
317031
|
}
|
|
316238
317032
|
function checkedRealPath(existingPath, workspaceRealPath) {
|
|
316239
317033
|
try {
|
|
316240
|
-
return (0,
|
|
317034
|
+
return (0, import_node_fs6.realpathSync)(existingPath);
|
|
316241
317035
|
} catch (error) {
|
|
316242
|
-
if ((0,
|
|
316243
|
-
const linkTarget = (0,
|
|
316244
|
-
const resolvedTarget =
|
|
317036
|
+
if ((0, import_node_fs6.lstatSync)(existingPath).isSymbolicLink()) {
|
|
317037
|
+
const linkTarget = (0, import_node_fs6.readlinkSync)(existingPath);
|
|
317038
|
+
const resolvedTarget = import_node_path5.default.resolve(import_node_path5.default.dirname(existingPath), linkTarget);
|
|
316245
317039
|
ensureInsideWorkspace(workspaceRealPath, resolvedTarget);
|
|
316246
317040
|
}
|
|
316247
317041
|
throw error;
|
|
@@ -316251,9 +317045,9 @@ function assertOutputFileAllowed2(filePath) {
|
|
|
316251
317045
|
if (!filePath) {
|
|
316252
317046
|
return void 0;
|
|
316253
317047
|
}
|
|
316254
|
-
const workspaceRoot =
|
|
316255
|
-
const workspaceRealPath = (0,
|
|
316256
|
-
const resolved =
|
|
317048
|
+
const workspaceRoot = import_node_path5.default.resolve(process.cwd());
|
|
317049
|
+
const workspaceRealPath = (0, import_node_fs6.realpathSync)(workspaceRoot);
|
|
317050
|
+
const resolved = import_node_path5.default.isAbsolute(filePath) ? import_node_path5.default.resolve(filePath) : import_node_path5.default.resolve(workspaceRoot, filePath);
|
|
316257
317051
|
const existingPath = nearestExistingPath2(resolved);
|
|
316258
317052
|
ensureInsideWorkspace(workspaceRealPath, checkedRealPath(existingPath, workspaceRealPath));
|
|
316259
317053
|
return resolved;
|
|
@@ -316263,8 +317057,8 @@ async function writeOptionalFile(filePath, content) {
|
|
|
316263
317057
|
if (!resolved) {
|
|
316264
317058
|
return;
|
|
316265
317059
|
}
|
|
316266
|
-
await (0, import_promises4.mkdir)(
|
|
316267
|
-
ensureInsideWorkspace((0,
|
|
317060
|
+
await (0, import_promises4.mkdir)(import_node_path5.default.dirname(resolved), { recursive: true });
|
|
317061
|
+
ensureInsideWorkspace((0, import_node_fs6.realpathSync)(import_node_path5.default.resolve(process.cwd())), (0, import_node_fs6.realpathSync)(import_node_path5.default.dirname(resolved)));
|
|
316268
317062
|
await (0, import_promises4.writeFile)(resolved, content, "utf8");
|
|
316269
317063
|
}
|
|
316270
317064
|
function requireCliInput(name, value) {
|
|
@@ -316322,9 +317116,9 @@ function isEntrypoint(currentPath, entrypointPath) {
|
|
|
316322
317116
|
return false;
|
|
316323
317117
|
}
|
|
316324
317118
|
try {
|
|
316325
|
-
return (0,
|
|
317119
|
+
return (0, import_node_fs6.realpathSync)(currentPath) === (0, import_node_fs6.realpathSync)(entrypointPath);
|
|
316326
317120
|
} catch {
|
|
316327
|
-
return
|
|
317121
|
+
return import_node_path5.default.resolve(currentPath) === import_node_path5.default.resolve(entrypointPath);
|
|
316328
317122
|
}
|
|
316329
317123
|
}
|
|
316330
317124
|
if (isEntrypoint(currentModulePath, entrypoint)) {
|