@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/README.md +15 -13
- package/action.yml +3 -3
- package/dist/action.cjs +269 -43
- package/dist/cli.cjs +361 -135
- package/dist/index.cjs +273 -43
- package/package.json +3 -3
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
|
|
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(
|
|
12314
|
-
Object.defineProperties(
|
|
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(
|
|
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
|
|
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(
|
|
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
|
-
|
|
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.
|
|
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 = [
|
|
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.
|
|
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.
|
|
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
|
|
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
|
|
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
|
-
|
|
21707
|
-
|
|
21708
|
-
|
|
21709
|
-
|
|
21710
|
-
|
|
21711
|
-
|
|
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
|
-
|
|
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 "
|
|
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:
|
|
22652
|
+
postmanAccessToken: accessToken,
|
|
22450
22653
|
explicitTeamId: inputs.postmanTeamId || void 0,
|
|
22451
22654
|
mode: inputs.credentialPreflight,
|
|
22452
|
-
mask: createSecretMasker([inputs.postmanApiKey,
|
|
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
|
|
22569
|
-
|
|
22570
|
-
|
|
22571
|
-
|
|
22572
|
-
|
|
22573
|
-
|
|
22574
|
-
|
|
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(
|
|
22589
|
-
|
|
22590
|
-
|
|
22591
|
-
|
|
22592
|
-
|
|
22593
|
-
|
|
22594
|
-
|
|
22595
|
-
|
|
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,
|