@stackgenhq/backstage-plugin-stackgen-backend 0.3.6-beta.1 → 0.3.7
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/actions/core/assign_project_members_action.cjs.js +7 -18
- package/dist/actions/core/assign_project_members_action.cjs.js.map +1 -1
- package/dist/actions/core/create_appstack_action.cjs.js +22 -27
- package/dist/actions/core/create_appstack_action.cjs.js.map +1 -1
- package/dist/actions/core/create_project_action.cjs.js +6 -33
- package/dist/actions/core/create_project_action.cjs.js.map +1 -1
- package/dist/actions/core/download_iac_action.cjs.js +2 -9
- package/dist/actions/core/download_iac_action.cjs.js.map +1 -1
- package/dist/actions/core/set_environment_variable_values_action.cjs.js +1 -7
- package/dist/actions/core/set_environment_variable_values_action.cjs.js.map +1 -1
- package/dist/actions/core/set_state_backend_action.cjs.js +6 -16
- package/dist/actions/core/set_state_backend_action.cjs.js.map +1 -1
- package/dist/exporter/gitExporterConfigHttp.cjs.js +2 -16
- package/dist/exporter/gitExporterConfigHttp.cjs.js.map +1 -1
- package/dist/modules/stackgenUiProxiesModule.cjs.js +2 -12
- package/dist/modules/stackgenUiProxiesModule.cjs.js.map +1 -1
- package/dist/utils/api-objects.cjs.js +22 -41
- package/dist/utils/api-objects.cjs.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ This plugin is installed via the `@stackgenhq/backstage-plugin-stackgen-backend`
|
|
|
11
11
|
yarn --cwd packages/backend add @stackgenhq/backstage-plugin-stackgen-backend
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
-
No `.yarnrc.yml` GitHub Packages scope is required
|
|
14
|
+
No `.yarnrc.yml` GitHub Packages scope is required if you install from npmjs. The same version is also published to GitHub Packages.
|
|
15
15
|
Then add the plugin to your backend in `packages/backend/src/index.ts`:
|
|
16
16
|
|
|
17
17
|
```ts
|
|
@@ -39,8 +39,7 @@ async function resolveProjectMemberRoleId(stackgenApis, preferredRoleId, logger)
|
|
|
39
39
|
return resolved;
|
|
40
40
|
}
|
|
41
41
|
} catch (error) {
|
|
42
|
-
|
|
43
|
-
logger.warn(`Failed to list roles for member assignment: ${detail}`);
|
|
42
|
+
logger.warn(`Failed to list roles for member assignment: ${String(error)}`);
|
|
44
43
|
}
|
|
45
44
|
throw new Error(
|
|
46
45
|
"Could not resolve a project member roleId. Set stackGen.projectMemberRoleId or ensure RoleManagementApi.listRoles returns roles."
|
|
@@ -140,15 +139,10 @@ const assignProjectMembersAction = (config, logger) => {
|
|
|
140
139
|
});
|
|
141
140
|
} catch (error) {
|
|
142
141
|
const parsedError = await apiObjects.readClientError(error);
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
parsedError.body,
|
|
146
|
-
parsedError.text,
|
|
147
|
-
parsedError.requestId
|
|
148
|
-
);
|
|
149
|
-
if (!isAlreadyMemberError(parsedError.status, detail) && !isAlreadyMemberError(parsedError.status, parsedError.text)) {
|
|
142
|
+
const text = parsedError.text || String(error);
|
|
143
|
+
if (!isAlreadyMemberError(parsedError.status, text)) {
|
|
150
144
|
throw new Error(
|
|
151
|
-
`Failed to assign user ${user.label || user.id} to project: ${
|
|
145
|
+
`Failed to assign user ${user.label || user.id} to project (${parsedError.status}): ${text.slice(0, 300)}`
|
|
152
146
|
);
|
|
153
147
|
}
|
|
154
148
|
ctx.logger.info(
|
|
@@ -172,15 +166,10 @@ const assignProjectMembersAction = (config, logger) => {
|
|
|
172
166
|
});
|
|
173
167
|
} catch (error) {
|
|
174
168
|
const parsedError = await apiObjects.readClientError(error);
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
parsedError.body,
|
|
178
|
-
parsedError.text,
|
|
179
|
-
parsedError.requestId
|
|
180
|
-
);
|
|
181
|
-
if (!isAlreadyMemberError(parsedError.status, detail) && !isAlreadyMemberError(parsedError.status, parsedError.text)) {
|
|
169
|
+
const text = parsedError.text || String(error);
|
|
170
|
+
if (!isAlreadyMemberError(parsedError.status, text)) {
|
|
182
171
|
throw new Error(
|
|
183
|
-
`Failed to assign groups to project: ${
|
|
172
|
+
`Failed to assign groups to project (${parsedError.status}): ${text.slice(0, 300)}`
|
|
184
173
|
);
|
|
185
174
|
}
|
|
186
175
|
ctx.logger.info("Some groups were already project members");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assign_project_members_action.cjs.js","sources":["../../../src/actions/core/assign_project_members_action.ts"],"sourcesContent":["import { createTemplateAction } from \"@backstage/plugin-scaffolder-node\";\nimport { LoggerService } from \"@backstage/backend-plugin-api\";\nimport { Config } from \"@backstage/config\";\nimport { z } from \"zod\";\nimport {\n formatApiFailure,\n formatClientErrorMessage,\n getStackgenApiObjects,\n readClientError,\n} from \"../../utils/api-objects\";\n\nconst memberSchema = z.object({\n type: z.enum([\"user\", \"group\"]),\n id: z.string().min(1),\n label: z.string().optional(),\n});\n\nexport const assignProjectMembersInputSchema = z.object({\n /** StackGen project / team (org) id. */\n projectId: z.string().min(1, \"projectId is required\"),\n /** Output of the UserGroupSelect scaffolder field. */\n members: z.array(memberSchema).default([]),\n /** Role UUID for assigned users/groups. When omitted, resolves project developer role. */\n roleId: z.string().optional(),\n});\n\nexport const assignProjectMembersOutputSchema = z.object({\n assignedUsers: z.number(),\n assignedGroups: z.number(),\n /** Newline-separated labels for scaffolder output.text tabs. */\n assignedUsersText: z.string(),\n assignedGroupsText: z.string(),\n roleId: z.string().optional(),\n});\n\nasync function resolveProjectMemberRoleId(\n stackgenApis: ReturnType<typeof getStackgenApiObjects>,\n preferredRoleId: string | undefined,\n logger: LoggerService,\n): Promise<string> {\n if (preferredRoleId?.trim()) {\n return preferredRoleId.trim();\n }\n\n try {\n const response = await stackgenApis.roleApiObj.listRoles();\n const roles = response?.roles ?? [];\n const byName = (name: string) =>\n roles.find((role) => role.name?.toLowerCase() === name)?.id?.trim();\n\n // Match appcd-ui project member defaults: developer, then admin, then first role.\n const resolved =\n byName(\"developer\") || byName(\"admin\") || roles[0]?.id?.trim();\n if (resolved) {\n logger.info(`Resolved project member roleId=${resolved}`);\n return resolved;\n }\n } catch (error) {\n const detail = await formatClientErrorMessage(error);\n logger.warn(`Failed to list roles for member assignment: ${detail}`);\n }\n\n throw new Error(\n \"Could not resolve a project member roleId. Set stackGen.projectMemberRoleId or ensure RoleManagementApi.listRoles returns roles.\",\n );\n}\n\nfunction readUserId(row: any): string {\n return String(row?.id || row?.userId || row?.user?.id || \"\").trim();\n}\n\nfunction readGroupId(row: any): string {\n return String(row?.groupId || row?.id || row?.group?.id || \"\").trim();\n}\n\nfunction isAlreadyMemberError(status: number, text: string): boolean {\n const lowered = text.toLowerCase();\n return (\n status === 409 ||\n lowered.includes(\"already member\") ||\n lowered.includes(\"already exists\") ||\n lowered.includes(\"already assigned\")\n );\n}\n\nasync function loadProjectMembership(\n stackgenApis: ReturnType<typeof getStackgenApiObjects>,\n projectId: string,\n): Promise<{ userIds: Set<string>; groupIds: Set<string> }> {\n const orgUsers = await stackgenApis.projectApiObject.getOrganizationUsers({\n orgId: projectId,\n });\n const orgGroups = await stackgenApis.projectApiObject.getOrganizationGroups({\n orgId: projectId,\n });\n const userRows = Array.isArray(orgUsers) ? orgUsers : [];\n let groupRows: any[];\n if (Array.isArray(orgGroups?.groupAssignments)) {\n groupRows = orgGroups.groupAssignments;\n } else if (Array.isArray(orgGroups)) {\n groupRows = orgGroups;\n } else {\n groupRows = [];\n }\n\n return {\n userIds: new Set(userRows.map(readUserId).filter(Boolean)),\n groupIds: new Set(groupRows.map(readGroupId).filter(Boolean)),\n };\n}\n\n/**\n * Assigns users and/or groups from UserGroupSelect to a StackGen project.\n * Uses the same OrgManagement APIs as appcd-ui project membership.\n */\nexport const assignProjectMembersAction = (\n config: Config,\n logger: LoggerService,\n) => {\n return createTemplateAction({\n id: \"stackGen:assignProjectMembers\",\n description:\n \"Assigns StackGen users and/or groups to a project (from UserGroupSelect)\",\n schema: {\n input: () => assignProjectMembersInputSchema,\n output: () => assignProjectMembersOutputSchema,\n },\n async handler(ctx) {\n const stackgenApis = getStackgenApiObjects(config);\n const projectId = ctx.input.projectId.trim();\n const members = ctx.input.members ?? [];\n\n const users = members.filter((member) => member.type === \"user\");\n const groups = members.filter((member) => member.type === \"group\");\n const formatMemberLines = (\n list: Array<{ id: string; label?: string }>,\n emptyLabel: string,\n ) =>\n list.length === 0\n ? emptyLabel\n : list\n .map((member) => member.label?.trim() || member.id)\n .join(\"\\n\");\n\n if (users.length === 0 && groups.length === 0) {\n ctx.logger.info(\"No members selected; skipping assignment\");\n ctx.output(\"assignedUsers\", 0);\n ctx.output(\"assignedGroups\", 0);\n ctx.output(\"assignedUsersText\", \"No users assigned\");\n ctx.output(\"assignedGroupsText\", \"No groups assigned\");\n return;\n }\n\n const roleId = await resolveProjectMemberRoleId(\n stackgenApis,\n ctx.input.roleId?.trim() ||\n config.getOptionalString(\"stackGen.projectMemberRoleId\")?.trim(),\n logger,\n );\n\n // Project create / createAppStack often already added the current user.\n // Skip existing members so an \"already member\" response cannot block the rest.\n let existing = await loadProjectMembership(stackgenApis, projectId);\n ctx.logger.info(\n `Project ${projectId} currently has ${existing.userIds.size} user(s) and ${existing.groupIds.size} group(s)`,\n );\n\n const usersToAdd = users.filter((user) => !existing.userIds.has(user.id));\n const groupsToAdd = groups.filter(\n (group) => !existing.groupIds.has(group.id),\n );\n const skippedUsers = users.filter((user) => existing.userIds.has(user.id));\n const skippedGroups = groups.filter((group) =>\n existing.groupIds.has(group.id),\n );\n\n if (skippedUsers.length > 0) {\n ctx.logger.info(\n `Skipping ${skippedUsers.length} already-present user(s): ${skippedUsers\n .map((user) => user.label || user.id)\n .join(\", \")}`,\n );\n }\n if (skippedGroups.length > 0) {\n ctx.logger.info(\n `Skipping ${skippedGroups.length} already-present group(s): ${skippedGroups\n .map((group) => group.label || group.id)\n .join(\", \")}`,\n );\n }\n\n // Assign users one-by-one so one conflict cannot drop the rest of the batch.\n for (const user of usersToAdd) {\n ctx.logger.info(\n `Assigning user ${user.label || user.id} to project ${projectId} with role ${roleId}`,\n );\n try {\n await stackgenApis.projectApiObject.assignUsersToOrg({\n orgId: projectId,\n assignUsersToOrgRequest: {\n userAssignments: [{ userId: user.id, roleId }],\n } as never,\n });\n } catch (error) {\n const parsedError = await readClientError(error);\n const detail = formatApiFailure(\n parsedError.status,\n parsedError.body,\n parsedError.text,\n parsedError.requestId,\n );\n if (\n !isAlreadyMemberError(parsedError.status, detail) &&\n !isAlreadyMemberError(parsedError.status, parsedError.text)\n ) {\n throw new Error(\n `Failed to assign user ${user.label || user.id} to project: ${detail}`,\n );\n }\n ctx.logger.info(\n `User ${user.label || user.id} was already a project member`,\n );\n }\n }\n\n if (groupsToAdd.length > 0) {\n ctx.logger.info(\n `Assigning ${groupsToAdd.length} group(s) to project ${projectId} with role ${roleId}`,\n );\n try {\n await stackgenApis.projectApiObject.assignGroupsToOrg({\n orgId: projectId,\n assignGroupsToOrgRequest: {\n groupAssignments: groupsToAdd.map((group) => ({\n groupId: group.id,\n roleId,\n })),\n },\n });\n } catch (error) {\n const parsedError = await readClientError(error);\n const detail = formatApiFailure(\n parsedError.status,\n parsedError.body,\n parsedError.text,\n parsedError.requestId,\n );\n if (\n !isAlreadyMemberError(parsedError.status, detail) &&\n !isAlreadyMemberError(parsedError.status, parsedError.text)\n ) {\n throw new Error(\n `Failed to assign groups to project: ${detail}`,\n );\n }\n ctx.logger.info(\"Some groups were already project members\");\n }\n }\n\n existing = await loadProjectMembership(stackgenApis, projectId);\n ctx.logger.info(\n `Project ${projectId} now has ${existing.userIds.size} user(s) and ${existing.groupIds.size} group(s)`,\n );\n\n const missingUsers = users.filter(\n (user) => !existing.userIds.has(user.id),\n );\n if (missingUsers.length > 0) {\n throw new Error(\n `Assigned users but ${missingUsers.length} are still missing from project members: ${missingUsers\n .map((user) => user.label || user.id)\n .join(\", \")}. Check roleId and project id.`,\n );\n }\n\n const missingGroups = groups.filter(\n (group) => !existing.groupIds.has(group.id),\n );\n if (missingGroups.length > 0) {\n throw new Error(\n `Assigned groups but ${missingGroups.length} are still missing from project members: ${missingGroups\n .map((group) => group.label || group.id)\n .join(\", \")}. Check roleId and project id.`,\n );\n }\n\n ctx.output(\"assignedUsers\", users.length);\n ctx.output(\"assignedGroups\", groups.length);\n ctx.output(\n \"assignedUsersText\",\n formatMemberLines(users, \"No users assigned\"),\n );\n ctx.output(\n \"assignedGroupsText\",\n formatMemberLines(groups, \"No groups assigned\"),\n );\n ctx.output(\"roleId\", roleId);\n },\n });\n};\n"],"names":["z","formatClientErrorMessage","createTemplateAction","getStackgenApiObjects","readClientError","formatApiFailure"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"assign_project_members_action.cjs.js","sources":["../../../src/actions/core/assign_project_members_action.ts"],"sourcesContent":["import { createTemplateAction } from \"@backstage/plugin-scaffolder-node\";\nimport { LoggerService } from \"@backstage/backend-plugin-api\";\nimport { Config } from \"@backstage/config\";\nimport { z } from \"zod\";\nimport { getStackgenApiObjects, readClientError } from \"../../utils/api-objects\";\n\nconst memberSchema = z.object({\n type: z.enum([\"user\", \"group\"]),\n id: z.string().min(1),\n label: z.string().optional(),\n});\n\nexport const assignProjectMembersInputSchema = z.object({\n /** StackGen project / team (org) id. */\n projectId: z.string().min(1, \"projectId is required\"),\n /** Output of the UserGroupSelect scaffolder field. */\n members: z.array(memberSchema).default([]),\n /** Role UUID for assigned users/groups. When omitted, resolves project developer role. */\n roleId: z.string().optional(),\n});\n\nexport const assignProjectMembersOutputSchema = z.object({\n assignedUsers: z.number(),\n assignedGroups: z.number(),\n /** Newline-separated labels for scaffolder output.text tabs. */\n assignedUsersText: z.string(),\n assignedGroupsText: z.string(),\n roleId: z.string().optional(),\n});\n\nasync function resolveProjectMemberRoleId(\n stackgenApis: ReturnType<typeof getStackgenApiObjects>,\n preferredRoleId: string | undefined,\n logger: LoggerService,\n): Promise<string> {\n if (preferredRoleId?.trim()) {\n return preferredRoleId.trim();\n }\n\n try {\n const response = await stackgenApis.roleApiObj.listRoles();\n const roles = response?.roles ?? [];\n const byName = (name: string) =>\n roles.find((role) => role.name?.toLowerCase() === name)?.id?.trim();\n\n // Match appcd-ui project member defaults: developer, then admin, then first role.\n const resolved =\n byName(\"developer\") || byName(\"admin\") || roles[0]?.id?.trim();\n if (resolved) {\n logger.info(`Resolved project member roleId=${resolved}`);\n return resolved;\n }\n } catch (error) {\n logger.warn(`Failed to list roles for member assignment: ${String(error)}`);\n }\n\n throw new Error(\n \"Could not resolve a project member roleId. Set stackGen.projectMemberRoleId or ensure RoleManagementApi.listRoles returns roles.\",\n );\n}\n\nfunction readUserId(row: any): string {\n return String(row?.id || row?.userId || row?.user?.id || \"\").trim();\n}\n\nfunction readGroupId(row: any): string {\n return String(row?.groupId || row?.id || row?.group?.id || \"\").trim();\n}\n\nfunction isAlreadyMemberError(status: number, text: string): boolean {\n const lowered = text.toLowerCase();\n return (\n status === 409 ||\n lowered.includes(\"already member\") ||\n lowered.includes(\"already exists\") ||\n lowered.includes(\"already assigned\")\n );\n}\n\nasync function loadProjectMembership(\n stackgenApis: ReturnType<typeof getStackgenApiObjects>,\n projectId: string,\n): Promise<{ userIds: Set<string>; groupIds: Set<string> }> {\n const orgUsers = await stackgenApis.projectApiObject.getOrganizationUsers({\n orgId: projectId,\n });\n const orgGroups = await stackgenApis.projectApiObject.getOrganizationGroups({\n orgId: projectId,\n });\n const userRows = Array.isArray(orgUsers) ? orgUsers : [];\n let groupRows: any[];\n if (Array.isArray(orgGroups?.groupAssignments)) {\n groupRows = orgGroups.groupAssignments;\n } else if (Array.isArray(orgGroups)) {\n groupRows = orgGroups;\n } else {\n groupRows = [];\n }\n\n return {\n userIds: new Set(userRows.map(readUserId).filter(Boolean)),\n groupIds: new Set(groupRows.map(readGroupId).filter(Boolean)),\n };\n}\n\n/**\n * Assigns users and/or groups from UserGroupSelect to a StackGen project.\n * Uses the same OrgManagement APIs as appcd-ui project membership.\n */\nexport const assignProjectMembersAction = (\n config: Config,\n logger: LoggerService,\n) => {\n return createTemplateAction({\n id: \"stackGen:assignProjectMembers\",\n description:\n \"Assigns StackGen users and/or groups to a project (from UserGroupSelect)\",\n schema: {\n input: () => assignProjectMembersInputSchema,\n output: () => assignProjectMembersOutputSchema,\n },\n async handler(ctx) {\n const stackgenApis = getStackgenApiObjects(config);\n const projectId = ctx.input.projectId.trim();\n const members = ctx.input.members ?? [];\n\n const users = members.filter((member) => member.type === \"user\");\n const groups = members.filter((member) => member.type === \"group\");\n const formatMemberLines = (\n list: Array<{ id: string; label?: string }>,\n emptyLabel: string,\n ) =>\n list.length === 0\n ? emptyLabel\n : list\n .map((member) => member.label?.trim() || member.id)\n .join(\"\\n\");\n\n if (users.length === 0 && groups.length === 0) {\n ctx.logger.info(\"No members selected; skipping assignment\");\n ctx.output(\"assignedUsers\", 0);\n ctx.output(\"assignedGroups\", 0);\n ctx.output(\"assignedUsersText\", \"No users assigned\");\n ctx.output(\"assignedGroupsText\", \"No groups assigned\");\n return;\n }\n\n const roleId = await resolveProjectMemberRoleId(\n stackgenApis,\n ctx.input.roleId?.trim() ||\n config.getOptionalString(\"stackGen.projectMemberRoleId\")?.trim(),\n logger,\n );\n\n // Project create / createAppStack often already added the current user.\n // Skip existing members so an \"already member\" response cannot block the rest.\n let existing = await loadProjectMembership(stackgenApis, projectId);\n ctx.logger.info(\n `Project ${projectId} currently has ${existing.userIds.size} user(s) and ${existing.groupIds.size} group(s)`,\n );\n\n const usersToAdd = users.filter((user) => !existing.userIds.has(user.id));\n const groupsToAdd = groups.filter(\n (group) => !existing.groupIds.has(group.id),\n );\n const skippedUsers = users.filter((user) => existing.userIds.has(user.id));\n const skippedGroups = groups.filter((group) =>\n existing.groupIds.has(group.id),\n );\n\n if (skippedUsers.length > 0) {\n ctx.logger.info(\n `Skipping ${skippedUsers.length} already-present user(s): ${skippedUsers\n .map((user) => user.label || user.id)\n .join(\", \")}`,\n );\n }\n if (skippedGroups.length > 0) {\n ctx.logger.info(\n `Skipping ${skippedGroups.length} already-present group(s): ${skippedGroups\n .map((group) => group.label || group.id)\n .join(\", \")}`,\n );\n }\n\n // Assign users one-by-one so one conflict cannot drop the rest of the batch.\n for (const user of usersToAdd) {\n ctx.logger.info(\n `Assigning user ${user.label || user.id} to project ${projectId} with role ${roleId}`,\n );\n try {\n await stackgenApis.projectApiObject.assignUsersToOrg({\n orgId: projectId,\n assignUsersToOrgRequest: {\n userAssignments: [{ userId: user.id, roleId }],\n } as never,\n });\n } catch (error) {\n const parsedError = await readClientError(error);\n const text = parsedError.text || String(error);\n if (!isAlreadyMemberError(parsedError.status, text)) {\n throw new Error(\n `Failed to assign user ${user.label || user.id} to project (${parsedError.status}): ${text.slice(0, 300)}`,\n );\n }\n ctx.logger.info(\n `User ${user.label || user.id} was already a project member`,\n );\n }\n }\n\n if (groupsToAdd.length > 0) {\n ctx.logger.info(\n `Assigning ${groupsToAdd.length} group(s) to project ${projectId} with role ${roleId}`,\n );\n try {\n await stackgenApis.projectApiObject.assignGroupsToOrg({\n orgId: projectId,\n assignGroupsToOrgRequest: {\n groupAssignments: groupsToAdd.map((group) => ({\n groupId: group.id,\n roleId,\n })),\n },\n });\n } catch (error) {\n const parsedError = await readClientError(error);\n const text = parsedError.text || String(error);\n if (!isAlreadyMemberError(parsedError.status, text)) {\n throw new Error(\n `Failed to assign groups to project (${parsedError.status}): ${text.slice(0, 300)}`,\n );\n }\n ctx.logger.info(\"Some groups were already project members\");\n }\n }\n\n existing = await loadProjectMembership(stackgenApis, projectId);\n ctx.logger.info(\n `Project ${projectId} now has ${existing.userIds.size} user(s) and ${existing.groupIds.size} group(s)`,\n );\n\n const missingUsers = users.filter(\n (user) => !existing.userIds.has(user.id),\n );\n if (missingUsers.length > 0) {\n throw new Error(\n `Assigned users but ${missingUsers.length} are still missing from project members: ${missingUsers\n .map((user) => user.label || user.id)\n .join(\", \")}. Check roleId and project id.`,\n );\n }\n\n const missingGroups = groups.filter(\n (group) => !existing.groupIds.has(group.id),\n );\n if (missingGroups.length > 0) {\n throw new Error(\n `Assigned groups but ${missingGroups.length} are still missing from project members: ${missingGroups\n .map((group) => group.label || group.id)\n .join(\", \")}. Check roleId and project id.`,\n );\n }\n\n ctx.output(\"assignedUsers\", users.length);\n ctx.output(\"assignedGroups\", groups.length);\n ctx.output(\n \"assignedUsersText\",\n formatMemberLines(users, \"No users assigned\"),\n );\n ctx.output(\n \"assignedGroupsText\",\n formatMemberLines(groups, \"No groups assigned\"),\n );\n ctx.output(\"roleId\", roleId);\n },\n });\n};\n"],"names":["z","createTemplateAction","getStackgenApiObjects","readClientError"],"mappings":"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"}
|
|
@@ -218,17 +218,8 @@ function validateExpectedJsonResponse(responseText, endpoint) {
|
|
|
218
218
|
);
|
|
219
219
|
}
|
|
220
220
|
}
|
|
221
|
-
function
|
|
222
|
-
return
|
|
223
|
-
}
|
|
224
|
-
async function detailFromThrownError(error) {
|
|
225
|
-
if (error?.response) {
|
|
226
|
-
return apiObjects.formatClientErrorMessage(error);
|
|
227
|
-
}
|
|
228
|
-
if (error instanceof Error) {
|
|
229
|
-
return error.message;
|
|
230
|
-
}
|
|
231
|
-
return String(error);
|
|
221
|
+
function getErrorMessage(parsedBody, responseText) {
|
|
222
|
+
return parsedBody?.msg || parsedBody?.message || parsedBody?.error || responseText || "Unknown error";
|
|
232
223
|
}
|
|
233
224
|
async function cloneTopologyFromTemplateAppstack(params) {
|
|
234
225
|
const {
|
|
@@ -261,7 +252,7 @@ async function cloneTopologyFromTemplateAppstack(params) {
|
|
|
261
252
|
);
|
|
262
253
|
if (!res.ok) {
|
|
263
254
|
throw new Error(
|
|
264
|
-
`Failed to clone topology from template AppStack: ${
|
|
255
|
+
`Failed to clone topology from template AppStack: ${res.status} ${getErrorMessage(res.parsed, res.text)}`
|
|
265
256
|
);
|
|
266
257
|
}
|
|
267
258
|
validateExpectedJsonResponse(
|
|
@@ -303,7 +294,7 @@ async function fetchTemplateAppStackSummary(params) {
|
|
|
303
294
|
);
|
|
304
295
|
if (!res.ok) {
|
|
305
296
|
throw new Error(
|
|
306
|
-
`Failed to list template AppStacks from appcd: ${
|
|
297
|
+
`Failed to list template AppStacks from appcd: ${res.status} ${getErrorMessage(res.parsed, res.text)}`
|
|
307
298
|
);
|
|
308
299
|
}
|
|
309
300
|
validateExpectedJsonResponse(res.text, "appStacksApiObj.getTemplateAppstacks");
|
|
@@ -353,7 +344,7 @@ async function fetchAppStackSnapshotForTemplateClone(params) {
|
|
|
353
344
|
);
|
|
354
345
|
if (!res.ok) {
|
|
355
346
|
logger.warn(
|
|
356
|
-
`[${traceId}] could not load AppStack ${templateUuid} via appcd GET (${
|
|
347
|
+
`[${traceId}] could not load AppStack ${templateUuid} via appcd GET (${res.status} ${getErrorMessage(res.parsed, res.text)}); using tenant template summary / defaults for clone`
|
|
357
348
|
);
|
|
358
349
|
return void 0;
|
|
359
350
|
}
|
|
@@ -380,7 +371,7 @@ async function ensureProjectMembershipForAppstackCreate(params) {
|
|
|
380
371
|
);
|
|
381
372
|
if (!meResponse.ok) {
|
|
382
373
|
throw new Error(
|
|
383
|
-
`Failed to fetch PAT user from auth/me: ${
|
|
374
|
+
`Failed to fetch PAT user from auth/me: ${meResponse.status} ${getErrorMessage(meResponse.parsed, meResponse.text)}`
|
|
384
375
|
);
|
|
385
376
|
}
|
|
386
377
|
validateExpectedJsonResponse(meResponse.text, "authenticationApiObject.getMe");
|
|
@@ -418,7 +409,7 @@ async function ensureProjectMembershipForAppstackCreate(params) {
|
|
|
418
409
|
};
|
|
419
410
|
}
|
|
420
411
|
throw new Error(
|
|
421
|
-
`Failed to assign PAT user to project before appstack creation: ${
|
|
412
|
+
`Failed to assign PAT user to project before appstack creation: ${addUserResponse.status} ${getErrorMessage(addUserResponse.parsed, addUserResponse.text)}`
|
|
422
413
|
);
|
|
423
414
|
}
|
|
424
415
|
validateExpectedJsonResponse(
|
|
@@ -479,7 +470,7 @@ async function resolveTeamNameForUrl(stackgenApis, teamId, logger, traceId) {
|
|
|
479
470
|
return teamName || void 0;
|
|
480
471
|
} catch (error) {
|
|
481
472
|
logger.warn(
|
|
482
|
-
`[${traceId}] unable to resolve team name for appStack URL: ${
|
|
473
|
+
`[${traceId}] unable to resolve team name for appStack URL: ${String(error)}`
|
|
483
474
|
);
|
|
484
475
|
return void 0;
|
|
485
476
|
}
|
|
@@ -618,7 +609,7 @@ const createAppStackAction = (config, logger) => {
|
|
|
618
609
|
const blankCreateBody = blankCreateResponse.parsed;
|
|
619
610
|
const blankCreateText = blankCreateResponse.text;
|
|
620
611
|
if (!blankCreateResponse.ok) {
|
|
621
|
-
const errorMessage =
|
|
612
|
+
const errorMessage = blankCreateBody?.msg || blankCreateBody?.message || blankCreateText || "Unknown error";
|
|
622
613
|
const isLikelyExistsError = blankCreateResponse.status === 409 || blankCreateResponse.status === 400;
|
|
623
614
|
if (isLikelyExistsError) {
|
|
624
615
|
try {
|
|
@@ -674,9 +665,8 @@ const createAppStackAction = (config, logger) => {
|
|
|
674
665
|
if (errorString.includes("already exists. View it here")) {
|
|
675
666
|
throw resolveError;
|
|
676
667
|
}
|
|
677
|
-
const resolveDetail = await detailFromThrownError(resolveError);
|
|
678
668
|
ctx.logger.warn(
|
|
679
|
-
`[${traceId}] failed to resolve existing appstack for error message: ${
|
|
669
|
+
`[${traceId}] failed to resolve existing appstack for error message: ${resolveError}`
|
|
680
670
|
);
|
|
681
671
|
}
|
|
682
672
|
}
|
|
@@ -693,7 +683,7 @@ const createAppStackAction = (config, logger) => {
|
|
|
693
683
|
}
|
|
694
684
|
}
|
|
695
685
|
throw new Error(
|
|
696
|
-
`Failed to create blank appstack: ${errorMessage}.${membershipHint}`
|
|
686
|
+
`Failed to create blank appstack: ${blankCreateResponse.status} ${errorMessage}.${membershipHint}`
|
|
697
687
|
);
|
|
698
688
|
} else {
|
|
699
689
|
validateExpectedJsonResponse(blankCreateText, blankCreateUrl);
|
|
@@ -717,8 +707,9 @@ const createAppStackAction = (config, logger) => {
|
|
|
717
707
|
const listBody = listResponse.parsed;
|
|
718
708
|
const listText = listResponse.text;
|
|
719
709
|
if (!listResponse.ok) {
|
|
710
|
+
const errorMessage = listBody?.msg || listBody?.message || listText || "Unknown error";
|
|
720
711
|
throw new Error(
|
|
721
|
-
`Failed to resolve appstack ID: ${
|
|
712
|
+
`Failed to resolve appstack ID: ${listResponse.status} ${errorMessage}`
|
|
722
713
|
);
|
|
723
714
|
}
|
|
724
715
|
validateExpectedJsonResponse(listText, listUrl);
|
|
@@ -774,10 +765,12 @@ const createAppStackAction = (config, logger) => {
|
|
|
774
765
|
}),
|
|
775
766
|
201
|
|
776
767
|
);
|
|
768
|
+
const createResourceBody = createResourceResponse.parsed;
|
|
777
769
|
const createResourceText = createResourceResponse.text;
|
|
778
770
|
if (!createResourceResponse.ok) {
|
|
771
|
+
const errorMessage = createResourceBody?.msg || createResourceBody?.message || createResourceText || "Unknown error";
|
|
779
772
|
throw new Error(
|
|
780
|
-
`Failed to add resource pack to topology: ${
|
|
773
|
+
`Failed to add resource pack to topology: ${createResourceResponse.status} ${errorMessage}`
|
|
781
774
|
);
|
|
782
775
|
}
|
|
783
776
|
validateExpectedJsonResponse(createResourceText, createResourceUrl);
|
|
@@ -811,10 +804,12 @@ const createAppStackAction = (config, logger) => {
|
|
|
811
804
|
}),
|
|
812
805
|
201
|
|
813
806
|
);
|
|
807
|
+
const addResourceBody = addResourceResponse.parsed;
|
|
814
808
|
const addResourceText = addResourceResponse.text;
|
|
815
809
|
if (!addResourceResponse.ok) {
|
|
810
|
+
const errorMessage = addResourceBody?.msg || addResourceBody?.message || addResourceText || "Unknown error";
|
|
816
811
|
throw new Error(
|
|
817
|
-
`Failed to add resource '${resource.resourceType}' to topology: ${
|
|
812
|
+
`Failed to add resource '${resource.resourceType}' to topology: ${addResourceResponse.status} ${errorMessage}`
|
|
818
813
|
);
|
|
819
814
|
}
|
|
820
815
|
validateExpectedJsonResponse(addResourceText, addResourceUrl);
|
|
@@ -874,7 +869,7 @@ const createAppStackAction = (config, logger) => {
|
|
|
874
869
|
const responseText = response.text;
|
|
875
870
|
ctx.logger.info(`[${traceId}] Response status: ${response.status}`);
|
|
876
871
|
if (!response.ok) {
|
|
877
|
-
const errorMessage =
|
|
872
|
+
const errorMessage = responseBody?.msg || responseBody?.message || responseText || "Unknown error";
|
|
878
873
|
ctx.logger.error(
|
|
879
874
|
`[${traceId}] Error response: ${errorMessage}. Diagnostics: ${JSON.stringify({
|
|
880
875
|
teamId: appstack.teamId,
|
|
@@ -888,7 +883,7 @@ const createAppStackAction = (config, logger) => {
|
|
|
888
883
|
})}`
|
|
889
884
|
);
|
|
890
885
|
throw new Error(
|
|
891
|
-
`Failed to create appstack: ${errorMessage}`
|
|
886
|
+
`Failed to create appstack: ${response.status} ${errorMessage}`
|
|
892
887
|
);
|
|
893
888
|
}
|
|
894
889
|
validateExpectedJsonResponse(responseText, requestUrl);
|
|
@@ -935,7 +930,7 @@ const createAppStackAction = (config, logger) => {
|
|
|
935
930
|
)
|
|
936
931
|
);
|
|
937
932
|
} catch (error) {
|
|
938
|
-
const errorString =
|
|
933
|
+
const errorString = String(error);
|
|
939
934
|
let errorMessage = `Failed to create appStack: ${errorString}`;
|
|
940
935
|
if (membershipPreflightWarning && !errorString.includes("already exists. View it here")) {
|
|
941
936
|
errorMessage += ` (membership preflight warning: ${membershipPreflightWarning})`;
|