@postman-cse/onboarding-repo-sync 1.0.1 → 1.0.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 +16 -5
- package/action.yml +2 -2
- package/dist/action.cjs +80 -4
- package/dist/cli.cjs +80 -4
- package/dist/index.cjs +80 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
# Postman Repo Sync
|
|
1
|
+
# Postman Onboarding: Repo Sync
|
|
2
2
|
|
|
3
|
-
[](https://github.com/postman-cs/postman-repo-sync-action/actions/workflows/ci.yml)
|
|
4
|
-
[](https://github.com/postman-cs/postman-repo-sync-action/releases)
|
|
5
|
-
[](https://www.npmjs.com/package/@postman-cse/onboarding-repo-sync)
|
|
6
|
-
[](LICENSE)
|
|
3
|
+
[](https://github.com/postman-cs/postman-repo-sync-action/actions/workflows/ci.yml) [](https://github.com/postman-cs/postman-repo-sync-action/releases) [](https://www.npmjs.com/package/@postman-cse/onboarding-repo-sync) [](LICENSE)
|
|
7
4
|
|
|
8
5
|
Exports Postman collections and environments into your repository and wires CI, mocks, and monitors around them.
|
|
9
6
|
|
|
7
|
+
Part of the [Postman API Onboarding suite](https://github.com/postman-cs/postman-api-onboarding-action).
|
|
8
|
+
|
|
10
9
|
## Usage
|
|
11
10
|
|
|
12
11
|
```yaml
|
|
@@ -205,6 +204,18 @@ Deeper reference:
|
|
|
205
204
|
|
|
206
205
|
## Resources
|
|
207
206
|
|
|
207
|
+
### The suite
|
|
208
|
+
|
|
209
|
+
| Action | Role |
|
|
210
|
+
| --- | --- |
|
|
211
|
+
| [Postman API Onboarding](https://github.com/postman-cs/postman-api-onboarding-action) | Entry point: chains workspace bootstrap, repo sync, and optional Insights linking |
|
|
212
|
+
| [Postman Onboarding: Service Token](https://github.com/postman-cs/postman-resolve-service-token-action) | Mints the service-account access token and team ID |
|
|
213
|
+
| [Postman Onboarding: AWS Spec Discovery](https://github.com/postman-cs/postman-aws-spec-discovery-action) | Discovers and exports API specs from AWS services |
|
|
214
|
+
| [Postman Onboarding: Workspace Bootstrap](https://github.com/postman-cs/postman-bootstrap-action) | Creates the workspace, uploads the spec, generates collections |
|
|
215
|
+
| [Postman Onboarding: Smoke Flow](https://github.com/postman-cs/postman-smoke-flow-action) | Applies a curated flow.yaml to the Smoke collection |
|
|
216
|
+
| [Postman Onboarding: Repo Sync](https://github.com/postman-cs/postman-repo-sync-action) | Exports artifacts into the repo and wires CI, mocks, and monitors |
|
|
217
|
+
| [Postman Onboarding: Insights Linking](https://github.com/postman-cs/postman-insights-onboarding-action) | Links Insights discovered services to the workspace |
|
|
218
|
+
|
|
208
219
|
- [postman-resolve-service-token-action](https://github.com/postman-cs/postman-resolve-service-token-action): mints a service-account access token and team ID.
|
|
209
220
|
- [postman-api-onboarding-action](https://github.com/postman-cs/postman-api-onboarding-action): composite action that orchestrates the onboarding pipeline.
|
|
210
221
|
- [postman-bootstrap-action](https://github.com/postman-cs/postman-bootstrap-action): workspace provisioning, spec upload, and collection generation.
|
package/action.yml
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
name: Postman Repo Sync
|
|
2
|
-
description: Export Postman collections and environments into your repo
|
|
1
|
+
name: 'Postman Onboarding: Repo Sync'
|
|
2
|
+
description: Export Postman collections and environments into your repo with CI wiring. Part of the Postman API Onboarding suite.
|
|
3
3
|
author: Postman
|
|
4
4
|
branding:
|
|
5
5
|
icon: refresh-cw
|
package/dist/action.cjs
CHANGED
|
@@ -9182,14 +9182,14 @@ var require_retry_agent = __commonJS({
|
|
|
9182
9182
|
this.#options = options;
|
|
9183
9183
|
}
|
|
9184
9184
|
dispatch(opts, handler) {
|
|
9185
|
-
const
|
|
9185
|
+
const retry2 = new RetryHandler({
|
|
9186
9186
|
...opts,
|
|
9187
9187
|
retryOptions: this.#options
|
|
9188
9188
|
}, {
|
|
9189
9189
|
dispatch: this.#agent.dispatch.bind(this.#agent),
|
|
9190
9190
|
handler
|
|
9191
9191
|
});
|
|
9192
|
-
return this.#agent.dispatch(opts,
|
|
9192
|
+
return this.#agent.dispatch(opts, retry2);
|
|
9193
9193
|
}
|
|
9194
9194
|
close() {
|
|
9195
9195
|
return this.#agent.close();
|
|
@@ -25282,12 +25282,60 @@ var postmanRepoSyncActionContract = {
|
|
|
25282
25282
|
}
|
|
25283
25283
|
};
|
|
25284
25284
|
|
|
25285
|
+
// src/lib/retry.ts
|
|
25286
|
+
function sleep(delayMs) {
|
|
25287
|
+
return new Promise((resolve3) => {
|
|
25288
|
+
setTimeout(resolve3, delayMs);
|
|
25289
|
+
});
|
|
25290
|
+
}
|
|
25291
|
+
function normalizeRetryOptions(options) {
|
|
25292
|
+
return {
|
|
25293
|
+
maxAttempts: Math.max(1, options.maxAttempts ?? 3),
|
|
25294
|
+
delayMs: Math.max(0, options.delayMs ?? 2e3),
|
|
25295
|
+
backoffMultiplier: Math.max(1, options.backoffMultiplier ?? 1),
|
|
25296
|
+
maxDelayMs: options.maxDelayMs === void 0 ? Number.POSITIVE_INFINITY : Math.max(0, options.maxDelayMs),
|
|
25297
|
+
onRetry: options.onRetry ?? (async () => void 0),
|
|
25298
|
+
shouldRetry: options.shouldRetry ?? (() => true),
|
|
25299
|
+
sleep: options.sleep ?? sleep
|
|
25300
|
+
};
|
|
25301
|
+
}
|
|
25302
|
+
async function retry(operation, options = {}) {
|
|
25303
|
+
const normalized = normalizeRetryOptions(options);
|
|
25304
|
+
let nextDelayMs = normalized.delayMs;
|
|
25305
|
+
for (let attempt = 1; attempt <= normalized.maxAttempts; attempt += 1) {
|
|
25306
|
+
try {
|
|
25307
|
+
return await operation();
|
|
25308
|
+
} catch (error2) {
|
|
25309
|
+
const shouldRetry = attempt < normalized.maxAttempts && normalized.shouldRetry(error2, {
|
|
25310
|
+
attempt,
|
|
25311
|
+
maxAttempts: normalized.maxAttempts
|
|
25312
|
+
});
|
|
25313
|
+
if (!shouldRetry) {
|
|
25314
|
+
throw error2;
|
|
25315
|
+
}
|
|
25316
|
+
await normalized.onRetry({
|
|
25317
|
+
attempt,
|
|
25318
|
+
maxAttempts: normalized.maxAttempts,
|
|
25319
|
+
delayMs: nextDelayMs,
|
|
25320
|
+
error: error2
|
|
25321
|
+
});
|
|
25322
|
+
await normalized.sleep(nextDelayMs);
|
|
25323
|
+
nextDelayMs = Math.min(
|
|
25324
|
+
normalized.maxDelayMs,
|
|
25325
|
+
Math.round(nextDelayMs * normalized.backoffMultiplier)
|
|
25326
|
+
);
|
|
25327
|
+
}
|
|
25328
|
+
}
|
|
25329
|
+
throw new Error("Retry exhausted without returning or throwing");
|
|
25330
|
+
}
|
|
25331
|
+
|
|
25285
25332
|
// src/lib/postman/postman-assets-client.ts
|
|
25286
25333
|
var PostmanAssetsClient = class {
|
|
25287
25334
|
apiKey;
|
|
25288
25335
|
baseUrl;
|
|
25289
25336
|
bifrostBaseUrl;
|
|
25290
25337
|
fetchImpl;
|
|
25338
|
+
retrySleep;
|
|
25291
25339
|
constructor(options) {
|
|
25292
25340
|
this.apiKey = String(options.apiKey || "").trim();
|
|
25293
25341
|
this.baseUrl = String(options.baseUrl || POSTMAN_ENDPOINT_PROFILES.prod.apiBaseUrl).replace(
|
|
@@ -25298,6 +25346,7 @@ var PostmanAssetsClient = class {
|
|
|
25298
25346
|
options.bifrostBaseUrl || POSTMAN_ENDPOINT_PROFILES.prod.bifrostBaseUrl
|
|
25299
25347
|
).replace(/\/+$/, "");
|
|
25300
25348
|
this.fetchImpl = options.fetchImpl ?? fetch;
|
|
25349
|
+
this.retrySleep = options.retrySleep;
|
|
25301
25350
|
void (options.secretMasker ?? createSecretMasker([this.apiKey]));
|
|
25302
25351
|
}
|
|
25303
25352
|
getBaseUrl() {
|
|
@@ -25361,9 +25410,36 @@ var PostmanAssetsClient = class {
|
|
|
25361
25410
|
})
|
|
25362
25411
|
});
|
|
25363
25412
|
}
|
|
25413
|
+
/**
|
|
25414
|
+
* Monitor and mock creation reference a collection that may have been
|
|
25415
|
+
* created moments earlier; the Postman backend is eventually consistent
|
|
25416
|
+
* and can reject the reference with a 400 "Unable to load collection"
|
|
25417
|
+
* until the collection becomes visible. Retry only that specific 400 and
|
|
25418
|
+
* 429 throttling: both guarantee nothing was created. A 5xx on these
|
|
25419
|
+
* non-idempotent creates is ambiguous (the asset may exist server-side),
|
|
25420
|
+
* so it is not retried to avoid duplicate mocks and monitors.
|
|
25421
|
+
*/
|
|
25422
|
+
async requestWithCollectionRetry(path8, init) {
|
|
25423
|
+
return retry(() => this.request(path8, init), {
|
|
25424
|
+
maxAttempts: 5,
|
|
25425
|
+
delayMs: 2e3,
|
|
25426
|
+
backoffMultiplier: 2,
|
|
25427
|
+
maxDelayMs: 15e3,
|
|
25428
|
+
...this.retrySleep ? { sleep: this.retrySleep } : {},
|
|
25429
|
+
shouldRetry: (error2) => {
|
|
25430
|
+
if (!(error2 instanceof HttpError)) {
|
|
25431
|
+
return false;
|
|
25432
|
+
}
|
|
25433
|
+
if (error2.status === 429) {
|
|
25434
|
+
return true;
|
|
25435
|
+
}
|
|
25436
|
+
return error2.status === 400 && /unable to load collection/i.test(error2.responseBody);
|
|
25437
|
+
}
|
|
25438
|
+
});
|
|
25439
|
+
}
|
|
25364
25440
|
async createMonitor(workspaceId, name, collectionUid, environmentUid, cronSchedule) {
|
|
25365
25441
|
const effectiveCron = cronSchedule && cronSchedule.trim() ? cronSchedule.trim() : "0 0 * * 0";
|
|
25366
|
-
const response = await this.
|
|
25442
|
+
const response = await this.requestWithCollectionRetry(`/monitors?workspace=${workspaceId}`, {
|
|
25367
25443
|
method: "POST",
|
|
25368
25444
|
body: JSON.stringify({
|
|
25369
25445
|
monitor: {
|
|
@@ -25393,7 +25469,7 @@ var PostmanAssetsClient = class {
|
|
|
25393
25469
|
return uid;
|
|
25394
25470
|
}
|
|
25395
25471
|
async createMock(workspaceId, name, collectionUid, environmentUid) {
|
|
25396
|
-
const response = await this.
|
|
25472
|
+
const response = await this.requestWithCollectionRetry(`/mocks?workspace=${workspaceId}`, {
|
|
25397
25473
|
method: "POST",
|
|
25398
25474
|
body: JSON.stringify({
|
|
25399
25475
|
mock: {
|
package/dist/cli.cjs
CHANGED
|
@@ -9183,14 +9183,14 @@ var require_retry_agent = __commonJS({
|
|
|
9183
9183
|
this.#options = options;
|
|
9184
9184
|
}
|
|
9185
9185
|
dispatch(opts, handler) {
|
|
9186
|
-
const
|
|
9186
|
+
const retry2 = new RetryHandler({
|
|
9187
9187
|
...opts,
|
|
9188
9188
|
retryOptions: this.#options
|
|
9189
9189
|
}, {
|
|
9190
9190
|
dispatch: this.#agent.dispatch.bind(this.#agent),
|
|
9191
9191
|
handler
|
|
9192
9192
|
});
|
|
9193
|
-
return this.#agent.dispatch(opts,
|
|
9193
|
+
return this.#agent.dispatch(opts, retry2);
|
|
9194
9194
|
}
|
|
9195
9195
|
close() {
|
|
9196
9196
|
return this.#agent.close();
|
|
@@ -23385,12 +23385,60 @@ var postmanRepoSyncActionContract = {
|
|
|
23385
23385
|
}
|
|
23386
23386
|
};
|
|
23387
23387
|
|
|
23388
|
+
// src/lib/retry.ts
|
|
23389
|
+
function sleep(delayMs) {
|
|
23390
|
+
return new Promise((resolve2) => {
|
|
23391
|
+
setTimeout(resolve2, delayMs);
|
|
23392
|
+
});
|
|
23393
|
+
}
|
|
23394
|
+
function normalizeRetryOptions(options) {
|
|
23395
|
+
return {
|
|
23396
|
+
maxAttempts: Math.max(1, options.maxAttempts ?? 3),
|
|
23397
|
+
delayMs: Math.max(0, options.delayMs ?? 2e3),
|
|
23398
|
+
backoffMultiplier: Math.max(1, options.backoffMultiplier ?? 1),
|
|
23399
|
+
maxDelayMs: options.maxDelayMs === void 0 ? Number.POSITIVE_INFINITY : Math.max(0, options.maxDelayMs),
|
|
23400
|
+
onRetry: options.onRetry ?? (async () => void 0),
|
|
23401
|
+
shouldRetry: options.shouldRetry ?? (() => true),
|
|
23402
|
+
sleep: options.sleep ?? sleep
|
|
23403
|
+
};
|
|
23404
|
+
}
|
|
23405
|
+
async function retry(operation, options = {}) {
|
|
23406
|
+
const normalized = normalizeRetryOptions(options);
|
|
23407
|
+
let nextDelayMs = normalized.delayMs;
|
|
23408
|
+
for (let attempt = 1; attempt <= normalized.maxAttempts; attempt += 1) {
|
|
23409
|
+
try {
|
|
23410
|
+
return await operation();
|
|
23411
|
+
} catch (error) {
|
|
23412
|
+
const shouldRetry = attempt < normalized.maxAttempts && normalized.shouldRetry(error, {
|
|
23413
|
+
attempt,
|
|
23414
|
+
maxAttempts: normalized.maxAttempts
|
|
23415
|
+
});
|
|
23416
|
+
if (!shouldRetry) {
|
|
23417
|
+
throw error;
|
|
23418
|
+
}
|
|
23419
|
+
await normalized.onRetry({
|
|
23420
|
+
attempt,
|
|
23421
|
+
maxAttempts: normalized.maxAttempts,
|
|
23422
|
+
delayMs: nextDelayMs,
|
|
23423
|
+
error
|
|
23424
|
+
});
|
|
23425
|
+
await normalized.sleep(nextDelayMs);
|
|
23426
|
+
nextDelayMs = Math.min(
|
|
23427
|
+
normalized.maxDelayMs,
|
|
23428
|
+
Math.round(nextDelayMs * normalized.backoffMultiplier)
|
|
23429
|
+
);
|
|
23430
|
+
}
|
|
23431
|
+
}
|
|
23432
|
+
throw new Error("Retry exhausted without returning or throwing");
|
|
23433
|
+
}
|
|
23434
|
+
|
|
23388
23435
|
// src/lib/postman/postman-assets-client.ts
|
|
23389
23436
|
var PostmanAssetsClient = class {
|
|
23390
23437
|
apiKey;
|
|
23391
23438
|
baseUrl;
|
|
23392
23439
|
bifrostBaseUrl;
|
|
23393
23440
|
fetchImpl;
|
|
23441
|
+
retrySleep;
|
|
23394
23442
|
constructor(options) {
|
|
23395
23443
|
this.apiKey = String(options.apiKey || "").trim();
|
|
23396
23444
|
this.baseUrl = String(options.baseUrl || POSTMAN_ENDPOINT_PROFILES.prod.apiBaseUrl).replace(
|
|
@@ -23401,6 +23449,7 @@ var PostmanAssetsClient = class {
|
|
|
23401
23449
|
options.bifrostBaseUrl || POSTMAN_ENDPOINT_PROFILES.prod.bifrostBaseUrl
|
|
23402
23450
|
).replace(/\/+$/, "");
|
|
23403
23451
|
this.fetchImpl = options.fetchImpl ?? fetch;
|
|
23452
|
+
this.retrySleep = options.retrySleep;
|
|
23404
23453
|
void (options.secretMasker ?? createSecretMasker([this.apiKey]));
|
|
23405
23454
|
}
|
|
23406
23455
|
getBaseUrl() {
|
|
@@ -23464,9 +23513,36 @@ var PostmanAssetsClient = class {
|
|
|
23464
23513
|
})
|
|
23465
23514
|
});
|
|
23466
23515
|
}
|
|
23516
|
+
/**
|
|
23517
|
+
* Monitor and mock creation reference a collection that may have been
|
|
23518
|
+
* created moments earlier; the Postman backend is eventually consistent
|
|
23519
|
+
* and can reject the reference with a 400 "Unable to load collection"
|
|
23520
|
+
* until the collection becomes visible. Retry only that specific 400 and
|
|
23521
|
+
* 429 throttling: both guarantee nothing was created. A 5xx on these
|
|
23522
|
+
* non-idempotent creates is ambiguous (the asset may exist server-side),
|
|
23523
|
+
* so it is not retried to avoid duplicate mocks and monitors.
|
|
23524
|
+
*/
|
|
23525
|
+
async requestWithCollectionRetry(path4, init) {
|
|
23526
|
+
return retry(() => this.request(path4, init), {
|
|
23527
|
+
maxAttempts: 5,
|
|
23528
|
+
delayMs: 2e3,
|
|
23529
|
+
backoffMultiplier: 2,
|
|
23530
|
+
maxDelayMs: 15e3,
|
|
23531
|
+
...this.retrySleep ? { sleep: this.retrySleep } : {},
|
|
23532
|
+
shouldRetry: (error) => {
|
|
23533
|
+
if (!(error instanceof HttpError)) {
|
|
23534
|
+
return false;
|
|
23535
|
+
}
|
|
23536
|
+
if (error.status === 429) {
|
|
23537
|
+
return true;
|
|
23538
|
+
}
|
|
23539
|
+
return error.status === 400 && /unable to load collection/i.test(error.responseBody);
|
|
23540
|
+
}
|
|
23541
|
+
});
|
|
23542
|
+
}
|
|
23467
23543
|
async createMonitor(workspaceId, name, collectionUid, environmentUid, cronSchedule) {
|
|
23468
23544
|
const effectiveCron = cronSchedule && cronSchedule.trim() ? cronSchedule.trim() : "0 0 * * 0";
|
|
23469
|
-
const response = await this.
|
|
23545
|
+
const response = await this.requestWithCollectionRetry(`/monitors?workspace=${workspaceId}`, {
|
|
23470
23546
|
method: "POST",
|
|
23471
23547
|
body: JSON.stringify({
|
|
23472
23548
|
monitor: {
|
|
@@ -23496,7 +23572,7 @@ var PostmanAssetsClient = class {
|
|
|
23496
23572
|
return uid;
|
|
23497
23573
|
}
|
|
23498
23574
|
async createMock(workspaceId, name, collectionUid, environmentUid) {
|
|
23499
|
-
const response = await this.
|
|
23575
|
+
const response = await this.requestWithCollectionRetry(`/mocks?workspace=${workspaceId}`, {
|
|
23500
23576
|
method: "POST",
|
|
23501
23577
|
body: JSON.stringify({
|
|
23502
23578
|
mock: {
|
package/dist/index.cjs
CHANGED
|
@@ -9183,14 +9183,14 @@ var require_retry_agent = __commonJS({
|
|
|
9183
9183
|
this.#options = options;
|
|
9184
9184
|
}
|
|
9185
9185
|
dispatch(opts, handler) {
|
|
9186
|
-
const
|
|
9186
|
+
const retry2 = new RetryHandler({
|
|
9187
9187
|
...opts,
|
|
9188
9188
|
retryOptions: this.#options
|
|
9189
9189
|
}, {
|
|
9190
9190
|
dispatch: this.#agent.dispatch.bind(this.#agent),
|
|
9191
9191
|
handler
|
|
9192
9192
|
});
|
|
9193
|
-
return this.#agent.dispatch(opts,
|
|
9193
|
+
return this.#agent.dispatch(opts, retry2);
|
|
9194
9194
|
}
|
|
9195
9195
|
close() {
|
|
9196
9196
|
return this.#agent.close();
|
|
@@ -25297,12 +25297,60 @@ var postmanRepoSyncActionContract = {
|
|
|
25297
25297
|
}
|
|
25298
25298
|
};
|
|
25299
25299
|
|
|
25300
|
+
// src/lib/retry.ts
|
|
25301
|
+
function sleep(delayMs) {
|
|
25302
|
+
return new Promise((resolve3) => {
|
|
25303
|
+
setTimeout(resolve3, delayMs);
|
|
25304
|
+
});
|
|
25305
|
+
}
|
|
25306
|
+
function normalizeRetryOptions(options) {
|
|
25307
|
+
return {
|
|
25308
|
+
maxAttempts: Math.max(1, options.maxAttempts ?? 3),
|
|
25309
|
+
delayMs: Math.max(0, options.delayMs ?? 2e3),
|
|
25310
|
+
backoffMultiplier: Math.max(1, options.backoffMultiplier ?? 1),
|
|
25311
|
+
maxDelayMs: options.maxDelayMs === void 0 ? Number.POSITIVE_INFINITY : Math.max(0, options.maxDelayMs),
|
|
25312
|
+
onRetry: options.onRetry ?? (async () => void 0),
|
|
25313
|
+
shouldRetry: options.shouldRetry ?? (() => true),
|
|
25314
|
+
sleep: options.sleep ?? sleep
|
|
25315
|
+
};
|
|
25316
|
+
}
|
|
25317
|
+
async function retry(operation, options = {}) {
|
|
25318
|
+
const normalized = normalizeRetryOptions(options);
|
|
25319
|
+
let nextDelayMs = normalized.delayMs;
|
|
25320
|
+
for (let attempt = 1; attempt <= normalized.maxAttempts; attempt += 1) {
|
|
25321
|
+
try {
|
|
25322
|
+
return await operation();
|
|
25323
|
+
} catch (error2) {
|
|
25324
|
+
const shouldRetry = attempt < normalized.maxAttempts && normalized.shouldRetry(error2, {
|
|
25325
|
+
attempt,
|
|
25326
|
+
maxAttempts: normalized.maxAttempts
|
|
25327
|
+
});
|
|
25328
|
+
if (!shouldRetry) {
|
|
25329
|
+
throw error2;
|
|
25330
|
+
}
|
|
25331
|
+
await normalized.onRetry({
|
|
25332
|
+
attempt,
|
|
25333
|
+
maxAttempts: normalized.maxAttempts,
|
|
25334
|
+
delayMs: nextDelayMs,
|
|
25335
|
+
error: error2
|
|
25336
|
+
});
|
|
25337
|
+
await normalized.sleep(nextDelayMs);
|
|
25338
|
+
nextDelayMs = Math.min(
|
|
25339
|
+
normalized.maxDelayMs,
|
|
25340
|
+
Math.round(nextDelayMs * normalized.backoffMultiplier)
|
|
25341
|
+
);
|
|
25342
|
+
}
|
|
25343
|
+
}
|
|
25344
|
+
throw new Error("Retry exhausted without returning or throwing");
|
|
25345
|
+
}
|
|
25346
|
+
|
|
25300
25347
|
// src/lib/postman/postman-assets-client.ts
|
|
25301
25348
|
var PostmanAssetsClient = class {
|
|
25302
25349
|
apiKey;
|
|
25303
25350
|
baseUrl;
|
|
25304
25351
|
bifrostBaseUrl;
|
|
25305
25352
|
fetchImpl;
|
|
25353
|
+
retrySleep;
|
|
25306
25354
|
constructor(options) {
|
|
25307
25355
|
this.apiKey = String(options.apiKey || "").trim();
|
|
25308
25356
|
this.baseUrl = String(options.baseUrl || POSTMAN_ENDPOINT_PROFILES.prod.apiBaseUrl).replace(
|
|
@@ -25313,6 +25361,7 @@ var PostmanAssetsClient = class {
|
|
|
25313
25361
|
options.bifrostBaseUrl || POSTMAN_ENDPOINT_PROFILES.prod.bifrostBaseUrl
|
|
25314
25362
|
).replace(/\/+$/, "");
|
|
25315
25363
|
this.fetchImpl = options.fetchImpl ?? fetch;
|
|
25364
|
+
this.retrySleep = options.retrySleep;
|
|
25316
25365
|
void (options.secretMasker ?? createSecretMasker([this.apiKey]));
|
|
25317
25366
|
}
|
|
25318
25367
|
getBaseUrl() {
|
|
@@ -25376,9 +25425,36 @@ var PostmanAssetsClient = class {
|
|
|
25376
25425
|
})
|
|
25377
25426
|
});
|
|
25378
25427
|
}
|
|
25428
|
+
/**
|
|
25429
|
+
* Monitor and mock creation reference a collection that may have been
|
|
25430
|
+
* created moments earlier; the Postman backend is eventually consistent
|
|
25431
|
+
* and can reject the reference with a 400 "Unable to load collection"
|
|
25432
|
+
* until the collection becomes visible. Retry only that specific 400 and
|
|
25433
|
+
* 429 throttling: both guarantee nothing was created. A 5xx on these
|
|
25434
|
+
* non-idempotent creates is ambiguous (the asset may exist server-side),
|
|
25435
|
+
* so it is not retried to avoid duplicate mocks and monitors.
|
|
25436
|
+
*/
|
|
25437
|
+
async requestWithCollectionRetry(path8, init) {
|
|
25438
|
+
return retry(() => this.request(path8, init), {
|
|
25439
|
+
maxAttempts: 5,
|
|
25440
|
+
delayMs: 2e3,
|
|
25441
|
+
backoffMultiplier: 2,
|
|
25442
|
+
maxDelayMs: 15e3,
|
|
25443
|
+
...this.retrySleep ? { sleep: this.retrySleep } : {},
|
|
25444
|
+
shouldRetry: (error2) => {
|
|
25445
|
+
if (!(error2 instanceof HttpError)) {
|
|
25446
|
+
return false;
|
|
25447
|
+
}
|
|
25448
|
+
if (error2.status === 429) {
|
|
25449
|
+
return true;
|
|
25450
|
+
}
|
|
25451
|
+
return error2.status === 400 && /unable to load collection/i.test(error2.responseBody);
|
|
25452
|
+
}
|
|
25453
|
+
});
|
|
25454
|
+
}
|
|
25379
25455
|
async createMonitor(workspaceId, name, collectionUid, environmentUid, cronSchedule) {
|
|
25380
25456
|
const effectiveCron = cronSchedule && cronSchedule.trim() ? cronSchedule.trim() : "0 0 * * 0";
|
|
25381
|
-
const response = await this.
|
|
25457
|
+
const response = await this.requestWithCollectionRetry(`/monitors?workspace=${workspaceId}`, {
|
|
25382
25458
|
method: "POST",
|
|
25383
25459
|
body: JSON.stringify({
|
|
25384
25460
|
monitor: {
|
|
@@ -25408,7 +25484,7 @@ var PostmanAssetsClient = class {
|
|
|
25408
25484
|
return uid;
|
|
25409
25485
|
}
|
|
25410
25486
|
async createMock(workspaceId, name, collectionUid, environmentUid) {
|
|
25411
|
-
const response = await this.
|
|
25487
|
+
const response = await this.requestWithCollectionRetry(`/mocks?workspace=${workspaceId}`, {
|
|
25412
25488
|
method: "POST",
|
|
25413
25489
|
body: JSON.stringify({
|
|
25414
25490
|
mock: {
|