@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 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 GENERATION_POLL_ATTEMPTS = 90;
263463
- static GENERATION_POLL_DELAY_MS = 2e3;
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 < _PostmanGatewayAssetsClient.GENERATION_POLL_ATTEMPTS; attempt += 1) {
263614
- await this.sleep(_PostmanGatewayAssetsClient.GENERATION_POLL_DELAY_MS);
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 === _PostmanGatewayAssetsClient.GENERATION_POLL_ATTEMPTS - 1) {
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 mintAccessTokenIfNeeded(inputs, log, setSecret2) {
307764
- if (inputs.postmanAccessToken || !inputs.postmanApiKey) {
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 mintAccessTokenIfNeeded(inputs, {
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 GENERATION_POLL_ATTEMPTS = 90;
261781
- static GENERATION_POLL_DELAY_MS = 2e3;
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 < _PostmanGatewayAssetsClient.GENERATION_POLL_ATTEMPTS; attempt += 1) {
261932
- await this.sleep(_PostmanGatewayAssetsClient.GENERATION_POLL_DELAY_MS);
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 === _PostmanGatewayAssetsClient.GENERATION_POLL_ATTEMPTS - 1) {
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 mintAccessTokenIfNeeded(inputs, log, setSecret2) {
306060
- if (inputs.postmanAccessToken || !inputs.postmanApiKey) {
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 mintAccessTokenIfNeeded(inputs, mintReporter);
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: () => 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 GENERATION_POLL_ATTEMPTS = 90;
263481
- static GENERATION_POLL_DELAY_MS = 2e3;
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 < _PostmanGatewayAssetsClient.GENERATION_POLL_ATTEMPTS; attempt += 1) {
263632
- await this.sleep(_PostmanGatewayAssetsClient.GENERATION_POLL_DELAY_MS);
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 === _PostmanGatewayAssetsClient.GENERATION_POLL_ATTEMPTS - 1) {
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 mintAccessTokenIfNeeded(inputs, log, setSecret2) {
307782
- if (inputs.postmanAccessToken || !inputs.postmanApiKey) {
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 mintAccessTokenIfNeeded(inputs, {
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.7.1",
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",