@postman-cs/onboarding-repo-sync 2.10.5 → 2.10.7
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 +76 -2
- package/dist/cli.cjs +142 -32
- package/dist/index.cjs +76 -2
- package/package.json +1 -1
package/dist/action.cjs
CHANGED
|
@@ -127537,6 +127537,7 @@ function requireMockVisibility(mock, requested) {
|
|
|
127537
127537
|
return mock;
|
|
127538
127538
|
}
|
|
127539
127539
|
var MAX_CREATE_FLIGHTS = 256;
|
|
127540
|
+
var COLLECTION_LIST_PAGE_LIMIT = 100;
|
|
127540
127541
|
var createFlights = /* @__PURE__ */ new Map();
|
|
127541
127542
|
var PostmanGatewayAssetsClient = class {
|
|
127542
127543
|
gateway;
|
|
@@ -127708,8 +127709,80 @@ var PostmanGatewayAssetsClient = class {
|
|
|
127708
127709
|
method: "get",
|
|
127709
127710
|
path: `/specifications/${id}/collections`
|
|
127710
127711
|
});
|
|
127711
|
-
|
|
127712
|
-
return
|
|
127712
|
+
if (!Array.isArray(response?.data)) throw new Error("SPEC_COLLECTION_LIST_RESPONSE_INVALID");
|
|
127713
|
+
return response.data.map((value) => {
|
|
127714
|
+
const entry = this.asRecord(value);
|
|
127715
|
+
const rawUid = entry?.collection ?? entry?.collectionId ?? entry?.id;
|
|
127716
|
+
if (!entry || typeof rawUid !== "string" || entry.name !== void 0 && typeof entry.name !== "string") {
|
|
127717
|
+
throw new Error("SPEC_COLLECTION_LIST_RESPONSE_INVALID");
|
|
127718
|
+
}
|
|
127719
|
+
const uid = this.requireSafePathSegment(rawUid, "Specification collection UID");
|
|
127720
|
+
return { uid, name: typeof entry.name === "string" ? entry.name.trim() : "" };
|
|
127721
|
+
});
|
|
127722
|
+
}
|
|
127723
|
+
/**
|
|
127724
|
+
* Authoritative workspace collection-name snapshot for GC. Drain the v3
|
|
127725
|
+
* collection service's cursor before returning: a partial inventory must not
|
|
127726
|
+
* authorize parent/spec deletion. This list route replaces per-relation full
|
|
127727
|
+
* exports in GC; `getCollection` remains reserved for repo file materialization.
|
|
127728
|
+
*/
|
|
127729
|
+
async listCollections(workspaceId) {
|
|
127730
|
+
const ws = this.requireSafePathSegment(workspaceId, "Workspace UID");
|
|
127731
|
+
const rows = [];
|
|
127732
|
+
const seenCursors = /* @__PURE__ */ new Set();
|
|
127733
|
+
let cursor;
|
|
127734
|
+
for (let page = 0; page < COLLECTION_LIST_PAGE_LIMIT; page += 1) {
|
|
127735
|
+
const response = await this.gateway.requestJson({
|
|
127736
|
+
service: "collection",
|
|
127737
|
+
method: "get",
|
|
127738
|
+
path: `/v3/collections/?workspace=${ws}`,
|
|
127739
|
+
...cursor ? { query: { cursor } } : {}
|
|
127740
|
+
});
|
|
127741
|
+
if (!Array.isArray(response?.data)) throw new Error("COLLECTION_LIST_RESPONSE_INVALID");
|
|
127742
|
+
for (const value of response.data) {
|
|
127743
|
+
const record = this.asRecord(value);
|
|
127744
|
+
const rawUid = record?.id ?? record?.uid;
|
|
127745
|
+
const rawName = record?.name ?? record?.title;
|
|
127746
|
+
if (typeof rawUid !== "string" || typeof rawName !== "string") {
|
|
127747
|
+
throw new Error("COLLECTION_LIST_RESPONSE_INVALID");
|
|
127748
|
+
}
|
|
127749
|
+
const uid = rawUid.trim();
|
|
127750
|
+
const name = rawName.trim();
|
|
127751
|
+
if (!uid || !name || !/^[A-Za-z0-9._~-]+$/.test(uid) || uid === "." || uid === "..") {
|
|
127752
|
+
throw new Error("COLLECTION_LIST_RESPONSE_INVALID");
|
|
127753
|
+
}
|
|
127754
|
+
rows.push({ uid, name });
|
|
127755
|
+
}
|
|
127756
|
+
const meta = response.meta === void 0 ? null : this.asRecord(response.meta);
|
|
127757
|
+
if (response.meta !== void 0 && response.meta !== null && !meta) {
|
|
127758
|
+
throw new Error("COLLECTION_LIST_CURSOR_INVALID");
|
|
127759
|
+
}
|
|
127760
|
+
const paginationValue = meta?.pagination;
|
|
127761
|
+
const pagination = paginationValue === void 0 ? null : this.asRecord(paginationValue);
|
|
127762
|
+
if (paginationValue !== void 0 && paginationValue !== null && !pagination) {
|
|
127763
|
+
throw new Error("COLLECTION_LIST_CURSOR_INVALID");
|
|
127764
|
+
}
|
|
127765
|
+
const cursorValue = meta?.cursor;
|
|
127766
|
+
const cursorEnvelope = cursorValue === void 0 ? null : this.asRecord(cursorValue);
|
|
127767
|
+
if (cursorValue !== void 0 && cursorValue !== null && !cursorEnvelope) {
|
|
127768
|
+
throw new Error("COLLECTION_LIST_CURSOR_INVALID");
|
|
127769
|
+
}
|
|
127770
|
+
const candidates = [pagination?.nextPage, cursorEnvelope?.next, meta?.nextCursor, response.nextCursor].filter((value) => value !== void 0 && value !== null && value !== "");
|
|
127771
|
+
if (candidates.some((value) => typeof value !== "string")) {
|
|
127772
|
+
throw new Error("COLLECTION_LIST_CURSOR_INVALID");
|
|
127773
|
+
}
|
|
127774
|
+
const nextCursors = [...new Set(candidates.map((value) => String(value).trim()).filter(Boolean))];
|
|
127775
|
+
if (nextCursors.length > 1) throw new Error("COLLECTION_LIST_CURSOR_AMBIGUOUS");
|
|
127776
|
+
const next = nextCursors[0];
|
|
127777
|
+
if (!next) return rows;
|
|
127778
|
+
if (seenCursors.has(next)) throw new Error("COLLECTION_LIST_CURSOR_REPEATED");
|
|
127779
|
+
seenCursors.add(next);
|
|
127780
|
+
if (page === COLLECTION_LIST_PAGE_LIMIT - 1) {
|
|
127781
|
+
throw new Error("COLLECTION_LIST_PAGE_LIMIT_EXCEEDED");
|
|
127782
|
+
}
|
|
127783
|
+
cursor = next;
|
|
127784
|
+
}
|
|
127785
|
+
throw new Error("COLLECTION_LIST_PAGE_LIMIT_EXCEEDED");
|
|
127713
127786
|
}
|
|
127714
127787
|
async deleteSpec(specId) {
|
|
127715
127788
|
const id = this.requireSafePathSegment(specId, "Specification UID");
|
|
@@ -132164,6 +132237,7 @@ function createRepoSyncDependencies(inputs, resolved, factories, options = {}) {
|
|
|
132164
132237
|
deleteMock: gatewayAssets.deleteMock.bind(gatewayAssets),
|
|
132165
132238
|
deleteMonitor: gatewayAssets.deleteMonitor.bind(gatewayAssets),
|
|
132166
132239
|
deleteCollection: gatewayAssets.deleteCollection.bind(gatewayAssets),
|
|
132240
|
+
listCollections: gatewayAssets.listCollections.bind(gatewayAssets),
|
|
132167
132241
|
listSpecifications: gatewayAssets.listSpecifications.bind(gatewayAssets),
|
|
132168
132242
|
getSpecContent: gatewayAssets.getSpecContent.bind(gatewayAssets),
|
|
132169
132243
|
listSpecCollections: gatewayAssets.listSpecCollections.bind(gatewayAssets),
|
package/dist/cli.cjs
CHANGED
|
@@ -125642,6 +125642,7 @@ function requireMockVisibility(mock, requested) {
|
|
|
125642
125642
|
return mock;
|
|
125643
125643
|
}
|
|
125644
125644
|
var MAX_CREATE_FLIGHTS = 256;
|
|
125645
|
+
var COLLECTION_LIST_PAGE_LIMIT = 100;
|
|
125645
125646
|
var createFlights = /* @__PURE__ */ new Map();
|
|
125646
125647
|
var PostmanGatewayAssetsClient = class {
|
|
125647
125648
|
gateway;
|
|
@@ -125813,8 +125814,80 @@ var PostmanGatewayAssetsClient = class {
|
|
|
125813
125814
|
method: "get",
|
|
125814
125815
|
path: `/specifications/${id}/collections`
|
|
125815
125816
|
});
|
|
125816
|
-
|
|
125817
|
-
return
|
|
125817
|
+
if (!Array.isArray(response?.data)) throw new Error("SPEC_COLLECTION_LIST_RESPONSE_INVALID");
|
|
125818
|
+
return response.data.map((value) => {
|
|
125819
|
+
const entry = this.asRecord(value);
|
|
125820
|
+
const rawUid = entry?.collection ?? entry?.collectionId ?? entry?.id;
|
|
125821
|
+
if (!entry || typeof rawUid !== "string" || entry.name !== void 0 && typeof entry.name !== "string") {
|
|
125822
|
+
throw new Error("SPEC_COLLECTION_LIST_RESPONSE_INVALID");
|
|
125823
|
+
}
|
|
125824
|
+
const uid = this.requireSafePathSegment(rawUid, "Specification collection UID");
|
|
125825
|
+
return { uid, name: typeof entry.name === "string" ? entry.name.trim() : "" };
|
|
125826
|
+
});
|
|
125827
|
+
}
|
|
125828
|
+
/**
|
|
125829
|
+
* Authoritative workspace collection-name snapshot for GC. Drain the v3
|
|
125830
|
+
* collection service's cursor before returning: a partial inventory must not
|
|
125831
|
+
* authorize parent/spec deletion. This list route replaces per-relation full
|
|
125832
|
+
* exports in GC; `getCollection` remains reserved for repo file materialization.
|
|
125833
|
+
*/
|
|
125834
|
+
async listCollections(workspaceId) {
|
|
125835
|
+
const ws = this.requireSafePathSegment(workspaceId, "Workspace UID");
|
|
125836
|
+
const rows = [];
|
|
125837
|
+
const seenCursors = /* @__PURE__ */ new Set();
|
|
125838
|
+
let cursor;
|
|
125839
|
+
for (let page = 0; page < COLLECTION_LIST_PAGE_LIMIT; page += 1) {
|
|
125840
|
+
const response = await this.gateway.requestJson({
|
|
125841
|
+
service: "collection",
|
|
125842
|
+
method: "get",
|
|
125843
|
+
path: `/v3/collections/?workspace=${ws}`,
|
|
125844
|
+
...cursor ? { query: { cursor } } : {}
|
|
125845
|
+
});
|
|
125846
|
+
if (!Array.isArray(response?.data)) throw new Error("COLLECTION_LIST_RESPONSE_INVALID");
|
|
125847
|
+
for (const value of response.data) {
|
|
125848
|
+
const record = this.asRecord(value);
|
|
125849
|
+
const rawUid = record?.id ?? record?.uid;
|
|
125850
|
+
const rawName = record?.name ?? record?.title;
|
|
125851
|
+
if (typeof rawUid !== "string" || typeof rawName !== "string") {
|
|
125852
|
+
throw new Error("COLLECTION_LIST_RESPONSE_INVALID");
|
|
125853
|
+
}
|
|
125854
|
+
const uid = rawUid.trim();
|
|
125855
|
+
const name = rawName.trim();
|
|
125856
|
+
if (!uid || !name || !/^[A-Za-z0-9._~-]+$/.test(uid) || uid === "." || uid === "..") {
|
|
125857
|
+
throw new Error("COLLECTION_LIST_RESPONSE_INVALID");
|
|
125858
|
+
}
|
|
125859
|
+
rows.push({ uid, name });
|
|
125860
|
+
}
|
|
125861
|
+
const meta = response.meta === void 0 ? null : this.asRecord(response.meta);
|
|
125862
|
+
if (response.meta !== void 0 && response.meta !== null && !meta) {
|
|
125863
|
+
throw new Error("COLLECTION_LIST_CURSOR_INVALID");
|
|
125864
|
+
}
|
|
125865
|
+
const paginationValue = meta?.pagination;
|
|
125866
|
+
const pagination = paginationValue === void 0 ? null : this.asRecord(paginationValue);
|
|
125867
|
+
if (paginationValue !== void 0 && paginationValue !== null && !pagination) {
|
|
125868
|
+
throw new Error("COLLECTION_LIST_CURSOR_INVALID");
|
|
125869
|
+
}
|
|
125870
|
+
const cursorValue = meta?.cursor;
|
|
125871
|
+
const cursorEnvelope = cursorValue === void 0 ? null : this.asRecord(cursorValue);
|
|
125872
|
+
if (cursorValue !== void 0 && cursorValue !== null && !cursorEnvelope) {
|
|
125873
|
+
throw new Error("COLLECTION_LIST_CURSOR_INVALID");
|
|
125874
|
+
}
|
|
125875
|
+
const candidates = [pagination?.nextPage, cursorEnvelope?.next, meta?.nextCursor, response.nextCursor].filter((value) => value !== void 0 && value !== null && value !== "");
|
|
125876
|
+
if (candidates.some((value) => typeof value !== "string")) {
|
|
125877
|
+
throw new Error("COLLECTION_LIST_CURSOR_INVALID");
|
|
125878
|
+
}
|
|
125879
|
+
const nextCursors = [...new Set(candidates.map((value) => String(value).trim()).filter(Boolean))];
|
|
125880
|
+
if (nextCursors.length > 1) throw new Error("COLLECTION_LIST_CURSOR_AMBIGUOUS");
|
|
125881
|
+
const next = nextCursors[0];
|
|
125882
|
+
if (!next) return rows;
|
|
125883
|
+
if (seenCursors.has(next)) throw new Error("COLLECTION_LIST_CURSOR_REPEATED");
|
|
125884
|
+
seenCursors.add(next);
|
|
125885
|
+
if (page === COLLECTION_LIST_PAGE_LIMIT - 1) {
|
|
125886
|
+
throw new Error("COLLECTION_LIST_PAGE_LIMIT_EXCEEDED");
|
|
125887
|
+
}
|
|
125888
|
+
cursor = next;
|
|
125889
|
+
}
|
|
125890
|
+
throw new Error("COLLECTION_LIST_PAGE_LIMIT_EXCEEDED");
|
|
125818
125891
|
}
|
|
125819
125892
|
async deleteSpec(specId) {
|
|
125820
125893
|
const id = this.requireSafePathSegment(specId, "Specification UID");
|
|
@@ -130073,6 +130146,7 @@ function createRepoSyncDependencies(inputs, resolved, factories, options = {}) {
|
|
|
130073
130146
|
deleteMock: gatewayAssets.deleteMock.bind(gatewayAssets),
|
|
130074
130147
|
deleteMonitor: gatewayAssets.deleteMonitor.bind(gatewayAssets),
|
|
130075
130148
|
deleteCollection: gatewayAssets.deleteCollection.bind(gatewayAssets),
|
|
130149
|
+
listCollections: gatewayAssets.listCollections.bind(gatewayAssets),
|
|
130076
130150
|
listSpecifications: gatewayAssets.listSpecifications.bind(gatewayAssets),
|
|
130077
130151
|
getSpecContent: gatewayAssets.getSpecContent.bind(gatewayAssets),
|
|
130078
130152
|
listSpecCollections: gatewayAssets.listSpecCollections.bind(gatewayAssets),
|
|
@@ -130389,28 +130463,53 @@ function markerFromSpecContent(content) {
|
|
|
130389
130463
|
function isGcCandidateName(name) {
|
|
130390
130464
|
return / @[A-Za-z0-9._-]+/.test(name) || /^\[[A-Z][A-Z0-9]*\] /.test(name);
|
|
130391
130465
|
}
|
|
130392
|
-
|
|
130393
|
-
|
|
130394
|
-
|
|
130395
|
-
|
|
130396
|
-
|
|
130466
|
+
var BARE_COLLECTION_MODEL_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
130467
|
+
var PUBLIC_COLLECTION_MODEL_ID = /^\d+-([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/i;
|
|
130468
|
+
var SAFE_COLLECTION_ID = /^[A-Za-z0-9._~-]+$/;
|
|
130469
|
+
function normalizedCollectionIdentity(raw) {
|
|
130470
|
+
if (typeof raw !== "string") return void 0;
|
|
130471
|
+
const value = raw.trim();
|
|
130472
|
+
if (!value || value === "." || value === ".." || !SAFE_COLLECTION_ID.test(value)) return void 0;
|
|
130473
|
+
const publicMatch = PUBLIC_COLLECTION_MODEL_ID.exec(value);
|
|
130474
|
+
if (publicMatch) return publicMatch[1].toLowerCase();
|
|
130475
|
+
if (BARE_COLLECTION_MODEL_ID.test(value)) return value.toLowerCase();
|
|
130476
|
+
return value;
|
|
130477
|
+
}
|
|
130478
|
+
function indexCollectionInventory(rows) {
|
|
130479
|
+
if (!Array.isArray(rows)) throw new Error("COLLECTION_INVENTORY_INVALID");
|
|
130480
|
+
const index = /* @__PURE__ */ new Map();
|
|
130481
|
+
for (const raw of rows) {
|
|
130482
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
130483
|
+
throw new Error("COLLECTION_INVENTORY_INVALID");
|
|
130484
|
+
}
|
|
130485
|
+
const record = raw;
|
|
130486
|
+
const identity = normalizedCollectionIdentity(record.uid);
|
|
130487
|
+
const uid = typeof record.uid === "string" ? record.uid.trim() : "";
|
|
130488
|
+
const name = typeof record.name === "string" ? record.name.trim() : "";
|
|
130489
|
+
if (!identity || !uid || !name) throw new Error("COLLECTION_INVENTORY_INVALID");
|
|
130490
|
+
const matches = index.get(identity) ?? [];
|
|
130491
|
+
matches.push({ uid, name });
|
|
130492
|
+
index.set(identity, matches);
|
|
130493
|
+
}
|
|
130494
|
+
return index;
|
|
130397
130495
|
}
|
|
130398
130496
|
async function collectGcCandidates(postman, workspaceId) {
|
|
130399
130497
|
const candidates = [];
|
|
130400
|
-
|
|
130401
|
-
|
|
130402
|
-
|
|
130403
|
-
|
|
130404
|
-
|
|
130405
|
-
|
|
130406
|
-
|
|
130407
|
-
|
|
130408
|
-
|
|
130409
|
-
|
|
130410
|
-
|
|
130411
|
-
|
|
130498
|
+
let collectionInventory;
|
|
130499
|
+
try {
|
|
130500
|
+
collectionInventory = indexCollectionInventory(await postman.listCollections(workspaceId));
|
|
130501
|
+
} catch {
|
|
130502
|
+
collectionInventory = void 0;
|
|
130503
|
+
}
|
|
130504
|
+
const resolveGeneratedCollection = (uid) => {
|
|
130505
|
+
const identity = normalizedCollectionIdentity(uid);
|
|
130506
|
+
if (!identity || !collectionInventory) return void 0;
|
|
130507
|
+
const matches = collectionInventory.get(identity) ?? [];
|
|
130508
|
+
if (matches.length !== 1) return void 0;
|
|
130509
|
+
const match = matches[0];
|
|
130510
|
+
return isGcCandidateName(match.name) ? match : void 0;
|
|
130412
130511
|
};
|
|
130413
|
-
const
|
|
130512
|
+
const discoveredCollectionIdentities = /* @__PURE__ */ new Set();
|
|
130414
130513
|
const environments = await postman.listEnvironments(workspaceId);
|
|
130415
130514
|
for (const env of environments) {
|
|
130416
130515
|
if (!isGcCandidateName(env.name)) continue;
|
|
@@ -130448,10 +130547,11 @@ async function collectGcCandidates(postman, workspaceId) {
|
|
|
130448
130547
|
if (marker && monitor.collectionUid) ownedCollections.set(monitor.collectionUid, { marker });
|
|
130449
130548
|
}
|
|
130450
130549
|
for (const [uid, collection] of ownedCollections) {
|
|
130451
|
-
const
|
|
130452
|
-
|
|
130453
|
-
|
|
130454
|
-
|
|
130550
|
+
const resolved = resolveGeneratedCollection(uid);
|
|
130551
|
+
const identity = normalizedCollectionIdentity(resolved?.uid);
|
|
130552
|
+
if (resolved && identity && !discoveredCollectionIdentities.has(identity)) {
|
|
130553
|
+
candidates.push({ kind: "collection", uid: resolved.uid, name: resolved.name, marker: collection.marker });
|
|
130554
|
+
discoveredCollectionIdentities.add(identity);
|
|
130455
130555
|
}
|
|
130456
130556
|
}
|
|
130457
130557
|
const specifications = await postman.listSpecifications(workspaceId);
|
|
@@ -130467,14 +130567,22 @@ async function collectGcCandidates(postman, workspaceId) {
|
|
|
130467
130567
|
const linkedCandidates = [];
|
|
130468
130568
|
let relationsResolved = true;
|
|
130469
130569
|
try {
|
|
130470
|
-
|
|
130471
|
-
|
|
130472
|
-
|
|
130473
|
-
|
|
130570
|
+
const relations = await postman.listSpecCollections(spec.uid);
|
|
130571
|
+
if (relations.length === 0) relationsResolved = false;
|
|
130572
|
+
for (const collection of relations) {
|
|
130573
|
+
const relationIdentity = normalizedCollectionIdentity(collection.uid);
|
|
130574
|
+
if (!relationIdentity) {
|
|
130575
|
+
relationsResolved = false;
|
|
130576
|
+
continue;
|
|
130577
|
+
}
|
|
130578
|
+
if (discoveredCollectionIdentities.has(relationIdentity)) continue;
|
|
130579
|
+
const resolved = resolveGeneratedCollection(collection.uid);
|
|
130580
|
+
const resolvedIdentity = normalizedCollectionIdentity(resolved?.uid);
|
|
130581
|
+
if (!resolved || !resolvedIdentity || resolvedIdentity !== relationIdentity) {
|
|
130474
130582
|
relationsResolved = false;
|
|
130475
130583
|
continue;
|
|
130476
130584
|
}
|
|
130477
|
-
linkedCandidates.push({ kind: "collection", uid:
|
|
130585
|
+
linkedCandidates.push({ kind: "collection", uid: resolved.uid, name: resolved.name, marker });
|
|
130478
130586
|
}
|
|
130479
130587
|
} catch {
|
|
130480
130588
|
relationsResolved = false;
|
|
@@ -130484,9 +130592,10 @@ async function collectGcCandidates(postman, workspaceId) {
|
|
|
130484
130592
|
}
|
|
130485
130593
|
candidates.push({ kind: "spec", uid: spec.uid, name: spec.name, marker });
|
|
130486
130594
|
for (const collection of linkedCandidates) {
|
|
130487
|
-
|
|
130595
|
+
const identity = normalizedCollectionIdentity(collection.uid);
|
|
130596
|
+
if (!identity || discoveredCollectionIdentities.has(identity)) continue;
|
|
130488
130597
|
candidates.push(collection);
|
|
130489
|
-
|
|
130598
|
+
discoveredCollectionIdentities.add(identity);
|
|
130490
130599
|
}
|
|
130491
130600
|
} else {
|
|
130492
130601
|
candidates.push({ kind: "spec", uid: spec.uid, name: spec.name, marker });
|
|
@@ -131150,7 +131259,7 @@ async function runGcCommand(argv, env, writeStdout) {
|
|
|
131150
131259
|
{ persistGeneratedApiKeySecret: false, env }
|
|
131151
131260
|
);
|
|
131152
131261
|
const dependencies = createCliDependencies(inputs, resolved);
|
|
131153
|
-
if (!dependencies.postman.deleteCollection || !dependencies.postman.listSpecifications || !dependencies.postman.getSpecContent || !dependencies.postman.listSpecCollections || !dependencies.postman.deleteSpec) {
|
|
131262
|
+
if (!dependencies.postman.deleteCollection || !dependencies.postman.listCollections || !dependencies.postman.listSpecifications || !dependencies.postman.getSpecContent || !dependencies.postman.listSpecCollections || !dependencies.postman.deleteSpec) {
|
|
131154
131263
|
throw new Error("gc requires the full branch-aware inventory client; this runtime is missing a spec or collection GC capability.");
|
|
131155
131264
|
}
|
|
131156
131265
|
const summary2 = await runGc({
|
|
@@ -131159,6 +131268,7 @@ async function runGcCommand(argv, env, writeStdout) {
|
|
|
131159
131268
|
postman: {
|
|
131160
131269
|
...dependencies.postman,
|
|
131161
131270
|
deleteCollection: dependencies.postman.deleteCollection,
|
|
131271
|
+
listCollections: dependencies.postman.listCollections,
|
|
131162
131272
|
listSpecifications: dependencies.postman.listSpecifications,
|
|
131163
131273
|
getSpecContent: dependencies.postman.getSpecContent,
|
|
131164
131274
|
listSpecCollections: dependencies.postman.listSpecCollections,
|
package/dist/index.cjs
CHANGED
|
@@ -127563,6 +127563,7 @@ function requireMockVisibility(mock, requested) {
|
|
|
127563
127563
|
return mock;
|
|
127564
127564
|
}
|
|
127565
127565
|
var MAX_CREATE_FLIGHTS = 256;
|
|
127566
|
+
var COLLECTION_LIST_PAGE_LIMIT = 100;
|
|
127566
127567
|
var createFlights = /* @__PURE__ */ new Map();
|
|
127567
127568
|
var PostmanGatewayAssetsClient = class {
|
|
127568
127569
|
gateway;
|
|
@@ -127734,8 +127735,80 @@ var PostmanGatewayAssetsClient = class {
|
|
|
127734
127735
|
method: "get",
|
|
127735
127736
|
path: `/specifications/${id}/collections`
|
|
127736
127737
|
});
|
|
127737
|
-
|
|
127738
|
-
return
|
|
127738
|
+
if (!Array.isArray(response?.data)) throw new Error("SPEC_COLLECTION_LIST_RESPONSE_INVALID");
|
|
127739
|
+
return response.data.map((value) => {
|
|
127740
|
+
const entry = this.asRecord(value);
|
|
127741
|
+
const rawUid = entry?.collection ?? entry?.collectionId ?? entry?.id;
|
|
127742
|
+
if (!entry || typeof rawUid !== "string" || entry.name !== void 0 && typeof entry.name !== "string") {
|
|
127743
|
+
throw new Error("SPEC_COLLECTION_LIST_RESPONSE_INVALID");
|
|
127744
|
+
}
|
|
127745
|
+
const uid = this.requireSafePathSegment(rawUid, "Specification collection UID");
|
|
127746
|
+
return { uid, name: typeof entry.name === "string" ? entry.name.trim() : "" };
|
|
127747
|
+
});
|
|
127748
|
+
}
|
|
127749
|
+
/**
|
|
127750
|
+
* Authoritative workspace collection-name snapshot for GC. Drain the v3
|
|
127751
|
+
* collection service's cursor before returning: a partial inventory must not
|
|
127752
|
+
* authorize parent/spec deletion. This list route replaces per-relation full
|
|
127753
|
+
* exports in GC; `getCollection` remains reserved for repo file materialization.
|
|
127754
|
+
*/
|
|
127755
|
+
async listCollections(workspaceId) {
|
|
127756
|
+
const ws = this.requireSafePathSegment(workspaceId, "Workspace UID");
|
|
127757
|
+
const rows = [];
|
|
127758
|
+
const seenCursors = /* @__PURE__ */ new Set();
|
|
127759
|
+
let cursor;
|
|
127760
|
+
for (let page = 0; page < COLLECTION_LIST_PAGE_LIMIT; page += 1) {
|
|
127761
|
+
const response = await this.gateway.requestJson({
|
|
127762
|
+
service: "collection",
|
|
127763
|
+
method: "get",
|
|
127764
|
+
path: `/v3/collections/?workspace=${ws}`,
|
|
127765
|
+
...cursor ? { query: { cursor } } : {}
|
|
127766
|
+
});
|
|
127767
|
+
if (!Array.isArray(response?.data)) throw new Error("COLLECTION_LIST_RESPONSE_INVALID");
|
|
127768
|
+
for (const value of response.data) {
|
|
127769
|
+
const record = this.asRecord(value);
|
|
127770
|
+
const rawUid = record?.id ?? record?.uid;
|
|
127771
|
+
const rawName = record?.name ?? record?.title;
|
|
127772
|
+
if (typeof rawUid !== "string" || typeof rawName !== "string") {
|
|
127773
|
+
throw new Error("COLLECTION_LIST_RESPONSE_INVALID");
|
|
127774
|
+
}
|
|
127775
|
+
const uid = rawUid.trim();
|
|
127776
|
+
const name = rawName.trim();
|
|
127777
|
+
if (!uid || !name || !/^[A-Za-z0-9._~-]+$/.test(uid) || uid === "." || uid === "..") {
|
|
127778
|
+
throw new Error("COLLECTION_LIST_RESPONSE_INVALID");
|
|
127779
|
+
}
|
|
127780
|
+
rows.push({ uid, name });
|
|
127781
|
+
}
|
|
127782
|
+
const meta = response.meta === void 0 ? null : this.asRecord(response.meta);
|
|
127783
|
+
if (response.meta !== void 0 && response.meta !== null && !meta) {
|
|
127784
|
+
throw new Error("COLLECTION_LIST_CURSOR_INVALID");
|
|
127785
|
+
}
|
|
127786
|
+
const paginationValue = meta?.pagination;
|
|
127787
|
+
const pagination = paginationValue === void 0 ? null : this.asRecord(paginationValue);
|
|
127788
|
+
if (paginationValue !== void 0 && paginationValue !== null && !pagination) {
|
|
127789
|
+
throw new Error("COLLECTION_LIST_CURSOR_INVALID");
|
|
127790
|
+
}
|
|
127791
|
+
const cursorValue = meta?.cursor;
|
|
127792
|
+
const cursorEnvelope = cursorValue === void 0 ? null : this.asRecord(cursorValue);
|
|
127793
|
+
if (cursorValue !== void 0 && cursorValue !== null && !cursorEnvelope) {
|
|
127794
|
+
throw new Error("COLLECTION_LIST_CURSOR_INVALID");
|
|
127795
|
+
}
|
|
127796
|
+
const candidates = [pagination?.nextPage, cursorEnvelope?.next, meta?.nextCursor, response.nextCursor].filter((value) => value !== void 0 && value !== null && value !== "");
|
|
127797
|
+
if (candidates.some((value) => typeof value !== "string")) {
|
|
127798
|
+
throw new Error("COLLECTION_LIST_CURSOR_INVALID");
|
|
127799
|
+
}
|
|
127800
|
+
const nextCursors = [...new Set(candidates.map((value) => String(value).trim()).filter(Boolean))];
|
|
127801
|
+
if (nextCursors.length > 1) throw new Error("COLLECTION_LIST_CURSOR_AMBIGUOUS");
|
|
127802
|
+
const next = nextCursors[0];
|
|
127803
|
+
if (!next) return rows;
|
|
127804
|
+
if (seenCursors.has(next)) throw new Error("COLLECTION_LIST_CURSOR_REPEATED");
|
|
127805
|
+
seenCursors.add(next);
|
|
127806
|
+
if (page === COLLECTION_LIST_PAGE_LIMIT - 1) {
|
|
127807
|
+
throw new Error("COLLECTION_LIST_PAGE_LIMIT_EXCEEDED");
|
|
127808
|
+
}
|
|
127809
|
+
cursor = next;
|
|
127810
|
+
}
|
|
127811
|
+
throw new Error("COLLECTION_LIST_PAGE_LIMIT_EXCEEDED");
|
|
127739
127812
|
}
|
|
127740
127813
|
async deleteSpec(specId) {
|
|
127741
127814
|
const id = this.requireSafePathSegment(specId, "Specification UID");
|
|
@@ -132190,6 +132263,7 @@ function createRepoSyncDependencies(inputs, resolved, factories, options = {}) {
|
|
|
132190
132263
|
deleteMock: gatewayAssets.deleteMock.bind(gatewayAssets),
|
|
132191
132264
|
deleteMonitor: gatewayAssets.deleteMonitor.bind(gatewayAssets),
|
|
132192
132265
|
deleteCollection: gatewayAssets.deleteCollection.bind(gatewayAssets),
|
|
132266
|
+
listCollections: gatewayAssets.listCollections.bind(gatewayAssets),
|
|
132193
132267
|
listSpecifications: gatewayAssets.listSpecifications.bind(gatewayAssets),
|
|
132194
132268
|
getSpecContent: gatewayAssets.getSpecContent.bind(gatewayAssets),
|
|
132195
132269
|
listSpecCollections: gatewayAssets.listSpecCollections.bind(gatewayAssets),
|