@postman-cse/onboarding-bootstrap 0.15.0 → 0.15.3
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 +5 -0
- package/action.yml +5 -1
- package/dist/action.cjs +6 -4
- package/dist/cli.cjs +327 -71
- package/dist/index.cjs +6 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# postman-bootstrap-action
|
|
2
2
|
|
|
3
|
+
[](https://github.com/postman-cs/postman-bootstrap-action/actions/workflows/ci.yml)
|
|
4
|
+
[](https://github.com/postman-cs/postman-bootstrap-action/releases)
|
|
5
|
+
[](https://www.npmjs.com/package/@postman-cse/onboarding-bootstrap)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
|
|
3
8
|
Public customer preview GitHub Action for Postman workspace bootstrap from a registry-backed OpenAPI spec.
|
|
4
9
|
|
|
5
10
|
## Scope
|
package/action.yml
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
name: postman-bootstrap-action
|
|
2
|
-
description:
|
|
2
|
+
description: Create or reuse a Postman workspace, upload an OpenAPI spec, and generate baseline, smoke, and contract collections.
|
|
3
|
+
author: Postman
|
|
4
|
+
branding:
|
|
5
|
+
icon: box
|
|
6
|
+
color: orange
|
|
3
7
|
inputs:
|
|
4
8
|
|
|
5
9
|
workspace-id:
|
package/dist/action.cjs
CHANGED
|
@@ -47921,20 +47921,22 @@ async function probeSessionIdentity(baseUrl, accessToken, fetchImpl) {
|
|
|
47921
47921
|
if (!payload) {
|
|
47922
47922
|
return void 0;
|
|
47923
47923
|
}
|
|
47924
|
-
const
|
|
47925
|
-
const
|
|
47924
|
+
const root = asRecord(payload.session) ?? payload;
|
|
47925
|
+
const identity = asRecord(root.identity);
|
|
47926
|
+
const data = asRecord(root.data);
|
|
47926
47927
|
const user = asRecord(data?.user);
|
|
47927
47928
|
const roleEntries = Array.isArray(user?.roles) ? user.roles.map((entry) => coerceText(entry) ?? coerceId(entry)).filter((entry) => Boolean(entry)) : [];
|
|
47928
47929
|
const singleRole = coerceText(user?.role);
|
|
47929
47930
|
const roles = roleEntries.length > 0 ? roleEntries : singleRole ? [singleRole] : void 0;
|
|
47930
47931
|
const resolved = {
|
|
47931
47932
|
source: "iapub/sessions",
|
|
47932
|
-
userId: coerceId(user?.id),
|
|
47933
|
+
userId: coerceId(identity?.user) ?? coerceId(user?.id),
|
|
47933
47934
|
fullName: coerceText(user?.fullName) ?? coerceText(user?.name) ?? coerceText(user?.username),
|
|
47934
47935
|
teamId: coerceId(identity?.team),
|
|
47936
|
+
teamName: coerceText(user?.teamName),
|
|
47935
47937
|
teamDomain: coerceText(identity?.domain),
|
|
47936
47938
|
...roles ? { roles } : {},
|
|
47937
|
-
consumerType: coerceText(
|
|
47939
|
+
consumerType: coerceText(root.consumerType) ?? coerceText(data?.consumerType) ?? coerceText(user?.consumerType)
|
|
47938
47940
|
};
|
|
47939
47941
|
memoizedSessionIdentity = resolved;
|
|
47940
47942
|
return resolved;
|
package/dist/cli.cjs
CHANGED
|
@@ -46147,10 +46147,255 @@ function resolvePostmanEndpointProfile(stack) {
|
|
|
46147
46147
|
}
|
|
46148
46148
|
|
|
46149
46149
|
// src/lib/postman/credential-identity.ts
|
|
46150
|
+
var sessionPath = "/api/sessions/current";
|
|
46151
|
+
var pmakMemo = /* @__PURE__ */ new Map();
|
|
46152
|
+
var sessionMemo = /* @__PURE__ */ new Map();
|
|
46150
46153
|
var memoizedSessionIdentity;
|
|
46151
46154
|
function getMemoizedSessionIdentity() {
|
|
46152
46155
|
return memoizedSessionIdentity;
|
|
46153
46156
|
}
|
|
46157
|
+
function asRecord(value) {
|
|
46158
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
46159
|
+
return void 0;
|
|
46160
|
+
}
|
|
46161
|
+
return value;
|
|
46162
|
+
}
|
|
46163
|
+
function coerceId(raw) {
|
|
46164
|
+
return raw ? String(raw) : void 0;
|
|
46165
|
+
}
|
|
46166
|
+
function coerceText(raw) {
|
|
46167
|
+
if (typeof raw !== "string") {
|
|
46168
|
+
return void 0;
|
|
46169
|
+
}
|
|
46170
|
+
const trimmed = raw.trim();
|
|
46171
|
+
return trimmed ? trimmed : void 0;
|
|
46172
|
+
}
|
|
46173
|
+
function normalizeBaseUrl(raw) {
|
|
46174
|
+
return String(raw || "").replace(/\/+$/, "");
|
|
46175
|
+
}
|
|
46176
|
+
async function resolvePmakIdentity(opts) {
|
|
46177
|
+
const apiKey = String(opts.apiKey || "").trim();
|
|
46178
|
+
if (!apiKey) {
|
|
46179
|
+
return void 0;
|
|
46180
|
+
}
|
|
46181
|
+
const baseUrl = normalizeBaseUrl(opts.apiBaseUrl);
|
|
46182
|
+
const memoKey = `${baseUrl}::${apiKey}`;
|
|
46183
|
+
let pending = pmakMemo.get(memoKey);
|
|
46184
|
+
if (!pending) {
|
|
46185
|
+
pending = probePmakIdentity(baseUrl, apiKey, opts.fetchImpl ?? fetch);
|
|
46186
|
+
pmakMemo.set(memoKey, pending);
|
|
46187
|
+
}
|
|
46188
|
+
return pending;
|
|
46189
|
+
}
|
|
46190
|
+
async function probePmakIdentity(baseUrl, apiKey, fetchImpl) {
|
|
46191
|
+
try {
|
|
46192
|
+
const response = await fetchImpl(`${baseUrl}/me`, {
|
|
46193
|
+
method: "GET",
|
|
46194
|
+
headers: { "X-Api-Key": apiKey }
|
|
46195
|
+
});
|
|
46196
|
+
if (!response.ok) {
|
|
46197
|
+
return void 0;
|
|
46198
|
+
}
|
|
46199
|
+
const payload = asRecord(await response.json());
|
|
46200
|
+
const user = asRecord(payload?.user);
|
|
46201
|
+
if (!user) {
|
|
46202
|
+
return void 0;
|
|
46203
|
+
}
|
|
46204
|
+
return {
|
|
46205
|
+
source: "pmak/me",
|
|
46206
|
+
userId: coerceId(user.id),
|
|
46207
|
+
fullName: coerceText(user.fullName) ?? coerceText(user.username),
|
|
46208
|
+
teamId: coerceId(user.teamId),
|
|
46209
|
+
teamName: coerceText(user.teamName),
|
|
46210
|
+
teamDomain: coerceText(user.teamDomain)
|
|
46211
|
+
};
|
|
46212
|
+
} catch {
|
|
46213
|
+
return void 0;
|
|
46214
|
+
}
|
|
46215
|
+
}
|
|
46216
|
+
async function resolveSessionIdentity(opts) {
|
|
46217
|
+
const accessToken = String(opts.accessToken || "").trim();
|
|
46218
|
+
if (!accessToken) {
|
|
46219
|
+
return void 0;
|
|
46220
|
+
}
|
|
46221
|
+
const baseUrl = normalizeBaseUrl(opts.iapubBaseUrl);
|
|
46222
|
+
const memoKey = `${baseUrl}::${accessToken}`;
|
|
46223
|
+
let pending = sessionMemo.get(memoKey);
|
|
46224
|
+
if (!pending) {
|
|
46225
|
+
pending = probeSessionIdentity(baseUrl, accessToken, opts.fetchImpl ?? fetch);
|
|
46226
|
+
sessionMemo.set(memoKey, pending);
|
|
46227
|
+
}
|
|
46228
|
+
return pending;
|
|
46229
|
+
}
|
|
46230
|
+
async function probeSessionIdentity(baseUrl, accessToken, fetchImpl) {
|
|
46231
|
+
try {
|
|
46232
|
+
const response = await fetchImpl(`${baseUrl}${sessionPath}`, {
|
|
46233
|
+
method: "GET",
|
|
46234
|
+
headers: { "x-access-token": accessToken }
|
|
46235
|
+
});
|
|
46236
|
+
if (!response.ok) {
|
|
46237
|
+
return void 0;
|
|
46238
|
+
}
|
|
46239
|
+
const payload = asRecord(await response.json());
|
|
46240
|
+
if (!payload) {
|
|
46241
|
+
return void 0;
|
|
46242
|
+
}
|
|
46243
|
+
const root = asRecord(payload.session) ?? payload;
|
|
46244
|
+
const identity = asRecord(root.identity);
|
|
46245
|
+
const data = asRecord(root.data);
|
|
46246
|
+
const user = asRecord(data?.user);
|
|
46247
|
+
const roleEntries = Array.isArray(user?.roles) ? user.roles.map((entry) => coerceText(entry) ?? coerceId(entry)).filter((entry) => Boolean(entry)) : [];
|
|
46248
|
+
const singleRole = coerceText(user?.role);
|
|
46249
|
+
const roles = roleEntries.length > 0 ? roleEntries : singleRole ? [singleRole] : void 0;
|
|
46250
|
+
const resolved = {
|
|
46251
|
+
source: "iapub/sessions",
|
|
46252
|
+
userId: coerceId(identity?.user) ?? coerceId(user?.id),
|
|
46253
|
+
fullName: coerceText(user?.fullName) ?? coerceText(user?.name) ?? coerceText(user?.username),
|
|
46254
|
+
teamId: coerceId(identity?.team),
|
|
46255
|
+
teamName: coerceText(user?.teamName),
|
|
46256
|
+
teamDomain: coerceText(identity?.domain),
|
|
46257
|
+
...roles ? { roles } : {},
|
|
46258
|
+
consumerType: coerceText(root.consumerType) ?? coerceText(data?.consumerType) ?? coerceText(user?.consumerType)
|
|
46259
|
+
};
|
|
46260
|
+
memoizedSessionIdentity = resolved;
|
|
46261
|
+
return resolved;
|
|
46262
|
+
} catch {
|
|
46263
|
+
return void 0;
|
|
46264
|
+
}
|
|
46265
|
+
}
|
|
46266
|
+
function describeTeam(id) {
|
|
46267
|
+
const label = id?.teamName ?? id?.teamDomain;
|
|
46268
|
+
return `team ${id?.teamId ?? "unresolved"}${label ? ` (${label})` : ""}`;
|
|
46269
|
+
}
|
|
46270
|
+
function formatIdentityLine(id, mask) {
|
|
46271
|
+
const teamPart = id.teamId ? describeTeam(id) : "team unresolved";
|
|
46272
|
+
const domainPart = id.teamDomain ? `, domain ${id.teamDomain}` : "";
|
|
46273
|
+
if (id.source === "pmak/me") {
|
|
46274
|
+
const userPart = id.userId ? `user ${id.userId}${id.fullName ? ` (${id.fullName})` : ""}, ` : "";
|
|
46275
|
+
return mask(`postman: PMAK identity - ${userPart}${teamPart}${domainPart}`);
|
|
46276
|
+
}
|
|
46277
|
+
return mask(
|
|
46278
|
+
`postman: access-token session identity - ${teamPart}${domainPart} [source: iapub/sessions]`
|
|
46279
|
+
);
|
|
46280
|
+
}
|
|
46281
|
+
function crossCheckIdentities(args) {
|
|
46282
|
+
if (args.mode === "off") {
|
|
46283
|
+
return { ok: true, level: "ok", message: "" };
|
|
46284
|
+
}
|
|
46285
|
+
const pmakTeamId = args.pmak?.teamId;
|
|
46286
|
+
const sessionTeamId = args.session?.teamId;
|
|
46287
|
+
if (pmakTeamId && sessionTeamId && pmakTeamId !== sessionTeamId) {
|
|
46288
|
+
const level = args.mode === "enforce" ? "fail" : "note";
|
|
46289
|
+
const lead = level === "fail" ? "credential preflight FAILED" : "credential preflight note";
|
|
46290
|
+
const fix = level === "fail" ? "Use one credential pair from a single parent org: re-mint the access token from the same parent org as postman-api-key (postman-resolve-service-token-action, or POST https://api.getpostman.com/service-account-tokens with that team's PMAK), or set postman-api-key to the matching parent org." : "Use one credential pair from a single parent org. Set credential-preflight: enforce to fail the run on this condition.";
|
|
46291
|
+
return {
|
|
46292
|
+
ok: false,
|
|
46293
|
+
level,
|
|
46294
|
+
message: args.mask(
|
|
46295
|
+
`postman: ${lead} - PMAK belongs to ${describeTeam(args.pmak)} but the access token's session belongs to a different parent org, ${describeTeam(args.session)}. Assets would be created against one team while Bifrost linking and governance act under the other, producing duplicate-link 400s and workspaces not visible to the other credential. ` + fix
|
|
46296
|
+
)
|
|
46297
|
+
};
|
|
46298
|
+
}
|
|
46299
|
+
if (pmakTeamId && sessionTeamId) {
|
|
46300
|
+
const scope = args.workspaceTeamId || args.explicitTeamId ? "parent org team" : "team";
|
|
46301
|
+
const label = args.pmak?.teamName ?? args.pmak?.teamDomain ?? args.session?.teamName ?? args.session?.teamDomain;
|
|
46302
|
+
return {
|
|
46303
|
+
ok: true,
|
|
46304
|
+
level: "ok",
|
|
46305
|
+
message: args.mask(
|
|
46306
|
+
`postman: credential preflight OK - PMAK and access token both resolve to ${scope} ${pmakTeamId}${label ? ` (${label})` : ""}`
|
|
46307
|
+
)
|
|
46308
|
+
};
|
|
46309
|
+
}
|
|
46310
|
+
const missing = [
|
|
46311
|
+
!pmakTeamId ? "PMAK identity" : void 0,
|
|
46312
|
+
!sessionTeamId ? "access-token session identity" : void 0
|
|
46313
|
+
].filter(Boolean).join(" and ");
|
|
46314
|
+
return {
|
|
46315
|
+
ok: false,
|
|
46316
|
+
level: "note",
|
|
46317
|
+
message: args.mask(
|
|
46318
|
+
`postman: credential preflight note - cross-check skipped because the ${missing} did not resolve a team id; continuing with reactive error guidance only`
|
|
46319
|
+
)
|
|
46320
|
+
};
|
|
46321
|
+
}
|
|
46322
|
+
async function runCredentialPreflight(args) {
|
|
46323
|
+
if (args.mode === "off") {
|
|
46324
|
+
return;
|
|
46325
|
+
}
|
|
46326
|
+
const mask = args.mask;
|
|
46327
|
+
const apiKey = String(args.postmanApiKey || "").trim();
|
|
46328
|
+
const accessToken = String(args.postmanAccessToken || "").trim();
|
|
46329
|
+
let pmak;
|
|
46330
|
+
if (apiKey) {
|
|
46331
|
+
try {
|
|
46332
|
+
pmak = await resolvePmakIdentity({
|
|
46333
|
+
apiBaseUrl: args.apiBaseUrl,
|
|
46334
|
+
apiKey,
|
|
46335
|
+
fetchImpl: args.fetchImpl
|
|
46336
|
+
});
|
|
46337
|
+
} catch (error) {
|
|
46338
|
+
args.log.warning(
|
|
46339
|
+
mask(
|
|
46340
|
+
`postman: credential preflight could not resolve PMAK identity: ${error instanceof Error ? error.message : String(error)}`
|
|
46341
|
+
)
|
|
46342
|
+
);
|
|
46343
|
+
}
|
|
46344
|
+
if (pmak) {
|
|
46345
|
+
args.log.info(formatIdentityLine(pmak, mask));
|
|
46346
|
+
} else {
|
|
46347
|
+
args.log.warning(
|
|
46348
|
+
mask("postman: credential preflight could not resolve PMAK identity from GET /me; continuing")
|
|
46349
|
+
);
|
|
46350
|
+
}
|
|
46351
|
+
}
|
|
46352
|
+
if (!accessToken) {
|
|
46353
|
+
args.log.info(mask("postman: Bifrost diagnostics limited: no access token"));
|
|
46354
|
+
return;
|
|
46355
|
+
}
|
|
46356
|
+
let session;
|
|
46357
|
+
try {
|
|
46358
|
+
session = await resolveSessionIdentity({
|
|
46359
|
+
iapubBaseUrl: args.iapubBaseUrl,
|
|
46360
|
+
accessToken,
|
|
46361
|
+
fetchImpl: args.fetchImpl
|
|
46362
|
+
});
|
|
46363
|
+
} catch (error) {
|
|
46364
|
+
args.log.warning(
|
|
46365
|
+
mask(
|
|
46366
|
+
`postman: credential preflight could not resolve access-token session identity: ${error instanceof Error ? error.message : String(error)}`
|
|
46367
|
+
)
|
|
46368
|
+
);
|
|
46369
|
+
}
|
|
46370
|
+
if (session) {
|
|
46371
|
+
args.log.info(formatIdentityLine(session, mask));
|
|
46372
|
+
} else {
|
|
46373
|
+
args.log.warning(
|
|
46374
|
+
mask(
|
|
46375
|
+
"postman: credential preflight could not resolve the access-token session identity from iapub; continuing with reactive error guidance only"
|
|
46376
|
+
)
|
|
46377
|
+
);
|
|
46378
|
+
}
|
|
46379
|
+
const result = crossCheckIdentities({
|
|
46380
|
+
pmak,
|
|
46381
|
+
session,
|
|
46382
|
+
workspaceTeamId: args.workspaceTeamId,
|
|
46383
|
+
explicitTeamId: args.explicitTeamId,
|
|
46384
|
+
mode: args.mode,
|
|
46385
|
+
mask
|
|
46386
|
+
});
|
|
46387
|
+
if (!result.message) {
|
|
46388
|
+
return;
|
|
46389
|
+
}
|
|
46390
|
+
if (result.level === "fail") {
|
|
46391
|
+
throw new Error(result.message);
|
|
46392
|
+
}
|
|
46393
|
+
if (result.level === "note") {
|
|
46394
|
+
args.log.warning(result.message);
|
|
46395
|
+
return;
|
|
46396
|
+
}
|
|
46397
|
+
args.log.info(result.message);
|
|
46398
|
+
}
|
|
46154
46399
|
|
|
46155
46400
|
// src/lib/postman/error-advice.ts
|
|
46156
46401
|
var WORKSPACE_PERSONAL_ONLY_ADVICE = "Workspace creation failed: This may be an Org-mode account that requires a workspace-team-id input. The Postman API does not allow creating team workspaces at the organization level. Use the workspace-team-id input to specify which sub-team should own this workspace.";
|
|
@@ -46256,7 +46501,7 @@ async function retry(operation, options = {}) {
|
|
|
46256
46501
|
}
|
|
46257
46502
|
|
|
46258
46503
|
// src/lib/postman/postman-assets-client.ts
|
|
46259
|
-
function
|
|
46504
|
+
function asRecord2(value) {
|
|
46260
46505
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
46261
46506
|
return null;
|
|
46262
46507
|
}
|
|
@@ -46264,8 +46509,8 @@ function asRecord(value) {
|
|
|
46264
46509
|
}
|
|
46265
46510
|
function extractWorkspacesPage(data) {
|
|
46266
46511
|
const workspaces = Array.isArray(data?.workspaces) ? data.workspaces : [];
|
|
46267
|
-
const meta =
|
|
46268
|
-
const pagination =
|
|
46512
|
+
const meta = asRecord2(data?.meta);
|
|
46513
|
+
const pagination = asRecord2(data?.pagination);
|
|
46269
46514
|
const nextCursor = String(
|
|
46270
46515
|
data?.nextCursor ?? data?.next_cursor ?? meta?.nextCursor ?? meta?.next_cursor ?? pagination?.nextCursor ?? pagination?.next_cursor ?? ""
|
|
46271
46516
|
).trim() || void 0;
|
|
@@ -46357,7 +46602,7 @@ var PostmanAssetsClient = class {
|
|
|
46357
46602
|
async getTeams() {
|
|
46358
46603
|
const data = await this.request("/teams");
|
|
46359
46604
|
const teams = data?.data ?? [];
|
|
46360
|
-
return Array.isArray(teams) ? teams.map((entry) =>
|
|
46605
|
+
return Array.isArray(teams) ? teams.map((entry) => asRecord2(entry)).filter((team) => Boolean(team?.id && team?.name)).map((team) => ({
|
|
46361
46606
|
id: Number(team.id),
|
|
46362
46607
|
name: String(team.name),
|
|
46363
46608
|
handle: String(team.handle || ""),
|
|
@@ -46417,20 +46662,20 @@ var PostmanAssetsClient = class {
|
|
|
46417
46662
|
}
|
|
46418
46663
|
throw err;
|
|
46419
46664
|
}
|
|
46420
|
-
const createdWorkspace =
|
|
46665
|
+
const createdWorkspace = asRecord2(created?.workspace);
|
|
46421
46666
|
const workspaceId = String(createdWorkspace?.id || "").trim();
|
|
46422
46667
|
if (!workspaceId) {
|
|
46423
46668
|
throw new Error("Workspace create did not return an id");
|
|
46424
46669
|
}
|
|
46425
46670
|
const workspace = await this.request(`/workspaces/${workspaceId}`);
|
|
46426
|
-
let visibility =
|
|
46671
|
+
let visibility = asRecord2(workspace?.workspace)?.visibility;
|
|
46427
46672
|
if (visibility !== "team") {
|
|
46428
46673
|
await this.request(`/workspaces/${workspaceId}`, {
|
|
46429
46674
|
method: "PUT",
|
|
46430
46675
|
body: JSON.stringify(payload)
|
|
46431
46676
|
});
|
|
46432
46677
|
const reread = await this.request(`/workspaces/${workspaceId}`);
|
|
46433
|
-
visibility =
|
|
46678
|
+
visibility = asRecord2(reread?.workspace)?.visibility;
|
|
46434
46679
|
}
|
|
46435
46680
|
if (typeof visibility === "string" && visibility !== "team") {
|
|
46436
46681
|
let cleanedUp = false;
|
|
@@ -46459,7 +46704,7 @@ var PostmanAssetsClient = class {
|
|
|
46459
46704
|
async getWorkspaceVisibility(workspaceId) {
|
|
46460
46705
|
try {
|
|
46461
46706
|
const workspace = await this.request(`/workspaces/${workspaceId}`);
|
|
46462
|
-
const visibility =
|
|
46707
|
+
const visibility = asRecord2(workspace?.workspace)?.visibility;
|
|
46463
46708
|
return typeof visibility === "string" ? visibility : null;
|
|
46464
46709
|
} catch {
|
|
46465
46710
|
return null;
|
|
@@ -46481,7 +46726,7 @@ var PostmanAssetsClient = class {
|
|
|
46481
46726
|
nextCursor = page.nextCursor;
|
|
46482
46727
|
}
|
|
46483
46728
|
} while (nextCursor);
|
|
46484
|
-
return allWorkspaces.map((entry) =>
|
|
46729
|
+
return allWorkspaces.map((entry) => asRecord2(entry)).filter((workspace) => Boolean(workspace?.id && workspace?.name)).map((workspace) => ({
|
|
46485
46730
|
id: String(workspace.id),
|
|
46486
46731
|
name: String(workspace.name),
|
|
46487
46732
|
type: String(workspace.type ?? "team")
|
|
@@ -46529,7 +46774,7 @@ var PostmanAssetsClient = class {
|
|
|
46529
46774
|
async inviteRequesterToWorkspace(workspaceId, email) {
|
|
46530
46775
|
const users = await this.request("/users");
|
|
46531
46776
|
const userList = Array.isArray(users?.data) ? users.data : [];
|
|
46532
|
-
const user = userList.map((entry) =>
|
|
46777
|
+
const user = userList.map((entry) => asRecord2(entry)).find((entry) => entry?.email === email);
|
|
46533
46778
|
if (!user?.id) {
|
|
46534
46779
|
return;
|
|
46535
46780
|
}
|
|
@@ -46617,12 +46862,12 @@ var PostmanAssetsClient = class {
|
|
|
46617
46862
|
}
|
|
46618
46863
|
};
|
|
46619
46864
|
const extractUid = (data) => {
|
|
46620
|
-
const root =
|
|
46621
|
-
const details =
|
|
46865
|
+
const root = asRecord2(data);
|
|
46866
|
+
const details = asRecord2(root?.details);
|
|
46622
46867
|
const resources = Array.isArray(details?.resources) ? details.resources : [];
|
|
46623
|
-
const firstResource =
|
|
46624
|
-
const collection =
|
|
46625
|
-
const resource =
|
|
46868
|
+
const firstResource = asRecord2(resources[0]);
|
|
46869
|
+
const collection = asRecord2(root?.collection);
|
|
46870
|
+
const resource = asRecord2(root?.resource);
|
|
46626
46871
|
return String(
|
|
46627
46872
|
firstResource?.id ?? collection?.id ?? collection?.uid ?? resource?.uid ?? resource?.id ?? ""
|
|
46628
46873
|
).trim() || void 0;
|
|
@@ -46656,9 +46901,9 @@ var PostmanAssetsClient = class {
|
|
|
46656
46901
|
if (directUid) {
|
|
46657
46902
|
return directUid;
|
|
46658
46903
|
}
|
|
46659
|
-
let taskUrl = String(generationResponse?.url ?? "") || String(generationResponse?.task_url ?? "") || String(generationResponse?.taskUrl ?? "") || String(
|
|
46904
|
+
let taskUrl = String(generationResponse?.url ?? "") || String(generationResponse?.task_url ?? "") || String(generationResponse?.taskUrl ?? "") || String(asRecord2(generationResponse?.links)?.task ?? "");
|
|
46660
46905
|
if (!taskUrl) {
|
|
46661
|
-
const task =
|
|
46906
|
+
const task = asRecord2(generationResponse?.task);
|
|
46662
46907
|
const taskId = generationResponse?.taskId || task?.id || generationResponse?.id;
|
|
46663
46908
|
if (!taskId) {
|
|
46664
46909
|
throw new Error(
|
|
@@ -46672,8 +46917,8 @@ var PostmanAssetsClient = class {
|
|
|
46672
46917
|
setTimeout(resolve3, 2e3);
|
|
46673
46918
|
});
|
|
46674
46919
|
const task = await this.request(taskUrl);
|
|
46675
|
-
const taskRecord =
|
|
46676
|
-
const taskNested =
|
|
46920
|
+
const taskRecord = asRecord2(task);
|
|
46921
|
+
const taskNested = asRecord2(taskRecord?.task);
|
|
46677
46922
|
const status = String(taskRecord?.status || taskNested?.status || "").toLowerCase();
|
|
46678
46923
|
if (status === "completed") {
|
|
46679
46924
|
const taskUid = extractUid(task);
|
|
@@ -46704,7 +46949,7 @@ var PostmanAssetsClient = class {
|
|
|
46704
46949
|
}
|
|
46705
46950
|
async injectTests(collectionUid, type2) {
|
|
46706
46951
|
const collectionResponse = await this.request(`/collections/${collectionUid}`);
|
|
46707
|
-
const collection =
|
|
46952
|
+
const collection = asRecord2(collectionResponse?.collection);
|
|
46708
46953
|
if (!collection) {
|
|
46709
46954
|
throw new Error(`Failed to fetch collection ${collectionUid}`);
|
|
46710
46955
|
}
|
|
@@ -46790,7 +47035,7 @@ var PostmanAssetsClient = class {
|
|
|
46790
47035
|
});
|
|
46791
47036
|
}
|
|
46792
47037
|
if (Array.isArray(itemNode.item)) {
|
|
46793
|
-
itemNode.item.map((entry) =>
|
|
47038
|
+
itemNode.item.map((entry) => asRecord2(entry)).filter((entry) => Boolean(entry)).forEach(injectScripts);
|
|
46794
47039
|
}
|
|
46795
47040
|
};
|
|
46796
47041
|
if (Array.isArray(collection.item)) {
|
|
@@ -46818,7 +47063,7 @@ var PostmanAssetsClient = class {
|
|
|
46818
47063
|
}
|
|
46819
47064
|
})
|
|
46820
47065
|
});
|
|
46821
|
-
const environment =
|
|
47066
|
+
const environment = asRecord2(response?.environment);
|
|
46822
47067
|
const uid = String(environment?.uid || "").trim();
|
|
46823
47068
|
if (!uid) {
|
|
46824
47069
|
throw new Error("Environment create did not return a UID");
|
|
@@ -46851,7 +47096,7 @@ var PostmanAssetsClient = class {
|
|
|
46851
47096
|
}
|
|
46852
47097
|
})
|
|
46853
47098
|
});
|
|
46854
|
-
const monitor =
|
|
47099
|
+
const monitor = asRecord2(response?.monitor);
|
|
46855
47100
|
const uid = String(monitor?.uid || "").trim();
|
|
46856
47101
|
if (!uid) {
|
|
46857
47102
|
throw new Error("Monitor create did not return a UID");
|
|
@@ -46870,8 +47115,8 @@ var PostmanAssetsClient = class {
|
|
|
46870
47115
|
}
|
|
46871
47116
|
})
|
|
46872
47117
|
});
|
|
46873
|
-
const mock =
|
|
46874
|
-
const mockConfig =
|
|
47118
|
+
const mock = asRecord2(response?.mock);
|
|
47119
|
+
const mockConfig = asRecord2(mock?.config);
|
|
46875
47120
|
const uid = String(mock?.uid || "").trim();
|
|
46876
47121
|
if (!uid) {
|
|
46877
47122
|
throw new Error("Mock create did not return a UID");
|
|
@@ -47743,7 +47988,7 @@ var STRIP_KEYS = /* @__PURE__ */ new Set([
|
|
|
47743
47988
|
"discriminator",
|
|
47744
47989
|
"format"
|
|
47745
47990
|
]);
|
|
47746
|
-
function
|
|
47991
|
+
function asRecord3(value) {
|
|
47747
47992
|
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
47748
47993
|
return value;
|
|
47749
47994
|
}
|
|
@@ -47755,7 +48000,7 @@ function decodePointerSegment(segment) {
|
|
|
47755
48000
|
}
|
|
47756
48001
|
function resolvePointer(root, ref) {
|
|
47757
48002
|
if (!ref.startsWith("#/")) return void 0;
|
|
47758
|
-
return ref.slice(2).split("/").map(decodePointerSegment).reduce((node, segment) =>
|
|
48003
|
+
return ref.slice(2).split("/").map(decodePointerSegment).reduce((node, segment) => asRecord3(node)?.[segment], root);
|
|
47759
48004
|
}
|
|
47760
48005
|
function unsupported(message) {
|
|
47761
48006
|
return { unsupported: message };
|
|
@@ -47765,7 +48010,7 @@ function mergeRequiredWithoutWriteOnly(required, writeOnlyProperties) {
|
|
|
47765
48010
|
return values.length > 0 ? values : void 0;
|
|
47766
48011
|
}
|
|
47767
48012
|
function hasUnsupported(child) {
|
|
47768
|
-
return
|
|
48013
|
+
return asRecord3(child)?.unsupported;
|
|
47769
48014
|
}
|
|
47770
48015
|
function rootDialect(root, version, schemaRecord) {
|
|
47771
48016
|
if (version === "3.0") return DRAFT_07_SCHEMA_URI;
|
|
@@ -47785,7 +48030,7 @@ function normalizeSchema(root, schema2, options) {
|
|
|
47785
48030
|
const bad = normalized2.map(hasUnsupported).find(Boolean);
|
|
47786
48031
|
return bad ? unsupported(bad) : normalized2;
|
|
47787
48032
|
}
|
|
47788
|
-
const record =
|
|
48033
|
+
const record = asRecord3(schema2);
|
|
47789
48034
|
if (!record) return schema2;
|
|
47790
48035
|
const ref = typeof record.$ref === "string" ? record.$ref : "";
|
|
47791
48036
|
if (ref) {
|
|
@@ -47820,10 +48065,10 @@ function normalizeSchema(root, schema2, options) {
|
|
|
47820
48065
|
const nullable = sourceSchema.nullable === true && options.version === "3.0";
|
|
47821
48066
|
delete sourceSchema.nullable;
|
|
47822
48067
|
const writeOnlyProperties = /* @__PURE__ */ new Set();
|
|
47823
|
-
const rawProperties =
|
|
48068
|
+
const rawProperties = asRecord3(sourceSchema.properties);
|
|
47824
48069
|
if (rawProperties) {
|
|
47825
48070
|
for (const [propertyName, propertySchema] of Object.entries(rawProperties)) {
|
|
47826
|
-
if (
|
|
48071
|
+
if (asRecord3(propertySchema)?.writeOnly === true) writeOnlyProperties.add(propertyName);
|
|
47827
48072
|
}
|
|
47828
48073
|
}
|
|
47829
48074
|
const normalized = {};
|
|
@@ -47855,7 +48100,7 @@ function normalizeSchema(root, schema2, options) {
|
|
|
47855
48100
|
return unsupported("Tuple array items are unsupported in OpenAPI 3.0");
|
|
47856
48101
|
}
|
|
47857
48102
|
if (key === "properties") {
|
|
47858
|
-
const properties =
|
|
48103
|
+
const properties = asRecord3(value);
|
|
47859
48104
|
if (!properties) continue;
|
|
47860
48105
|
const nextProperties = {};
|
|
47861
48106
|
for (const [propertyName, propertySchema] of Object.entries(properties)) {
|
|
@@ -47898,7 +48143,7 @@ function normalizeSchema(root, schema2, options) {
|
|
|
47898
48143
|
}
|
|
47899
48144
|
function packSchema(root, schema2, version) {
|
|
47900
48145
|
try {
|
|
47901
|
-
const dialect = rootDialect(root, version,
|
|
48146
|
+
const dialect = rootDialect(root, version, asRecord3(schema2) ?? void 0);
|
|
47902
48147
|
const normalized = normalizeSchema(root, schema2, { version, rootSchema: true, dialect });
|
|
47903
48148
|
const message = hasUnsupported(normalized);
|
|
47904
48149
|
return message ? unsupported(message) : { schema: normalized };
|
|
@@ -47909,7 +48154,7 @@ function packSchema(root, schema2, version) {
|
|
|
47909
48154
|
|
|
47910
48155
|
// src/lib/spec/contract-index.ts
|
|
47911
48156
|
var HTTP_METHODS = /* @__PURE__ */ new Set(["get", "put", "post", "delete", "options", "head", "patch", "trace"]);
|
|
47912
|
-
function
|
|
48157
|
+
function asRecord4(value) {
|
|
47913
48158
|
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
47914
48159
|
return value;
|
|
47915
48160
|
}
|
|
@@ -47926,12 +48171,12 @@ function detectOpenApiVersion(root) {
|
|
|
47926
48171
|
return match[1] === "1" ? "3.1" : "3.0";
|
|
47927
48172
|
}
|
|
47928
48173
|
function resolveInternalRef(root, value) {
|
|
47929
|
-
const record =
|
|
48174
|
+
const record = asRecord4(value);
|
|
47930
48175
|
if (!record) return null;
|
|
47931
48176
|
const ref = typeof record.$ref === "string" ? record.$ref : "";
|
|
47932
48177
|
if (!ref) return record;
|
|
47933
48178
|
if (!ref.startsWith("#/")) throw new Error(`CONTRACT_UNRESOLVED_REF: External ref remained after bundling: ${ref}`);
|
|
47934
|
-
const resolved =
|
|
48179
|
+
const resolved = asRecord4(resolvePointer(root, ref));
|
|
47935
48180
|
if (!resolved) throw new Error(`CONTRACT_UNRESOLVED_REF: Unresolved OpenAPI $ref: ${ref}`);
|
|
47936
48181
|
return resolved;
|
|
47937
48182
|
}
|
|
@@ -47951,11 +48196,11 @@ function normalizePath(path6) {
|
|
|
47951
48196
|
return trimmed.split("/").map((segment, index) => index === 0 ? "" : safeDecodeSegment(segment)).join("/") || "/";
|
|
47952
48197
|
}
|
|
47953
48198
|
function pathItemServers(pathItem) {
|
|
47954
|
-
return asArray2(pathItem.servers).map((entry) =>
|
|
48199
|
+
return asArray2(pathItem.servers).map((entry) => asRecord4(entry)).map((entry) => typeof entry?.url === "string" ? entry.url : "").filter(Boolean);
|
|
47955
48200
|
}
|
|
47956
48201
|
function operationServers(root, pathItem, operation) {
|
|
47957
48202
|
const rawServers = asArray2(operation.servers).length > 0 ? asArray2(operation.servers) : pathItemServers(pathItem).length > 0 ? asArray2(pathItem.servers) : asArray2(root.servers);
|
|
47958
|
-
const values = rawServers.map((entry) =>
|
|
48203
|
+
const values = rawServers.map((entry) => asRecord4(entry)).map((entry) => typeof entry?.url === "string" ? entry.url : "").filter(Boolean);
|
|
47959
48204
|
return values.length > 0 ? values : [""];
|
|
47960
48205
|
}
|
|
47961
48206
|
function serverPathPrefix(url) {
|
|
@@ -47976,10 +48221,10 @@ function normalizeResponseKey(status) {
|
|
|
47976
48221
|
return /^[1-5]xx$/i.test(raw) ? raw.toUpperCase() : raw;
|
|
47977
48222
|
}
|
|
47978
48223
|
function collectSecurityApiKeys(root, operation) {
|
|
47979
|
-
const securitySchemes =
|
|
48224
|
+
const securitySchemes = asRecord4(asRecord4(root.components)?.securitySchemes);
|
|
47980
48225
|
const requirements = operation.security === void 0 ? asArray2(root.security) : asArray2(operation.security);
|
|
47981
48226
|
const names = /* @__PURE__ */ new Set();
|
|
47982
|
-
for (const requirement of requirements.map((entry) =>
|
|
48227
|
+
for (const requirement of requirements.map((entry) => asRecord4(entry)).filter(Boolean)) {
|
|
47983
48228
|
for (const schemeName of Object.keys(requirement)) {
|
|
47984
48229
|
const scheme = resolveInternalRef(root, securitySchemes?.[schemeName]);
|
|
47985
48230
|
if (scheme?.type === "apiKey" && typeof scheme.name === "string" && ["query", "header"].includes(String(scheme.in))) {
|
|
@@ -47997,10 +48242,10 @@ function securitySchemeKind(scheme) {
|
|
|
47997
48242
|
return type2;
|
|
47998
48243
|
}
|
|
47999
48244
|
function collectSecuritySchemeWarnings(root, operation) {
|
|
48000
|
-
const securitySchemes =
|
|
48245
|
+
const securitySchemes = asRecord4(asRecord4(root.components)?.securitySchemes);
|
|
48001
48246
|
const requirements = operation.security === void 0 ? asArray2(root.security) : asArray2(operation.security);
|
|
48002
48247
|
const warnings = /* @__PURE__ */ new Set();
|
|
48003
|
-
for (const requirement of requirements.map((entry) =>
|
|
48248
|
+
for (const requirement of requirements.map((entry) => asRecord4(entry)).filter(Boolean)) {
|
|
48004
48249
|
for (const schemeName of Object.keys(requirement)) {
|
|
48005
48250
|
const scheme = resolveInternalRef(root, securitySchemes?.[schemeName]);
|
|
48006
48251
|
warnings.add(
|
|
@@ -48036,24 +48281,24 @@ function collectParameters(root, pathItem, operation) {
|
|
|
48036
48281
|
function collectRequestBody(root, operation) {
|
|
48037
48282
|
const body = resolveInternalRef(root, operation.requestBody);
|
|
48038
48283
|
if (!body || body.required !== true) return void 0;
|
|
48039
|
-
const content =
|
|
48284
|
+
const content = asRecord4(body.content);
|
|
48040
48285
|
return {
|
|
48041
48286
|
required: true,
|
|
48042
48287
|
contentTypes: content ? Object.keys(content) : []
|
|
48043
48288
|
};
|
|
48044
48289
|
}
|
|
48045
48290
|
function responseContent(root, version, response) {
|
|
48046
|
-
const content =
|
|
48291
|
+
const content = asRecord4(response.content);
|
|
48047
48292
|
if (!content) return {};
|
|
48048
48293
|
const media = {};
|
|
48049
48294
|
for (const [contentType, mediaObject] of Object.entries(content)) {
|
|
48050
|
-
const schema2 =
|
|
48295
|
+
const schema2 = asRecord4(mediaObject)?.schema;
|
|
48051
48296
|
media[contentType] = schema2 === void 0 ? {} : packSchema(root, schema2, version);
|
|
48052
48297
|
}
|
|
48053
48298
|
return media;
|
|
48054
48299
|
}
|
|
48055
48300
|
function responseHeaders(root, version, response) {
|
|
48056
|
-
const headers =
|
|
48301
|
+
const headers = asRecord4(response.headers);
|
|
48057
48302
|
if (!headers) return [];
|
|
48058
48303
|
return Object.entries(headers).map(([name, rawHeader]) => {
|
|
48059
48304
|
const header = resolveInternalRef(root, rawHeader);
|
|
@@ -48068,10 +48313,10 @@ function buildContractIndex(root) {
|
|
|
48068
48313
|
if (root.swagger === "2.0") throw new Error("CONTRACT_UNSUPPORTED_OPENAPI_VERSION: Dynamic contract tests require OpenAPI 3.0 or 3.1 (found swagger 2.0)");
|
|
48069
48314
|
if (!("openapi" in root)) throw new Error("CONTRACT_UNSUPPORTED_OPENAPI_VERSION: Dynamic contract tests require OpenAPI 3.0 or 3.1 (missing openapi)");
|
|
48070
48315
|
const version = detectOpenApiVersion(root);
|
|
48071
|
-
const paths =
|
|
48316
|
+
const paths = asRecord4(root.paths);
|
|
48072
48317
|
const operations = [];
|
|
48073
48318
|
const warnings = [];
|
|
48074
|
-
if (
|
|
48319
|
+
if (asRecord4(root.webhooks)) warnings.push("CONTRACT_WEBHOOKS_NOT_VALIDATED: OpenAPI webhooks are not validated by dynamic contract tests");
|
|
48075
48320
|
if (paths) {
|
|
48076
48321
|
for (const [path6, rawPathItem] of Object.entries(paths)) {
|
|
48077
48322
|
const pathItem = resolveInternalRef(root, rawPathItem);
|
|
@@ -48082,7 +48327,7 @@ function buildContractIndex(root) {
|
|
|
48082
48327
|
const operation = resolveInternalRef(root, rawOperation);
|
|
48083
48328
|
if (!operation) continue;
|
|
48084
48329
|
if (operation.callbacks) warnings.push(`CONTRACT_CALLBACKS_NOT_VALIDATED: callbacks are not validated for ${lowerMethod.toUpperCase()} ${path6}`);
|
|
48085
|
-
const responses =
|
|
48330
|
+
const responses = asRecord4(operation.responses);
|
|
48086
48331
|
if (!responses || Object.keys(responses).length === 0) {
|
|
48087
48332
|
throw new Error(`CONTRACT_OPERATION_NO_RESPONSES: ${lowerMethod.toUpperCase()} ${path6} must define at least one response`);
|
|
48088
48333
|
}
|
|
@@ -48172,7 +48417,7 @@ var CONTRACT_SIZE_LIMITS = {
|
|
|
48172
48417
|
maxTestScriptBytes: 9e5,
|
|
48173
48418
|
maxCollectionUpdateBytes: 4e6
|
|
48174
48419
|
};
|
|
48175
|
-
function
|
|
48420
|
+
function asRecord5(value) {
|
|
48176
48421
|
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
48177
48422
|
return value;
|
|
48178
48423
|
}
|
|
@@ -48181,7 +48426,7 @@ function asArray3(value) {
|
|
|
48181
48426
|
}
|
|
48182
48427
|
function stringifyPathSegment(segment) {
|
|
48183
48428
|
if (typeof segment === "string") return segment;
|
|
48184
|
-
const record =
|
|
48429
|
+
const record = asRecord5(segment);
|
|
48185
48430
|
if (!record) return String(segment ?? "");
|
|
48186
48431
|
for (const key of ["value", "key", "name"]) {
|
|
48187
48432
|
if (typeof record[key] === "string" && record[key]) return String(record[key]);
|
|
@@ -48199,10 +48444,10 @@ function pathFromRaw(raw) {
|
|
|
48199
48444
|
}
|
|
48200
48445
|
}
|
|
48201
48446
|
function requestPath(request) {
|
|
48202
|
-
const record =
|
|
48447
|
+
const record = asRecord5(request);
|
|
48203
48448
|
const url = record?.url ?? request;
|
|
48204
48449
|
if (typeof url === "string") return pathFromRaw(url);
|
|
48205
|
-
const urlRecord =
|
|
48450
|
+
const urlRecord = asRecord5(url);
|
|
48206
48451
|
if (!urlRecord) return "/";
|
|
48207
48452
|
if (Array.isArray(urlRecord.path)) return normalizePath(`/${urlRecord.path.map(stringifyPathSegment).filter(Boolean).join("/")}`);
|
|
48208
48453
|
if (typeof urlRecord.path === "string") return normalizePath(urlRecord.path);
|
|
@@ -48234,7 +48479,7 @@ function matchCandidate(candidate, request) {
|
|
|
48234
48479
|
return { matched: true, staticCount, templateCount };
|
|
48235
48480
|
}
|
|
48236
48481
|
function matchOperation(index, request) {
|
|
48237
|
-
const record =
|
|
48482
|
+
const record = asRecord5(request);
|
|
48238
48483
|
const method = String(record?.method || "").toUpperCase();
|
|
48239
48484
|
const path6 = requestPath(request);
|
|
48240
48485
|
const candidates = index.operations.filter((operation) => operation.method === method).flatMap((operation) => operation.candidates.map((candidate) => ({ operation, score: matchCandidate(candidate, path6), serverFull: candidate !== normalizePath(operation.path) }))).filter((entry) => entry.score.matched).map((entry) => ({ operation: entry.operation, score: [entry.score.staticCount, entry.serverFull ? 2 : 1, -entry.score.templateCount] })).sort((a, b) => {
|
|
@@ -48385,17 +48630,17 @@ function createSecretsResolverItem() {
|
|
|
48385
48630
|
}
|
|
48386
48631
|
function isResolverItem(item) {
|
|
48387
48632
|
if (item.name !== "00 - Resolve Secrets") return false;
|
|
48388
|
-
const request =
|
|
48633
|
+
const request = asRecord5(item.request);
|
|
48389
48634
|
if (String(request?.method || "").toUpperCase() !== "POST") return false;
|
|
48390
|
-
const headers = asArray3(request?.header).map((entry) =>
|
|
48635
|
+
const headers = asArray3(request?.header).map((entry) => asRecord5(entry));
|
|
48391
48636
|
const target = headers.find((entry) => entry?.key === "X-Amz-Target");
|
|
48392
48637
|
return String(target?.value || "") === "secretsmanager.GetSecretValue" && !requestPath(request).includes("secretsmanager");
|
|
48393
48638
|
}
|
|
48394
48639
|
function requestQueryNames(request) {
|
|
48395
|
-
const url =
|
|
48640
|
+
const url = asRecord5(request.url);
|
|
48396
48641
|
const names = /* @__PURE__ */ new Set();
|
|
48397
48642
|
if (Array.isArray(url?.query)) {
|
|
48398
|
-
for (const entry of url.query.map((item) =>
|
|
48643
|
+
for (const entry of url.query.map((item) => asRecord5(item)).filter(Boolean)) {
|
|
48399
48644
|
if (entry.disabled !== true && typeof entry.key === "string") names.add(entry.key.toLowerCase());
|
|
48400
48645
|
}
|
|
48401
48646
|
}
|
|
@@ -48410,17 +48655,17 @@ function requestQueryNames(request) {
|
|
|
48410
48655
|
}
|
|
48411
48656
|
function requestHeaderNames(request) {
|
|
48412
48657
|
const names = /* @__PURE__ */ new Set();
|
|
48413
|
-
for (const entry of asArray3(request.header).map((item) =>
|
|
48658
|
+
for (const entry of asArray3(request.header).map((item) => asRecord5(item)).filter(Boolean)) {
|
|
48414
48659
|
if (entry.disabled !== true && typeof entry.key === "string") names.add(entry.key.toLowerCase());
|
|
48415
48660
|
}
|
|
48416
48661
|
return names;
|
|
48417
48662
|
}
|
|
48418
48663
|
function requestHeaderValue(request, name) {
|
|
48419
|
-
const match = asArray3(request.header).map((item) =>
|
|
48664
|
+
const match = asArray3(request.header).map((item) => asRecord5(item)).filter(Boolean).find((entry) => String(entry.key || "").toLowerCase() === name.toLowerCase() && entry.disabled !== true);
|
|
48420
48665
|
return typeof match?.value === "string" ? match.value : void 0;
|
|
48421
48666
|
}
|
|
48422
48667
|
function hasRequestBody(request) {
|
|
48423
|
-
const body =
|
|
48668
|
+
const body = asRecord5(request.body);
|
|
48424
48669
|
if (!body) return false;
|
|
48425
48670
|
if (typeof body.raw === "string" && body.raw.trim()) return true;
|
|
48426
48671
|
return ["urlencoded", "formdata", "graphql"].some((key) => Array.isArray(body[key]) ? body[key].length > 0 : Boolean(body[key]));
|
|
@@ -48471,21 +48716,21 @@ function validateScript(script) {
|
|
|
48471
48716
|
return void 0;
|
|
48472
48717
|
}
|
|
48473
48718
|
function scriptExecLines(script) {
|
|
48474
|
-
const record =
|
|
48719
|
+
const record = asRecord5(script);
|
|
48475
48720
|
if (!record) return [];
|
|
48476
48721
|
if (Array.isArray(record.exec)) return record.exec.map((line) => String(line));
|
|
48477
48722
|
if (typeof record.exec === "string") return [record.exec];
|
|
48478
48723
|
return [];
|
|
48479
48724
|
}
|
|
48480
48725
|
function scanExecutableScripts(node, warnings) {
|
|
48481
|
-
for (const event of asArray3(node.event).map((entry) =>
|
|
48726
|
+
for (const event of asArray3(node.event).map((entry) => asRecord5(entry)).filter(Boolean)) {
|
|
48482
48727
|
const lines = scriptExecLines(event.script);
|
|
48483
48728
|
if (lines.length === 0) continue;
|
|
48484
48729
|
const warning = validateScript(lines);
|
|
48485
48730
|
if (warning) warnings.push(warning);
|
|
48486
48731
|
}
|
|
48487
48732
|
for (const child of asArray3(node.item)) {
|
|
48488
|
-
const childRecord =
|
|
48733
|
+
const childRecord = asRecord5(child);
|
|
48489
48734
|
if (childRecord) scanExecutableScripts(childRecord, warnings);
|
|
48490
48735
|
}
|
|
48491
48736
|
}
|
|
@@ -48495,7 +48740,7 @@ function instrumentContractCollection(collection, index) {
|
|
|
48495
48740
|
const inject = (item) => {
|
|
48496
48741
|
if (isResolverItem(item)) return;
|
|
48497
48742
|
if (item.request) {
|
|
48498
|
-
const request =
|
|
48743
|
+
const request = asRecord5(item.request) ?? {};
|
|
48499
48744
|
const result = matchOperation(index, request);
|
|
48500
48745
|
let script;
|
|
48501
48746
|
if (result.operation) {
|
|
@@ -48509,15 +48754,15 @@ function instrumentContractCollection(collection, index) {
|
|
|
48509
48754
|
} else {
|
|
48510
48755
|
script = createMappingFailureScript(`No OpenAPI operation matched request ${result.method} ${result.path}`);
|
|
48511
48756
|
}
|
|
48512
|
-
const events = asArray3(item.event).filter((entry) =>
|
|
48757
|
+
const events = asArray3(item.event).filter((entry) => asRecord5(entry)?.listen !== "test");
|
|
48513
48758
|
item.event = [...events, { listen: "test", script: { type: "text/javascript", exec: script } }];
|
|
48514
48759
|
}
|
|
48515
48760
|
for (const child of asArray3(item.item)) {
|
|
48516
|
-
const childRecord =
|
|
48761
|
+
const childRecord = asRecord5(child);
|
|
48517
48762
|
if (childRecord) inject(childRecord);
|
|
48518
48763
|
}
|
|
48519
48764
|
};
|
|
48520
|
-
const items = asArray3(collection.item).map((entry) =>
|
|
48765
|
+
const items = asArray3(collection.item).map((entry) => asRecord5(entry)).filter((entry) => Boolean(entry)).filter((entry) => !isResolverItem(entry));
|
|
48521
48766
|
collection.item = items;
|
|
48522
48767
|
for (const item of items) inject(item);
|
|
48523
48768
|
const missing = index.operations.filter((operation) => !covered.has(operation.id));
|
|
@@ -60881,7 +61126,7 @@ function compileErrors(result) {
|
|
|
60881
61126
|
|
|
60882
61127
|
// src/lib/spec/openapi-loader.ts
|
|
60883
61128
|
var import_yaml2 = __toESM(require_dist(), 1);
|
|
60884
|
-
function
|
|
61129
|
+
function asRecord6(value) {
|
|
60885
61130
|
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
60886
61131
|
return value;
|
|
60887
61132
|
}
|
|
@@ -60896,7 +61141,7 @@ function parseOpenApiDocument(content) {
|
|
|
60896
61141
|
throw new Error("CONTRACT_SPEC_PARSE_FAILED: Spec content is not valid JSON or YAML");
|
|
60897
61142
|
}
|
|
60898
61143
|
}
|
|
60899
|
-
const doc =
|
|
61144
|
+
const doc = asRecord6(parsed);
|
|
60900
61145
|
if (!doc) throw new Error("CONTRACT_SPEC_PARSE_FAILED: Spec content must be a JSON or YAML object");
|
|
60901
61146
|
return doc;
|
|
60902
61147
|
}
|
|
@@ -60924,7 +61169,7 @@ function collectExternalRefs(node, baseUrl, refs) {
|
|
|
60924
61169
|
node.forEach((entry) => collectExternalRefs(entry, baseUrl, refs));
|
|
60925
61170
|
return;
|
|
60926
61171
|
}
|
|
60927
|
-
const record =
|
|
61172
|
+
const record = asRecord6(node);
|
|
60928
61173
|
if (!record) return;
|
|
60929
61174
|
const ref = typeof record.$ref === "string" ? record.$ref : "";
|
|
60930
61175
|
if (ref && !ref.startsWith("#")) {
|
|
@@ -62707,6 +62952,17 @@ async function runCli(argv = process.argv.slice(2), runtime = {}) {
|
|
|
62707
62952
|
assertOutputFileAllowed2(config.resultJsonPath);
|
|
62708
62953
|
assertOutputFileAllowed2(config.dotenvPath);
|
|
62709
62954
|
const dependencies = createCliDependencies(inputs);
|
|
62955
|
+
await runCredentialPreflight({
|
|
62956
|
+
apiBaseUrl: inputs.postmanApiBase,
|
|
62957
|
+
iapubBaseUrl: inputs.postmanIapubBase,
|
|
62958
|
+
postmanApiKey: inputs.postmanApiKey,
|
|
62959
|
+
postmanAccessToken: inputs.postmanAccessToken,
|
|
62960
|
+
workspaceTeamId: inputs.workspaceTeamId,
|
|
62961
|
+
explicitTeamId: inputs.teamId || void 0,
|
|
62962
|
+
mode: inputs.credentialPreflight,
|
|
62963
|
+
mask: createSecretMasker([inputs.postmanApiKey, inputs.postmanAccessToken]),
|
|
62964
|
+
log: dependencies.core
|
|
62965
|
+
});
|
|
62710
62966
|
if ((inputs.domain || inputs.governanceGroup) && !dependencies.internalIntegration) {
|
|
62711
62967
|
dependencies.core.warning(
|
|
62712
62968
|
"Skipping governance assignment because postman-access-token is not configured"
|
package/dist/index.cjs
CHANGED
|
@@ -47937,20 +47937,22 @@ async function probeSessionIdentity(baseUrl, accessToken, fetchImpl) {
|
|
|
47937
47937
|
if (!payload) {
|
|
47938
47938
|
return void 0;
|
|
47939
47939
|
}
|
|
47940
|
-
const
|
|
47941
|
-
const
|
|
47940
|
+
const root = asRecord(payload.session) ?? payload;
|
|
47941
|
+
const identity = asRecord(root.identity);
|
|
47942
|
+
const data = asRecord(root.data);
|
|
47942
47943
|
const user = asRecord(data?.user);
|
|
47943
47944
|
const roleEntries = Array.isArray(user?.roles) ? user.roles.map((entry) => coerceText(entry) ?? coerceId(entry)).filter((entry) => Boolean(entry)) : [];
|
|
47944
47945
|
const singleRole = coerceText(user?.role);
|
|
47945
47946
|
const roles = roleEntries.length > 0 ? roleEntries : singleRole ? [singleRole] : void 0;
|
|
47946
47947
|
const resolved = {
|
|
47947
47948
|
source: "iapub/sessions",
|
|
47948
|
-
userId: coerceId(user?.id),
|
|
47949
|
+
userId: coerceId(identity?.user) ?? coerceId(user?.id),
|
|
47949
47950
|
fullName: coerceText(user?.fullName) ?? coerceText(user?.name) ?? coerceText(user?.username),
|
|
47950
47951
|
teamId: coerceId(identity?.team),
|
|
47952
|
+
teamName: coerceText(user?.teamName),
|
|
47951
47953
|
teamDomain: coerceText(identity?.domain),
|
|
47952
47954
|
...roles ? { roles } : {},
|
|
47953
|
-
consumerType: coerceText(
|
|
47955
|
+
consumerType: coerceText(root.consumerType) ?? coerceText(data?.consumerType) ?? coerceText(user?.consumerType)
|
|
47954
47956
|
};
|
|
47955
47957
|
memoizedSessionIdentity = resolved;
|
|
47956
47958
|
return resolved;
|