@postman-cs/onboarding-repo-sync 2.10.6 → 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/index.cjs CHANGED
@@ -121664,6 +121664,9 @@ var PostmanAssetsClient = class {
121664
121664
  }
121665
121665
  };
121666
121666
 
121667
+ // src/lib/postman/postman-gateway-assets-client.ts
121668
+ var import_node_util = require("node:util");
121669
+
121667
121670
  // node_modules/acorn/dist/acorn.mjs
121668
121671
  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];
121669
121672
  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];
@@ -128266,79 +128269,160 @@ var PostmanGatewayAssetsClient = class {
128266
128269
  isAmbiguousTransportError(error2) {
128267
128270
  return this.isRetryableIdempotentWriteOutcome(error2);
128268
128271
  }
128269
- normalizeCollectionScripts(scripts) {
128270
- if (!Array.isArray(scripts)) return [];
128271
- return scripts.map((entry) => this.asRecord(entry)).filter((entry) => entry !== null);
128272
+ isRootPatchSnapshotConflict(error2) {
128273
+ return error2 instanceof HttpError && [400, 409, 412].includes(error2.status);
128274
+ }
128275
+ normalizeCollectionScripts(scripts, operation) {
128276
+ if (scripts === void 0 || scripts === null) return [];
128277
+ if (!Array.isArray(scripts)) {
128278
+ throw new Error(
128279
+ `PRIVATE_MOCK_AUTH_ROOT_INVALID: ${operation} returned a non-array scripts field.`
128280
+ );
128281
+ }
128282
+ const normalized = scripts.map((entry) => this.asRecord(entry));
128283
+ if (normalized.some((entry) => entry === null)) {
128284
+ throw new Error(
128285
+ `PRIVATE_MOCK_AUTH_ROOT_INVALID: ${operation} returned a non-object script entry.`
128286
+ );
128287
+ }
128288
+ return normalized;
128272
128289
  }
128273
128290
  rootScriptsIncludeManagedAuthHook(scripts) {
128274
128291
  return scripts.some((script) => isManagedPrivateMockAuthRootHook(script));
128275
128292
  }
128276
- buildPrivateMockRootScripts(existingScripts) {
128277
- const managedScript = {
128278
- type: PRIVATE_MOCK_AUTH_ROOT_TYPE,
128279
- code: PRIVATE_MOCK_AUTH_ROOT_SCRIPT,
128280
- language: "text/javascript"
128281
- };
128282
- return [...existingScripts, managedScript];
128293
+ expectedPrivateMockRootScripts(existingScripts) {
128294
+ return [
128295
+ ...existingScripts,
128296
+ {
128297
+ type: PRIVATE_MOCK_AUTH_ROOT_TYPE,
128298
+ code: PRIVATE_MOCK_AUTH_ROOT_SCRIPT,
128299
+ language: "text/javascript"
128300
+ }
128301
+ ];
128302
+ }
128303
+ assertAtMostOneManagedRootHook(scripts, operation) {
128304
+ const count = scripts.filter((script) => isManagedPrivateMockAuthRootHook(script)).length;
128305
+ if (count > 1) {
128306
+ throw new Error(
128307
+ `PRIVATE_MOCK_AUTH_ROOT_DUPLICATE: ${operation} contains ${count} exact managed hooks.`
128308
+ );
128309
+ }
128283
128310
  }
128284
128311
  async readCollectionRootScripts(collectionUid) {
128285
128312
  const id = this.requireCollectionPublicUid(collectionUid);
128286
- const response = await this.gateway.requestJson({
128287
- service: "collection",
128288
- method: "get",
128289
- path: `/v3/collections/${id}/export`
128290
- });
128313
+ const response = await this.gateway.requestJson(
128314
+ {
128315
+ service: "collection",
128316
+ method: "get",
128317
+ path: `/v3/collections/${id}`
128318
+ },
128319
+ // Root reconciliation is evidence, not a transient-success mechanism.
128320
+ // One response must prove the current state; never hide a 5xx by retrying.
128321
+ { retryTransient: false }
128322
+ );
128291
128323
  const data2 = this.asRecord(response?.data);
128292
- const collection = this.asRecord(data2?.collection);
128293
- if (!collection) {
128324
+ if (!data2) {
128294
128325
  throw new Error(
128295
- `PRIVATE_MOCK_AUTH_EXPORT_INVALID: Collection ${id} export did not return data.collection; refusing to configure private-mock root auth from an unexpected envelope.`
128326
+ `PRIVATE_MOCK_AUTH_ROOT_INVALID: Collection ${id} root read did not return data; refusing to configure private-mock root auth from an unexpected envelope.`
128296
128327
  );
128297
128328
  }
128298
- return this.normalizeCollectionScripts(collection.scripts);
128329
+ return this.normalizeCollectionScripts(data2.scripts, `Collection ${id} root read`);
128299
128330
  }
128300
- async patchCollectionRootScripts(collectionUid, scripts) {
128331
+ async patchCollectionRootScripts(collectionUid, existingScripts) {
128301
128332
  const id = this.requireCollectionPublicUid(collectionUid);
128302
- await this.gateway.requestJson(
128333
+ const expectedScripts = this.expectedPrivateMockRootScripts(existingScripts);
128334
+ const managedScript = expectedScripts.at(-1);
128335
+ const response = await this.gateway.requestJson(
128303
128336
  {
128304
128337
  service: "collection",
128305
128338
  method: "patch",
128306
128339
  path: `/v3/collections/${id}`,
128307
- body: [{ op: "add", path: "/scripts", value: scripts }]
128340
+ // Bootstrap creates these HTTP collections through Sync. Its current
128341
+ // collection-service wire projection materializes absent/null scripts
128342
+ // as `[]` before applying RFC 6902, so this pair is one atomic
128343
+ // compare-and-append. If that contract ever changes, `test` fails and
128344
+ // the append cannot overwrite or manufacture a scripts field.
128345
+ body: [
128346
+ { op: "test", path: "/scripts", value: existingScripts },
128347
+ { op: "add", path: "/scripts/-", value: managedScript }
128348
+ ]
128308
128349
  },
128309
128350
  { retryTransient: false }
128310
128351
  );
128352
+ const data2 = this.asRecord(response?.data);
128353
+ if (!data2) {
128354
+ throw new Error(
128355
+ `PRIVATE_MOCK_AUTH_ROOT_PATCH_INVALID: Collection ${id} root patch did not return data.`
128356
+ );
128357
+ }
128358
+ const scripts = this.normalizeCollectionScripts(data2.scripts, `Collection ${id} root patch`);
128359
+ if (!(0, import_node_util.isDeepStrictEqual)(scripts, expectedScripts)) {
128360
+ throw new Error(
128361
+ `PRIVATE_MOCK_AUTH_ROOT_PATCH_UNVERIFIED: Collection ${id} root patch response did not exactly preserve the prior scripts and append one managed hook.`
128362
+ );
128363
+ }
128364
+ return scripts;
128311
128365
  }
128312
128366
  /**
128313
128367
  * Add a secret-free runtime hook at the collection root. The PMAK value is
128314
128368
  * supplied only by the runner as a transient variable; this method persists
128315
128369
  * the variable name and header wiring, never the credential.
128316
128370
  */
128317
- async configurePrivateMockRuntimeAuth(collectionUid) {
128371
+ async configurePrivateMockRuntimeAuth(collectionUid, trustedRootScripts) {
128318
128372
  const cid = this.requireCollectionPublicUid(collectionUid);
128319
- const installFromFreshRoot = async (existingScripts) => {
128373
+ const installFromRootSnapshot = async (existingScripts) => {
128374
+ this.assertAtMostOneManagedRootHook(existingScripts, `Collection ${cid} root snapshot`);
128320
128375
  if (this.rootScriptsIncludeManagedAuthHook(existingScripts)) {
128321
128376
  return 0;
128322
128377
  }
128323
- const nextScripts = this.buildPrivateMockRootScripts(existingScripts);
128378
+ const expectedScripts = this.expectedPrivateMockRootScripts(existingScripts);
128324
128379
  try {
128325
- await this.patchCollectionRootScripts(cid, nextScripts);
128380
+ await this.patchCollectionRootScripts(cid, existingScripts);
128326
128381
  return 1;
128327
128382
  } catch (error2) {
128383
+ if (this.isRootPatchSnapshotConflict(error2)) {
128384
+ const currentScripts = await this.readCollectionRootScripts(cid);
128385
+ if ((0, import_node_util.isDeepStrictEqual)(currentScripts, expectedScripts)) {
128386
+ return 0;
128387
+ }
128388
+ throw error2;
128389
+ }
128328
128390
  if (!this.isAmbiguousTransportError(error2)) {
128329
128391
  throw error2;
128330
128392
  }
128331
128393
  const freshScripts = await this.readCollectionRootScripts(cid);
128332
- if (this.rootScriptsIncludeManagedAuthHook(freshScripts)) {
128394
+ if ((0, import_node_util.isDeepStrictEqual)(freshScripts, expectedScripts)) {
128333
128395
  return 1;
128334
128396
  }
128335
- const recomputed = this.buildPrivateMockRootScripts(freshScripts);
128336
- await this.patchCollectionRootScripts(cid, recomputed);
128337
- return 1;
128397
+ if (!(0, import_node_util.isDeepStrictEqual)(freshScripts, existingScripts)) {
128398
+ throw new Error(
128399
+ `PRIVATE_MOCK_AUTH_ROOT_RECONCILE_DIVERGED: Collection ${cid} root scripts changed while reconciling an ambiguous patch.`,
128400
+ { cause: error2 }
128401
+ );
128402
+ }
128403
+ try {
128404
+ await this.patchCollectionRootScripts(cid, existingScripts);
128405
+ return 1;
128406
+ } catch (resendError) {
128407
+ if (!this.isAmbiguousTransportError(resendError)) {
128408
+ throw resendError;
128409
+ }
128410
+ const finalScripts = await this.readCollectionRootScripts(cid);
128411
+ if ((0, import_node_util.isDeepStrictEqual)(finalScripts, expectedScripts)) {
128412
+ return 1;
128413
+ }
128414
+ if (!(0, import_node_util.isDeepStrictEqual)(finalScripts, existingScripts)) {
128415
+ throw new Error(
128416
+ `PRIVATE_MOCK_AUTH_ROOT_RECONCILE_DIVERGED: Collection ${cid} root scripts changed after the ambiguous patch resend.`,
128417
+ { cause: resendError }
128418
+ );
128419
+ }
128420
+ throw resendError;
128421
+ }
128338
128422
  }
128339
128423
  };
128340
- const scripts = await this.readCollectionRootScripts(cid);
128341
- return installFromFreshRoot(scripts);
128424
+ const scripts = trustedRootScripts === void 0 ? await this.readCollectionRootScripts(cid) : this.normalizeCollectionScripts(trustedRootScripts, `Trusted collection ${cid} root`);
128425
+ return installFromRootSnapshot(scripts);
128342
128426
  }
128343
128427
  async listMocks() {
128344
128428
  const response = await this.gateway.requestJson({
@@ -128676,6 +128760,45 @@ function cloneCollection(collection) {
128676
128760
  return cloneCollectionNodeIterative(collection);
128677
128761
  }
128678
128762
  }
128763
+ function cleanManagedItemAuthScriptsInPlace(item, stripManagedBlocks) {
128764
+ if (!stripManagedBlocks) {
128765
+ return 0;
128766
+ }
128767
+ const scripts = item.scripts;
128768
+ if (!Array.isArray(scripts)) {
128769
+ return 0;
128770
+ }
128771
+ let strippedBlocks = 0;
128772
+ const nextScripts = [];
128773
+ for (const script of scripts) {
128774
+ if (!script || typeof script !== "object" || Array.isArray(script)) {
128775
+ nextScripts.push(script);
128776
+ continue;
128777
+ }
128778
+ const record = script;
128779
+ if (String(record.type ?? "") !== "beforeRequest") {
128780
+ nextScripts.push(record);
128781
+ continue;
128782
+ }
128783
+ const originalCode = String(record.code ?? "");
128784
+ const cleaned = stripManagedItemAuthBlocks(originalCode);
128785
+ if (cleaned === originalCode) {
128786
+ nextScripts.push(record);
128787
+ continue;
128788
+ }
128789
+ strippedBlocks += countManagedItemAuthBlocks(originalCode);
128790
+ if (!cleaned) {
128791
+ continue;
128792
+ }
128793
+ nextScripts.push({ ...record, code: cleaned });
128794
+ }
128795
+ if (nextScripts.length === 0) {
128796
+ delete item.scripts;
128797
+ } else {
128798
+ item.scripts = nextScripts;
128799
+ }
128800
+ return strippedBlocks;
128801
+ }
128679
128802
  function isPrivateMockLegacyExportCleanupEnabled() {
128680
128803
  const value = String(process.env.POSTMAN_PRIVATE_MOCK_LEGACY_EXPORT_CLEANUP ?? "").trim().toLowerCase();
128681
128804
  return value !== "off";
@@ -128684,52 +128807,23 @@ function verifyPrivateMockRootHook(collection) {
128684
128807
  const scripts = asArray2(collection.scripts);
128685
128808
  return scripts.some((script) => isManagedPrivateMockAuthRootHook(script));
128686
128809
  }
128810
+ function applyPrivateMockArtifactNodeCleanup(node, options = {}) {
128811
+ const stripManagedBlocks = options.stripManagedBlocks ?? isPrivateMockLegacyExportCleanupEnabled();
128812
+ const cloned = cloneCollection(node);
128813
+ return {
128814
+ node: cloned,
128815
+ strippedBlocks: cleanManagedItemAuthScriptsInPlace(cloned, stripManagedBlocks)
128816
+ };
128817
+ }
128687
128818
  function applyPrivateMockExportCleanup(collection, options = {}) {
128688
128819
  const stripManagedBlocks = options.stripManagedBlocks ?? isPrivateMockLegacyExportCleanupEnabled();
128689
128820
  const cloned = cloneCollection(collection);
128690
128821
  let strippedBlocks = 0;
128691
- const visitItem = (item) => {
128692
- if (!stripManagedBlocks) {
128693
- return;
128694
- }
128695
- const scripts = item.scripts;
128696
- if (!Array.isArray(scripts)) {
128697
- return;
128698
- }
128699
- const nextScripts = [];
128700
- for (const script of scripts) {
128701
- if (!script || typeof script !== "object" || Array.isArray(script)) {
128702
- nextScripts.push(script);
128703
- continue;
128704
- }
128705
- const record = script;
128706
- if (String(record.type ?? "") !== "beforeRequest") {
128707
- nextScripts.push(record);
128708
- continue;
128709
- }
128710
- const originalCode = String(record.code ?? "");
128711
- const cleaned = stripManagedItemAuthBlocks(originalCode);
128712
- if (cleaned === originalCode) {
128713
- nextScripts.push(record);
128714
- continue;
128715
- }
128716
- strippedBlocks += countManagedItemAuthBlocks(originalCode);
128717
- if (!cleaned) {
128718
- continue;
128719
- }
128720
- nextScripts.push({ ...record, code: cleaned });
128721
- }
128722
- if (nextScripts.length === 0) {
128723
- delete item.scripts;
128724
- } else {
128725
- item.scripts = nextScripts;
128726
- }
128727
- };
128728
128822
  const walkItemsIteratively = (rootItems) => {
128729
128823
  const stack = [...rootItems].reverse();
128730
128824
  while (stack.length > 0) {
128731
128825
  const item = stack.pop();
128732
- visitItem(item);
128826
+ strippedBlocks += cleanManagedItemAuthScriptsInPlace(item, stripManagedBlocks);
128733
128827
  for (const key of ["items", "children"]) {
128734
128828
  const nested = asArray2(item[key]);
128735
128829
  for (let i3 = nested.length - 1; i3 >= 0; i3 -= 1) {
@@ -130897,7 +130991,7 @@ function validateCanonicalV3CollectionFile(relative4, bytes) {
130897
130991
  );
130898
130992
  }
130899
130993
  }
130900
- async function digestAndValidatePrebuiltCollectionTree(files) {
130994
+ async function digestAndValidatePrebuiltCollectionTree(files, onFile) {
130901
130995
  if (!files.some((file) => file.relative === ".resources/definition.yaml")) {
130902
130996
  failPrebuiltCollections("prebuilt collection tree is missing .resources/definition.yaml");
130903
130997
  }
@@ -130925,6 +131019,7 @@ async function digestAndValidatePrebuiltCollectionTree(files) {
130925
131019
  );
130926
131020
  }
130927
131021
  validateCanonicalV3CollectionFile(file.relative, bytes);
131022
+ onFile?.(file, bytes);
130928
131023
  }
130929
131024
  return hash.digest("hex");
130930
131025
  }
@@ -130972,6 +131067,147 @@ function tryReusePrebuiltCollection(options) {
130972
131067
  }
130973
131068
  return prepared.artifactDigest === entry.artifactDigest;
130974
131069
  }
131070
+ function normalizeTrustedPrivateMockRootScripts(value, role) {
131071
+ if (value === void 0 || value === null) {
131072
+ return [];
131073
+ }
131074
+ if (!Array.isArray(value) || value.some((entry) => !isPlainObject2(entry))) {
131075
+ failPrebuiltCollections(
131076
+ `prebuilt ${role} collection root scripts must be an array of mappings`
131077
+ );
131078
+ }
131079
+ return value.map((entry) => ({ ...entry }));
131080
+ }
131081
+ function serializePrivateMockArtifactNode(node) {
131082
+ return Buffer.from(dump(node, {
131083
+ lineWidth: -1,
131084
+ noRefs: true,
131085
+ sortKeys: false
131086
+ }));
131087
+ }
131088
+ async function planPrivateMockPrebuiltArtifact(options) {
131089
+ const { role, collectionId, expectedPath, artifactDir, prepared } = options;
131090
+ if (!prepared || !tryReusePrebuiltCollection({
131091
+ prepared,
131092
+ expectedPath,
131093
+ expectedCloudId: collectionId
131094
+ })) {
131095
+ return void 0;
131096
+ }
131097
+ const files = listPrebuiltCollectionTreeFiles(prepared.confinedPath, artifactDir);
131098
+ const updates = [];
131099
+ let rootScripts;
131100
+ const stripManagedBlocks = isPrivateMockLegacyExportCleanupEnabled();
131101
+ const currentDigest = await digestAndValidatePrebuiltCollectionTree(files, (file, original) => {
131102
+ let parsed;
131103
+ try {
131104
+ parsed = load(original.toString("utf8"));
131105
+ } catch (error2) {
131106
+ failPrebuiltCollections(
131107
+ `prebuilt ${role} collection changed to malformed YAML at ${file.relative} (${error2 instanceof Error ? error2.message : String(error2)})`
131108
+ );
131109
+ }
131110
+ if (!isPlainObject2(parsed)) {
131111
+ failPrebuiltCollections(
131112
+ `prebuilt ${role} collection file ${file.relative} must contain a YAML mapping`
131113
+ );
131114
+ }
131115
+ let nextNode;
131116
+ if (file.relative === ".resources/definition.yaml") {
131117
+ rootScripts = normalizeTrustedPrivateMockRootScripts(parsed.scripts, role);
131118
+ if (!rootScripts.some((script) => isManagedPrivateMockAuthRootHook(script))) {
131119
+ nextNode = {
131120
+ ...parsed,
131121
+ scripts: [
131122
+ ...rootScripts,
131123
+ {
131124
+ type: PRIVATE_MOCK_AUTH_ROOT_TYPE,
131125
+ code: PRIVATE_MOCK_AUTH_ROOT_SCRIPT,
131126
+ language: "text/javascript"
131127
+ }
131128
+ ]
131129
+ };
131130
+ }
131131
+ } else {
131132
+ const cleaned = applyPrivateMockArtifactNodeCleanup(parsed, { stripManagedBlocks });
131133
+ if (cleaned.strippedBlocks > 0) {
131134
+ nextNode = cleaned.node;
131135
+ }
131136
+ }
131137
+ if (nextNode) {
131138
+ const next = serializePrivateMockArtifactNode(nextNode);
131139
+ if (!next.equals(original)) {
131140
+ updates.push({
131141
+ absolute: file.absolute,
131142
+ relative: file.relative,
131143
+ original: Buffer.from(original),
131144
+ next
131145
+ });
131146
+ }
131147
+ }
131148
+ });
131149
+ if (currentDigest !== prepared.entry.artifactDigest) {
131150
+ failPrebuiltCollections(
131151
+ `prebuilt ${role} collection changed after initial validation; expected artifactDigest ${prepared.entry.artifactDigest}, observed ${currentDigest}`
131152
+ );
131153
+ }
131154
+ if (!rootScripts) {
131155
+ failPrebuiltCollections(`prebuilt ${role} collection root definition disappeared`);
131156
+ }
131157
+ return { prepared, rootScripts, updates };
131158
+ }
131159
+ function applyPrivateMockPrebuiltPlans(plans) {
131160
+ const updates = plans.flatMap((plan) => plan.updates);
131161
+ const seen = /* @__PURE__ */ new Set();
131162
+ for (const update of updates) {
131163
+ if (seen.has(update.absolute)) {
131164
+ failPrebuiltCollections(
131165
+ `private-mock artifact plan addressed ${update.relative} more than once`
131166
+ );
131167
+ }
131168
+ seen.add(update.absolute);
131169
+ let current2;
131170
+ try {
131171
+ const stat2 = (0, import_node_fs6.lstatSync)(update.absolute);
131172
+ if (stat2.isSymbolicLink() || !stat2.isFile()) {
131173
+ failPrebuiltCollections(
131174
+ `prebuilt collection tree file changed or became unsupported at ${update.relative}`
131175
+ );
131176
+ }
131177
+ current2 = (0, import_node_fs6.readFileSync)(update.absolute);
131178
+ } catch (error2) {
131179
+ if (error2 instanceof Error && error2.message.startsWith("CONTRACT_PREBUILT_COLLECTIONS_INVALID:")) {
131180
+ throw error2;
131181
+ }
131182
+ failPrebuiltCollections(
131183
+ `prebuilt collection tree file changed or became unreadable at ${update.relative}`
131184
+ );
131185
+ }
131186
+ if (!current2.equals(update.original)) {
131187
+ failPrebuiltCollections(
131188
+ `prebuilt collection tree file changed before private-mock reconciliation at ${update.relative}`
131189
+ );
131190
+ }
131191
+ }
131192
+ const written = [];
131193
+ try {
131194
+ for (const update of updates) {
131195
+ (0, import_node_fs6.writeFileSync)(update.absolute, update.next);
131196
+ written.push(update);
131197
+ }
131198
+ } catch (error2) {
131199
+ for (const update of written.reverse()) {
131200
+ try {
131201
+ (0, import_node_fs6.writeFileSync)(update.absolute, update.original);
131202
+ } catch {
131203
+ }
131204
+ }
131205
+ throw error2;
131206
+ }
131207
+ for (const plan of plans) {
131208
+ plan.prepared.privateMockArtifactReady = true;
131209
+ }
131210
+ }
130975
131211
  async function preparePrivateMockCloudCollection(role, collectionId, postman) {
130976
131212
  const col = await postman.getCollection(collectionId);
130977
131213
  const { collection } = applyPrivateMockExportCleanup(col, {
@@ -131011,20 +131247,23 @@ async function runBoundedInOrder(items, width, worker) {
131011
131247
  async function acquireCollectionArtifact(options) {
131012
131248
  const { role, collectionId, dirName, collectionsDir, prebuiltByRole, postman, core, privateMockAuth = false } = options;
131013
131249
  const expectedPath = `${collectionsDir}/${dirName}`;
131014
- const forceCloudExport = privateMockAuth;
131015
131250
  const entry = prebuiltByRole.get(role);
131016
- if (entry && !forceCloudExport && tryReusePrebuiltCollection({
131251
+ const exactPrebuilt = Boolean(entry && tryReusePrebuiltCollection({
131017
131252
  prepared: entry,
131018
131253
  expectedPath,
131019
131254
  expectedCloudId: collectionId
131020
- })) {
131021
- core.info(`Reusing prebuilt ${role} collection tree at ${expectedPath} (artifactDigest match)`);
131255
+ }));
131256
+ const reusePrebuilt = exactPrebuilt && (!privateMockAuth || entry?.privateMockArtifactReady === true);
131257
+ if (reusePrebuilt) {
131258
+ core.info(
131259
+ privateMockAuth ? `Reusing locally reconciled private-mock ${role} collection tree at ${expectedPath} (source artifactDigest match)` : `Reusing prebuilt ${role} collection tree at ${expectedPath} (artifactDigest match)`
131260
+ );
131022
131261
  return { reusePrebuilt: true };
131023
131262
  }
131024
131263
  if (entry) {
131025
- 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`);
131264
+ 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`);
131026
131265
  }
131027
- const cloud = forceCloudExport ? await preparePrivateMockCloudCollection(role, collectionId, postman) : await postman.getCollection(collectionId);
131266
+ const cloud = privateMockAuth ? await preparePrivateMockCloudCollection(role, collectionId, postman) : await postman.getCollection(collectionId);
131028
131267
  return { reusePrebuilt: false, cloudCollection: cloud };
131029
131268
  }
131030
131269
  async function exportCollectionArtifact(options) {
@@ -131699,19 +131938,49 @@ async function runRepoSyncInner(inputs, dependencies, executionContext) {
131699
131938
  "PRIVATE_MOCK_RUNTIME_AUTH_UNAVAILABLE: The Postman client cannot configure runtime x-api-key injection."
131700
131939
  );
131701
131940
  }
131941
+ const collectionTargets = [
131942
+ { role: "baseline", collectionUid: inputs.baselineCollectionId, kind: "Baseline" },
131943
+ { role: "smoke", collectionUid: inputs.smokeCollectionId, kind: "Smoke" },
131944
+ { role: "contract", collectionUid: inputs.contractCollectionId, kind: "Contract" }
131945
+ ].filter((target) => Boolean(target.collectionUid));
131946
+ const prebuiltPlans = /* @__PURE__ */ new Map();
131947
+ for (const target of collectionTargets) {
131948
+ const plan = await planPrivateMockPrebuiltArtifact({
131949
+ role: target.role,
131950
+ collectionId: target.collectionUid,
131951
+ expectedPath: `${inputs.artifactDir}/collections/${getCollectionDirectoryName(target.kind, assetProjectName)}`,
131952
+ artifactDir: inputs.artifactDir,
131953
+ prepared: preparedPrebuiltCollections.get(target.role)
131954
+ });
131955
+ if (plan) {
131956
+ prebuiltPlans.set(target.role, plan);
131957
+ }
131958
+ }
131702
131959
  const configured = [];
131703
131960
  const configuredUids = /* @__PURE__ */ new Set();
131704
- for (const { role, collectionUid } of [
131705
- { role: "baseline", collectionUid: inputs.baselineCollectionId },
131706
- { role: "smoke", collectionUid: inputs.smokeCollectionId },
131707
- { role: "contract", collectionUid: inputs.contractCollectionId }
131708
- ]) {
131709
- if (!collectionUid || configuredUids.has(collectionUid)) {
131961
+ for (const { role, collectionUid } of collectionTargets) {
131962
+ if (configuredUids.has(collectionUid)) {
131710
131963
  continue;
131711
131964
  }
131712
131965
  configuredUids.add(collectionUid);
131713
131966
  try {
131714
- await dependencies.postman.configurePrivateMockRuntimeAuth(collectionUid);
131967
+ const plansForUid = collectionTargets.filter((target) => target.collectionUid === collectionUid).map((target) => prebuiltPlans.get(target.role)).filter((plan) => Boolean(plan));
131968
+ const trustedRootScripts = plansForUid[0]?.rootScripts;
131969
+ if (trustedRootScripts && plansForUid.some(
131970
+ (plan) => JSON.stringify(plan.rootScripts) !== JSON.stringify(trustedRootScripts)
131971
+ )) {
131972
+ failPrebuiltCollections(
131973
+ `roles sharing collection ${collectionUid} disagree on trusted root scripts`
131974
+ );
131975
+ }
131976
+ if (trustedRootScripts) {
131977
+ await dependencies.postman.configurePrivateMockRuntimeAuth(
131978
+ collectionUid,
131979
+ trustedRootScripts
131980
+ );
131981
+ } else {
131982
+ await dependencies.postman.configurePrivateMockRuntimeAuth(collectionUid);
131983
+ }
131715
131984
  configured.push(collectionUid);
131716
131985
  } catch (error2) {
131717
131986
  throw new Error(
@@ -131720,6 +131989,7 @@ async function runRepoSyncInner(inputs, dependencies, executionContext) {
131720
131989
  );
131721
131990
  }
131722
131991
  }
131992
+ applyPrivateMockPrebuiltPlans([...prebuiltPlans.values()]);
131723
131993
  if (configured.length > 0) {
131724
131994
  (dependencies.core.notice ?? dependencies.core.info)(
131725
131995
  `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.`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@postman-cs/onboarding-repo-sync",
3
- "version": "2.10.6",
3
+ "version": "2.10.8",
4
4
  "description": "Postman repo sync GitHub Action.",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",