@postman-cs/onboarding-repo-sync 2.10.7 → 2.10.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.cjs CHANGED
@@ -109084,7 +109084,7 @@ var import_node_child_process = require("node:child_process");
109084
109084
  var import_node_fs7 = require("node:fs");
109085
109085
  var import_promises = require("node:fs/promises");
109086
109086
  var import_node_path4 = __toESM(require("node:path"), 1);
109087
- var import_node_util = require("node:util");
109087
+ var import_node_util2 = require("node:util");
109088
109088
 
109089
109089
  // node_modules/@actions/http-client/lib/index.js
109090
109090
  var tunnel = __toESM(require_tunnel2(), 1);
@@ -119743,6 +119743,9 @@ var PostmanAssetsClient = class {
119743
119743
  }
119744
119744
  };
119745
119745
 
119746
+ // src/lib/postman/postman-gateway-assets-client.ts
119747
+ var import_node_util = require("node:util");
119748
+
119746
119749
  // node_modules/acorn/dist/acorn.mjs
119747
119750
  var astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 574, 3, 9, 9, 7, 9, 32, 4, 318, 1, 78, 5, 71, 10, 50, 3, 123, 2, 54, 14, 32, 10, 3, 1, 11, 3, 46, 10, 8, 0, 46, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 2, 11, 83, 11, 7, 0, 3, 0, 158, 11, 6, 9, 7, 3, 56, 1, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 68, 8, 2, 0, 3, 0, 2, 3, 2, 4, 2, 0, 15, 1, 83, 17, 10, 9, 5, 0, 82, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 7, 19, 58, 14, 5, 9, 243, 14, 166, 9, 71, 5, 2, 1, 3, 3, 2, 0, 2, 1, 13, 9, 120, 6, 3, 6, 4, 0, 29, 9, 41, 6, 2, 3, 9, 0, 10, 10, 47, 15, 199, 7, 137, 9, 54, 7, 2, 7, 17, 9, 57, 21, 2, 13, 123, 5, 4, 0, 2, 1, 2, 6, 2, 0, 9, 9, 49, 4, 2, 1, 2, 4, 9, 9, 55, 9, 266, 3, 10, 1, 2, 0, 49, 6, 4, 4, 14, 10, 5350, 0, 7, 14, 11465, 27, 2343, 9, 87, 9, 39, 4, 60, 6, 26, 9, 535, 9, 470, 0, 2, 54, 8, 3, 82, 0, 12, 1, 19628, 1, 4178, 9, 519, 45, 3, 22, 543, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 101, 0, 161, 6, 10, 9, 357, 0, 62, 13, 499, 13, 245, 1, 2, 9, 233, 0, 3, 0, 8, 1, 6, 0, 475, 6, 110, 6, 6, 9, 4759, 9, 787719, 239];
119748
119751
  var astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 14, 29, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 13, 10, 2, 14, 2, 6, 2, 1, 2, 10, 2, 14, 2, 6, 2, 1, 4, 51, 13, 310, 10, 21, 11, 7, 25, 5, 2, 41, 2, 8, 70, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 66, 18, 2, 1, 11, 21, 11, 25, 7, 25, 39, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 28, 43, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 56, 50, 14, 50, 14, 35, 39, 27, 10, 22, 251, 41, 7, 1, 17, 5, 57, 28, 11, 0, 9, 21, 43, 17, 47, 20, 28, 22, 13, 52, 58, 1, 3, 0, 14, 44, 33, 24, 27, 35, 30, 0, 3, 0, 9, 34, 4, 0, 13, 47, 15, 3, 22, 0, 2, 0, 36, 17, 2, 24, 20, 1, 64, 6, 2, 0, 2, 3, 2, 14, 2, 9, 8, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 19, 0, 13, 4, 31, 9, 2, 0, 3, 0, 2, 37, 2, 0, 26, 0, 2, 0, 45, 52, 19, 3, 21, 2, 31, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 14, 0, 72, 26, 38, 6, 186, 43, 117, 63, 32, 7, 3, 0, 3, 7, 2, 1, 2, 23, 16, 0, 2, 0, 95, 7, 3, 38, 17, 0, 2, 0, 29, 0, 11, 39, 8, 0, 22, 0, 12, 45, 20, 0, 19, 72, 200, 32, 32, 8, 2, 36, 18, 0, 50, 29, 113, 6, 2, 1, 2, 37, 22, 0, 26, 5, 2, 1, 2, 31, 15, 0, 24, 43, 261, 18, 16, 0, 2, 12, 2, 33, 125, 0, 80, 921, 103, 110, 18, 195, 2637, 96, 16, 1071, 18, 5, 26, 3994, 6, 582, 6842, 29, 1763, 568, 8, 30, 18, 78, 18, 29, 19, 47, 17, 3, 32, 20, 6, 18, 433, 44, 212, 63, 33, 24, 3, 24, 45, 74, 6, 0, 67, 12, 65, 1, 2, 0, 15, 4, 10, 7381, 42, 31, 98, 114, 8702, 3, 2, 6, 2, 1, 2, 290, 16, 0, 30, 2, 3, 0, 15, 3, 9, 395, 2309, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 1845, 30, 7, 5, 262, 61, 147, 44, 11, 6, 17, 0, 322, 29, 19, 43, 485, 27, 229, 29, 3, 0, 208, 30, 2, 2, 2, 1, 2, 6, 3, 4, 10, 1, 225, 6, 2, 3, 2, 1, 2, 14, 2, 196, 60, 67, 8, 0, 1205, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42719, 33, 4381, 3, 5773, 3, 7472, 16, 621, 2467, 541, 1507, 4938, 6, 8489];
@@ -126345,79 +126348,160 @@ var PostmanGatewayAssetsClient = class {
126345
126348
  isAmbiguousTransportError(error) {
126346
126349
  return this.isRetryableIdempotentWriteOutcome(error);
126347
126350
  }
126348
- normalizeCollectionScripts(scripts) {
126349
- if (!Array.isArray(scripts)) return [];
126350
- return scripts.map((entry) => this.asRecord(entry)).filter((entry) => entry !== null);
126351
+ isRootPatchSnapshotConflict(error) {
126352
+ return error instanceof HttpError && [400, 409, 412].includes(error.status);
126353
+ }
126354
+ normalizeCollectionScripts(scripts, operation) {
126355
+ if (scripts === void 0 || scripts === null) return [];
126356
+ if (!Array.isArray(scripts)) {
126357
+ throw new Error(
126358
+ `PRIVATE_MOCK_AUTH_ROOT_INVALID: ${operation} returned a non-array scripts field.`
126359
+ );
126360
+ }
126361
+ const normalized = scripts.map((entry) => this.asRecord(entry));
126362
+ if (normalized.some((entry) => entry === null)) {
126363
+ throw new Error(
126364
+ `PRIVATE_MOCK_AUTH_ROOT_INVALID: ${operation} returned a non-object script entry.`
126365
+ );
126366
+ }
126367
+ return normalized;
126351
126368
  }
126352
126369
  rootScriptsIncludeManagedAuthHook(scripts) {
126353
126370
  return scripts.some((script) => isManagedPrivateMockAuthRootHook(script));
126354
126371
  }
126355
- buildPrivateMockRootScripts(existingScripts) {
126356
- const managedScript = {
126357
- type: PRIVATE_MOCK_AUTH_ROOT_TYPE,
126358
- code: PRIVATE_MOCK_AUTH_ROOT_SCRIPT,
126359
- language: "text/javascript"
126360
- };
126361
- return [...existingScripts, managedScript];
126372
+ expectedPrivateMockRootScripts(existingScripts) {
126373
+ return [
126374
+ ...existingScripts,
126375
+ {
126376
+ type: PRIVATE_MOCK_AUTH_ROOT_TYPE,
126377
+ code: PRIVATE_MOCK_AUTH_ROOT_SCRIPT,
126378
+ language: "text/javascript"
126379
+ }
126380
+ ];
126381
+ }
126382
+ assertAtMostOneManagedRootHook(scripts, operation) {
126383
+ const count = scripts.filter((script) => isManagedPrivateMockAuthRootHook(script)).length;
126384
+ if (count > 1) {
126385
+ throw new Error(
126386
+ `PRIVATE_MOCK_AUTH_ROOT_DUPLICATE: ${operation} contains ${count} exact managed hooks.`
126387
+ );
126388
+ }
126362
126389
  }
126363
126390
  async readCollectionRootScripts(collectionUid) {
126364
126391
  const id = this.requireCollectionPublicUid(collectionUid);
126365
- const response = await this.gateway.requestJson({
126366
- service: "collection",
126367
- method: "get",
126368
- path: `/v3/collections/${id}/export`
126369
- });
126392
+ const response = await this.gateway.requestJson(
126393
+ {
126394
+ service: "collection",
126395
+ method: "get",
126396
+ path: `/v3/collections/${id}`
126397
+ },
126398
+ // Root reconciliation is evidence, not a transient-success mechanism.
126399
+ // One response must prove the current state; never hide a 5xx by retrying.
126400
+ { retryTransient: false }
126401
+ );
126370
126402
  const data2 = this.asRecord(response?.data);
126371
- const collection = this.asRecord(data2?.collection);
126372
- if (!collection) {
126403
+ if (!data2) {
126373
126404
  throw new Error(
126374
- `PRIVATE_MOCK_AUTH_EXPORT_INVALID: Collection ${id} export did not return data.collection; refusing to configure private-mock root auth from an unexpected envelope.`
126405
+ `PRIVATE_MOCK_AUTH_ROOT_INVALID: Collection ${id} root read did not return data; refusing to configure private-mock root auth from an unexpected envelope.`
126375
126406
  );
126376
126407
  }
126377
- return this.normalizeCollectionScripts(collection.scripts);
126408
+ return this.normalizeCollectionScripts(data2.scripts, `Collection ${id} root read`);
126378
126409
  }
126379
- async patchCollectionRootScripts(collectionUid, scripts) {
126410
+ async patchCollectionRootScripts(collectionUid, existingScripts) {
126380
126411
  const id = this.requireCollectionPublicUid(collectionUid);
126381
- await this.gateway.requestJson(
126412
+ const expectedScripts = this.expectedPrivateMockRootScripts(existingScripts);
126413
+ const managedScript = expectedScripts.at(-1);
126414
+ const response = await this.gateway.requestJson(
126382
126415
  {
126383
126416
  service: "collection",
126384
126417
  method: "patch",
126385
126418
  path: `/v3/collections/${id}`,
126386
- body: [{ op: "add", path: "/scripts", value: scripts }]
126419
+ // Bootstrap creates these HTTP collections through Sync. Its current
126420
+ // collection-service wire projection materializes absent/null scripts
126421
+ // as `[]` before applying RFC 6902, so this pair is one atomic
126422
+ // compare-and-append. If that contract ever changes, `test` fails and
126423
+ // the append cannot overwrite or manufacture a scripts field.
126424
+ body: [
126425
+ { op: "test", path: "/scripts", value: existingScripts },
126426
+ { op: "add", path: "/scripts/-", value: managedScript }
126427
+ ]
126387
126428
  },
126388
126429
  { retryTransient: false }
126389
126430
  );
126431
+ const data2 = this.asRecord(response?.data);
126432
+ if (!data2) {
126433
+ throw new Error(
126434
+ `PRIVATE_MOCK_AUTH_ROOT_PATCH_INVALID: Collection ${id} root patch did not return data.`
126435
+ );
126436
+ }
126437
+ const scripts = this.normalizeCollectionScripts(data2.scripts, `Collection ${id} root patch`);
126438
+ if (!(0, import_node_util.isDeepStrictEqual)(scripts, expectedScripts)) {
126439
+ throw new Error(
126440
+ `PRIVATE_MOCK_AUTH_ROOT_PATCH_UNVERIFIED: Collection ${id} root patch response did not exactly preserve the prior scripts and append one managed hook.`
126441
+ );
126442
+ }
126443
+ return scripts;
126390
126444
  }
126391
126445
  /**
126392
126446
  * Add a secret-free runtime hook at the collection root. The PMAK value is
126393
126447
  * supplied only by the runner as a transient variable; this method persists
126394
126448
  * the variable name and header wiring, never the credential.
126395
126449
  */
126396
- async configurePrivateMockRuntimeAuth(collectionUid) {
126450
+ async configurePrivateMockRuntimeAuth(collectionUid, trustedRootScripts) {
126397
126451
  const cid = this.requireCollectionPublicUid(collectionUid);
126398
- const installFromFreshRoot = async (existingScripts) => {
126452
+ const installFromRootSnapshot = async (existingScripts) => {
126453
+ this.assertAtMostOneManagedRootHook(existingScripts, `Collection ${cid} root snapshot`);
126399
126454
  if (this.rootScriptsIncludeManagedAuthHook(existingScripts)) {
126400
126455
  return 0;
126401
126456
  }
126402
- const nextScripts = this.buildPrivateMockRootScripts(existingScripts);
126457
+ const expectedScripts = this.expectedPrivateMockRootScripts(existingScripts);
126403
126458
  try {
126404
- await this.patchCollectionRootScripts(cid, nextScripts);
126459
+ await this.patchCollectionRootScripts(cid, existingScripts);
126405
126460
  return 1;
126406
126461
  } catch (error) {
126462
+ if (this.isRootPatchSnapshotConflict(error)) {
126463
+ const currentScripts = await this.readCollectionRootScripts(cid);
126464
+ if ((0, import_node_util.isDeepStrictEqual)(currentScripts, expectedScripts)) {
126465
+ return 0;
126466
+ }
126467
+ throw error;
126468
+ }
126407
126469
  if (!this.isAmbiguousTransportError(error)) {
126408
126470
  throw error;
126409
126471
  }
126410
126472
  const freshScripts = await this.readCollectionRootScripts(cid);
126411
- if (this.rootScriptsIncludeManagedAuthHook(freshScripts)) {
126473
+ if ((0, import_node_util.isDeepStrictEqual)(freshScripts, expectedScripts)) {
126412
126474
  return 1;
126413
126475
  }
126414
- const recomputed = this.buildPrivateMockRootScripts(freshScripts);
126415
- await this.patchCollectionRootScripts(cid, recomputed);
126416
- return 1;
126476
+ if (!(0, import_node_util.isDeepStrictEqual)(freshScripts, existingScripts)) {
126477
+ throw new Error(
126478
+ `PRIVATE_MOCK_AUTH_ROOT_RECONCILE_DIVERGED: Collection ${cid} root scripts changed while reconciling an ambiguous patch.`,
126479
+ { cause: error }
126480
+ );
126481
+ }
126482
+ try {
126483
+ await this.patchCollectionRootScripts(cid, existingScripts);
126484
+ return 1;
126485
+ } catch (resendError) {
126486
+ if (!this.isAmbiguousTransportError(resendError)) {
126487
+ throw resendError;
126488
+ }
126489
+ const finalScripts = await this.readCollectionRootScripts(cid);
126490
+ if ((0, import_node_util.isDeepStrictEqual)(finalScripts, expectedScripts)) {
126491
+ return 1;
126492
+ }
126493
+ if (!(0, import_node_util.isDeepStrictEqual)(finalScripts, existingScripts)) {
126494
+ throw new Error(
126495
+ `PRIVATE_MOCK_AUTH_ROOT_RECONCILE_DIVERGED: Collection ${cid} root scripts changed after the ambiguous patch resend.`,
126496
+ { cause: resendError }
126497
+ );
126498
+ }
126499
+ throw resendError;
126500
+ }
126417
126501
  }
126418
126502
  };
126419
- const scripts = await this.readCollectionRootScripts(cid);
126420
- return installFromFreshRoot(scripts);
126503
+ const scripts = trustedRootScripts === void 0 ? await this.readCollectionRootScripts(cid) : this.normalizeCollectionScripts(trustedRootScripts, `Trusted collection ${cid} root`);
126504
+ return installFromRootSnapshot(scripts);
126421
126505
  }
126422
126506
  async listMocks() {
126423
126507
  const response = await this.gateway.requestJson({
@@ -126755,6 +126839,45 @@ function cloneCollection(collection) {
126755
126839
  return cloneCollectionNodeIterative(collection);
126756
126840
  }
126757
126841
  }
126842
+ function cleanManagedItemAuthScriptsInPlace(item, stripManagedBlocks) {
126843
+ if (!stripManagedBlocks) {
126844
+ return 0;
126845
+ }
126846
+ const scripts = item.scripts;
126847
+ if (!Array.isArray(scripts)) {
126848
+ return 0;
126849
+ }
126850
+ let strippedBlocks = 0;
126851
+ const nextScripts = [];
126852
+ for (const script of scripts) {
126853
+ if (!script || typeof script !== "object" || Array.isArray(script)) {
126854
+ nextScripts.push(script);
126855
+ continue;
126856
+ }
126857
+ const record = script;
126858
+ if (String(record.type ?? "") !== "beforeRequest") {
126859
+ nextScripts.push(record);
126860
+ continue;
126861
+ }
126862
+ const originalCode = String(record.code ?? "");
126863
+ const cleaned = stripManagedItemAuthBlocks(originalCode);
126864
+ if (cleaned === originalCode) {
126865
+ nextScripts.push(record);
126866
+ continue;
126867
+ }
126868
+ strippedBlocks += countManagedItemAuthBlocks(originalCode);
126869
+ if (!cleaned) {
126870
+ continue;
126871
+ }
126872
+ nextScripts.push({ ...record, code: cleaned });
126873
+ }
126874
+ if (nextScripts.length === 0) {
126875
+ delete item.scripts;
126876
+ } else {
126877
+ item.scripts = nextScripts;
126878
+ }
126879
+ return strippedBlocks;
126880
+ }
126758
126881
  function isPrivateMockLegacyExportCleanupEnabled() {
126759
126882
  const value = String(process.env.POSTMAN_PRIVATE_MOCK_LEGACY_EXPORT_CLEANUP ?? "").trim().toLowerCase();
126760
126883
  return value !== "off";
@@ -126763,52 +126886,23 @@ function verifyPrivateMockRootHook(collection) {
126763
126886
  const scripts = asArray2(collection.scripts);
126764
126887
  return scripts.some((script) => isManagedPrivateMockAuthRootHook(script));
126765
126888
  }
126889
+ function applyPrivateMockArtifactNodeCleanup(node, options = {}) {
126890
+ const stripManagedBlocks = options.stripManagedBlocks ?? isPrivateMockLegacyExportCleanupEnabled();
126891
+ const cloned = cloneCollection(node);
126892
+ return {
126893
+ node: cloned,
126894
+ strippedBlocks: cleanManagedItemAuthScriptsInPlace(cloned, stripManagedBlocks)
126895
+ };
126896
+ }
126766
126897
  function applyPrivateMockExportCleanup(collection, options = {}) {
126767
126898
  const stripManagedBlocks = options.stripManagedBlocks ?? isPrivateMockLegacyExportCleanupEnabled();
126768
126899
  const cloned = cloneCollection(collection);
126769
126900
  let strippedBlocks = 0;
126770
- const visitItem = (item) => {
126771
- if (!stripManagedBlocks) {
126772
- return;
126773
- }
126774
- const scripts = item.scripts;
126775
- if (!Array.isArray(scripts)) {
126776
- return;
126777
- }
126778
- const nextScripts = [];
126779
- for (const script of scripts) {
126780
- if (!script || typeof script !== "object" || Array.isArray(script)) {
126781
- nextScripts.push(script);
126782
- continue;
126783
- }
126784
- const record = script;
126785
- if (String(record.type ?? "") !== "beforeRequest") {
126786
- nextScripts.push(record);
126787
- continue;
126788
- }
126789
- const originalCode = String(record.code ?? "");
126790
- const cleaned = stripManagedItemAuthBlocks(originalCode);
126791
- if (cleaned === originalCode) {
126792
- nextScripts.push(record);
126793
- continue;
126794
- }
126795
- strippedBlocks += countManagedItemAuthBlocks(originalCode);
126796
- if (!cleaned) {
126797
- continue;
126798
- }
126799
- nextScripts.push({ ...record, code: cleaned });
126800
- }
126801
- if (nextScripts.length === 0) {
126802
- delete item.scripts;
126803
- } else {
126804
- item.scripts = nextScripts;
126805
- }
126806
- };
126807
126901
  const walkItemsIteratively = (rootItems) => {
126808
126902
  const stack = [...rootItems].reverse();
126809
126903
  while (stack.length > 0) {
126810
126904
  const item = stack.pop();
126811
- visitItem(item);
126905
+ strippedBlocks += cleanManagedItemAuthScriptsInPlace(item, stripManagedBlocks);
126812
126906
  for (const key of ["items", "children"]) {
126813
126907
  const nested = asArray2(item[key]);
126814
126908
  for (let i3 = nested.length - 1; i3 >= 0; i3 -= 1) {
@@ -128780,7 +128874,7 @@ function validateCanonicalV3CollectionFile(relative3, bytes) {
128780
128874
  );
128781
128875
  }
128782
128876
  }
128783
- async function digestAndValidatePrebuiltCollectionTree(files) {
128877
+ async function digestAndValidatePrebuiltCollectionTree(files, onFile) {
128784
128878
  if (!files.some((file) => file.relative === ".resources/definition.yaml")) {
128785
128879
  failPrebuiltCollections("prebuilt collection tree is missing .resources/definition.yaml");
128786
128880
  }
@@ -128808,6 +128902,7 @@ async function digestAndValidatePrebuiltCollectionTree(files) {
128808
128902
  );
128809
128903
  }
128810
128904
  validateCanonicalV3CollectionFile(file.relative, bytes);
128905
+ onFile?.(file, bytes);
128811
128906
  }
128812
128907
  return hash.digest("hex");
128813
128908
  }
@@ -128855,6 +128950,147 @@ function tryReusePrebuiltCollection(options) {
128855
128950
  }
128856
128951
  return prepared.artifactDigest === entry.artifactDigest;
128857
128952
  }
128953
+ function normalizeTrustedPrivateMockRootScripts(value, role) {
128954
+ if (value === void 0 || value === null) {
128955
+ return [];
128956
+ }
128957
+ if (!Array.isArray(value) || value.some((entry) => !isPlainObject2(entry))) {
128958
+ failPrebuiltCollections(
128959
+ `prebuilt ${role} collection root scripts must be an array of mappings`
128960
+ );
128961
+ }
128962
+ return value.map((entry) => ({ ...entry }));
128963
+ }
128964
+ function serializePrivateMockArtifactNode(node) {
128965
+ return Buffer.from(dump(node, {
128966
+ lineWidth: -1,
128967
+ noRefs: true,
128968
+ sortKeys: false
128969
+ }));
128970
+ }
128971
+ async function planPrivateMockPrebuiltArtifact(options) {
128972
+ const { role, collectionId, expectedPath, artifactDir, prepared } = options;
128973
+ if (!prepared || !tryReusePrebuiltCollection({
128974
+ prepared,
128975
+ expectedPath,
128976
+ expectedCloudId: collectionId
128977
+ })) {
128978
+ return void 0;
128979
+ }
128980
+ const files = listPrebuiltCollectionTreeFiles(prepared.confinedPath, artifactDir);
128981
+ const updates = [];
128982
+ let rootScripts;
128983
+ const stripManagedBlocks = isPrivateMockLegacyExportCleanupEnabled();
128984
+ const currentDigest = await digestAndValidatePrebuiltCollectionTree(files, (file, original) => {
128985
+ let parsed;
128986
+ try {
128987
+ parsed = load(original.toString("utf8"));
128988
+ } catch (error) {
128989
+ failPrebuiltCollections(
128990
+ `prebuilt ${role} collection changed to malformed YAML at ${file.relative} (${error instanceof Error ? error.message : String(error)})`
128991
+ );
128992
+ }
128993
+ if (!isPlainObject2(parsed)) {
128994
+ failPrebuiltCollections(
128995
+ `prebuilt ${role} collection file ${file.relative} must contain a YAML mapping`
128996
+ );
128997
+ }
128998
+ let nextNode;
128999
+ if (file.relative === ".resources/definition.yaml") {
129000
+ rootScripts = normalizeTrustedPrivateMockRootScripts(parsed.scripts, role);
129001
+ if (!rootScripts.some((script) => isManagedPrivateMockAuthRootHook(script))) {
129002
+ nextNode = {
129003
+ ...parsed,
129004
+ scripts: [
129005
+ ...rootScripts,
129006
+ {
129007
+ type: PRIVATE_MOCK_AUTH_ROOT_TYPE,
129008
+ code: PRIVATE_MOCK_AUTH_ROOT_SCRIPT,
129009
+ language: "text/javascript"
129010
+ }
129011
+ ]
129012
+ };
129013
+ }
129014
+ } else {
129015
+ const cleaned = applyPrivateMockArtifactNodeCleanup(parsed, { stripManagedBlocks });
129016
+ if (cleaned.strippedBlocks > 0) {
129017
+ nextNode = cleaned.node;
129018
+ }
129019
+ }
129020
+ if (nextNode) {
129021
+ const next = serializePrivateMockArtifactNode(nextNode);
129022
+ if (!next.equals(original)) {
129023
+ updates.push({
129024
+ absolute: file.absolute,
129025
+ relative: file.relative,
129026
+ original: Buffer.from(original),
129027
+ next
129028
+ });
129029
+ }
129030
+ }
129031
+ });
129032
+ if (currentDigest !== prepared.entry.artifactDigest) {
129033
+ failPrebuiltCollections(
129034
+ `prebuilt ${role} collection changed after initial validation; expected artifactDigest ${prepared.entry.artifactDigest}, observed ${currentDigest}`
129035
+ );
129036
+ }
129037
+ if (!rootScripts) {
129038
+ failPrebuiltCollections(`prebuilt ${role} collection root definition disappeared`);
129039
+ }
129040
+ return { prepared, rootScripts, updates };
129041
+ }
129042
+ function applyPrivateMockPrebuiltPlans(plans) {
129043
+ const updates = plans.flatMap((plan) => plan.updates);
129044
+ const seen = /* @__PURE__ */ new Set();
129045
+ for (const update of updates) {
129046
+ if (seen.has(update.absolute)) {
129047
+ failPrebuiltCollections(
129048
+ `private-mock artifact plan addressed ${update.relative} more than once`
129049
+ );
129050
+ }
129051
+ seen.add(update.absolute);
129052
+ let current2;
129053
+ try {
129054
+ const stat2 = (0, import_node_fs6.lstatSync)(update.absolute);
129055
+ if (stat2.isSymbolicLink() || !stat2.isFile()) {
129056
+ failPrebuiltCollections(
129057
+ `prebuilt collection tree file changed or became unsupported at ${update.relative}`
129058
+ );
129059
+ }
129060
+ current2 = (0, import_node_fs6.readFileSync)(update.absolute);
129061
+ } catch (error) {
129062
+ if (error instanceof Error && error.message.startsWith("CONTRACT_PREBUILT_COLLECTIONS_INVALID:")) {
129063
+ throw error;
129064
+ }
129065
+ failPrebuiltCollections(
129066
+ `prebuilt collection tree file changed or became unreadable at ${update.relative}`
129067
+ );
129068
+ }
129069
+ if (!current2.equals(update.original)) {
129070
+ failPrebuiltCollections(
129071
+ `prebuilt collection tree file changed before private-mock reconciliation at ${update.relative}`
129072
+ );
129073
+ }
129074
+ }
129075
+ const written = [];
129076
+ try {
129077
+ for (const update of updates) {
129078
+ (0, import_node_fs6.writeFileSync)(update.absolute, update.next);
129079
+ written.push(update);
129080
+ }
129081
+ } catch (error) {
129082
+ for (const update of written.reverse()) {
129083
+ try {
129084
+ (0, import_node_fs6.writeFileSync)(update.absolute, update.original);
129085
+ } catch {
129086
+ }
129087
+ }
129088
+ throw error;
129089
+ }
129090
+ for (const plan of plans) {
129091
+ plan.prepared.privateMockArtifactReady = true;
129092
+ }
129093
+ }
128858
129094
  async function preparePrivateMockCloudCollection(role, collectionId, postman) {
128859
129095
  const col = await postman.getCollection(collectionId);
128860
129096
  const { collection } = applyPrivateMockExportCleanup(col, {
@@ -128894,20 +129130,23 @@ async function runBoundedInOrder(items, width, worker) {
128894
129130
  async function acquireCollectionArtifact(options) {
128895
129131
  const { role, collectionId, dirName, collectionsDir, prebuiltByRole, postman, core, privateMockAuth = false } = options;
128896
129132
  const expectedPath = `${collectionsDir}/${dirName}`;
128897
- const forceCloudExport = privateMockAuth;
128898
129133
  const entry = prebuiltByRole.get(role);
128899
- if (entry && !forceCloudExport && tryReusePrebuiltCollection({
129134
+ const exactPrebuilt = Boolean(entry && tryReusePrebuiltCollection({
128900
129135
  prepared: entry,
128901
129136
  expectedPath,
128902
129137
  expectedCloudId: collectionId
128903
- })) {
128904
- core.info(`Reusing prebuilt ${role} collection tree at ${expectedPath} (artifactDigest match)`);
129138
+ }));
129139
+ const reusePrebuilt = exactPrebuilt && (!privateMockAuth || entry?.privateMockArtifactReady === true);
129140
+ if (reusePrebuilt) {
129141
+ core.info(
129142
+ privateMockAuth ? `Reusing locally reconciled private-mock ${role} collection tree at ${expectedPath} (source artifactDigest match)` : `Reusing prebuilt ${role} collection tree at ${expectedPath} (artifactDigest match)`
129143
+ );
128905
129144
  return { reusePrebuilt: true };
128906
129145
  }
128907
129146
  if (entry) {
128908
- core.info(forceCloudExport ? `Private mock requires cloud export for ${role} collection to reconcile managed root hook; exporting from cloud` : `Prebuilt ${role} collection entry present but did not exactly match; exporting from cloud`);
129147
+ core.info(privateMockAuth ? `Private mock has no locally reconciled exact prebuilt ${role} collection; exporting from cloud` : `Prebuilt ${role} collection entry present but did not exactly match; exporting from cloud`);
128909
129148
  }
128910
- const cloud = forceCloudExport ? await preparePrivateMockCloudCollection(role, collectionId, postman) : await postman.getCollection(collectionId);
129149
+ const cloud = privateMockAuth ? await preparePrivateMockCloudCollection(role, collectionId, postman) : await postman.getCollection(collectionId);
128911
129150
  return { reusePrebuilt: false, cloudCollection: cloud };
128912
129151
  }
128913
129152
  async function exportCollectionArtifact(options) {
@@ -129582,19 +129821,49 @@ async function runRepoSyncInner(inputs, dependencies, executionContext) {
129582
129821
  "PRIVATE_MOCK_RUNTIME_AUTH_UNAVAILABLE: The Postman client cannot configure runtime x-api-key injection."
129583
129822
  );
129584
129823
  }
129824
+ const collectionTargets = [
129825
+ { role: "baseline", collectionUid: inputs.baselineCollectionId, kind: "Baseline" },
129826
+ { role: "smoke", collectionUid: inputs.smokeCollectionId, kind: "Smoke" },
129827
+ { role: "contract", collectionUid: inputs.contractCollectionId, kind: "Contract" }
129828
+ ].filter((target) => Boolean(target.collectionUid));
129829
+ const prebuiltPlans = /* @__PURE__ */ new Map();
129830
+ for (const target of collectionTargets) {
129831
+ const plan = await planPrivateMockPrebuiltArtifact({
129832
+ role: target.role,
129833
+ collectionId: target.collectionUid,
129834
+ expectedPath: `${inputs.artifactDir}/collections/${getCollectionDirectoryName(target.kind, assetProjectName)}`,
129835
+ artifactDir: inputs.artifactDir,
129836
+ prepared: preparedPrebuiltCollections.get(target.role)
129837
+ });
129838
+ if (plan) {
129839
+ prebuiltPlans.set(target.role, plan);
129840
+ }
129841
+ }
129585
129842
  const configured = [];
129586
129843
  const configuredUids = /* @__PURE__ */ new Set();
129587
- for (const { role, collectionUid } of [
129588
- { role: "baseline", collectionUid: inputs.baselineCollectionId },
129589
- { role: "smoke", collectionUid: inputs.smokeCollectionId },
129590
- { role: "contract", collectionUid: inputs.contractCollectionId }
129591
- ]) {
129592
- if (!collectionUid || configuredUids.has(collectionUid)) {
129844
+ for (const { role, collectionUid } of collectionTargets) {
129845
+ if (configuredUids.has(collectionUid)) {
129593
129846
  continue;
129594
129847
  }
129595
129848
  configuredUids.add(collectionUid);
129596
129849
  try {
129597
- await dependencies.postman.configurePrivateMockRuntimeAuth(collectionUid);
129850
+ const plansForUid = collectionTargets.filter((target) => target.collectionUid === collectionUid).map((target) => prebuiltPlans.get(target.role)).filter((plan) => Boolean(plan));
129851
+ const trustedRootScripts = plansForUid[0]?.rootScripts;
129852
+ if (trustedRootScripts && plansForUid.some(
129853
+ (plan) => JSON.stringify(plan.rootScripts) !== JSON.stringify(trustedRootScripts)
129854
+ )) {
129855
+ failPrebuiltCollections(
129856
+ `roles sharing collection ${collectionUid} disagree on trusted root scripts`
129857
+ );
129858
+ }
129859
+ if (trustedRootScripts) {
129860
+ await dependencies.postman.configurePrivateMockRuntimeAuth(
129861
+ collectionUid,
129862
+ trustedRootScripts
129863
+ );
129864
+ } else {
129865
+ await dependencies.postman.configurePrivateMockRuntimeAuth(collectionUid);
129866
+ }
129598
129867
  configured.push(collectionUid);
129599
129868
  } catch (error) {
129600
129869
  throw new Error(
@@ -129603,6 +129872,7 @@ async function runRepoSyncInner(inputs, dependencies, executionContext) {
129603
129872
  );
129604
129873
  }
129605
129874
  }
129875
+ applyPrivateMockPrebuiltPlans([...prebuiltPlans.values()]);
129606
129876
  if (configured.length > 0) {
129607
129877
  (dependencies.core.notice ?? dependencies.core.info)(
129608
129878
  `Private mock: installed a request hook on ${configured.length} collection(s) that sends the ${PRIVATE_MOCK_AUTH_VARIABLE2} variable as x-api-key, and only to *.mock.pstmn.io hosts. The generated CI workflow supplies it from the POSTMAN_API_KEY secret. For manual runs in the Postman app, set that variable to a key with access to the mock. No key is stored in the collection, environment, outputs, or repository.`
@@ -130682,7 +130952,7 @@ async function runGc(options) {
130682
130952
  }
130683
130953
 
130684
130954
  // src/cli.ts
130685
- var execFileAsync = (0, import_node_util.promisify)(import_node_child_process.execFile);
130955
+ var execFileAsync = (0, import_node_util2.promisify)(import_node_child_process.execFile);
130686
130956
  var CLI_INPUT_NAMES = [
130687
130957
  "working-directory",
130688
130958
  "project-name",