@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/index.cjs
CHANGED
|
@@ -19746,7 +19746,7 @@ var require_response = __commonJS({
|
|
|
19746
19746
|
var assert = require("node:assert");
|
|
19747
19747
|
var { isomorphicEncode, serializeJavascriptValueToJSONString } = require_infra();
|
|
19748
19748
|
var textEncoder = new TextEncoder("utf-8");
|
|
19749
|
-
var
|
|
19749
|
+
var Response2 = class _Response {
|
|
19750
19750
|
/** @type {Headers} */
|
|
19751
19751
|
#headers;
|
|
19752
19752
|
#state;
|
|
@@ -19916,13 +19916,13 @@ var require_response = __commonJS({
|
|
|
19916
19916
|
response.#state = newState;
|
|
19917
19917
|
}
|
|
19918
19918
|
};
|
|
19919
|
-
var { getResponseHeaders, setResponseHeaders, getResponseState, setResponseState } =
|
|
19920
|
-
Reflect.deleteProperty(
|
|
19921
|
-
Reflect.deleteProperty(
|
|
19922
|
-
Reflect.deleteProperty(
|
|
19923
|
-
Reflect.deleteProperty(
|
|
19924
|
-
mixinBody(
|
|
19925
|
-
Object.defineProperties(
|
|
19919
|
+
var { getResponseHeaders, setResponseHeaders, getResponseState, setResponseState } = Response2;
|
|
19920
|
+
Reflect.deleteProperty(Response2, "getResponseHeaders");
|
|
19921
|
+
Reflect.deleteProperty(Response2, "setResponseHeaders");
|
|
19922
|
+
Reflect.deleteProperty(Response2, "getResponseState");
|
|
19923
|
+
Reflect.deleteProperty(Response2, "setResponseState");
|
|
19924
|
+
mixinBody(Response2, getResponseState);
|
|
19925
|
+
Object.defineProperties(Response2.prototype, {
|
|
19926
19926
|
type: kEnumerableProperty,
|
|
19927
19927
|
url: kEnumerableProperty,
|
|
19928
19928
|
status: kEnumerableProperty,
|
|
@@ -19938,7 +19938,7 @@ var require_response = __commonJS({
|
|
|
19938
19938
|
configurable: true
|
|
19939
19939
|
}
|
|
19940
19940
|
});
|
|
19941
|
-
Object.defineProperties(
|
|
19941
|
+
Object.defineProperties(Response2, {
|
|
19942
19942
|
json: kEnumerableProperty,
|
|
19943
19943
|
redirect: kEnumerableProperty,
|
|
19944
19944
|
error: kEnumerableProperty
|
|
@@ -20071,7 +20071,7 @@ var require_response = __commonJS({
|
|
|
20071
20071
|
}
|
|
20072
20072
|
}
|
|
20073
20073
|
function fromInnerResponse(innerResponse, guard) {
|
|
20074
|
-
const response = new
|
|
20074
|
+
const response = new Response2(kConstruct);
|
|
20075
20075
|
setResponseState(response, innerResponse);
|
|
20076
20076
|
const headers = new Headers3(kConstruct);
|
|
20077
20077
|
setResponseHeaders(response, headers);
|
|
@@ -20125,14 +20125,14 @@ var require_response = __commonJS({
|
|
|
20125
20125
|
converter: webidl.converters.HeadersInit
|
|
20126
20126
|
}
|
|
20127
20127
|
]);
|
|
20128
|
-
webidl.is.Response = webidl.util.MakeTypeAssertion(
|
|
20128
|
+
webidl.is.Response = webidl.util.MakeTypeAssertion(Response2);
|
|
20129
20129
|
module2.exports = {
|
|
20130
20130
|
isNetworkError,
|
|
20131
20131
|
makeNetworkError,
|
|
20132
20132
|
makeResponse,
|
|
20133
20133
|
makeAppropriateNetworkError,
|
|
20134
20134
|
filterResponse,
|
|
20135
|
-
Response,
|
|
20135
|
+
Response: Response2,
|
|
20136
20136
|
cloneResponse,
|
|
20137
20137
|
fromInnerResponse,
|
|
20138
20138
|
getResponseState
|
|
@@ -99440,7 +99440,7 @@ var require_response2 = __commonJS({
|
|
|
99440
99440
|
}
|
|
99441
99441
|
return stream;
|
|
99442
99442
|
};
|
|
99443
|
-
var
|
|
99443
|
+
var Response2;
|
|
99444
99444
|
_.inherit(
|
|
99445
99445
|
/**
|
|
99446
99446
|
* Response holds data related to the request body. By default, it provides a nice wrapper for url-encoded,
|
|
@@ -99451,14 +99451,14 @@ var require_response2 = __commonJS({
|
|
|
99451
99451
|
*
|
|
99452
99452
|
* @param {Response.definition} options -
|
|
99453
99453
|
*/
|
|
99454
|
-
|
|
99455
|
-
|
|
99454
|
+
Response2 = function PostmanResponse(options) {
|
|
99455
|
+
Response2.super_.apply(this, arguments);
|
|
99456
99456
|
this.update(options || {});
|
|
99457
99457
|
},
|
|
99458
99458
|
Property
|
|
99459
99459
|
);
|
|
99460
99460
|
_.assign(
|
|
99461
|
-
|
|
99461
|
+
Response2.prototype,
|
|
99462
99462
|
/** @lends Response.prototype */
|
|
99463
99463
|
{
|
|
99464
99464
|
update(options) {
|
|
@@ -99524,7 +99524,7 @@ var require_response2 = __commonJS({
|
|
|
99524
99524
|
}
|
|
99525
99525
|
);
|
|
99526
99526
|
_.assign(
|
|
99527
|
-
|
|
99527
|
+
Response2.prototype,
|
|
99528
99528
|
/** @lends Response.prototype */
|
|
99529
99529
|
{
|
|
99530
99530
|
/**
|
|
@@ -99702,7 +99702,7 @@ var require_response2 = __commonJS({
|
|
|
99702
99702
|
}
|
|
99703
99703
|
);
|
|
99704
99704
|
_.assign(
|
|
99705
|
-
|
|
99705
|
+
Response2,
|
|
99706
99706
|
/** @lends Response */
|
|
99707
99707
|
{
|
|
99708
99708
|
/**
|
|
@@ -99720,7 +99720,7 @@ var require_response2 = __commonJS({
|
|
|
99720
99720
|
* @returns {Boolean}
|
|
99721
99721
|
*/
|
|
99722
99722
|
isResponse: function(obj) {
|
|
99723
|
-
return Boolean(obj) && (obj instanceof
|
|
99723
|
+
return Boolean(obj) && (obj instanceof Response2 || _.inSuperChain(obj.constructor, "_postman_propertyName", Response2._postman_propertyName));
|
|
99724
99724
|
},
|
|
99725
99725
|
/**
|
|
99726
99726
|
* Converts the response object from the request module to the postman responseBody format
|
|
@@ -99731,7 +99731,7 @@ var require_response2 = __commonJS({
|
|
|
99731
99731
|
* @todo Add a key: `originalRequest` to the returned object as well, referring to response.request
|
|
99732
99732
|
*/
|
|
99733
99733
|
createFromNode: function(response, cookies) {
|
|
99734
|
-
return new
|
|
99734
|
+
return new Response2({
|
|
99735
99735
|
cookie: cookies,
|
|
99736
99736
|
body: response.body.toString(),
|
|
99737
99737
|
stream: response.body,
|
|
@@ -99810,7 +99810,7 @@ var require_response2 = __commonJS({
|
|
|
99810
99810
|
}
|
|
99811
99811
|
);
|
|
99812
99812
|
module2.exports = {
|
|
99813
|
-
Response
|
|
99813
|
+
Response: Response2
|
|
99814
99814
|
};
|
|
99815
99815
|
}
|
|
99816
99816
|
});
|
|
@@ -99824,7 +99824,7 @@ var require_item = __commonJS({
|
|
|
99824
99824
|
var EventList = require_event_list().EventList;
|
|
99825
99825
|
var Request = require_request13().Request;
|
|
99826
99826
|
var RequestAuth = require_request_auth().RequestAuth;
|
|
99827
|
-
var
|
|
99827
|
+
var Response2 = require_response2().Response;
|
|
99828
99828
|
var Item;
|
|
99829
99829
|
var OBJECT = "object";
|
|
99830
99830
|
var STRING = "string";
|
|
@@ -99891,7 +99891,7 @@ var require_item = __commonJS({
|
|
|
99891
99891
|
*
|
|
99892
99892
|
* @type {PropertyList<Response>}
|
|
99893
99893
|
*/
|
|
99894
|
-
responses: new PropertyList(
|
|
99894
|
+
responses: new PropertyList(Response2, this, definition && definition.response),
|
|
99895
99895
|
/**
|
|
99896
99896
|
* Events are a set of of {@link Script}s that are executed when certain activities are triggered on an
|
|
99897
99897
|
* Item. For example, on defining an event that listens to the "test" event, would cause the associated
|
|
@@ -135578,6 +135578,54 @@ var HttpError = class _HttpError extends Error {
|
|
|
135578
135578
|
}
|
|
135579
135579
|
};
|
|
135580
135580
|
|
|
135581
|
+
// src/lib/postman/pmak-diagnostics.ts
|
|
135582
|
+
var memo = /* @__PURE__ */ new Map();
|
|
135583
|
+
var normalize3 = (value) => new URL(value.trim()).toString().replace(/\/+$/, "");
|
|
135584
|
+
function maskPmakDiagnostic(message, secrets) {
|
|
135585
|
+
let masked = String(message);
|
|
135586
|
+
for (const secret of secrets) if (secret) masked = masked.split(secret).join("***");
|
|
135587
|
+
return Array.from(masked, (character) => {
|
|
135588
|
+
const code = character.codePointAt(0) ?? 0;
|
|
135589
|
+
return code <= 31 || code >= 127 && code <= 159 ? " " : character;
|
|
135590
|
+
}).join("").replace(/\s+/g, " ").trim();
|
|
135591
|
+
}
|
|
135592
|
+
function formatRejectedMint(original, result) {
|
|
135593
|
+
const teamId = typeof result.payload?.user?.teamId === "number" ? ` (team ${(result.payload?.user).teamId})` : "";
|
|
135594
|
+
if (result.kind === "personal") return `Personal API key detected, cannot mint a service-account access token${teamId}.`;
|
|
135595
|
+
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.`;
|
|
135596
|
+
if (result.kind === "invalid") return "The postman-api-key is invalid, disabled, or expired.";
|
|
135597
|
+
return original;
|
|
135598
|
+
}
|
|
135599
|
+
async function inspectPmakIdentity(options) {
|
|
135600
|
+
const apiBaseUrl = normalize3(options.apiBaseUrl);
|
|
135601
|
+
const key = `${apiBaseUrl}\0${options.apiKey}`;
|
|
135602
|
+
let pending = memo.get(key);
|
|
135603
|
+
if (!pending) {
|
|
135604
|
+
pending = (async () => {
|
|
135605
|
+
try {
|
|
135606
|
+
const timeout = AbortSignal.timeout(options.timeoutMs ?? 2e3);
|
|
135607
|
+
const signal = options.signal ? AbortSignal.any([options.signal, timeout]) : timeout;
|
|
135608
|
+
const response = await (options.fetchImpl ?? fetch)(`${apiBaseUrl}/me`, { method: "GET", headers: { "X-Api-Key": options.apiKey }, signal });
|
|
135609
|
+
if (response.status === 401 || response.status === 403) return { kind: "invalid", status: response.status };
|
|
135610
|
+
if (!response.ok) return { kind: "inconclusive", status: response.status };
|
|
135611
|
+
const payload = await response.json().catch(() => void 0);
|
|
135612
|
+
const user = payload?.user;
|
|
135613
|
+
if (!user || typeof user !== "object" || Array.isArray(user)) return { kind: "inconclusive", payload };
|
|
135614
|
+
const record = user;
|
|
135615
|
+
if (typeof record.username === "string" && record.username || typeof record.email === "string" && record.email) return { kind: "personal", status: response.status, payload };
|
|
135616
|
+
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 };
|
|
135617
|
+
return { kind: "inconclusive", payload };
|
|
135618
|
+
} catch {
|
|
135619
|
+
return { kind: "inconclusive" };
|
|
135620
|
+
}
|
|
135621
|
+
})();
|
|
135622
|
+
memo.set(key, pending);
|
|
135623
|
+
}
|
|
135624
|
+
const result = await pending;
|
|
135625
|
+
if (options.mode === "preflight" && result.kind === "inconclusive") memo.delete(key);
|
|
135626
|
+
return result;
|
|
135627
|
+
}
|
|
135628
|
+
|
|
135581
135629
|
// src/lib/postman/credential-identity.ts
|
|
135582
135630
|
var sessionPath = "/api/sessions/current";
|
|
135583
135631
|
var SESSION_MAX_ATTEMPTS = 3;
|
|
@@ -135671,14 +135719,8 @@ async function resolvePmakIdentity(opts) {
|
|
|
135671
135719
|
}
|
|
135672
135720
|
async function probePmakIdentity(baseUrl, apiKey, fetchImpl) {
|
|
135673
135721
|
try {
|
|
135674
|
-
const
|
|
135675
|
-
|
|
135676
|
-
headers: { "X-Api-Key": apiKey }
|
|
135677
|
-
});
|
|
135678
|
-
if (!response.ok) {
|
|
135679
|
-
return void 0;
|
|
135680
|
-
}
|
|
135681
|
-
const payload = asRecord(await response.json());
|
|
135722
|
+
const diagnostic = await inspectPmakIdentity({ apiBaseUrl: baseUrl, apiKey, fetchImpl });
|
|
135723
|
+
const payload = asRecord(diagnostic.payload);
|
|
135682
135724
|
const user = asRecord(payload?.user);
|
|
135683
135725
|
if (!user) {
|
|
135684
135726
|
return void 0;
|
|
@@ -135980,6 +136022,39 @@ function adviseFromHttpError(err, ctx) {
|
|
|
135980
136022
|
return new Error(ctx.mask(advice), { cause: err });
|
|
135981
136023
|
}
|
|
135982
136024
|
|
|
136025
|
+
// src/lib/postman/app-version.ts
|
|
136026
|
+
var UPDATE_URL = "https://dl.pstmn.io/update/status?currentVersion=12.0.0&platform=osx_arm64";
|
|
136027
|
+
var FLOOR_VERSION = "12.0.0";
|
|
136028
|
+
var VERSION_PATTERN = /^[0-9]+\.[0-9]+\.[0-9]+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;
|
|
136029
|
+
var PostmanAppVersionProvider = class {
|
|
136030
|
+
fetchImpl;
|
|
136031
|
+
requestTimeoutMs;
|
|
136032
|
+
pending;
|
|
136033
|
+
constructor(options = {}) {
|
|
136034
|
+
this.fetchImpl = options.fetchImpl ?? fetch;
|
|
136035
|
+
this.requestTimeoutMs = options.requestTimeoutMs ?? 2e3;
|
|
136036
|
+
}
|
|
136037
|
+
async get() {
|
|
136038
|
+
if (process.env.POSTMAN_GATEWAY_APP_VERSION === "off") return void 0;
|
|
136039
|
+
this.pending ??= this.resolve();
|
|
136040
|
+
return this.pending;
|
|
136041
|
+
}
|
|
136042
|
+
async resolve() {
|
|
136043
|
+
try {
|
|
136044
|
+
const response = await this.fetchImpl(UPDATE_URL, {
|
|
136045
|
+
signal: AbortSignal.timeout(this.requestTimeoutMs)
|
|
136046
|
+
});
|
|
136047
|
+
if (!response.ok) return FLOOR_VERSION;
|
|
136048
|
+
const payload = await response.json();
|
|
136049
|
+
const version = typeof payload.version === "string" ? payload.version : "";
|
|
136050
|
+
return VERSION_PATTERN.test(version) ? version : FLOOR_VERSION;
|
|
136051
|
+
} catch {
|
|
136052
|
+
return FLOOR_VERSION;
|
|
136053
|
+
}
|
|
136054
|
+
}
|
|
136055
|
+
};
|
|
136056
|
+
var defaultPostmanAppVersionProvider = new PostmanAppVersionProvider();
|
|
136057
|
+
|
|
135983
136058
|
// src/lib/postman/internal-integration-adapter.ts
|
|
135984
136059
|
function extractDuplicateWorkspaceId(body) {
|
|
135985
136060
|
try {
|
|
@@ -135999,6 +136074,8 @@ var BifrostInternalIntegrationAdapter = class {
|
|
|
135999
136074
|
secretMasker;
|
|
136000
136075
|
teamId;
|
|
136001
136076
|
workerBaseUrl;
|
|
136077
|
+
gateway;
|
|
136078
|
+
appVersionProvider;
|
|
136002
136079
|
constructor(options) {
|
|
136003
136080
|
this.accessToken = String(options.accessToken || "").trim();
|
|
136004
136081
|
this.getAccessToken = options.getAccessToken;
|
|
@@ -136011,6 +136088,8 @@ var BifrostInternalIntegrationAdapter = class {
|
|
|
136011
136088
|
this.workerBaseUrl = String(
|
|
136012
136089
|
options.workerBaseUrl || "https://catalog-admin.postman-account2009.workers.dev"
|
|
136013
136090
|
).replace(/\/+$/, "");
|
|
136091
|
+
this.gateway = options.gateway;
|
|
136092
|
+
this.appVersionProvider = options.appVersionProvider ?? defaultPostmanAppVersionProvider;
|
|
136014
136093
|
this.secretMasker = options.secretMasker ?? createSecretMasker([this.accessToken]);
|
|
136015
136094
|
}
|
|
136016
136095
|
/** Live access token: re-minted value when a provider accessor is wired, else the captured one. */
|
|
@@ -136018,7 +136097,7 @@ var BifrostInternalIntegrationAdapter = class {
|
|
|
136018
136097
|
return this.getAccessToken ? String(this.getAccessToken() || "").trim() : this.accessToken;
|
|
136019
136098
|
}
|
|
136020
136099
|
/** Build Bifrost proxy headers. Only includes x-entity-team-id for org-mode teams. */
|
|
136021
|
-
bifrostHeaders() {
|
|
136100
|
+
async bifrostHeaders() {
|
|
136022
136101
|
const headers = {
|
|
136023
136102
|
"Content-Type": "application/json",
|
|
136024
136103
|
"x-access-token": this.currentToken()
|
|
@@ -136026,6 +136105,8 @@ var BifrostInternalIntegrationAdapter = class {
|
|
|
136026
136105
|
if (this.teamId && this.orgMode) {
|
|
136027
136106
|
headers["x-entity-team-id"] = this.teamId;
|
|
136028
136107
|
}
|
|
136108
|
+
const appVersion = await this.appVersionProvider.get();
|
|
136109
|
+
if (appVersion) headers["x-app-version"] = appVersion;
|
|
136029
136110
|
return headers;
|
|
136030
136111
|
}
|
|
136031
136112
|
/** Reactive error-advice context, enriched with the preflight session memo when present. */
|
|
@@ -136056,6 +136137,58 @@ var BifrostInternalIntegrationAdapter = class {
|
|
|
136056
136137
|
if (associations.length === 0) {
|
|
136057
136138
|
return;
|
|
136058
136139
|
}
|
|
136140
|
+
const mode = process.env.POSTMAN_SYSTEM_ENV_ASSOCIATION_MODE ?? "direct";
|
|
136141
|
+
if (mode !== "direct" && mode !== "worker") {
|
|
136142
|
+
throw new Error("POSTMAN_SYSTEM_ENV_ASSOCIATION_MODE must be direct or worker");
|
|
136143
|
+
}
|
|
136144
|
+
if (mode === "direct") {
|
|
136145
|
+
if (!this.gateway) {
|
|
136146
|
+
throw new Error("Direct system-environment association requires the access-token gateway");
|
|
136147
|
+
}
|
|
136148
|
+
const groups = /* @__PURE__ */ new Map();
|
|
136149
|
+
for (const association of associations) {
|
|
136150
|
+
const systemEnvId = String(association.systemEnvId || "").trim();
|
|
136151
|
+
const uid = String(association.envUid || "").trim();
|
|
136152
|
+
if (!systemEnvId || !uid) continue;
|
|
136153
|
+
const key = `${systemEnvId}\0${workspaceId}`;
|
|
136154
|
+
const uids = groups.get(key) ?? /* @__PURE__ */ new Set();
|
|
136155
|
+
uids.add(uid);
|
|
136156
|
+
groups.set(key, uids);
|
|
136157
|
+
}
|
|
136158
|
+
for (const [key, uids] of [...groups.entries()].sort(([a], [b]) => a.localeCompare(b))) {
|
|
136159
|
+
const [systemEnvironmentId, groupedWorkspaceId] = key.split("\0");
|
|
136160
|
+
const postmanEnvironmentIds = [...uids].sort();
|
|
136161
|
+
let response2;
|
|
136162
|
+
try {
|
|
136163
|
+
response2 = await this.gateway.requestJson({
|
|
136164
|
+
service: "api-catalog",
|
|
136165
|
+
method: "post",
|
|
136166
|
+
path: "/api/system-envs/associations",
|
|
136167
|
+
body: {
|
|
136168
|
+
systemEnvironmentId,
|
|
136169
|
+
workspaceEntries: [{ workspaceId: groupedWorkspaceId, postmanEnvironmentIds }]
|
|
136170
|
+
},
|
|
136171
|
+
fallback: "none"
|
|
136172
|
+
}, { retryTransient: true });
|
|
136173
|
+
} catch (error2) {
|
|
136174
|
+
if (error2 instanceof HttpError) {
|
|
136175
|
+
throw adviseFromHttpError(error2, this.adviceContext("system environment association")) ?? error2;
|
|
136176
|
+
}
|
|
136177
|
+
throw error2;
|
|
136178
|
+
}
|
|
136179
|
+
if (!response2 || response2.success !== true) {
|
|
136180
|
+
throw new Error("SYSTEM_ENV_ASSOCIATION_INCOMPLETE");
|
|
136181
|
+
}
|
|
136182
|
+
if (response2.data !== void 0) {
|
|
136183
|
+
if (!Array.isArray(response2.data)) throw new Error("SYSTEM_ENV_ASSOCIATION_INCOMPLETE");
|
|
136184
|
+
const seen = new Set(response2.data.filter((row) => !!row && typeof row === "object").map((row) => `${row.systemEnvironmentId}\0${row.workspaceId}\0${row.postmanEnvironmentId}`));
|
|
136185
|
+
if (!postmanEnvironmentIds.every((uid) => seen.has(`${systemEnvironmentId}\0${groupedWorkspaceId}\0${uid}`))) {
|
|
136186
|
+
throw new Error("SYSTEM_ENV_ASSOCIATION_INCOMPLETE");
|
|
136187
|
+
}
|
|
136188
|
+
}
|
|
136189
|
+
}
|
|
136190
|
+
return;
|
|
136191
|
+
}
|
|
136059
136192
|
const token = this.currentToken();
|
|
136060
136193
|
const response = await this.fetchImpl(
|
|
136061
136194
|
`${this.workerBaseUrl}/api/internal/system-envs/associate`,
|
|
@@ -136113,7 +136246,7 @@ var BifrostInternalIntegrationAdapter = class {
|
|
|
136113
136246
|
try {
|
|
136114
136247
|
const response = await this.fetchImpl(url, {
|
|
136115
136248
|
method: "POST",
|
|
136116
|
-
headers: this.bifrostHeaders(),
|
|
136249
|
+
headers: await this.bifrostHeaders(),
|
|
136117
136250
|
body: JSON.stringify(payload)
|
|
136118
136251
|
});
|
|
136119
136252
|
let parsed = {};
|
|
@@ -136202,7 +136335,7 @@ var BifrostInternalIntegrationAdapter = class {
|
|
|
136202
136335
|
versionControl: true
|
|
136203
136336
|
}
|
|
136204
136337
|
};
|
|
136205
|
-
const headers = this.bifrostHeaders();
|
|
136338
|
+
const headers = await this.bifrostHeaders();
|
|
136206
136339
|
const response = await this.fetchImpl(url, {
|
|
136207
136340
|
method: "POST",
|
|
136208
136341
|
headers,
|
|
@@ -136257,7 +136390,7 @@ var BifrostInternalIntegrationAdapter = class {
|
|
|
136257
136390
|
try {
|
|
136258
136391
|
const response = await this.fetchImpl(`${this.bifrostBaseUrl}/ws/proxy`, {
|
|
136259
136392
|
method: "POST",
|
|
136260
|
-
headers: this.bifrostHeaders(),
|
|
136393
|
+
headers: await this.bifrostHeaders(),
|
|
136261
136394
|
body: JSON.stringify({
|
|
136262
136395
|
service: "workspaces",
|
|
136263
136396
|
method: "GET",
|
|
@@ -136288,7 +136421,7 @@ var BifrostInternalIntegrationAdapter = class {
|
|
|
136288
136421
|
}
|
|
136289
136422
|
async createApiKey(name) {
|
|
136290
136423
|
const url = `${this.bifrostBaseUrl}/ws/proxy`;
|
|
136291
|
-
const headers = this.bifrostHeaders();
|
|
136424
|
+
const headers = await this.bifrostHeaders();
|
|
136292
136425
|
const payload = {
|
|
136293
136426
|
service: "identity",
|
|
136294
136427
|
method: "POST",
|
|
@@ -136373,6 +136506,16 @@ async function retry(operation, options = {}) {
|
|
|
136373
136506
|
}
|
|
136374
136507
|
throw new Error("Retry exhausted without returning or throwing");
|
|
136375
136508
|
}
|
|
136509
|
+
function fullJitterDelayMs(attempt, baseMs, capMs, random = Math.random) {
|
|
136510
|
+
return Math.floor(random() * Math.max(0, Math.min(capMs, baseMs * 2 ** Math.max(0, attempt))));
|
|
136511
|
+
}
|
|
136512
|
+
function parseRetryAfterMs2(value) {
|
|
136513
|
+
const trimmed = value?.trim();
|
|
136514
|
+
if (!trimmed) return void 0;
|
|
136515
|
+
if (/^\d+$/.test(trimmed)) return Number(trimmed) * 1e3;
|
|
136516
|
+
const time = Date.parse(trimmed);
|
|
136517
|
+
return Number.isNaN(time) ? void 0 : Math.max(0, time - Date.now());
|
|
136518
|
+
}
|
|
136376
136519
|
|
|
136377
136520
|
// src/contracts.ts
|
|
136378
136521
|
var postmanRepoSyncActionContract = {
|
|
@@ -136802,6 +136945,17 @@ var PostmanGatewayAssetsClient = class {
|
|
|
136802
136945
|
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);
|
|
136803
136946
|
}
|
|
136804
136947
|
async getSpecContent(specId) {
|
|
136948
|
+
if (process.env.POSTMAN_SPEC_TREE_FAST_PATH !== "off") {
|
|
136949
|
+
try {
|
|
136950
|
+
const treeContent = await this.getSpecContentFromTree(specId);
|
|
136951
|
+
if (treeContent !== void 0) return treeContent;
|
|
136952
|
+
} catch (error2) {
|
|
136953
|
+
if (!(error2 instanceof HttpError) || ![403, 404, 405, 501].includes(error2.status)) throw error2;
|
|
136954
|
+
}
|
|
136955
|
+
}
|
|
136956
|
+
return this.getSpecContentLegacy(specId);
|
|
136957
|
+
}
|
|
136958
|
+
async getSpecContentLegacy(specId) {
|
|
136805
136959
|
const files = await this.gateway.requestJson({
|
|
136806
136960
|
service: "specification",
|
|
136807
136961
|
method: "get",
|
|
@@ -136820,6 +136974,46 @@ var PostmanGatewayAssetsClient = class {
|
|
|
136820
136974
|
const record = this.dataOf(file);
|
|
136821
136975
|
return typeof record?.content === "string" ? record.content : void 0;
|
|
136822
136976
|
}
|
|
136977
|
+
/** Minimal `/tree` reader: validate the entire returned inventory before selecting ROOT. */
|
|
136978
|
+
async getSpecContentFromTree(specId) {
|
|
136979
|
+
const rows = [];
|
|
136980
|
+
const cursors = /* @__PURE__ */ new Set();
|
|
136981
|
+
let cursor;
|
|
136982
|
+
for (let page = 0; page < 100; page += 1) {
|
|
136983
|
+
const response = await this.gateway.requestJson({
|
|
136984
|
+
service: "specification",
|
|
136985
|
+
method: "get",
|
|
136986
|
+
path: `/specifications/${specId}/tree`,
|
|
136987
|
+
query: { fields: "id,name,type,path,parentId,fileType,content", limit: 100, ...cursor ? { cursor } : {} }
|
|
136988
|
+
});
|
|
136989
|
+
if (!Array.isArray(response?.data)) return void 0;
|
|
136990
|
+
for (const value of response.data) {
|
|
136991
|
+
const row = this.asRecord(value);
|
|
136992
|
+
if (!row || row.type === "FOLDER") continue;
|
|
136993
|
+
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;
|
|
136994
|
+
const path9 = row.path.replace(/\\/g, "/").normalize("NFC");
|
|
136995
|
+
if (path9.startsWith("/") || path9.split("/").some((part) => part === ".." || !part)) throw new Error("CONTRACT_DEFINITION_PATH_INVALID");
|
|
136996
|
+
rows.push({ ...row, path: path9 });
|
|
136997
|
+
}
|
|
136998
|
+
const meta = this.asRecord(response?.meta);
|
|
136999
|
+
const cursorValue = this.asRecord(meta?.cursor)?.next;
|
|
137000
|
+
const next = typeof cursorValue === "string" && cursorValue.trim() ? cursorValue.trim() : void 0;
|
|
137001
|
+
if (!next) break;
|
|
137002
|
+
if (cursors.has(next)) throw new Error("SPEC_TREE_CURSOR_REPEATED");
|
|
137003
|
+
cursors.add(next);
|
|
137004
|
+
if (page === 99) throw new Error("SPEC_TREE_PAGE_LIMIT_EXCEEDED");
|
|
137005
|
+
cursor = next;
|
|
137006
|
+
}
|
|
137007
|
+
const paths = /* @__PURE__ */ new Set();
|
|
137008
|
+
for (const row of rows) {
|
|
137009
|
+
const path9 = String(row.path).toLocaleLowerCase();
|
|
137010
|
+
if (paths.has(path9)) throw new Error("CONTRACT_DEFINITION_DUPLICATE_PATH");
|
|
137011
|
+
paths.add(path9);
|
|
137012
|
+
}
|
|
137013
|
+
const roots = rows.filter((row) => row.fileType === "ROOT");
|
|
137014
|
+
if (roots.length !== 1) throw new Error("CONTRACT_DEFINITION_INVENTORY_INVALID");
|
|
137015
|
+
return String(roots[0]?.content);
|
|
137016
|
+
}
|
|
136823
137017
|
async listSpecCollections(specId) {
|
|
136824
137018
|
const response = await this.gateway.requestJson({
|
|
136825
137019
|
service: "specification",
|
|
@@ -137379,10 +137573,12 @@ var PostmanGatewayAssetsClient = class {
|
|
|
137379
137573
|
// src/lib/postman/token-provider.ts
|
|
137380
137574
|
var MintError = class extends Error {
|
|
137381
137575
|
permanent;
|
|
137382
|
-
|
|
137576
|
+
status;
|
|
137577
|
+
constructor(message, permanent, status) {
|
|
137383
137578
|
super(message);
|
|
137384
137579
|
this.name = "MintError";
|
|
137385
137580
|
this.permanent = permanent;
|
|
137581
|
+
this.status = status;
|
|
137386
137582
|
}
|
|
137387
137583
|
};
|
|
137388
137584
|
function extractAccessToken(payload) {
|
|
@@ -137462,7 +137658,8 @@ var AccessTokenProvider = class {
|
|
|
137462
137658
|
if (status === 401 || status === 403) {
|
|
137463
137659
|
throw new MintError(
|
|
137464
137660
|
`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.`,
|
|
137465
|
-
true
|
|
137661
|
+
true,
|
|
137662
|
+
status
|
|
137466
137663
|
);
|
|
137467
137664
|
}
|
|
137468
137665
|
if (status === 400 && body.toLowerCase().includes("service accounts not enabled")) {
|
|
@@ -137487,26 +137684,9 @@ var AccessTokenProvider = class {
|
|
|
137487
137684
|
}
|
|
137488
137685
|
};
|
|
137489
137686
|
async function describeMintFailure(mintError, apiKey, apiBaseUrl, fetchImpl) {
|
|
137490
|
-
const raw = mintError instanceof Error ? mintError.message : String(mintError);
|
|
137491
|
-
|
|
137492
|
-
|
|
137493
|
-
return raw;
|
|
137494
|
-
}
|
|
137495
|
-
try {
|
|
137496
|
-
const me = await fetchImpl(`${apiBaseUrl}/me`, { headers: { "x-api-key": apiKey } });
|
|
137497
|
-
if (me.ok) {
|
|
137498
|
-
const body = await me.json().catch(() => void 0);
|
|
137499
|
-
const user = body?.user;
|
|
137500
|
-
const looksPersonal = Boolean(user && (user.username || user.email));
|
|
137501
|
-
if (looksPersonal) {
|
|
137502
|
-
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.";
|
|
137503
|
-
}
|
|
137504
|
-
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.";
|
|
137505
|
-
}
|
|
137506
|
-
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.";
|
|
137507
|
-
} catch {
|
|
137508
|
-
return raw;
|
|
137509
|
-
}
|
|
137687
|
+
const raw = maskPmakDiagnostic(mintError instanceof Error ? mintError.message : String(mintError), [apiKey]);
|
|
137688
|
+
if (!(mintError instanceof MintError) || mintError.status !== 401 && mintError.status !== 403) return raw;
|
|
137689
|
+
return formatRejectedMint(raw, await inspectPmakIdentity({ apiBaseUrl, apiKey, fetchImpl }));
|
|
137510
137690
|
}
|
|
137511
137691
|
async function mintAccessTokenIfNeeded(inputs, log, setSecret2, fetchImpl = fetch) {
|
|
137512
137692
|
if (inputs.postmanAccessToken || !inputs.postmanApiKey) {
|
|
@@ -137555,6 +137735,10 @@ var AccessTokenGatewayClient = class {
|
|
|
137555
137735
|
fallbackBaseUrl;
|
|
137556
137736
|
retryBaseDelayMs;
|
|
137557
137737
|
sleepImpl;
|
|
137738
|
+
appVersionProvider;
|
|
137739
|
+
requestTimeoutMs;
|
|
137740
|
+
retryMaxDelayMs;
|
|
137741
|
+
randomImpl;
|
|
137558
137742
|
constructor(options) {
|
|
137559
137743
|
this.tokenProvider = options.tokenProvider;
|
|
137560
137744
|
this.bifrostBaseUrl = String(
|
|
@@ -137569,16 +137753,22 @@ var AccessTokenGatewayClient = class {
|
|
|
137569
137753
|
this.fallbackBaseUrl = fallbackEnv === "off" ? void 0 : options.fallbackBaseUrl?.replace(/\/+$/, "");
|
|
137570
137754
|
this.retryBaseDelayMs = options.retryBaseDelayMs ?? 400;
|
|
137571
137755
|
this.sleepImpl = options.sleepImpl ?? defaultSleep;
|
|
137756
|
+
this.appVersionProvider = options.appVersionProvider ?? defaultPostmanAppVersionProvider;
|
|
137757
|
+
this.requestTimeoutMs = options.requestTimeoutMs ?? 3e4;
|
|
137758
|
+
this.retryMaxDelayMs = options.retryMaxDelayMs ?? 5e3;
|
|
137759
|
+
this.randomImpl = options.randomImpl ?? Math.random;
|
|
137572
137760
|
}
|
|
137573
137761
|
configureTeamContext(teamId, orgMode) {
|
|
137574
137762
|
this.teamId = String(teamId || "").trim();
|
|
137575
137763
|
this.orgMode = orgMode;
|
|
137576
137764
|
}
|
|
137577
|
-
buildHeaders(extra) {
|
|
137765
|
+
async buildHeaders(extra) {
|
|
137766
|
+
const appVersion = await this.appVersionProvider.get();
|
|
137578
137767
|
const headers = {
|
|
137579
137768
|
"Content-Type": "application/json",
|
|
137580
137769
|
"x-access-token": this.tokenProvider.current(),
|
|
137581
|
-
...extra || {}
|
|
137770
|
+
...extra || {},
|
|
137771
|
+
...appVersion ? { "x-app-version": appVersion } : {}
|
|
137582
137772
|
};
|
|
137583
137773
|
if (this.teamId && this.orgMode) {
|
|
137584
137774
|
headers["x-entity-team-id"] = this.teamId;
|
|
@@ -137587,17 +137777,24 @@ var AccessTokenGatewayClient = class {
|
|
|
137587
137777
|
}
|
|
137588
137778
|
async send(request, baseUrl) {
|
|
137589
137779
|
const url = `${baseUrl ?? this.bifrostBaseUrl}/ws/proxy`;
|
|
137590
|
-
|
|
137591
|
-
|
|
137592
|
-
|
|
137593
|
-
|
|
137594
|
-
|
|
137595
|
-
|
|
137596
|
-
|
|
137597
|
-
|
|
137598
|
-
|
|
137599
|
-
|
|
137600
|
-
|
|
137780
|
+
const controller = new AbortController();
|
|
137781
|
+
const timer = setTimeout(() => controller.abort(), this.requestTimeoutMs);
|
|
137782
|
+
try {
|
|
137783
|
+
return await this.fetchImpl(url, {
|
|
137784
|
+
method: "POST",
|
|
137785
|
+
headers: await this.buildHeaders(request.headers),
|
|
137786
|
+
signal: controller.signal,
|
|
137787
|
+
body: JSON.stringify({
|
|
137788
|
+
service: request.service,
|
|
137789
|
+
method: request.method,
|
|
137790
|
+
path: request.path,
|
|
137791
|
+
...request.query !== void 0 ? { query: request.query } : {},
|
|
137792
|
+
...request.body !== void 0 ? { body: request.body } : {}
|
|
137793
|
+
})
|
|
137794
|
+
});
|
|
137795
|
+
} finally {
|
|
137796
|
+
clearTimeout(timer);
|
|
137797
|
+
}
|
|
137601
137798
|
}
|
|
137602
137799
|
/**
|
|
137603
137800
|
* One cold, serial attempt against the fallback base URL after the primary
|
|
@@ -137624,6 +137821,7 @@ var AccessTokenGatewayClient = class {
|
|
|
137624
137821
|
* they are the freshest authoritative answer.
|
|
137625
137822
|
*/
|
|
137626
137823
|
fallbackEligible(request, retryTransient) {
|
|
137824
|
+
if (request.fallback === "none") return false;
|
|
137627
137825
|
if (!this.fallbackBaseUrl) return false;
|
|
137628
137826
|
return retryTransient || request.fallback === "auto";
|
|
137629
137827
|
}
|
|
@@ -137653,7 +137851,7 @@ var AccessTokenGatewayClient = class {
|
|
|
137653
137851
|
response = await this.send(request);
|
|
137654
137852
|
} catch (error2) {
|
|
137655
137853
|
if (retryTransient && attempt < this.maxRetries) {
|
|
137656
|
-
const delay = this.
|
|
137854
|
+
const delay = this.retryDelayMs(attempt);
|
|
137657
137855
|
attempt += 1;
|
|
137658
137856
|
await this.sleepImpl(delay);
|
|
137659
137857
|
continue;
|
|
@@ -137663,7 +137861,17 @@ var AccessTokenGatewayClient = class {
|
|
|
137663
137861
|
throw error2;
|
|
137664
137862
|
}
|
|
137665
137863
|
if (response.ok) {
|
|
137666
|
-
|
|
137864
|
+
const okBody = await response.text().catch(() => "");
|
|
137865
|
+
const inner = this.innerStatus(okBody);
|
|
137866
|
+
if (inner !== void 0) {
|
|
137867
|
+
if (retryTransient && this.isTransient(inner, okBody) && attempt < this.maxRetries) {
|
|
137868
|
+
await this.sleepImpl(this.retryDelayMs(attempt));
|
|
137869
|
+
attempt += 1;
|
|
137870
|
+
continue;
|
|
137871
|
+
}
|
|
137872
|
+
throw this.toInnerHttpError(request, inner, okBody);
|
|
137873
|
+
}
|
|
137874
|
+
return this.rebuildResponse(response, okBody);
|
|
137667
137875
|
}
|
|
137668
137876
|
const body = await response.text().catch(() => "");
|
|
137669
137877
|
if (isExpiredAuthError(response.status, body) && this.tokenProvider.canRefresh()) {
|
|
@@ -137675,8 +137883,8 @@ var AccessTokenGatewayClient = class {
|
|
|
137675
137883
|
const retryBody = await response.text().catch(() => "");
|
|
137676
137884
|
throw this.toHttpError(request, response, retryBody);
|
|
137677
137885
|
}
|
|
137678
|
-
if (retryTransient &&
|
|
137679
|
-
const delay = this.
|
|
137886
|
+
if (retryTransient && this.isTransient(response.status, body) && attempt < this.maxRetries) {
|
|
137887
|
+
const delay = this.retryDelayMs(attempt, parseRetryAfterMs2(response.headers.get("retry-after")));
|
|
137680
137888
|
attempt += 1;
|
|
137681
137889
|
await this.sleepImpl(delay);
|
|
137682
137890
|
continue;
|
|
@@ -137686,6 +137894,24 @@ var AccessTokenGatewayClient = class {
|
|
|
137686
137894
|
throw this.toHttpError(request, response, body);
|
|
137687
137895
|
}
|
|
137688
137896
|
}
|
|
137897
|
+
retryDelayMs(attempt, retryAfter) {
|
|
137898
|
+
return retryAfter === void 0 ? fullJitterDelayMs(attempt, this.retryBaseDelayMs, this.retryMaxDelayMs, this.randomImpl) : Math.min(this.retryMaxDelayMs, retryAfter);
|
|
137899
|
+
}
|
|
137900
|
+
isTransient(status, body) {
|
|
137901
|
+
return status === 408 || status === 429 || status >= 500 || /ESOCKETTIMEDOUT|ETIMEDOUT|ECONNRESET|serverError|downstream/.test(body);
|
|
137902
|
+
}
|
|
137903
|
+
innerStatus(body) {
|
|
137904
|
+
try {
|
|
137905
|
+
const value = JSON.parse(body);
|
|
137906
|
+
const status = Number(value.status ?? value.statusCode);
|
|
137907
|
+
return value.error || value.success === false || status >= 400 ? status >= 400 ? status : 502 : void 0;
|
|
137908
|
+
} catch {
|
|
137909
|
+
return void 0;
|
|
137910
|
+
}
|
|
137911
|
+
}
|
|
137912
|
+
rebuildResponse(response, body) {
|
|
137913
|
+
return new Response([204, 205, 304].includes(response.status) ? null : body, { status: response.status, statusText: response.statusText, headers: response.headers });
|
|
137914
|
+
}
|
|
137689
137915
|
/** Send a gateway request and parse the JSON body, or null when empty. */
|
|
137690
137916
|
async requestJson(request, options = {}) {
|
|
137691
137917
|
const response = await this.request(request, options);
|
|
@@ -137732,11 +137958,19 @@ var AccessTokenGatewayClient = class {
|
|
|
137732
137958
|
url: `${this.bifrostBaseUrl}/ws/proxy (${request.service}: ${request.method} ${request.path})`,
|
|
137733
137959
|
status: response.status,
|
|
137734
137960
|
statusText: response.statusText,
|
|
137735
|
-
requestHeaders:
|
|
137961
|
+
requestHeaders: {
|
|
137962
|
+
"Content-Type": "application/json",
|
|
137963
|
+
"x-access-token": this.tokenProvider.current(),
|
|
137964
|
+
...request.headers || {},
|
|
137965
|
+
...this.teamId && this.orgMode ? { "x-entity-team-id": this.teamId } : {}
|
|
137966
|
+
},
|
|
137736
137967
|
responseBody: this.secretMasker(body),
|
|
137737
137968
|
secretValues: [this.tokenProvider.current()]
|
|
137738
137969
|
});
|
|
137739
137970
|
}
|
|
137971
|
+
toInnerHttpError(request, status, body) {
|
|
137972
|
+
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()] });
|
|
137973
|
+
}
|
|
137740
137974
|
};
|
|
137741
137975
|
|
|
137742
137976
|
// src/lib/ssl-validation.ts
|
|
@@ -138853,8 +139087,8 @@ function stripVolatileFields(obj) {
|
|
|
138853
139087
|
}
|
|
138854
139088
|
return obj;
|
|
138855
139089
|
}
|
|
138856
|
-
function writeJsonFile(path9, content,
|
|
138857
|
-
const data =
|
|
139090
|
+
function writeJsonFile(path9, content, normalize4 = false) {
|
|
139091
|
+
const data = normalize4 ? stripVolatileFields(content) : content;
|
|
138858
139092
|
(0, import_node_fs4.writeFileSync)(path9, JSON.stringify(data, null, 2));
|
|
138859
139093
|
}
|
|
138860
139094
|
function buildMappedSpecCloudKey(mappedSource, specSyncMode, releaseLabel) {
|
|
@@ -139877,7 +140111,8 @@ function createRepoSyncDependencies(inputs, resolved, factories, options = {}) {
|
|
|
139877
140111
|
bifrostBaseUrl: inputs.postmanBifrostBase,
|
|
139878
140112
|
orgMode: inputs.orgMode,
|
|
139879
140113
|
teamId: resolved.teamId,
|
|
139880
|
-
secretMasker: masker
|
|
140114
|
+
secretMasker: masker,
|
|
140115
|
+
gateway
|
|
139881
140116
|
});
|
|
139882
140117
|
return {
|
|
139883
140118
|
teamId: resolved.teamId,
|