@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/dist/action.cjs CHANGED
@@ -55569,7 +55569,7 @@ var require_lodash = __commonJS({
55569
55569
  }
55570
55570
  return mapped.length && mapped[0] === arrays[0] ? baseIntersection(mapped, undefined2, comparator) : [];
55571
55571
  });
55572
- function join3(array, separator) {
55572
+ function join4(array, separator) {
55573
55573
  return array == null ? "" : nativeJoin.call(array, separator);
55574
55574
  }
55575
55575
  function last(array) {
@@ -57488,7 +57488,7 @@ var require_lodash = __commonJS({
57488
57488
  lodash.isUndefined = isUndefined;
57489
57489
  lodash.isWeakMap = isWeakMap;
57490
57490
  lodash.isWeakSet = isWeakSet;
57491
- lodash.join = join3;
57491
+ lodash.join = join4;
57492
57492
  lodash.kebabCase = kebabCase;
57493
57493
  lodash.last = last;
57494
57494
  lodash.lastIndexOf = lastIndexOf;
@@ -127435,16 +127435,16 @@ var require_printer = __commonJS({
127435
127435
  },
127436
127436
  // Document
127437
127437
  Document: {
127438
- leave: (node) => join3(node.definitions, "\n\n")
127438
+ leave: (node) => join4(node.definitions, "\n\n")
127439
127439
  },
127440
127440
  OperationDefinition: {
127441
127441
  leave(node) {
127442
- const varDefs = hasMultilineItems(node.variableDefinitions) ? wrap("(\n", join3(node.variableDefinitions, "\n"), "\n)") : wrap("(", join3(node.variableDefinitions, ", "), ")");
127443
- const prefix = wrap("", node.description, "\n") + join3(
127442
+ const varDefs = hasMultilineItems(node.variableDefinitions) ? wrap("(\n", join4(node.variableDefinitions, "\n"), "\n)") : wrap("(", join4(node.variableDefinitions, ", "), ")");
127443
+ const prefix = wrap("", node.description, "\n") + join4(
127444
127444
  [
127445
127445
  node.operation,
127446
- join3([node.name, varDefs]),
127447
- join3(node.directives, " ")
127446
+ join4([node.name, varDefs]),
127447
+ join4(node.directives, " ")
127448
127448
  ],
127449
127449
  " "
127450
127450
  );
@@ -127452,7 +127452,7 @@ var require_printer = __commonJS({
127452
127452
  }
127453
127453
  },
127454
127454
  VariableDefinition: {
127455
- leave: ({ variable, type, defaultValue, directives, description }) => wrap("", description, "\n") + variable + ": " + type + wrap(" = ", defaultValue) + wrap(" ", join3(directives, " "))
127455
+ leave: ({ variable, type, defaultValue, directives, description }) => wrap("", description, "\n") + variable + ": " + type + wrap(" = ", defaultValue) + wrap(" ", join4(directives, " "))
127456
127456
  },
127457
127457
  SelectionSet: {
127458
127458
  leave: ({ selections }) => block(selections)
@@ -127460,11 +127460,11 @@ var require_printer = __commonJS({
127460
127460
  Field: {
127461
127461
  leave({ alias, name, arguments: args, directives, selectionSet }) {
127462
127462
  const prefix = wrap("", alias, ": ") + name;
127463
- let argsLine = prefix + wrap("(", join3(args, ", "), ")");
127463
+ let argsLine = prefix + wrap("(", join4(args, ", "), ")");
127464
127464
  if (argsLine.length > MAX_LINE_LENGTH) {
127465
- argsLine = prefix + wrap("(\n", indent2(join3(args, "\n")), "\n)");
127465
+ argsLine = prefix + wrap("(\n", indent2(join4(args, "\n")), "\n)");
127466
127466
  }
127467
- return join3([argsLine, join3(directives, " "), selectionSet], " ");
127467
+ return join4([argsLine, join4(directives, " "), selectionSet], " ");
127468
127468
  }
127469
127469
  },
127470
127470
  Argument: {
@@ -127472,14 +127472,14 @@ var require_printer = __commonJS({
127472
127472
  },
127473
127473
  // Fragments
127474
127474
  FragmentSpread: {
127475
- leave: ({ name, directives }) => "..." + name + wrap(" ", join3(directives, " "))
127475
+ leave: ({ name, directives }) => "..." + name + wrap(" ", join4(directives, " "))
127476
127476
  },
127477
127477
  InlineFragment: {
127478
- leave: ({ typeCondition, directives, selectionSet }) => join3(
127478
+ leave: ({ typeCondition, directives, selectionSet }) => join4(
127479
127479
  [
127480
127480
  "...",
127481
127481
  wrap("on ", typeCondition),
127482
- join3(directives, " "),
127482
+ join4(directives, " "),
127483
127483
  selectionSet
127484
127484
  ],
127485
127485
  " "
@@ -127495,7 +127495,7 @@ var require_printer = __commonJS({
127495
127495
  description
127496
127496
  }) => wrap("", description, "\n") + // Note: fragment variable definitions are experimental and may be changed
127497
127497
  // or removed in the future.
127498
- `fragment ${name}${wrap("(", join3(variableDefinitions, ", "), ")")} on ${typeCondition} ${wrap("", join3(directives, " "), " ")}` + selectionSet
127498
+ `fragment ${name}${wrap("(", join4(variableDefinitions, ", "), ")")} on ${typeCondition} ${wrap("", join4(directives, " "), " ")}` + selectionSet
127499
127499
  },
127500
127500
  // Value
127501
127501
  IntValue: {
@@ -127517,17 +127517,17 @@ var require_printer = __commonJS({
127517
127517
  leave: ({ value }) => value
127518
127518
  },
127519
127519
  ListValue: {
127520
- leave: ({ values }) => "[" + join3(values, ", ") + "]"
127520
+ leave: ({ values }) => "[" + join4(values, ", ") + "]"
127521
127521
  },
127522
127522
  ObjectValue: {
127523
- leave: ({ fields }) => "{" + join3(fields, ", ") + "}"
127523
+ leave: ({ fields }) => "{" + join4(fields, ", ") + "}"
127524
127524
  },
127525
127525
  ObjectField: {
127526
127526
  leave: ({ name, value }) => name + ": " + value
127527
127527
  },
127528
127528
  // Directive
127529
127529
  Directive: {
127530
- leave: ({ name, arguments: args }) => "@" + name + wrap("(", join3(args, ", "), ")")
127530
+ leave: ({ name, arguments: args }) => "@" + name + wrap("(", join4(args, ", "), ")")
127531
127531
  },
127532
127532
  // Type
127533
127533
  NamedType: {
@@ -127541,61 +127541,61 @@ var require_printer = __commonJS({
127541
127541
  },
127542
127542
  // Type System Definitions
127543
127543
  SchemaDefinition: {
127544
- leave: ({ description, directives, operationTypes }) => wrap("", description, "\n") + join3(["schema", join3(directives, " "), block(operationTypes)], " ")
127544
+ leave: ({ description, directives, operationTypes }) => wrap("", description, "\n") + join4(["schema", join4(directives, " "), block(operationTypes)], " ")
127545
127545
  },
127546
127546
  OperationTypeDefinition: {
127547
127547
  leave: ({ operation, type }) => operation + ": " + type
127548
127548
  },
127549
127549
  ScalarTypeDefinition: {
127550
- leave: ({ description, name, directives }) => wrap("", description, "\n") + join3(["scalar", name, join3(directives, " ")], " ")
127550
+ leave: ({ description, name, directives }) => wrap("", description, "\n") + join4(["scalar", name, join4(directives, " ")], " ")
127551
127551
  },
127552
127552
  ObjectTypeDefinition: {
127553
- leave: ({ description, name, interfaces, directives, fields }) => wrap("", description, "\n") + join3(
127553
+ leave: ({ description, name, interfaces, directives, fields }) => wrap("", description, "\n") + join4(
127554
127554
  [
127555
127555
  "type",
127556
127556
  name,
127557
- wrap("implements ", join3(interfaces, " & ")),
127558
- join3(directives, " "),
127557
+ wrap("implements ", join4(interfaces, " & ")),
127558
+ join4(directives, " "),
127559
127559
  block(fields)
127560
127560
  ],
127561
127561
  " "
127562
127562
  )
127563
127563
  },
127564
127564
  FieldDefinition: {
127565
- leave: ({ description, name, arguments: args, type, directives }) => wrap("", description, "\n") + name + (hasMultilineItems(args) ? wrap("(\n", indent2(join3(args, "\n")), "\n)") : wrap("(", join3(args, ", "), ")")) + ": " + type + wrap(" ", join3(directives, " "))
127565
+ 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, " "))
127566
127566
  },
127567
127567
  InputValueDefinition: {
127568
- leave: ({ description, name, type, defaultValue, directives }) => wrap("", description, "\n") + join3(
127569
- [name + ": " + type, wrap("= ", defaultValue), join3(directives, " ")],
127568
+ leave: ({ description, name, type, defaultValue, directives }) => wrap("", description, "\n") + join4(
127569
+ [name + ": " + type, wrap("= ", defaultValue), join4(directives, " ")],
127570
127570
  " "
127571
127571
  )
127572
127572
  },
127573
127573
  InterfaceTypeDefinition: {
127574
- leave: ({ description, name, interfaces, directives, fields }) => wrap("", description, "\n") + join3(
127574
+ leave: ({ description, name, interfaces, directives, fields }) => wrap("", description, "\n") + join4(
127575
127575
  [
127576
127576
  "interface",
127577
127577
  name,
127578
- wrap("implements ", join3(interfaces, " & ")),
127579
- join3(directives, " "),
127578
+ wrap("implements ", join4(interfaces, " & ")),
127579
+ join4(directives, " "),
127580
127580
  block(fields)
127581
127581
  ],
127582
127582
  " "
127583
127583
  )
127584
127584
  },
127585
127585
  UnionTypeDefinition: {
127586
- leave: ({ description, name, directives, types: types2 }) => wrap("", description, "\n") + join3(
127587
- ["union", name, join3(directives, " "), wrap("= ", join3(types2, " | "))],
127586
+ leave: ({ description, name, directives, types: types2 }) => wrap("", description, "\n") + join4(
127587
+ ["union", name, join4(directives, " "), wrap("= ", join4(types2, " | "))],
127588
127588
  " "
127589
127589
  )
127590
127590
  },
127591
127591
  EnumTypeDefinition: {
127592
- leave: ({ description, name, directives, values }) => wrap("", description, "\n") + join3(["enum", name, join3(directives, " "), block(values)], " ")
127592
+ leave: ({ description, name, directives, values }) => wrap("", description, "\n") + join4(["enum", name, join4(directives, " "), block(values)], " ")
127593
127593
  },
127594
127594
  EnumValueDefinition: {
127595
- leave: ({ description, name, directives }) => wrap("", description, "\n") + join3([name, join3(directives, " ")], " ")
127595
+ leave: ({ description, name, directives }) => wrap("", description, "\n") + join4([name, join4(directives, " ")], " ")
127596
127596
  },
127597
127597
  InputObjectTypeDefinition: {
127598
- leave: ({ description, name, directives, fields }) => wrap("", description, "\n") + join3(["input", name, join3(directives, " "), block(fields)], " ")
127598
+ leave: ({ description, name, directives, fields }) => wrap("", description, "\n") + join4(["input", name, join4(directives, " "), block(fields)], " ")
127599
127599
  },
127600
127600
  DirectiveDefinition: {
127601
127601
  leave: ({
@@ -127605,84 +127605,84 @@ var require_printer = __commonJS({
127605
127605
  directives,
127606
127606
  repeatable,
127607
127607
  locations
127608
- }) => wrap("", description, "\n") + "directive @" + name + (hasMultilineItems(args) ? wrap("(\n", indent2(join3(args, "\n")), "\n)") : wrap("(", join3(args, ", "), ")")) + wrap(" ", join3(directives, " ")) + (repeatable ? " repeatable" : "") + " on " + join3(locations, " | ")
127608
+ }) => 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, " | ")
127609
127609
  },
127610
127610
  SchemaExtension: {
127611
- leave: ({ directives, operationTypes }) => join3(
127612
- ["extend schema", join3(directives, " "), block(operationTypes)],
127611
+ leave: ({ directives, operationTypes }) => join4(
127612
+ ["extend schema", join4(directives, " "), block(operationTypes)],
127613
127613
  " "
127614
127614
  )
127615
127615
  },
127616
127616
  ScalarTypeExtension: {
127617
- leave: ({ name, directives }) => join3(["extend scalar", name, join3(directives, " ")], " ")
127617
+ leave: ({ name, directives }) => join4(["extend scalar", name, join4(directives, " ")], " ")
127618
127618
  },
127619
127619
  ObjectTypeExtension: {
127620
- leave: ({ name, interfaces, directives, fields }) => join3(
127620
+ leave: ({ name, interfaces, directives, fields }) => join4(
127621
127621
  [
127622
127622
  "extend type",
127623
127623
  name,
127624
- wrap("implements ", join3(interfaces, " & ")),
127625
- join3(directives, " "),
127624
+ wrap("implements ", join4(interfaces, " & ")),
127625
+ join4(directives, " "),
127626
127626
  block(fields)
127627
127627
  ],
127628
127628
  " "
127629
127629
  )
127630
127630
  },
127631
127631
  InterfaceTypeExtension: {
127632
- leave: ({ name, interfaces, directives, fields }) => join3(
127632
+ leave: ({ name, interfaces, directives, fields }) => join4(
127633
127633
  [
127634
127634
  "extend interface",
127635
127635
  name,
127636
- wrap("implements ", join3(interfaces, " & ")),
127637
- join3(directives, " "),
127636
+ wrap("implements ", join4(interfaces, " & ")),
127637
+ join4(directives, " "),
127638
127638
  block(fields)
127639
127639
  ],
127640
127640
  " "
127641
127641
  )
127642
127642
  },
127643
127643
  UnionTypeExtension: {
127644
- leave: ({ name, directives, types: types2 }) => join3(
127644
+ leave: ({ name, directives, types: types2 }) => join4(
127645
127645
  [
127646
127646
  "extend union",
127647
127647
  name,
127648
- join3(directives, " "),
127649
- wrap("= ", join3(types2, " | "))
127648
+ join4(directives, " "),
127649
+ wrap("= ", join4(types2, " | "))
127650
127650
  ],
127651
127651
  " "
127652
127652
  )
127653
127653
  },
127654
127654
  EnumTypeExtension: {
127655
- leave: ({ name, directives, values }) => join3(["extend enum", name, join3(directives, " "), block(values)], " ")
127655
+ leave: ({ name, directives, values }) => join4(["extend enum", name, join4(directives, " "), block(values)], " ")
127656
127656
  },
127657
127657
  InputObjectTypeExtension: {
127658
- leave: ({ name, directives, fields }) => join3(["extend input", name, join3(directives, " "), block(fields)], " ")
127658
+ leave: ({ name, directives, fields }) => join4(["extend input", name, join4(directives, " "), block(fields)], " ")
127659
127659
  },
127660
127660
  DirectiveExtension: {
127661
- leave: ({ name, directives }) => join3(["extend directive @" + name, join3(directives, " ")], " ")
127661
+ leave: ({ name, directives }) => join4(["extend directive @" + name, join4(directives, " ")], " ")
127662
127662
  },
127663
127663
  // Schema Coordinates
127664
127664
  TypeCoordinate: {
127665
127665
  leave: ({ name }) => name
127666
127666
  },
127667
127667
  MemberCoordinate: {
127668
- leave: ({ name, memberName }) => join3([name, wrap(".", memberName)])
127668
+ leave: ({ name, memberName }) => join4([name, wrap(".", memberName)])
127669
127669
  },
127670
127670
  ArgumentCoordinate: {
127671
- leave: ({ name, fieldName, argumentName }) => join3([name, wrap(".", fieldName), wrap("(", argumentName, ":)")])
127671
+ leave: ({ name, fieldName, argumentName }) => join4([name, wrap(".", fieldName), wrap("(", argumentName, ":)")])
127672
127672
  },
127673
127673
  DirectiveCoordinate: {
127674
- leave: ({ name }) => join3(["@", name])
127674
+ leave: ({ name }) => join4(["@", name])
127675
127675
  },
127676
127676
  DirectiveArgumentCoordinate: {
127677
- leave: ({ name, argumentName }) => join3(["@", name, wrap("(", argumentName, ":)")])
127677
+ leave: ({ name, argumentName }) => join4(["@", name, wrap("(", argumentName, ":)")])
127678
127678
  }
127679
127679
  };
127680
- function join3(maybeArray, separator = "") {
127680
+ function join4(maybeArray, separator = "") {
127681
127681
  var _maybeArray$filter$jo;
127682
127682
  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 : "";
127683
127683
  }
127684
127684
  function block(array) {
127685
- return wrap("{\n", indent2(join3(array, "\n")), "\n}");
127685
+ return wrap("{\n", indent2(join4(array, "\n")), "\n}");
127686
127686
  }
127687
127687
  function wrap(start, maybeString, end = "") {
127688
127688
  return maybeString != null && maybeString !== "" ? start + maybeString + end : "";
@@ -152316,7 +152316,7 @@ var require_index_cjs = __commonJS({
152316
152316
  const t = parse10(r);
152317
152317
  return "http" === t.protocol || "https" === t.protocol;
152318
152318
  }
152319
- var join3 = (...r) => {
152319
+ var join4 = (...r) => {
152320
152320
  if (0 === r.length) return ".";
152321
152321
  const t = r.map(parse10), e = Object.assign({}, t[0]);
152322
152322
  for (let n = 1; n < t.length; n++) {
@@ -152340,7 +152340,7 @@ var require_index_cjs = __commonJS({
152340
152340
  function resolve5(...r) {
152341
152341
  if (0 === r.length) return ".";
152342
152342
  const t = normalizeParsed(parse10(r[r.length - 1]));
152343
- return t.absolute ? format3(t) : join3(...r);
152343
+ return t.absolute ? format3(t) : join4(...r);
152344
152344
  }
152345
152345
  var startsWithWindowsDrive = (r) => {
152346
152346
  return null !== parse10(r).drive;
@@ -152354,7 +152354,7 @@ var require_index_cjs = __commonJS({
152354
152354
  function serializeSrn({ shortcode: r, orgSlug: t, projectSlug: e, uri: n = "" }) {
152355
152355
  return [r, t, e, n.replace(/^\//, "")].filter(Boolean).join("/");
152356
152356
  }
152357
- exports2.basename = basename3, exports2.deserializeSrn = deserializeSrn, exports2.dirname = dirname3, exports2.extname = extname2, exports2.format = format3, exports2.isAbsolute = isAbsolute, exports2.isURL = isURL, exports2.join = join3, exports2.normalize = normalize3, exports2.parse = parse10, exports2.relative = relative2, exports2.resolve = resolve5, exports2.sep = "/", exports2.serializeSrn = serializeSrn, exports2.startsWithWindowsDrive = startsWithWindowsDrive, exports2.stripRoot = stripRoot, exports2.toFSPath = normalize3;
152357
+ 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 = resolve5, exports2.sep = "/", exports2.serializeSrn = serializeSrn, exports2.startsWithWindowsDrive = startsWithWindowsDrive, exports2.stripRoot = stripRoot, exports2.toFSPath = normalize3;
152358
152358
  }
152359
152359
  });
152360
152360
 
@@ -154097,7 +154097,7 @@ var require_stable = __commonJS({
154097
154097
  return result;
154098
154098
  }
154099
154099
  function stringifyFullFn(key, parent, stack, replacer, indent2) {
154100
- var i, res, join3;
154100
+ var i, res, join4;
154101
154101
  const originalIndentation = indentation;
154102
154102
  var value = parent[key];
154103
154103
  if (typeof value === "object" && value !== null && typeof value.toJSON === "function") {
@@ -154123,12 +154123,12 @@ var require_stable = __commonJS({
154123
154123
  indentation += indent2;
154124
154124
  res += `
154125
154125
  ${indentation}`;
154126
- join3 = `,
154126
+ join4 = `,
154127
154127
  ${indentation}`;
154128
154128
  for (i = 0; i < value.length - 1; i++) {
154129
154129
  const tmp2 = stringifyFullFn(i, value, stack, replacer, indent2);
154130
154130
  res += tmp2 !== void 0 ? tmp2 : "null";
154131
- res += join3;
154131
+ res += join4;
154132
154132
  }
154133
154133
  const tmp = stringifyFullFn(i, value, stack, replacer, indent2);
154134
154134
  res += tmp !== void 0 ? tmp : "null";
@@ -154150,7 +154150,7 @@ ${originalIndentation}`;
154150
154150
  indentation += indent2;
154151
154151
  res += `
154152
154152
  ${indentation}`;
154153
- join3 = `,
154153
+ join4 = `,
154154
154154
  ${indentation}`;
154155
154155
  var separator = "";
154156
154156
  for (i = 0; i < keys.length; i++) {
@@ -154158,7 +154158,7 @@ ${indentation}`;
154158
154158
  const tmp = stringifyFullFn(key, value, stack, replacer, indent2);
154159
154159
  if (tmp !== void 0) {
154160
154160
  res += `${separator}"${strEscape(key)}": ${tmp}`;
154161
- separator = join3;
154161
+ separator = join4;
154162
154162
  }
154163
154163
  }
154164
154164
  if (separator !== "") {
@@ -154180,7 +154180,7 @@ ${originalIndentation}`;
154180
154180
  }
154181
154181
  }
154182
154182
  function stringifyFullArr(key, value, stack, replacer, indent2) {
154183
- var i, res, join3;
154183
+ var i, res, join4;
154184
154184
  const originalIndentation = indentation;
154185
154185
  if (typeof value === "object" && value !== null && typeof value.toJSON === "function") {
154186
154186
  value = value.toJSON(key);
@@ -154204,12 +154204,12 @@ ${originalIndentation}`;
154204
154204
  indentation += indent2;
154205
154205
  res += `
154206
154206
  ${indentation}`;
154207
- join3 = `,
154207
+ join4 = `,
154208
154208
  ${indentation}`;
154209
154209
  for (i = 0; i < value.length - 1; i++) {
154210
154210
  const tmp2 = stringifyFullArr(i, value[i], stack, replacer, indent2);
154211
154211
  res += tmp2 !== void 0 ? tmp2 : "null";
154212
- res += join3;
154212
+ res += join4;
154213
154213
  }
154214
154214
  const tmp = stringifyFullArr(i, value[i], stack, replacer, indent2);
154215
154215
  res += tmp !== void 0 ? tmp : "null";
@@ -154230,7 +154230,7 @@ ${originalIndentation}`;
154230
154230
  indentation += indent2;
154231
154231
  res += `
154232
154232
  ${indentation}`;
154233
- join3 = `,
154233
+ join4 = `,
154234
154234
  ${indentation}`;
154235
154235
  var separator = "";
154236
154236
  for (i = 0; i < replacer.length; i++) {
@@ -154239,7 +154239,7 @@ ${indentation}`;
154239
154239
  const tmp = stringifyFullArr(key, value[key], stack, replacer, indent2);
154240
154240
  if (tmp !== void 0) {
154241
154241
  res += `${separator}"${strEscape(key)}": ${tmp}`;
154242
- separator = join3;
154242
+ separator = join4;
154243
154243
  }
154244
154244
  }
154245
154245
  }
@@ -154262,7 +154262,7 @@ ${originalIndentation}`;
154262
154262
  }
154263
154263
  }
154264
154264
  function stringifyIndent(key, value, stack, indent2) {
154265
- var i, res, join3;
154265
+ var i, res, join4;
154266
154266
  const originalIndentation = indentation;
154267
154267
  switch (typeof value) {
154268
154268
  case "object":
@@ -154292,12 +154292,12 @@ ${originalIndentation}`;
154292
154292
  indentation += indent2;
154293
154293
  res += `
154294
154294
  ${indentation}`;
154295
- join3 = `,
154295
+ join4 = `,
154296
154296
  ${indentation}`;
154297
154297
  for (i = 0; i < value.length - 1; i++) {
154298
154298
  const tmp2 = stringifyIndent(i, value[i], stack, indent2);
154299
154299
  res += tmp2 !== void 0 ? tmp2 : "null";
154300
- res += join3;
154300
+ res += join4;
154301
154301
  }
154302
154302
  const tmp = stringifyIndent(i, value[i], stack, indent2);
154303
154303
  res += tmp !== void 0 ? tmp : "null";
@@ -154319,7 +154319,7 @@ ${originalIndentation}`;
154319
154319
  indentation += indent2;
154320
154320
  res += `
154321
154321
  ${indentation}`;
154322
- join3 = `,
154322
+ join4 = `,
154323
154323
  ${indentation}`;
154324
154324
  var separator = "";
154325
154325
  for (i = 0; i < keys.length; i++) {
@@ -154327,7 +154327,7 @@ ${indentation}`;
154327
154327
  const tmp = stringifyIndent(key, value[key], stack, indent2);
154328
154328
  if (tmp !== void 0) {
154329
154329
  res += `${separator}"${strEscape(key)}": ${tmp}`;
154330
- separator = join3;
154330
+ separator = join4;
154331
154331
  }
154332
154332
  }
154333
154333
  if (separator !== "") {
@@ -172660,7 +172660,7 @@ var require_lodash2 = __commonJS({
172660
172660
  }
172661
172661
  return mapped.length && mapped[0] === arrays[0] ? baseIntersection(mapped, undefined2, comparator) : [];
172662
172662
  });
172663
- function join3(array, separator) {
172663
+ function join4(array, separator) {
172664
172664
  return array == null ? "" : nativeJoin.call(array, separator);
172665
172665
  }
172666
172666
  function last(array) {
@@ -174584,7 +174584,7 @@ var require_lodash2 = __commonJS({
174584
174584
  lodash.isUndefined = isUndefined;
174585
174585
  lodash.isWeakMap = isWeakMap;
174586
174586
  lodash.isWeakSet = isWeakSet;
174587
- lodash.join = join3;
174587
+ lodash.join = join4;
174588
174588
  lodash.kebabCase = kebabCase;
174589
174589
  lodash.last = last;
174590
174590
  lodash.lastIndexOf = lastIndexOf;
@@ -179718,7 +179718,7 @@ var require_lodash3 = __commonJS({
179718
179718
  }
179719
179719
  return mapped.length && mapped[0] === arrays[0] ? baseIntersection(mapped, undefined2, comparator) : [];
179720
179720
  });
179721
- function join3(array, separator) {
179721
+ function join4(array, separator) {
179722
179722
  return array == null ? "" : nativeJoin.call(array, separator);
179723
179723
  }
179724
179724
  function last(array) {
@@ -181642,7 +181642,7 @@ var require_lodash3 = __commonJS({
181642
181642
  lodash.isUndefined = isUndefined;
181643
181643
  lodash.isWeakMap = isWeakMap;
181644
181644
  lodash.isWeakSet = isWeakSet;
181645
- lodash.join = join3;
181645
+ lodash.join = join4;
181646
181646
  lodash.kebabCase = kebabCase;
181647
181647
  lodash.last = last;
181648
181648
  lodash.lastIndexOf = lastIndexOf;
@@ -283137,7 +283137,7 @@ var require_lodash5 = __commonJS({
283137
283137
  }
283138
283138
  return mapped.length && mapped[0] === arrays[0] ? baseIntersection(mapped, undefined2, comparator) : [];
283139
283139
  });
283140
- function join3(array, separator) {
283140
+ function join4(array, separator) {
283141
283141
  return array == null ? "" : nativeJoin.call(array, separator);
283142
283142
  }
283143
283143
  function last(array) {
@@ -285061,7 +285061,7 @@ var require_lodash5 = __commonJS({
285061
285061
  lodash.isUndefined = isUndefined;
285062
285062
  lodash.isWeakMap = isWeakMap;
285063
285063
  lodash.isWeakSet = isWeakSet;
285064
- lodash.join = join3;
285064
+ lodash.join = join4;
285065
285065
  lodash.kebabCase = kebabCase;
285066
285066
  lodash.last = last;
285067
285067
  lodash.lastIndexOf = lastIndexOf;
@@ -294670,7 +294670,7 @@ function getIDToken(aud) {
294670
294670
 
294671
294671
  // src/index.ts
294672
294672
  var import_node_crypto4 = require("node:crypto");
294673
- var import_node_fs4 = require("node:fs");
294673
+ var import_node_fs5 = require("node:fs");
294674
294674
  var path9 = __toESM(require("node:path"), 1);
294675
294675
  var import_yaml4 = __toESM(require_dist(), 1);
294676
294676
 
@@ -296224,12 +296224,62 @@ function resolvePostmanEndpointProfile(stack, region = "us") {
296224
296224
 
296225
296225
  // src/lib/postman/credential-identity.ts
296226
296226
  var sessionPath = "/api/sessions/current";
296227
+ var SESSION_MAX_ATTEMPTS = 3;
296228
+ var SESSION_RETRY_BASE_DELAY_MS = 500;
296229
+ var SESSION_RETRY_MAX_DELAY_MS = 8e3;
296227
296230
  var pmakMemo = /* @__PURE__ */ new Map();
296228
296231
  var sessionMemo = /* @__PURE__ */ new Map();
296229
296232
  var memoizedSessionIdentity;
296233
+ var memoizedSessionFailure;
296234
+ function defaultSessionSleep(ms) {
296235
+ return new Promise((resolve5) => setTimeout(resolve5, ms));
296236
+ }
296237
+ function defaultRandom() {
296238
+ return Math.random();
296239
+ }
296240
+ function parseRetryAfterMs(value) {
296241
+ const trimmed = value?.trim();
296242
+ if (!trimmed) {
296243
+ return void 0;
296244
+ }
296245
+ if (/^\d+$/.test(trimmed)) {
296246
+ return Number(trimmed) * 1e3;
296247
+ }
296248
+ const dateMs = Date.parse(trimmed);
296249
+ if (!Number.isNaN(dateMs)) {
296250
+ return Math.max(0, dateMs - Date.now());
296251
+ }
296252
+ return void 0;
296253
+ }
296254
+ function parseRateLimitResetMs(value) {
296255
+ const trimmed = value?.trim();
296256
+ if (!trimmed || !/^\d+$/.test(trimmed)) {
296257
+ return void 0;
296258
+ }
296259
+ const seconds = Number(trimmed);
296260
+ const nowSeconds = Date.now() / 1e3;
296261
+ if (seconds > nowSeconds) {
296262
+ return Math.max(0, (seconds - nowSeconds) * 1e3);
296263
+ }
296264
+ return seconds * 1e3;
296265
+ }
296266
+ function computeSessionRetryDelayMs(response, attempt, random) {
296267
+ const headers = response?.headers;
296268
+ const signal = parseRetryAfterMs(headers?.get("retry-after") ?? null) ?? parseRateLimitResetMs(
296269
+ headers?.get("ratelimit-reset") ?? headers?.get("x-ratelimit-reset") ?? null
296270
+ );
296271
+ if (signal !== void 0) {
296272
+ return Math.min(Math.max(0, signal), SESSION_RETRY_MAX_DELAY_MS);
296273
+ }
296274
+ const ceiling = Math.min(SESSION_RETRY_MAX_DELAY_MS, SESSION_RETRY_BASE_DELAY_MS * 2 ** (attempt - 1));
296275
+ return Math.round(random() * ceiling);
296276
+ }
296230
296277
  function getMemoizedSessionIdentity() {
296231
296278
  return memoizedSessionIdentity;
296232
296279
  }
296280
+ function getSessionResolutionFailure() {
296281
+ return memoizedSessionFailure;
296282
+ }
296233
296283
  function asRecord2(value) {
296234
296284
  if (!value || typeof value !== "object" || Array.isArray(value)) {
296235
296285
  return void 0;
@@ -296298,46 +296348,90 @@ async function resolveSessionIdentity(opts) {
296298
296348
  const memoKey = `${baseUrl}::${accessToken}`;
296299
296349
  let pending = sessionMemo.get(memoKey);
296300
296350
  if (!pending) {
296301
- pending = probeSessionIdentity(baseUrl, accessToken, opts.fetchImpl ?? fetch);
296351
+ pending = probeSessionIdentity(
296352
+ baseUrl,
296353
+ accessToken,
296354
+ opts.fetchImpl ?? fetch,
296355
+ Math.max(1, opts.maxAttempts ?? SESSION_MAX_ATTEMPTS),
296356
+ opts.sleepImpl ?? defaultSessionSleep,
296357
+ opts.randomImpl ?? defaultRandom
296358
+ );
296302
296359
  sessionMemo.set(memoKey, pending);
296303
296360
  }
296304
296361
  return pending;
296305
296362
  }
296306
- async function probeSessionIdentity(baseUrl, accessToken, fetchImpl) {
296363
+ async function parseSessionResponse(response) {
296364
+ let payload;
296307
296365
  try {
296308
- const response = await fetchImpl(`${baseUrl}${sessionPath}`, {
296309
- method: "GET",
296310
- headers: { "x-access-token": accessToken }
296311
- });
296312
- if (!response.ok) {
296313
- return void 0;
296314
- }
296315
- const payload = asRecord2(await response.json());
296316
- if (!payload) {
296317
- return void 0;
296318
- }
296319
- const root = asRecord2(payload.session) ?? payload;
296320
- const identity = asRecord2(root.identity);
296321
- const data = asRecord2(root.data);
296322
- const user = asRecord2(data?.user);
296323
- const roleEntries = Array.isArray(user?.roles) ? user.roles.map((entry) => coerceText(entry) ?? coerceId(entry)).filter((entry) => Boolean(entry)) : [];
296324
- const singleRole = coerceText(user?.role);
296325
- const roles = roleEntries.length > 0 ? roleEntries : singleRole ? [singleRole] : void 0;
296326
- const resolved = {
296327
- source: "iapub/sessions",
296328
- userId: coerceId(identity?.user) ?? coerceId(user?.id),
296329
- fullName: coerceText(user?.fullName) ?? coerceText(user?.name) ?? coerceText(user?.username),
296330
- teamId: coerceId(identity?.team),
296331
- teamName: coerceText(user?.teamName),
296332
- teamDomain: coerceText(identity?.domain),
296333
- ...roles ? { roles } : {},
296334
- consumerType: coerceText(root.consumerType) ?? coerceText(data?.consumerType) ?? coerceText(user?.consumerType)
296335
- };
296336
- memoizedSessionIdentity = resolved;
296337
- return resolved;
296366
+ payload = asRecord2(await response.json());
296338
296367
  } catch {
296339
296368
  return void 0;
296340
296369
  }
296370
+ if (!payload) {
296371
+ return void 0;
296372
+ }
296373
+ const root = asRecord2(payload.session) ?? payload;
296374
+ const identity = asRecord2(root.identity);
296375
+ const data = asRecord2(root.data);
296376
+ const user = asRecord2(data?.user);
296377
+ const roleEntries = Array.isArray(user?.roles) ? user.roles.map((entry) => coerceText(entry) ?? coerceId(entry)).filter((entry) => Boolean(entry)) : [];
296378
+ const singleRole = coerceText(user?.role);
296379
+ const roles = roleEntries.length > 0 ? roleEntries : singleRole ? [singleRole] : void 0;
296380
+ return {
296381
+ source: "iapub/sessions",
296382
+ userId: coerceId(identity?.user) ?? coerceId(user?.id),
296383
+ fullName: coerceText(user?.fullName) ?? coerceText(user?.name) ?? coerceText(user?.username),
296384
+ teamId: coerceId(identity?.team),
296385
+ teamName: coerceText(user?.teamName),
296386
+ teamDomain: coerceText(identity?.domain),
296387
+ ...roles ? { roles } : {},
296388
+ consumerType: coerceText(root.consumerType) ?? coerceText(data?.consumerType) ?? coerceText(user?.consumerType)
296389
+ };
296390
+ }
296391
+ async function probeSessionIdentity(baseUrl, accessToken, fetchImpl, maxAttempts, sleepImpl, random) {
296392
+ let failure = "unavailable";
296393
+ for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
296394
+ let response;
296395
+ try {
296396
+ response = await fetchImpl(`${baseUrl}${sessionPath}`, {
296397
+ method: "GET",
296398
+ headers: { "x-access-token": accessToken }
296399
+ });
296400
+ } catch {
296401
+ failure = "unavailable";
296402
+ if (attempt < maxAttempts) {
296403
+ await sleepImpl(computeSessionRetryDelayMs(void 0, attempt, random));
296404
+ continue;
296405
+ }
296406
+ break;
296407
+ }
296408
+ if (response.ok) {
296409
+ const resolved = await parseSessionResponse(response);
296410
+ if (resolved) {
296411
+ memoizedSessionIdentity = resolved;
296412
+ memoizedSessionFailure = void 0;
296413
+ return resolved;
296414
+ }
296415
+ failure = "unavailable";
296416
+ break;
296417
+ }
296418
+ if (response.status === 401 || response.status === 403) {
296419
+ failure = "auth";
296420
+ break;
296421
+ }
296422
+ if (response.status === 429 || response.status >= 500) {
296423
+ failure = "unavailable";
296424
+ if (attempt < maxAttempts) {
296425
+ await sleepImpl(computeSessionRetryDelayMs(response, attempt, random));
296426
+ continue;
296427
+ }
296428
+ break;
296429
+ }
296430
+ failure = "unavailable";
296431
+ break;
296432
+ }
296433
+ memoizedSessionFailure = failure;
296434
+ return void 0;
296341
296435
  }
296342
296436
  function describeTeam(id) {
296343
296437
  const label = id?.teamName ?? id?.teamDomain;
@@ -296428,7 +296522,9 @@ async function runCredentialPreflight(args) {
296428
296522
  session = await resolveSessionIdentity({
296429
296523
  iapubBaseUrl: args.iapubBaseUrl,
296430
296524
  accessToken,
296431
- fetchImpl: args.fetchImpl
296525
+ fetchImpl: args.fetchImpl,
296526
+ ...args.sleepImpl ? { sleepImpl: args.sleepImpl } : {},
296527
+ ...args.randomImpl ? { randomImpl: args.randomImpl } : {}
296432
296528
  });
296433
296529
  } catch (error2) {
296434
296530
  args.log.warning(
@@ -296448,11 +296544,20 @@ async function runCredentialPreflight(args) {
296448
296544
  );
296449
296545
  }
296450
296546
  } else {
296547
+ const failure = getSessionResolutionFailure();
296548
+ 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.";
296549
+ const base = "postman: credential preflight could not resolve the access-token session identity from iapub: " + detail;
296550
+ if (args.mode === "enforce") {
296551
+ throw new Error(
296552
+ mask(
296553
+ `${base} (credential-preflight: enforce requires a resolvable session identity; use credential-preflight: warn to continue with reactive error guidance only.)`
296554
+ )
296555
+ );
296556
+ }
296451
296557
  args.log.warning(
296452
- mask(
296453
- "postman: credential preflight could not resolve the access-token session identity from iapub; continuing with reactive error guidance only"
296454
- )
296558
+ mask(`${base} Continuing with reactive error guidance only (credential-preflight: warn).`)
296455
296559
  );
296560
+ return;
296456
296561
  }
296457
296562
  const result = crossCheckIdentities({
296458
296563
  pmak,
@@ -298219,7 +298324,11 @@ function securityCheckFor(schemeName, scheme) {
298219
298324
  if (scheme?.type === "http") {
298220
298325
  const httpScheme = String(scheme.scheme || "").toLowerCase();
298221
298326
  if (httpScheme === "basic") return { scheme: schemeName, kind, checkable: true, prefix: "Basic " };
298222
- if (httpScheme === "bearer") return { scheme: schemeName, kind, checkable: true, prefix: "Bearer " };
298327
+ if (httpScheme === "bearer") {
298328
+ const check = { scheme: schemeName, kind, checkable: true, prefix: "Bearer " };
298329
+ if (typeof scheme.bearerFormat === "string" && scheme.bearerFormat) check.bearerFormat = scheme.bearerFormat;
298330
+ return check;
298331
+ }
298223
298332
  if (httpScheme) return { scheme: schemeName, kind, checkable: true, prefix: `${httpScheme.charAt(0).toUpperCase()}${httpScheme.slice(1)} ` };
298224
298333
  return { scheme: schemeName, kind, checkable: true, in: "header", name: "Authorization" };
298225
298334
  }
@@ -298358,6 +298467,7 @@ function collectParameterChecks(root, pathItem, operation, version2, operationId
298358
298467
  if (defaultSerialization) warnings.push(`CONTRACT_SCHEMA_NOT_COMPILED: parameter ${location2}:${name} schema on ${operationId} skipped (${packed.unsupported})`);
298359
298468
  continue;
298360
298469
  }
298470
+ validateParameterExamples(root, param, packed, `${location2}:${name} of ${operationId}`, warnings);
298361
298471
  if (location2 === "path") {
298362
298472
  const containingSegment = pathTemplate.split("/").find((segment) => segment.includes(`{${name}}`));
298363
298473
  if (containingSegment !== void 0 && containingSegment !== `{${name}}`) {
@@ -298374,12 +298484,32 @@ function collectParameterChecks(root, pathItem, operation, version2, operationId
298374
298484
  }
298375
298485
  const scalarSchema = packedScalarSchema(packed);
298376
298486
  if (scalarSchema !== void 0) {
298377
- if (!defaultSerialization) continue;
298487
+ const decodablePathStyle = location2 === "path" && (style === "label" || style === "matrix") && !explode ? style : void 0;
298488
+ if (!defaultSerialization && !decodablePathStyle) continue;
298489
+ if (!defaultSerialization) warnings.push(...noteWarnings);
298378
298490
  const check2 = { in: location2, name, required: param.required === true, schema: scalarSchema };
298491
+ if (decodablePathStyle) check2.pathStyle = decodablePathStyle;
298379
298492
  if (location2 === "query" && param.allowEmptyValue === true) check2.allowEmptyValue = true;
298380
298493
  checks.push(check2);
298381
298494
  continue;
298382
298495
  }
298496
+ if (location2 === "query" && style === "deepObject" && explode) {
298497
+ const objectSchema = asRecord5(packed.schema);
298498
+ const properties = objectSchema ? asRecord5(objectSchema.properties) : null;
298499
+ const allScalar = properties !== null && Object.keys(properties).length > 0 && Object.values(properties).every((prop) => {
298500
+ const record = asRecord5(prop);
298501
+ if (!record) return false;
298502
+ const types2 = Array.isArray(record.type) ? record.type : [record.type];
298503
+ return types2.every((entry) => typeof entry === "string" && SCALAR_SCHEMA_TYPES.has(entry));
298504
+ });
298505
+ if (allScalar) {
298506
+ warnings.push(...noteWarnings);
298507
+ const check2 = { in: "query", name, required: param.required === true, schema: packed.schema, decode: "deepObject" };
298508
+ if (param.allowEmptyValue === true) check2.allowEmptyValue = true;
298509
+ checks.push(check2);
298510
+ continue;
298511
+ }
298512
+ }
298383
298513
  if (location2 !== "query" && location2 !== "header") continue;
298384
298514
  const items = packedArrayItemsSchema(packed);
298385
298515
  if (items === void 0) continue;
@@ -298690,6 +298820,185 @@ function responseHeaders(root, version2, response, context, warnings) {
298690
298820
  }
298691
298821
  return entries;
298692
298822
  }
298823
+ var IANA_HTTP_AUTH_SCHEMES = /* @__PURE__ */ new Set([
298824
+ "basic",
298825
+ "bearer",
298826
+ "concealed",
298827
+ "digest",
298828
+ "dpop",
298829
+ "gnap",
298830
+ "hoba",
298831
+ "mutual",
298832
+ "negotiate",
298833
+ "oauth",
298834
+ "privatetoken",
298835
+ "scram-sha-1",
298836
+ "scram-sha-256",
298837
+ "vapid"
298838
+ ]);
298839
+ function httpsUrlLint(value, label, schemeName) {
298840
+ if (typeof value !== "string" || !value) return void 0;
298841
+ try {
298842
+ const parsed = new URL(value);
298843
+ if (parsed.protocol !== "https:") return `CONTRACT_SECURITY_SCHEME_URL: security scheme ${schemeName} ${label} ${value} is not an HTTPS URL`;
298844
+ } catch {
298845
+ return `CONTRACT_SECURITY_SCHEME_URL: security scheme ${schemeName} ${label} ${value} is not a valid URL`;
298846
+ }
298847
+ return void 0;
298848
+ }
298849
+ function collectSecurityStaticLints(root, operation) {
298850
+ const securitySchemes = asRecord5(asRecord5(root.components)?.securitySchemes);
298851
+ const requirements = operation.security === void 0 ? asArray3(root.security) : asArray3(operation.security);
298852
+ const warnings = /* @__PURE__ */ new Set();
298853
+ for (const requirement of requirements.map((entry) => asRecord5(entry)).filter((entry) => Boolean(entry))) {
298854
+ for (const [schemeName, requiredScopes] of Object.entries(requirement)) {
298855
+ let scheme;
298856
+ try {
298857
+ scheme = resolveInternalRef(root, securitySchemes?.[schemeName]);
298858
+ } catch {
298859
+ scheme = null;
298860
+ }
298861
+ if (!scheme) continue;
298862
+ if (scheme.type === "http") {
298863
+ const httpScheme = String(scheme.scheme || "").toLowerCase();
298864
+ if (httpScheme && !IANA_HTTP_AUTH_SCHEMES.has(httpScheme)) {
298865
+ warnings.add(`CONTRACT_UNKNOWN_HTTP_AUTH_SCHEME: security scheme ${schemeName} uses "${httpScheme}", which is not in the IANA HTTP Authentication Scheme registry`);
298866
+ }
298867
+ }
298868
+ if (scheme.type === "apiKey" && String(scheme.in) === "query") {
298869
+ warnings.add(`CONTRACT_CREDENTIALS_IN_QUERY: security scheme ${schemeName} sends credentials in the query string, which leaks into logs and referrers`);
298870
+ }
298871
+ if (scheme.type === "openIdConnect") {
298872
+ const urlWarning = httpsUrlLint(scheme.openIdConnectUrl, "openIdConnectUrl", schemeName);
298873
+ if (urlWarning) warnings.add(urlWarning);
298874
+ else if (typeof scheme.openIdConnectUrl === "string" && !scheme.openIdConnectUrl.endsWith("/.well-known/openid-configuration")) {
298875
+ warnings.add(`CONTRACT_SECURITY_SCHEME_URL: security scheme ${schemeName} openIdConnectUrl does not end in /.well-known/openid-configuration`);
298876
+ }
298877
+ }
298878
+ if (scheme.type === "oauth2") {
298879
+ const flows = asRecord5(scheme.flows) ?? {};
298880
+ const declaredScopes = /* @__PURE__ */ new Set();
298881
+ for (const [flowName, rawFlow] of Object.entries(flows)) {
298882
+ const flow = asRecord5(rawFlow);
298883
+ if (!flow) continue;
298884
+ for (const scope of Object.keys(asRecord5(flow.scopes) ?? {})) declaredScopes.add(scope);
298885
+ const urlFields = [["refreshUrl", flow.refreshUrl]];
298886
+ if (flowName === "implicit" || flowName === "authorizationCode") urlFields.push(["authorizationUrl", flow.authorizationUrl]);
298887
+ if (flowName === "password" || flowName === "clientCredentials" || flowName === "authorizationCode") urlFields.push(["tokenUrl", flow.tokenUrl]);
298888
+ for (const [label, value] of urlFields) {
298889
+ const urlWarning = httpsUrlLint(value, `${flowName} ${label}`, schemeName);
298890
+ if (urlWarning) warnings.add(urlWarning);
298891
+ }
298892
+ }
298893
+ for (const scope of asArray3(requiredScopes).filter((entry) => typeof entry === "string")) {
298894
+ if (!declaredScopes.has(scope)) {
298895
+ warnings.add(`CONTRACT_OAUTH2_UNDECLARED_SCOPE: operation requires scope "${scope}" of ${schemeName}, which no flow of the scheme declares`);
298896
+ }
298897
+ }
298898
+ }
298899
+ }
298900
+ }
298901
+ return [...warnings];
298902
+ }
298903
+ function collectSecurityResponseLints(root, operation, responses, operationId) {
298904
+ const warnings = [];
298905
+ const requirements = operation.security === void 0 ? asArray3(root.security) : asArray3(operation.security);
298906
+ const requirementRecords = requirements.map((entry) => asRecord5(entry)).filter((entry) => Boolean(entry));
298907
+ const secured = requirementRecords.length > 0 && requirementRecords.every((entry) => Object.keys(entry).length > 0);
298908
+ const statusKeys = new Set(Object.keys(responses));
298909
+ const hasCatchAll = statusKeys.has("default") || statusKeys.has("4XX");
298910
+ if (secured && !statusKeys.has("401") && !hasCatchAll) {
298911
+ warnings.push(`CONTRACT_SECURITY_RESPONSES_INCOMPLETE: ${operationId} requires authentication but documents no 401 (or 4XX/default) response`);
298912
+ }
298913
+ const usesScopes = requirementRecords.some((entry) => Object.values(entry).some((scopes) => Array.isArray(scopes) && scopes.length > 0));
298914
+ if (secured && usesScopes && !statusKeys.has("403") && !hasCatchAll) {
298915
+ warnings.push(`CONTRACT_SECURITY_RESPONSES_INCOMPLETE: ${operationId} requires scopes but documents no 403 (or 4XX/default) response`);
298916
+ }
298917
+ if (requirementRecords.length === 0) {
298918
+ for (const status of ["401", "403"]) {
298919
+ if (statusKeys.has(status)) warnings.push(`CONTRACT_UNSECURED_AUTH_RESPONSES: ${operationId} documents a ${status} response but declares no security requirement`);
298920
+ }
298921
+ }
298922
+ return warnings;
298923
+ }
298924
+ function collectLinkExpressions(root, response, operationId, warnings) {
298925
+ const links = asRecord5(response.links);
298926
+ if (!links) return [];
298927
+ const expressions = [];
298928
+ let unevaluated = false;
298929
+ for (const [linkName, rawLink] of Object.entries(links)) {
298930
+ let link;
298931
+ try {
298932
+ link = resolveInternalRef(root, rawLink);
298933
+ } catch {
298934
+ link = null;
298935
+ }
298936
+ if (!link) {
298937
+ unevaluated = true;
298938
+ continue;
298939
+ }
298940
+ const values = Object.values(asRecord5(link.parameters) ?? {});
298941
+ if (link.requestBody !== void 0) values.push(link.requestBody);
298942
+ if (values.length === 0) unevaluated = true;
298943
+ for (const value of values) {
298944
+ if (typeof value !== "string" || !value.startsWith("$")) continue;
298945
+ const bodyMatch = value.match(/^\$response\.body#(\/.*)$/);
298946
+ if (bodyMatch) {
298947
+ expressions.push({ link: linkName, kind: "body", pointer: bodyMatch[1] });
298948
+ continue;
298949
+ }
298950
+ const headerMatch = value.match(/^\$response\.header\.([!#$%&'*+.^_`|~0-9A-Za-z-]+)$/);
298951
+ if (headerMatch) {
298952
+ expressions.push({ link: linkName, kind: "header", header: headerMatch[1] });
298953
+ continue;
298954
+ }
298955
+ unevaluated = true;
298956
+ }
298957
+ }
298958
+ if (expressions.length === 0) {
298959
+ if (unevaluated) warnings.add(`CONTRACT_LINKS_NOT_VALIDATED: response links are not validated for ${operationId}`);
298960
+ } else if (unevaluated) {
298961
+ warnings.add(`CONTRACT_LINKS_PARTIALLY_VALIDATED: some link expressions for ${operationId} are not runtime-evaluable and are skipped`);
298962
+ }
298963
+ return expressions;
298964
+ }
298965
+ function escapeRegExpLiteral(value) {
298966
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
298967
+ }
298968
+ function serverAdvisoryPatterns(root, pathItem, operation) {
298969
+ const serverLists = [asArray3(operation.servers), asArray3(pathItem.servers), asArray3(root.servers)];
298970
+ const servers = serverLists.find((list) => list.length > 0) ?? [];
298971
+ const patterns = [];
298972
+ for (const rawServer of servers) {
298973
+ const server = asRecord5(rawServer);
298974
+ if (!server) continue;
298975
+ const url = typeof server.url === "string" ? server.url.trim() : "";
298976
+ if (!url || url === "/") continue;
298977
+ const variables = asRecord5(server.variables);
298978
+ const pattern = url.split(/(\{[^}]+\})/).map((part) => {
298979
+ const varMatch = part.match(/^\{([^}]+)\}$/);
298980
+ if (!varMatch) return escapeRegExpLiteral(part);
298981
+ const variable = asRecord5(variables?.[varMatch[1]]);
298982
+ const enumValues = asArray3(variable?.enum).filter((entry) => typeof entry === "string");
298983
+ if (enumValues.length > 0) return `(${enumValues.map(escapeRegExpLiteral).join("|")})`;
298984
+ return "[^/]*";
298985
+ }).join("");
298986
+ patterns.push(`^${pattern}`);
298987
+ }
298988
+ return patterns.length > 0 ? patterns : void 0;
298989
+ }
298990
+ function validateParameterExamples(root, param, packed, context, warnings) {
298991
+ if (packed.schema === void 0 || packed.unsupported) return;
298992
+ const candidates = exampleCandidates(root, param);
298993
+ if (candidates.length === 0) return;
298994
+ const validate3 = compileSchemaValidator(packed.schema);
298995
+ if (!validate3) return;
298996
+ for (const candidate of candidates) {
298997
+ if (!validate3(candidate.value)) {
298998
+ warnings.push(`CONTRACT_EXAMPLE_SCHEMA_MISMATCH: ${candidate.label} for parameter ${context} does not match its schema`);
298999
+ }
299000
+ }
299001
+ }
298693
299002
  function buildContractIndex(root) {
298694
299003
  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)");
298695
299004
  if (!("openapi" in root)) throw new Error("CONTRACT_UNSUPPORTED_OPENAPI_VERSION: Dynamic contract tests require OpenAPI 3.0 or 3.1 (missing openapi)");
@@ -298708,6 +299017,9 @@ function buildContractIndex(root) {
298708
299017
  const operation = resolveInternalRef(root, rawOperation);
298709
299018
  if (!operation) continue;
298710
299019
  if (operation.callbacks) warnings.push(`CONTRACT_CALLBACKS_NOT_VALIDATED: callbacks are not validated for ${lowerMethod.toUpperCase()} ${path10}`);
299020
+ if (operation.requestBody !== void 0 && ["get", "head", "delete"].includes(lowerMethod)) {
299021
+ warnings.push(`CONTRACT_METHOD_BODY_SEMANTICS: ${lowerMethod.toUpperCase()} ${path10} declares a request body; RFC 9110 defines no request-body semantics for ${lowerMethod.toUpperCase()}`);
299022
+ }
298711
299023
  const responses = asRecord5(operation.responses);
298712
299024
  if (!responses || Object.keys(responses).length === 0) {
298713
299025
  throw new Error(`CONTRACT_OPERATION_NO_RESPONSES: ${lowerMethod.toUpperCase()} ${path10} must define at least one response`);
@@ -298717,11 +299029,15 @@ function buildContractIndex(root) {
298717
299029
  for (const [status, rawResponse] of Object.entries(responses)) {
298718
299030
  const response = resolveInternalRef(root, rawResponse);
298719
299031
  if (!response) continue;
298720
- if (asRecord5(response.links)) {
298721
- responseWarnings.add(`CONTRACT_LINKS_NOT_VALIDATED: response links are not validated for ${lowerMethod.toUpperCase()} ${path10}`);
299032
+ if (status !== "default" && !/^[1-5]XX$/.test(status) && !/^[1-5][0-9][0-9]$/.test(status)) {
299033
+ responseWarnings.add(`CONTRACT_INVALID_STATUS_CODE: ${lowerMethod.toUpperCase()} ${path10} declares response status "${status}" outside RFC 9110's 100-599, 1XX-5XX, or default forms`);
298722
299034
  }
299035
+ const linkExpressions = collectLinkExpressions(root, response, `${lowerMethod.toUpperCase()} ${path10}`, responseWarnings);
298723
299036
  const responseContext = `${lowerMethod.toUpperCase()} ${path10} status ${status}`;
298724
299037
  const content = responseContent(root, version2, response, responseContext, responseWarnings);
299038
+ if ((status === "204" || status === "205" || status === "304") && Object.keys(content).length > 0) {
299039
+ responseWarnings.add(`CONTRACT_BODYLESS_STATUS_WITH_CONTENT: ${lowerMethod.toUpperCase()} ${path10} declares content for status ${status}, which RFC 9110 forbids on the wire`);
299040
+ }
298725
299041
  for (const [contentType2, media] of Object.entries(content)) {
298726
299042
  const base = contentType2.toLowerCase().split(";")[0]?.trim() ?? "";
298727
299043
  const schemaType = asRecord5(media.schema)?.type;
@@ -298733,7 +299049,8 @@ function buildContractIndex(root) {
298733
299049
  contractResponses[normalizeResponseKey(status)] = {
298734
299050
  content,
298735
299051
  hasBody: Object.keys(content).length > 0,
298736
- headers
299052
+ headers,
299053
+ ...linkExpressions.length > 0 ? { links: linkExpressions } : {}
298737
299054
  };
298738
299055
  }
298739
299056
  const candidates = [...new Set([
@@ -298746,11 +299063,13 @@ function buildContractIndex(root) {
298746
299063
  opWarnings.push(...collectSecuritySchemeWarnings(root, operation));
298747
299064
  const parameterChecks = collectParameterChecks(root, pathItem, operation, version2, operationId, path10, opWarnings);
298748
299065
  const checkedKeys = new Set((parameterChecks ?? []).map((check) => `${check.in}:${check.name.toLowerCase()}`));
298749
- const decodedKeys = new Set((parameterChecks ?? []).filter((check) => check.decode).map((check) => `${check.in}:${check.name.toLowerCase()}`));
299066
+ const decodedKeys = new Set((parameterChecks ?? []).filter((check) => check.decode || check.pathStyle).map((check) => `${check.in}:${check.name.toLowerCase()}`));
298750
299067
  opWarnings.push(...collectSerializationWarnings(root, pathItem, operation, decodedKeys));
298751
299068
  if (operation.deprecated === true) {
298752
299069
  opWarnings.push(`CONTRACT_OPERATION_DEPRECATED: ${lowerMethod.toUpperCase()} ${path10} is marked deprecated in the OpenAPI document`);
298753
299070
  }
299071
+ opWarnings.push(...collectSecurityStaticLints(root, operation));
299072
+ opWarnings.push(...collectSecurityResponseLints(root, operation, responses, operationId));
298754
299073
  const requiredParameters = collectParameters(root, pathItem, operation);
298755
299074
  for (const parameter of requiredParameters.filter((entry) => entry.securityDerived)) {
298756
299075
  opWarnings.push(`CONTRACT_SECURITY_NOT_VALIDATED: security parameter ${parameter.in}:${parameter.name} is not statically required in generated requests`);
@@ -298779,6 +299098,9 @@ function buildContractIndex(root) {
298779
299098
  parameterChecks,
298780
299099
  requestBody: collectRequestBody(root, operation, version2, operationId, opWarnings),
298781
299100
  security: collectSecurityRuntimeChecks(root, operation),
299101
+ pathMethods: Object.keys(pathItem).filter((key) => HTTP_METHODS.has(key)).map((key) => key.toUpperCase()),
299102
+ deprecated: operation.deprecated === true || void 0,
299103
+ servers: serverAdvisoryPatterns(root, pathItem, operation),
298782
299104
  warnings: opWarnings
298783
299105
  });
298784
299106
  }
@@ -298955,7 +299277,7 @@ function buildValidatorAssignments(operation, warnings, skipped) {
298955
299277
  return lines;
298956
299278
  }
298957
299279
  function createContractScript(operation, warnings = []) {
298958
- const contract = { method: operation.method, path: operation.path, responses: operation.responses, security: operation.security, parameters: operation.parameterChecks };
299280
+ 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 };
298959
299281
  const skipped = [];
298960
299282
  const validatorLines = buildValidatorAssignments(operation, warnings, skipped);
298961
299283
  return [
@@ -299066,6 +299388,417 @@ function createContractScript(operation, warnings = []) {
299066
299388
  ' if (!isJsonSubtype(actual.subtype) && media.media.schema && media.media.schema.type !== "string") { return; }',
299067
299389
  ' if (!validate(value)) pm.expect.fail("OpenAPI schema validation failed for " + contract.method + " " + contract.path + " status " + pm.response.code + ": " + JSON.stringify(validate.errors || []));',
299068
299390
  "});",
299391
+ "pm.test('Response satisfies RFC 9110 status-code requirements', function () {",
299392
+ " var code = pm.response.code;",
299393
+ ' function respHeader(name) { return pm.response.headers.get(name) || ""; }',
299394
+ " if (code === 401) {",
299395
+ ' var challenge = respHeader("WWW-Authenticate");',
299396
+ ' if (!challenge) pm.expect.fail("RFC 9110 requires WWW-Authenticate on 401 responses");',
299397
+ ' var wantsBearer = (contract.security || []).some(function (alternative) { return alternative.some(function (check) { return check.prefix && check.prefix.toLowerCase().indexOf("bearer") === 0; }); });',
299398
+ ' 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);',
299399
+ ' 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);',
299400
+ ' 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);',
299401
+ " }",
299402
+ " if (code === 401 || code === 403) {",
299403
+ ' var authChallenge = respHeader("WWW-Authenticate");',
299404
+ ' var bearerError = authChallenge && /\\bbearer\\b/i.test(authChallenge) ? authChallenge.match(/\\berror\\s*=\\s*"?([A-Za-z0-9_]+)"?/i) : null;',
299405
+ ' 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]);',
299406
+ " }",
299407
+ " if (code === 405) {",
299408
+ ' var allow = respHeader("Allow");',
299409
+ ' if (!allow) pm.expect.fail("RFC 9110 requires Allow on 405 responses");',
299410
+ ' var allowed = allow.split(",").map(function (entry) { return entry.trim().toUpperCase(); });',
299411
+ ' (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); });',
299412
+ " }",
299413
+ ' if (code === 304 && responseText().trim().length > 0) pm.expect.fail("RFC 9110 forbids content in a 304 response");',
299414
+ ' var retryAfter = respHeader("Retry-After");',
299415
+ " if (retryAfter && (code === 429 || code === 503 || (code >= 300 && code < 400))) {",
299416
+ ' 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);',
299417
+ " }",
299418
+ ' var location = respHeader("Location");',
299419
+ " if (location && (code === 201 || (code >= 300 && code < 400))) {",
299420
+ ' if (/\\s/.test(location.trim()) || location.trim().length === 0) pm.expect.fail("Location must be a valid URI-reference (RFC 9110 / RFC 3986): " + location);',
299421
+ " }",
299422
+ "});",
299423
+ "pm.test('Error and encoding conventions match RFC 9457 / RFC 8259 / RFC 8288', function () {",
299424
+ ' var contentTypeRaw = pm.response.headers.get("Content-Type") || "";',
299425
+ " var ct = mediaParts(contentTypeRaw);",
299426
+ ' if (ct.type === "application" && ct.subtype === "problem+json") {',
299427
+ " var problem;",
299428
+ ' try { problem = pm.response.json(); } catch (error) { pm.expect.fail("application/problem+json body is not valid JSON (RFC 9457): " + error); }',
299429
+ ' if (!problem || typeof problem !== "object" || Array.isArray(problem)) pm.expect.fail("problem details must be a JSON object (RFC 9457)");',
299430
+ ' ["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]); });',
299431
+ ' ["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]); });',
299432
+ " if (problem.status !== undefined) {",
299433
+ ' if (typeof problem.status !== "number") pm.expect.fail("RFC 9457 status member must be a number; got " + typeof problem.status);',
299434
+ ' 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 + ")");',
299435
+ " }",
299436
+ " }",
299437
+ " if (isJsonSubtype(ct.subtype)) {",
299438
+ ' var charsetMatch = contentTypeRaw.match(/charset\\s*=\\s*"?([^";\\s]+)"?/i);',
299439
+ ' if (charsetMatch && charsetMatch[1].toLowerCase() !== "utf-8") pm.expect.fail("JSON interchange must be UTF-8 (RFC 8259); got charset=" + charsetMatch[1]);',
299440
+ " }",
299441
+ ' var link = pm.response.headers.get("Link");',
299442
+ " if (link) {",
299443
+ " link.split(/,(?=\\s*<)/).forEach(function (value) {",
299444
+ ' if (!/^\\s*<[^>]*>/.test(value)) pm.expect.fail("RFC 8288 link-value must start with a <URI-Reference>: " + value);',
299445
+ ' if (!/;\\s*rel\\s*=/i.test(value)) pm.expect.fail("RFC 8288 link-value must carry a rel parameter: " + value);',
299446
+ " });",
299447
+ " }",
299448
+ "});",
299449
+ "var rfcAdvisories = [];",
299450
+ "function rfcAdvise(message) { if (rfcAdvisories.indexOf(message) === -1) rfcAdvisories.push(message); }",
299451
+ 'function rfcRespHeader(name) { return pm.response.headers.get(name) || ""; }',
299452
+ "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; }",
299453
+ "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)); }",
299454
+ "function rfcIsToken(value) { return /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/.test(String(value)); }",
299455
+ 'function rfcIsEntityTag(value) { return /^(W\\/)?"[\\x21\\x23-\\x7e\\x80-\\xff]*"$/.test(String(value).trim()); }',
299456
+ "function rfcIsFieldContent(value) { return /^[\\t \\x21-\\x7e\\x80-\\xff]*$/.test(String(value)); }",
299457
+ '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; }',
299458
+ `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; }`,
299459
+ '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; }',
299460
+ "function rfcSfParse(input, kind) {",
299461
+ " var s = String(input), i = 0;",
299462
+ ' function ws() { while (i < s.length && (s.charAt(i) === " " || s.charAt(i) === "\\t")) i += 1; }',
299463
+ " 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); }",
299464
+ " function bareItem() {",
299465
+ " var ch = s.charAt(i);",
299466
+ ` 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; }`,
299467
+ ' 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; }',
299468
+ ' if (ch === "?") { i += 1; if (s.charAt(i) !== "0" && s.charAt(i) !== "1") return null; i += 1; return true; }',
299469
+ ' 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; }',
299470
+ ' 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; }',
299471
+ " if (/[A-Za-z*]/.test(ch)) { i += 1; while (i < s.length && /[!#$%&'*+.^_`|~:\\/0-9A-Za-z-]/.test(s.charAt(i))) i += 1; return true; }",
299472
+ " return null;",
299473
+ " }",
299474
+ ' 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; }',
299475
+ ' 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(); }',
299476
+ " ws();",
299477
+ ' if (kind === "item") { if (item() === null) return false; ws(); return i === s.length; }',
299478
+ " if (i === s.length) return true;",
299479
+ " while (i < s.length) {",
299480
+ ' 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; }',
299481
+ " else if (item() === null) return false;",
299482
+ " ws();",
299483
+ " if (i === s.length) return true;",
299484
+ ' if (s.charAt(i) !== ",") return false;',
299485
+ " i += 1; ws();",
299486
+ " if (i === s.length) return false;",
299487
+ " }",
299488
+ " return true;",
299489
+ "}",
299490
+ "pm.test('Response header fields satisfy RFC 9110 field syntax', function () {",
299491
+ " pm.response.headers.each(function (header) {",
299492
+ " if (!header) return;",
299493
+ ' if (!rfcIsToken(String(header.key))) pm.expect.fail("Response header name is not a valid RFC 9110 token: " + header.key);',
299494
+ ' if (!rfcIsFieldContent(String(header.value))) pm.expect.fail("Response header value contains characters forbidden by RFC 9110 field-content: " + header.key);',
299495
+ " });",
299496
+ ' ["content-type", "content-length", "etag", "location", "date", "age", "expires", "last-modified", "retry-after"].forEach(function (name) {',
299497
+ " var values = rfcHeaderAll(name);",
299498
+ ' 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)"); }',
299499
+ " });",
299500
+ "});",
299501
+ "pm.test('Response header values satisfy their RFC grammars', function () {",
299502
+ ' var date = rfcRespHeader("Date");',
299503
+ ' if (date && !rfcIsHttpDate(date)) pm.expect.fail("Date must be an IMF-fixdate (RFC 9110): " + date);',
299504
+ ' if (!date) rfcAdvise("RFC 9110: origin servers SHOULD send a Date header");',
299505
+ ' var etag = rfcRespHeader("ETag");',
299506
+ ' if (etag && !rfcIsEntityTag(etag)) pm.expect.fail("ETag is not a valid entity-tag (RFC 9110): " + etag);',
299507
+ ' var lastModified = rfcRespHeader("Last-Modified");',
299508
+ " if (lastModified) {",
299509
+ ' if (!rfcIsHttpDate(lastModified)) pm.expect.fail("Last-Modified must be a valid HTTP-date (RFC 9110): " + lastModified);',
299510
+ ' 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);',
299511
+ " }",
299512
+ ' var vary = rfcRespHeader("Vary");',
299513
+ " if (vary) {",
299514
+ ' var varyMembers = vary.split(",").map(function (entry) { return entry.trim(); });',
299515
+ ' if (varyMembers.indexOf("*") !== -1 && varyMembers.length > 1) pm.expect.fail("Vary: * must not be combined with other members (RFC 9110): " + vary);',
299516
+ ' varyMembers.forEach(function (member) { if (member !== "*" && !rfcIsToken(member)) pm.expect.fail("Vary member is not a field-name token (RFC 9110): " + member); });',
299517
+ " }",
299518
+ ' var contentLocation = rfcRespHeader("Content-Location");',
299519
+ ' if (contentLocation && (/\\s/.test(contentLocation.trim()) || contentLocation.trim().length === 0)) pm.expect.fail("Content-Location must be a valid URI-reference (RFC 9110): " + contentLocation);',
299520
+ ' var acceptRanges = rfcRespHeader("Accept-Ranges");',
299521
+ ' if (acceptRanges && !rfcTokenList(acceptRanges)) pm.expect.fail("Accept-Ranges must be a list of range-unit tokens (RFC 9110): " + acceptRanges);',
299522
+ ' var contentLanguage = rfcRespHeader("Content-Language");',
299523
+ ' 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()); });',
299524
+ ' var allow = rfcRespHeader("Allow");',
299525
+ ' if (allow && allow.trim() && !rfcTokenList(allow)) pm.expect.fail("Allow must be a comma-separated list of method tokens (RFC 9110): " + allow);',
299526
+ ' if (allow && contract.method === "OPTIONS" && pm.response.code >= 200 && pm.response.code < 300) {',
299527
+ ' var optionsAllowed = allow.split(",").map(function (entry) { return entry.trim().toUpperCase(); });',
299528
+ ' (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); });',
299529
+ " }",
299530
+ ' var age = rfcRespHeader("Age");',
299531
+ ' if (age && !/^[0-9]+$/.test(age.trim())) pm.expect.fail("Age must be a non-negative integer of delta-seconds (RFC 9111): " + age);',
299532
+ ' var expires = rfcRespHeader("Expires");',
299533
+ ' if (expires && !rfcIsHttpDate(expires)) rfcAdvise("RFC 9111: Expires is not a valid HTTP-date and will be treated as already expired: " + expires);',
299534
+ ' if (rfcHeaderAll("warning").length > 0) rfcAdvise("RFC 9111 obsoleted the Warning header; the server still emits it");',
299535
+ ' var cacheControl = rfcRespHeader("Cache-Control");',
299536
+ " if (cacheControl) {",
299537
+ " var seenDirectives = {};",
299538
+ " rfcSplitList(cacheControl).forEach(function (entry) {",
299539
+ " var directive = entry.trim();",
299540
+ ' if (!directive) { pm.expect.fail("Cache-Control contains an empty directive (RFC 9111): " + cacheControl); return; }',
299541
+ ' var eq = directive.indexOf("=");',
299542
+ " var name = (eq === -1 ? directive : directive.slice(0, eq)).trim().toLowerCase();",
299543
+ " var argument = eq === -1 ? undefined : directive.slice(eq + 1).trim();",
299544
+ ' if (!rfcIsToken(name)) pm.expect.fail("Cache-Control directive name is not a token (RFC 9111): " + directive);',
299545
+ " seenDirectives[name] = argument === undefined ? true : argument;",
299546
+ ' 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);',
299547
+ " });",
299548
+ ' 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);',
299549
+ " }",
299550
+ ' var acceptPatch = rfcRespHeader("Accept-Patch");',
299551
+ ' 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()); });',
299552
+ ' var deprecation = rfcRespHeader("Deprecation");',
299553
+ ' if (deprecation && !/^@-?[0-9]+$/.test(deprecation.trim())) pm.expect.fail("Deprecation must be an RFC 9745 Date structured field (@unix-timestamp): " + deprecation);',
299554
+ ' var sunset = rfcRespHeader("Sunset");',
299555
+ " if (sunset) {",
299556
+ ' if (!rfcIsHttpDate(sunset)) pm.expect.fail("Sunset must be a valid HTTP-date (RFC 8594): " + sunset);',
299557
+ ' else if (Date.parse(sunset) < Date.now()) rfcAdvise("RFC 8594: Sunset date is already in the past: " + sunset);',
299558
+ " }",
299559
+ ' var preferenceApplied = rfcRespHeader("Preference-Applied");',
299560
+ " if (preferenceApplied) {",
299561
+ ' var requestPrefer = requestHeader("Prefer").toLowerCase();',
299562
+ " rfcSplitList(preferenceApplied).forEach(function (entry) {",
299563
+ ' var token = entry.split("=")[0].trim().toLowerCase();',
299564
+ ' if (token && requestPrefer.indexOf(token) === -1) pm.expect.fail("Preference-Applied echoes a preference the request never sent (RFC 7240): " + entry.trim());',
299565
+ " });",
299566
+ " }",
299567
+ "});",
299568
+ "pm.test('Response satisfies RFC 9110 message framing requirements', function () {",
299569
+ " var code = pm.response.code;",
299570
+ ' if ((code === 204 || code < 200) && rfcRespHeader("Content-Length")) pm.expect.fail("RFC 9110 forbids Content-Length on 1xx and 204 responses");',
299571
+ ' if ([301, 302, 303, 307, 308].indexOf(code) !== -1 && !rfcRespHeader("Location")) pm.expect.fail("RFC 9110 expects Location on a " + code + " redirect response");',
299572
+ " if (code === 416) {",
299573
+ ' var unsatisfiedRange = rfcRespHeader("Content-Range");',
299574
+ ' if (!unsatisfiedRange) pm.expect.fail("RFC 9110 requires Content-Range (unsatisfied-range form) on 416 responses");',
299575
+ ' 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);',
299576
+ " }",
299577
+ " if (code === 206) {",
299578
+ ' var contentRange = rfcRespHeader("Content-Range");',
299579
+ ' var responseMedia = mediaParts(rfcRespHeader("Content-Type"));',
299580
+ ' var isByteranges = responseMedia.type === "multipart" && responseMedia.subtype === "byteranges";',
299581
+ ' if (!contentRange && !isByteranges) pm.expect.fail("RFC 9110 requires Content-Range on a single-part 206 response (or multipart/byteranges for multi-range)");',
299582
+ ' if (contentRange && isByteranges) pm.expect.fail("RFC 9110 forbids Content-Range on a multipart/byteranges 206 response");',
299583
+ " if (contentRange) {",
299584
+ " var rangeParts = contentRange.trim().match(/^(\\S+) (?:([0-9]+)-([0-9]+)|\\*)\\/([0-9]+|\\*)$/);",
299585
+ ' if (!rangeParts) pm.expect.fail("Content-Range is not a valid RFC 9110 range: " + contentRange);',
299586
+ " else {",
299587
+ ' if (rangeParts[1] !== "bytes") rfcAdvise("RFC 9110: 206 Content-Range uses a non-bytes range unit: " + rangeParts[1]);',
299588
+ " if (rangeParts[2] !== undefined) {",
299589
+ ' if (Number(rangeParts[2]) > Number(rangeParts[3])) pm.expect.fail("Content-Range first-byte-pos must be <= last-byte-pos (RFC 9110): " + contentRange);',
299590
+ ' if (rangeParts[4] !== "*" && Number(rangeParts[3]) >= Number(rangeParts[4])) pm.expect.fail("Content-Range last-byte-pos must be < complete-length (RFC 9110): " + contentRange);',
299591
+ " }",
299592
+ " }",
299593
+ " }",
299594
+ " }",
299595
+ ' if (code === 407 && !rfcRespHeader("Proxy-Authenticate")) pm.expect.fail("RFC 9110 requires Proxy-Authenticate on 407 responses");',
299596
+ ' if (code === 415 && contract.method === "PATCH" && !rfcRespHeader("Accept-Patch")) rfcAdvise("RFC 5789: a 415 response to PATCH SHOULD carry Accept-Patch");',
299597
+ "});",
299598
+ "pm.test('Response media type is acceptable under the request Accept header', function () {",
299599
+ " if (pm.response.code < 200 || pm.response.code >= 300 || isBodyless()) return;",
299600
+ ' var accept = requestHeader("Accept");',
299601
+ ' if (!accept || accept.indexOf("{{") !== -1) return;',
299602
+ ' var actual = mediaParts(rfcRespHeader("Content-Type"));',
299603
+ " if (!actual.type) return;",
299604
+ " var acceptable = false;",
299605
+ " var jsonSoftened = false;",
299606
+ " rfcSplitList(accept).forEach(function (entry) {",
299607
+ " var range = mediaParts(entry);",
299608
+ ' var qMatch = entry.match(/;\\s*q\\s*=\\s*"?([0-9.]+)"?/i);',
299609
+ " if (qMatch && Number(qMatch[1]) <= 0) return;",
299610
+ ' if ((range.type === "*" && range.subtype === "*") || (range.type === actual.type && (range.subtype === "*" || range.subtype === actual.subtype))) acceptable = true;',
299611
+ ' if (range.type === actual.type && range.subtype === "json" && isJsonSubtype(actual.subtype)) jsonSoftened = true;',
299612
+ " });",
299613
+ ' if (!acceptable && jsonSoftened) { rfcAdvise("Content negotiation: response " + actual.raw + " is a +json type while the request only accepted application/json"); return; }',
299614
+ ' if (!acceptable) pm.expect.fail("Response Content-Type " + actual.raw + " is not acceptable under the request Accept header (RFC 9110): " + accept);',
299615
+ "});",
299616
+ "pm.test('Response body satisfies its media type RFC conventions', function () {",
299617
+ ' var contentTypeValue = rfcRespHeader("Content-Type");',
299618
+ " var media = mediaParts(contentTypeValue);",
299619
+ " var text = responseText();",
299620
+ ' if (pm.response.code === 406 && !text.trim()) rfcAdvise("RFC 9110: a 406 response SHOULD include a list of available representations");',
299621
+ " if (!text) return;",
299622
+ " if (isJsonSubtype(media.subtype)) {",
299623
+ ' if (text.charCodeAt(0) === 65279) pm.expect.fail("RFC 8259 forbids a byte order mark at the start of JSON text");',
299624
+ ' var charsetParam = contentTypeValue.match(/charset\\s*=\\s*"?([^";\\s]+)"?/i);',
299625
+ ' if (charsetParam) rfcAdvise("RFC 8259 defines no charset parameter for JSON media types; got charset=" + charsetParam[1]);',
299626
+ " }",
299627
+ ' if (media.raw === "application/x-ndjson" || media.raw === "application/jsonl" || media.raw === "application/x-jsonlines") {',
299628
+ ' 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); } });',
299629
+ " }",
299630
+ ' if (media.raw === "text/event-stream") {',
299631
+ ' 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); });',
299632
+ " }",
299633
+ ' if (media.type === "multipart") {',
299634
+ ' var boundary = contentTypeValue.match(/;\\s*boundary=(?:"([^"]*)"|([^;]*))/i);',
299635
+ ' var boundaryValue = boundary ? (boundary[1] !== undefined ? boundary[1] : boundary[2].trim()) : "";',
299636
+ ' if (!boundaryValue) pm.expect.fail("multipart responses must carry a boundary parameter (RFC 2046): " + contentTypeValue);',
299637
+ " else {",
299638
+ ' if (boundaryValue.length > 70) pm.expect.fail("multipart boundary must be 1-70 characters (RFC 2046): " + boundaryValue);',
299639
+ ` 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);`,
299640
+ " }",
299641
+ " }",
299642
+ ' if (media.raw === "application/hal+json") {',
299643
+ " var hal; try { hal = JSON.parse(text); } catch (error) { hal = null; }",
299644
+ ' if (hal && typeof hal === "object" && !Array.isArray(hal)) {',
299645
+ " var halLinks = hal._links;",
299646
+ ' if (halLinks !== undefined && (typeof halLinks !== "object" || Array.isArray(halLinks) || halLinks === null)) pm.expect.fail("HAL _links must be an object of link relations");',
299647
+ ' 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"); }); });',
299648
+ " var halEmbedded = hal._embedded;",
299649
+ ' if (halEmbedded !== undefined && (typeof halEmbedded !== "object" || Array.isArray(halEmbedded) || halEmbedded === null)) pm.expect.fail("HAL _embedded must be an object of resource names");',
299650
+ " }",
299651
+ " }",
299652
+ ' if (media.raw === "application/vnd.api+json") {',
299653
+ " var jsonApi; try { jsonApi = JSON.parse(text); } catch (error) { jsonApi = null; }",
299654
+ ' if (jsonApi && typeof jsonApi === "object" && !Array.isArray(jsonApi)) {',
299655
+ ' 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");',
299656
+ ' if (jsonApi.data !== undefined && jsonApi.errors !== undefined) pm.expect.fail("JSON:API forbids data and errors in the same document");',
299657
+ " }",
299658
+ " }",
299659
+ ' if (media.subtype === "problem+xml") {',
299660
+ ' if (text.indexOf("urn:ietf:rfc:7807") === -1) rfcAdvise("application/problem+xml body does not reference the urn:ietf:rfc:7807 namespace");',
299661
+ " var xmlStatus = text.match(/<status[^>]*>\\s*([0-9]+)\\s*<\\/status>/);",
299662
+ ' 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 + ")");',
299663
+ " }",
299664
+ "});",
299665
+ "pm.test('Structured field response headers parse per RFC 8941', function () {",
299666
+ ' [["Cache-Status", "list"], ["Proxy-Status", "list"], ["Priority", "dict"], ["RateLimit", "dict"], ["RateLimit-Policy", "dict"], ["Signature", "dict"], ["Signature-Input", "dict"]].forEach(function (pair) {',
299667
+ ' var value = rfcHeaderAll(pair[0]).join(", ");',
299668
+ " if (!value) return;",
299669
+ ' if (!rfcSfParse(value, pair[1])) pm.expect.fail(pair[0] + " is not a valid RFC 8941 structured field (" + pair[1] + "): " + value);',
299670
+ " });",
299671
+ "});",
299672
+ "pm.test('Content-Digest and Repr-Digest match the response body (RFC 9530)', function () {",
299673
+ " var cryptoLib = null;",
299674
+ ' try { cryptoLib = require("crypto-js"); } catch (error) { cryptoLib = null; }',
299675
+ ' ["Content-Digest", "Repr-Digest"].forEach(function (name) {',
299676
+ " var value = rfcRespHeader(name);",
299677
+ " if (!value) return;",
299678
+ ' if (!rfcSfParse(value, "dict")) { pm.expect.fail(name + " is not a valid RFC 8941 dictionary (RFC 9530): " + value); return; }',
299679
+ ' if (!cryptoLib || rfcRespHeader("Content-Encoding")) return;',
299680
+ ' var media = mediaParts(rfcRespHeader("Content-Type"));',
299681
+ ' if (media.type !== "text" && !isJsonSubtype(media.subtype) && !/xml$/.test(media.subtype)) return;',
299682
+ " rfcSplitList(value).forEach(function (entry) {",
299683
+ " var match = entry.trim().match(/^(sha-256|sha-512)=:([A-Za-z0-9+\\/=]+):$/);",
299684
+ " if (!match) return;",
299685
+ ' var computed = match[1] === "sha-256" ? cryptoLib.SHA256(responseText()) : cryptoLib.SHA512(responseText());',
299686
+ " var encoded = cryptoLib.enc.Base64.stringify(computed);",
299687
+ ' 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]);',
299688
+ " });",
299689
+ " });",
299690
+ "});",
299691
+ "pm.test('Request credentials are well-formed per their authentication scheme RFCs', function () {",
299692
+ ' var authorization = requestHeader("Authorization");',
299693
+ ' if (authorization && authorization.indexOf("{{") === -1) {',
299694
+ " var schemeMatch = authorization.match(/^(\\S+)(?:\\s+([\\s\\S]*))?$/);",
299695
+ ' var authScheme = schemeMatch ? schemeMatch[1].toLowerCase() : "";',
299696
+ ' var authParams = schemeMatch && schemeMatch[2] !== undefined ? schemeMatch[2].trim() : "";',
299697
+ ' if (authScheme === "basic") {',
299698
+ " var decoded = rfcBase64Decode(authParams);",
299699
+ ' if (decoded === null) pm.expect.fail("Basic credentials must be base64 (RFC 7617)");',
299700
+ ' else if (decoded.indexOf(":") === -1) pm.expect.fail("Basic credentials must decode to user-id:password (RFC 7617)");',
299701
+ " }",
299702
+ ' if (authScheme === "bearer" && !/^[A-Za-z0-9\\-._~+\\/]+=*$/.test(authParams)) pm.expect.fail("Bearer token does not match the b64token grammar (RFC 6750)");',
299703
+ ' if (authScheme === "digest") {',
299704
+ ' 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); });',
299705
+ ' var digestResponse = authParams.match(/\\bresponse\\s*=\\s*"?([^",\\s]+)"?/i);',
299706
+ ' if (digestResponse && !/^[0-9a-fA-F]+$/.test(digestResponse[1])) pm.expect.fail("Digest response parameter must be hex (RFC 7616): " + digestResponse[1]);',
299707
+ " }",
299708
+ " }",
299709
+ ' var wantsJwt = (contract.security || []).some(function (alternative) { return alternative.some(function (check) { return check.prefix === "Bearer " && String(check.bearerFormat || "").toUpperCase() === "JWT"; }); });',
299710
+ ' if (wantsJwt && authorization && authorization.indexOf("{{") === -1 && authorization.toLowerCase().indexOf("bearer ") === 0) {',
299711
+ " var jwtToken = authorization.slice(7).trim();",
299712
+ ' var jwtSegments = jwtToken.split(".");',
299713
+ ' if (jwtSegments.length !== 3) pm.expect.fail("bearerFormat JWT tokens must have three base64url segments (RFC 7519); got " + jwtSegments.length);',
299714
+ ' else if (!jwtSegments.every(function (segment) { return /^[A-Za-z0-9_-]+$/.test(segment); })) pm.expect.fail("JWT segments must be base64url (RFC 7515)");',
299715
+ " else {",
299716
+ ' var jwtDecode = function (segment) { var padded = segment.replace(/-/g, "+").replace(/_/g, "/"); while (padded.length % 4 !== 0) padded += "="; return rfcBase64Decode(padded); };',
299717
+ " var jwtHeader = null; var jwtPayload = null;",
299718
+ ' try { jwtHeader = JSON.parse(jwtDecode(jwtSegments[0])); } catch (error) { pm.expect.fail("JWT header segment does not decode to JSON (RFC 7515)"); }',
299719
+ ' try { jwtPayload = JSON.parse(jwtDecode(jwtSegments[1])); } catch (error) { pm.expect.fail("JWT payload segment does not decode to JSON (RFC 7519)"); }',
299720
+ ' if (jwtHeader && typeof jwtHeader.alg !== "string") pm.expect.fail("JWT header must carry a string alg member (RFC 7515)");',
299721
+ " if (jwtPayload) {",
299722
+ ' ["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)"); });',
299723
+ ' if (typeof jwtPayload.exp === "number" && jwtPayload.exp * 1000 < Date.now()) rfcAdvise("RFC 7519: the outgoing JWT exp claim is already in the past");',
299724
+ " }",
299725
+ " }",
299726
+ " }",
299727
+ ' if (hasQueryParam("access_token")) rfcAdvise("RFC 6750: bearer tokens SHOULD NOT travel in the query string");',
299728
+ " (contract.security || []).forEach(function (alternative) {",
299729
+ " alternative.forEach(function (check) {",
299730
+ " if (!check.checkable || !check.name) return;",
299731
+ ' if (check.in === "query") { if (hasQueryParam(check.name)) rfcAdvise("Security scheme " + check.scheme + " sends credentials in the query string"); return; }',
299732
+ ' if (check.in !== "header" || String(check.name).toLowerCase() === "authorization") return;',
299733
+ " var apiKeyValue = requestHeader(check.name);",
299734
+ ' if (!apiKeyValue || apiKeyValue.indexOf("{{") !== -1) return;',
299735
+ ' if (apiKeyValue !== apiKeyValue.trim()) pm.expect.fail("API key header " + check.name + " carries leading or trailing whitespace");',
299736
+ ' if (!rfcIsFieldContent(apiKeyValue)) pm.expect.fail("API key header " + check.name + " contains characters forbidden by RFC 9110 field-content");',
299737
+ " });",
299738
+ " });",
299739
+ "});",
299740
+ "pm.test('Request preconditions, preferences, and patch bodies follow their RFCs', function () {",
299741
+ ' ["If-Match", "If-None-Match"].forEach(function (name) {',
299742
+ " var value = requestHeader(name);",
299743
+ ' if (!value || value.indexOf("{{") !== -1 || value.trim() === "*") return;',
299744
+ ' 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()); });',
299745
+ " });",
299746
+ ' var prefer = requestHeader("Prefer");',
299747
+ ' if (prefer && prefer.indexOf("{{") === -1) {',
299748
+ ' 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()); });',
299749
+ " }",
299750
+ ' var requestContentType = mediaBase(requestHeader("Content-Type"));',
299751
+ " var body = pm.request.body;",
299752
+ ' var raw = body && body.mode === "raw" && typeof body.raw === "string" ? body.raw : "";',
299753
+ ' if (!raw.trim() || raw.indexOf("{{") !== -1 || /"<[^"<>]*>"/.test(raw)) return;',
299754
+ ' if (requestContentType === "application/json-patch+json") {',
299755
+ ' 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; }',
299756
+ ' if (!Array.isArray(patch)) { pm.expect.fail("A JSON Patch document must be an array of operations (RFC 6902)"); return; }',
299757
+ " patch.forEach(function (operation, operationIndex) {",
299758
+ ' if (!operation || typeof operation !== "object" || Array.isArray(operation)) { pm.expect.fail("JSON Patch operation " + operationIndex + " must be an object (RFC 6902)"); return; }',
299759
+ ' 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);',
299760
+ " var pointerPattern = /^(\\/([^\\/~]|~[01])*)*$/;",
299761
+ ' if (typeof operation.path !== "string" || !pointerPattern.test(operation.path)) pm.expect.fail("JSON Patch operation " + operationIndex + " path must be an RFC 6901 JSON Pointer");',
299762
+ ' 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)");',
299763
+ ' 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)");',
299764
+ " });",
299765
+ " }",
299766
+ ' if (requestContentType === "application/merge-patch+json") {',
299767
+ ' 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); }',
299768
+ " }",
299769
+ "});",
299770
+ "pm.test('Deprecated operation signals deprecation in the response', function () {",
299771
+ " if (!contract.deprecated) return;",
299772
+ ' if (!rfcRespHeader("Deprecation") && !rfcRespHeader("Sunset")) rfcAdvise("RFC 9745: the OpenAPI document deprecates this operation but the response carries neither Deprecation nor Sunset");',
299773
+ "});",
299774
+ "pm.test('OpenAPI link expressions resolve against the response', function () {",
299775
+ " if (!selected || !selected.value.links || selected.value.links.length === 0) return;",
299776
+ " var linkBody = null; var linkBodyParsed = false;",
299777
+ " selected.value.links.forEach(function (expression) {",
299778
+ ' if (expression.kind === "header") {',
299779
+ ' if (!pm.response.headers.get(expression.header)) pm.expect.fail("OpenAPI link " + expression.link + " references response header " + expression.header + " which is absent");',
299780
+ " return;",
299781
+ " }",
299782
+ " if (!linkBodyParsed) { linkBodyParsed = true; try { linkBody = JSON.parse(responseText()); } catch (error) { linkBody = null; } }",
299783
+ ' if (linkBody === null) { pm.expect.fail("OpenAPI link " + expression.link + " references the response body but the body is not JSON"); return; }',
299784
+ " var target = linkBody;",
299785
+ ' var tokens = String(expression.pointer).split("/").slice(1).map(function (token) { return token.replace(/~1/g, "/").replace(/~0/g, "~"); });',
299786
+ " for (var t = 0; t < tokens.length; t += 1) {",
299787
+ ' if (target !== null && typeof target === "object") target = Array.isArray(target) ? target[Number(tokens[t])] : target[tokens[t]];',
299788
+ " else { target = undefined; break; }",
299789
+ " }",
299790
+ ' if (target === undefined) pm.expect.fail("OpenAPI link " + expression.link + " expression $response.body#" + expression.pointer + " does not resolve in the response body");',
299791
+ " });",
299792
+ "});",
299793
+ "pm.test('Request URL conforms to an OpenAPI servers entry', function () {",
299794
+ " if (!contract.servers || contract.servers.length === 0) return;",
299795
+ ' var requestUrl = "";',
299796
+ ' try { requestUrl = String(pm.request.url.toString()); } catch (ignored) { requestUrl = ""; }',
299797
+ ' if (!requestUrl || requestUrl.indexOf("{{") !== -1) return;',
299798
+ ' var pathOnly = requestUrl.replace(/^[a-z][a-z0-9+.-]*:\\/\\/[^\\/]+/i, "");',
299799
+ ' 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; } });',
299800
+ ' if (!matched) rfcAdvise("Request URL does not match any OpenAPI servers entry: " + requestUrl);',
299801
+ "});",
299069
299802
  ...operation.security ? [
299070
299803
  "pm.test('Request carries credentials required by OpenAPI security', function () {",
299071
299804
  " function satisfied(check) {",
@@ -299105,6 +299838,12 @@ function createContractScript(operation, warnings = []) {
299105
299838
  ' if (param.allowEmptyValue && entries.length === 1 && entries[0] === "") return;',
299106
299839
  " if (entries.some(isPlaceholder)) return;",
299107
299840
  " value = entries.map(function (entry) { return coerceBySchema(decodeComponent(entry), param.items); });",
299841
+ ' } else if (param.decode === "deepObject") {',
299842
+ " var deepValue = {}; var deepFound = false; var deepPlaceholder = false;",
299843
+ ' 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]]) || {}); });',
299844
+ ' if (!deepFound) { if (param.required) pm.expect.fail("Required parameter " + param.in + ":" + param.name + " was not sent for " + contract.method + " " + contract.path); return; }',
299845
+ " if (deepPlaceholder) return;",
299846
+ " value = deepValue;",
299108
299847
  " } else if (param.decode) {",
299109
299848
  ' var joined = param.in === "query" ? queryValue(String(param.name).toLowerCase()) : headerValue(param.name);',
299110
299849
  ' if (joined === undefined) { if (param.required) pm.expect.fail("Required parameter " + param.in + ":" + param.name + " was not sent for " + contract.method + " " + contract.path); return; }',
@@ -299121,6 +299860,8 @@ function createContractScript(operation, warnings = []) {
299121
299860
  ' } else if (param.in === "path") {',
299122
299861
  " value = pathParamValue(param.name);",
299123
299862
  " if (value === undefined) return;",
299863
+ ' if (param.pathStyle === "label") { if (String(value).charAt(0) !== ".") return; value = String(value).slice(1); }',
299864
+ ' if (param.pathStyle === "matrix") { var matrixPrefix = ";" + param.name + "="; if (String(value).indexOf(matrixPrefix) !== 0) return; value = String(value).slice(matrixPrefix.length); }',
299124
299865
  ' if (isPlaceholder(value) || value.charAt(0) === ":" || value.charAt(0) === "{") return;',
299125
299866
  " value = coerceBySchema(value, param.schema);",
299126
299867
  ' } else if (param.in === "cookie") {',
@@ -299172,6 +299913,9 @@ function createContractScript(operation, warnings = []) {
299172
299913
  ' if (pm.response.headers.get("Content-Encoding")) return;',
299173
299914
  " var mustBeEmpty = isBodyless() || (selected && Object.keys(selected.value.content || {}).length === 0);",
299174
299915
  ' 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);',
299916
+ "});",
299917
+ "pm.test('RFC SHOULD-level advisories are documented', function () {",
299918
+ ' pm.expect(rfcAdvisories, "SHOULD-level findings (advisory, non-failing): " + rfcAdvisories.join("; ")).to.be.an("array");',
299175
299919
  "});"
299176
299920
  ];
299177
299921
  }
@@ -299241,6 +299985,9 @@ function assertStaticRequestShape(operation, request) {
299241
299985
  }
299242
299986
  }
299243
299987
  const warnings = collectStaticBodyWarnings(operation, request, contentType2);
299988
+ if (["GET", "HEAD", "DELETE"].includes(operation.method) && hasRequestBody(request)) {
299989
+ 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`);
299990
+ }
299244
299991
  if (operation.requestBody && !operation.requestBody.required && operation.requestBody.contentTypes.length > 0 && hasRequestBody(request) && contentType2) {
299245
299992
  const actual = contentType2.toLowerCase().split(";")[0]?.trim() ?? "";
299246
299993
  const matches = operation.requestBody.contentTypes.some((expected) => mediaTypeMatchesPattern(expected.toLowerCase(), actual));
@@ -299495,6 +300242,15 @@ function asRecord7(value) {
299495
300242
  }
299496
300243
  return value;
299497
300244
  }
300245
+ function adviseWorkspaceFlipForbidden(error2) {
300246
+ if (error2 instanceof HttpError && error2.status === 403) {
300247
+ const body = error2.responseBody || "";
300248
+ if (/addWorkspaceLevelTeamRoles/i.test(body) || /You are not authorized to perform this action/i.test(body)) {
300249
+ return new Error(WORKSPACE_PERSONAL_ONLY_ADVICE, { cause: error2 });
300250
+ }
300251
+ }
300252
+ return error2;
300253
+ }
299498
300254
  function extractGitRepoUrl(value) {
299499
300255
  if (!value) return null;
299500
300256
  if (typeof value === "string") {
@@ -299800,7 +300556,7 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
299800
300556
  }
299801
300557
  } catch (error2) {
299802
300558
  await this.deleteWorkspace(workspaceId).catch(() => void 0);
299803
- throw error2;
300559
+ throw adviseWorkspaceFlipForbidden(error2);
299804
300560
  }
299805
300561
  return { id: workspaceId };
299806
300562
  }
@@ -301057,7 +301813,7 @@ function resolveActionVersion(explicit) {
301057
301813
  if (explicit) {
301058
301814
  return explicit;
301059
301815
  }
301060
- return "2.1.2" ? "2.1.2" : "unknown";
301816
+ return typeof __ACTION_VERSION__ !== "undefined" && __ACTION_VERSION__ ? __ACTION_VERSION__ : "unknown";
301061
301817
  }
301062
301818
  function telemetryDisabled(env) {
301063
301819
  const flag = String(env.POSTMAN_ACTIONS_TELEMETRY ?? "").trim().toLowerCase();
@@ -301179,11 +301935,23 @@ function createTelemetryContext(options) {
301179
301935
  };
301180
301936
  }
301181
301937
 
301182
- // src/lib/spec/openapi-loader.ts
301938
+ // src/action-version.ts
301183
301939
  var import_node_fs3 = require("node:fs");
301940
+ var import_node_path3 = require("node:path");
301941
+ function resolveActionVersion2() {
301942
+ try {
301943
+ const raw = (0, import_node_fs3.readFileSync)((0, import_node_path3.join)(__dirname, "..", "package.json"), "utf8");
301944
+ return JSON.parse(raw).version ?? "unknown";
301945
+ } catch {
301946
+ return "unknown";
301947
+ }
301948
+ }
301949
+
301950
+ // src/lib/spec/openapi-loader.ts
301951
+ var import_node_fs4 = require("node:fs");
301184
301952
  var import_promises3 = require("node:fs/promises");
301185
301953
  var import_node_url2 = require("node:url");
301186
- var import_node_path3 = __toESM(require("node:path"), 1);
301954
+ var import_node_path4 = __toESM(require("node:path"), 1);
301187
301955
 
301188
301956
  // node_modules/@apidevtools/json-schema-ref-parser/dist/lib/util/convert-path-to-posix.js
301189
301957
  var win32Sep = "\\";
@@ -301524,14 +302292,14 @@ function fromFileSystemPath(path10) {
301524
302292
  const hasProjectUri = upperPath.includes(posixUpper);
301525
302293
  const isAbsolutePath = isAbsoluteWin32Path.test(path10) || path10.startsWith("http://") || path10.startsWith("https://") || path10.startsWith("file://");
301526
302294
  if (!(hasProjectDir || hasProjectUri || isAbsolutePath) && !projectDir.startsWith("http")) {
301527
- const join3 = (a, b) => {
302295
+ const join4 = (a, b) => {
301528
302296
  if (a.endsWith("/") || a.endsWith("\\")) {
301529
302297
  return a + b;
301530
302298
  } else {
301531
302299
  return a + "/" + b;
301532
302300
  }
301533
302301
  };
301534
- path10 = join3(projectDir, path10);
302302
+ path10 = join4(projectDir, path10);
301535
302303
  }
301536
302304
  path10 = convertPathToPosix(path10);
301537
302305
  }
@@ -305646,6 +306414,7 @@ function inventory$Ref($refParent, $refKey, path10, scopeBase, dynamicIdScope, p
305646
306414
  const file = stripHash(pointer.path);
305647
306415
  const hash = getHash(pointer.path);
305648
306416
  const external = file !== $refs._root$Ref.path && !$refs._aliases[file];
306417
+ const nestedResource = Boolean($refs._aliases[file]) && pointer.$ref.value !== $refs._root$Ref.value;
305649
306418
  const extended = ref_default.isExtended$Ref($ref);
305650
306419
  indirections += pointer.indirections;
305651
306420
  const existingEntry = findInInventory(inventory, $refParent, $refKey);
@@ -305679,6 +306448,8 @@ function inventory$Ref($refParent, $refKey, path10, scopeBase, dynamicIdScope, p
305679
306448
  // Does this $ref extend its resolved value? (i.e. it has extra properties, in addition to "$ref")
305680
306449
  external,
305681
306450
  // Does this $ref pointer point to a file other than the main JSON Schema file?
306451
+ nestedResource,
306452
+ // Does this $ref resolve to an embedded schema resource with its own $id?
305682
306453
  indirections
305683
306454
  // The number of indirect references that were traversed to resolve the value
305684
306455
  });
@@ -305714,7 +306485,7 @@ function remap(inventory, options, rootId) {
305714
306485
  for (const entry of inventory) {
305715
306486
  const bundleOpts = options.bundle || {};
305716
306487
  if (!entry.external) {
305717
- if (bundleOpts.optimizeInternalRefs !== false) {
306488
+ if (bundleOpts.optimizeInternalRefs !== false && !entry.nestedResource) {
305718
306489
  entry.$ref.$ref = entry.hash;
305719
306490
  }
305720
306491
  } else if (entry.file === file && entry.hash === hash) {
@@ -313518,22 +314289,22 @@ async function loadOpenApiContractSpec(specUrl, options = {}) {
313518
314289
  async function loadOpenApiContractSpecFromPath(specPath, options = {}) {
313519
314290
  if (!specPath) throw new Error("CONTRACT_SPEC_READ_FAILED: spec-path must not be empty");
313520
314291
  const workspaceRoot = (() => {
313521
- const root = import_node_path3.default.resolve(process.env.GITHUB_WORKSPACE ?? process.cwd());
314292
+ const root = import_node_path4.default.resolve(process.env.GITHUB_WORKSPACE ?? process.cwd());
313522
314293
  try {
313523
- return (0, import_node_fs3.realpathSync)(root);
314294
+ return (0, import_node_fs4.realpathSync)(root);
313524
314295
  } catch {
313525
314296
  return root;
313526
314297
  }
313527
314298
  })();
313528
- const resolved = import_node_path3.default.resolve(workspaceRoot, specPath);
314299
+ const resolved = import_node_path4.default.resolve(workspaceRoot, specPath);
313529
314300
  let absolutePath;
313530
314301
  try {
313531
- absolutePath = (0, import_node_fs3.realpathSync)(resolved);
314302
+ absolutePath = (0, import_node_fs4.realpathSync)(resolved);
313532
314303
  } catch (error2) {
313533
314304
  throw new Error(`CONTRACT_SPEC_READ_FAILED: Unable to read spec at ${specPath}`, { cause: error2 });
313534
314305
  }
313535
- const rel = import_node_path3.default.relative(workspaceRoot, absolutePath);
313536
- if (!rel || rel.startsWith("..") || import_node_path3.default.isAbsolute(rel)) {
314306
+ const rel = import_node_path4.default.relative(workspaceRoot, absolutePath);
314307
+ if (!rel || rel.startsWith("..") || import_node_path4.default.isAbsolute(rel)) {
313537
314308
  throw new Error(`CONTRACT_SPEC_READ_FAILED: spec-path must resolve inside ${workspaceRoot}, got: ${specPath}`);
313538
314309
  }
313539
314310
  const maxBytes = options.maxBytesPerResource ?? SAFE_FETCH_LIMITS.maxBytesPerResource;
@@ -313947,6 +314718,17 @@ function buildOperationScript(operation, index, warnings) {
313947
314718
  ' pm.expect(pm.response.code, "GraphQL responses are HTTP 200 even when the data field carries errors").to.be.below(500);',
313948
314719
  "});"
313949
314720
  );
314721
+ lines.push(
314722
+ "pm.test(" + JSON.stringify("[" + label + "] GraphQL-over-HTTP media type and status are consistent") + ", function () {",
314723
+ ' var contentType = ((pm.response.headers && pm.response.headers.get && pm.response.headers.get("Content-Type")) || "").toLowerCase();',
314724
+ ' var mediaType = contentType.split(";")[0].trim();',
314725
+ " if (!mediaType) return;",
314726
+ ' 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>")); }',
314727
+ " var wellFormed = gqlBody.data !== undefined || Array.isArray(gqlBody.errors);",
314728
+ ' 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"); }',
314729
+ ' 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); }',
314730
+ "});"
314731
+ );
313950
314732
  lines.push(
313951
314733
  `pm.test(${JSON.stringify(`[${label}] GraphQL errors are well-formed and not a total failure`)}, function () {`,
313952
314734
  " var errors = gqlBody.errors;",
@@ -315487,6 +316269,8 @@ function createSoapScript(operation, warnings = []) {
315487
316269
  hasOutput: Boolean(operation.output)
315488
316270
  };
315489
316271
  const responseRegex = operation.expectedResponseElement ? elementPresenceRegex(operation.expectedResponseElement) : "";
316272
+ const mediaType = operation.soapVersion === "1.2" ? "application/soap+xml" : "text/xml";
316273
+ 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);';
315490
316274
  const lines = [
315491
316275
  `var soap = JSON.parse(${JSON.stringify(JSON.stringify(meta))});`,
315492
316276
  'var bodyText = (pm.response.text && pm.response.text()) || "";',
@@ -315497,9 +316281,11 @@ function createSoapScript(operation, warnings = []) {
315497
316281
  " pm.response.to.have.status(200);",
315498
316282
  "});",
315499
316283
  "",
315500
- "pm.test('SOAP response Content-Type is XML', function () {",
316284
+ // SOAP 1.1 responses bind to text/xml (SOAP 1.1 HTTP binding, WS-I Basic
316285
+ // Profile); SOAP 1.2 responses bind to application/soap+xml (RFC 3902).
316286
+ `pm.test('SOAP response Content-Type matches the SOAP ${operation.soapVersion} binding', function () {`,
315501
316287
  ' var ct = header("Content-Type").toLowerCase();',
315502
- ' pm.expect(ct, "expected an XML SOAP content-type, got: " + ct).to.match(/(?:text\\/xml|application\\/soap\\+xml|application\\/xml|\\+xml)/);',
316288
+ ` pm.expect(ct, "SOAP ${operation.soapVersion} responses use ${mediaType} (got: " + (ct || "<missing>") + ")").to.include("${mediaType}");`,
315503
316289
  "});",
315504
316290
  "",
315505
316291
  "pm.test('SOAP Envelope element is present', function () {",
@@ -315516,6 +316302,13 @@ function createSoapScript(operation, warnings = []) {
315516
316302
  ' var detail = (bodyText.match(/<(?:[A-Za-z_][\\w.-]*:)?(?:faultstring|Reason|Text)[^>]*>([\\s\\S]*?)<\\//) || [])[1] || "";',
315517
316303
  ' pm.expect.fail("SOAP Fault returned for operation " + soap.name + (detail ? (": " + detail.trim()) : ""));',
315518
316304
  " }",
316305
+ "});",
316306
+ "",
316307
+ "pm.test('SOAP Fault and HTTP status are consistent', function () {",
316308
+ ' var faulted = matchTag("Fault").test(bodyText);',
316309
+ " var code = pm.response.code;",
316310
+ faultStatusLine,
316311
+ ' if (!faulted && code === 500) pm.expect.fail("HTTP 500 from a SOAP endpoint must carry a SOAP Fault in the body");',
315519
316312
  "});"
315520
316313
  ];
315521
316314
  if (responseRegex) {
@@ -316767,6 +317560,7 @@ function normalizeSpecDocument(raw, warn) {
316767
317560
  async function runBootstrap(inputs, dependencies) {
316768
317561
  const telemetry = createTelemetryContext({
316769
317562
  action: "postman-bootstrap-action",
317563
+ actionVersion: resolveActionVersion2(),
316770
317564
  logger: dependencies.core
316771
317565
  });
316772
317566
  try {
@@ -317173,7 +317967,7 @@ async function runBootstrapInner(inputs, dependencies, telemetry) {
317173
317967
  async () => {
317174
317968
  if (inputs.specPath) {
317175
317969
  const workspaceRoot = path9.resolve(process.env.GITHUB_WORKSPACE ?? process.cwd());
317176
- return (0, import_node_fs4.readFileSync)(path9.resolve(workspaceRoot, inputs.specPath), "utf8");
317970
+ return (0, import_node_fs5.readFileSync)(path9.resolve(workspaceRoot, inputs.specPath), "utf8");
317177
317971
  }
317178
317972
  if (dependencies.specFetcher === fetch) {
317179
317973
  return safeFetchText(inputs.specUrl, { depth: 0 });