@postman-cse/onboarding-bootstrap 0.14.2 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/action.yml +4 -0
- package/dist/action.cjs +452 -90
- package/dist/cli.cjs +127 -19
- package/dist/index.cjs +452 -90
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -45095,6 +45095,12 @@ var customerPreviewActionContract = {
|
|
|
45095
45095
|
description: "Postman access token used for governance and workspace mutations.",
|
|
45096
45096
|
required: false
|
|
45097
45097
|
},
|
|
45098
|
+
"credential-preflight": {
|
|
45099
|
+
description: "Credential identity preflight policy. warn (default) logs a note and continues when postman-api-key and postman-access-token resolve to different parent orgs; enforce fails the run on that condition before any workspace is created; off skips the identity probes entirely (the reactive error guidance still applies). Promotion of the default to enforce is planned once the live e2e legs prove both directions.",
|
|
45100
|
+
required: false,
|
|
45101
|
+
default: "warn",
|
|
45102
|
+
allowedValues: ["enforce", "warn", "off"]
|
|
45103
|
+
},
|
|
45098
45104
|
"integration-backend": {
|
|
45099
45105
|
description: "Integration backend for downstream workspace connectivity.",
|
|
45100
45106
|
required: false,
|
|
@@ -46118,13 +46124,15 @@ var POSTMAN_ENDPOINT_PROFILES = {
|
|
|
46118
46124
|
apiBaseUrl: "https://api.getpostman.com",
|
|
46119
46125
|
bifrostBaseUrl: "https://bifrost-premium-https-v4.gw.postman.com",
|
|
46120
46126
|
cliInstallUrl: "https://dl-cli.pstmn.io/install/unix.sh",
|
|
46121
|
-
gatewayBaseUrl: "https://gateway.postman.com"
|
|
46127
|
+
gatewayBaseUrl: "https://gateway.postman.com",
|
|
46128
|
+
iapubBaseUrl: "https://iapub.postman.co"
|
|
46122
46129
|
},
|
|
46123
46130
|
beta: {
|
|
46124
46131
|
apiBaseUrl: "https://api.getpostman-beta.com",
|
|
46125
46132
|
bifrostBaseUrl: "https://bifrost-https-v4.gw.postman-beta.com",
|
|
46126
46133
|
cliInstallUrl: "https://dl-cli.pstmn-beta.io/install/unix.sh",
|
|
46127
|
-
gatewayBaseUrl: "https://gateway.postman-beta.com"
|
|
46134
|
+
gatewayBaseUrl: "https://gateway.postman-beta.com",
|
|
46135
|
+
iapubBaseUrl: "https://iapub.postman.co"
|
|
46128
46136
|
}
|
|
46129
46137
|
};
|
|
46130
46138
|
function parsePostmanStack(value) {
|
|
@@ -46138,6 +46146,68 @@ function resolvePostmanEndpointProfile(stack) {
|
|
|
46138
46146
|
return POSTMAN_ENDPOINT_PROFILES[stack];
|
|
46139
46147
|
}
|
|
46140
46148
|
|
|
46149
|
+
// src/lib/postman/credential-identity.ts
|
|
46150
|
+
var memoizedSessionIdentity;
|
|
46151
|
+
function getMemoizedSessionIdentity() {
|
|
46152
|
+
return memoizedSessionIdentity;
|
|
46153
|
+
}
|
|
46154
|
+
|
|
46155
|
+
// src/lib/postman/error-advice.ts
|
|
46156
|
+
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.";
|
|
46157
|
+
function workspaceTeamIdUnauthorizedAdvice(targetTeamId) {
|
|
46158
|
+
return `The workspace-team-id input (${targetTeamId}) was rejected as unauthorized by the Postman API. In org-mode accounts it must be the numeric id of a sub-team this API key can access; GET https://api.getpostman.com/teams lists the available sub-teams. Fix the workspace-team-id value and re-run.`;
|
|
46159
|
+
}
|
|
46160
|
+
function adviseFromWorkspaceCreateError(err, targetTeamId) {
|
|
46161
|
+
if (err.message.includes("Only personal workspaces")) {
|
|
46162
|
+
return new Error(WORKSPACE_PERSONAL_ONLY_ADVICE, { cause: err });
|
|
46163
|
+
}
|
|
46164
|
+
if (targetTeamId != null && err.message.includes("You are not authorized to perform this action")) {
|
|
46165
|
+
return new Error(workspaceTeamIdUnauthorizedAdvice(targetTeamId), { cause: err });
|
|
46166
|
+
}
|
|
46167
|
+
return void 0;
|
|
46168
|
+
}
|
|
46169
|
+
function expiryAdvice(code) {
|
|
46170
|
+
return `postman: Bifrost rejected the access token (${code}). Service-account access tokens expire after about 1 to 1.5 hours; this run likely outlived its token. Re-mint a fresh token (postman-resolve-service-token-action, or POST https://api.getpostman.com/service-account-tokens) and re-run. If it was just minted, confirm postman-access-token is the token for the same parent org as postman-api-key.`;
|
|
46171
|
+
}
|
|
46172
|
+
function forbiddenAdvice(ctx) {
|
|
46173
|
+
const sessionDetail = ctx.sessionTeamId ? ` while the access token is valid (it resolved to team ${ctx.sessionTeamId}${ctx.sessionRoles && ctx.sessionRoles.length > 0 ? `, roles [${ctx.sessionRoles.join(", ")}]` : ""}${ctx.sessionConsumerType ? `, consumerType ${ctx.sessionConsumerType}` : ""} at preflight)` : "";
|
|
46174
|
+
const scopedTeamId = ctx.workspaceTeamId || ctx.explicitTeamId;
|
|
46175
|
+
const teamClause = scopedTeamId ? `, or workspace-team-id ${scopedTeamId} names a sub-team it cannot act in` : ", or the workspace-team-id / POSTMAN_TEAM_ID in use names a sub-team it cannot act in";
|
|
46176
|
+
return `postman: Bifrost refused ${ctx.operation || "this operation"} with 403${sessionDetail}. The token's identity lacks permission for this endpoint${teamClause}. Verify the token's role and that workspace-team-id / POSTMAN_TEAM_ID matches a sub-team from GET https://api.getpostman.com/teams.`;
|
|
46177
|
+
}
|
|
46178
|
+
function buildAdvice(status, body, ctx) {
|
|
46179
|
+
if (body.includes("UNAUTHENTICATED")) {
|
|
46180
|
+
return expiryAdvice("UNAUTHENTICATED");
|
|
46181
|
+
}
|
|
46182
|
+
if (body.includes("authenticationError")) {
|
|
46183
|
+
return expiryAdvice("authenticationError");
|
|
46184
|
+
}
|
|
46185
|
+
if (body.includes("Only personal workspaces")) {
|
|
46186
|
+
return WORKSPACE_PERSONAL_ONLY_ADVICE;
|
|
46187
|
+
}
|
|
46188
|
+
if (body.includes("projectAlreadyConnected")) {
|
|
46189
|
+
return `postman: ${ctx.operation || "this operation"} reports projectAlreadyConnected with no workspace id in the error body. The repository is already linked to a workspace this credential cannot see, usually one created by a different credential pair or sub-team. Delete the stale link or its workspace, then re-run with one credential pair from a single parent org.`;
|
|
46190
|
+
}
|
|
46191
|
+
if (body.includes("invalidParamError") && body.includes("already exists")) {
|
|
46192
|
+
return `postman: ${ctx.operation || "this operation"} hit a duplicate resource error (invalidParamError: already exists). A matching resource already exists, possibly under another credential pair or sub-team where this credential cannot see it. Identify which workspace holds the existing resource and re-run with one credential pair from a single parent org.`;
|
|
46193
|
+
}
|
|
46194
|
+
if (body.includes("Team feature is not available for your organization")) {
|
|
46195
|
+
return `postman: ${ctx.operation || "this operation"} failed because the team feature is not available for this organization. The credential belongs to an account whose plan lacks team features; use credentials from the intended team and confirm the plan supports this operation.`;
|
|
46196
|
+
}
|
|
46197
|
+
if (body.includes("You are not authorized to perform this action") || status === 403 && ctx.hasAccessToken) {
|
|
46198
|
+
return forbiddenAdvice(ctx);
|
|
46199
|
+
}
|
|
46200
|
+
return void 0;
|
|
46201
|
+
}
|
|
46202
|
+
function adviseFromHttpError(err, ctx) {
|
|
46203
|
+
const body = err.responseBody || err.message || "";
|
|
46204
|
+
const advice = buildAdvice(err.status, body, ctx);
|
|
46205
|
+
if (!advice) {
|
|
46206
|
+
return void 0;
|
|
46207
|
+
}
|
|
46208
|
+
return new Error(ctx.mask(advice), { cause: err });
|
|
46209
|
+
}
|
|
46210
|
+
|
|
46141
46211
|
// src/lib/retry.ts
|
|
46142
46212
|
function sleep(delayMs) {
|
|
46143
46213
|
return new Promise((resolve3) => {
|
|
@@ -46339,17 +46409,11 @@ var PostmanAssetsClient = class {
|
|
|
46339
46409
|
body: JSON.stringify(payload)
|
|
46340
46410
|
});
|
|
46341
46411
|
} catch (err) {
|
|
46342
|
-
if (err instanceof Error
|
|
46343
|
-
|
|
46344
|
-
|
|
46345
|
-
|
|
46346
|
-
|
|
46347
|
-
}
|
|
46348
|
-
if (targetTeamId != null && err instanceof Error && err.message.includes("You are not authorized to perform this action")) {
|
|
46349
|
-
throw new Error(
|
|
46350
|
-
`The workspace-team-id input (${targetTeamId}) was rejected as unauthorized by the Postman API. In org-mode accounts it must be the numeric id of a sub-team this API key can access; GET https://api.getpostman.com/teams lists the available sub-teams. Fix the workspace-team-id value and re-run.`,
|
|
46351
|
-
{ cause: err }
|
|
46352
|
-
);
|
|
46412
|
+
if (err instanceof Error) {
|
|
46413
|
+
const advised = adviseFromWorkspaceCreateError(err, targetTeamId);
|
|
46414
|
+
if (advised) {
|
|
46415
|
+
throw advised;
|
|
46416
|
+
}
|
|
46353
46417
|
}
|
|
46354
46418
|
throw err;
|
|
46355
46419
|
}
|
|
@@ -46878,6 +46942,18 @@ var BifrostInternalIntegrationAdapter = class _BifrostInternalIntegrationAdapter
|
|
|
46878
46942
|
this.teamId = String(teamId || "").trim();
|
|
46879
46943
|
this.orgMode = orgMode;
|
|
46880
46944
|
}
|
|
46945
|
+
adviceContext(operation) {
|
|
46946
|
+
const session = getMemoizedSessionIdentity();
|
|
46947
|
+
return {
|
|
46948
|
+
operation,
|
|
46949
|
+
hasAccessToken: Boolean(this.accessToken),
|
|
46950
|
+
sessionTeamId: session?.teamId,
|
|
46951
|
+
sessionRoles: session?.roles,
|
|
46952
|
+
sessionConsumerType: session?.consumerType,
|
|
46953
|
+
explicitTeamId: this.teamId || void 0,
|
|
46954
|
+
mask: this.secretMasker
|
|
46955
|
+
};
|
|
46956
|
+
}
|
|
46881
46957
|
async proxyRequest(service, method, requestPath2, body, options = {}) {
|
|
46882
46958
|
const url = `${this.bifrostBaseUrl}/ws/proxy`;
|
|
46883
46959
|
const headers = {
|
|
@@ -46944,7 +47020,7 @@ var BifrostInternalIntegrationAdapter = class _BifrostInternalIntegrationAdapter
|
|
|
46944
47020
|
{ appVersion, query: { tag: "governance" } }
|
|
46945
47021
|
);
|
|
46946
47022
|
if (!listResponse.ok) {
|
|
46947
|
-
|
|
47023
|
+
const httpErr = await HttpError.fromResponse(listResponse, {
|
|
46948
47024
|
method: "GET",
|
|
46949
47025
|
requestHeaders: {
|
|
46950
47026
|
"Content-Type": "application/json",
|
|
@@ -46955,6 +47031,8 @@ var BifrostInternalIntegrationAdapter = class _BifrostInternalIntegrationAdapter
|
|
|
46955
47031
|
secretValues: [this.accessToken],
|
|
46956
47032
|
url: `${this.bifrostBaseUrl}/ws/proxy`
|
|
46957
47033
|
});
|
|
47034
|
+
const advised = adviseFromHttpError(httpErr, this.adviceContext("governance assignment"));
|
|
47035
|
+
throw advised ?? httpErr;
|
|
46958
47036
|
}
|
|
46959
47037
|
const groups = await listResponse.json();
|
|
46960
47038
|
const group = (groups.workspaceGroups ?? groups.data)?.find(
|
|
@@ -46980,7 +47058,7 @@ var BifrostInternalIntegrationAdapter = class _BifrostInternalIntegrationAdapter
|
|
|
46980
47058
|
{ appVersion }
|
|
46981
47059
|
);
|
|
46982
47060
|
if (!patchResponse.ok) {
|
|
46983
|
-
|
|
47061
|
+
const httpErr = await HttpError.fromResponse(patchResponse, {
|
|
46984
47062
|
method: "PATCH",
|
|
46985
47063
|
requestHeaders: {
|
|
46986
47064
|
"Content-Type": "application/json",
|
|
@@ -46991,6 +47069,8 @@ var BifrostInternalIntegrationAdapter = class _BifrostInternalIntegrationAdapter
|
|
|
46991
47069
|
secretValues: [this.accessToken],
|
|
46992
47070
|
url: `${this.bifrostBaseUrl}/ws/proxy`
|
|
46993
47071
|
});
|
|
47072
|
+
const advised = adviseFromHttpError(httpErr, this.adviceContext("governance assignment"));
|
|
47073
|
+
throw advised ?? httpErr;
|
|
46994
47074
|
}
|
|
46995
47075
|
}
|
|
46996
47076
|
async connectWorkspaceToRepository(workspaceId, repoUrl) {
|
|
@@ -47024,7 +47104,7 @@ var BifrostInternalIntegrationAdapter = class _BifrostInternalIntegrationAdapter
|
|
|
47024
47104
|
);
|
|
47025
47105
|
}
|
|
47026
47106
|
}
|
|
47027
|
-
|
|
47107
|
+
const httpErr = await HttpError.fromResponse(response, {
|
|
47028
47108
|
method: "POST",
|
|
47029
47109
|
requestHeaders: {
|
|
47030
47110
|
"Content-Type": "application/json",
|
|
@@ -47034,6 +47114,8 @@ var BifrostInternalIntegrationAdapter = class _BifrostInternalIntegrationAdapter
|
|
|
47034
47114
|
secretValues: [this.accessToken],
|
|
47035
47115
|
url: `${this.bifrostBaseUrl}/ws/proxy`
|
|
47036
47116
|
});
|
|
47117
|
+
const advised = adviseFromHttpError(httpErr, this.adviceContext("workspace repository linking"));
|
|
47118
|
+
throw advised ?? httpErr;
|
|
47037
47119
|
}
|
|
47038
47120
|
async linkCollectionsToSpecification(specificationId, collections) {
|
|
47039
47121
|
if (collections.length === 0) {
|
|
@@ -47051,7 +47133,7 @@ var BifrostInternalIntegrationAdapter = class _BifrostInternalIntegrationAdapter
|
|
|
47051
47133
|
if (response.ok) {
|
|
47052
47134
|
return;
|
|
47053
47135
|
}
|
|
47054
|
-
|
|
47136
|
+
const httpErr = await HttpError.fromResponse(response, {
|
|
47055
47137
|
method: "POST",
|
|
47056
47138
|
requestHeaders: {
|
|
47057
47139
|
"Content-Type": "application/json",
|
|
@@ -47061,6 +47143,11 @@ var BifrostInternalIntegrationAdapter = class _BifrostInternalIntegrationAdapter
|
|
|
47061
47143
|
secretValues: [this.accessToken],
|
|
47062
47144
|
url: `${this.bifrostBaseUrl}/ws/proxy`
|
|
47063
47145
|
});
|
|
47146
|
+
const advised = adviseFromHttpError(
|
|
47147
|
+
httpErr,
|
|
47148
|
+
this.adviceContext("collection-to-specification linking")
|
|
47149
|
+
);
|
|
47150
|
+
throw advised ?? httpErr;
|
|
47064
47151
|
}
|
|
47065
47152
|
async syncCollection(specificationId, collectionId) {
|
|
47066
47153
|
const response = await this.proxyRequest(
|
|
@@ -47071,7 +47158,7 @@ var BifrostInternalIntegrationAdapter = class _BifrostInternalIntegrationAdapter
|
|
|
47071
47158
|
if (response.ok) {
|
|
47072
47159
|
return;
|
|
47073
47160
|
}
|
|
47074
|
-
|
|
47161
|
+
const httpErr = await HttpError.fromResponse(response, {
|
|
47075
47162
|
method: "POST",
|
|
47076
47163
|
requestHeaders: {
|
|
47077
47164
|
"Content-Type": "application/json",
|
|
@@ -47081,6 +47168,8 @@ var BifrostInternalIntegrationAdapter = class _BifrostInternalIntegrationAdapter
|
|
|
47081
47168
|
secretValues: [this.accessToken],
|
|
47082
47169
|
url: `${this.bifrostBaseUrl}/ws/proxy`
|
|
47083
47170
|
});
|
|
47171
|
+
const advised = adviseFromHttpError(httpErr, this.adviceContext("collection sync"));
|
|
47172
|
+
throw advised ?? httpErr;
|
|
47084
47173
|
}
|
|
47085
47174
|
async getWorkspaceGitRepoUrl(workspaceId) {
|
|
47086
47175
|
const response = await this.proxyRequest(
|
|
@@ -61167,6 +61256,11 @@ function resolveInputs(env = process.env) {
|
|
|
61167
61256
|
governanceMappingJson: parseGovernanceMappingJson(getInput("governance-mapping-json", env)),
|
|
61168
61257
|
postmanApiKey: getInput("postman-api-key", env) ?? "",
|
|
61169
61258
|
postmanAccessToken: getInput("postman-access-token", env),
|
|
61259
|
+
credentialPreflight: parseEnumInput(
|
|
61260
|
+
"credential-preflight",
|
|
61261
|
+
getInput("credential-preflight", env),
|
|
61262
|
+
customerPreviewActionContract.inputs["credential-preflight"].default ?? "warn"
|
|
61263
|
+
),
|
|
61170
61264
|
integrationBackend,
|
|
61171
61265
|
folderStrategy: parseEnumInput("folder-strategy", getInput("folder-strategy", env), "Paths"),
|
|
61172
61266
|
nestedFolderHierarchy: parseBooleanInput("nested-folder-hierarchy", getInput("nested-folder-hierarchy", env), false),
|
|
@@ -61176,6 +61270,7 @@ function resolveInputs(env = process.env) {
|
|
|
61176
61270
|
postmanBifrostBase: endpointProfile.bifrostBaseUrl,
|
|
61177
61271
|
postmanGatewayBase: endpointProfile.gatewayBaseUrl,
|
|
61178
61272
|
postmanCliInstallUrl: endpointProfile.cliInstallUrl,
|
|
61273
|
+
postmanIapubBase: endpointProfile.iapubBaseUrl,
|
|
61179
61274
|
githubRefName: env.GITHUB_REF_NAME,
|
|
61180
61275
|
githubHeadRef: env.GITHUB_HEAD_REF,
|
|
61181
61276
|
githubRef: env.GITHUB_REF,
|
|
@@ -61712,8 +61807,20 @@ For CLI usage, pass --workspace-team-id <id> or export POSTMAN_WORKSPACE_TEAM_ID
|
|
|
61712
61807
|
governanceGroupName
|
|
61713
61808
|
);
|
|
61714
61809
|
} catch (error) {
|
|
61810
|
+
const session = getMemoizedSessionIdentity();
|
|
61811
|
+
const advised = error instanceof HttpError ? adviseFromHttpError(error, {
|
|
61812
|
+
operation: "governance assignment",
|
|
61813
|
+
hasAccessToken: Boolean(inputs.postmanAccessToken),
|
|
61814
|
+
sessionTeamId: session?.teamId,
|
|
61815
|
+
sessionRoles: session?.roles,
|
|
61816
|
+
sessionConsumerType: session?.consumerType,
|
|
61817
|
+
workspaceTeamId: inputs.workspaceTeamId,
|
|
61818
|
+
explicitTeamId: inputs.teamId || void 0,
|
|
61819
|
+
mask: createSecretMasker([inputs.postmanApiKey, inputs.postmanAccessToken])
|
|
61820
|
+
}) : void 0;
|
|
61821
|
+
const reported = advised ?? error;
|
|
61715
61822
|
dependencies.core.warning(
|
|
61716
|
-
`Failed to assign governance group: ${
|
|
61823
|
+
`Failed to assign governance group: ${reported instanceof Error ? reported.message : String(reported)}`
|
|
61717
61824
|
);
|
|
61718
61825
|
}
|
|
61719
61826
|
}
|
|
@@ -62375,6 +62482,7 @@ var cliInputNames = [
|
|
|
62375
62482
|
"spec-path",
|
|
62376
62483
|
"postman-api-key",
|
|
62377
62484
|
"postman-access-token",
|
|
62485
|
+
"credential-preflight",
|
|
62378
62486
|
"workspace-id",
|
|
62379
62487
|
"spec-id",
|
|
62380
62488
|
"baseline-collection-id",
|