@postman-cse/onboarding-repo-sync 2.1.10 → 2.1.13
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 +1 -1
- package/dist/action.cjs +314 -79
- package/dist/cli.cjs +314 -79
- package/dist/index.cjs +314 -79
- package/package.json +4 -3
- package/scripts/verify-release-artifacts.mjs +239 -0
package/dist/action.cjs
CHANGED
|
@@ -19745,7 +19745,7 @@ var require_response = __commonJS({
|
|
|
19745
19745
|
var assert = require("node:assert");
|
|
19746
19746
|
var { isomorphicEncode, serializeJavascriptValueToJSONString } = require_infra();
|
|
19747
19747
|
var textEncoder = new TextEncoder("utf-8");
|
|
19748
|
-
var
|
|
19748
|
+
var Response2 = class _Response {
|
|
19749
19749
|
/** @type {Headers} */
|
|
19750
19750
|
#headers;
|
|
19751
19751
|
#state;
|
|
@@ -19915,13 +19915,13 @@ var require_response = __commonJS({
|
|
|
19915
19915
|
response.#state = newState;
|
|
19916
19916
|
}
|
|
19917
19917
|
};
|
|
19918
|
-
var { getResponseHeaders, setResponseHeaders, getResponseState, setResponseState } =
|
|
19919
|
-
Reflect.deleteProperty(
|
|
19920
|
-
Reflect.deleteProperty(
|
|
19921
|
-
Reflect.deleteProperty(
|
|
19922
|
-
Reflect.deleteProperty(
|
|
19923
|
-
mixinBody(
|
|
19924
|
-
Object.defineProperties(
|
|
19918
|
+
var { getResponseHeaders, setResponseHeaders, getResponseState, setResponseState } = Response2;
|
|
19919
|
+
Reflect.deleteProperty(Response2, "getResponseHeaders");
|
|
19920
|
+
Reflect.deleteProperty(Response2, "setResponseHeaders");
|
|
19921
|
+
Reflect.deleteProperty(Response2, "getResponseState");
|
|
19922
|
+
Reflect.deleteProperty(Response2, "setResponseState");
|
|
19923
|
+
mixinBody(Response2, getResponseState);
|
|
19924
|
+
Object.defineProperties(Response2.prototype, {
|
|
19925
19925
|
type: kEnumerableProperty,
|
|
19926
19926
|
url: kEnumerableProperty,
|
|
19927
19927
|
status: kEnumerableProperty,
|
|
@@ -19937,7 +19937,7 @@ var require_response = __commonJS({
|
|
|
19937
19937
|
configurable: true
|
|
19938
19938
|
}
|
|
19939
19939
|
});
|
|
19940
|
-
Object.defineProperties(
|
|
19940
|
+
Object.defineProperties(Response2, {
|
|
19941
19941
|
json: kEnumerableProperty,
|
|
19942
19942
|
redirect: kEnumerableProperty,
|
|
19943
19943
|
error: kEnumerableProperty
|
|
@@ -20070,7 +20070,7 @@ var require_response = __commonJS({
|
|
|
20070
20070
|
}
|
|
20071
20071
|
}
|
|
20072
20072
|
function fromInnerResponse(innerResponse, guard) {
|
|
20073
|
-
const response = new
|
|
20073
|
+
const response = new Response2(kConstruct);
|
|
20074
20074
|
setResponseState(response, innerResponse);
|
|
20075
20075
|
const headers = new Headers3(kConstruct);
|
|
20076
20076
|
setResponseHeaders(response, headers);
|
|
@@ -20124,14 +20124,14 @@ var require_response = __commonJS({
|
|
|
20124
20124
|
converter: webidl.converters.HeadersInit
|
|
20125
20125
|
}
|
|
20126
20126
|
]);
|
|
20127
|
-
webidl.is.Response = webidl.util.MakeTypeAssertion(
|
|
20127
|
+
webidl.is.Response = webidl.util.MakeTypeAssertion(Response2);
|
|
20128
20128
|
module2.exports = {
|
|
20129
20129
|
isNetworkError,
|
|
20130
20130
|
makeNetworkError,
|
|
20131
20131
|
makeResponse,
|
|
20132
20132
|
makeAppropriateNetworkError,
|
|
20133
20133
|
filterResponse,
|
|
20134
|
-
Response,
|
|
20134
|
+
Response: Response2,
|
|
20135
20135
|
cloneResponse,
|
|
20136
20136
|
fromInnerResponse,
|
|
20137
20137
|
getResponseState
|
|
@@ -99439,7 +99439,7 @@ var require_response2 = __commonJS({
|
|
|
99439
99439
|
}
|
|
99440
99440
|
return stream;
|
|
99441
99441
|
};
|
|
99442
|
-
var
|
|
99442
|
+
var Response2;
|
|
99443
99443
|
_.inherit(
|
|
99444
99444
|
/**
|
|
99445
99445
|
* Response holds data related to the request body. By default, it provides a nice wrapper for url-encoded,
|
|
@@ -99450,14 +99450,14 @@ var require_response2 = __commonJS({
|
|
|
99450
99450
|
*
|
|
99451
99451
|
* @param {Response.definition} options -
|
|
99452
99452
|
*/
|
|
99453
|
-
|
|
99454
|
-
|
|
99453
|
+
Response2 = function PostmanResponse(options) {
|
|
99454
|
+
Response2.super_.apply(this, arguments);
|
|
99455
99455
|
this.update(options || {});
|
|
99456
99456
|
},
|
|
99457
99457
|
Property
|
|
99458
99458
|
);
|
|
99459
99459
|
_.assign(
|
|
99460
|
-
|
|
99460
|
+
Response2.prototype,
|
|
99461
99461
|
/** @lends Response.prototype */
|
|
99462
99462
|
{
|
|
99463
99463
|
update(options) {
|
|
@@ -99523,7 +99523,7 @@ var require_response2 = __commonJS({
|
|
|
99523
99523
|
}
|
|
99524
99524
|
);
|
|
99525
99525
|
_.assign(
|
|
99526
|
-
|
|
99526
|
+
Response2.prototype,
|
|
99527
99527
|
/** @lends Response.prototype */
|
|
99528
99528
|
{
|
|
99529
99529
|
/**
|
|
@@ -99701,7 +99701,7 @@ var require_response2 = __commonJS({
|
|
|
99701
99701
|
}
|
|
99702
99702
|
);
|
|
99703
99703
|
_.assign(
|
|
99704
|
-
|
|
99704
|
+
Response2,
|
|
99705
99705
|
/** @lends Response */
|
|
99706
99706
|
{
|
|
99707
99707
|
/**
|
|
@@ -99719,7 +99719,7 @@ var require_response2 = __commonJS({
|
|
|
99719
99719
|
* @returns {Boolean}
|
|
99720
99720
|
*/
|
|
99721
99721
|
isResponse: function(obj) {
|
|
99722
|
-
return Boolean(obj) && (obj instanceof
|
|
99722
|
+
return Boolean(obj) && (obj instanceof Response2 || _.inSuperChain(obj.constructor, "_postman_propertyName", Response2._postman_propertyName));
|
|
99723
99723
|
},
|
|
99724
99724
|
/**
|
|
99725
99725
|
* Converts the response object from the request module to the postman responseBody format
|
|
@@ -99730,7 +99730,7 @@ var require_response2 = __commonJS({
|
|
|
99730
99730
|
* @todo Add a key: `originalRequest` to the returned object as well, referring to response.request
|
|
99731
99731
|
*/
|
|
99732
99732
|
createFromNode: function(response, cookies) {
|
|
99733
|
-
return new
|
|
99733
|
+
return new Response2({
|
|
99734
99734
|
cookie: cookies,
|
|
99735
99735
|
body: response.body.toString(),
|
|
99736
99736
|
stream: response.body,
|
|
@@ -99809,7 +99809,7 @@ var require_response2 = __commonJS({
|
|
|
99809
99809
|
}
|
|
99810
99810
|
);
|
|
99811
99811
|
module2.exports = {
|
|
99812
|
-
Response
|
|
99812
|
+
Response: Response2
|
|
99813
99813
|
};
|
|
99814
99814
|
}
|
|
99815
99815
|
});
|
|
@@ -99823,7 +99823,7 @@ var require_item = __commonJS({
|
|
|
99823
99823
|
var EventList = require_event_list().EventList;
|
|
99824
99824
|
var Request = require_request13().Request;
|
|
99825
99825
|
var RequestAuth = require_request_auth().RequestAuth;
|
|
99826
|
-
var
|
|
99826
|
+
var Response2 = require_response2().Response;
|
|
99827
99827
|
var Item;
|
|
99828
99828
|
var OBJECT = "object";
|
|
99829
99829
|
var STRING = "string";
|
|
@@ -99890,7 +99890,7 @@ var require_item = __commonJS({
|
|
|
99890
99890
|
*
|
|
99891
99891
|
* @type {PropertyList<Response>}
|
|
99892
99892
|
*/
|
|
99893
|
-
responses: new PropertyList(
|
|
99893
|
+
responses: new PropertyList(Response2, this, definition && definition.response),
|
|
99894
99894
|
/**
|
|
99895
99895
|
* Events are a set of of {@link Script}s that are executed when certain activities are triggered on an
|
|
99896
99896
|
* Item. For example, on defining an event that listens to the "test" event, would cause the associated
|
|
@@ -135557,6 +135557,54 @@ var HttpError = class _HttpError extends Error {
|
|
|
135557
135557
|
}
|
|
135558
135558
|
};
|
|
135559
135559
|
|
|
135560
|
+
// src/lib/postman/pmak-diagnostics.ts
|
|
135561
|
+
var memo = /* @__PURE__ */ new Map();
|
|
135562
|
+
var normalize3 = (value) => new URL(value.trim()).toString().replace(/\/+$/, "");
|
|
135563
|
+
function maskPmakDiagnostic(message, secrets) {
|
|
135564
|
+
let masked = String(message);
|
|
135565
|
+
for (const secret of secrets) if (secret) masked = masked.split(secret).join("***");
|
|
135566
|
+
return Array.from(masked, (character) => {
|
|
135567
|
+
const code = character.codePointAt(0) ?? 0;
|
|
135568
|
+
return code <= 31 || code >= 127 && code <= 159 ? " " : character;
|
|
135569
|
+
}).join("").replace(/\s+/g, " ").trim();
|
|
135570
|
+
}
|
|
135571
|
+
function formatRejectedMint(original, result) {
|
|
135572
|
+
const teamId = typeof result.payload?.user?.teamId === "number" ? ` (team ${(result.payload?.user).teamId})` : "";
|
|
135573
|
+
if (result.kind === "personal") return `Personal API key detected, cannot mint a service-account access token${teamId}.`;
|
|
135574
|
+
if (result.kind === "service-account") return `The postman-api-key authenticates (GET /me OK) but was rejected by POST /service-account-tokens${teamId} and lacks permission to mint access tokens.`;
|
|
135575
|
+
if (result.kind === "invalid") return "The postman-api-key is invalid, disabled, or expired.";
|
|
135576
|
+
return original;
|
|
135577
|
+
}
|
|
135578
|
+
async function inspectPmakIdentity(options) {
|
|
135579
|
+
const apiBaseUrl = normalize3(options.apiBaseUrl);
|
|
135580
|
+
const key = `${apiBaseUrl}\0${options.apiKey}`;
|
|
135581
|
+
let pending = memo.get(key);
|
|
135582
|
+
if (!pending) {
|
|
135583
|
+
pending = (async () => {
|
|
135584
|
+
try {
|
|
135585
|
+
const timeout = AbortSignal.timeout(options.timeoutMs ?? 2e3);
|
|
135586
|
+
const signal = options.signal ? AbortSignal.any([options.signal, timeout]) : timeout;
|
|
135587
|
+
const response = await (options.fetchImpl ?? fetch)(`${apiBaseUrl}/me`, { method: "GET", headers: { "X-Api-Key": options.apiKey }, signal });
|
|
135588
|
+
if (response.status === 401 || response.status === 403) return { kind: "invalid", status: response.status };
|
|
135589
|
+
if (!response.ok) return { kind: "inconclusive", status: response.status };
|
|
135590
|
+
const payload = await response.json().catch(() => void 0);
|
|
135591
|
+
const user = payload?.user;
|
|
135592
|
+
if (!user || typeof user !== "object" || Array.isArray(user)) return { kind: "inconclusive", payload };
|
|
135593
|
+
const record = user;
|
|
135594
|
+
if (typeof record.username === "string" && record.username || typeof record.email === "string" && record.email) return { kind: "personal", status: response.status, payload };
|
|
135595
|
+
if ("username" in record && "email" in record && (record.username == null || record.username === "") && (record.email == null || record.email === "")) return { kind: "service-account", status: response.status, payload };
|
|
135596
|
+
return { kind: "inconclusive", payload };
|
|
135597
|
+
} catch {
|
|
135598
|
+
return { kind: "inconclusive" };
|
|
135599
|
+
}
|
|
135600
|
+
})();
|
|
135601
|
+
memo.set(key, pending);
|
|
135602
|
+
}
|
|
135603
|
+
const result = await pending;
|
|
135604
|
+
if (options.mode === "preflight" && result.kind === "inconclusive") memo.delete(key);
|
|
135605
|
+
return result;
|
|
135606
|
+
}
|
|
135607
|
+
|
|
135560
135608
|
// src/lib/postman/credential-identity.ts
|
|
135561
135609
|
var sessionPath = "/api/sessions/current";
|
|
135562
135610
|
var SESSION_MAX_ATTEMPTS = 3;
|
|
@@ -135650,14 +135698,8 @@ async function resolvePmakIdentity(opts) {
|
|
|
135650
135698
|
}
|
|
135651
135699
|
async function probePmakIdentity(baseUrl, apiKey, fetchImpl) {
|
|
135652
135700
|
try {
|
|
135653
|
-
const
|
|
135654
|
-
|
|
135655
|
-
headers: { "X-Api-Key": apiKey }
|
|
135656
|
-
});
|
|
135657
|
-
if (!response.ok) {
|
|
135658
|
-
return void 0;
|
|
135659
|
-
}
|
|
135660
|
-
const payload = asRecord(await response.json());
|
|
135701
|
+
const diagnostic = await inspectPmakIdentity({ apiBaseUrl: baseUrl, apiKey, fetchImpl });
|
|
135702
|
+
const payload = asRecord(diagnostic.payload);
|
|
135661
135703
|
const user = asRecord(payload?.user);
|
|
135662
135704
|
if (!user) {
|
|
135663
135705
|
return void 0;
|
|
@@ -135959,6 +136001,39 @@ function adviseFromHttpError(err, ctx) {
|
|
|
135959
136001
|
return new Error(ctx.mask(advice), { cause: err });
|
|
135960
136002
|
}
|
|
135961
136003
|
|
|
136004
|
+
// src/lib/postman/app-version.ts
|
|
136005
|
+
var UPDATE_URL = "https://dl.pstmn.io/update/status?currentVersion=12.0.0&platform=osx_arm64";
|
|
136006
|
+
var FLOOR_VERSION = "12.0.0";
|
|
136007
|
+
var VERSION_PATTERN = /^[0-9]+\.[0-9]+\.[0-9]+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;
|
|
136008
|
+
var PostmanAppVersionProvider = class {
|
|
136009
|
+
fetchImpl;
|
|
136010
|
+
requestTimeoutMs;
|
|
136011
|
+
pending;
|
|
136012
|
+
constructor(options = {}) {
|
|
136013
|
+
this.fetchImpl = options.fetchImpl ?? fetch;
|
|
136014
|
+
this.requestTimeoutMs = options.requestTimeoutMs ?? 2e3;
|
|
136015
|
+
}
|
|
136016
|
+
async get() {
|
|
136017
|
+
if (process.env.POSTMAN_GATEWAY_APP_VERSION === "off") return void 0;
|
|
136018
|
+
this.pending ??= this.resolve();
|
|
136019
|
+
return this.pending;
|
|
136020
|
+
}
|
|
136021
|
+
async resolve() {
|
|
136022
|
+
try {
|
|
136023
|
+
const response = await this.fetchImpl(UPDATE_URL, {
|
|
136024
|
+
signal: AbortSignal.timeout(this.requestTimeoutMs)
|
|
136025
|
+
});
|
|
136026
|
+
if (!response.ok) return FLOOR_VERSION;
|
|
136027
|
+
const payload = await response.json();
|
|
136028
|
+
const version = typeof payload.version === "string" ? payload.version : "";
|
|
136029
|
+
return VERSION_PATTERN.test(version) ? version : FLOOR_VERSION;
|
|
136030
|
+
} catch {
|
|
136031
|
+
return FLOOR_VERSION;
|
|
136032
|
+
}
|
|
136033
|
+
}
|
|
136034
|
+
};
|
|
136035
|
+
var defaultPostmanAppVersionProvider = new PostmanAppVersionProvider();
|
|
136036
|
+
|
|
135962
136037
|
// src/lib/postman/internal-integration-adapter.ts
|
|
135963
136038
|
function extractDuplicateWorkspaceId(body) {
|
|
135964
136039
|
try {
|
|
@@ -135978,6 +136053,8 @@ var BifrostInternalIntegrationAdapter = class {
|
|
|
135978
136053
|
secretMasker;
|
|
135979
136054
|
teamId;
|
|
135980
136055
|
workerBaseUrl;
|
|
136056
|
+
gateway;
|
|
136057
|
+
appVersionProvider;
|
|
135981
136058
|
constructor(options) {
|
|
135982
136059
|
this.accessToken = String(options.accessToken || "").trim();
|
|
135983
136060
|
this.getAccessToken = options.getAccessToken;
|
|
@@ -135990,6 +136067,8 @@ var BifrostInternalIntegrationAdapter = class {
|
|
|
135990
136067
|
this.workerBaseUrl = String(
|
|
135991
136068
|
options.workerBaseUrl || "https://catalog-admin.postman-account2009.workers.dev"
|
|
135992
136069
|
).replace(/\/+$/, "");
|
|
136070
|
+
this.gateway = options.gateway;
|
|
136071
|
+
this.appVersionProvider = options.appVersionProvider ?? defaultPostmanAppVersionProvider;
|
|
135993
136072
|
this.secretMasker = options.secretMasker ?? createSecretMasker([this.accessToken]);
|
|
135994
136073
|
}
|
|
135995
136074
|
/** Live access token: re-minted value when a provider accessor is wired, else the captured one. */
|
|
@@ -135997,7 +136076,7 @@ var BifrostInternalIntegrationAdapter = class {
|
|
|
135997
136076
|
return this.getAccessToken ? String(this.getAccessToken() || "").trim() : this.accessToken;
|
|
135998
136077
|
}
|
|
135999
136078
|
/** Build Bifrost proxy headers. Only includes x-entity-team-id for org-mode teams. */
|
|
136000
|
-
bifrostHeaders() {
|
|
136079
|
+
async bifrostHeaders() {
|
|
136001
136080
|
const headers = {
|
|
136002
136081
|
"Content-Type": "application/json",
|
|
136003
136082
|
"x-access-token": this.currentToken()
|
|
@@ -136005,6 +136084,8 @@ var BifrostInternalIntegrationAdapter = class {
|
|
|
136005
136084
|
if (this.teamId && this.orgMode) {
|
|
136006
136085
|
headers["x-entity-team-id"] = this.teamId;
|
|
136007
136086
|
}
|
|
136087
|
+
const appVersion = await this.appVersionProvider.get();
|
|
136088
|
+
if (appVersion) headers["x-app-version"] = appVersion;
|
|
136008
136089
|
return headers;
|
|
136009
136090
|
}
|
|
136010
136091
|
/** Reactive error-advice context, enriched with the preflight session memo when present. */
|
|
@@ -136035,6 +136116,58 @@ var BifrostInternalIntegrationAdapter = class {
|
|
|
136035
136116
|
if (associations.length === 0) {
|
|
136036
136117
|
return;
|
|
136037
136118
|
}
|
|
136119
|
+
const mode = process.env.POSTMAN_SYSTEM_ENV_ASSOCIATION_MODE ?? "direct";
|
|
136120
|
+
if (mode !== "direct" && mode !== "worker") {
|
|
136121
|
+
throw new Error("POSTMAN_SYSTEM_ENV_ASSOCIATION_MODE must be direct or worker");
|
|
136122
|
+
}
|
|
136123
|
+
if (mode === "direct") {
|
|
136124
|
+
if (!this.gateway) {
|
|
136125
|
+
throw new Error("Direct system-environment association requires the access-token gateway");
|
|
136126
|
+
}
|
|
136127
|
+
const groups = /* @__PURE__ */ new Map();
|
|
136128
|
+
for (const association of associations) {
|
|
136129
|
+
const systemEnvId = String(association.systemEnvId || "").trim();
|
|
136130
|
+
const uid = String(association.envUid || "").trim();
|
|
136131
|
+
if (!systemEnvId || !uid) continue;
|
|
136132
|
+
const key = `${systemEnvId}\0${workspaceId}`;
|
|
136133
|
+
const uids = groups.get(key) ?? /* @__PURE__ */ new Set();
|
|
136134
|
+
uids.add(uid);
|
|
136135
|
+
groups.set(key, uids);
|
|
136136
|
+
}
|
|
136137
|
+
for (const [key, uids] of [...groups.entries()].sort(([a], [b]) => a.localeCompare(b))) {
|
|
136138
|
+
const [systemEnvironmentId, groupedWorkspaceId] = key.split("\0");
|
|
136139
|
+
const postmanEnvironmentIds = [...uids].sort();
|
|
136140
|
+
let response2;
|
|
136141
|
+
try {
|
|
136142
|
+
response2 = await this.gateway.requestJson({
|
|
136143
|
+
service: "api-catalog",
|
|
136144
|
+
method: "post",
|
|
136145
|
+
path: "/api/system-envs/associations",
|
|
136146
|
+
body: {
|
|
136147
|
+
systemEnvironmentId,
|
|
136148
|
+
workspaceEntries: [{ workspaceId: groupedWorkspaceId, postmanEnvironmentIds }]
|
|
136149
|
+
},
|
|
136150
|
+
fallback: "none"
|
|
136151
|
+
}, { retryTransient: true });
|
|
136152
|
+
} catch (error2) {
|
|
136153
|
+
if (error2 instanceof HttpError) {
|
|
136154
|
+
throw adviseFromHttpError(error2, this.adviceContext("system environment association")) ?? error2;
|
|
136155
|
+
}
|
|
136156
|
+
throw error2;
|
|
136157
|
+
}
|
|
136158
|
+
if (!response2 || response2.success !== true) {
|
|
136159
|
+
throw new Error("SYSTEM_ENV_ASSOCIATION_INCOMPLETE");
|
|
136160
|
+
}
|
|
136161
|
+
if (response2.data !== void 0) {
|
|
136162
|
+
if (!Array.isArray(response2.data)) throw new Error("SYSTEM_ENV_ASSOCIATION_INCOMPLETE");
|
|
136163
|
+
const seen = new Set(response2.data.filter((row) => !!row && typeof row === "object").map((row) => `${row.systemEnvironmentId}\0${row.workspaceId}\0${row.postmanEnvironmentId}`));
|
|
136164
|
+
if (!postmanEnvironmentIds.every((uid) => seen.has(`${systemEnvironmentId}\0${groupedWorkspaceId}\0${uid}`))) {
|
|
136165
|
+
throw new Error("SYSTEM_ENV_ASSOCIATION_INCOMPLETE");
|
|
136166
|
+
}
|
|
136167
|
+
}
|
|
136168
|
+
}
|
|
136169
|
+
return;
|
|
136170
|
+
}
|
|
136038
136171
|
const token = this.currentToken();
|
|
136039
136172
|
const response = await this.fetchImpl(
|
|
136040
136173
|
`${this.workerBaseUrl}/api/internal/system-envs/associate`,
|
|
@@ -136092,7 +136225,7 @@ var BifrostInternalIntegrationAdapter = class {
|
|
|
136092
136225
|
try {
|
|
136093
136226
|
const response = await this.fetchImpl(url, {
|
|
136094
136227
|
method: "POST",
|
|
136095
|
-
headers: this.bifrostHeaders(),
|
|
136228
|
+
headers: await this.bifrostHeaders(),
|
|
136096
136229
|
body: JSON.stringify(payload)
|
|
136097
136230
|
});
|
|
136098
136231
|
let parsed = {};
|
|
@@ -136181,7 +136314,7 @@ var BifrostInternalIntegrationAdapter = class {
|
|
|
136181
136314
|
versionControl: true
|
|
136182
136315
|
}
|
|
136183
136316
|
};
|
|
136184
|
-
const headers = this.bifrostHeaders();
|
|
136317
|
+
const headers = await this.bifrostHeaders();
|
|
136185
136318
|
const response = await this.fetchImpl(url, {
|
|
136186
136319
|
method: "POST",
|
|
136187
136320
|
headers,
|
|
@@ -136236,7 +136369,7 @@ var BifrostInternalIntegrationAdapter = class {
|
|
|
136236
136369
|
try {
|
|
136237
136370
|
const response = await this.fetchImpl(`${this.bifrostBaseUrl}/ws/proxy`, {
|
|
136238
136371
|
method: "POST",
|
|
136239
|
-
headers: this.bifrostHeaders(),
|
|
136372
|
+
headers: await this.bifrostHeaders(),
|
|
136240
136373
|
body: JSON.stringify({
|
|
136241
136374
|
service: "workspaces",
|
|
136242
136375
|
method: "GET",
|
|
@@ -136267,7 +136400,7 @@ var BifrostInternalIntegrationAdapter = class {
|
|
|
136267
136400
|
}
|
|
136268
136401
|
async createApiKey(name) {
|
|
136269
136402
|
const url = `${this.bifrostBaseUrl}/ws/proxy`;
|
|
136270
|
-
const headers = this.bifrostHeaders();
|
|
136403
|
+
const headers = await this.bifrostHeaders();
|
|
136271
136404
|
const payload = {
|
|
136272
136405
|
service: "identity",
|
|
136273
136406
|
method: "POST",
|
|
@@ -136352,6 +136485,16 @@ async function retry(operation, options = {}) {
|
|
|
136352
136485
|
}
|
|
136353
136486
|
throw new Error("Retry exhausted without returning or throwing");
|
|
136354
136487
|
}
|
|
136488
|
+
function fullJitterDelayMs(attempt, baseMs, capMs, random = Math.random) {
|
|
136489
|
+
return Math.floor(random() * Math.max(0, Math.min(capMs, baseMs * 2 ** Math.max(0, attempt))));
|
|
136490
|
+
}
|
|
136491
|
+
function parseRetryAfterMs2(value) {
|
|
136492
|
+
const trimmed = value?.trim();
|
|
136493
|
+
if (!trimmed) return void 0;
|
|
136494
|
+
if (/^\d+$/.test(trimmed)) return Number(trimmed) * 1e3;
|
|
136495
|
+
const time = Date.parse(trimmed);
|
|
136496
|
+
return Number.isNaN(time) ? void 0 : Math.max(0, time - Date.now());
|
|
136497
|
+
}
|
|
136355
136498
|
|
|
136356
136499
|
// src/contracts.ts
|
|
136357
136500
|
var postmanRepoSyncActionContract = {
|
|
@@ -136781,6 +136924,17 @@ var PostmanGatewayAssetsClient = class {
|
|
|
136781
136924
|
return data.map((entry) => this.asRecord(entry)).filter((entry) => entry !== null).map((entry) => ({ uid: String(entry.id ?? entry.uid ?? "").trim(), name: String(entry.name ?? "").trim() })).filter((entry) => entry.uid && entry.name);
|
|
136782
136925
|
}
|
|
136783
136926
|
async getSpecContent(specId) {
|
|
136927
|
+
if (process.env.POSTMAN_SPEC_TREE_FAST_PATH !== "off") {
|
|
136928
|
+
try {
|
|
136929
|
+
const treeContent = await this.getSpecContentFromTree(specId);
|
|
136930
|
+
if (treeContent !== void 0) return treeContent;
|
|
136931
|
+
} catch (error2) {
|
|
136932
|
+
if (!(error2 instanceof HttpError) || ![403, 404, 405, 501].includes(error2.status)) throw error2;
|
|
136933
|
+
}
|
|
136934
|
+
}
|
|
136935
|
+
return this.getSpecContentLegacy(specId);
|
|
136936
|
+
}
|
|
136937
|
+
async getSpecContentLegacy(specId) {
|
|
136784
136938
|
const files = await this.gateway.requestJson({
|
|
136785
136939
|
service: "specification",
|
|
136786
136940
|
method: "get",
|
|
@@ -136799,6 +136953,46 @@ var PostmanGatewayAssetsClient = class {
|
|
|
136799
136953
|
const record = this.dataOf(file);
|
|
136800
136954
|
return typeof record?.content === "string" ? record.content : void 0;
|
|
136801
136955
|
}
|
|
136956
|
+
/** Minimal `/tree` reader: validate the entire returned inventory before selecting ROOT. */
|
|
136957
|
+
async getSpecContentFromTree(specId) {
|
|
136958
|
+
const rows = [];
|
|
136959
|
+
const cursors = /* @__PURE__ */ new Set();
|
|
136960
|
+
let cursor;
|
|
136961
|
+
for (let page = 0; page < 100; page += 1) {
|
|
136962
|
+
const response = await this.gateway.requestJson({
|
|
136963
|
+
service: "specification",
|
|
136964
|
+
method: "get",
|
|
136965
|
+
path: `/specifications/${specId}/tree`,
|
|
136966
|
+
query: { fields: "id,name,type,path,parentId,fileType,content", limit: 100, ...cursor ? { cursor } : {} }
|
|
136967
|
+
});
|
|
136968
|
+
if (!Array.isArray(response?.data)) return void 0;
|
|
136969
|
+
for (const value of response.data) {
|
|
136970
|
+
const row = this.asRecord(value);
|
|
136971
|
+
if (!row || row.type === "FOLDER") continue;
|
|
136972
|
+
if (row.type !== "FILE" || typeof row.id !== "string" || !row.id.trim() || typeof row.path !== "string" || !row.path.trim() || typeof row.content !== "string" || typeof row.fileType !== "string" || !row.fileType.trim()) return void 0;
|
|
136973
|
+
const path9 = row.path.replace(/\\/g, "/").normalize("NFC");
|
|
136974
|
+
if (path9.startsWith("/") || path9.split("/").some((part) => part === ".." || !part)) throw new Error("CONTRACT_DEFINITION_PATH_INVALID");
|
|
136975
|
+
rows.push({ ...row, path: path9 });
|
|
136976
|
+
}
|
|
136977
|
+
const meta = this.asRecord(response?.meta);
|
|
136978
|
+
const cursorValue = this.asRecord(meta?.cursor)?.next;
|
|
136979
|
+
const next = typeof cursorValue === "string" && cursorValue.trim() ? cursorValue.trim() : void 0;
|
|
136980
|
+
if (!next) break;
|
|
136981
|
+
if (cursors.has(next)) throw new Error("SPEC_TREE_CURSOR_REPEATED");
|
|
136982
|
+
cursors.add(next);
|
|
136983
|
+
if (page === 99) throw new Error("SPEC_TREE_PAGE_LIMIT_EXCEEDED");
|
|
136984
|
+
cursor = next;
|
|
136985
|
+
}
|
|
136986
|
+
const paths = /* @__PURE__ */ new Set();
|
|
136987
|
+
for (const row of rows) {
|
|
136988
|
+
const path9 = String(row.path).toLocaleLowerCase();
|
|
136989
|
+
if (paths.has(path9)) throw new Error("CONTRACT_DEFINITION_DUPLICATE_PATH");
|
|
136990
|
+
paths.add(path9);
|
|
136991
|
+
}
|
|
136992
|
+
const roots = rows.filter((row) => row.fileType === "ROOT");
|
|
136993
|
+
if (roots.length !== 1) throw new Error("CONTRACT_DEFINITION_INVENTORY_INVALID");
|
|
136994
|
+
return String(roots[0]?.content);
|
|
136995
|
+
}
|
|
136802
136996
|
async listSpecCollections(specId) {
|
|
136803
136997
|
const response = await this.gateway.requestJson({
|
|
136804
136998
|
service: "specification",
|
|
@@ -137358,10 +137552,12 @@ var PostmanGatewayAssetsClient = class {
|
|
|
137358
137552
|
// src/lib/postman/token-provider.ts
|
|
137359
137553
|
var MintError = class extends Error {
|
|
137360
137554
|
permanent;
|
|
137361
|
-
|
|
137555
|
+
status;
|
|
137556
|
+
constructor(message, permanent, status) {
|
|
137362
137557
|
super(message);
|
|
137363
137558
|
this.name = "MintError";
|
|
137364
137559
|
this.permanent = permanent;
|
|
137560
|
+
this.status = status;
|
|
137365
137561
|
}
|
|
137366
137562
|
};
|
|
137367
137563
|
function extractAccessToken(payload) {
|
|
@@ -137441,7 +137637,8 @@ var AccessTokenProvider = class {
|
|
|
137441
137637
|
if (status === 401 || status === 403) {
|
|
137442
137638
|
throw new MintError(
|
|
137443
137639
|
`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.`,
|
|
137444
|
-
true
|
|
137640
|
+
true,
|
|
137641
|
+
status
|
|
137445
137642
|
);
|
|
137446
137643
|
}
|
|
137447
137644
|
if (status === 400 && body.toLowerCase().includes("service accounts not enabled")) {
|
|
@@ -137466,26 +137663,9 @@ var AccessTokenProvider = class {
|
|
|
137466
137663
|
}
|
|
137467
137664
|
};
|
|
137468
137665
|
async function describeMintFailure(mintError, apiKey, apiBaseUrl, fetchImpl) {
|
|
137469
|
-
const raw = mintError instanceof Error ? mintError.message : String(mintError);
|
|
137470
|
-
|
|
137471
|
-
|
|
137472
|
-
return raw;
|
|
137473
|
-
}
|
|
137474
|
-
try {
|
|
137475
|
-
const me = await fetchImpl(`${apiBaseUrl}/me`, { headers: { "x-api-key": apiKey } });
|
|
137476
|
-
if (me.ok) {
|
|
137477
|
-
const body = await me.json().catch(() => void 0);
|
|
137478
|
-
const user = body?.user;
|
|
137479
|
-
const looksPersonal = Boolean(user && (user.username || user.email));
|
|
137480
|
-
if (looksPersonal) {
|
|
137481
|
-
return "Personal API key detected, cannot mint a service-account access token. POST /service-account-tokens only accepts a SERVICE-ACCOUNT API key; this postman-api-key belongs to a user account" + (user?.teamId ? ` (team ${user.teamId})` : "") + ". Create a service account in Team Settings and use its PMAK, or mint the token elsewhere and pass postman-access-token.";
|
|
137482
|
-
}
|
|
137483
|
-
return "The postman-api-key authenticates (GET /me OK) but was rejected by POST /service-account-tokens" + (user?.teamId ? ` (team ${user.teamId})` : "") + ". The service account likely lacks permission to mint access tokens, or service accounts are restricted for this team. Check the service account role in Team Settings, or pass a pre-minted postman-access-token.";
|
|
137484
|
-
}
|
|
137485
|
-
return "The postman-api-key is invalid, disabled, or expired (rejected by both POST /service-account-tokens and GET /me). Generate a fresh service-account PMAK in Team Settings and update the secret.";
|
|
137486
|
-
} catch {
|
|
137487
|
-
return raw;
|
|
137488
|
-
}
|
|
137666
|
+
const raw = maskPmakDiagnostic(mintError instanceof Error ? mintError.message : String(mintError), [apiKey]);
|
|
137667
|
+
if (!(mintError instanceof MintError) || mintError.status !== 401 && mintError.status !== 403) return raw;
|
|
137668
|
+
return formatRejectedMint(raw, await inspectPmakIdentity({ apiBaseUrl, apiKey, fetchImpl }));
|
|
137489
137669
|
}
|
|
137490
137670
|
async function mintAccessTokenIfNeeded(inputs, log, setSecret2, fetchImpl = fetch) {
|
|
137491
137671
|
if (inputs.postmanAccessToken || !inputs.postmanApiKey) {
|
|
@@ -137534,6 +137714,10 @@ var AccessTokenGatewayClient = class {
|
|
|
137534
137714
|
fallbackBaseUrl;
|
|
137535
137715
|
retryBaseDelayMs;
|
|
137536
137716
|
sleepImpl;
|
|
137717
|
+
appVersionProvider;
|
|
137718
|
+
requestTimeoutMs;
|
|
137719
|
+
retryMaxDelayMs;
|
|
137720
|
+
randomImpl;
|
|
137537
137721
|
constructor(options) {
|
|
137538
137722
|
this.tokenProvider = options.tokenProvider;
|
|
137539
137723
|
this.bifrostBaseUrl = String(
|
|
@@ -137548,16 +137732,22 @@ var AccessTokenGatewayClient = class {
|
|
|
137548
137732
|
this.fallbackBaseUrl = fallbackEnv === "off" ? void 0 : options.fallbackBaseUrl?.replace(/\/+$/, "");
|
|
137549
137733
|
this.retryBaseDelayMs = options.retryBaseDelayMs ?? 400;
|
|
137550
137734
|
this.sleepImpl = options.sleepImpl ?? defaultSleep;
|
|
137735
|
+
this.appVersionProvider = options.appVersionProvider ?? defaultPostmanAppVersionProvider;
|
|
137736
|
+
this.requestTimeoutMs = options.requestTimeoutMs ?? 3e4;
|
|
137737
|
+
this.retryMaxDelayMs = options.retryMaxDelayMs ?? 5e3;
|
|
137738
|
+
this.randomImpl = options.randomImpl ?? Math.random;
|
|
137551
137739
|
}
|
|
137552
137740
|
configureTeamContext(teamId, orgMode) {
|
|
137553
137741
|
this.teamId = String(teamId || "").trim();
|
|
137554
137742
|
this.orgMode = orgMode;
|
|
137555
137743
|
}
|
|
137556
|
-
buildHeaders(extra) {
|
|
137744
|
+
async buildHeaders(extra) {
|
|
137745
|
+
const appVersion = await this.appVersionProvider.get();
|
|
137557
137746
|
const headers = {
|
|
137558
137747
|
"Content-Type": "application/json",
|
|
137559
137748
|
"x-access-token": this.tokenProvider.current(),
|
|
137560
|
-
...extra || {}
|
|
137749
|
+
...extra || {},
|
|
137750
|
+
...appVersion ? { "x-app-version": appVersion } : {}
|
|
137561
137751
|
};
|
|
137562
137752
|
if (this.teamId && this.orgMode) {
|
|
137563
137753
|
headers["x-entity-team-id"] = this.teamId;
|
|
@@ -137566,17 +137756,24 @@ var AccessTokenGatewayClient = class {
|
|
|
137566
137756
|
}
|
|
137567
137757
|
async send(request, baseUrl) {
|
|
137568
137758
|
const url = `${baseUrl ?? this.bifrostBaseUrl}/ws/proxy`;
|
|
137569
|
-
|
|
137570
|
-
|
|
137571
|
-
|
|
137572
|
-
|
|
137573
|
-
|
|
137574
|
-
|
|
137575
|
-
|
|
137576
|
-
|
|
137577
|
-
|
|
137578
|
-
|
|
137579
|
-
|
|
137759
|
+
const controller = new AbortController();
|
|
137760
|
+
const timer = setTimeout(() => controller.abort(), this.requestTimeoutMs);
|
|
137761
|
+
try {
|
|
137762
|
+
return await this.fetchImpl(url, {
|
|
137763
|
+
method: "POST",
|
|
137764
|
+
headers: await this.buildHeaders(request.headers),
|
|
137765
|
+
signal: controller.signal,
|
|
137766
|
+
body: JSON.stringify({
|
|
137767
|
+
service: request.service,
|
|
137768
|
+
method: request.method,
|
|
137769
|
+
path: request.path,
|
|
137770
|
+
...request.query !== void 0 ? { query: request.query } : {},
|
|
137771
|
+
...request.body !== void 0 ? { body: request.body } : {}
|
|
137772
|
+
})
|
|
137773
|
+
});
|
|
137774
|
+
} finally {
|
|
137775
|
+
clearTimeout(timer);
|
|
137776
|
+
}
|
|
137580
137777
|
}
|
|
137581
137778
|
/**
|
|
137582
137779
|
* One cold, serial attempt against the fallback base URL after the primary
|
|
@@ -137603,6 +137800,7 @@ var AccessTokenGatewayClient = class {
|
|
|
137603
137800
|
* they are the freshest authoritative answer.
|
|
137604
137801
|
*/
|
|
137605
137802
|
fallbackEligible(request, retryTransient) {
|
|
137803
|
+
if (request.fallback === "none") return false;
|
|
137606
137804
|
if (!this.fallbackBaseUrl) return false;
|
|
137607
137805
|
return retryTransient || request.fallback === "auto";
|
|
137608
137806
|
}
|
|
@@ -137632,7 +137830,7 @@ var AccessTokenGatewayClient = class {
|
|
|
137632
137830
|
response = await this.send(request);
|
|
137633
137831
|
} catch (error2) {
|
|
137634
137832
|
if (retryTransient && attempt < this.maxRetries) {
|
|
137635
|
-
const delay = this.
|
|
137833
|
+
const delay = this.retryDelayMs(attempt);
|
|
137636
137834
|
attempt += 1;
|
|
137637
137835
|
await this.sleepImpl(delay);
|
|
137638
137836
|
continue;
|
|
@@ -137642,7 +137840,17 @@ var AccessTokenGatewayClient = class {
|
|
|
137642
137840
|
throw error2;
|
|
137643
137841
|
}
|
|
137644
137842
|
if (response.ok) {
|
|
137645
|
-
|
|
137843
|
+
const okBody = await response.text().catch(() => "");
|
|
137844
|
+
const inner = this.innerStatus(okBody);
|
|
137845
|
+
if (inner !== void 0) {
|
|
137846
|
+
if (retryTransient && this.isTransient(inner, okBody) && attempt < this.maxRetries) {
|
|
137847
|
+
await this.sleepImpl(this.retryDelayMs(attempt));
|
|
137848
|
+
attempt += 1;
|
|
137849
|
+
continue;
|
|
137850
|
+
}
|
|
137851
|
+
throw this.toInnerHttpError(request, inner, okBody);
|
|
137852
|
+
}
|
|
137853
|
+
return this.rebuildResponse(response, okBody);
|
|
137646
137854
|
}
|
|
137647
137855
|
const body = await response.text().catch(() => "");
|
|
137648
137856
|
if (isExpiredAuthError(response.status, body) && this.tokenProvider.canRefresh()) {
|
|
@@ -137654,8 +137862,8 @@ var AccessTokenGatewayClient = class {
|
|
|
137654
137862
|
const retryBody = await response.text().catch(() => "");
|
|
137655
137863
|
throw this.toHttpError(request, response, retryBody);
|
|
137656
137864
|
}
|
|
137657
|
-
if (retryTransient &&
|
|
137658
|
-
const delay = this.
|
|
137865
|
+
if (retryTransient && this.isTransient(response.status, body) && attempt < this.maxRetries) {
|
|
137866
|
+
const delay = this.retryDelayMs(attempt, parseRetryAfterMs2(response.headers.get("retry-after")));
|
|
137659
137867
|
attempt += 1;
|
|
137660
137868
|
await this.sleepImpl(delay);
|
|
137661
137869
|
continue;
|
|
@@ -137665,6 +137873,24 @@ var AccessTokenGatewayClient = class {
|
|
|
137665
137873
|
throw this.toHttpError(request, response, body);
|
|
137666
137874
|
}
|
|
137667
137875
|
}
|
|
137876
|
+
retryDelayMs(attempt, retryAfter) {
|
|
137877
|
+
return retryAfter === void 0 ? fullJitterDelayMs(attempt, this.retryBaseDelayMs, this.retryMaxDelayMs, this.randomImpl) : Math.min(this.retryMaxDelayMs, retryAfter);
|
|
137878
|
+
}
|
|
137879
|
+
isTransient(status, body) {
|
|
137880
|
+
return status === 408 || status === 429 || status >= 500 || /ESOCKETTIMEDOUT|ETIMEDOUT|ECONNRESET|serverError|downstream/.test(body);
|
|
137881
|
+
}
|
|
137882
|
+
innerStatus(body) {
|
|
137883
|
+
try {
|
|
137884
|
+
const value = JSON.parse(body);
|
|
137885
|
+
const status = Number(value.status ?? value.statusCode);
|
|
137886
|
+
return value.error || value.success === false || status >= 400 ? status >= 400 ? status : 502 : void 0;
|
|
137887
|
+
} catch {
|
|
137888
|
+
return void 0;
|
|
137889
|
+
}
|
|
137890
|
+
}
|
|
137891
|
+
rebuildResponse(response, body) {
|
|
137892
|
+
return new Response([204, 205, 304].includes(response.status) ? null : body, { status: response.status, statusText: response.statusText, headers: response.headers });
|
|
137893
|
+
}
|
|
137668
137894
|
/** Send a gateway request and parse the JSON body, or null when empty. */
|
|
137669
137895
|
async requestJson(request, options = {}) {
|
|
137670
137896
|
const response = await this.request(request, options);
|
|
@@ -137711,11 +137937,19 @@ var AccessTokenGatewayClient = class {
|
|
|
137711
137937
|
url: `${this.bifrostBaseUrl}/ws/proxy (${request.service}: ${request.method} ${request.path})`,
|
|
137712
137938
|
status: response.status,
|
|
137713
137939
|
statusText: response.statusText,
|
|
137714
|
-
requestHeaders:
|
|
137940
|
+
requestHeaders: {
|
|
137941
|
+
"Content-Type": "application/json",
|
|
137942
|
+
"x-access-token": this.tokenProvider.current(),
|
|
137943
|
+
...request.headers || {},
|
|
137944
|
+
...this.teamId && this.orgMode ? { "x-entity-team-id": this.teamId } : {}
|
|
137945
|
+
},
|
|
137715
137946
|
responseBody: this.secretMasker(body),
|
|
137716
137947
|
secretValues: [this.tokenProvider.current()]
|
|
137717
137948
|
});
|
|
137718
137949
|
}
|
|
137950
|
+
toInnerHttpError(request, status, body) {
|
|
137951
|
+
return new HttpError({ method: request.method.toUpperCase(), url: `${this.bifrostBaseUrl}/ws/proxy (${request.service}: ${request.method} ${request.path}) [inner]`, status, statusText: "Inner Error", requestHeaders: { "x-access-token": this.tokenProvider.current() }, responseBody: this.secretMasker(body), secretValues: [this.tokenProvider.current()] });
|
|
137952
|
+
}
|
|
137719
137953
|
};
|
|
137720
137954
|
|
|
137721
137955
|
// src/lib/ssl-validation.ts
|
|
@@ -138832,8 +139066,8 @@ function stripVolatileFields(obj) {
|
|
|
138832
139066
|
}
|
|
138833
139067
|
return obj;
|
|
138834
139068
|
}
|
|
138835
|
-
function writeJsonFile(path9, content,
|
|
138836
|
-
const data =
|
|
139069
|
+
function writeJsonFile(path9, content, normalize4 = false) {
|
|
139070
|
+
const data = normalize4 ? stripVolatileFields(content) : content;
|
|
138837
139071
|
(0, import_node_fs4.writeFileSync)(path9, JSON.stringify(data, null, 2));
|
|
138838
139072
|
}
|
|
138839
139073
|
function buildMappedSpecCloudKey(mappedSource, specSyncMode, releaseLabel) {
|
|
@@ -139856,7 +140090,8 @@ function createRepoSyncDependencies(inputs, resolved, factories, options = {}) {
|
|
|
139856
140090
|
bifrostBaseUrl: inputs.postmanBifrostBase,
|
|
139857
140091
|
orgMode: inputs.orgMode,
|
|
139858
140092
|
teamId: resolved.teamId,
|
|
139859
|
-
secretMasker: masker
|
|
140093
|
+
secretMasker: masker,
|
|
140094
|
+
gateway
|
|
139860
140095
|
});
|
|
139861
140096
|
return {
|
|
139862
140097
|
teamId: resolved.teamId,
|