@postman-cse/onboarding-repo-sync 2.1.1 → 2.1.2
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 +322 -128
- package/dist/cli.cjs +322 -128
- package/dist/index.cjs +322 -128
- package/package.json +1 -1
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
|
}
|
|
@@ -128856,12 +129039,17 @@ async function runRepoSyncInner(inputs, dependencies) {
|
|
|
128856
129039
|
const mockEnvUid = envUids.dev || envUids.prod || Object.values(envUids)[0];
|
|
128857
129040
|
if (mockEnvUid) {
|
|
128858
129041
|
let resolvedMockUrl = "";
|
|
129042
|
+
const mockName = `${assetProjectName} Mock`;
|
|
128859
129043
|
if (inputs.mockUrl) {
|
|
128860
129044
|
resolvedMockUrl = inputs.mockUrl;
|
|
128861
129045
|
dependencies.core.info(`Reusing mock from explicit input: ${resolvedMockUrl}`);
|
|
128862
129046
|
}
|
|
128863
129047
|
if (!resolvedMockUrl && inputs.baselineCollectionId) {
|
|
128864
|
-
const discovered = await dependencies.postman.findMockByCollection(
|
|
129048
|
+
const discovered = await dependencies.postman.findMockByCollection(
|
|
129049
|
+
inputs.baselineCollectionId,
|
|
129050
|
+
mockEnvUid,
|
|
129051
|
+
mockName
|
|
129052
|
+
);
|
|
128865
129053
|
if (discovered) {
|
|
128866
129054
|
resolvedMockUrl = discovered.mockUrl;
|
|
128867
129055
|
dependencies.core.info(`Discovered existing mock for collection ${inputs.baselineCollectionId}: ${resolvedMockUrl}`);
|
|
@@ -128870,7 +129058,7 @@ async function runRepoSyncInner(inputs, dependencies) {
|
|
|
128870
129058
|
if (!resolvedMockUrl) {
|
|
128871
129059
|
const mock = await dependencies.postman.createMock(
|
|
128872
129060
|
inputs.workspaceId,
|
|
128873
|
-
|
|
129061
|
+
mockName,
|
|
128874
129062
|
inputs.baselineCollectionId,
|
|
128875
129063
|
mockEnvUid
|
|
128876
129064
|
);
|
|
@@ -128885,6 +129073,7 @@ async function runRepoSyncInner(inputs, dependencies) {
|
|
|
128885
129073
|
const effectiveCron = inputs.monitorCron && inputs.monitorCron.trim() ? inputs.monitorCron.trim() : "";
|
|
128886
129074
|
if (monitorEnvUid && inputs.monitorType !== "cli") {
|
|
128887
129075
|
let resolvedMonitorId = "";
|
|
129076
|
+
const monitorName = `${assetProjectName} - Smoke Monitor`;
|
|
128888
129077
|
if (inputs.monitorId) {
|
|
128889
129078
|
const valid = await dependencies.postman.monitorExists(inputs.monitorId);
|
|
128890
129079
|
if (valid) {
|
|
@@ -128895,7 +129084,11 @@ async function runRepoSyncInner(inputs, dependencies) {
|
|
|
128895
129084
|
}
|
|
128896
129085
|
}
|
|
128897
129086
|
if (!resolvedMonitorId && inputs.smokeCollectionId) {
|
|
128898
|
-
const discovered = await dependencies.postman.findMonitorByCollection(
|
|
129087
|
+
const discovered = await dependencies.postman.findMonitorByCollection(
|
|
129088
|
+
inputs.smokeCollectionId,
|
|
129089
|
+
monitorEnvUid,
|
|
129090
|
+
monitorName
|
|
129091
|
+
);
|
|
128899
129092
|
if (discovered) {
|
|
128900
129093
|
resolvedMonitorId = discovered.uid;
|
|
128901
129094
|
dependencies.core.info(`Discovered existing monitor for collection ${inputs.smokeCollectionId}: ${resolvedMonitorId}`);
|
|
@@ -128904,7 +129097,7 @@ async function runRepoSyncInner(inputs, dependencies) {
|
|
|
128904
129097
|
if (!resolvedMonitorId) {
|
|
128905
129098
|
resolvedMonitorId = await dependencies.postman.createMonitor(
|
|
128906
129099
|
inputs.workspaceId,
|
|
128907
|
-
|
|
129100
|
+
monitorName,
|
|
128908
129101
|
inputs.smokeCollectionId,
|
|
128909
129102
|
monitorEnvUid,
|
|
128910
129103
|
effectiveCron || void 0
|
|
@@ -129117,6 +129310,7 @@ function createRepoSyncDependencies(inputs, resolved, factories, options = {}) {
|
|
|
129117
129310
|
createEnvironment: gatewayAssets.createEnvironment.bind(gatewayAssets),
|
|
129118
129311
|
getEnvironment: gatewayAssets.getEnvironment.bind(gatewayAssets),
|
|
129119
129312
|
updateEnvironment: gatewayAssets.updateEnvironment.bind(gatewayAssets),
|
|
129313
|
+
findEnvironmentByName: gatewayAssets.findEnvironmentByName.bind(gatewayAssets),
|
|
129120
129314
|
// Collection read via the v3 export endpoint — returns canonical v3 IR,
|
|
129121
129315
|
// written to disk by `convertAndSplitAnyCollection`. PMAK is never used for
|
|
129122
129316
|
// collection reads.
|