@postman-cse/onboarding-insights 2.1.0 → 2.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -18685,8 +18685,11 @@ __export(index_exports, {
18685
18685
  createInsightsBifrostClient: () => createInsightsBifrostClient,
18686
18686
  createInsightsTokenProvider: () => createInsightsTokenProvider,
18687
18687
  createPlannedOutputs: () => createPlannedOutputs,
18688
+ getInput: () => getInput2,
18688
18689
  getTeams: () => getTeams,
18690
+ parseCreateApiKey: () => parseCreateApiKey,
18689
18691
  parsePreflightMode: () => parsePreflightMode,
18692
+ parseServiceNotFoundPolicy: () => parseServiceNotFoundPolicy,
18690
18693
  resolveApiKeyAndTeamId: () => resolveApiKeyAndTeamId,
18691
18694
  resolveInputs: () => resolveInputs,
18692
18695
  runAction: () => runAction,
@@ -21562,6 +21565,42 @@ async function retry(operation, options = {}) {
21562
21565
  }
21563
21566
  throw new Error("Retry exhausted without returning or throwing");
21564
21567
  }
21568
+ function isTransientHttpStatus(status) {
21569
+ return status === 408 || status === 429 || status >= 500;
21570
+ }
21571
+ function extractStatus(error2) {
21572
+ if (error2 instanceof HttpError) {
21573
+ return error2.status;
21574
+ }
21575
+ if (error2 && typeof error2 === "object" && "status" in error2) {
21576
+ const status = error2.status;
21577
+ return typeof status === "number" ? status : void 0;
21578
+ }
21579
+ if (error2 && typeof error2 === "object" && "cause" in error2) {
21580
+ return extractStatus(error2.cause);
21581
+ }
21582
+ return void 0;
21583
+ }
21584
+ function shouldRetryReadError(error2) {
21585
+ const status = extractStatus(error2);
21586
+ if (status === void 0) {
21587
+ return true;
21588
+ }
21589
+ return isTransientHttpStatus(status);
21590
+ }
21591
+ function isAmbiguousMutationFailure(error2) {
21592
+ const status = extractStatus(error2);
21593
+ if (status === void 0) {
21594
+ return true;
21595
+ }
21596
+ return isTransientHttpStatus(status);
21597
+ }
21598
+ var SAFE_READ_RETRY = {
21599
+ maxAttempts: 3,
21600
+ delayMs: 2e3,
21601
+ backoffMultiplier: 2,
21602
+ shouldRetry: (error2) => shouldRetryReadError(error2)
21603
+ };
21565
21604
 
21566
21605
  // src/lib/postman/base-urls.ts
21567
21606
  var POSTMAN_ENDPOINT_PROFILES = {
@@ -21776,6 +21815,27 @@ var MAX_PROVIDER_SERVICE_PAGES = 100;
21776
21815
  function isExpiredAuthError(status, body) {
21777
21816
  return status === 401 || body.includes("UNAUTHENTICATED") || body.includes("authenticationError");
21778
21817
  }
21818
+ function normalizeRepoUrl(url) {
21819
+ return url.trim().replace(/\/+$/, "").toLowerCase();
21820
+ }
21821
+ async function mutateOnceThenReconcile(options) {
21822
+ const existing = await options.findExisting();
21823
+ if (existing !== null) {
21824
+ return existing;
21825
+ }
21826
+ try {
21827
+ return await options.mutate();
21828
+ } catch (error2) {
21829
+ if (!isAmbiguousMutationFailure(error2)) {
21830
+ throw error2;
21831
+ }
21832
+ const adopted = await options.findExisting();
21833
+ if (adopted !== null) {
21834
+ return adopted;
21835
+ }
21836
+ throw error2;
21837
+ }
21838
+ }
21779
21839
  var BifrostCatalogClient = class {
21780
21840
  tokenProvider;
21781
21841
  teamId;
@@ -21812,8 +21872,9 @@ var BifrostCatalogClient = class {
21812
21872
  }
21813
21873
  /**
21814
21874
  * Build Bifrost proxy headers.
21815
- * x-entity-team-id is ONLY included when teamId is present (org-mode tokens).
21816
- * Non-org-mode tokens must OMIT it so Bifrost resolves team from the access token.
21875
+ * x-entity-team-id is ONLY included when teamId is present (explicit input /
21876
+ * POSTMAN_TEAM_ID). Non-org-mode tokens must OMIT it so Bifrost resolves team
21877
+ * from the access token. Team is never inferred from PMAK.
21817
21878
  */
21818
21879
  headers() {
21819
21880
  const h = {
@@ -21841,7 +21902,7 @@ var BifrostCatalogClient = class {
21841
21902
  mask: createSecretMasker(this.secretValues)
21842
21903
  };
21843
21904
  }
21844
- async proxyRequest(method, path6, body = {}, operation = "api-catalog request") {
21905
+ async proxyRequest(method, path6, body = {}, operation = "api-catalog request", allowAuthReplay = false) {
21845
21906
  const send2 = async () => this.fetchFn(this.bifrostProxyUrl, {
21846
21907
  method: "POST",
21847
21908
  headers: this.headers(),
@@ -21855,7 +21916,7 @@ var BifrostCatalogClient = class {
21855
21916
  let response = await send2();
21856
21917
  if (!response.ok) {
21857
21918
  const bodyText = await response.text().catch(() => "");
21858
- if (isExpiredAuthError(response.status, bodyText) && this.tokenProvider.canRefresh()) {
21919
+ if (allowAuthReplay && isExpiredAuthError(response.status, bodyText) && this.tokenProvider.canRefresh()) {
21859
21920
  try {
21860
21921
  const refreshed = await this.tokenProvider.refresh();
21861
21922
  this.registerAccessToken(refreshed);
@@ -21906,7 +21967,7 @@ var BifrostCatalogClient = class {
21906
21967
  }
21907
21968
  return data;
21908
21969
  }
21909
- async akitaProxyRequest(method, path6, body = {}, operation = "Insights request") {
21970
+ async akitaProxyRequest(method, path6, body = {}, operation = "Insights request", allowAuthReplay = false) {
21910
21971
  const send2 = async () => this.fetchFn(this.bifrostProxyUrl, {
21911
21972
  method: "POST",
21912
21973
  headers: this.headers(),
@@ -21920,7 +21981,7 @@ var BifrostCatalogClient = class {
21920
21981
  let response = await send2();
21921
21982
  if (!response.ok) {
21922
21983
  const text = await response.text().catch(() => "");
21923
- if (isExpiredAuthError(response.status, text) && this.tokenProvider.canRefresh()) {
21984
+ if (allowAuthReplay && isExpiredAuthError(response.status, text) && this.tokenProvider.canRefresh()) {
21924
21985
  try {
21925
21986
  const refreshed = await this.tokenProvider.refresh();
21926
21987
  this.registerAccessToken(refreshed);
@@ -21949,6 +22010,17 @@ ${advised.message}` : advised.message : text;
21949
22010
  const data = await response.json();
21950
22011
  return { ok: true, status: response.status, data, errorText: "" };
21951
22012
  }
22013
+ throwAkitaFailure(status, errorText, operation, path6) {
22014
+ const httpErr = new HttpError({
22015
+ method: "POST",
22016
+ url: `bifrost:akita:${path6}`,
22017
+ status,
22018
+ statusText: status >= 500 ? "Error" : "Client Error",
22019
+ responseBody: errorText
22020
+ });
22021
+ const advised = adviseFromHttpError(httpErr, this.adviceContext(operation));
22022
+ throw advised ?? httpErr;
22023
+ }
21952
22024
  async listDiscoveredServices() {
21953
22025
  return retry(
21954
22026
  async () => {
@@ -21976,26 +22048,80 @@ ${advised.message}` : advised.message : text;
21976
22048
  }
21977
22049
  return allItems;
21978
22050
  },
21979
- { maxAttempts: 3, delayMs: 2e3, backoffMultiplier: 2 }
22051
+ SAFE_READ_RETRY
21980
22052
  );
21981
22053
  }
21982
- async prepareCollection(serviceId, workspaceId) {
22054
+ /** List discovered + integrated services for exact link reconciliation. */
22055
+ async listServicesForReconcile() {
21983
22056
  return retry(
21984
22057
  async () => {
22058
+ const allItems = [];
22059
+ let cursor = null;
22060
+ const seenCursors = /* @__PURE__ */ new Set();
22061
+ for (let page = 0; page < MAX_DISCOVERED_SERVICE_PAGES; page += 1) {
22062
+ const query = cursor ? `?cursor=${encodeURIComponent(cursor)}` : "";
22063
+ const data = await this.proxyRequest(
22064
+ "GET",
22065
+ `/api/v1/onboarding/discovered-services${query}`,
22066
+ {},
22067
+ "service link reconciliation"
22068
+ );
22069
+ allItems.push(...data.items || []);
22070
+ if (data.total && allItems.length >= data.total) {
22071
+ break;
22072
+ }
22073
+ const nextCursor = data.nextCursor || null;
22074
+ if (!nextCursor || seenCursors.has(nextCursor)) {
22075
+ break;
22076
+ }
22077
+ seenCursors.add(nextCursor);
22078
+ cursor = nextCursor;
22079
+ }
22080
+ return allItems;
22081
+ },
22082
+ SAFE_READ_RETRY
22083
+ );
22084
+ }
22085
+ async findPreparedCollection(serviceId, workspaceId) {
22086
+ const services = await this.listServicesForReconcile();
22087
+ const match = services.find(
22088
+ (service) => service.id === serviceId && Boolean(service.collectionId) && service.workspaceId === workspaceId
22089
+ );
22090
+ return match?.collectionId ? String(match.collectionId) : null;
22091
+ }
22092
+ async findGitLink(params) {
22093
+ const services = await this.listServicesForReconcile();
22094
+ const match = services.find((service) => {
22095
+ if (service.id !== params.serviceId) return false;
22096
+ if (service.workspaceId !== params.workspaceId) return false;
22097
+ if (service.environmentId !== params.environmentId) return false;
22098
+ if (!service.gitRepositoryUrl) return false;
22099
+ return normalizeRepoUrl(service.gitRepositoryUrl) === normalizeRepoUrl(params.gitRepositoryUrl);
22100
+ });
22101
+ return match ? true : null;
22102
+ }
22103
+ async prepareCollection(serviceId, workspaceId) {
22104
+ return mutateOnceThenReconcile({
22105
+ findExisting: () => this.findPreparedCollection(serviceId, workspaceId),
22106
+ mutate: async () => {
21985
22107
  const data = await this.proxyRequest(
21986
22108
  "POST",
21987
22109
  "/api/v1/onboarding/prepare-collection",
21988
22110
  { service_id: String(serviceId), workspace_id: workspaceId },
21989
- "collection preparation"
22111
+ "collection preparation",
22112
+ false
21990
22113
  );
22114
+ if (!data?.id) {
22115
+ throw new Error("prepare-collection succeeded without a collection id");
22116
+ }
21991
22117
  return data.id;
21992
- },
21993
- { maxAttempts: 3, delayMs: 2e3, backoffMultiplier: 2 }
21994
- );
22118
+ }
22119
+ });
21995
22120
  }
21996
22121
  async onboardGit(params) {
21997
- await retry(
21998
- async () => {
22122
+ await mutateOnceThenReconcile({
22123
+ findExisting: () => this.findGitLink(params),
22124
+ mutate: async () => {
21999
22125
  const body = {
22000
22126
  via_integrations: false,
22001
22127
  git_service_name: "github",
@@ -22011,24 +22137,32 @@ ${advised.message}` : advised.message : text;
22011
22137
  "POST",
22012
22138
  "/api/v1/onboarding/git",
22013
22139
  body,
22014
- "git onboarding"
22140
+ "git onboarding",
22141
+ false
22015
22142
  );
22016
- },
22017
- { maxAttempts: 2, delayMs: 3e3 }
22018
- );
22143
+ return true;
22144
+ }
22145
+ });
22019
22146
  }
22020
- async resolveProviderServiceId(projectName, clusterName) {
22147
+ async listProviderServices() {
22021
22148
  const allServices = [];
22022
22149
  let page = 1;
22023
22150
  const pageSize = 100;
22024
22151
  for (let pageCount = 0; pageCount < MAX_PROVIDER_SERVICE_PAGES; pageCount += 1) {
22025
22152
  const result = await this.akitaProxyRequest(
22026
22153
  "GET",
22027
- `/v2/api-catalog/services?status=discovered&populate_endpoints=false&populate_discovery_metadata=true&page=${page}&page_size=${pageSize}`,
22154
+ `/v2/api-catalog/services?populate_endpoints=false&populate_discovery_metadata=true&page=${page}&page_size=${pageSize}`,
22028
22155
  {},
22029
22156
  "provider service resolution"
22030
22157
  );
22031
- if (!result.ok || !result.data) return null;
22158
+ if (!result.ok || !result.data) {
22159
+ this.throwAkitaFailure(
22160
+ result.status,
22161
+ result.errorText,
22162
+ "provider service resolution",
22163
+ "GET /v2/api-catalog/services"
22164
+ );
22165
+ }
22032
22166
  const services = result.data.services || [];
22033
22167
  allServices.push(...services);
22034
22168
  if (result.data.total && allServices.length >= result.data.total) {
@@ -22039,86 +22173,225 @@ ${advised.message}` : advised.message : text;
22039
22173
  }
22040
22174
  page++;
22041
22175
  }
22176
+ return allServices;
22177
+ }
22178
+ async resolveProviderServiceId(projectName, clusterName) {
22179
+ const allServices = await retry(
22180
+ async () => this.listProviderServices(),
22181
+ SAFE_READ_RETRY
22182
+ );
22042
22183
  if (clusterName) {
22043
22184
  const fullName = `${clusterName}/${projectName}`;
22044
22185
  const exactMatch = allServices.find((s) => s.name === fullName);
22045
22186
  return exactMatch?.id || null;
22046
22187
  }
22047
- const finalSegmentMatch = allServices.find(
22188
+ const finalSegmentMatches = allServices.filter(
22048
22189
  (s) => getFinalServiceSegment(s.name) === projectName
22049
22190
  );
22050
- if (finalSegmentMatch) return finalSegmentMatch.id;
22051
- const bracketedMatch = allServices.find(
22191
+ if (finalSegmentMatches.length > 1) {
22192
+ throw new Error(
22193
+ `Ambiguous Insights provider service "${projectName}": multiple final-segment matches (${finalSegmentMatches.map((s) => s.name).join(", ")}). Provide cluster-name to select the canonical service identity.`
22194
+ );
22195
+ }
22196
+ if (finalSegmentMatches.length === 1) return finalSegmentMatches[0].id;
22197
+ const bracketedMatches = allServices.filter(
22052
22198
  (s) => getFinalServiceSegment(s.name).includes(`[${projectName}]`)
22053
22199
  );
22054
- return bracketedMatch?.id || null;
22200
+ if (bracketedMatches.length > 1) {
22201
+ throw new Error(
22202
+ `Ambiguous Insights provider service "${projectName}": multiple bracketed matches. Provide cluster-name to select the canonical service identity.`
22203
+ );
22204
+ }
22205
+ return bracketedMatches[0]?.id || null;
22206
+ }
22207
+ async findAcknowledgedOnboarding(providerServiceId, workspaceId, systemEnvironmentId) {
22208
+ const services = await this.listProviderServices();
22209
+ const match = services.find(
22210
+ (service) => service.id === providerServiceId && service.workspace_id === workspaceId && service.system_env === systemEnvironmentId && (service.status === "onboarded" || service.status === "integrated" || Boolean(service.workspace_id))
22211
+ );
22212
+ return match ? true : null;
22055
22213
  }
22056
22214
  async acknowledgeOnboarding(providerServiceId, workspaceId, systemEnvironmentId) {
22057
- const result = await this.akitaProxyRequest(
22058
- "POST",
22059
- "/v2/api-catalog/services/onboard",
22060
- {
22061
- services: [{
22062
- service_id: providerServiceId,
22063
- workspace_id: workspaceId,
22064
- system_env: systemEnvironmentId
22065
- }]
22215
+ await mutateOnceThenReconcile({
22216
+ findExisting: () => this.findAcknowledgedOnboarding(providerServiceId, workspaceId, systemEnvironmentId),
22217
+ mutate: async () => {
22218
+ const result = await this.akitaProxyRequest(
22219
+ "POST",
22220
+ "/v2/api-catalog/services/onboard",
22221
+ {
22222
+ services: [{
22223
+ service_id: providerServiceId,
22224
+ workspace_id: workspaceId,
22225
+ system_env: systemEnvironmentId
22226
+ }]
22227
+ },
22228
+ "Insights onboarding acknowledgment",
22229
+ false
22230
+ );
22231
+ if (!result.ok) {
22232
+ this.throwAkitaFailure(
22233
+ result.status,
22234
+ result.errorText,
22235
+ "Insights onboarding acknowledgment",
22236
+ "POST /v2/api-catalog/services/onboard"
22237
+ );
22238
+ }
22239
+ return true;
22240
+ }
22241
+ });
22242
+ }
22243
+ async findWorkspaceAcknowledged(workspaceId) {
22244
+ const result = await retry(
22245
+ async () => {
22246
+ const response = await this.akitaProxyRequest(
22247
+ "GET",
22248
+ `/v2/workspaces/${workspaceId}/onboarding/acknowledge`,
22249
+ {},
22250
+ "workspace onboarding acknowledgment status"
22251
+ );
22252
+ if (!response.ok) {
22253
+ this.throwAkitaFailure(
22254
+ response.status,
22255
+ response.errorText,
22256
+ "workspace onboarding acknowledgment status",
22257
+ `GET /v2/workspaces/${workspaceId}/onboarding/acknowledge`
22258
+ );
22259
+ }
22260
+ return response;
22066
22261
  },
22067
- "Insights onboarding acknowledgment"
22262
+ SAFE_READ_RETRY
22068
22263
  );
22069
- if (!result.ok) {
22070
- throw new Error(`Insights acknowledge failed: ${result.status} ${result.errorText}`);
22071
- }
22264
+ return result.data?.onboarding_acknowledged ? true : null;
22072
22265
  }
22073
22266
  async acknowledgeWorkspace(workspaceId) {
22074
- const result = await this.akitaProxyRequest(
22075
- "POST",
22076
- `/v2/workspaces/${workspaceId}/onboarding/acknowledge`,
22077
- {},
22078
- "workspace onboarding acknowledgment"
22079
- );
22080
- if (!result.ok) {
22081
- throw new Error(`Workspace acknowledge failed: ${result.status} ${result.errorText}`);
22082
- }
22267
+ await mutateOnceThenReconcile({
22268
+ findExisting: () => this.findWorkspaceAcknowledged(workspaceId),
22269
+ mutate: async () => {
22270
+ const result = await this.akitaProxyRequest(
22271
+ "POST",
22272
+ `/v2/workspaces/${workspaceId}/onboarding/acknowledge`,
22273
+ {},
22274
+ "workspace onboarding acknowledgment",
22275
+ false
22276
+ );
22277
+ if (!result.ok) {
22278
+ this.throwAkitaFailure(
22279
+ result.status,
22280
+ result.errorText,
22281
+ "workspace onboarding acknowledgment",
22282
+ `POST /v2/workspaces/${workspaceId}/onboarding/acknowledge`
22283
+ );
22284
+ }
22285
+ return true;
22286
+ }
22287
+ });
22083
22288
  }
22084
- // PMAK-only by proven exception. A live probe against the observability
22085
- // application-binding endpoint (POST /v2/agent/api-catalog/workspaces/:id/
22086
- // applications) showed x-access-token is rejected identically to the x-api-key
22087
- // control: both return 401 {"message":"Postman User not found"} for a
22088
- // service-account credential, because the observability service has no
22089
- // "Postman User" for a service account. The access token offers no improvement
22090
- // over the API key here, so this route is not migrated to access-token-primary
22091
- // (the suite-wide migration explicitly leaves probe-failed routes on PMAK).
22092
- async createApplication(workspaceId, systemEnv) {
22289
+ async findApplication(workspaceId, systemEnv, expectedServiceId) {
22093
22290
  const response = await this.fetchFn(
22094
22291
  `${this.observabilityBaseUrl}/v2/agent/api-catalog/workspaces/${workspaceId}/applications`,
22095
22292
  {
22096
- method: "POST",
22293
+ method: "GET",
22097
22294
  headers: {
22098
22295
  "x-api-key": this.apiKey,
22099
22296
  "x-postman-env": this.observabilityEnv,
22100
22297
  "Content-Type": "application/json"
22101
- },
22102
- body: JSON.stringify({ system_env: systemEnv })
22298
+ }
22103
22299
  }
22104
22300
  );
22105
22301
  if (!response.ok) {
22106
22302
  const httpErr = await HttpError.fromResponse(response, {
22107
- method: "POST",
22108
- url: `observability:createApplication(${workspaceId})`,
22303
+ method: "GET",
22304
+ url: `observability:listApplications(${workspaceId})`,
22109
22305
  secretValues: this.secretValues
22110
22306
  });
22111
- const advised = adviseFromHttpError(httpErr, this.adviceContext("application binding"));
22307
+ const advised = adviseFromHttpError(httpErr, this.adviceContext("application binding lookup"));
22112
22308
  throw advised ?? httpErr;
22113
22309
  }
22114
- return response.json();
22310
+ const data = await response.json();
22311
+ const matches = (data.applications || []).filter(
22312
+ (app) => app.application_id && app.service_id && app.system_env === systemEnv && (!expectedServiceId || app.service_id === expectedServiceId)
22313
+ );
22314
+ if (matches.length > 1) {
22315
+ throw new Error(
22316
+ `Multiple application bindings match workspace ${workspaceId}, system environment ${systemEnv}, and service ${expectedServiceId || "(unspecified)"}`
22317
+ );
22318
+ }
22319
+ const match = matches[0];
22320
+ if (!match?.application_id || !match.service_id) {
22321
+ return null;
22322
+ }
22323
+ return {
22324
+ application_id: String(match.application_id),
22325
+ service_id: String(match.service_id)
22326
+ };
22327
+ }
22328
+ // PMAK-only by proven exception. A live probe against the observability
22329
+ // application-binding endpoint (POST /v2/agent/api-catalog/workspaces/:id/
22330
+ // applications) showed x-access-token is rejected identically to the x-api-key
22331
+ // control: both return 401 {"message":"Postman User not found"} for a
22332
+ // service-account credential, because the observability service has no
22333
+ // "Postman User" for a service account. The access token offers no improvement
22334
+ // over the API key here, so this route is not migrated to access-token-primary
22335
+ // (the suite-wide migration explicitly leaves probe-failed routes on PMAK).
22336
+ async createApplication(workspaceId, systemEnv, expectedServiceId) {
22337
+ return mutateOnceThenReconcile({
22338
+ findExisting: () => retry(
22339
+ () => this.findApplication(workspaceId, systemEnv, expectedServiceId),
22340
+ SAFE_READ_RETRY
22341
+ ),
22342
+ mutate: async () => {
22343
+ const response = await this.fetchFn(
22344
+ `${this.observabilityBaseUrl}/v2/agent/api-catalog/workspaces/${workspaceId}/applications`,
22345
+ {
22346
+ method: "POST",
22347
+ headers: {
22348
+ "x-api-key": this.apiKey,
22349
+ "x-postman-env": this.observabilityEnv,
22350
+ "Content-Type": "application/json"
22351
+ },
22352
+ body: JSON.stringify({ system_env: systemEnv })
22353
+ }
22354
+ );
22355
+ if (!response.ok) {
22356
+ const httpErr = await HttpError.fromResponse(response, {
22357
+ method: "POST",
22358
+ url: `observability:createApplication(${workspaceId})`,
22359
+ secretValues: this.secretValues
22360
+ });
22361
+ const advised = adviseFromHttpError(httpErr, this.adviceContext("application binding"));
22362
+ throw advised ?? httpErr;
22363
+ }
22364
+ const created = await response.json();
22365
+ if (expectedServiceId && created.service_id !== expectedServiceId) {
22366
+ throw new Error(
22367
+ `Application binding credential/scope mismatch: expected service ${expectedServiceId}, received ${created.service_id}`
22368
+ );
22369
+ }
22370
+ return created;
22371
+ }
22372
+ });
22115
22373
  }
22116
22374
  async getTeamVerificationToken(workspaceId) {
22117
- const result = await this.akitaProxyRequest(
22118
- "GET",
22119
- `/v2/workspaces/${workspaceId}/team-verification-token`,
22120
- {},
22121
- "team verification token retrieval"
22375
+ const result = await retry(
22376
+ async () => {
22377
+ const page = await this.akitaProxyRequest(
22378
+ "GET",
22379
+ `/v2/workspaces/${workspaceId}/team-verification-token`,
22380
+ {},
22381
+ "team verification token retrieval"
22382
+ );
22383
+ if (!page.ok && (page.status === 408 || page.status === 429 || page.status >= 500)) {
22384
+ throw new HttpError({
22385
+ method: "GET",
22386
+ url: `bifrost:akita:GET /v2/workspaces/${workspaceId}/team-verification-token`,
22387
+ status: page.status,
22388
+ statusText: "Error",
22389
+ responseBody: page.errorText
22390
+ });
22391
+ }
22392
+ return page;
22393
+ },
22394
+ SAFE_READ_RETRY
22122
22395
  );
22123
22396
  if (!result.ok || !result.data) return null;
22124
22397
  return result.data.team_verification_token || null;
@@ -22151,24 +22424,87 @@ ${advised.message}` : advised.message : text;
22151
22424
  return String(apikey.key);
22152
22425
  }
22153
22426
  };
22427
+ function buildCanonicalServiceIdentity(service, projectName, clusterName, providerServiceId) {
22428
+ const derivedCluster = clusterName || (service.name.includes("/") ? service.name.slice(0, service.name.lastIndexOf("/")) : null);
22429
+ return {
22430
+ serviceId: service.id,
22431
+ serviceName: service.name,
22432
+ clusterName: derivedCluster,
22433
+ projectName,
22434
+ ...providerServiceId ? { providerServiceId } : {}
22435
+ };
22436
+ }
22154
22437
  function findDiscoveredService(services, projectName, clusterName) {
22155
22438
  if (clusterName) {
22156
22439
  const fullName = `${clusterName}/${projectName}`;
22157
- return services.find((s) => s.name === fullName);
22440
+ const match = services.find((s) => s.name === fullName);
22441
+ if (match) {
22442
+ match.canonicalIdentity = buildCanonicalServiceIdentity(match, projectName, clusterName);
22443
+ }
22444
+ return match;
22158
22445
  }
22159
- const finalSegmentMatch = services.find(
22446
+ const finalSegmentMatches = services.filter(
22160
22447
  (service) => getFinalServiceSegment(service.name) === projectName
22161
22448
  );
22162
- if (finalSegmentMatch) return finalSegmentMatch;
22163
- return services.find(
22449
+ if (finalSegmentMatches.length > 1) {
22450
+ throw new Error(
22451
+ `Ambiguous discovered service "${projectName}": multiple final-segment matches (${finalSegmentMatches.map((s) => s.name).join(", ")}). cluster-name is required to select the canonical service identity.`
22452
+ );
22453
+ }
22454
+ if (finalSegmentMatches.length === 1) {
22455
+ const match = finalSegmentMatches[0];
22456
+ match.canonicalIdentity = buildCanonicalServiceIdentity(match, projectName);
22457
+ return match;
22458
+ }
22459
+ const bracketedMatches = services.filter(
22164
22460
  (service) => getFinalServiceSegment(service.name).includes(`[${projectName}]`)
22165
22461
  );
22462
+ if (bracketedMatches.length > 1) {
22463
+ throw new Error(
22464
+ `Ambiguous discovered service "${projectName}": multiple bracketed matches. cluster-name is required to select the canonical service identity.`
22465
+ );
22466
+ }
22467
+ if (bracketedMatches.length === 1) {
22468
+ const match = bracketedMatches[0];
22469
+ match.canonicalIdentity = buildCanonicalServiceIdentity(match, projectName);
22470
+ return match;
22471
+ }
22472
+ return void 0;
22166
22473
  }
22167
22474
  function getFinalServiceSegment(serviceName) {
22168
22475
  const lastSlash = serviceName.lastIndexOf("/");
22169
22476
  return lastSlash === -1 ? serviceName : serviceName.slice(lastSlash + 1);
22170
22477
  }
22171
22478
 
22479
+ // src/lib/input.ts
22480
+ function normalizeInputValue(value) {
22481
+ return String(value ?? "").trim();
22482
+ }
22483
+ function runnerInputEnvName(name) {
22484
+ return `INPUT_${name.replace(/ /g, "_").toUpperCase()}`;
22485
+ }
22486
+ function normalizedInputEnvName(name) {
22487
+ return `INPUT_${name.replace(/-/g, "_").toUpperCase()}`;
22488
+ }
22489
+ function getInput2(name, env = process.env) {
22490
+ const normalizedName = normalizedInputEnvName(name);
22491
+ const runnerName = runnerInputEnvName(name);
22492
+ const normalizedRaw = env[normalizedName];
22493
+ const runnerRaw = runnerName === normalizedName ? void 0 : env[runnerName];
22494
+ const hasNormalized = normalizedRaw !== void 0;
22495
+ const hasRunner = runnerRaw !== void 0;
22496
+ if (hasNormalized && hasRunner) {
22497
+ const normalizedValue = normalizeInputValue(normalizedRaw);
22498
+ const runnerValue = normalizeInputValue(runnerRaw);
22499
+ if (normalizedValue !== runnerValue) {
22500
+ throw new Error(
22501
+ `Conflicting values for ${name}: ${normalizedName}=${JSON.stringify(normalizedValue)} vs ${runnerName}=${JSON.stringify(runnerValue)}`
22502
+ );
22503
+ }
22504
+ }
22505
+ return normalizeInputValue(hasNormalized ? normalizedRaw : runnerRaw);
22506
+ }
22507
+
22172
22508
  // node_modules/@postman-cse/automation-telemetry-core/dist/ci-context.js
22173
22509
  function norm(value) {
22174
22510
  const trimmed = (value ?? "").trim();
@@ -22325,7 +22661,7 @@ function normalize(value) {
22325
22661
  const trimmed = (value ?? "").trim();
22326
22662
  return trimmed.length > 0 ? trimmed : void 0;
22327
22663
  }
22328
- function normalizeRepoUrl(url) {
22664
+ function normalizeRepoUrl2(url) {
22329
22665
  const raw = normalize(url);
22330
22666
  if (!raw) {
22331
22667
  return void 0;
@@ -22393,7 +22729,7 @@ function classifyRefKind(env = process.env) {
22393
22729
  return "unknown";
22394
22730
  }
22395
22731
  function detectRepoContext(input, env = process.env) {
22396
- const repoUrl = normalizeRepoUrl(input.repoUrl) ?? normalizeRepoUrl(env.GITHUB_SERVER_URL && env.GITHUB_REPOSITORY ? `${env.GITHUB_SERVER_URL}/${env.GITHUB_REPOSITORY}` : void 0) ?? normalizeRepoUrl(env.CI_PROJECT_URL) ?? normalizeRepoUrl(env.BITBUCKET_GIT_HTTP_ORIGIN) ?? normalizeRepoUrl(env.BUILD_REPOSITORY_URI);
22732
+ const repoUrl = normalizeRepoUrl2(input.repoUrl) ?? normalizeRepoUrl2(env.GITHUB_SERVER_URL && env.GITHUB_REPOSITORY ? `${env.GITHUB_SERVER_URL}/${env.GITHUB_REPOSITORY}` : void 0) ?? normalizeRepoUrl2(env.CI_PROJECT_URL) ?? normalizeRepoUrl2(env.BITBUCKET_GIT_HTTP_ORIGIN) ?? normalizeRepoUrl2(env.BUILD_REPOSITORY_URI);
22397
22733
  const repoSlug = normalize(input.repoSlug) ?? normalize(env.GITHUB_REPOSITORY) ?? normalize(env.CI_PROJECT_PATH) ?? (env.BITBUCKET_WORKSPACE && env.BITBUCKET_REPO_SLUG ? normalize(`${env.BITBUCKET_WORKSPACE}/${env.BITBUCKET_REPO_SLUG}`) : void 0) ?? normalize(env.BUILD_REPOSITORY_NAME);
22398
22734
  const ref = normalize(input.ref) ?? normalize(env.GITHUB_REF_NAME) ?? normalize(env.CI_COMMIT_REF_NAME) ?? normalize(env.BITBUCKET_BRANCH) ?? normalize(env.BUILD_SOURCEBRANCHNAME);
22399
22735
  const sha = normalize(input.sha) ?? normalize(env.GITHUB_SHA) ?? normalize(env.CI_COMMIT_SHA) ?? normalize(env.BITBUCKET_COMMIT) ?? normalize(env.BUILD_SOURCEVERSION);
@@ -22570,7 +22906,7 @@ var DEFAULT_POSTMAN_BIFROST_BASE = PROD_ENDPOINTS.bifrostBaseUrl;
22570
22906
  var DEFAULT_POSTMAN_IAPUB_BASE = PROD_ENDPOINTS.iapubBaseUrl;
22571
22907
  var DEFAULT_POSTMAN_OBSERVABILITY_BASE = PROD_ENDPOINTS.observabilityBaseUrl;
22572
22908
  function parsePreflightMode(value) {
22573
- const normalized = String(value || "warn").trim().toLowerCase();
22909
+ const normalized = String(value || "enforce").trim().toLowerCase();
22574
22910
  if (normalized === "enforce" || normalized === "warn") {
22575
22911
  return normalized;
22576
22912
  }
@@ -22578,6 +22914,27 @@ function parsePreflightMode(value) {
22578
22914
  `Unsupported credential-preflight "${value}". Supported values: enforce, warn`
22579
22915
  );
22580
22916
  }
22917
+ function parseServiceNotFoundPolicy(value) {
22918
+ const normalized = String(value || "fail").trim().toLowerCase();
22919
+ if (normalized === "fail" || normalized === "warn") {
22920
+ return normalized;
22921
+ }
22922
+ throw new Error(
22923
+ `Unsupported service-not-found-policy "${value}". Supported values: fail, warn`
22924
+ );
22925
+ }
22926
+ function parseCreateApiKey(value) {
22927
+ const normalized = String(value || "false").trim().toLowerCase();
22928
+ if (normalized === "true") {
22929
+ return true;
22930
+ }
22931
+ if (normalized === "false" || normalized === "") {
22932
+ return false;
22933
+ }
22934
+ throw new Error(
22935
+ `Unsupported create-api-key "${value}". Supported values: true, false`
22936
+ );
22937
+ }
22581
22938
  function trimTrailingSlash(value) {
22582
22939
  return value.replace(/\/+$/, "");
22583
22940
  }
@@ -22618,7 +22975,7 @@ function clamp(value, min, max, fallback) {
22618
22975
  return Math.min(max, Math.max(min, parsed));
22619
22976
  }
22620
22977
  function resolveInputs(env = process.env) {
22621
- const get = (name, fallback = "") => env[`INPUT_${name.toUpperCase().replace(/-/g, "_")}`]?.trim() || fallback;
22978
+ const get = (name, fallback = "") => getInput2(name, env) || fallback;
22622
22979
  const projectName = get("project-name");
22623
22980
  if (!projectName) throw new Error("project-name is required");
22624
22981
  const postmanAccessToken = get("postman-access-token");
@@ -22659,7 +23016,9 @@ function resolveInputs(env = process.env) {
22659
23016
  postmanApiKey,
22660
23017
  postmanTeamId,
22661
23018
  githubToken: get("github-token", env.GITHUB_TOKEN || ""),
22662
- credentialPreflight: parsePreflightMode(get("credential-preflight", "warn")),
23019
+ credentialPreflight: parsePreflightMode(get("credential-preflight", "enforce")),
23020
+ createApiKey: parseCreateApiKey(get("create-api-key", "false")),
23021
+ serviceNotFoundPolicy: parseServiceNotFoundPolicy(get("service-not-found-policy", "fail")),
22663
23022
  pollTimeoutSeconds: clamp(rawTimeout, POLL_TIMEOUT_MIN, POLL_TIMEOUT_MAX, POLL_TIMEOUT_DEFAULT),
22664
23023
  pollIntervalSeconds: clamp(rawInterval, POLL_INTERVAL_MIN, POLL_INTERVAL_MAX, POLL_INTERVAL_DEFAULT),
22665
23024
  postmanRegion,
@@ -22685,6 +23044,7 @@ async function runOnboarding(inputs, client, sleepFn = sleep, reporter = core_ex
22685
23044
  const timeoutMs = inputs.pollTimeoutSeconds * 1e3;
22686
23045
  const intervalMs = inputs.pollIntervalSeconds * 1e3;
22687
23046
  const startTime = Date.now();
23047
+ const policy = inputs.serviceNotFoundPolicy ?? "fail";
22688
23048
  reporter.info(`Looking for discovered service matching "${inputs.clusterName ? `${inputs.clusterName}/` : ""}${inputs.projectName}"...`);
22689
23049
  let match = void 0;
22690
23050
  while (Date.now() - startTime < timeoutMs) {
@@ -22699,15 +23059,35 @@ async function runOnboarding(inputs, client, sleepFn = sleep, reporter = core_ex
22699
23059
  await sleepFn(intervalMs);
22700
23060
  }
22701
23061
  if (!match) {
22702
- reporter.warning(`Service "${inputs.projectName}" not found in discovered services after ${inputs.pollTimeoutSeconds}s`);
22703
- return {
22704
- discoveredServiceId: 0,
22705
- discoveredServiceName: "",
22706
- collectionId: "",
22707
- applicationId: "",
22708
- verificationToken: null,
22709
- status: "not-found"
22710
- };
23062
+ const message = `Service "${inputs.projectName}" not found in discovered services after ${inputs.pollTimeoutSeconds}s`;
23063
+ if (policy === "warn") {
23064
+ reporter.warning(message);
23065
+ return {
23066
+ discoveredServiceId: 0,
23067
+ discoveredServiceName: "",
23068
+ collectionId: "",
23069
+ applicationId: "",
23070
+ verificationToken: null,
23071
+ status: "not-found"
23072
+ };
23073
+ }
23074
+ throw new Error(`${message}. Full linking requires a discovered service (service-not-found-policy=fail).`);
23075
+ }
23076
+ const canonicalBase = match.canonicalIdentity ?? buildCanonicalServiceIdentity(match, inputs.projectName, inputs.clusterName || void 0);
23077
+ const providerServiceId = await client.resolveProviderServiceId(
23078
+ inputs.projectName,
23079
+ inputs.clusterName || void 0
23080
+ );
23081
+ if (!providerServiceId) {
23082
+ throw new Error(
23083
+ `Insights provider service "${canonicalBase.serviceName}" was not found. Full linking requires one exact canonical service identity.`
23084
+ );
23085
+ }
23086
+ const sysEnvId = inputs.systemEnvironmentId || match.systemEnvironmentId || "";
23087
+ if (!sysEnvId) {
23088
+ throw new Error(
23089
+ `No system environment id is available for "${canonicalBase.serviceName}"; refusing partial linking writes.`
23090
+ );
22711
23091
  }
22712
23092
  reporter.info(`Preparing collection for service ${match.id} in workspace ${inputs.workspaceId}...`);
22713
23093
  const collectionId = await client.prepareCollection(match.id, inputs.workspaceId);
@@ -22727,27 +23107,12 @@ async function runOnboarding(inputs, client, sleepFn = sleep, reporter = core_ex
22727
23107
  } else {
22728
23108
  reporter.info(`Skipping git onboarding for non-GitHub repo: ${repoUrl}`);
22729
23109
  }
22730
- const providerServiceId = await client.resolveProviderServiceId(
22731
- inputs.projectName,
22732
- inputs.clusterName || void 0
22733
- );
22734
- let applicationId = "";
22735
- if (providerServiceId) {
22736
- const sysEnvId = inputs.systemEnvironmentId || match.systemEnvironmentId || "";
22737
- if (sysEnvId) {
22738
- reporter.info(`Acknowledging Insights onboarding for ${providerServiceId}...`);
22739
- await client.acknowledgeOnboarding(providerServiceId, inputs.workspaceId, sysEnvId);
22740
- reporter.info(`Insights acknowledged: ${providerServiceId}`);
22741
- reporter.info(`Creating application binding for workspace ${inputs.workspaceId} with system_env ${sysEnvId}...`);
22742
- const appResult = await client.createApplication(inputs.workspaceId, sysEnvId);
22743
- applicationId = appResult.application_id;
22744
- reporter.info(`Application binding created: ${appResult.application_id} for service ${appResult.service_id}`);
22745
- } else {
22746
- reporter.warning("No systemEnvironmentId available; skipping Insights acknowledgment and application binding");
22747
- }
22748
- } else {
22749
- reporter.warning("Could not resolve Akita provider service ID; skipping acknowledgment and application binding");
22750
- }
23110
+ reporter.info(`Acknowledging Insights onboarding for ${providerServiceId}...`);
23111
+ await client.acknowledgeOnboarding(providerServiceId, inputs.workspaceId, sysEnvId);
23112
+ reporter.info(`Insights acknowledged: ${providerServiceId}`);
23113
+ reporter.info(`Creating application binding for workspace ${inputs.workspaceId} with system_env ${sysEnvId}...`);
23114
+ const appResult = await client.createApplication(inputs.workspaceId, sysEnvId, providerServiceId);
23115
+ reporter.info(`Application binding created: ${appResult.application_id} for service ${appResult.service_id}`);
22751
23116
  reporter.info(`Acknowledging workspace onboarding for ${inputs.workspaceId}...`);
22752
23117
  await client.acknowledgeWorkspace(inputs.workspaceId);
22753
23118
  reporter.info("Workspace onboarding acknowledged");
@@ -22763,9 +23128,13 @@ async function runOnboarding(inputs, client, sleepFn = sleep, reporter = core_ex
22763
23128
  discoveredServiceId: match.id,
22764
23129
  discoveredServiceName: match.name,
22765
23130
  collectionId,
22766
- applicationId,
23131
+ applicationId: appResult.application_id,
22767
23132
  verificationToken,
22768
- status: "success"
23133
+ status: "success",
23134
+ canonicalIdentity: {
23135
+ ...canonicalBase,
23136
+ ...providerServiceId ? { providerServiceId } : {}
23137
+ }
22769
23138
  };
22770
23139
  }
22771
23140
  async function resolveApiKeyAndTeamId(inputs, client, reporter = core_exports) {
@@ -22774,6 +23143,7 @@ async function resolveApiKeyAndTeamId(inputs, client, reporter = core_exports) {
22774
23143
  let keyValid = false;
22775
23144
  let pmakIdentity;
22776
23145
  const apiBase = inputs.postmanApiBase || DEFAULT_POSTMAN_API_BASE;
23146
+ const createApiKey = inputs.createApiKey === true;
22777
23147
  if (apiKey) {
22778
23148
  const result = await validateApiKey(apiKey, apiBase);
22779
23149
  keyValid = result.valid;
@@ -22784,49 +23154,36 @@ async function resolveApiKeyAndTeamId(inputs, client, reporter = core_exports) {
22784
23154
  }
22785
23155
  }
22786
23156
  if (!keyValid) {
22787
- reporter.info("Generating a new Postman API key via Bifrost identity service...");
22788
- const keyName = `insights-onboarding-action-${Date.now()}`;
23157
+ if (!createApiKey) {
23158
+ if (apiKey) {
23159
+ throw new Error(
23160
+ "postman-api-key is invalid or expired. Provide a valid key, or set create-api-key=true to opt in to durable Bifrost API-key creation."
23161
+ );
23162
+ }
23163
+ throw new Error(
23164
+ "postman-api-key is required for application binding. Provide a valid key, or set create-api-key=true to opt in to durable Bifrost API-key creation."
23165
+ );
23166
+ }
23167
+ reporter.info("create-api-key=true: generating a durable Postman API key via Bifrost identity service...");
23168
+ const keyName = `insights-onboarding-${inputs.projectName}`;
22789
23169
  apiKey = await client.createApiKey(keyName);
22790
23170
  reporter.setSecret(apiKey);
22791
23171
  client.setApiKey(apiKey);
22792
- reporter.info("New API key created successfully.");
22793
- }
22794
- let resolvedTeamId = teamId;
22795
- if (!resolvedTeamId && apiKey) {
22796
- try {
22797
- const teams = await getTeams(apiKey, apiBase);
22798
- if (teams.length > 1 && teams.every((t) => t.organizationId == null)) {
22799
- reporter.warning(
22800
- "GET /teams returned multiple teams but none include organizationId. Org-mode auto-detection may be degraded due to an upstream API change. Set postman-team-id explicitly if Bifrost calls fail."
22801
- );
22802
- }
22803
- const isOrgMode = teams.some((t) => t.organizationId != null);
22804
- if (isOrgMode) {
22805
- if (teams.length === 1) {
22806
- resolvedTeamId = String(teams[0].id);
22807
- reporter.info(
22808
- `Org-mode account detected. Using sub-team ${teams[0].id} (${teams[0].name ?? "unknown"}) for Bifrost calls.`
22809
- );
22810
- } else {
22811
- const meResult = await validateApiKey(apiKey, apiBase);
22812
- const meTeamId = meResult.teamId ? parseInt(meResult.teamId, 10) : NaN;
22813
- if (!Number.isNaN(meTeamId) && teams.some((t) => t.id === meTeamId)) {
22814
- resolvedTeamId = String(meTeamId);
22815
- reporter.info(
22816
- `Org-mode account detected. Using sub-team ${meTeamId} (from /me) for Bifrost calls.`
22817
- );
22818
- }
22819
- }
22820
- }
22821
- } catch {
23172
+ const createdIdentity = await validateApiKey(apiKey, apiBase);
23173
+ if (!createdIdentity.valid) {
23174
+ throw new Error("The explicitly created postman-api-key could not be validated; refusing linking writes.");
22822
23175
  }
23176
+ pmakIdentity = { source: "pmak/me", teamId: createdIdentity.teamId };
23177
+ reporter.info(`New API key created successfully (${keyName}).`);
22823
23178
  }
22824
- if (resolvedTeamId) {
22825
- reporter.info(`Using postman-team-id for Bifrost headers: ${resolvedTeamId}`);
23179
+ if (teamId) {
23180
+ reporter.info(`Using explicit postman-team-id for Bifrost headers: ${teamId}`);
22826
23181
  } else {
22827
- reporter.info("No postman-team-id resolved; omitting x-entity-team-id so Bifrost resolves team from the access token.");
23182
+ reporter.info(
23183
+ "No postman-team-id / POSTMAN_TEAM_ID provided; omitting x-entity-team-id so Bifrost resolves team from the access token."
23184
+ );
22828
23185
  }
22829
- return { apiKey, teamId: resolvedTeamId, pmakIdentity };
23186
+ return { apiKey, teamId, pmakIdentity };
22830
23187
  }
22831
23188
  async function runCredentialPreflightForInputs(inputs, pmak, reporter, fetchImpl, liveAccessToken) {
22832
23189
  const accessToken = liveAccessToken ?? inputs.postmanAccessToken;
@@ -22884,24 +23241,54 @@ async function runAction() {
22884
23241
  inputs.postmanTeamId,
22885
23242
  inputs.postmanApiKey
22886
23243
  );
22887
- const { apiKey, teamId, pmakIdentity } = await resolveApiKeyAndTeamId(inputs, preliminaryClient, core_exports);
22888
- const activeTokenProvider = apiKey !== inputs.postmanApiKey ? new AccessTokenProvider({
22889
- accessToken: tokenProvider.current(),
22890
- apiKey,
22891
- apiBaseUrl: inputs.postmanApiBase || DEFAULT_POSTMAN_API_BASE,
22892
- onToken: (token) => setSecret(token)
22893
- }) : tokenProvider;
22894
23244
  const telemetry = createTelemetryContext({ action: "postman-insights-onboarding-action", actionVersion: resolveActionVersion2(), logger: core_exports });
22895
- telemetry.setTeamId(inputs.postmanTeamId || pmakIdentity?.teamId);
23245
+ telemetry.setTeamId(inputs.postmanTeamId);
22896
23246
  let result;
22897
23247
  try {
23248
+ let apiKey = inputs.postmanApiKey;
23249
+ let pmakIdentity;
23250
+ const apiBase = inputs.postmanApiBase || DEFAULT_POSTMAN_API_BASE;
23251
+ if (apiKey) {
23252
+ const validated = await validateApiKey(apiKey, apiBase);
23253
+ if (validated.valid) {
23254
+ pmakIdentity = { source: "pmak/me", teamId: validated.teamId };
23255
+ } else if (!inputs.createApiKey) {
23256
+ throw new Error(
23257
+ "postman-api-key is invalid or expired. Provide a valid key, or set create-api-key=true to opt in to durable Bifrost API-key creation."
23258
+ );
23259
+ } else {
23260
+ warning("Provided postman-api-key is invalid or expired.");
23261
+ }
23262
+ } else if (!inputs.createApiKey) {
23263
+ throw new Error(
23264
+ "postman-api-key is required for application binding. Provide a valid key, or set create-api-key=true to opt in to durable Bifrost API-key creation."
23265
+ );
23266
+ }
22898
23267
  await runCredentialPreflightForInputs(
22899
23268
  inputs,
22900
23269
  pmakIdentity,
22901
23270
  core_exports,
22902
23271
  void 0,
22903
- activeTokenProvider.current()
23272
+ tokenProvider.current()
22904
23273
  );
23274
+ const resolved = await resolveApiKeyAndTeamId(inputs, preliminaryClient, core_exports);
23275
+ apiKey = resolved.apiKey;
23276
+ const teamId = resolved.teamId;
23277
+ if (resolved.pmakIdentity?.teamId !== pmakIdentity?.teamId) {
23278
+ await runCredentialPreflightForInputs(
23279
+ inputs,
23280
+ resolved.pmakIdentity,
23281
+ core_exports,
23282
+ void 0,
23283
+ tokenProvider.current()
23284
+ );
23285
+ }
23286
+ const activeTokenProvider = apiKey !== inputs.postmanApiKey ? new AccessTokenProvider({
23287
+ accessToken: tokenProvider.current(),
23288
+ apiKey,
23289
+ apiBaseUrl: inputs.postmanApiBase || DEFAULT_POSTMAN_API_BASE,
23290
+ onToken: (token) => setSecret(token)
23291
+ }) : tokenProvider;
22905
23292
  const client = createInsightsBifrostClient(inputs, activeTokenProvider, teamId, apiKey);
22906
23293
  result = await runOnboarding(inputs, client, sleep, core_exports);
22907
23294
  } catch (error2) {
@@ -22936,8 +23323,11 @@ async function runAction() {
22936
23323
  createInsightsBifrostClient,
22937
23324
  createInsightsTokenProvider,
22938
23325
  createPlannedOutputs,
23326
+ getInput,
22939
23327
  getTeams,
23328
+ parseCreateApiKey,
22940
23329
  parsePreflightMode,
23330
+ parseServiceNotFoundPolicy,
22941
23331
  resolveApiKeyAndTeamId,
22942
23332
  resolveInputs,
22943
23333
  runAction,