@postman-cse/onboarding-repo-sync 2.1.1 → 2.1.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/README.md +2 -0
- package/dist/action.cjs +376 -138
- package/dist/cli.cjs +376 -138
- package/dist/index.cjs +376 -138
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -127306,12 +127306,20 @@ async function retry(operation, options = {}) {
|
|
|
127306
127306
|
}
|
|
127307
127307
|
|
|
127308
127308
|
// src/lib/postman/postman-gateway-assets-client.ts
|
|
127309
|
+
var MAX_CREATE_FLIGHTS = 256;
|
|
127310
|
+
var createFlights = /* @__PURE__ */ new Map();
|
|
127309
127311
|
var PostmanGatewayAssetsClient = class {
|
|
127310
127312
|
gateway;
|
|
127311
127313
|
workspaceId;
|
|
127314
|
+
sleep;
|
|
127315
|
+
reconcileAttempts;
|
|
127316
|
+
reconcileDelayMs;
|
|
127312
127317
|
constructor(options) {
|
|
127313
127318
|
this.gateway = options.gateway;
|
|
127314
127319
|
this.workspaceId = String(options.workspaceId || "").trim();
|
|
127320
|
+
this.sleep = options.sleep ?? sleep;
|
|
127321
|
+
this.reconcileAttempts = Math.max(1, options.reconcileAttempts ?? 3);
|
|
127322
|
+
this.reconcileDelayMs = Math.max(0, options.reconcileDelayMs ?? 500);
|
|
127315
127323
|
}
|
|
127316
127324
|
asRecord(value) {
|
|
127317
127325
|
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
@@ -127341,8 +127349,64 @@ var PostmanGatewayAssetsClient = class {
|
|
|
127341
127349
|
const parts = trimmed.split("-");
|
|
127342
127350
|
return parts.length >= 6 ? parts.slice(1).join("-") : trimmed;
|
|
127343
127351
|
}
|
|
127344
|
-
|
|
127345
|
-
|
|
127352
|
+
isAmbiguousCreateOutcome(error2) {
|
|
127353
|
+
if (error2 instanceof HttpError) {
|
|
127354
|
+
return error2.status === 408 || error2.status === 429 || error2.status >= 500;
|
|
127355
|
+
}
|
|
127356
|
+
return error2 instanceof Error;
|
|
127357
|
+
}
|
|
127358
|
+
isRetryableIdempotentWriteOutcome(error2) {
|
|
127359
|
+
if (error2 instanceof HttpError) {
|
|
127360
|
+
return error2.status === 408 || error2.status === 429 || error2.status >= 500;
|
|
127361
|
+
}
|
|
127362
|
+
return error2 instanceof Error;
|
|
127363
|
+
}
|
|
127364
|
+
selectExactMatch(kind, identity, matches) {
|
|
127365
|
+
if (matches.length > 1) {
|
|
127366
|
+
const ids = matches.map((match) => match.uid).join(", ");
|
|
127367
|
+
throw new Error(
|
|
127368
|
+
`Multiple ${kind}s match ${identity}: ${ids}. Refusing to choose one; remove duplicates or pass an explicit asset ID.`
|
|
127369
|
+
);
|
|
127370
|
+
}
|
|
127371
|
+
return matches[0] ?? null;
|
|
127372
|
+
}
|
|
127373
|
+
async singleFlight(key, fingerprint, kind, operation) {
|
|
127374
|
+
const existing = createFlights.get(key);
|
|
127375
|
+
if (existing) {
|
|
127376
|
+
if (existing.fingerprint !== fingerprint) {
|
|
127377
|
+
throw new Error(`Incompatible concurrent ${kind} create for ${key}`);
|
|
127378
|
+
}
|
|
127379
|
+
return existing.promise;
|
|
127380
|
+
}
|
|
127381
|
+
if (createFlights.size >= MAX_CREATE_FLIGHTS) {
|
|
127382
|
+
throw new Error(`Too many concurrent Postman asset creates (limit ${MAX_CREATE_FLIGHTS})`);
|
|
127383
|
+
}
|
|
127384
|
+
const pending = operation().finally(() => {
|
|
127385
|
+
if (createFlights.get(key)?.promise === pending) {
|
|
127386
|
+
createFlights.delete(key);
|
|
127387
|
+
}
|
|
127388
|
+
});
|
|
127389
|
+
createFlights.set(key, { fingerprint, promise: pending });
|
|
127390
|
+
return pending;
|
|
127391
|
+
}
|
|
127392
|
+
async discoverAfterAmbiguousCreate(discover, error2) {
|
|
127393
|
+
if (!this.isAmbiguousCreateOutcome(error2)) {
|
|
127394
|
+
return null;
|
|
127395
|
+
}
|
|
127396
|
+
for (let attempt = 0; attempt < this.reconcileAttempts; attempt += 1) {
|
|
127397
|
+
if (attempt > 0) {
|
|
127398
|
+
await this.sleep(this.reconcileDelayMs);
|
|
127399
|
+
}
|
|
127400
|
+
const found = await discover();
|
|
127401
|
+
if (found) {
|
|
127402
|
+
return found;
|
|
127403
|
+
}
|
|
127404
|
+
}
|
|
127405
|
+
return null;
|
|
127406
|
+
}
|
|
127407
|
+
publicEnvironmentUid(data, bareId) {
|
|
127408
|
+
const owner = String(data?.owner ?? "").trim();
|
|
127409
|
+
return owner && !bareId.startsWith(`${owner}-`) ? `${owner}-${bareId}` : bareId;
|
|
127346
127410
|
}
|
|
127347
127411
|
// --- environments (service: sync) ---
|
|
127348
127412
|
//
|
|
@@ -127353,9 +127417,10 @@ var PostmanGatewayAssetsClient = class {
|
|
|
127353
127417
|
/**
|
|
127354
127418
|
* Create/upsert an environment through the sync service.
|
|
127355
127419
|
* POST /environment/import?workspace=:ws { id:<uuid>, name, values } ->
|
|
127356
|
-
* { data:{ id:<bare uuid>, owner } }. The id is generated once
|
|
127357
|
-
*
|
|
127358
|
-
*
|
|
127420
|
+
* { data:{ id:<bare uuid>, owner } }. The id is generated once for the
|
|
127421
|
+
* operation. Unsafe creates submit once (no blind retry); on an ambiguous
|
|
127422
|
+
* response the client discovers by exact workspace-scoped name before
|
|
127423
|
+
* failing.
|
|
127359
127424
|
*
|
|
127360
127425
|
* Returns the PUBLIC uid (`<owner>-<uuid>`), not the bare model id the sync
|
|
127361
127426
|
* import echoes: mock/monitor create reference the environment by its public
|
|
@@ -127365,33 +127430,54 @@ var PostmanGatewayAssetsClient = class {
|
|
|
127365
127430
|
*/
|
|
127366
127431
|
async createEnvironment(workspaceId, name, values) {
|
|
127367
127432
|
const ws = workspaceId || this.workspaceId;
|
|
127368
|
-
const
|
|
127369
|
-
const
|
|
127370
|
-
|
|
127371
|
-
|
|
127372
|
-
|
|
127373
|
-
|
|
127374
|
-
|
|
127375
|
-
|
|
127376
|
-
|
|
127377
|
-
|
|
127378
|
-
|
|
127379
|
-
|
|
127380
|
-
|
|
127381
|
-
|
|
127382
|
-
|
|
127383
|
-
|
|
127384
|
-
|
|
127385
|
-
|
|
127386
|
-
|
|
127387
|
-
|
|
127388
|
-
|
|
127389
|
-
|
|
127390
|
-
|
|
127391
|
-
|
|
127392
|
-
|
|
127393
|
-
|
|
127394
|
-
|
|
127433
|
+
const envName = String(name ?? "").trim();
|
|
127434
|
+
const flightKey = `environment:${ws}:${envName}`;
|
|
127435
|
+
const normalizedValues = values.map((v) => ({
|
|
127436
|
+
key: v.key,
|
|
127437
|
+
value: v.value,
|
|
127438
|
+
type: v.type ?? "default",
|
|
127439
|
+
enabled: v.enabled ?? true
|
|
127440
|
+
}));
|
|
127441
|
+
return this.singleFlight(flightKey, JSON.stringify(normalizedValues), "environment", async () => {
|
|
127442
|
+
const existing = await this.findEnvironmentByName(ws, envName);
|
|
127443
|
+
if (existing?.uid) {
|
|
127444
|
+
await this.updateEnvironment(existing.uid, envName, values);
|
|
127445
|
+
return existing.uid;
|
|
127446
|
+
}
|
|
127447
|
+
const id = crypto.randomUUID();
|
|
127448
|
+
const body = {
|
|
127449
|
+
id,
|
|
127450
|
+
name: envName,
|
|
127451
|
+
values: normalizedValues
|
|
127452
|
+
};
|
|
127453
|
+
try {
|
|
127454
|
+
const response = await this.gateway.requestJson(
|
|
127455
|
+
{
|
|
127456
|
+
service: "sync",
|
|
127457
|
+
method: "post",
|
|
127458
|
+
path: `/environment/import?workspace=${ws}`,
|
|
127459
|
+
body
|
|
127460
|
+
},
|
|
127461
|
+
{ retryTransient: false }
|
|
127462
|
+
);
|
|
127463
|
+
const data = this.dataOf(response);
|
|
127464
|
+
const bareId = this.idOf(data);
|
|
127465
|
+
if (!bareId) {
|
|
127466
|
+
throw new Error("Environment import did not return a UID");
|
|
127467
|
+
}
|
|
127468
|
+
return this.publicEnvironmentUid(data, bareId);
|
|
127469
|
+
} catch (error2) {
|
|
127470
|
+
const adopted = await this.discoverAfterAmbiguousCreate(async () => {
|
|
127471
|
+
const match = await this.findEnvironmentByName(ws, envName);
|
|
127472
|
+
return match?.uid ?? null;
|
|
127473
|
+
}, error2);
|
|
127474
|
+
if (adopted) {
|
|
127475
|
+
await this.updateEnvironment(adopted, envName, values);
|
|
127476
|
+
return adopted;
|
|
127477
|
+
}
|
|
127478
|
+
throw error2;
|
|
127479
|
+
}
|
|
127480
|
+
});
|
|
127395
127481
|
}
|
|
127396
127482
|
/**
|
|
127397
127483
|
* Update an existing environment through the sync service.
|
|
@@ -127421,7 +127507,7 @@ var PostmanGatewayAssetsClient = class {
|
|
|
127421
127507
|
path: `/environment/${id}`,
|
|
127422
127508
|
body
|
|
127423
127509
|
}),
|
|
127424
|
-
{ maxAttempts: 5, delayMs: 2e3, backoffMultiplier: 2, maxDelayMs: 15e3, shouldRetry: (e) => this.
|
|
127510
|
+
{ maxAttempts: 5, delayMs: 2e3, backoffMultiplier: 2, maxDelayMs: 15e3, shouldRetry: (e) => this.isRetryableIdempotentWriteOutcome(e) }
|
|
127425
127511
|
);
|
|
127426
127512
|
}
|
|
127427
127513
|
/**
|
|
@@ -127445,13 +127531,37 @@ var PostmanGatewayAssetsClient = class {
|
|
|
127445
127531
|
*/
|
|
127446
127532
|
async listEnvironments(workspaceId) {
|
|
127447
127533
|
const ws = workspaceId || this.workspaceId;
|
|
127448
|
-
const response = await this.gateway.requestJson(
|
|
127449
|
-
|
|
127450
|
-
|
|
127451
|
-
|
|
127452
|
-
|
|
127534
|
+
const response = await this.gateway.requestJson(
|
|
127535
|
+
{
|
|
127536
|
+
service: "sync",
|
|
127537
|
+
method: "post",
|
|
127538
|
+
path: `/list/environment?workspace=${ws}`
|
|
127539
|
+
},
|
|
127540
|
+
{ retryTransient: true }
|
|
127541
|
+
);
|
|
127453
127542
|
const items = Array.isArray(response?.data) ? response.data : [];
|
|
127454
|
-
return items.map((raw) => this.asRecord(raw)).filter((e) => e !== null).map((e) =>
|
|
127543
|
+
return items.map((raw) => this.asRecord(raw)).filter((e) => e !== null).map((e) => {
|
|
127544
|
+
const bareOrPublic = this.idOf(e);
|
|
127545
|
+
return {
|
|
127546
|
+
name: String(e.name ?? ""),
|
|
127547
|
+
uid: this.publicEnvironmentUid(e, bareOrPublic)
|
|
127548
|
+
};
|
|
127549
|
+
});
|
|
127550
|
+
}
|
|
127551
|
+
/** Exact name match within a workspace. Prefer tracked UIDs before calling. */
|
|
127552
|
+
async findEnvironmentByName(workspaceId, name) {
|
|
127553
|
+
const want = String(name ?? "").trim();
|
|
127554
|
+
if (!want) {
|
|
127555
|
+
return null;
|
|
127556
|
+
}
|
|
127557
|
+
const environments = await this.listEnvironments(workspaceId);
|
|
127558
|
+
const matches = environments.filter((entry) => entry.name === want);
|
|
127559
|
+
const match = this.selectExactMatch(
|
|
127560
|
+
"environment",
|
|
127561
|
+
`workspace ${workspaceId} and name "${want}"`,
|
|
127562
|
+
matches
|
|
127563
|
+
);
|
|
127564
|
+
return match?.uid ? { uid: match.uid, name: match.name } : null;
|
|
127455
127565
|
}
|
|
127456
127566
|
// --- collection read (service: collection, v3 export) ---
|
|
127457
127567
|
//
|
|
@@ -127481,32 +127591,51 @@ var PostmanGatewayAssetsClient = class {
|
|
|
127481
127591
|
// --- mocks (service: mock) ---
|
|
127482
127592
|
async createMock(workspaceId, name, collectionUid, environmentUid) {
|
|
127483
127593
|
const ws = workspaceId || this.workspaceId;
|
|
127594
|
+
const mockName = String(name ?? "").trim();
|
|
127484
127595
|
const collection = String(collectionUid ?? "").trim();
|
|
127485
127596
|
const environment = String(environmentUid ?? "").trim();
|
|
127486
|
-
const
|
|
127487
|
-
|
|
127488
|
-
collection,
|
|
127489
|
-
|
|
127490
|
-
|
|
127491
|
-
|
|
127492
|
-
|
|
127493
|
-
|
|
127494
|
-
|
|
127495
|
-
|
|
127496
|
-
|
|
127497
|
-
|
|
127498
|
-
|
|
127499
|
-
|
|
127500
|
-
|
|
127501
|
-
|
|
127502
|
-
|
|
127503
|
-
|
|
127504
|
-
|
|
127505
|
-
|
|
127506
|
-
|
|
127507
|
-
|
|
127508
|
-
|
|
127509
|
-
|
|
127597
|
+
const flightKey = `mock:${ws}:${collection}:${environment}:${mockName}`;
|
|
127598
|
+
return this.singleFlight(flightKey, flightKey, "mock", async () => {
|
|
127599
|
+
const existing = await this.findMockByCollection(collection, environment, mockName);
|
|
127600
|
+
if (existing) {
|
|
127601
|
+
return { uid: existing.uid, url: existing.mockUrl };
|
|
127602
|
+
}
|
|
127603
|
+
const body = {
|
|
127604
|
+
name: mockName,
|
|
127605
|
+
collection,
|
|
127606
|
+
private: false,
|
|
127607
|
+
...environment ? { environment } : {}
|
|
127608
|
+
};
|
|
127609
|
+
try {
|
|
127610
|
+
const response = await this.gateway.requestJson(
|
|
127611
|
+
{
|
|
127612
|
+
service: "mock",
|
|
127613
|
+
method: "post",
|
|
127614
|
+
path: `/mocks?workspace=${ws}`,
|
|
127615
|
+
body
|
|
127616
|
+
},
|
|
127617
|
+
{ retryTransient: false }
|
|
127618
|
+
);
|
|
127619
|
+
const record = this.dataOf(response);
|
|
127620
|
+
const uid = this.idOf(record);
|
|
127621
|
+
if (!uid) {
|
|
127622
|
+
throw new Error("Mock create did not return a UID");
|
|
127623
|
+
}
|
|
127624
|
+
return {
|
|
127625
|
+
uid,
|
|
127626
|
+
url: String(record?.url ?? record?.mockUrl ?? "").trim()
|
|
127627
|
+
};
|
|
127628
|
+
} catch (error2) {
|
|
127629
|
+
const adopted = await this.discoverAfterAmbiguousCreate(
|
|
127630
|
+
() => this.findMockByCollection(collection, environment, mockName),
|
|
127631
|
+
error2
|
|
127632
|
+
);
|
|
127633
|
+
if (adopted) {
|
|
127634
|
+
return { uid: adopted.uid, url: adopted.mockUrl };
|
|
127635
|
+
}
|
|
127636
|
+
throw error2;
|
|
127637
|
+
}
|
|
127638
|
+
});
|
|
127510
127639
|
}
|
|
127511
127640
|
async listMocks() {
|
|
127512
127641
|
const response = await this.gateway.requestJson({
|
|
@@ -127535,10 +127664,19 @@ var PostmanGatewayAssetsClient = class {
|
|
|
127535
127664
|
return false;
|
|
127536
127665
|
}
|
|
127537
127666
|
}
|
|
127538
|
-
async findMockByCollection(collectionUid) {
|
|
127667
|
+
async findMockByCollection(collectionUid, environmentUid, name) {
|
|
127539
127668
|
const mocks = await this.listMocks();
|
|
127540
127669
|
const want = String(collectionUid ?? "").trim();
|
|
127541
|
-
const
|
|
127670
|
+
const environment = String(environmentUid ?? "").trim();
|
|
127671
|
+
const mockName = String(name ?? "").trim();
|
|
127672
|
+
const matches = mocks.filter(
|
|
127673
|
+
(mock) => mock.collection === want && mock.environment === environment && mock.name === mockName
|
|
127674
|
+
);
|
|
127675
|
+
const match = this.selectExactMatch(
|
|
127676
|
+
"mock",
|
|
127677
|
+
`workspace ${this.workspaceId}, name "${mockName}", collection ${want}, and environment ${environment || "(none)"}`,
|
|
127678
|
+
matches
|
|
127679
|
+
);
|
|
127542
127680
|
return match ? { uid: match.uid, mockUrl: match.mockUrl } : null;
|
|
127543
127681
|
}
|
|
127544
127682
|
// --- monitors (service: monitors; collection-based = jobTemplates) ---
|
|
@@ -127555,32 +127693,51 @@ var PostmanGatewayAssetsClient = class {
|
|
|
127555
127693
|
async createMonitor(workspaceId, name, collectionUid, environmentUid, cronSchedule) {
|
|
127556
127694
|
const ws = workspaceId || this.workspaceId;
|
|
127557
127695
|
const effectiveCron = cronSchedule && cronSchedule.trim() ? cronSchedule.trim() : "0 0 * * 0";
|
|
127696
|
+
const monitorName = String(name ?? "").trim();
|
|
127558
127697
|
const collection = String(collectionUid ?? "").trim();
|
|
127559
127698
|
const environment = String(environmentUid ?? "").trim();
|
|
127560
|
-
const
|
|
127561
|
-
|
|
127562
|
-
collection,
|
|
127563
|
-
|
|
127564
|
-
|
|
127565
|
-
|
|
127566
|
-
|
|
127567
|
-
|
|
127568
|
-
|
|
127569
|
-
|
|
127570
|
-
|
|
127571
|
-
|
|
127572
|
-
|
|
127573
|
-
|
|
127574
|
-
|
|
127575
|
-
|
|
127576
|
-
|
|
127577
|
-
|
|
127578
|
-
|
|
127579
|
-
|
|
127580
|
-
|
|
127581
|
-
|
|
127582
|
-
|
|
127583
|
-
|
|
127699
|
+
const flightKey = `monitor:${ws}:${collection}:${environment}:${monitorName}`;
|
|
127700
|
+
return this.singleFlight(flightKey, effectiveCron, "monitor", async () => {
|
|
127701
|
+
const existing = await this.findMonitorByCollection(collection, environment, monitorName);
|
|
127702
|
+
if (existing?.uid) {
|
|
127703
|
+
return existing.uid;
|
|
127704
|
+
}
|
|
127705
|
+
const body = {
|
|
127706
|
+
name: monitorName,
|
|
127707
|
+
collection,
|
|
127708
|
+
options: { strictSSL: false, followRedirects: true, requestTimeout: null, requestDelay: 0 },
|
|
127709
|
+
notifications: { onFailure: [], onError: [] },
|
|
127710
|
+
retry: {},
|
|
127711
|
+
schedule: { cronPattern: effectiveCron, timeZone: "UTC" },
|
|
127712
|
+
distribution: null,
|
|
127713
|
+
...environment ? { environment } : {}
|
|
127714
|
+
};
|
|
127715
|
+
try {
|
|
127716
|
+
const response = await this.gateway.requestJson(
|
|
127717
|
+
{
|
|
127718
|
+
service: "monitors",
|
|
127719
|
+
method: "post",
|
|
127720
|
+
path: `/jobTemplates?workspace=${ws}`,
|
|
127721
|
+
body
|
|
127722
|
+
},
|
|
127723
|
+
{ retryTransient: false }
|
|
127724
|
+
);
|
|
127725
|
+
const uid = this.idOf(this.dataOf(response));
|
|
127726
|
+
if (!uid) {
|
|
127727
|
+
throw new Error("Monitor create did not return a UID");
|
|
127728
|
+
}
|
|
127729
|
+
return uid;
|
|
127730
|
+
} catch (error2) {
|
|
127731
|
+
const adopted = await this.discoverAfterAmbiguousCreate(
|
|
127732
|
+
() => this.findMonitorByCollection(collection, environment, monitorName),
|
|
127733
|
+
error2
|
|
127734
|
+
);
|
|
127735
|
+
if (adopted?.uid) {
|
|
127736
|
+
return adopted.uid;
|
|
127737
|
+
}
|
|
127738
|
+
throw error2;
|
|
127739
|
+
}
|
|
127740
|
+
});
|
|
127584
127741
|
}
|
|
127585
127742
|
async listMonitors() {
|
|
127586
127743
|
const response = await this.gateway.requestJson({
|
|
@@ -127603,24 +127760,30 @@ var PostmanGatewayAssetsClient = class {
|
|
|
127603
127760
|
return false;
|
|
127604
127761
|
}
|
|
127605
127762
|
}
|
|
127606
|
-
async findMonitorByCollection(collectionUid) {
|
|
127763
|
+
async findMonitorByCollection(collectionUid, environmentUid, name) {
|
|
127607
127764
|
const want = String(collectionUid ?? "").trim();
|
|
127608
|
-
const
|
|
127609
|
-
|
|
127610
|
-
|
|
127611
|
-
|
|
127612
|
-
|
|
127613
|
-
|
|
127614
|
-
const
|
|
127615
|
-
|
|
127765
|
+
const environment = String(environmentUid ?? "").trim();
|
|
127766
|
+
const monitorName = String(name ?? "").trim();
|
|
127767
|
+
const monitors = await this.listMonitors();
|
|
127768
|
+
const matches = monitors.filter(
|
|
127769
|
+
(monitor) => monitor.collectionUid === want && monitor.environmentUid === environment && monitor.name === monitorName
|
|
127770
|
+
);
|
|
127771
|
+
const match = this.selectExactMatch(
|
|
127772
|
+
"monitor",
|
|
127773
|
+
`workspace ${this.workspaceId}, name "${monitorName}", collection ${want}, and environment ${environment || "(none)"}`,
|
|
127774
|
+
matches
|
|
127775
|
+
);
|
|
127616
127776
|
return match?.uid ? { uid: match.uid, name: match.name } : null;
|
|
127617
127777
|
}
|
|
127618
127778
|
async runMonitor(uid) {
|
|
127619
|
-
await this.gateway.requestJson(
|
|
127620
|
-
|
|
127621
|
-
|
|
127622
|
-
|
|
127623
|
-
|
|
127779
|
+
await this.gateway.requestJson(
|
|
127780
|
+
{
|
|
127781
|
+
service: "monitors",
|
|
127782
|
+
method: "post",
|
|
127783
|
+
path: `/jobTemplates/${uid}/jobs`
|
|
127784
|
+
},
|
|
127785
|
+
{ retryTransient: false }
|
|
127786
|
+
);
|
|
127624
127787
|
}
|
|
127625
127788
|
};
|
|
127626
127789
|
|
|
@@ -127786,12 +127949,8 @@ async function mintAccessTokenIfNeeded(inputs, log, setSecret2, fetchImpl = fetc
|
|
|
127786
127949
|
function isExpiredAuthError(status, body) {
|
|
127787
127950
|
return status === 401 || body.includes("UNAUTHENTICATED") || body.includes("authenticationError");
|
|
127788
127951
|
}
|
|
127789
|
-
function
|
|
127790
|
-
|
|
127791
|
-
if (status >= 500 && (body.includes("ESOCKETTIMEDOUT") || body.includes("ETIMEDOUT") || body.includes("ECONNRESET") || body.includes("serverError") || body.includes("downstream"))) {
|
|
127792
|
-
return true;
|
|
127793
|
-
}
|
|
127794
|
-
return false;
|
|
127952
|
+
function isRetryableSafeReadResponse(status) {
|
|
127953
|
+
return status === 408 || status === 429 || status >= 500;
|
|
127795
127954
|
}
|
|
127796
127955
|
function defaultSleep(ms) {
|
|
127797
127956
|
return new Promise((resolve3) => setTimeout(resolve3, ms));
|
|
@@ -127850,14 +128009,28 @@ var AccessTokenGatewayClient = class {
|
|
|
127850
128009
|
}
|
|
127851
128010
|
/**
|
|
127852
128011
|
* Send a gateway request, refreshing the token once on an auth failure and
|
|
127853
|
-
* retrying transient downstream failures (5xx / Bifrost read
|
|
127854
|
-
* exponential backoff.
|
|
127855
|
-
*
|
|
128012
|
+
* optionally retrying transient downstream failures (5xx / Bifrost read
|
|
128013
|
+
* timeouts) with exponential backoff. Safe reads keep transient retries;
|
|
128014
|
+
* unsafe creates pass `{ retryTransient: false }` and reconcile after an
|
|
128015
|
+
* ambiguous response instead of re-POSTing. Auth refresh remains independent
|
|
128016
|
+
* of the transient-retry budget.
|
|
127856
128017
|
*/
|
|
127857
|
-
async request(request) {
|
|
128018
|
+
async request(request, options = {}) {
|
|
128019
|
+
const retryTransient = options.retryTransient ?? request.method === "get";
|
|
127858
128020
|
let attempt = 0;
|
|
127859
128021
|
for (; ; ) {
|
|
127860
|
-
let response
|
|
128022
|
+
let response;
|
|
128023
|
+
try {
|
|
128024
|
+
response = await this.send(request);
|
|
128025
|
+
} catch (error2) {
|
|
128026
|
+
if (retryTransient && attempt < this.maxRetries) {
|
|
128027
|
+
const delay = this.retryBaseDelayMs * 2 ** attempt;
|
|
128028
|
+
attempt += 1;
|
|
128029
|
+
await this.sleepImpl(delay);
|
|
128030
|
+
continue;
|
|
128031
|
+
}
|
|
128032
|
+
throw error2;
|
|
128033
|
+
}
|
|
127861
128034
|
if (response.ok) {
|
|
127862
128035
|
return response;
|
|
127863
128036
|
}
|
|
@@ -127871,7 +128044,7 @@ var AccessTokenGatewayClient = class {
|
|
|
127871
128044
|
const retryBody = await response.text().catch(() => "");
|
|
127872
128045
|
throw this.toHttpError(request, response, retryBody);
|
|
127873
128046
|
}
|
|
127874
|
-
if (
|
|
128047
|
+
if (retryTransient && isRetryableSafeReadResponse(response.status) && attempt < this.maxRetries) {
|
|
127875
128048
|
const delay = this.retryBaseDelayMs * 2 ** attempt;
|
|
127876
128049
|
attempt += 1;
|
|
127877
128050
|
await this.sleepImpl(delay);
|
|
@@ -127881,8 +128054,8 @@ var AccessTokenGatewayClient = class {
|
|
|
127881
128054
|
}
|
|
127882
128055
|
}
|
|
127883
128056
|
/** Send a gateway request and parse the JSON body, or null when empty. */
|
|
127884
|
-
async requestJson(request) {
|
|
127885
|
-
const response = await this.request(request);
|
|
128057
|
+
async requestJson(request, options = {}) {
|
|
128058
|
+
const response = await this.request(request, options);
|
|
127886
128059
|
const text = await response.text().catch(() => "");
|
|
127887
128060
|
if (!text.trim()) {
|
|
127888
128061
|
return null;
|
|
@@ -128474,18 +128647,28 @@ async function upsertEnvironments(inputs, dependencies, resourcesState) {
|
|
|
128474
128647
|
for (const envName of inputs.environments) {
|
|
128475
128648
|
const runtimeUrl = String(inputs.envRuntimeUrls[envName] || "").trim();
|
|
128476
128649
|
const values = buildEnvironmentValues(envName, runtimeUrl);
|
|
128477
|
-
const
|
|
128478
|
-
|
|
128479
|
-
|
|
128480
|
-
|
|
128481
|
-
|
|
128482
|
-
|
|
128650
|
+
const displayName = `${inputs.projectName} - ${envName}`;
|
|
128651
|
+
let existingUid = String(envUids[envName] || "").trim();
|
|
128652
|
+
if (!existingUid) {
|
|
128653
|
+
const discovered = await dependencies.postman.findEnvironmentByName(
|
|
128654
|
+
inputs.workspaceId,
|
|
128655
|
+
displayName
|
|
128483
128656
|
);
|
|
128657
|
+
if (discovered?.uid) {
|
|
128658
|
+
existingUid = discovered.uid;
|
|
128659
|
+
dependencies.core.info(
|
|
128660
|
+
`Discovered existing environment for ${displayName}: ${existingUid}`
|
|
128661
|
+
);
|
|
128662
|
+
}
|
|
128663
|
+
}
|
|
128664
|
+
if (existingUid) {
|
|
128665
|
+
await dependencies.postman.updateEnvironment(existingUid, displayName, values);
|
|
128666
|
+
envUids[envName] = existingUid;
|
|
128484
128667
|
continue;
|
|
128485
128668
|
}
|
|
128486
128669
|
envUids[envName] = await dependencies.postman.createEnvironment(
|
|
128487
128670
|
inputs.workspaceId,
|
|
128488
|
-
|
|
128671
|
+
displayName,
|
|
128489
128672
|
values
|
|
128490
128673
|
);
|
|
128491
128674
|
}
|
|
@@ -128531,10 +128714,33 @@ function writeJsonFile(path9, content, normalize3 = false) {
|
|
|
128531
128714
|
const data = normalize3 ? stripVolatileFields(content) : content;
|
|
128532
128715
|
(0, import_node_fs3.writeFileSync)(path9, JSON.stringify(data, null, 2));
|
|
128533
128716
|
}
|
|
128534
|
-
function
|
|
128535
|
-
|
|
128536
|
-
|
|
128537
|
-
}
|
|
128717
|
+
function buildMappedSpecCloudKey(mappedSource, specSyncMode, releaseLabel) {
|
|
128718
|
+
if (specSyncMode !== "version") {
|
|
128719
|
+
return mappedSource;
|
|
128720
|
+
}
|
|
128721
|
+
const normalized = normalizeReleaseLabel(releaseLabel || "");
|
|
128722
|
+
if (!normalized) {
|
|
128723
|
+
return void 0;
|
|
128724
|
+
}
|
|
128725
|
+
return `${mappedSource}#release=${normalized}`;
|
|
128726
|
+
}
|
|
128727
|
+
function resolveDurableWorkspaceId(options) {
|
|
128728
|
+
const { candidateId, priorId, workspaceLinkEnabled, workspaceLinkStatus } = options;
|
|
128729
|
+
const candidate = candidateId.trim();
|
|
128730
|
+
const prior = priorId?.trim() || void 0;
|
|
128731
|
+
if (!workspaceLinkEnabled) {
|
|
128732
|
+
return candidate || prior;
|
|
128733
|
+
}
|
|
128734
|
+
if (workspaceLinkStatus === "success") {
|
|
128735
|
+
return candidate || void 0;
|
|
128736
|
+
}
|
|
128737
|
+
return prior === candidate ? prior : void 0;
|
|
128738
|
+
}
|
|
128739
|
+
function buildResourcesManifest(workspaceId, collectionMap, envMap, artifactDir, localSpecRefs, mappedSpecRef, specId, existingSpecs) {
|
|
128740
|
+
const manifest = {};
|
|
128741
|
+
if (workspaceId) {
|
|
128742
|
+
manifest.workspace = { id: workspaceId };
|
|
128743
|
+
}
|
|
128538
128744
|
const localResources = {};
|
|
128539
128745
|
const cloudResources = {};
|
|
128540
128746
|
const collectionKeys = Object.keys(collectionMap);
|
|
@@ -128555,8 +128761,12 @@ function buildResourcesManifest(workspaceId, collectionMap, envMap, artifactDir,
|
|
|
128555
128761
|
if (localSpecRefs.length > 0) {
|
|
128556
128762
|
localResources.specs = localSpecRefs;
|
|
128557
128763
|
}
|
|
128764
|
+
const specs = { ...existingSpecs || {} };
|
|
128558
128765
|
if (mappedSpecRef && specId) {
|
|
128559
|
-
|
|
128766
|
+
specs[mappedSpecRef] = specId;
|
|
128767
|
+
}
|
|
128768
|
+
if (Object.keys(specs).length > 0) {
|
|
128769
|
+
cloudResources.specs = specs;
|
|
128560
128770
|
}
|
|
128561
128771
|
if (Object.keys(localResources).length > 0) {
|
|
128562
128772
|
manifest.localResources = localResources;
|
|
@@ -128623,7 +128833,7 @@ function assertPathWithinCwd(targetPath, fieldName) {
|
|
|
128623
128833
|
throw new Error(`${fieldName} must stay within the repository root; received ${targetPath}`);
|
|
128624
128834
|
}
|
|
128625
128835
|
}
|
|
128626
|
-
async function exportArtifacts(inputs, dependencies, envUids, assetProjectName) {
|
|
128836
|
+
async function exportArtifacts(inputs, dependencies, envUids, assetProjectName, options) {
|
|
128627
128837
|
if (!inputs.workspaceId) {
|
|
128628
128838
|
return;
|
|
128629
128839
|
}
|
|
@@ -128657,6 +128867,11 @@ async function exportArtifacts(inputs, dependencies, envUids, assetProjectName)
|
|
|
128657
128867
|
const manifestCollections = {};
|
|
128658
128868
|
const discoveredSpecs = scanLocalSpecReferences();
|
|
128659
128869
|
const mappedSpec = resolveMappedSpecReference(inputs.specPath, discoveredSpecs);
|
|
128870
|
+
const mappedSpecCloudKey = mappedSpec && inputs.specId ? buildMappedSpecCloudKey(
|
|
128871
|
+
mappedSpec.configRelativePath,
|
|
128872
|
+
inputs.specSyncMode,
|
|
128873
|
+
options.releaseLabel
|
|
128874
|
+
) : void 0;
|
|
128660
128875
|
if (inputs.baselineCollectionId) {
|
|
128661
128876
|
const col = await dependencies.postman.getCollection(inputs.baselineCollectionId);
|
|
128662
128877
|
const dirName = getCollectionDirectoryName("Baseline", assetProjectName);
|
|
@@ -128682,14 +128897,21 @@ async function exportArtifacts(inputs, dependencies, envUids, assetProjectName)
|
|
|
128682
128897
|
true
|
|
128683
128898
|
);
|
|
128684
128899
|
}
|
|
128900
|
+
const durableWorkspaceId = resolveDurableWorkspaceId({
|
|
128901
|
+
candidateId: inputs.workspaceId,
|
|
128902
|
+
priorId: options.priorWorkspaceId,
|
|
128903
|
+
workspaceLinkEnabled: inputs.workspaceLinkEnabled,
|
|
128904
|
+
workspaceLinkStatus: options.workspaceLinkStatus
|
|
128905
|
+
});
|
|
128685
128906
|
(0, import_node_fs3.writeFileSync)(".postman/resources.yaml", buildResourcesManifest(
|
|
128686
|
-
|
|
128907
|
+
durableWorkspaceId,
|
|
128687
128908
|
manifestCollections,
|
|
128688
128909
|
envUids,
|
|
128689
128910
|
inputs.artifactDir,
|
|
128690
128911
|
discoveredSpecs.map((spec) => spec.configRelativePath),
|
|
128691
|
-
|
|
128692
|
-
inputs.specId || void 0
|
|
128912
|
+
mappedSpecCloudKey,
|
|
128913
|
+
inputs.specId || void 0,
|
|
128914
|
+
options.existingSpecs
|
|
128693
128915
|
));
|
|
128694
128916
|
if (mappedSpec && Object.keys(manifestCollections).length > 0) {
|
|
128695
128917
|
(0, import_node_fs3.writeFileSync)(
|
|
@@ -128856,12 +129078,17 @@ async function runRepoSyncInner(inputs, dependencies) {
|
|
|
128856
129078
|
const mockEnvUid = envUids.dev || envUids.prod || Object.values(envUids)[0];
|
|
128857
129079
|
if (mockEnvUid) {
|
|
128858
129080
|
let resolvedMockUrl = "";
|
|
129081
|
+
const mockName = `${assetProjectName} Mock`;
|
|
128859
129082
|
if (inputs.mockUrl) {
|
|
128860
129083
|
resolvedMockUrl = inputs.mockUrl;
|
|
128861
129084
|
dependencies.core.info(`Reusing mock from explicit input: ${resolvedMockUrl}`);
|
|
128862
129085
|
}
|
|
128863
129086
|
if (!resolvedMockUrl && inputs.baselineCollectionId) {
|
|
128864
|
-
const discovered = await dependencies.postman.findMockByCollection(
|
|
129087
|
+
const discovered = await dependencies.postman.findMockByCollection(
|
|
129088
|
+
inputs.baselineCollectionId,
|
|
129089
|
+
mockEnvUid,
|
|
129090
|
+
mockName
|
|
129091
|
+
);
|
|
128865
129092
|
if (discovered) {
|
|
128866
129093
|
resolvedMockUrl = discovered.mockUrl;
|
|
128867
129094
|
dependencies.core.info(`Discovered existing mock for collection ${inputs.baselineCollectionId}: ${resolvedMockUrl}`);
|
|
@@ -128870,7 +129097,7 @@ async function runRepoSyncInner(inputs, dependencies) {
|
|
|
128870
129097
|
if (!resolvedMockUrl) {
|
|
128871
129098
|
const mock = await dependencies.postman.createMock(
|
|
128872
129099
|
inputs.workspaceId,
|
|
128873
|
-
|
|
129100
|
+
mockName,
|
|
128874
129101
|
inputs.baselineCollectionId,
|
|
128875
129102
|
mockEnvUid
|
|
128876
129103
|
);
|
|
@@ -128885,6 +129112,7 @@ async function runRepoSyncInner(inputs, dependencies) {
|
|
|
128885
129112
|
const effectiveCron = inputs.monitorCron && inputs.monitorCron.trim() ? inputs.monitorCron.trim() : "";
|
|
128886
129113
|
if (monitorEnvUid && inputs.monitorType !== "cli") {
|
|
128887
129114
|
let resolvedMonitorId = "";
|
|
129115
|
+
const monitorName = `${assetProjectName} - Smoke Monitor`;
|
|
128888
129116
|
if (inputs.monitorId) {
|
|
128889
129117
|
const valid = await dependencies.postman.monitorExists(inputs.monitorId);
|
|
128890
129118
|
if (valid) {
|
|
@@ -128895,7 +129123,11 @@ async function runRepoSyncInner(inputs, dependencies) {
|
|
|
128895
129123
|
}
|
|
128896
129124
|
}
|
|
128897
129125
|
if (!resolvedMonitorId && inputs.smokeCollectionId) {
|
|
128898
|
-
const discovered = await dependencies.postman.findMonitorByCollection(
|
|
129126
|
+
const discovered = await dependencies.postman.findMonitorByCollection(
|
|
129127
|
+
inputs.smokeCollectionId,
|
|
129128
|
+
monitorEnvUid,
|
|
129129
|
+
monitorName
|
|
129130
|
+
);
|
|
128899
129131
|
if (discovered) {
|
|
128900
129132
|
resolvedMonitorId = discovered.uid;
|
|
128901
129133
|
dependencies.core.info(`Discovered existing monitor for collection ${inputs.smokeCollectionId}: ${resolvedMonitorId}`);
|
|
@@ -128904,7 +129136,7 @@ async function runRepoSyncInner(inputs, dependencies) {
|
|
|
128904
129136
|
if (!resolvedMonitorId) {
|
|
128905
129137
|
resolvedMonitorId = await dependencies.postman.createMonitor(
|
|
128906
129138
|
inputs.workspaceId,
|
|
128907
|
-
|
|
129139
|
+
monitorName,
|
|
128908
129140
|
inputs.smokeCollectionId,
|
|
128909
129141
|
monitorEnvUid,
|
|
128910
129142
|
effectiveCron || void 0
|
|
@@ -128938,7 +129170,12 @@ async function runRepoSyncInner(inputs, dependencies) {
|
|
|
128938
129170
|
);
|
|
128939
129171
|
}
|
|
128940
129172
|
}
|
|
128941
|
-
await exportArtifacts(inputs, dependencies, envUids, assetProjectName
|
|
129173
|
+
await exportArtifacts(inputs, dependencies, envUids, assetProjectName, {
|
|
129174
|
+
workspaceLinkStatus: outputs["workspace-link-status"],
|
|
129175
|
+
priorWorkspaceId: resourcesState?.workspace?.id,
|
|
129176
|
+
existingSpecs: resourcesState?.cloudResources?.specs,
|
|
129177
|
+
releaseLabel
|
|
129178
|
+
});
|
|
128942
129179
|
const commit = await commitAndPushGeneratedFiles(inputs, dependencies);
|
|
128943
129180
|
outputs["commit-sha"] = commit.commitSha;
|
|
128944
129181
|
if (commit.resolvedCurrentRef) {
|
|
@@ -129117,6 +129354,7 @@ function createRepoSyncDependencies(inputs, resolved, factories, options = {}) {
|
|
|
129117
129354
|
createEnvironment: gatewayAssets.createEnvironment.bind(gatewayAssets),
|
|
129118
129355
|
getEnvironment: gatewayAssets.getEnvironment.bind(gatewayAssets),
|
|
129119
129356
|
updateEnvironment: gatewayAssets.updateEnvironment.bind(gatewayAssets),
|
|
129357
|
+
findEnvironmentByName: gatewayAssets.findEnvironmentByName.bind(gatewayAssets),
|
|
129120
129358
|
// Collection read via the v3 export endpoint — returns canonical v3 IR,
|
|
129121
129359
|
// written to disk by `convertAndSplitAnyCollection`. PMAK is never used for
|
|
129122
129360
|
// collection reads.
|