@postman-cse/onboarding-bootstrap 2.9.1 → 2.9.3

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
@@ -264257,7 +264257,8 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
264257
264257
  service: "collection",
264258
264258
  method: "patch",
264259
264259
  path: `/v3/collections/${this.bareModelId(collectionId)}`,
264260
- retry: "none",
264260
+ // Replacing a generated collection's name with the same value is idempotent.
264261
+ retry: "safe",
264261
264262
  body: [{ op: "replace", path: "/name", value: name }]
264262
264263
  });
264263
264264
  }
@@ -264456,15 +264457,25 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
264456
264457
  }
264457
264458
  // --- collection v3 mutation + tagging (live-proven 2026-06-30; see docs/REST-to-gateway.md) ---
264458
264459
  //
264459
- // These retire bootstrap's last asset-op PMAK dependencies. The gateway keys
264460
- // the v3 collection-items surface on the BARE model id (strip the `<owner>-`
264461
- // prefix) with a trailing slash; the tagging service is distinct from the
264462
- // collection service and takes the FULL uid.
264463
- /** `<owner>-<uuid>` public uid -> bare `<uuid>` model id (the v3 items surface keys on it). */
264460
+ // These retire bootstrap's last asset-op PMAK dependencies. Collection ROOT
264461
+ // routes (GET/PATCH/DELETE `/v3/collections/:id`) accept the bare model id.
264462
+ // Collection ITEMS routes (`/v3/collections/:id/items/...`) must use the FULL
264463
+ // public uid (`<owner>-<uuid>`): bare model ids are flaky on org-mode squads
264464
+ // (live-proven 2026-07-14 on team 172912 / Northwind immediate post-generation
264465
+ // `GET .../items/` returns 403 FORBIDDEN with bare id, 200 with full uid).
264466
+ // The tagging service is distinct and takes the FULL uid.
264467
+ /** `<owner>-<uuid>` public uid -> bare `<uuid>` model id (collection ROOT routes only). */
264464
264468
  bareModelId(uid) {
264465
264469
  const u = String(uid ?? "").trim();
264466
264470
  return u.includes("-") ? u.slice(u.indexOf("-") + 1) : u;
264467
264471
  }
264472
+ /**
264473
+ * Collection id for ITEMS routes. Prefer the full public uid; fall back to the
264474
+ * trimmed input when the caller already has a bare/model id.
264475
+ */
264476
+ collectionItemsId(uid) {
264477
+ return String(uid ?? "").trim();
264478
+ }
264468
264479
  /**
264469
264480
  * PATCH a freshly-created item's `/scripts`, tolerating the two transient
264470
264481
  * failures this immediate-after-create write is prone to on the shared gateway:
@@ -264523,9 +264534,9 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
264523
264534
  /**
264524
264535
  * Inject smoke-test assertions into every leaf request of a spec-generated
264525
264536
  * collection, over the v3 collection-items surface (no PMAK):
264526
- * 1. `GET /v3/collections/:cid/items/` (bare model id, trailing slash) — flat list.
264537
+ * 1. `GET /v3/collections/:cid/items/` (FULL public uid, trailing slash) — flat list.
264527
264538
  * 2. for each `http-request` leaf, `PATCH /v3/collections/:cid/items/:itemId`
264528
- * (full uid for `:itemId`, `X-Entity-Type: http-request` header) with a
264539
+ * (full uid for `:cid` and `:itemId`, `X-Entity-Type: http-request` header) with a
264529
264540
  * JSON-Patch that sets `/scripts` to the canonical v3 shape
264530
264541
  * (`[{type:'afterResponse', code, language}]`). The v3 surface persists test
264531
264542
  * scripts under `scripts`, NOT `events`: a `/events` patch returns 200 but is
@@ -264538,7 +264549,7 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
264538
264549
  */
264539
264550
  async injectTests(collectionUid, type) {
264540
264551
  void type;
264541
- const cid = this.bareModelId(collectionUid);
264552
+ const cid = this.collectionItemsId(collectionUid);
264542
264553
  const listed = await this.gateway.requestJson({
264543
264554
  service: "collection",
264544
264555
  method: "get",
@@ -264709,7 +264720,7 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
264709
264720
  * Inject the deterministic OpenAPI contract assertions into every generated
264710
264721
  * request of a spec-generated collection, entirely over the v3 collection
264711
264722
  * surface (no PMAK, no v2.1.0 read/PUT):
264712
- * 1. `GET /v3/collections/:cid/items/` — flat item list (ids as full uids).
264723
+ * 1. `GET /v3/collections/:cid/items/` — flat item list (FULL public uid for `:cid`).
264713
264724
  * 2. `GET /v3/collections/:cid/items/:itemId` (`X-Entity-Type: http-request`)
264714
264725
  * — the full v3 IR record (method/url/headers/body) the matcher needs.
264715
264726
  * 3. `planContractItemScripts` matches each request to its OpenAPI operation
@@ -264720,7 +264731,7 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
264720
264731
  * Returns the non-fatal instrumentation warnings for the caller to surface.
264721
264732
  */
264722
264733
  async injectContractTests(collectionUid, index) {
264723
- const cid = this.bareModelId(collectionUid);
264734
+ const cid = this.collectionItemsId(collectionUid);
264724
264735
  const listed = await this.gateway.requestJson({
264725
264736
  service: "collection",
264726
264737
  method: "get",
@@ -265120,11 +265131,12 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
265120
265131
  if (!rawId) {
265121
265132
  throw new Error("Collection create did not return an id");
265122
265133
  }
265123
- const cid = this.bareModelId(rawId);
265134
+ const itemsCid = this.collectionItemsId(rawId);
265135
+ const rootCid = this.bareModelId(rawId);
265124
265136
  await options.onRootCreated?.(rawId);
265125
265137
  try {
265126
- await this.createItemTree(cid, asItemArray(v3.items), cid);
265127
- await this.applyCollectionLevelSettings(cid, v3, { rename: true });
265138
+ await this.createItemTree(itemsCid, asItemArray(v3.items), itemsCid);
265139
+ await this.applyCollectionLevelSettings(rootCid, v3, { rename: true });
265128
265140
  } catch (error2) {
265129
265141
  if (options.onRootCreated) throw error2;
265130
265142
  let cleanupError;
@@ -265151,22 +265163,23 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
265151
265163
  * from the converted v3 IR and reapply name/auth/variables.
265152
265164
  */
265153
265165
  async updateCollection(collectionUid, collection) {
265154
- const cid = this.bareModelId(collectionUid);
265166
+ const itemsCid = this.collectionItemsId(collectionUid);
265167
+ const rootCid = this.bareModelId(collectionUid);
265155
265168
  const v3 = this.normalizeCollectionForWrite(collection);
265156
- const existingItems = await this.listCollectionItems(cid);
265169
+ const existingItems = await this.listCollectionItems(itemsCid);
265157
265170
  for (const item of existingItems) {
265158
265171
  const itemId = String(item.id).trim();
265159
265172
  try {
265160
265173
  await this.gateway.requestJson({
265161
265174
  service: "collection",
265162
265175
  method: "delete",
265163
- path: `/v3/collections/${cid}/items/${itemId}`,
265176
+ path: `/v3/collections/${itemsCid}/items/${itemId}`,
265164
265177
  retry: "none",
265165
265178
  headers: { "X-Entity-Type": String(item.$kind ?? "http-request") }
265166
265179
  });
265167
265180
  } catch (error2) {
265168
265181
  if (isAmbiguousTransportError(error2)) {
265169
- const stillPresent = (await this.listCollectionItems(cid)).some(
265182
+ const stillPresent = (await this.listCollectionItems(itemsCid)).some(
265170
265183
  (candidate) => String(candidate.id ?? "").trim() === itemId
265171
265184
  );
265172
265185
  if (!stillPresent) continue;
@@ -265177,14 +265190,14 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
265177
265190
  }
265178
265191
  }
265179
265192
  }
265180
- const remainingItems = await this.listCollectionItems(cid);
265193
+ const remainingItems = await this.listCollectionItems(itemsCid);
265181
265194
  if (remainingItems.length > 0) {
265182
265195
  throw new Error(
265183
265196
  `Collection delete verification failed: ${remainingItems.length} old items remain`
265184
265197
  );
265185
265198
  }
265186
- await this.createItemTree(cid, asItemArray(v3.items), cid);
265187
- await this.applyCollectionLevelSettings(cid, v3, { rename: true, reconcileRemovals: true });
265199
+ await this.createItemTree(itemsCid, asItemArray(v3.items), itemsCid);
265200
+ await this.applyCollectionLevelSettings(rootCid, v3, { rename: true, reconcileRemovals: true });
265188
265201
  }
265189
265202
  };
265190
265203
 
package/dist/cli.cjs CHANGED
@@ -262575,7 +262575,8 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
262575
262575
  service: "collection",
262576
262576
  method: "patch",
262577
262577
  path: `/v3/collections/${this.bareModelId(collectionId)}`,
262578
- retry: "none",
262578
+ // Replacing a generated collection's name with the same value is idempotent.
262579
+ retry: "safe",
262579
262580
  body: [{ op: "replace", path: "/name", value: name }]
262580
262581
  });
262581
262582
  }
@@ -262774,15 +262775,25 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
262774
262775
  }
262775
262776
  // --- collection v3 mutation + tagging (live-proven 2026-06-30; see docs/REST-to-gateway.md) ---
262776
262777
  //
262777
- // These retire bootstrap's last asset-op PMAK dependencies. The gateway keys
262778
- // the v3 collection-items surface on the BARE model id (strip the `<owner>-`
262779
- // prefix) with a trailing slash; the tagging service is distinct from the
262780
- // collection service and takes the FULL uid.
262781
- /** `<owner>-<uuid>` public uid -> bare `<uuid>` model id (the v3 items surface keys on it). */
262778
+ // These retire bootstrap's last asset-op PMAK dependencies. Collection ROOT
262779
+ // routes (GET/PATCH/DELETE `/v3/collections/:id`) accept the bare model id.
262780
+ // Collection ITEMS routes (`/v3/collections/:id/items/...`) must use the FULL
262781
+ // public uid (`<owner>-<uuid>`): bare model ids are flaky on org-mode squads
262782
+ // (live-proven 2026-07-14 on team 172912 / Northwind immediate post-generation
262783
+ // `GET .../items/` returns 403 FORBIDDEN with bare id, 200 with full uid).
262784
+ // The tagging service is distinct and takes the FULL uid.
262785
+ /** `<owner>-<uuid>` public uid -> bare `<uuid>` model id (collection ROOT routes only). */
262782
262786
  bareModelId(uid) {
262783
262787
  const u = String(uid ?? "").trim();
262784
262788
  return u.includes("-") ? u.slice(u.indexOf("-") + 1) : u;
262785
262789
  }
262790
+ /**
262791
+ * Collection id for ITEMS routes. Prefer the full public uid; fall back to the
262792
+ * trimmed input when the caller already has a bare/model id.
262793
+ */
262794
+ collectionItemsId(uid) {
262795
+ return String(uid ?? "").trim();
262796
+ }
262786
262797
  /**
262787
262798
  * PATCH a freshly-created item's `/scripts`, tolerating the two transient
262788
262799
  * failures this immediate-after-create write is prone to on the shared gateway:
@@ -262841,9 +262852,9 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
262841
262852
  /**
262842
262853
  * Inject smoke-test assertions into every leaf request of a spec-generated
262843
262854
  * collection, over the v3 collection-items surface (no PMAK):
262844
- * 1. `GET /v3/collections/:cid/items/` (bare model id, trailing slash) — flat list.
262855
+ * 1. `GET /v3/collections/:cid/items/` (FULL public uid, trailing slash) — flat list.
262845
262856
  * 2. for each `http-request` leaf, `PATCH /v3/collections/:cid/items/:itemId`
262846
- * (full uid for `:itemId`, `X-Entity-Type: http-request` header) with a
262857
+ * (full uid for `:cid` and `:itemId`, `X-Entity-Type: http-request` header) with a
262847
262858
  * JSON-Patch that sets `/scripts` to the canonical v3 shape
262848
262859
  * (`[{type:'afterResponse', code, language}]`). The v3 surface persists test
262849
262860
  * scripts under `scripts`, NOT `events`: a `/events` patch returns 200 but is
@@ -262856,7 +262867,7 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
262856
262867
  */
262857
262868
  async injectTests(collectionUid, type) {
262858
262869
  void type;
262859
- const cid = this.bareModelId(collectionUid);
262870
+ const cid = this.collectionItemsId(collectionUid);
262860
262871
  const listed = await this.gateway.requestJson({
262861
262872
  service: "collection",
262862
262873
  method: "get",
@@ -263027,7 +263038,7 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
263027
263038
  * Inject the deterministic OpenAPI contract assertions into every generated
263028
263039
  * request of a spec-generated collection, entirely over the v3 collection
263029
263040
  * surface (no PMAK, no v2.1.0 read/PUT):
263030
- * 1. `GET /v3/collections/:cid/items/` — flat item list (ids as full uids).
263041
+ * 1. `GET /v3/collections/:cid/items/` — flat item list (FULL public uid for `:cid`).
263031
263042
  * 2. `GET /v3/collections/:cid/items/:itemId` (`X-Entity-Type: http-request`)
263032
263043
  * — the full v3 IR record (method/url/headers/body) the matcher needs.
263033
263044
  * 3. `planContractItemScripts` matches each request to its OpenAPI operation
@@ -263038,7 +263049,7 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
263038
263049
  * Returns the non-fatal instrumentation warnings for the caller to surface.
263039
263050
  */
263040
263051
  async injectContractTests(collectionUid, index) {
263041
- const cid = this.bareModelId(collectionUid);
263052
+ const cid = this.collectionItemsId(collectionUid);
263042
263053
  const listed = await this.gateway.requestJson({
263043
263054
  service: "collection",
263044
263055
  method: "get",
@@ -263438,11 +263449,12 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
263438
263449
  if (!rawId) {
263439
263450
  throw new Error("Collection create did not return an id");
263440
263451
  }
263441
- const cid = this.bareModelId(rawId);
263452
+ const itemsCid = this.collectionItemsId(rawId);
263453
+ const rootCid = this.bareModelId(rawId);
263442
263454
  await options.onRootCreated?.(rawId);
263443
263455
  try {
263444
- await this.createItemTree(cid, asItemArray(v3.items), cid);
263445
- await this.applyCollectionLevelSettings(cid, v3, { rename: true });
263456
+ await this.createItemTree(itemsCid, asItemArray(v3.items), itemsCid);
263457
+ await this.applyCollectionLevelSettings(rootCid, v3, { rename: true });
263446
263458
  } catch (error) {
263447
263459
  if (options.onRootCreated) throw error;
263448
263460
  let cleanupError;
@@ -263469,22 +263481,23 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
263469
263481
  * from the converted v3 IR and reapply name/auth/variables.
263470
263482
  */
263471
263483
  async updateCollection(collectionUid, collection) {
263472
- const cid = this.bareModelId(collectionUid);
263484
+ const itemsCid = this.collectionItemsId(collectionUid);
263485
+ const rootCid = this.bareModelId(collectionUid);
263473
263486
  const v3 = this.normalizeCollectionForWrite(collection);
263474
- const existingItems = await this.listCollectionItems(cid);
263487
+ const existingItems = await this.listCollectionItems(itemsCid);
263475
263488
  for (const item of existingItems) {
263476
263489
  const itemId = String(item.id).trim();
263477
263490
  try {
263478
263491
  await this.gateway.requestJson({
263479
263492
  service: "collection",
263480
263493
  method: "delete",
263481
- path: `/v3/collections/${cid}/items/${itemId}`,
263494
+ path: `/v3/collections/${itemsCid}/items/${itemId}`,
263482
263495
  retry: "none",
263483
263496
  headers: { "X-Entity-Type": String(item.$kind ?? "http-request") }
263484
263497
  });
263485
263498
  } catch (error) {
263486
263499
  if (isAmbiguousTransportError(error)) {
263487
- const stillPresent = (await this.listCollectionItems(cid)).some(
263500
+ const stillPresent = (await this.listCollectionItems(itemsCid)).some(
263488
263501
  (candidate) => String(candidate.id ?? "").trim() === itemId
263489
263502
  );
263490
263503
  if (!stillPresent) continue;
@@ -263495,14 +263508,14 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
263495
263508
  }
263496
263509
  }
263497
263510
  }
263498
- const remainingItems = await this.listCollectionItems(cid);
263511
+ const remainingItems = await this.listCollectionItems(itemsCid);
263499
263512
  if (remainingItems.length > 0) {
263500
263513
  throw new Error(
263501
263514
  `Collection delete verification failed: ${remainingItems.length} old items remain`
263502
263515
  );
263503
263516
  }
263504
- await this.createItemTree(cid, asItemArray(v3.items), cid);
263505
- await this.applyCollectionLevelSettings(cid, v3, { rename: true, reconcileRemovals: true });
263517
+ await this.createItemTree(itemsCid, asItemArray(v3.items), itemsCid);
263518
+ await this.applyCollectionLevelSettings(rootCid, v3, { rename: true, reconcileRemovals: true });
263506
263519
  }
263507
263520
  };
263508
263521
 
@@ -311847,6 +311860,44 @@ function createBootstrapDependencies(inputs, factories, orgMode = false) {
311847
311860
  }
311848
311861
 
311849
311862
  // src/cli.ts
311863
+ var HELP_TEXT = `Usage: postman-bootstrap [options]
311864
+
311865
+ Bootstrap Postman workspaces, specs, and collections from OpenAPI.
311866
+
311867
+ Options:
311868
+ --help Show this help and exit
311869
+ --version Show version and exit
311870
+ --result-json <path> Write JSON result (default: postman-bootstrap-result.json)
311871
+ --dotenv-path <path> Optional dotenv output path
311872
+ --<input-name> <value> Action input as kebab-case flag (same names as action.yml)
311873
+
311874
+ Examples:
311875
+ postman-bootstrap --help
311876
+ postman-bootstrap --project-name demo --spec-path ./openapi.yaml ...
311877
+ `;
311878
+ function wantsHelp(argv) {
311879
+ return argv.includes("--help") || argv.includes("-h");
311880
+ }
311881
+ function wantsVersion(argv) {
311882
+ return argv.includes("--version") || argv.includes("-V");
311883
+ }
311884
+ function resolvePackageVersion() {
311885
+ const candidates = [];
311886
+ if (typeof __filename === "string" && __filename) {
311887
+ candidates.push(import_node_path5.default.join(import_node_path5.default.dirname(__filename), "..", "package.json"));
311888
+ }
311889
+ candidates.push(import_node_path5.default.join(process.cwd(), "package.json"));
311890
+ for (const packageJsonPath of candidates) {
311891
+ try {
311892
+ const packageJson = JSON.parse((0, import_node_fs6.readFileSync)(packageJsonPath, "utf8"));
311893
+ if (packageJson.name === "@postman-cse/onboarding-bootstrap" && packageJson.version) {
311894
+ return String(packageJson.version).trim();
311895
+ }
311896
+ } catch {
311897
+ }
311898
+ }
311899
+ return "0.0.0";
311900
+ }
311850
311901
  var ConsoleReporter = class {
311851
311902
  error(message) {
311852
311903
  console.error(message);
@@ -312110,6 +312161,19 @@ function validateCliInputs(inputs) {
312110
312161
  }
312111
312162
  }
312112
312163
  async function runCli(argv = process.argv.slice(2), runtime = {}) {
312164
+ const writeStdout = runtime.writeStdout ?? ((chunk) => process.stdout.write(chunk));
312165
+ if (wantsHelp(argv) && wantsVersion(argv)) {
312166
+ throw new Error("Cannot use --help and --version together");
312167
+ }
312168
+ if (wantsHelp(argv)) {
312169
+ writeStdout(HELP_TEXT);
312170
+ return;
312171
+ }
312172
+ if (wantsVersion(argv)) {
312173
+ writeStdout(`${resolvePackageVersion()}
312174
+ `);
312175
+ return;
312176
+ }
312113
312177
  const env = runtime.env ?? process.env;
312114
312178
  const config = parseCliArgs(argv, env);
312115
312179
  const inputs = resolveInputs(config.inputEnv);
@@ -312138,7 +312202,6 @@ async function runCli(argv = process.argv.slice(2), runtime = {}) {
312138
312202
  const result = await (runtime.executeBootstrap ?? runBootstrap)(inputs, dependencies);
312139
312203
  await writeOptionalFile(config.resultJsonPath, JSON.stringify(result, null, 2));
312140
312204
  await writeOptionalFile(config.dotenvPath, toDotenv(result));
312141
- const writeStdout = runtime.writeStdout ?? ((chunk) => process.stdout.write(chunk));
312142
312205
  writeStdout(`${JSON.stringify(result, null, 2)}
312143
312206
  `);
312144
312207
  }
package/dist/index.cjs CHANGED
@@ -264276,7 +264276,8 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
264276
264276
  service: "collection",
264277
264277
  method: "patch",
264278
264278
  path: `/v3/collections/${this.bareModelId(collectionId)}`,
264279
- retry: "none",
264279
+ // Replacing a generated collection's name with the same value is idempotent.
264280
+ retry: "safe",
264280
264281
  body: [{ op: "replace", path: "/name", value: name }]
264281
264282
  });
264282
264283
  }
@@ -264475,15 +264476,25 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
264475
264476
  }
264476
264477
  // --- collection v3 mutation + tagging (live-proven 2026-06-30; see docs/REST-to-gateway.md) ---
264477
264478
  //
264478
- // These retire bootstrap's last asset-op PMAK dependencies. The gateway keys
264479
- // the v3 collection-items surface on the BARE model id (strip the `<owner>-`
264480
- // prefix) with a trailing slash; the tagging service is distinct from the
264481
- // collection service and takes the FULL uid.
264482
- /** `<owner>-<uuid>` public uid -> bare `<uuid>` model id (the v3 items surface keys on it). */
264479
+ // These retire bootstrap's last asset-op PMAK dependencies. Collection ROOT
264480
+ // routes (GET/PATCH/DELETE `/v3/collections/:id`) accept the bare model id.
264481
+ // Collection ITEMS routes (`/v3/collections/:id/items/...`) must use the FULL
264482
+ // public uid (`<owner>-<uuid>`): bare model ids are flaky on org-mode squads
264483
+ // (live-proven 2026-07-14 on team 172912 / Northwind immediate post-generation
264484
+ // `GET .../items/` returns 403 FORBIDDEN with bare id, 200 with full uid).
264485
+ // The tagging service is distinct and takes the FULL uid.
264486
+ /** `<owner>-<uuid>` public uid -> bare `<uuid>` model id (collection ROOT routes only). */
264483
264487
  bareModelId(uid) {
264484
264488
  const u = String(uid ?? "").trim();
264485
264489
  return u.includes("-") ? u.slice(u.indexOf("-") + 1) : u;
264486
264490
  }
264491
+ /**
264492
+ * Collection id for ITEMS routes. Prefer the full public uid; fall back to the
264493
+ * trimmed input when the caller already has a bare/model id.
264494
+ */
264495
+ collectionItemsId(uid) {
264496
+ return String(uid ?? "").trim();
264497
+ }
264487
264498
  /**
264488
264499
  * PATCH a freshly-created item's `/scripts`, tolerating the two transient
264489
264500
  * failures this immediate-after-create write is prone to on the shared gateway:
@@ -264542,9 +264553,9 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
264542
264553
  /**
264543
264554
  * Inject smoke-test assertions into every leaf request of a spec-generated
264544
264555
  * collection, over the v3 collection-items surface (no PMAK):
264545
- * 1. `GET /v3/collections/:cid/items/` (bare model id, trailing slash) — flat list.
264556
+ * 1. `GET /v3/collections/:cid/items/` (FULL public uid, trailing slash) — flat list.
264546
264557
  * 2. for each `http-request` leaf, `PATCH /v3/collections/:cid/items/:itemId`
264547
- * (full uid for `:itemId`, `X-Entity-Type: http-request` header) with a
264558
+ * (full uid for `:cid` and `:itemId`, `X-Entity-Type: http-request` header) with a
264548
264559
  * JSON-Patch that sets `/scripts` to the canonical v3 shape
264549
264560
  * (`[{type:'afterResponse', code, language}]`). The v3 surface persists test
264550
264561
  * scripts under `scripts`, NOT `events`: a `/events` patch returns 200 but is
@@ -264557,7 +264568,7 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
264557
264568
  */
264558
264569
  async injectTests(collectionUid, type) {
264559
264570
  void type;
264560
- const cid = this.bareModelId(collectionUid);
264571
+ const cid = this.collectionItemsId(collectionUid);
264561
264572
  const listed = await this.gateway.requestJson({
264562
264573
  service: "collection",
264563
264574
  method: "get",
@@ -264728,7 +264739,7 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
264728
264739
  * Inject the deterministic OpenAPI contract assertions into every generated
264729
264740
  * request of a spec-generated collection, entirely over the v3 collection
264730
264741
  * surface (no PMAK, no v2.1.0 read/PUT):
264731
- * 1. `GET /v3/collections/:cid/items/` — flat item list (ids as full uids).
264742
+ * 1. `GET /v3/collections/:cid/items/` — flat item list (FULL public uid for `:cid`).
264732
264743
  * 2. `GET /v3/collections/:cid/items/:itemId` (`X-Entity-Type: http-request`)
264733
264744
  * — the full v3 IR record (method/url/headers/body) the matcher needs.
264734
264745
  * 3. `planContractItemScripts` matches each request to its OpenAPI operation
@@ -264739,7 +264750,7 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
264739
264750
  * Returns the non-fatal instrumentation warnings for the caller to surface.
264740
264751
  */
264741
264752
  async injectContractTests(collectionUid, index) {
264742
- const cid = this.bareModelId(collectionUid);
264753
+ const cid = this.collectionItemsId(collectionUid);
264743
264754
  const listed = await this.gateway.requestJson({
264744
264755
  service: "collection",
264745
264756
  method: "get",
@@ -265139,11 +265150,12 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
265139
265150
  if (!rawId) {
265140
265151
  throw new Error("Collection create did not return an id");
265141
265152
  }
265142
- const cid = this.bareModelId(rawId);
265153
+ const itemsCid = this.collectionItemsId(rawId);
265154
+ const rootCid = this.bareModelId(rawId);
265143
265155
  await options.onRootCreated?.(rawId);
265144
265156
  try {
265145
- await this.createItemTree(cid, asItemArray(v3.items), cid);
265146
- await this.applyCollectionLevelSettings(cid, v3, { rename: true });
265157
+ await this.createItemTree(itemsCid, asItemArray(v3.items), itemsCid);
265158
+ await this.applyCollectionLevelSettings(rootCid, v3, { rename: true });
265147
265159
  } catch (error2) {
265148
265160
  if (options.onRootCreated) throw error2;
265149
265161
  let cleanupError;
@@ -265170,22 +265182,23 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
265170
265182
  * from the converted v3 IR and reapply name/auth/variables.
265171
265183
  */
265172
265184
  async updateCollection(collectionUid, collection) {
265173
- const cid = this.bareModelId(collectionUid);
265185
+ const itemsCid = this.collectionItemsId(collectionUid);
265186
+ const rootCid = this.bareModelId(collectionUid);
265174
265187
  const v3 = this.normalizeCollectionForWrite(collection);
265175
- const existingItems = await this.listCollectionItems(cid);
265188
+ const existingItems = await this.listCollectionItems(itemsCid);
265176
265189
  for (const item of existingItems) {
265177
265190
  const itemId = String(item.id).trim();
265178
265191
  try {
265179
265192
  await this.gateway.requestJson({
265180
265193
  service: "collection",
265181
265194
  method: "delete",
265182
- path: `/v3/collections/${cid}/items/${itemId}`,
265195
+ path: `/v3/collections/${itemsCid}/items/${itemId}`,
265183
265196
  retry: "none",
265184
265197
  headers: { "X-Entity-Type": String(item.$kind ?? "http-request") }
265185
265198
  });
265186
265199
  } catch (error2) {
265187
265200
  if (isAmbiguousTransportError(error2)) {
265188
- const stillPresent = (await this.listCollectionItems(cid)).some(
265201
+ const stillPresent = (await this.listCollectionItems(itemsCid)).some(
265189
265202
  (candidate) => String(candidate.id ?? "").trim() === itemId
265190
265203
  );
265191
265204
  if (!stillPresent) continue;
@@ -265196,14 +265209,14 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
265196
265209
  }
265197
265210
  }
265198
265211
  }
265199
- const remainingItems = await this.listCollectionItems(cid);
265212
+ const remainingItems = await this.listCollectionItems(itemsCid);
265200
265213
  if (remainingItems.length > 0) {
265201
265214
  throw new Error(
265202
265215
  `Collection delete verification failed: ${remainingItems.length} old items remain`
265203
265216
  );
265204
265217
  }
265205
- await this.createItemTree(cid, asItemArray(v3.items), cid);
265206
- await this.applyCollectionLevelSettings(cid, v3, { rename: true, reconcileRemovals: true });
265218
+ await this.createItemTree(itemsCid, asItemArray(v3.items), itemsCid);
265219
+ await this.applyCollectionLevelSettings(rootCid, v3, { rename: true, reconcileRemovals: true });
265207
265220
  }
265208
265221
  };
265209
265222
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@postman-cse/onboarding-bootstrap",
3
- "version": "2.9.1",
3
+ "version": "2.9.3",
4
4
  "description": "Bootstrap Postman workspaces, specs, and collections from OpenAPI.",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -18,8 +18,10 @@
18
18
  },
19
19
  "scripts": {
20
20
  "prepare": "git config core.hooksPath .githooks",
21
- "build": "npm run typecheck && rm -rf dist && esbuild src/index.ts --bundle --platform=node --target=node24 --format=cjs --alias:jsonc-parser=jsonc-parser/lib/esm/main.js --outfile=dist/index.cjs && esbuild src/main.ts --bundle --platform=node --target=node24 --format=cjs --alias:jsonc-parser=jsonc-parser/lib/esm/main.js --outfile=dist/action.cjs && esbuild src/cli.ts --bundle --platform=node --target=node24 --format=cjs --alias:jsonc-parser=jsonc-parser/lib/esm/main.js --outfile=dist/cli.cjs",
22
- "verify:dist": "npm run build && git diff --ignore-space-at-eol --text --exit-code -- dist",
21
+ "bundle": "rm -rf dist && esbuild src/index.ts --bundle --platform=node --target=node24 --format=cjs --alias:jsonc-parser=jsonc-parser/lib/esm/main.js --outfile=dist/index.cjs && esbuild src/main.ts --bundle --platform=node --target=node24 --format=cjs --alias:jsonc-parser=jsonc-parser/lib/esm/main.js --outfile=dist/action.cjs && esbuild src/cli.ts --bundle --platform=node --target=node24 --format=cjs --alias:jsonc-parser=jsonc-parser/lib/esm/main.js --banner:js='#!/usr/bin/env node' --outfile=dist/cli.cjs && chmod 755 dist/cli.cjs",
22
+ "build": "npm run typecheck && npm run bundle",
23
+ "verify:dist:assert": "git diff --ignore-space-at-eol --text --exit-code -- dist && node scripts/verify-dist-artifact.mjs",
24
+ "verify:dist": "npm run build && npm run verify:dist:assert",
23
25
  "docs:tables": "node scripts/render-action-tables.mjs",
24
26
  "lint": "eslint .",
25
27
  "lint:fix": "eslint . --fix",