@postman-cse/onboarding-insights 1.0.4 → 2.0.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/cli.cjs CHANGED
@@ -12167,7 +12167,7 @@ var require_response = __commonJS({
12167
12167
  var assert = require("node:assert");
12168
12168
  var { types } = require("node:util");
12169
12169
  var textEncoder = new TextEncoder("utf-8");
12170
- var Response = class _Response {
12170
+ var Response2 = class _Response {
12171
12171
  // Creates network error Response.
12172
12172
  static error() {
12173
12173
  const responseObject = fromInnerResponse(makeNetworkError(), "immutable");
@@ -12310,8 +12310,8 @@ var require_response = __commonJS({
12310
12310
  return `Response ${nodeUtil.formatWithOptions(options, properties)}`;
12311
12311
  }
12312
12312
  };
12313
- mixinBody(Response);
12314
- Object.defineProperties(Response.prototype, {
12313
+ mixinBody(Response2);
12314
+ Object.defineProperties(Response2.prototype, {
12315
12315
  type: kEnumerableProperty,
12316
12316
  url: kEnumerableProperty,
12317
12317
  status: kEnumerableProperty,
@@ -12327,7 +12327,7 @@ var require_response = __commonJS({
12327
12327
  configurable: true
12328
12328
  }
12329
12329
  });
12330
- Object.defineProperties(Response, {
12330
+ Object.defineProperties(Response2, {
12331
12331
  json: kEnumerableProperty,
12332
12332
  redirect: kEnumerableProperty,
12333
12333
  error: kEnumerableProperty
@@ -12460,7 +12460,7 @@ var require_response = __commonJS({
12460
12460
  }
12461
12461
  }
12462
12462
  function fromInnerResponse(innerResponse, guard) {
12463
- const response = new Response(kConstruct);
12463
+ const response = new Response2(kConstruct);
12464
12464
  response[kState] = innerResponse;
12465
12465
  response[kHeaders] = new Headers3(kConstruct);
12466
12466
  setHeadersList(response[kHeaders], innerResponse.headersList);
@@ -12528,7 +12528,7 @@ var require_response = __commonJS({
12528
12528
  makeResponse,
12529
12529
  makeAppropriateNetworkError,
12530
12530
  filterResponse,
12531
- Response,
12531
+ Response: Response2,
12532
12532
  cloneResponse,
12533
12533
  fromInnerResponse
12534
12534
  };
@@ -15200,7 +15200,7 @@ var require_cache = __commonJS({
15200
15200
  var { urlEquals, getFieldValues } = require_util5();
15201
15201
  var { kEnumerableProperty, isDisturbed } = require_util();
15202
15202
  var { webidl } = require_webidl();
15203
- var { Response, cloneResponse, fromInnerResponse } = require_response();
15203
+ var { Response: Response2, cloneResponse, fromInnerResponse } = require_response();
15204
15204
  var { Request, fromInnerRequest } = require_request2();
15205
15205
  var { kState } = require_symbols2();
15206
15206
  var { fetching } = require_fetch();
@@ -15727,7 +15727,7 @@ var require_cache = __commonJS({
15727
15727
  converter: webidl.converters.DOMString
15728
15728
  }
15729
15729
  ]);
15730
- webidl.converters.Response = webidl.interfaceConverter(Response);
15730
+ webidl.converters.Response = webidl.interfaceConverter(Response2);
15731
15731
  webidl.converters["sequence<RequestInfo>"] = webidl.sequenceConverter(
15732
15732
  webidl.converters.RequestInfo
15733
15733
  );
@@ -18689,6 +18689,209 @@ var import_node_fs = require("node:fs");
18689
18689
  var import_promises = require("node:fs/promises");
18690
18690
  var import_node_path = __toESM(require("node:path"), 1);
18691
18691
 
18692
+ // src/lib/retry.ts
18693
+ function sleep(delayMs) {
18694
+ return new Promise((resolve2) => {
18695
+ setTimeout(resolve2, delayMs);
18696
+ });
18697
+ }
18698
+ function normalizeRetryOptions(options) {
18699
+ return {
18700
+ maxAttempts: Math.max(1, options.maxAttempts ?? 3),
18701
+ delayMs: Math.max(0, options.delayMs ?? 2e3),
18702
+ backoffMultiplier: Math.max(1, options.backoffMultiplier ?? 1),
18703
+ maxDelayMs: options.maxDelayMs === void 0 ? Number.POSITIVE_INFINITY : Math.max(0, options.maxDelayMs),
18704
+ onRetry: options.onRetry ?? (async () => void 0),
18705
+ shouldRetry: options.shouldRetry ?? (() => true),
18706
+ sleep: options.sleep ?? sleep
18707
+ };
18708
+ }
18709
+ async function retry(operation, options = {}) {
18710
+ const normalized = normalizeRetryOptions(options);
18711
+ let nextDelayMs = normalized.delayMs;
18712
+ for (let attempt = 1; attempt <= normalized.maxAttempts; attempt += 1) {
18713
+ try {
18714
+ return await operation();
18715
+ } catch (error2) {
18716
+ const shouldRetry = attempt < normalized.maxAttempts && normalized.shouldRetry(error2, {
18717
+ attempt,
18718
+ maxAttempts: normalized.maxAttempts
18719
+ });
18720
+ if (!shouldRetry) {
18721
+ throw error2;
18722
+ }
18723
+ await normalized.onRetry({
18724
+ attempt,
18725
+ maxAttempts: normalized.maxAttempts,
18726
+ delayMs: nextDelayMs,
18727
+ error: error2
18728
+ });
18729
+ await normalized.sleep(nextDelayMs);
18730
+ nextDelayMs = Math.min(
18731
+ normalized.maxDelayMs,
18732
+ Math.round(nextDelayMs * normalized.backoffMultiplier)
18733
+ );
18734
+ }
18735
+ }
18736
+ throw new Error("Retry exhausted without returning or throwing");
18737
+ }
18738
+
18739
+ // src/lib/postman/base-urls.ts
18740
+ var POSTMAN_ENDPOINT_PROFILES = {
18741
+ prod: {
18742
+ apiBaseUrl: "https://api.getpostman.com",
18743
+ bifrostBaseUrl: "https://bifrost-premium-https-v4.gw.postman.com",
18744
+ iapubBaseUrl: "https://iapub.postman.co",
18745
+ observabilityBaseUrl: "https://api.observability.postman.com",
18746
+ observabilityEnv: "production"
18747
+ },
18748
+ beta: {
18749
+ apiBaseUrl: "https://api.getpostman-beta.com",
18750
+ bifrostBaseUrl: "https://bifrost-https-v4.gw.postman-beta.com",
18751
+ iapubBaseUrl: "https://iapub.postman.co",
18752
+ observabilityBaseUrl: "https://api.observability.postman-beta.com",
18753
+ observabilityEnv: "beta"
18754
+ }
18755
+ };
18756
+ function parsePostmanRegion(value) {
18757
+ const normalized = String(value || "us").trim().toLowerCase();
18758
+ if (normalized === "us" || normalized === "eu") {
18759
+ return normalized;
18760
+ }
18761
+ throw new Error(`Unsupported postman-region "${value}". Supported values: us, eu`);
18762
+ }
18763
+ function parsePostmanStack(value) {
18764
+ const normalized = String(value || "prod").trim().toLowerCase();
18765
+ if (normalized === "prod" || normalized === "beta") {
18766
+ return normalized;
18767
+ }
18768
+ throw new Error(`Unsupported postman-stack "${value}". Supported values: prod, beta`);
18769
+ }
18770
+ function resolvePostmanEndpointProfile(stack, region = "us") {
18771
+ if (stack === "beta" && region !== "us") {
18772
+ throw new Error("postman-region=eu is only supported with postman-stack=prod");
18773
+ }
18774
+ const profile = POSTMAN_ENDPOINT_PROFILES[stack];
18775
+ if (region === "eu") {
18776
+ return {
18777
+ ...profile,
18778
+ apiBaseUrl: "https://api.eu.postman.com"
18779
+ };
18780
+ }
18781
+ return profile;
18782
+ }
18783
+
18784
+ // src/lib/postman/token-provider.ts
18785
+ var MintError = class extends Error {
18786
+ permanent;
18787
+ constructor(message, permanent) {
18788
+ super(message);
18789
+ this.name = "MintError";
18790
+ this.permanent = permanent;
18791
+ }
18792
+ };
18793
+ function extractAccessToken(payload) {
18794
+ if (!payload || typeof payload !== "object") return void 0;
18795
+ const record = payload;
18796
+ const direct = record.access_token;
18797
+ if (typeof direct === "string" && direct.trim()) return direct.trim();
18798
+ const session = record.session;
18799
+ if (session && typeof session === "object") {
18800
+ const token = session.token;
18801
+ if (typeof token === "string" && token.trim()) return token.trim();
18802
+ }
18803
+ return void 0;
18804
+ }
18805
+ var AccessTokenProvider = class {
18806
+ token;
18807
+ apiKey;
18808
+ apiBaseUrl;
18809
+ fetchImpl;
18810
+ maxAttempts;
18811
+ onToken;
18812
+ sleep;
18813
+ inflight;
18814
+ constructor(options) {
18815
+ this.token = String(options.accessToken || "").trim();
18816
+ this.apiKey = String(options.apiKey || "").trim();
18817
+ this.apiBaseUrl = String(
18818
+ options.apiBaseUrl || POSTMAN_ENDPOINT_PROFILES.prod.apiBaseUrl
18819
+ ).replace(/\/+$/, "");
18820
+ this.fetchImpl = options.fetchImpl ?? fetch;
18821
+ this.maxAttempts = Math.max(1, options.maxAttempts ?? 2);
18822
+ this.onToken = options.onToken;
18823
+ this.sleep = options.sleep;
18824
+ }
18825
+ current() {
18826
+ return this.token;
18827
+ }
18828
+ /** True when a PMAK is present, so an expired token can be re-minted. */
18829
+ canRefresh() {
18830
+ return Boolean(this.apiKey);
18831
+ }
18832
+ refresh() {
18833
+ this.inflight ??= this.mintWithRetry().finally(() => {
18834
+ this.inflight = void 0;
18835
+ });
18836
+ return this.inflight;
18837
+ }
18838
+ async mintWithRetry() {
18839
+ if (!this.apiKey) {
18840
+ throw new Error(
18841
+ "postman: the access token expired and cannot be refreshed because no postman-api-key is present. Service-account access tokens expire after about 1 to 1.5 hours. Re-mint a fresh token (postman-resolve-service-token-action) and re-run."
18842
+ );
18843
+ }
18844
+ const token = await retry(() => this.mintOnce(), {
18845
+ maxAttempts: this.maxAttempts,
18846
+ delayMs: 1e3,
18847
+ backoffMultiplier: 2,
18848
+ ...this.sleep ? { sleep: this.sleep } : {},
18849
+ shouldRetry: (error2) => !(error2 instanceof MintError && error2.permanent)
18850
+ });
18851
+ this.token = token;
18852
+ this.onToken?.(token);
18853
+ return token;
18854
+ }
18855
+ async mintOnce() {
18856
+ const response = await this.fetchImpl(`${this.apiBaseUrl}/service-account-tokens`, {
18857
+ method: "POST",
18858
+ headers: {
18859
+ "Content-Type": "application/json",
18860
+ "x-api-key": this.apiKey
18861
+ },
18862
+ body: JSON.stringify({ apiKey: this.apiKey })
18863
+ });
18864
+ const body = await response.text().catch(() => "");
18865
+ if (!response.ok) {
18866
+ const status = response.status;
18867
+ if (status === 401 || status === 403) {
18868
+ throw new MintError(
18869
+ `postman: re-mint failed because the postman-api-key was rejected (PMAK rejected, HTTP ${status}); confirm it is a valid, enabled service-account PMAK for the intended team.`,
18870
+ true
18871
+ );
18872
+ }
18873
+ if (status === 400 && body.toLowerCase().includes("service accounts not enabled")) {
18874
+ throw new MintError(
18875
+ "postman: re-mint failed because service accounts are not enabled for this team; enable them in Team Settings or use a team where they are.",
18876
+ true
18877
+ );
18878
+ }
18879
+ throw new MintError(`postman: re-mint failed (service-account-tokens HTTP ${status}).`, false);
18880
+ }
18881
+ let parsed;
18882
+ try {
18883
+ parsed = JSON.parse(body);
18884
+ } catch {
18885
+ parsed = void 0;
18886
+ }
18887
+ const token = extractAccessToken(parsed);
18888
+ if (!token) {
18889
+ throw new MintError("postman: re-mint succeeded but no access token was returned.", false);
18890
+ }
18891
+ return token;
18892
+ }
18893
+ };
18894
+
18692
18895
  // node_modules/@actions/core/lib/core.js
18693
18896
  var core_exports = {};
18694
18897
  __export(core_exports, {
@@ -21404,98 +21607,6 @@ var HttpError = class _HttpError extends Error {
21404
21607
  }
21405
21608
  };
21406
21609
 
21407
- // src/lib/retry.ts
21408
- function sleep(delayMs) {
21409
- return new Promise((resolve2) => {
21410
- setTimeout(resolve2, delayMs);
21411
- });
21412
- }
21413
- function normalizeRetryOptions(options) {
21414
- return {
21415
- maxAttempts: Math.max(1, options.maxAttempts ?? 3),
21416
- delayMs: Math.max(0, options.delayMs ?? 2e3),
21417
- backoffMultiplier: Math.max(1, options.backoffMultiplier ?? 1),
21418
- maxDelayMs: options.maxDelayMs === void 0 ? Number.POSITIVE_INFINITY : Math.max(0, options.maxDelayMs),
21419
- onRetry: options.onRetry ?? (async () => void 0),
21420
- shouldRetry: options.shouldRetry ?? (() => true),
21421
- sleep: options.sleep ?? sleep
21422
- };
21423
- }
21424
- async function retry(operation, options = {}) {
21425
- const normalized = normalizeRetryOptions(options);
21426
- let nextDelayMs = normalized.delayMs;
21427
- for (let attempt = 1; attempt <= normalized.maxAttempts; attempt += 1) {
21428
- try {
21429
- return await operation();
21430
- } catch (error2) {
21431
- const shouldRetry = attempt < normalized.maxAttempts && normalized.shouldRetry(error2, {
21432
- attempt,
21433
- maxAttempts: normalized.maxAttempts
21434
- });
21435
- if (!shouldRetry) {
21436
- throw error2;
21437
- }
21438
- await normalized.onRetry({
21439
- attempt,
21440
- maxAttempts: normalized.maxAttempts,
21441
- delayMs: nextDelayMs,
21442
- error: error2
21443
- });
21444
- await normalized.sleep(nextDelayMs);
21445
- nextDelayMs = Math.min(
21446
- normalized.maxDelayMs,
21447
- Math.round(nextDelayMs * normalized.backoffMultiplier)
21448
- );
21449
- }
21450
- }
21451
- throw new Error("Retry exhausted without returning or throwing");
21452
- }
21453
-
21454
- // src/lib/postman/base-urls.ts
21455
- var POSTMAN_ENDPOINT_PROFILES = {
21456
- prod: {
21457
- apiBaseUrl: "https://api.getpostman.com",
21458
- bifrostBaseUrl: "https://bifrost-premium-https-v4.gw.postman.com",
21459
- iapubBaseUrl: "https://iapub.postman.co",
21460
- observabilityBaseUrl: "https://api.observability.postman.com",
21461
- observabilityEnv: "production"
21462
- },
21463
- beta: {
21464
- apiBaseUrl: "https://api.getpostman-beta.com",
21465
- bifrostBaseUrl: "https://bifrost-https-v4.gw.postman-beta.com",
21466
- iapubBaseUrl: "https://iapub.postman.co",
21467
- observabilityBaseUrl: "https://api.observability.postman-beta.com",
21468
- observabilityEnv: "beta"
21469
- }
21470
- };
21471
- function parsePostmanRegion(value) {
21472
- const normalized = String(value || "us").trim().toLowerCase();
21473
- if (normalized === "us" || normalized === "eu") {
21474
- return normalized;
21475
- }
21476
- throw new Error(`Unsupported postman-region "${value}". Supported values: us, eu`);
21477
- }
21478
- function parsePostmanStack(value) {
21479
- const normalized = String(value || "prod").trim().toLowerCase();
21480
- if (normalized === "prod" || normalized === "beta") {
21481
- return normalized;
21482
- }
21483
- throw new Error(`Unsupported postman-stack "${value}". Supported values: prod, beta`);
21484
- }
21485
- function resolvePostmanEndpointProfile(stack, region = "us") {
21486
- if (stack === "beta" && region !== "us") {
21487
- throw new Error("postman-region=eu is only supported with postman-stack=prod");
21488
- }
21489
- const profile = POSTMAN_ENDPOINT_PROFILES[stack];
21490
- if (region === "eu") {
21491
- return {
21492
- ...profile,
21493
- apiBaseUrl: "https://api.eu.postman.com"
21494
- };
21495
- }
21496
- return profile;
21497
- }
21498
-
21499
21610
  // src/lib/bifrost-client.ts
21500
21611
  var DEFAULT_BIFROST_BASE_URL = POSTMAN_ENDPOINT_PROFILES.prod.bifrostBaseUrl;
21501
21612
  var BIFROST_PROXY_PATH = "/ws/proxy";
@@ -21503,8 +21614,11 @@ var DEFAULT_OBSERVABILITY_BASE_URL = POSTMAN_ENDPOINT_PROFILES.prod.observabilit
21503
21614
  var DEFAULT_OBSERVABILITY_ENV = POSTMAN_ENDPOINT_PROFILES.prod.observabilityEnv;
21504
21615
  var MAX_DISCOVERED_SERVICE_PAGES = 100;
21505
21616
  var MAX_PROVIDER_SERVICE_PAGES = 100;
21617
+ function isExpiredAuthError(status, body) {
21618
+ return status === 401 || body.includes("UNAUTHENTICATED") || body.includes("authenticationError");
21619
+ }
21506
21620
  var BifrostCatalogClient = class {
21507
- accessToken;
21621
+ tokenProvider;
21508
21622
  teamId;
21509
21623
  apiKey;
21510
21624
  fetchFn;
@@ -21513,11 +21627,14 @@ var BifrostCatalogClient = class {
21513
21627
  observabilityBaseUrl;
21514
21628
  observabilityEnv;
21515
21629
  constructor(options) {
21516
- this.accessToken = options.accessToken;
21630
+ this.tokenProvider = options.tokenProvider ?? new AccessTokenProvider({
21631
+ accessToken: options.accessToken,
21632
+ apiKey: options.apiKey
21633
+ });
21517
21634
  this.teamId = options.teamId;
21518
21635
  this.apiKey = options.apiKey;
21519
21636
  this.fetchFn = options.fetchFn ?? globalThis.fetch;
21520
- this.secretValues = [options.accessToken, options.apiKey].filter(Boolean);
21637
+ this.secretValues = [this.tokenProvider.current(), options.apiKey].filter(Boolean);
21521
21638
  const base = (options.bifrostBaseUrl || DEFAULT_BIFROST_BASE_URL).replace(/\/+$/, "");
21522
21639
  this.bifrostProxyUrl = `${base}${BIFROST_PROXY_PATH}`;
21523
21640
  this.observabilityBaseUrl = (options.observabilityBaseUrl || DEFAULT_OBSERVABILITY_BASE_URL).replace(/\/+$/, "");
@@ -21529,6 +21646,11 @@ var BifrostCatalogClient = class {
21529
21646
  this.secretValues.push(apiKey);
21530
21647
  }
21531
21648
  }
21649
+ registerAccessToken(token) {
21650
+ if (token && !this.secretValues.includes(token)) {
21651
+ this.secretValues.push(token);
21652
+ }
21653
+ }
21532
21654
  /**
21533
21655
  * Build Bifrost proxy headers.
21534
21656
  * x-entity-team-id is ONLY included when teamId is present (org-mode tokens).
@@ -21536,7 +21658,7 @@ var BifrostCatalogClient = class {
21536
21658
  */
21537
21659
  headers() {
21538
21660
  const h = {
21539
- "x-access-token": this.accessToken,
21661
+ "x-access-token": this.tokenProvider.current(),
21540
21662
  "Content-Type": "application/json"
21541
21663
  };
21542
21664
  if (this.teamId) {
@@ -21552,7 +21674,7 @@ var BifrostCatalogClient = class {
21552
21674
  const session = getMemoizedSessionIdentity();
21553
21675
  return {
21554
21676
  operation,
21555
- hasAccessToken: Boolean(this.accessToken),
21677
+ hasAccessToken: Boolean(this.tokenProvider.current()),
21556
21678
  sessionTeamId: session?.teamId,
21557
21679
  sessionRoles: session?.roles,
21558
21680
  sessionConsumerType: session?.consumerType,
@@ -21561,7 +21683,7 @@ var BifrostCatalogClient = class {
21561
21683
  };
21562
21684
  }
21563
21685
  async proxyRequest(method, path7, body = {}, operation = "api-catalog request") {
21564
- const response = await this.fetchFn(this.bifrostProxyUrl, {
21686
+ const send2 = async () => this.fetchFn(this.bifrostProxyUrl, {
21565
21687
  method: "POST",
21566
21688
  headers: this.headers(),
21567
21689
  body: JSON.stringify({
@@ -21571,6 +21693,39 @@ var BifrostCatalogClient = class {
21571
21693
  body
21572
21694
  })
21573
21695
  });
21696
+ let response = await send2();
21697
+ if (!response.ok) {
21698
+ const bodyText = await response.text().catch(() => "");
21699
+ if (isExpiredAuthError(response.status, bodyText) && this.tokenProvider.canRefresh()) {
21700
+ try {
21701
+ const refreshed = await this.tokenProvider.refresh();
21702
+ this.registerAccessToken(refreshed);
21703
+ response = await send2();
21704
+ } catch {
21705
+ const httpErr = await HttpError.fromResponse(
21706
+ new Response(bodyText, { status: response.status, headers: response.headers }),
21707
+ {
21708
+ method: "POST",
21709
+ url: `bifrost:api-catalog:${method} ${path7}`,
21710
+ secretValues: this.secretValues
21711
+ }
21712
+ );
21713
+ const advised = adviseFromHttpError(httpErr, this.adviceContext(operation));
21714
+ throw advised ?? httpErr;
21715
+ }
21716
+ } else {
21717
+ const httpErr = await HttpError.fromResponse(
21718
+ new Response(bodyText, { status: response.status, headers: response.headers }),
21719
+ {
21720
+ method: "POST",
21721
+ url: `bifrost:api-catalog:${method} ${path7}`,
21722
+ secretValues: this.secretValues
21723
+ }
21724
+ );
21725
+ const advised = adviseFromHttpError(httpErr, this.adviceContext(operation));
21726
+ throw advised ?? httpErr;
21727
+ }
21728
+ }
21574
21729
  if (!response.ok) {
21575
21730
  const httpErr = await HttpError.fromResponse(response, {
21576
21731
  method: "POST",
@@ -21593,7 +21748,7 @@ var BifrostCatalogClient = class {
21593
21748
  return data;
21594
21749
  }
21595
21750
  async akitaProxyRequest(method, path7, body = {}, operation = "Insights request") {
21596
- const response = await this.fetchFn(this.bifrostProxyUrl, {
21751
+ const send2 = async () => this.fetchFn(this.bifrostProxyUrl, {
21597
21752
  method: "POST",
21598
21753
  headers: this.headers(),
21599
21754
  body: JSON.stringify({
@@ -21603,8 +21758,30 @@ var BifrostCatalogClient = class {
21603
21758
  body
21604
21759
  })
21605
21760
  });
21761
+ let response = await send2();
21606
21762
  if (!response.ok) {
21607
21763
  const text = await response.text().catch(() => "");
21764
+ if (isExpiredAuthError(response.status, text) && this.tokenProvider.canRefresh()) {
21765
+ try {
21766
+ const refreshed = await this.tokenProvider.refresh();
21767
+ this.registerAccessToken(refreshed);
21768
+ response = await send2();
21769
+ if (response.ok) {
21770
+ const data2 = await response.json();
21771
+ return { ok: true, status: response.status, data: data2, errorText: "" };
21772
+ }
21773
+ const retryText = await response.text().catch(() => "");
21774
+ const advised2 = adviseFromBifrostBody(response.status, retryText, this.adviceContext(operation));
21775
+ const errorText2 = advised2 ? retryText ? `${retryText}
21776
+ ${advised2.message}` : advised2.message : retryText;
21777
+ return { ok: false, status: response.status, data: null, errorText: errorText2 };
21778
+ } catch {
21779
+ const advised2 = adviseFromBifrostBody(response.status, text, this.adviceContext(operation));
21780
+ const errorText2 = advised2 ? text ? `${text}
21781
+ ${advised2.message}` : advised2.message : text;
21782
+ return { ok: false, status: response.status, data: null, errorText: errorText2 };
21783
+ }
21784
+ }
21608
21785
  const advised = adviseFromBifrostBody(response.status, text, this.adviceContext(operation));
21609
21786
  const errorText = advised ? text ? `${text}
21610
21787
  ${advised.message}` : advised.message : text;
@@ -21703,12 +21880,19 @@ ${advised.message}` : advised.message : text;
21703
21880
  }
21704
21881
  page++;
21705
21882
  }
21706
- const fullName = clusterName ? `${clusterName}/${projectName}` : projectName;
21707
- const exactMatch = allServices.find((s) => s.name === fullName);
21708
- if (exactMatch) return exactMatch.id;
21709
- if (clusterName) return null;
21710
- const suffixMatch = allServices.find((s) => s.name.endsWith(`/${projectName}`));
21711
- return suffixMatch?.id || null;
21883
+ if (clusterName) {
21884
+ const fullName = `${clusterName}/${projectName}`;
21885
+ const exactMatch = allServices.find((s) => s.name === fullName);
21886
+ return exactMatch?.id || null;
21887
+ }
21888
+ const finalSegmentMatch = allServices.find(
21889
+ (s) => getFinalServiceSegment(s.name) === projectName
21890
+ );
21891
+ if (finalSegmentMatch) return finalSegmentMatch.id;
21892
+ const bracketedMatch = allServices.find(
21893
+ (s) => getFinalServiceSegment(s.name).includes(`[${projectName}]`)
21894
+ );
21895
+ return bracketedMatch?.id || null;
21712
21896
  }
21713
21897
  async acknowledgeOnboarding(providerServiceId, workspaceId, systemEnvironmentId) {
21714
21898
  const result = await this.akitaProxyRequest(
@@ -21738,6 +21922,14 @@ ${advised.message}` : advised.message : text;
21738
21922
  throw new Error(`Workspace acknowledge failed: ${result.status} ${result.errorText}`);
21739
21923
  }
21740
21924
  }
21925
+ // PMAK-only by proven exception. A live probe against the observability
21926
+ // application-binding endpoint (POST /v2/agent/api-catalog/workspaces/:id/
21927
+ // applications) showed x-access-token is rejected identically to the x-api-key
21928
+ // control: both return 401 {"message":"Postman User not found"} for a
21929
+ // service-account credential, because the observability service has no
21930
+ // "Postman User" for a service account. The access token offers no improvement
21931
+ // over the API key here, so this route is not migrated to access-token-primary
21932
+ // (the suite-wide migration explicitly leaves probe-failed routes on PMAK).
21741
21933
  async createApplication(workspaceId, systemEnv) {
21742
21934
  const response = await this.fetchFn(
21743
21935
  `${this.observabilityBaseUrl}/v2/agent/api-catalog/workspaces/${workspaceId}/applications`,
@@ -21805,7 +21997,17 @@ function findDiscoveredService(services, projectName, clusterName) {
21805
21997
  const fullName = `${clusterName}/${projectName}`;
21806
21998
  return services.find((s) => s.name === fullName);
21807
21999
  }
21808
- return services.find((s) => s.name.endsWith(`/${projectName}`));
22000
+ const finalSegmentMatch = services.find(
22001
+ (service) => getFinalServiceSegment(service.name) === projectName
22002
+ );
22003
+ if (finalSegmentMatch) return finalSegmentMatch;
22004
+ return services.find(
22005
+ (service) => getFinalServiceSegment(service.name).includes(`[${projectName}]`)
22006
+ );
22007
+ }
22008
+ function getFinalServiceSegment(serviceName) {
22009
+ const lastSlash = serviceName.lastIndexOf("/");
22010
+ return lastSlash === -1 ? serviceName : serviceName.slice(lastSlash + 1);
21809
22011
  }
21810
22012
 
21811
22013
  // node_modules/@postman-cse/automation-telemetry-core/dist/ci-context.js
@@ -22062,7 +22264,7 @@ function resolveActionVersion(explicit) {
22062
22264
  if (explicit) {
22063
22265
  return explicit;
22064
22266
  }
22065
- return "1.0.4" ? "1.0.4" : "unknown";
22267
+ return "2.0.0" ? "2.0.0" : "unknown";
22066
22268
  }
22067
22269
  function telemetryDisabled(env) {
22068
22270
  const flag = String(env.POSTMAN_ACTIONS_TELEMETRY ?? "").trim().toLowerCase();
@@ -22441,19 +22643,39 @@ async function resolveApiKeyAndTeamId(inputs, client, reporter = core_exports) {
22441
22643
  }
22442
22644
  return { apiKey, teamId: resolvedTeamId, pmakIdentity };
22443
22645
  }
22444
- async function runCredentialPreflightForInputs(inputs, pmak, reporter, fetchImpl) {
22646
+ async function runCredentialPreflightForInputs(inputs, pmak, reporter, fetchImpl, liveAccessToken) {
22647
+ const accessToken = liveAccessToken ?? inputs.postmanAccessToken;
22445
22648
  await runCredentialPreflight({
22446
22649
  apiBaseUrl: inputs.postmanApiBase || DEFAULT_POSTMAN_API_BASE,
22447
22650
  iapubBaseUrl: inputs.postmanIapubBase || DEFAULT_POSTMAN_IAPUB_BASE,
22448
22651
  pmak,
22449
- postmanAccessToken: inputs.postmanAccessToken,
22652
+ postmanAccessToken: accessToken,
22450
22653
  explicitTeamId: inputs.postmanTeamId || void 0,
22451
22654
  mode: inputs.credentialPreflight,
22452
- mask: createSecretMasker([inputs.postmanApiKey, inputs.postmanAccessToken]),
22655
+ mask: createSecretMasker([inputs.postmanApiKey, accessToken]),
22453
22656
  log: reporter,
22454
22657
  fetchImpl
22455
22658
  });
22456
22659
  }
22660
+ function createInsightsTokenProvider(inputs, reporter, apiKey = inputs.postmanApiKey) {
22661
+ return new AccessTokenProvider({
22662
+ accessToken: inputs.postmanAccessToken,
22663
+ apiKey,
22664
+ apiBaseUrl: inputs.postmanApiBase || DEFAULT_POSTMAN_API_BASE,
22665
+ onToken: (token) => reporter.setSecret(token)
22666
+ });
22667
+ }
22668
+ function createInsightsBifrostClient(inputs, tokenProvider, teamId, apiKey) {
22669
+ return new BifrostCatalogClient({
22670
+ tokenProvider,
22671
+ accessToken: tokenProvider.current(),
22672
+ teamId,
22673
+ apiKey,
22674
+ bifrostBaseUrl: inputs.postmanBifrostBase,
22675
+ observabilityBaseUrl: inputs.postmanObservabilityBase,
22676
+ observabilityEnv: inputs.postmanObservabilityEnv
22677
+ });
22678
+ }
22457
22679
 
22458
22680
  // src/cli.ts
22459
22681
  var ConsoleReporter = class {
@@ -22565,19 +22787,24 @@ async function runCli(argv = process.argv.slice(2), runtime = {}) {
22565
22787
  if (inputs.githubToken) {
22566
22788
  reporter.setSecret(inputs.githubToken);
22567
22789
  }
22568
- const preliminaryClient = new BifrostCatalogClient({
22569
- accessToken: inputs.postmanAccessToken,
22570
- teamId: inputs.postmanTeamId,
22571
- apiKey: inputs.postmanApiKey,
22572
- bifrostBaseUrl: inputs.postmanBifrostBase,
22573
- observabilityBaseUrl: inputs.postmanObservabilityBase,
22574
- observabilityEnv: inputs.postmanObservabilityEnv
22575
- });
22790
+ const tokenProvider = createInsightsTokenProvider(inputs, reporter);
22791
+ const preliminaryClient = createInsightsBifrostClient(
22792
+ inputs,
22793
+ tokenProvider,
22794
+ inputs.postmanTeamId,
22795
+ inputs.postmanApiKey
22796
+ );
22576
22797
  const { apiKey, teamId, pmakIdentity } = await resolveApiKeyAndTeamId(
22577
22798
  inputs,
22578
22799
  preliminaryClient,
22579
22800
  reporter
22580
22801
  );
22802
+ const activeTokenProvider = apiKey !== inputs.postmanApiKey ? new AccessTokenProvider({
22803
+ accessToken: tokenProvider.current(),
22804
+ apiKey,
22805
+ apiBaseUrl: inputs.postmanApiBase || DEFAULT_POSTMAN_API_BASE,
22806
+ onToken: (token) => reporter.setSecret(token)
22807
+ }) : tokenProvider;
22581
22808
  const telemetry = createTelemetryContext({ action: "postman-insights-onboarding-action", logger: reporter });
22582
22809
  telemetry.setTeamId(inputs.postmanTeamId || pmakIdentity?.teamId);
22583
22810
  if (apiKey) {
@@ -22585,15 +22812,14 @@ async function runCli(argv = process.argv.slice(2), runtime = {}) {
22585
22812
  }
22586
22813
  let result;
22587
22814
  try {
22588
- await runCredentialPreflightForInputs(inputs, pmakIdentity, reporter);
22589
- const client = new BifrostCatalogClient({
22590
- accessToken: inputs.postmanAccessToken,
22591
- teamId,
22592
- apiKey,
22593
- bifrostBaseUrl: inputs.postmanBifrostBase,
22594
- observabilityBaseUrl: inputs.postmanObservabilityBase,
22595
- observabilityEnv: inputs.postmanObservabilityEnv
22596
- });
22815
+ await runCredentialPreflightForInputs(
22816
+ inputs,
22817
+ pmakIdentity,
22818
+ reporter,
22819
+ void 0,
22820
+ activeTokenProvider.current()
22821
+ );
22822
+ const client = createInsightsBifrostClient(inputs, activeTokenProvider, teamId, apiKey);
22597
22823
  result = await (runtime.executeOnboarding ?? runOnboarding)(
22598
22824
  inputs,
22599
22825
  client,