@postman-cse/onboarding-bootstrap 2.7.1 → 2.9.0
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 +77 -29
- package/dist/cli.cjs +77 -29
- package/dist/index.cjs +78 -30
- package/package.json +3 -1
package/dist/action.cjs
CHANGED
|
@@ -263423,6 +263423,14 @@ function asRecord7(value) {
|
|
|
263423
263423
|
}
|
|
263424
263424
|
return value;
|
|
263425
263425
|
}
|
|
263426
|
+
function resolvePollBudget(explicit, envValue, fallback, min) {
|
|
263427
|
+
if (typeof explicit === "number" && Number.isFinite(explicit) && explicit >= min) return explicit;
|
|
263428
|
+
if (envValue !== void 0) {
|
|
263429
|
+
const parsed = Number(envValue);
|
|
263430
|
+
if (Number.isFinite(parsed) && parsed >= min) return parsed;
|
|
263431
|
+
}
|
|
263432
|
+
return fallback;
|
|
263433
|
+
}
|
|
263426
263434
|
function adviseWorkspaceFlipForbidden(error2) {
|
|
263427
263435
|
if (error2 instanceof HttpError && error2.status === 403) {
|
|
263428
263436
|
const body2 = error2.responseBody || "";
|
|
@@ -263459,13 +263467,27 @@ function extractGitRepoUrl(value) {
|
|
|
263459
263467
|
}
|
|
263460
263468
|
var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
|
|
263461
263469
|
static GENERATION_LOCKED_MAX_RETRIES = 5;
|
|
263462
|
-
static
|
|
263463
|
-
static
|
|
263470
|
+
static DEFAULT_GENERATION_POLL_ATTEMPTS = 90;
|
|
263471
|
+
static DEFAULT_GENERATION_POLL_DELAY_MS = 2e3;
|
|
263464
263472
|
gateway;
|
|
263465
263473
|
sleep;
|
|
263474
|
+
generationPollAttempts;
|
|
263475
|
+
generationPollDelayMs;
|
|
263466
263476
|
constructor(options) {
|
|
263467
263477
|
this.gateway = options.gateway;
|
|
263468
263478
|
this.sleep = options.sleep ?? ((delayMs) => new Promise((resolve5) => setTimeout(resolve5, delayMs)));
|
|
263479
|
+
this.generationPollAttempts = resolvePollBudget(
|
|
263480
|
+
options.generationPollAttempts,
|
|
263481
|
+
process.env.POSTMAN_GENERATION_POLL_ATTEMPTS,
|
|
263482
|
+
_PostmanGatewayAssetsClient.DEFAULT_GENERATION_POLL_ATTEMPTS,
|
|
263483
|
+
1
|
|
263484
|
+
);
|
|
263485
|
+
this.generationPollDelayMs = resolvePollBudget(
|
|
263486
|
+
options.generationPollDelayMs,
|
|
263487
|
+
process.env.POSTMAN_GENERATION_POLL_DELAY_MS,
|
|
263488
|
+
_PostmanGatewayAssetsClient.DEFAULT_GENERATION_POLL_DELAY_MS,
|
|
263489
|
+
0
|
|
263490
|
+
);
|
|
263469
263491
|
}
|
|
263470
263492
|
configureTeamContext(teamId, orgMode) {
|
|
263471
263493
|
this.gateway.configureTeamContext(teamId, orgMode);
|
|
@@ -263610,8 +263632,8 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
|
|
|
263610
263632
|
};
|
|
263611
263633
|
const taskId = await this.postGenerationWithLockRetry(specId, body2);
|
|
263612
263634
|
if (taskId) {
|
|
263613
|
-
for (let attempt = 0; attempt <
|
|
263614
|
-
await this.sleep(
|
|
263635
|
+
for (let attempt = 0; attempt < this.generationPollAttempts; attempt += 1) {
|
|
263636
|
+
await this.sleep(this.generationPollDelayMs);
|
|
263615
263637
|
const task = await this.gateway.requestJson({
|
|
263616
263638
|
service: "specification",
|
|
263617
263639
|
method: "get",
|
|
@@ -263625,7 +263647,7 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
|
|
|
263625
263647
|
if (status && status !== "in-progress" && status !== "pending" && status !== "queued") {
|
|
263626
263648
|
break;
|
|
263627
263649
|
}
|
|
263628
|
-
if (attempt ===
|
|
263650
|
+
if (attempt === this.generationPollAttempts - 1) {
|
|
263629
263651
|
throw new Error(`Collection generation timed out for ${prefix}`);
|
|
263630
263652
|
}
|
|
263631
263653
|
}
|
|
@@ -264590,6 +264612,53 @@ var AccessTokenProvider = class {
|
|
|
264590
264612
|
return token;
|
|
264591
264613
|
}
|
|
264592
264614
|
};
|
|
264615
|
+
async function describeMintFailure(mintError, apiKey, apiBaseUrl, fetchImpl) {
|
|
264616
|
+
const raw = mintError instanceof Error ? mintError.message : String(mintError);
|
|
264617
|
+
const rejected = /HTTP 40[13]|PMAK rejected/.test(raw);
|
|
264618
|
+
if (!rejected) {
|
|
264619
|
+
return raw;
|
|
264620
|
+
}
|
|
264621
|
+
try {
|
|
264622
|
+
const me = await fetchImpl(`${apiBaseUrl}/me`, { headers: { "x-api-key": apiKey } });
|
|
264623
|
+
if (me.ok) {
|
|
264624
|
+
const body2 = await me.json().catch(() => void 0);
|
|
264625
|
+
const user = body2?.user;
|
|
264626
|
+
const looksPersonal = Boolean(user && (user.username || user.email));
|
|
264627
|
+
if (looksPersonal) {
|
|
264628
|
+
return "Personal API key detected, cannot mint a service-account access token. POST /service-account-tokens only accepts a SERVICE-ACCOUNT API key; this postman-api-key belongs to a user account" + (user?.teamId ? ` (team ${user.teamId})` : "") + ". Create a service account in Team Settings and use its PMAK, or mint the token elsewhere and pass postman-access-token.";
|
|
264629
|
+
}
|
|
264630
|
+
return "The postman-api-key authenticates (GET /me OK) but was rejected by POST /service-account-tokens" + (user?.teamId ? ` (team ${user.teamId})` : "") + ". The service account likely lacks permission to mint access tokens, or service accounts are restricted for this team. Check the service account role in Team Settings, or pass a pre-minted postman-access-token.";
|
|
264631
|
+
}
|
|
264632
|
+
return "The postman-api-key is invalid, disabled, or expired (rejected by both POST /service-account-tokens and GET /me). Generate a fresh service-account PMAK in Team Settings and update the secret.";
|
|
264633
|
+
} catch {
|
|
264634
|
+
return raw;
|
|
264635
|
+
}
|
|
264636
|
+
}
|
|
264637
|
+
async function mintAccessTokenIfNeeded(inputs, log, setSecret2, fetchImpl = fetch) {
|
|
264638
|
+
if (inputs.postmanAccessToken || !inputs.postmanApiKey) {
|
|
264639
|
+
return;
|
|
264640
|
+
}
|
|
264641
|
+
const apiBaseUrl = String(
|
|
264642
|
+
inputs.postmanApiBase || POSTMAN_ENDPOINT_PROFILES.prod.apiBaseUrl
|
|
264643
|
+
).replace(/\/+$/, "");
|
|
264644
|
+
const provider = new AccessTokenProvider({
|
|
264645
|
+
apiKey: inputs.postmanApiKey,
|
|
264646
|
+
apiBaseUrl,
|
|
264647
|
+
fetchImpl,
|
|
264648
|
+
onToken: (token) => setSecret2?.(token)
|
|
264649
|
+
});
|
|
264650
|
+
try {
|
|
264651
|
+
inputs.postmanAccessToken = await provider.refresh();
|
|
264652
|
+
log.info(
|
|
264653
|
+
"postman: no postman-access-token configured - minted a short-lived service-account access token from the postman-api-key."
|
|
264654
|
+
);
|
|
264655
|
+
} catch (error2) {
|
|
264656
|
+
const diagnosis = await describeMintFailure(error2, inputs.postmanApiKey, apiBaseUrl, fetchImpl);
|
|
264657
|
+
log.warning(
|
|
264658
|
+
"postman: could not mint an access token from the postman-api-key. " + diagnosis + " Continuing without an access token - access-token-only functionality will be unavailable unless postman-access-token is provided."
|
|
264659
|
+
);
|
|
264660
|
+
}
|
|
264661
|
+
}
|
|
264593
264662
|
|
|
264594
264663
|
// src/lib/postman/workspace-selection.ts
|
|
264595
264664
|
function chooseCanonicalWorkspace(args) {
|
|
@@ -307760,29 +307829,8 @@ function warnIfDeprecatedAccessToken(actionCore, inputs) {
|
|
|
307760
307829
|
)
|
|
307761
307830
|
);
|
|
307762
307831
|
}
|
|
307763
|
-
async function
|
|
307764
|
-
|
|
307765
|
-
return;
|
|
307766
|
-
}
|
|
307767
|
-
const provider = new AccessTokenProvider({
|
|
307768
|
-
apiKey: inputs.postmanApiKey,
|
|
307769
|
-
apiBaseUrl: inputs.postmanApiBase,
|
|
307770
|
-
onToken: (token) => setSecret2?.(token)
|
|
307771
|
-
});
|
|
307772
|
-
try {
|
|
307773
|
-
inputs.postmanAccessToken = await provider.refresh();
|
|
307774
|
-
log.info(
|
|
307775
|
-
"postman: no postman-access-token configured - minted a short-lived service-account access token from the postman-api-key."
|
|
307776
|
-
);
|
|
307777
|
-
} catch (error2) {
|
|
307778
|
-
const mask = createSecretMasker([inputs.postmanApiKey]);
|
|
307779
|
-
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
307780
|
-
log.warning(
|
|
307781
|
-
mask(
|
|
307782
|
-
"postman: could not mint an access token from the postman-api-key (" + message + "). Continuing with PMAK only - governance assignment and org-mode detection are disabled. Configure postman-access-token (postman-cs/postman-resolve-service-token-action) for full functionality."
|
|
307783
|
-
)
|
|
307784
|
-
);
|
|
307785
|
-
}
|
|
307832
|
+
async function mintAccessTokenIfNeeded2(inputs, log, setSecret2) {
|
|
307833
|
+
await mintAccessTokenIfNeeded(inputs, log, setSecret2);
|
|
307786
307834
|
}
|
|
307787
307835
|
function isLegacyAccessTokenDeprecationWarning(message) {
|
|
307788
307836
|
return message.includes("Postman CLI credential store populated by `postman login` is a legacy fallback");
|
|
@@ -309070,7 +309118,7 @@ async function runBootstrapInner(inputs, dependencies, telemetry) {
|
|
|
309070
309118
|
}
|
|
309071
309119
|
async function runAction(actionCore = core_exports, actionExec = exec_exports, actionIo = io_exports) {
|
|
309072
309120
|
const inputs = readActionInputs(actionCore);
|
|
309073
|
-
await
|
|
309121
|
+
await mintAccessTokenIfNeeded2(inputs, {
|
|
309074
309122
|
info: (message) => actionCore.info(message),
|
|
309075
309123
|
warning: (message) => actionCore.warning(message)
|
|
309076
309124
|
}, (secret) => actionCore.setSecret(secret));
|
package/dist/cli.cjs
CHANGED
|
@@ -261741,6 +261741,14 @@ function asRecord7(value) {
|
|
|
261741
261741
|
}
|
|
261742
261742
|
return value;
|
|
261743
261743
|
}
|
|
261744
|
+
function resolvePollBudget(explicit, envValue, fallback, min) {
|
|
261745
|
+
if (typeof explicit === "number" && Number.isFinite(explicit) && explicit >= min) return explicit;
|
|
261746
|
+
if (envValue !== void 0) {
|
|
261747
|
+
const parsed = Number(envValue);
|
|
261748
|
+
if (Number.isFinite(parsed) && parsed >= min) return parsed;
|
|
261749
|
+
}
|
|
261750
|
+
return fallback;
|
|
261751
|
+
}
|
|
261744
261752
|
function adviseWorkspaceFlipForbidden(error) {
|
|
261745
261753
|
if (error instanceof HttpError && error.status === 403) {
|
|
261746
261754
|
const body2 = error.responseBody || "";
|
|
@@ -261777,13 +261785,27 @@ function extractGitRepoUrl(value) {
|
|
|
261777
261785
|
}
|
|
261778
261786
|
var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
|
|
261779
261787
|
static GENERATION_LOCKED_MAX_RETRIES = 5;
|
|
261780
|
-
static
|
|
261781
|
-
static
|
|
261788
|
+
static DEFAULT_GENERATION_POLL_ATTEMPTS = 90;
|
|
261789
|
+
static DEFAULT_GENERATION_POLL_DELAY_MS = 2e3;
|
|
261782
261790
|
gateway;
|
|
261783
261791
|
sleep;
|
|
261792
|
+
generationPollAttempts;
|
|
261793
|
+
generationPollDelayMs;
|
|
261784
261794
|
constructor(options) {
|
|
261785
261795
|
this.gateway = options.gateway;
|
|
261786
261796
|
this.sleep = options.sleep ?? ((delayMs) => new Promise((resolve4) => setTimeout(resolve4, delayMs)));
|
|
261797
|
+
this.generationPollAttempts = resolvePollBudget(
|
|
261798
|
+
options.generationPollAttempts,
|
|
261799
|
+
process.env.POSTMAN_GENERATION_POLL_ATTEMPTS,
|
|
261800
|
+
_PostmanGatewayAssetsClient.DEFAULT_GENERATION_POLL_ATTEMPTS,
|
|
261801
|
+
1
|
|
261802
|
+
);
|
|
261803
|
+
this.generationPollDelayMs = resolvePollBudget(
|
|
261804
|
+
options.generationPollDelayMs,
|
|
261805
|
+
process.env.POSTMAN_GENERATION_POLL_DELAY_MS,
|
|
261806
|
+
_PostmanGatewayAssetsClient.DEFAULT_GENERATION_POLL_DELAY_MS,
|
|
261807
|
+
0
|
|
261808
|
+
);
|
|
261787
261809
|
}
|
|
261788
261810
|
configureTeamContext(teamId, orgMode) {
|
|
261789
261811
|
this.gateway.configureTeamContext(teamId, orgMode);
|
|
@@ -261928,8 +261950,8 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
|
|
|
261928
261950
|
};
|
|
261929
261951
|
const taskId = await this.postGenerationWithLockRetry(specId, body2);
|
|
261930
261952
|
if (taskId) {
|
|
261931
|
-
for (let attempt = 0; attempt <
|
|
261932
|
-
await this.sleep(
|
|
261953
|
+
for (let attempt = 0; attempt < this.generationPollAttempts; attempt += 1) {
|
|
261954
|
+
await this.sleep(this.generationPollDelayMs);
|
|
261933
261955
|
const task = await this.gateway.requestJson({
|
|
261934
261956
|
service: "specification",
|
|
261935
261957
|
method: "get",
|
|
@@ -261943,7 +261965,7 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
|
|
|
261943
261965
|
if (status && status !== "in-progress" && status !== "pending" && status !== "queued") {
|
|
261944
261966
|
break;
|
|
261945
261967
|
}
|
|
261946
|
-
if (attempt ===
|
|
261968
|
+
if (attempt === this.generationPollAttempts - 1) {
|
|
261947
261969
|
throw new Error(`Collection generation timed out for ${prefix}`);
|
|
261948
261970
|
}
|
|
261949
261971
|
}
|
|
@@ -262908,6 +262930,53 @@ var AccessTokenProvider = class {
|
|
|
262908
262930
|
return token;
|
|
262909
262931
|
}
|
|
262910
262932
|
};
|
|
262933
|
+
async function describeMintFailure(mintError, apiKey, apiBaseUrl, fetchImpl) {
|
|
262934
|
+
const raw = mintError instanceof Error ? mintError.message : String(mintError);
|
|
262935
|
+
const rejected = /HTTP 40[13]|PMAK rejected/.test(raw);
|
|
262936
|
+
if (!rejected) {
|
|
262937
|
+
return raw;
|
|
262938
|
+
}
|
|
262939
|
+
try {
|
|
262940
|
+
const me = await fetchImpl(`${apiBaseUrl}/me`, { headers: { "x-api-key": apiKey } });
|
|
262941
|
+
if (me.ok) {
|
|
262942
|
+
const body2 = await me.json().catch(() => void 0);
|
|
262943
|
+
const user = body2?.user;
|
|
262944
|
+
const looksPersonal = Boolean(user && (user.username || user.email));
|
|
262945
|
+
if (looksPersonal) {
|
|
262946
|
+
return "Personal API key detected, cannot mint a service-account access token. POST /service-account-tokens only accepts a SERVICE-ACCOUNT API key; this postman-api-key belongs to a user account" + (user?.teamId ? ` (team ${user.teamId})` : "") + ". Create a service account in Team Settings and use its PMAK, or mint the token elsewhere and pass postman-access-token.";
|
|
262947
|
+
}
|
|
262948
|
+
return "The postman-api-key authenticates (GET /me OK) but was rejected by POST /service-account-tokens" + (user?.teamId ? ` (team ${user.teamId})` : "") + ". The service account likely lacks permission to mint access tokens, or service accounts are restricted for this team. Check the service account role in Team Settings, or pass a pre-minted postman-access-token.";
|
|
262949
|
+
}
|
|
262950
|
+
return "The postman-api-key is invalid, disabled, or expired (rejected by both POST /service-account-tokens and GET /me). Generate a fresh service-account PMAK in Team Settings and update the secret.";
|
|
262951
|
+
} catch {
|
|
262952
|
+
return raw;
|
|
262953
|
+
}
|
|
262954
|
+
}
|
|
262955
|
+
async function mintAccessTokenIfNeeded(inputs, log, setSecret2, fetchImpl = fetch) {
|
|
262956
|
+
if (inputs.postmanAccessToken || !inputs.postmanApiKey) {
|
|
262957
|
+
return;
|
|
262958
|
+
}
|
|
262959
|
+
const apiBaseUrl = String(
|
|
262960
|
+
inputs.postmanApiBase || POSTMAN_ENDPOINT_PROFILES.prod.apiBaseUrl
|
|
262961
|
+
).replace(/\/+$/, "");
|
|
262962
|
+
const provider = new AccessTokenProvider({
|
|
262963
|
+
apiKey: inputs.postmanApiKey,
|
|
262964
|
+
apiBaseUrl,
|
|
262965
|
+
fetchImpl,
|
|
262966
|
+
onToken: (token) => setSecret2?.(token)
|
|
262967
|
+
});
|
|
262968
|
+
try {
|
|
262969
|
+
inputs.postmanAccessToken = await provider.refresh();
|
|
262970
|
+
log.info(
|
|
262971
|
+
"postman: no postman-access-token configured - minted a short-lived service-account access token from the postman-api-key."
|
|
262972
|
+
);
|
|
262973
|
+
} catch (error) {
|
|
262974
|
+
const diagnosis = await describeMintFailure(error, inputs.postmanApiKey, apiBaseUrl, fetchImpl);
|
|
262975
|
+
log.warning(
|
|
262976
|
+
"postman: could not mint an access token from the postman-api-key. " + diagnosis + " Continuing without an access token - access-token-only functionality will be unavailable unless postman-access-token is provided."
|
|
262977
|
+
);
|
|
262978
|
+
}
|
|
262979
|
+
}
|
|
262911
262980
|
|
|
262912
262981
|
// src/lib/postman/workspace-selection.ts
|
|
262913
262982
|
function chooseCanonicalWorkspace(args) {
|
|
@@ -306056,29 +306125,8 @@ function createPlannedOutputs(inputs) {
|
|
|
306056
306125
|
})
|
|
306057
306126
|
};
|
|
306058
306127
|
}
|
|
306059
|
-
async function
|
|
306060
|
-
|
|
306061
|
-
return;
|
|
306062
|
-
}
|
|
306063
|
-
const provider = new AccessTokenProvider({
|
|
306064
|
-
apiKey: inputs.postmanApiKey,
|
|
306065
|
-
apiBaseUrl: inputs.postmanApiBase,
|
|
306066
|
-
onToken: (token) => setSecret2?.(token)
|
|
306067
|
-
});
|
|
306068
|
-
try {
|
|
306069
|
-
inputs.postmanAccessToken = await provider.refresh();
|
|
306070
|
-
log.info(
|
|
306071
|
-
"postman: no postman-access-token configured - minted a short-lived service-account access token from the postman-api-key."
|
|
306072
|
-
);
|
|
306073
|
-
} catch (error) {
|
|
306074
|
-
const mask = createSecretMasker([inputs.postmanApiKey]);
|
|
306075
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
306076
|
-
log.warning(
|
|
306077
|
-
mask(
|
|
306078
|
-
"postman: could not mint an access token from the postman-api-key (" + message + "). Continuing with PMAK only - governance assignment and org-mode detection are disabled. Configure postman-access-token (postman-cs/postman-resolve-service-token-action) for full functionality."
|
|
306079
|
-
)
|
|
306080
|
-
);
|
|
306081
|
-
}
|
|
306128
|
+
async function mintAccessTokenIfNeeded2(inputs, log, setSecret2) {
|
|
306129
|
+
await mintAccessTokenIfNeeded(inputs, log, setSecret2);
|
|
306082
306130
|
}
|
|
306083
306131
|
function createWorkspaceName(inputs) {
|
|
306084
306132
|
return inputs.domainCode ? `[${inputs.domainCode}] ${inputs.projectName}` : inputs.projectName;
|
|
@@ -307696,7 +307744,7 @@ async function runCli(argv = process.argv.slice(2), runtime = {}) {
|
|
|
307696
307744
|
assertOutputFileAllowed2(config.resultJsonPath);
|
|
307697
307745
|
assertOutputFileAllowed2(config.dotenvPath);
|
|
307698
307746
|
const mintReporter = new ConsoleReporter();
|
|
307699
|
-
await
|
|
307747
|
+
await mintAccessTokenIfNeeded2(inputs, mintReporter);
|
|
307700
307748
|
const dependencies = createCliDependencies(inputs);
|
|
307701
307749
|
await runCredentialPreflight({
|
|
307702
307750
|
apiBaseUrl: inputs.postmanApiBase,
|
package/dist/index.cjs
CHANGED
|
@@ -253786,7 +253786,7 @@ __export(index_exports, {
|
|
|
253786
253786
|
ensurePostmanCli: () => ensurePostmanCli,
|
|
253787
253787
|
getInput: () => getInput2,
|
|
253788
253788
|
lintSpecViaCli: () => lintSpecViaCli,
|
|
253789
|
-
mintAccessTokenIfNeeded: () =>
|
|
253789
|
+
mintAccessTokenIfNeeded: () => mintAccessTokenIfNeeded2,
|
|
253790
253790
|
normalizeSpecDocument: () => normalizeSpecDocument,
|
|
253791
253791
|
readActionInputs: () => readActionInputs,
|
|
253792
253792
|
resolveInputs: () => resolveInputs,
|
|
@@ -263441,6 +263441,14 @@ function asRecord7(value) {
|
|
|
263441
263441
|
}
|
|
263442
263442
|
return value;
|
|
263443
263443
|
}
|
|
263444
|
+
function resolvePollBudget(explicit, envValue, fallback, min) {
|
|
263445
|
+
if (typeof explicit === "number" && Number.isFinite(explicit) && explicit >= min) return explicit;
|
|
263446
|
+
if (envValue !== void 0) {
|
|
263447
|
+
const parsed = Number(envValue);
|
|
263448
|
+
if (Number.isFinite(parsed) && parsed >= min) return parsed;
|
|
263449
|
+
}
|
|
263450
|
+
return fallback;
|
|
263451
|
+
}
|
|
263444
263452
|
function adviseWorkspaceFlipForbidden(error2) {
|
|
263445
263453
|
if (error2 instanceof HttpError && error2.status === 403) {
|
|
263446
263454
|
const body2 = error2.responseBody || "";
|
|
@@ -263477,13 +263485,27 @@ function extractGitRepoUrl(value) {
|
|
|
263477
263485
|
}
|
|
263478
263486
|
var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
|
|
263479
263487
|
static GENERATION_LOCKED_MAX_RETRIES = 5;
|
|
263480
|
-
static
|
|
263481
|
-
static
|
|
263488
|
+
static DEFAULT_GENERATION_POLL_ATTEMPTS = 90;
|
|
263489
|
+
static DEFAULT_GENERATION_POLL_DELAY_MS = 2e3;
|
|
263482
263490
|
gateway;
|
|
263483
263491
|
sleep;
|
|
263492
|
+
generationPollAttempts;
|
|
263493
|
+
generationPollDelayMs;
|
|
263484
263494
|
constructor(options) {
|
|
263485
263495
|
this.gateway = options.gateway;
|
|
263486
263496
|
this.sleep = options.sleep ?? ((delayMs) => new Promise((resolve5) => setTimeout(resolve5, delayMs)));
|
|
263497
|
+
this.generationPollAttempts = resolvePollBudget(
|
|
263498
|
+
options.generationPollAttempts,
|
|
263499
|
+
process.env.POSTMAN_GENERATION_POLL_ATTEMPTS,
|
|
263500
|
+
_PostmanGatewayAssetsClient.DEFAULT_GENERATION_POLL_ATTEMPTS,
|
|
263501
|
+
1
|
|
263502
|
+
);
|
|
263503
|
+
this.generationPollDelayMs = resolvePollBudget(
|
|
263504
|
+
options.generationPollDelayMs,
|
|
263505
|
+
process.env.POSTMAN_GENERATION_POLL_DELAY_MS,
|
|
263506
|
+
_PostmanGatewayAssetsClient.DEFAULT_GENERATION_POLL_DELAY_MS,
|
|
263507
|
+
0
|
|
263508
|
+
);
|
|
263487
263509
|
}
|
|
263488
263510
|
configureTeamContext(teamId, orgMode) {
|
|
263489
263511
|
this.gateway.configureTeamContext(teamId, orgMode);
|
|
@@ -263628,8 +263650,8 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
|
|
|
263628
263650
|
};
|
|
263629
263651
|
const taskId = await this.postGenerationWithLockRetry(specId, body2);
|
|
263630
263652
|
if (taskId) {
|
|
263631
|
-
for (let attempt = 0; attempt <
|
|
263632
|
-
await this.sleep(
|
|
263653
|
+
for (let attempt = 0; attempt < this.generationPollAttempts; attempt += 1) {
|
|
263654
|
+
await this.sleep(this.generationPollDelayMs);
|
|
263633
263655
|
const task = await this.gateway.requestJson({
|
|
263634
263656
|
service: "specification",
|
|
263635
263657
|
method: "get",
|
|
@@ -263643,7 +263665,7 @@ var PostmanGatewayAssetsClient = class _PostmanGatewayAssetsClient {
|
|
|
263643
263665
|
if (status && status !== "in-progress" && status !== "pending" && status !== "queued") {
|
|
263644
263666
|
break;
|
|
263645
263667
|
}
|
|
263646
|
-
if (attempt ===
|
|
263668
|
+
if (attempt === this.generationPollAttempts - 1) {
|
|
263647
263669
|
throw new Error(`Collection generation timed out for ${prefix}`);
|
|
263648
263670
|
}
|
|
263649
263671
|
}
|
|
@@ -264608,6 +264630,53 @@ var AccessTokenProvider = class {
|
|
|
264608
264630
|
return token;
|
|
264609
264631
|
}
|
|
264610
264632
|
};
|
|
264633
|
+
async function describeMintFailure(mintError, apiKey, apiBaseUrl, fetchImpl) {
|
|
264634
|
+
const raw = mintError instanceof Error ? mintError.message : String(mintError);
|
|
264635
|
+
const rejected = /HTTP 40[13]|PMAK rejected/.test(raw);
|
|
264636
|
+
if (!rejected) {
|
|
264637
|
+
return raw;
|
|
264638
|
+
}
|
|
264639
|
+
try {
|
|
264640
|
+
const me = await fetchImpl(`${apiBaseUrl}/me`, { headers: { "x-api-key": apiKey } });
|
|
264641
|
+
if (me.ok) {
|
|
264642
|
+
const body2 = await me.json().catch(() => void 0);
|
|
264643
|
+
const user = body2?.user;
|
|
264644
|
+
const looksPersonal = Boolean(user && (user.username || user.email));
|
|
264645
|
+
if (looksPersonal) {
|
|
264646
|
+
return "Personal API key detected, cannot mint a service-account access token. POST /service-account-tokens only accepts a SERVICE-ACCOUNT API key; this postman-api-key belongs to a user account" + (user?.teamId ? ` (team ${user.teamId})` : "") + ". Create a service account in Team Settings and use its PMAK, or mint the token elsewhere and pass postman-access-token.";
|
|
264647
|
+
}
|
|
264648
|
+
return "The postman-api-key authenticates (GET /me OK) but was rejected by POST /service-account-tokens" + (user?.teamId ? ` (team ${user.teamId})` : "") + ". The service account likely lacks permission to mint access tokens, or service accounts are restricted for this team. Check the service account role in Team Settings, or pass a pre-minted postman-access-token.";
|
|
264649
|
+
}
|
|
264650
|
+
return "The postman-api-key is invalid, disabled, or expired (rejected by both POST /service-account-tokens and GET /me). Generate a fresh service-account PMAK in Team Settings and update the secret.";
|
|
264651
|
+
} catch {
|
|
264652
|
+
return raw;
|
|
264653
|
+
}
|
|
264654
|
+
}
|
|
264655
|
+
async function mintAccessTokenIfNeeded(inputs, log, setSecret2, fetchImpl = fetch) {
|
|
264656
|
+
if (inputs.postmanAccessToken || !inputs.postmanApiKey) {
|
|
264657
|
+
return;
|
|
264658
|
+
}
|
|
264659
|
+
const apiBaseUrl = String(
|
|
264660
|
+
inputs.postmanApiBase || POSTMAN_ENDPOINT_PROFILES.prod.apiBaseUrl
|
|
264661
|
+
).replace(/\/+$/, "");
|
|
264662
|
+
const provider = new AccessTokenProvider({
|
|
264663
|
+
apiKey: inputs.postmanApiKey,
|
|
264664
|
+
apiBaseUrl,
|
|
264665
|
+
fetchImpl,
|
|
264666
|
+
onToken: (token) => setSecret2?.(token)
|
|
264667
|
+
});
|
|
264668
|
+
try {
|
|
264669
|
+
inputs.postmanAccessToken = await provider.refresh();
|
|
264670
|
+
log.info(
|
|
264671
|
+
"postman: no postman-access-token configured - minted a short-lived service-account access token from the postman-api-key."
|
|
264672
|
+
);
|
|
264673
|
+
} catch (error2) {
|
|
264674
|
+
const diagnosis = await describeMintFailure(error2, inputs.postmanApiKey, apiBaseUrl, fetchImpl);
|
|
264675
|
+
log.warning(
|
|
264676
|
+
"postman: could not mint an access token from the postman-api-key. " + diagnosis + " Continuing without an access token - access-token-only functionality will be unavailable unless postman-access-token is provided."
|
|
264677
|
+
);
|
|
264678
|
+
}
|
|
264679
|
+
}
|
|
264611
264680
|
|
|
264612
264681
|
// src/lib/postman/workspace-selection.ts
|
|
264613
264682
|
function chooseCanonicalWorkspace(args) {
|
|
@@ -307778,29 +307847,8 @@ function warnIfDeprecatedAccessToken(actionCore, inputs) {
|
|
|
307778
307847
|
)
|
|
307779
307848
|
);
|
|
307780
307849
|
}
|
|
307781
|
-
async function
|
|
307782
|
-
|
|
307783
|
-
return;
|
|
307784
|
-
}
|
|
307785
|
-
const provider = new AccessTokenProvider({
|
|
307786
|
-
apiKey: inputs.postmanApiKey,
|
|
307787
|
-
apiBaseUrl: inputs.postmanApiBase,
|
|
307788
|
-
onToken: (token) => setSecret2?.(token)
|
|
307789
|
-
});
|
|
307790
|
-
try {
|
|
307791
|
-
inputs.postmanAccessToken = await provider.refresh();
|
|
307792
|
-
log.info(
|
|
307793
|
-
"postman: no postman-access-token configured - minted a short-lived service-account access token from the postman-api-key."
|
|
307794
|
-
);
|
|
307795
|
-
} catch (error2) {
|
|
307796
|
-
const mask = createSecretMasker([inputs.postmanApiKey]);
|
|
307797
|
-
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
307798
|
-
log.warning(
|
|
307799
|
-
mask(
|
|
307800
|
-
"postman: could not mint an access token from the postman-api-key (" + message + "). Continuing with PMAK only - governance assignment and org-mode detection are disabled. Configure postman-access-token (postman-cs/postman-resolve-service-token-action) for full functionality."
|
|
307801
|
-
)
|
|
307802
|
-
);
|
|
307803
|
-
}
|
|
307850
|
+
async function mintAccessTokenIfNeeded2(inputs, log, setSecret2) {
|
|
307851
|
+
await mintAccessTokenIfNeeded(inputs, log, setSecret2);
|
|
307804
307852
|
}
|
|
307805
307853
|
function isLegacyAccessTokenDeprecationWarning(message) {
|
|
307806
307854
|
return message.includes("Postman CLI credential store populated by `postman login` is a legacy fallback");
|
|
@@ -309088,7 +309136,7 @@ async function runBootstrapInner(inputs, dependencies, telemetry) {
|
|
|
309088
309136
|
}
|
|
309089
309137
|
async function runAction(actionCore = core_exports, actionExec = exec_exports, actionIo = io_exports) {
|
|
309090
309138
|
const inputs = readActionInputs(actionCore);
|
|
309091
|
-
await
|
|
309139
|
+
await mintAccessTokenIfNeeded2(inputs, {
|
|
309092
309140
|
info: (message) => actionCore.info(message),
|
|
309093
309141
|
warning: (message) => actionCore.warning(message)
|
|
309094
309142
|
}, (secret) => actionCore.setSecret(secret));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@postman-cse/onboarding-bootstrap",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.9.0",
|
|
4
4
|
"description": "Bootstrap Postman workspaces, specs, and collections from OpenAPI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -61,6 +61,8 @@
|
|
|
61
61
|
"@commitlint/cli": "^21.0.2",
|
|
62
62
|
"@commitlint/config-conventional": "^21.0.2",
|
|
63
63
|
"@eslint/js": "^10.0.1",
|
|
64
|
+
"@grpc/grpc-js": "^1.14.4",
|
|
65
|
+
"@grpc/proto-loader": "^0.8.1",
|
|
64
66
|
"@types/node": "^26.1.0",
|
|
65
67
|
"esbuild": "0.28.1",
|
|
66
68
|
"eslint": "^10.4.1",
|