@stackgenhq/backstage-plugin-stackgen-backend 0.3.6-beta.1

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.
Files changed (66) hide show
  1. package/README.md +485 -0
  2. package/config.d.ts +39 -0
  3. package/dist/actions/core/assign_project_members_action.cjs.js +227 -0
  4. package/dist/actions/core/assign_project_members_action.cjs.js.map +1 -0
  5. package/dist/actions/core/create_appstack_action.cjs.js +953 -0
  6. package/dist/actions/core/create_appstack_action.cjs.js.map +1 -0
  7. package/dist/actions/core/create_project_action.cjs.js +243 -0
  8. package/dist/actions/core/create_project_action.cjs.js.map +1 -0
  9. package/dist/actions/core/download_iac_action.cjs.js +133 -0
  10. package/dist/actions/core/download_iac_action.cjs.js.map +1 -0
  11. package/dist/actions/core/set_environment_variable_values_action.cjs.js +121 -0
  12. package/dist/actions/core/set_environment_variable_values_action.cjs.js.map +1 -0
  13. package/dist/actions/core/set_state_backend_action.cjs.js +174 -0
  14. package/dist/actions/core/set_state_backend_action.cjs.js.map +1 -0
  15. package/dist/actions/exporter/export_iac_to_git_action.cjs.js +290 -0
  16. package/dist/actions/exporter/export_iac_to_git_action.cjs.js.map +1 -0
  17. package/dist/actions/exporter/list_vault_secrets_action.cjs.js +39 -0
  18. package/dist/actions/exporter/list_vault_secrets_action.cjs.js.map +1 -0
  19. package/dist/config/constants.cjs.js +23 -0
  20. package/dist/config/constants.cjs.js.map +1 -0
  21. package/dist/exporter/exportOverrides.cjs.js +27 -0
  22. package/dist/exporter/exportOverrides.cjs.js.map +1 -0
  23. package/dist/exporter/gitExporterConfigHttp.cjs.js +105 -0
  24. package/dist/exporter/gitExporterConfigHttp.cjs.js.map +1 -0
  25. package/dist/exporter/http.cjs.js +14 -0
  26. package/dist/exporter/http.cjs.js.map +1 -0
  27. package/dist/exporter/paths.cjs.js +25 -0
  28. package/dist/exporter/paths.cjs.js.map +1 -0
  29. package/dist/exporter/projectGitExporterTemplate.cjs.js +62 -0
  30. package/dist/exporter/projectGitExporterTemplate.cjs.js.map +1 -0
  31. package/dist/exporter/topologyResolve.cjs.js +71 -0
  32. package/dist/exporter/topologyResolve.cjs.js.map +1 -0
  33. package/dist/index.cjs.js +31 -0
  34. package/dist/index.cjs.js.map +1 -0
  35. package/dist/index.d.ts +224 -0
  36. package/dist/lib/extractArchive.cjs.js +62 -0
  37. package/dist/lib/extractArchive.cjs.js.map +1 -0
  38. package/dist/modules/stackgenExporterScaffolderModule.cjs.js +29 -0
  39. package/dist/modules/stackgenExporterScaffolderModule.cjs.js.map +1 -0
  40. package/dist/modules/stackgenUiProxiesModule.cjs.js +366 -0
  41. package/dist/modules/stackgenUiProxiesModule.cjs.js.map +1 -0
  42. package/dist/plugin/plugin.cjs.js +136 -0
  43. package/dist/plugin/plugin.cjs.js.map +1 -0
  44. package/dist/plugin/router.cjs.js +341 -0
  45. package/dist/plugin/router.cjs.js.map +1 -0
  46. package/dist/services/MappingsService/mappingsService.cjs.js +149 -0
  47. package/dist/services/MappingsService/mappingsService.cjs.js.map +1 -0
  48. package/dist/services/StackgenService/stackgenService.cjs.js +267 -0
  49. package/dist/services/StackgenService/stackgenService.cjs.js.map +1 -0
  50. package/dist/utils/api-objects.cjs.js +205 -0
  51. package/dist/utils/api-objects.cjs.js.map +1 -0
  52. package/dist/vendor/stackgen-api-client/index.cjs.js +47681 -0
  53. package/dist/vendor/stackgen-api-client/index.cjs.js.map +1 -0
  54. package/migrations/20250131055302_init.js +24 -0
  55. package/migrations/20250305123456_alter_type_associations.js +23 -0
  56. package/package.json +86 -0
  57. package/templates/appstack-configure-environment.yaml +81 -0
  58. package/templates/appstack-from-template.yaml +76 -0
  59. package/templates/appstack-with-modules.yaml +69 -0
  60. package/templates/appstack-with-resources.yaml +81 -0
  61. package/templates/export-iac.yaml +97 -0
  62. package/templates/full-infra-setup.yaml +156 -0
  63. package/templates/git_export_exporter_multi_scm.yaml +123 -0
  64. package/templates/project-advanced.yaml +77 -0
  65. package/templates/project-basic.yaml +39 -0
  66. package/templates/project-with-members.yaml +86 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create_appstack_action.cjs.js","sources":["../../../src/actions/core/create_appstack_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 executeApiRequest,\n formatApiFailure,\n formatClientErrorMessage,\n getStackgenApiObjects,\n} from \"../../utils/api-objects\";\n\nconst iacTypeSchema = z.enum([\"Helm\", \"Terraform\"]);\n\nconst childResourceSchema: z.ZodType<any> = z.lazy(() =>\n z.object({\n resourceType: z.string(),\n name: z.string().optional(),\n iacType: iacTypeSchema.optional(),\n configuration: z.record(z.string(), z.any()).optional(),\n tfVars: z.record(z.string(), z.string()).optional(),\n resourceTemplateVersionName: z.string().optional(),\n resourcePackId: z.string().optional(),\n templateId: z.string().optional(),\n children: z.array(childResourceSchema).optional(),\n }),\n);\n\nconst resourceSchema = z\n .object({\n resourceType: z.string().optional(),\n name: z.string().optional(),\n iacType: iacTypeSchema.optional(),\n resourceTemplateVersionName: z.string().optional(),\n configuration: z.record(z.string(), z.any()).optional(),\n tfVars: z.record(z.string(), z.string()).optional(),\n resourcePackId: z.string().optional(),\n templateId: z.string().optional(),\n children: z.array(childResourceSchema).optional(),\n /** ModuleSelect field shape — coerced to a custom module resource. */\n id: z.string().optional(),\n baseId: z.string().optional(),\n label: z.string().optional(),\n versionName: z.string().optional(),\n moduleName: z.string().optional(),\n })\n .superRefine((res: any, ctx: any) => {\n const hasConfiguration = !!res.configuration;\n const hasResourcePackId = !!res.resourcePackId;\n const looksLikeModuleSelect =\n typeof res.id === \"string\" &&\n res.id &&\n !res.resourceType &&\n !res.templateId &&\n !res.resourcePackId;\n\n if (!res.resourceType && !looksLikeModuleSelect) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message:\n \"resourceType is required (or pass a ModuleSelect value with id)\",\n path: [\"resourceType\"],\n });\n }\n\n if (hasConfiguration && hasResourcePackId) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message:\n \"only one of 'configuration' or 'resourcePackId' should be provided, not both for a resource\",\n path: [\"configuration\"],\n });\n }\n });\n\n/** Default for iac-gen topology clone when the template AppStack has no `coreConfig.targetCompute`. */\nconst DEFAULT_TOPOLOGY_DEPLOYMENT_TYPE = \"k8s\";\n\nexport const createAppstackInputSchema = z.object({\n appstack: z.object({\n name: z.string().trim().optional(),\n appstackName: z.string().trim().optional(),\n teamId: z.string().trim().min(1, \"appstack.teamId is required\"),\n /**\n * Required unless `templateAppstackId` is set (provider is then read from the\n * tenant template list `cloudProvider` or appcd `coreConfig.provider`).\n */\n cloudProvider: z.string().trim().optional(),\n /**\n * When set: resolve tenant template summary (and optionally appcd AppStack\n * `coreConfig`), create an empty AppStack, then POST iac-gen topology with\n * `appstackRefId` to clone. Mutually exclusive with a non-empty `resources` array.\n */\n templateAppstackId: z.string().trim().uuid().optional(),\n resources: z.array(resourceSchema).default([]),\n }).superRefine((appstack: any, ctx: any) => {\n const name = appstack.name?.trim();\n const appstackName = appstack.appstackName?.trim();\n if (!name && !appstackName) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"one of 'name' or 'appstackName' must be provided\",\n path: [\"name\"],\n });\n }\n const templateId = appstack.templateAppstackId?.trim();\n const cloud = appstack.cloudProvider?.trim();\n if (!templateId && !cloud) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message:\n \"appstack.cloudProvider is required when templateAppstackId is not set\",\n path: [\"cloudProvider\"],\n });\n }\n if (templateId && appstack.resources.length > 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message:\n \"templateAppstackId cannot be used together with a non-empty resources array; use either topology clone or explicit resources, not both\",\n path: [\"templateAppstackId\"],\n });\n }\n }),\n});\n\nexport const appstackOutputSchema = z.object({\n appstackId: z.string(),\n appstackName: z.string(),\n appStackURL: z.string(),\n topologyId: z.string().optional(),\n});\n\n/**\n * Integrations appstack payloads: `appstackId` is the appstack id; `uuid` is the topology id.\n * Also accepts legacy shapes (`id`, `topologyId` only).\n */\nfunction readIntegrationsAppstackIds(body: any): {\n appstackId: string;\n topologyId: string;\n} {\n const appstackId =\n (typeof body?.appstackId === 'string' && body.appstackId.trim()) ||\n (typeof body?.id === 'string' && body.id.trim()) ||\n '';\n const topologyId =\n (typeof body?.uuid === 'string' && body.uuid.trim()) ||\n (typeof body?.topologyId === 'string' && body.topologyId.trim()) ||\n appstackId ||\n '';\n return { appstackId, topologyId };\n}\n\nconst DEFAULT_PROJECT_MEMBER_ROLE_ID = \"00000000-0000-0000-0000-000000000002\";\n\nfunction validateTeamId(teamId: string | undefined, allowedTeams: string[]) {\n if (allowedTeams.length === 0) return;\n if (teamId && !allowedTeams.includes(teamId)) {\n throw new Error(`Team ID ${teamId} is not allowed.`);\n }\n}\n\nfunction walkResources(resources: any[], visit: (resource: any) => void): void {\n for (const resource of resources) {\n visit(resource);\n if (Array.isArray(resource?.children) && resource.children.length > 0) {\n walkResources(resource.children, visit);\n }\n }\n}\n\nfunction countField(resources: any[], field: string): number {\n let count = 0;\n walkResources(resources, resource => {\n if (resource && resource[field] !== undefined) {\n count += 1;\n }\n });\n return count;\n}\n\nfunction countResources(resources: any[]): number {\n let count = 0;\n walkResources(resources, () => {\n count += 1;\n });\n return count;\n}\n\nfunction inferIacType(resourceType: string): \"Helm\" | \"Terraform\" {\n return resourceType.toLowerCase().includes(\"helm\") ? \"Helm\" : \"Terraform\";\n}\n\n/** Strip a trailing \" (…)\" / \"(…)\" suffix without regex backtracking. */\nfunction stripTrailingParenthetical(label: string): string {\n const isSpace = (ch: string) => ch.trim() === \"\";\n let end = label.length;\n while (end > 0 && isSpace(label.charAt(end - 1))) {\n end -= 1;\n }\n if (end === 0 || label.charAt(end - 1) !== \")\") {\n return label.trim();\n }\n const close = end - 1;\n const open = label.lastIndexOf(\"(\", close);\n if (open < 0 || label.slice(open + 1, close).includes(\")\")) {\n return label.trim();\n }\n let start = open;\n while (start > 0 && isSpace(label.charAt(start - 1))) {\n start -= 1;\n }\n return `${label.slice(0, start)}${label.slice(end)}`.trim();\n}\n\nfunction normalizeIacType(\n iacType: unknown,\n resourceType: string,\n): \"Helm\" | \"Terraform\" {\n if (typeof iacType === \"string\") {\n const normalized = iacType.trim().toLowerCase();\n if (normalized === \"helm\") return \"Helm\";\n if (normalized === \"terraform\") return \"Terraform\";\n }\n return inferIacType(resourceType);\n}\n\nfunction resolveResourceName(resource: any, path: string): string {\n const explicitName =\n typeof resource?.name === \"string\" ? resource.name.trim() : \"\";\n if (explicitName) return explicitName;\n\n const configName =\n typeof resource?.configuration?.name === \"string\"\n ? resource.configuration.name.trim()\n : \"\";\n if (configName) return configName;\n\n return `${resource.resourceType}-${path}`;\n}\n\n// Legacy path: normalize resources but preserve resourcePackId (no resourceTemplateVersionName remap).\n// Also coerces ModuleSelect field values ({ id, label, versionName }) into custom module resources.\nfunction legacyNormalizeResources(resources: any[], parentPath = \"\"): any[] {\n return resources.map((res, index) => {\n const resourcePath = parentPath ? `${parentPath}-${index}` : `${index}`;\n const looksLikeModuleSelect =\n res &&\n typeof res === \"object\" &&\n typeof res.id === \"string\" &&\n res.id &&\n !res.resourceType &&\n !res.templateId &&\n !res.resourcePackId;\n\n const source = looksLikeModuleSelect\n ? {\n resourceType: \"vibe-coded-module\",\n iacType: \"Terraform\",\n templateId: res.id,\n name:\n typeof res.label === \"string\" && res.label.trim()\n ? stripTrailingParenthetical(res.label)\n : res.moduleName || res.id,\n }\n : res;\n\n const { children, ...rest } = source;\n const normalized: any = {\n ...rest,\n iacType: normalizeIacType(rest.iacType, rest.resourceType),\n name: resolveResourceName(rest, resourcePath),\n };\n\n if (Array.isArray(children) && children.length > 0) {\n normalized.children = legacyNormalizeResources(children, resourcePath);\n }\n\n return normalized;\n });\n}\n\nfunction validateExpectedJsonResponse(\n responseText: string,\n endpoint: string,\n): void {\n const trimmed = responseText.trim();\n if (!trimmed) {\n return;\n }\n\n const lowered = trimmed.toLowerCase();\n if (\n lowered === \"/login\" ||\n lowered.startsWith(\"<!doctype html\") ||\n lowered.startsWith(\"<html\")\n ) {\n throw new Error(\n `Received login response from ${endpoint}. Check configured base URL and API token permissions.`,\n );\n }\n\n if (!(trimmed.startsWith(\"{\") || trimmed.startsWith(\"[\"))) {\n throw new Error(\n `Unexpected non-JSON success response from ${endpoint}: ${trimmed.slice(0, 120)}`,\n );\n }\n}\n\nfunction formatRequestFailure(res: {\n status: number;\n parsed: unknown;\n text: string;\n requestId?: string;\n}): string {\n return formatApiFailure(res.status, res.parsed, res.text, res.requestId);\n}\n\n/** Prefer formatted client ResponseError; otherwise use Error.message. */\nasync function detailFromThrownError(error: unknown): Promise<string> {\n if ((error as { response?: unknown })?.response) {\n return formatClientErrorMessage(error);\n }\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n\nasync function cloneTopologyFromTemplateAppstack(params: {\n stackgenApis: ReturnType<typeof getStackgenApiObjects>;\n orgId: string;\n newAppstackId: string;\n templateAppstackId: string;\n cloudProvider: string;\n deploymentType: string;\n iacType: \"Helm\" | \"Terraform\";\n traceId: string;\n logger: LoggerService;\n}): Promise<void> {\n const {\n stackgenApis,\n orgId,\n newAppstackId,\n templateAppstackId,\n cloudProvider,\n deploymentType,\n iacType,\n traceId,\n logger,\n } = params;\n const body = {\n appstackId: newAppstackId,\n appstackRefId: templateAppstackId,\n cloudProvider,\n deploymentType,\n iacType,\n };\n logger.info(\n `[${traceId}] cloning topology from template appstack ${templateAppstackId} onto ${newAppstackId}`,\n );\n const res = await executeApiRequest(\n () =>\n stackgenApis.v1TopologyApiObj.createTopology({\n orgId,\n newTopologyRequest: body as never,\n }),\n 201,\n );\n if (!res.ok) {\n throw new Error(\n `Failed to clone topology from template AppStack: ${formatRequestFailure(res)}`,\n );\n }\n validateExpectedJsonResponse(\n res.text,\n \"topology.createTopologyRaw\",\n );\n}\n\n/** templateAppstack from GET /v1/template-appstacks (tenant-wide). */\ntype TemplateAppStackSummary = {\n appstackId: string;\n owner?: string;\n cloudProvider?: string;\n name?: string;\n};\n\n/** Snapshot from appcd GET /v1/appstacks/{uuid} for topology clone defaults. */\ntype TemplateAppStackSnapshot = {\n provider?: string;\n targetCompute?: string;\n targetIac?: unknown;\n};\n\nfunction pickTopologyIacTypeFromTargetIac(\n targetIac: unknown,\n): \"Helm\" | \"Terraform\" | undefined {\n if (!Array.isArray(targetIac)) {\n return undefined;\n }\n for (const entry of targetIac) {\n if (entry === \"Helm\" || entry === \"Terraform\") {\n return entry;\n }\n if (typeof entry === \"string\") {\n const n = entry.trim();\n if (n === \"Helm\" || n === \"Terraform\") {\n return n;\n }\n }\n }\n return undefined;\n}\n\n/**\n * Tenant template AppStacks live under their `owner` project. Listing them does not\n * require membership in that project; GET /appstacks/{uuid} often does.\n */\nasync function fetchTemplateAppStackSummary(params: {\n stackgenApis: ReturnType<typeof getStackgenApiObjects>;\n templateUuid: string;\n traceId: string;\n logger: LoggerService;\n}): Promise<TemplateAppStackSummary | undefined> {\n const { stackgenApis, templateUuid, traceId, logger } = params;\n const pageSize = 100;\n let offset = 0;\n\n for (;;) {\n logger.info(\n `[${traceId}] resolving template AppStack ${templateUuid} from tenant template list`,\n );\n const pageOffset = offset;\n const res = await executeApiRequest(() =>\n stackgenApis.appStacksApiObj.getTemplateAppstacks({\n limit: pageSize,\n offset: pageOffset,\n }),\n );\n if (!res.ok) {\n throw new Error(\n `Failed to list template AppStacks from appcd: ${formatRequestFailure(res)}`,\n );\n }\n validateExpectedJsonResponse(res.text, \"appStacksApiObj.getTemplateAppstacks\");\n\n const rows = Array.isArray(res.parsed?.appstacks) ? res.parsed.appstacks : [];\n const match = rows.find(\n (row: { appstackId?: string }) =>\n String(row?.appstackId || \"\").trim() === templateUuid,\n );\n if (match) {\n const cloudProvider =\n typeof match.cloudProvider === \"string\"\n ? match.cloudProvider.trim()\n : undefined;\n const owner =\n typeof match.owner === \"string\" ? match.owner.trim() : undefined;\n const name = typeof match.name === \"string\" ? match.name.trim() : undefined;\n return {\n appstackId: templateUuid,\n owner: owner || undefined,\n cloudProvider: cloudProvider || undefined,\n name: name || undefined,\n };\n }\n\n if (rows.length < pageSize) {\n return undefined;\n }\n offset += pageSize;\n if (offset > 10_000) {\n logger.warn(\n `[${traceId}] stopped paging template-appstacks after offset ${offset} without finding ${templateUuid}`,\n );\n return undefined;\n }\n }\n}\n\n/**\n * Best-effort coreConfig defaults. Cross-project templates often 404/403 here when\n * the PAT is not a member of the template owner project; callers fall back to the\n * tenant template summary.\n */\nasync function fetchAppStackSnapshotForTemplateClone(params: {\n stackgenApis: ReturnType<typeof getStackgenApiObjects>;\n orgId: string;\n templateUuid: string;\n traceId: string;\n logger: LoggerService;\n}): Promise<TemplateAppStackSnapshot | undefined> {\n const {\n stackgenApis,\n orgId,\n templateUuid,\n traceId,\n logger,\n } = params;\n logger.info(\n `[${traceId}] loading template AppStack for clone defaults`,\n );\n const res = await executeApiRequest(() =>\n stackgenApis.appStacksApiObj.getAppStack({\n uuid: templateUuid,\n orgId,\n }),\n );\n if (!res.ok) {\n logger.warn(\n `[${traceId}] could not load AppStack ${templateUuid} via appcd GET (${formatRequestFailure(res)}); using tenant template summary / defaults for clone`,\n );\n return undefined;\n }\n validateExpectedJsonResponse(res.text, \"appStacksApiObj.getAppStack\");\n const cc = res.parsed?.coreConfig;\n return {\n provider: typeof cc?.provider === \"string\" ? cc.provider.trim() : undefined,\n targetCompute:\n typeof cc?.targetCompute === \"string\" ? cc.targetCompute.trim() : undefined,\n targetIac: cc?.targetIac,\n };\n}\n\nfunction isAlreadyMemberResponse(\n status: number,\n parsedBody: any,\n responseText: string,\n): boolean {\n const lowered = `${parsedBody?.msg || \"\"} ${parsedBody?.message || \"\"} ${parsedBody?.error || \"\"} ${responseText || \"\"}`\n .toLowerCase();\n if (status === 409 && (lowered.includes(\"already\") || lowered.includes(\"exists\"))) {\n return true;\n }\n return lowered.includes(\"already member\") || lowered.includes(\"already exists\");\n}\n\nasync function ensureProjectMembershipForAppstackCreate(params: {\n stackgenApis: ReturnType<typeof getStackgenApiObjects>;\n projectId: string;\n roleId: string;\n traceId: string;\n logger: LoggerService;\n}): Promise<{ userId: string; addedToProject: boolean }> {\n const { stackgenApis, projectId, roleId, traceId, logger } = params;\n logger.info(`[${traceId}] resolving PAT user via appcd auth`);\n\n const meResponse = await executeApiRequest(\n () => stackgenApis.authenticationApiObject.getMe(),\n );\n\n if (!meResponse.ok) {\n throw new Error(\n `Failed to fetch PAT user from auth/me: ${formatRequestFailure(meResponse)}`,\n );\n }\n validateExpectedJsonResponse(meResponse.text, \"authenticationApiObject.getMe\");\n\n const userId = String(meResponse.parsed?.userId || \"\").trim();\n if (!userId) {\n throw new Error(\n \"auth/me response did not include userId; cannot assign project membership for appstack creation\",\n );\n }\n\n const addUserPayload = {\n userAssignments: [{ userId, roleId }],\n };\n logger.info(\n `[${traceId}] assigning PAT user ${userId} to project ${projectId} with role ${roleId}`,\n );\n\n const addUserResponse = await executeApiRequest(\n () =>\n stackgenApis.projectApiObject.assignUsersToOrg({\n orgId: projectId,\n assignUsersToOrgRequest: addUserPayload as never,\n }),\n 201,\n );\n\n if (!addUserResponse.ok) {\n if (\n isAlreadyMemberResponse(\n addUserResponse.status,\n addUserResponse.parsed,\n addUserResponse.text,\n )\n ) {\n logger.info(\n `[${traceId}] PAT user ${userId} is already assigned to project ${projectId}, continuing`,\n );\n return {\n userId,\n addedToProject: false,\n };\n }\n throw new Error(\n `Failed to assign PAT user to project before appstack creation: ${formatRequestFailure(addUserResponse)}`,\n );\n }\n validateExpectedJsonResponse(\n addUserResponse.text,\n \"projectApiObject.assignUsersToOrg\",\n );\n return {\n userId,\n addedToProject: true,\n };\n}\n\nfunction collectResourcePackResources(resources: any[]): any[] {\n const collected: any[] = [];\n walkResources(resources, resource => {\n if (resource?.resourcePackId) {\n collected.push(resource);\n }\n });\n return collected;\n}\n\nfunction buildAppStackUrl(\n baseUrl: string,\n appstackId: string,\n projectName?: string,\n): string {\n const cleanBaseUrl = baseUrl.endsWith(\"/\") ? baseUrl.slice(0, -1) : baseUrl;\n if (!appstackId) {\n return `${cleanBaseUrl}/appstacks`;\n }\n if (projectName) {\n return `${cleanBaseUrl}/project/${encodeURIComponent(\n projectName,\n )}/appstacks/${encodeURIComponent(appstackId)}?tabId=topology`;\n }\n return `${cleanBaseUrl}/appstacks/${encodeURIComponent(appstackId)}`;\n}\n\nasync function resolveTeamNameForUrl(\n stackgenApis: ReturnType<typeof getStackgenApiObjects>,\n teamId: string,\n logger: LoggerService,\n traceId: string,\n): Promise<string | undefined> {\n try {\n const response = await executeApiRequest(() =>\n stackgenApis.integrationsTeamApiObj.listTeams({ includeAll: true }),\n );\n\n if (!response.ok) {\n logger.warn(\n `[${traceId}] failed to resolve team name for appStack URL (status=${response.status})`,\n );\n return undefined;\n }\n\n validateExpectedJsonResponse(response.text, \"integrationsTeamApiObj.listTeams\");\n let teams: any[] = [];\n if (Array.isArray(response.parsed)) {\n teams = response.parsed;\n } else if (Array.isArray(response.parsed?.items)) {\n teams = response.parsed.items;\n }\n const matchedTeam = teams.find(\n (team: any) => (team?.id || team?.teamId || \"\").trim() === teamId,\n );\n let teamName: string | undefined;\n if (matchedTeam) {\n teamName =\n matchedTeam?.name?.trim() ||\n matchedTeam?.teamName?.trim() ||\n matchedTeam?.displayName?.trim();\n }\n return teamName || undefined;\n } catch (error) {\n logger.warn(\n `[${traceId}] unable to resolve team name for appStack URL: ${await detailFromThrownError(error)}`,\n );\n return undefined;\n }\n}\n\nexport const createAppStackAction = (config: Config, logger: LoggerService) => {\n return createTemplateAction({\n id: \"stackGen:createAppStack\",\n description:\n \"Creates an AppStack in StackGen for the provided configuration\",\n schema: {\n // Backstage parseSchemas only accepts (z) => ZodType or per-field callbacks.\n // Raw ZodObject yields schema.input/output === undefined (Installed actions blank).\n input: () => createAppstackInputSchema,\n output: () => appstackOutputSchema,\n },\n\n async handler(ctx: any) {\n let membershipPreflightWarning: string | undefined;\n const traceId = `create-appstack-${Date.now()}`;\n try {\n const allowedTeams =\n config\n .getOptionalString(\"stackGen.allowedTeams\")\n ?.split(\",\")\n .map((id: string) => id.trim()) || [];\n\n validateTeamId(ctx.input.appstack.teamId, allowedTeams);\n\n const stackgenApis = getStackgenApiObjects(config);\n const { appstack } = ctx.input;\n const resolvedAppstackName =\n appstack.name?.trim() || appstack.appstackName?.trim() || \"\";\n const incomingResources = appstack.resources ?? [];\n const projectMemberRoleId =\n config.getOptionalString(\"stackGen.projectMemberRoleId\")?.trim() ||\n DEFAULT_PROJECT_MEMBER_ROLE_ID;\n\n if (!resolvedAppstackName) {\n ctx.logger.error(\n `[${traceId}] Invalid appstack input: both name and appstackName are empty`,\n );\n throw new Error(\"appstack name is required and cannot be empty\");\n }\n\n const cleanBaseUrl = stackgenApis.baseUrl;\n const sanitizedResources = legacyNormalizeResources(incomingResources);\n const inputResourcePackIdCount = countField(incomingResources, \"resourcePackId\");\n const outputResourcePackIdCount = countField(sanitizedResources, \"resourcePackId\");\n const iacTypeCount = countField(sanitizedResources, \"iacType\");\n const nameCount = countField(sanitizedResources, \"name\");\n const templateIdCount = countField(sanitizedResources, \"templateId\");\n const totalResourceCount = countResources(sanitizedResources);\n\n const templateUuidForClone = appstack.templateAppstackId?.trim();\n const orgScopeForAppcd =\n config.getOptionalString(\"stackGen.orgId\")?.trim() ||\n appstack.teamId;\n\n let templateSummary: TemplateAppStackSummary | undefined;\n let templateSnapshot: TemplateAppStackSnapshot | undefined;\n if (templateUuidForClone) {\n templateSummary = await fetchTemplateAppStackSummary({\n stackgenApis,\n templateUuid: templateUuidForClone,\n traceId,\n logger: ctx.logger,\n });\n if (!templateSummary) {\n ctx.logger.warn(\n `[${traceId}] template AppStack ${templateUuidForClone} was not found in tenant template-appstacks; will try appcd GET with destination/org scope`,\n );\n }\n // Prefer template owner org for GET (templates are project-scoped there).\n const orgIdForTemplateGet =\n templateSummary?.owner || orgScopeForAppcd;\n templateSnapshot = await fetchAppStackSnapshotForTemplateClone({\n stackgenApis,\n orgId: orgIdForTemplateGet,\n templateUuid: templateUuidForClone,\n traceId,\n logger: ctx.logger,\n });\n }\n\n const effectiveCloudProvider = (\n appstack.cloudProvider?.trim() ||\n templateSnapshot?.provider ||\n templateSummary?.cloudProvider ||\n \"\"\n ).trim();\n if (!effectiveCloudProvider) {\n throw new Error(\n templateUuidForClone\n ? `Could not determine cloudProvider for template AppStack ${templateUuidForClone}. Pass appstack.cloudProvider, or ensure the UUID is a tenant template (template-appstacks) with cloudProvider set.`\n : \"appstack.cloudProvider is required when templateAppstackId is not set\",\n );\n }\n\n const deploymentTypeForTopologyClone =\n templateSnapshot?.targetCompute?.trim() ||\n DEFAULT_TOPOLOGY_DEPLOYMENT_TYPE;\n\n const topologyIacTypeForClone =\n pickTopologyIacTypeFromTargetIac(templateSnapshot?.targetIac) ??\n \"Terraform\";\n\n ctx.logger.info(\n `[${traceId}] createAppStack input summary: ${JSON.stringify({\n teamId: appstack.teamId,\n cloudProviderInput: appstack.cloudProvider?.trim() || undefined,\n effectiveCloudProvider,\n resolvedAppstackName,\n totalResourceCount,\n inputResourcePackIdCount,\n outputResourcePackIdCount,\n iacTypeCount,\n nameCount,\n templateAppstackId: templateUuidForClone || undefined,\n deploymentTypeForTopologyClone,\n topologyIacTypeForClone,\n appcdBaseUrl: cleanBaseUrl,\n roleId: projectMemberRoleId,\n })}`,\n );\n\n try {\n const membershipResult = await ensureProjectMembershipForAppstackCreate({\n stackgenApis,\n projectId: appstack.teamId,\n roleId: projectMemberRoleId,\n traceId,\n logger,\n });\n if (membershipResult.addedToProject) {\n logger.info(\n `[${traceId}] PAT user ${membershipResult.userId} was added to project/team ${appstack.teamId} and remains a member`,\n );\n }\n logger.info(\n `[${traceId}] verified PAT user membership for project/team ${appstack.teamId} before appstack creation`,\n );\n } catch (membershipError) {\n membershipPreflightWarning = String(membershipError);\n logger.warn(\n `[${traceId}] membership preflight failed, proceeding with appstack creation: ${membershipPreflightWarning}`,\n );\n }\n\n const hasResourcePackInput = inputResourcePackIdCount > 0;\n const hasCustomModuleInput = templateIdCount > 0;\n\n if (hasResourcePackInput || hasCustomModuleInput) {\n // Integrations API rejects `resourceType: resourcePack` and custom modules\n // (templateId); create blank appstack first, then add resources to the topology.\n const blankCreateUrl = `${cleanBaseUrl}/integrations/api/v1/projects/${appstack.teamId}/appstacks`;\n const blankCreatePayload = {\n name: resolvedAppstackName,\n cloudProvider: effectiveCloudProvider,\n topology: {\n source: { name: \"backstage\" },\n resources: [],\n resourceConnections: [],\n },\n };\n\n logger.info(\n `[${traceId}] two-step topology flow enabled (resourcePacks=${inputResourcePackIdCount}, customModules=${templateIdCount}), creating blank appStack at ${blankCreateUrl}`,\n );\n\n const blankCreateResponse = await executeApiRequest(\n () =>\n stackgenApis.integrationsAppstackApiObj.createProjectAppStack({\n projectId: appstack.teamId,\n appStackRequest: blankCreatePayload as never,\n }),\n 201,\n );\n const blankCreateBody = blankCreateResponse.parsed;\n const blankCreateText = blankCreateResponse.text;\n\n if (!blankCreateResponse.ok) {\n const errorMessage = formatRequestFailure(blankCreateResponse);\n\n const isLikelyExistsError =\n blankCreateResponse.status === 409 ||\n blankCreateResponse.status === 400;\n\n if (isLikelyExistsError) {\n // Attempt to resolve existing appstack to provide a helpful link\n try {\n const listResponse = await executeApiRequest(() =>\n stackgenApis.integrationsAppstackApiObj.listProjectAppStacks({\n projectId: appstack.teamId,\n name: resolvedAppstackName,\n }),\n );\n\n if (listResponse.ok) {\n const listBody = listResponse.parsed;\n ctx.logger.info(`[${traceId}] Existing AppStack lookup response body: ${JSON.stringify(listBody)}`);\n\n let appstacks: any[] = [];\n if (Array.isArray(listBody)) {\n appstacks = listBody;\n } else if (Array.isArray(listBody?.items)) {\n appstacks = listBody.items;\n }\n\n ctx.logger.info(`[${traceId}] Found ${appstacks.length} items in appstack list`);\n\n const exactMatch = appstacks.find((candidate: any) => {\n const candidateName =\n (candidate?.appstackName || candidate?.name || \"\").trim();\n const match = candidateName === resolvedAppstackName;\n if (!match) {\n ctx.logger.info(`[${traceId}] candidate '${candidateName}' != '${resolvedAppstackName}'`);\n }\n return match;\n });\n\n if (exactMatch) {\n ctx.logger.info(`[${traceId}] Found exact match for existing appstack: ${exactMatch.appstackId}`);\n const existingAppstackId =\n exactMatch.appstackId || exactMatch.id;\n const teamNameForUrl = await resolveTeamNameForUrl(\n stackgenApis,\n appstack.teamId,\n logger,\n traceId,\n );\n const appStackUrl = buildAppStackUrl(\n cleanBaseUrl,\n existingAppstackId,\n teamNameForUrl,\n );\n throw new Error(\n `AppStack '${resolvedAppstackName}' already exists. View it here: ${appStackUrl}`,\n );\n } else {\n ctx.logger.warn(`[${traceId}] No exact match found for '${resolvedAppstackName}' in ${appstacks.length} items`);\n }\n } else {\n ctx.logger.warn(`[${traceId}] List appstacks failed with status ${listResponse.status}`);\n }\n } catch (resolveError) {\n const errorString = String(resolveError);\n if (errorString.includes(\"already exists. View it here\")) {\n throw resolveError;\n }\n // If resolving fails, we fall through to the generic error below\n const resolveDetail = await detailFromThrownError(resolveError);\n ctx.logger.warn(\n `[${traceId}] failed to resolve existing appstack for error message: ${resolveDetail}`,\n );\n }\n }\n\n let membershipHint = \"\";\n if (\n blankCreateResponse.status === 500 &&\n String(blankCreateBody?.errCode || \"\").toUpperCase() ===\n \"CREATE_APPSTACK_ERROR\"\n ) {\n const visibleTeamName = await resolveTeamNameForUrl(\n stackgenApis,\n appstack.teamId,\n logger,\n traceId,\n );\n if (!visibleTeamName) {\n membershipHint =\n \" The provided team/project is not visible to this PAT. Ensure the PAT user is added to the project/team before creating appstacks in it.\";\n }\n }\n\n throw new Error(\n `Failed to create blank appstack: ${errorMessage}.${membershipHint}`,\n );\n } else {\n validateExpectedJsonResponse(blankCreateText, blankCreateUrl);\n }\n\n const fromBlank = readIntegrationsAppstackIds(blankCreateBody);\n let resolvedAppstackId = fromBlank.appstackId;\n let resolvedTopologyId = fromBlank.topologyId;\n\n if (!resolvedAppstackId) {\n const listUrl = `${cleanBaseUrl}/integrations/api/v1/projects/${appstack.teamId}/appstacks?name=${encodeURIComponent(\n resolvedAppstackName,\n )}`;\n logger.info(\n `[${traceId}] resolving appstack ID by list API ${listUrl}`,\n );\n\n const listResponse = await executeApiRequest(() =>\n stackgenApis.integrationsAppstackApiObj.listProjectAppStacks({\n projectId: appstack.teamId,\n name: resolvedAppstackName,\n }),\n );\n const listBody = listResponse.parsed;\n const listText = listResponse.text;\n\n if (!listResponse.ok) {\n throw new Error(\n `Failed to resolve appstack ID: ${formatRequestFailure(listResponse)}`,\n );\n }\n validateExpectedJsonResponse(listText, listUrl);\n\n let appstacks: any[] = [];\n if (Array.isArray(listBody)) {\n appstacks = listBody;\n } else if (Array.isArray(listBody?.items)) {\n appstacks = listBody.items;\n }\n const exactMatch = appstacks.find((candidate: any) => {\n const candidateName =\n (candidate?.appstackName || candidate?.name || \"\").trim();\n return candidateName === resolvedAppstackName;\n });\n\n const fromList = readIntegrationsAppstackIds(exactMatch);\n resolvedAppstackId = fromList.appstackId;\n resolvedTopologyId = fromList.topologyId || resolvedTopologyId;\n }\n\n if (!resolvedAppstackId) {\n throw new Error(\n `Failed to resolve appstack ID for '${resolvedAppstackName}' after blank create`,\n );\n }\n if (!resolvedTopologyId) {\n resolvedTopologyId = resolvedAppstackId;\n }\n\n const resourcePackResources = collectResourcePackResources(\n sanitizedResources,\n );\n if (resourcePackResources.length === 0 && hasResourcePackInput) {\n throw new Error(\n \"resource pack flow was selected but no resourcePackId was found after normalization\",\n );\n }\n\n const orgScope =\n config.getOptionalString(\"stackGen.orgId\")?.trim() || appstack.teamId;\n\n for (const resource of resourcePackResources) {\n const createResourceUrl = `${cleanBaseUrl}/iac-gen/v1/topologies/${encodeURIComponent(\n resolvedTopologyId,\n )}/resources${orgScope ? `?orgId=${encodeURIComponent(orgScope)}` : \"\"}`;\n const createResourcePayload = {\n resourceType: resource.resourceType || \"resourcePack\",\n name: resource.name,\n iacType: resource.iacType || \"Terraform\",\n resourcePackId: resource.resourcePackId,\n };\n logger.info(\n `[${traceId}] adding resource pack to topology ${resolvedTopologyId} via ${createResourceUrl}`,\n );\n\n const createResourceResponse = await executeApiRequest(\n () =>\n stackgenApis.v1ResourceApiObj.createResource({\n topologyId: resolvedTopologyId,\n orgId: orgScope || undefined,\n topologyResource: createResourcePayload as never,\n }),\n 201,\n );\n const createResourceText = createResourceResponse.text;\n\n if (!createResourceResponse.ok) {\n throw new Error(\n `Failed to add resource pack to topology: ${formatRequestFailure(createResourceResponse)}`,\n );\n }\n validateExpectedJsonResponse(createResourceText, createResourceUrl);\n }\n\n // Also add non-resource-pack resources (e.g. standalone aws_s3,\n // custom modules with templateId) to the same topology.\n const nonPackResources = sanitizedResources.filter(\n (r: any) => !r.resourcePackId,\n );\n for (const resource of nonPackResources) {\n const addResourceUrl = `${cleanBaseUrl}/iac-gen/v1/topologies/${encodeURIComponent(\n resolvedTopologyId,\n )}/resources${orgScope ? `?orgId=${encodeURIComponent(orgScope)}` : \"\"}`;\n const addResourcePayload: any = {\n resourceType: resource.resourceType,\n name: resource.name,\n iacType: resource.iacType || \"Terraform\",\n };\n if (resource.templateId) {\n addResourcePayload.templateId = resource.templateId;\n }\n if (resource.configuration) {\n addResourcePayload.configuration = resource.configuration;\n }\n logger.info(\n `[${traceId}] adding non-pack resource '${resource.resourceType}' (name=${resource.name}) to topology ${resolvedTopologyId}`,\n );\n\n const addResourceResponse = await executeApiRequest(\n () =>\n stackgenApis.v1ResourceApiObj.createResource({\n topologyId: resolvedTopologyId,\n orgId: orgScope || undefined,\n topologyResource: addResourcePayload as never,\n }),\n 201,\n );\n const addResourceText = addResourceResponse.text;\n\n if (!addResourceResponse.ok) {\n throw new Error(\n `Failed to add resource '${resource.resourceType}' to topology: ${formatRequestFailure(addResourceResponse)}`,\n );\n }\n validateExpectedJsonResponse(addResourceText, addResourceUrl);\n }\n\n ctx.logger.info(\n `[${traceId}] AppStack created successfully via resource pack flow: ${JSON.stringify({\n appstackId: resolvedAppstackId,\n topologyId: resolvedTopologyId,\n appstackName: resolvedAppstackName,\n resourcePackCount: resourcePackResources.length,\n nonPackResourceCount: nonPackResources.length,\n })}`,\n );\n ctx.output(\"appstackId\", resolvedAppstackId);\n ctx.output(\"appstackName\", resolvedAppstackName);\n ctx.output(\"topologyId\", resolvedTopologyId);\n const teamNameForUrl = await resolveTeamNameForUrl(\n stackgenApis,\n appstack.teamId,\n logger,\n traceId,\n );\n ctx.output(\n \"appStackURL\",\n buildAppStackUrl(cleanBaseUrl, resolvedAppstackId, teamNameForUrl),\n );\n return;\n }\n\n // Teams API: cloudProvider + topology with resources\n const apiPayload = {\n name: resolvedAppstackName,\n cloudProvider: effectiveCloudProvider,\n topology: {\n source: { name: \"backstage\" },\n resources: sanitizedResources,\n resourceConnections: [],\n },\n };\n\n const requestUrl = `${cleanBaseUrl}/integrations/api/v1/projects/${encodeURIComponent(appstack.teamId)}/appstacks`;\n logger.info(\n `[${traceId}] sending request to create appStack at ${requestUrl}`,\n );\n logger.info(\n `[${traceId}] appstack request payload summary: ${JSON.stringify({\n name: apiPayload.name,\n cloudProvider: apiPayload.cloudProvider,\n resourceCount: sanitizedResources.length,\n })}`,\n );\n\n const response = await executeApiRequest(\n () =>\n stackgenApis.integrationsAppstackApiObj.createProjectAppStack({\n projectId: appstack.teamId,\n appStackRequest: apiPayload as never,\n }),\n 201,\n );\n\n const responseBody = response.parsed;\n const responseText = response.text;\n ctx.logger.info(`[${traceId}] Response status: ${response.status}`);\n\n if (!response.ok) {\n const errorMessage = formatRequestFailure(response);\n ctx.logger.error(\n `[${traceId}] Error response: ${errorMessage}. Diagnostics: ${JSON.stringify({\n teamId: appstack.teamId,\n appstackName: resolvedAppstackName,\n cloudProvider: effectiveCloudProvider,\n totalResourceCount,\n inputResourcePackIdCount,\n outputResourcePackIdCount,\n iacTypeCount,\n nameCount,\n })}`,\n );\n throw new Error(\n `Failed to create appstack: ${errorMessage}`,\n );\n }\n validateExpectedJsonResponse(responseText, requestUrl);\n\n const createdIds = readIntegrationsAppstackIds(responseBody);\n if (templateUuidForClone) {\n await cloneTopologyFromTemplateAppstack({\n stackgenApis,\n orgId: orgScopeForAppcd,\n newAppstackId: createdIds.appstackId,\n templateAppstackId: templateUuidForClone,\n cloudProvider: effectiveCloudProvider,\n deploymentType: deploymentTypeForTopologyClone,\n iacType: topologyIacTypeForClone,\n traceId,\n logger: ctx.logger,\n });\n }\n ctx.logger.info(\n `[${traceId}] AppStack created successfully: ${JSON.stringify({\n appstackId: createdIds.appstackId,\n topologyId: createdIds.topologyId,\n appstackName: responseBody.appstackName || resolvedAppstackName,\n clonedFromTemplate: Boolean(templateUuidForClone),\n })}`,\n );\n ctx.output(\"appstackId\", createdIds.appstackId);\n ctx.output(\n \"appstackName\",\n responseBody.appstackName || resolvedAppstackName,\n );\n ctx.output(\"topologyId\", createdIds.topologyId);\n const teamNameForUrl = await resolveTeamNameForUrl(\n stackgenApis,\n appstack.teamId,\n logger,\n traceId,\n );\n ctx.output(\n \"appStackURL\",\n buildAppStackUrl(\n cleanBaseUrl,\n createdIds.appstackId,\n teamNameForUrl,\n ),\n );\n } catch (error: any) {\n const errorString = await detailFromThrownError(error);\n\n let errorMessage = `Failed to create appStack: ${errorString}`;\n\n // Only append membership warning if it's NOT an \"already exists\" error\n if (\n membershipPreflightWarning &&\n !errorString.includes(\"already exists. View it here\")\n ) {\n errorMessage += ` (membership preflight warning: ${membershipPreflightWarning})`;\n }\n\n ctx.logger.error(errorMessage);\n throw new Error(errorMessage);\n }\n },\n });\n};\n"],"names":["z","formatApiFailure","formatClientErrorMessage","executeApiRequest","createTemplateAction","getStackgenApiObjects","teamNameForUrl"],"mappings":";;;;;;AAWA,MAAM,gBAAgBA,KAAA,CAAE,IAAA,CAAK,CAAC,MAAA,EAAQ,WAAW,CAAC,CAAA;AAElD,MAAM,sBAAsCA,KAAA,CAAE,IAAA;AAAA,EAAK,MACjDA,MAAE,MAAA,CAAO;AAAA,IACP,YAAA,EAAcA,MAAE,MAAA,EAAO;AAAA,IACvB,IAAA,EAAMA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,IAC1B,OAAA,EAAS,cAAc,QAAA,EAAS;AAAA,IAChC,aAAA,EAAeA,KAAA,CAAE,MAAA,CAAOA,KAAA,CAAE,MAAA,IAAUA,KAAA,CAAE,GAAA,EAAK,CAAA,CAAE,QAAA,EAAS;AAAA,IACtD,MAAA,EAAQA,KAAA,CAAE,MAAA,CAAOA,KAAA,CAAE,MAAA,IAAUA,KAAA,CAAE,MAAA,EAAQ,CAAA,CAAE,QAAA,EAAS;AAAA,IAClD,2BAAA,EAA6BA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,IACjD,cAAA,EAAgBA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,IACpC,UAAA,EAAYA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,IAChC,QAAA,EAAUA,KAAA,CAAE,KAAA,CAAM,mBAAmB,EAAE,QAAA;AAAS,GACjD;AACH,CAAA;AAEA,MAAM,cAAA,GAAiBA,MACpB,MAAA,CAAO;AAAA,EACN,YAAA,EAAcA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EAClC,IAAA,EAAMA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EAC1B,OAAA,EAAS,cAAc,QAAA,EAAS;AAAA,EAChC,2BAAA,EAA6BA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EACjD,aAAA,EAAeA,KAAA,CAAE,MAAA,CAAOA,KAAA,CAAE,MAAA,IAAUA,KAAA,CAAE,GAAA,EAAK,CAAA,CAAE,QAAA,EAAS;AAAA,EACtD,MAAA,EAAQA,KAAA,CAAE,MAAA,CAAOA,KAAA,CAAE,MAAA,IAAUA,KAAA,CAAE,MAAA,EAAQ,CAAA,CAAE,QAAA,EAAS;AAAA,EAClD,cAAA,EAAgBA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EACpC,UAAA,EAAYA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EAChC,QAAA,EAAUA,KAAA,CAAE,KAAA,CAAM,mBAAmB,EAAE,QAAA,EAAS;AAAA;AAAA,EAEhD,EAAA,EAAIA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EACxB,MAAA,EAAQA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EAC5B,KAAA,EAAOA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EAC3B,WAAA,EAAaA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EACjC,UAAA,EAAYA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AACzB,CAAC,CAAA,CACA,WAAA,CAAY,CAAC,GAAA,EAAU,GAAA,KAAa;AACnC,EAAA,MAAM,gBAAA,GAAmB,CAAC,CAAC,GAAA,CAAI,aAAA;AAC/B,EAAA,MAAM,iBAAA,GAAoB,CAAC,CAAC,GAAA,CAAI,cAAA;AAChC,EAAA,MAAM,qBAAA,GACJ,OAAO,GAAA,CAAI,EAAA,KAAO,YAClB,GAAA,CAAI,EAAA,IACJ,CAAC,GAAA,CAAI,YAAA,IACL,CAAC,GAAA,CAAI,UAAA,IACL,CAAC,GAAA,CAAI,cAAA;AAEP,EAAA,IAAI,CAAC,GAAA,CAAI,YAAA,IAAgB,CAAC,qBAAA,EAAuB;AAC/C,IAAA,GAAA,CAAI,QAAA,CAAS;AAAA,MACX,IAAA,EAAMA,MAAE,YAAA,CAAa,MAAA;AAAA,MACrB,OAAA,EACE,iEAAA;AAAA,MACF,IAAA,EAAM,CAAC,cAAc;AAAA,KACtB,CAAA;AAAA,EACH;AAEA,EAAA,IAAI,oBAAoB,iBAAA,EAAmB;AACzC,IAAA,GAAA,CAAI,QAAA,CAAS;AAAA,MACX,IAAA,EAAMA,MAAE,YAAA,CAAa,MAAA;AAAA,MACrB,OAAA,EACE,6FAAA;AAAA,MACF,IAAA,EAAM,CAAC,eAAe;AAAA,KACvB,CAAA;AAAA,EACH;AACF,CAAC,CAAA;AAGH,MAAM,gCAAA,GAAmC,KAAA;AAElC,MAAM,yBAAA,GAA4BA,MAAE,MAAA,CAAO;AAAA,EAChD,QAAA,EAAUA,MAAE,MAAA,CAAO;AAAA,IACjB,MAAMA,KAAA,CAAE,MAAA,EAAO,CAAE,IAAA,GAAO,QAAA,EAAS;AAAA,IACjC,cAAcA,KAAA,CAAE,MAAA,EAAO,CAAE,IAAA,GAAO,QAAA,EAAS;AAAA,IACzC,MAAA,EAAQA,MAAE,MAAA,EAAO,CAAE,MAAK,CAAE,GAAA,CAAI,GAAG,6BAA6B,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAK9D,eAAeA,KAAA,CAAE,MAAA,EAAO,CAAE,IAAA,GAAO,QAAA,EAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAM1C,kBAAA,EAAoBA,MAAE,MAAA,EAAO,CAAE,MAAK,CAAE,IAAA,GAAO,QAAA,EAAS;AAAA,IACtD,WAAWA,KAAA,CAAE,KAAA,CAAM,cAAc,CAAA,CAAE,OAAA,CAAQ,EAAE;AAAA,GAC9C,CAAA,CAAE,WAAA,CAAY,CAAC,UAAe,GAAA,KAAa;AAC1C,IAAA,MAAM,IAAA,GAAO,QAAA,CAAS,IAAA,EAAM,IAAA,EAAK;AACjC,IAAA,MAAM,YAAA,GAAe,QAAA,CAAS,YAAA,EAAc,IAAA,EAAK;AACjD,IAAA,IAAI,CAAC,IAAA,IAAQ,CAAC,YAAA,EAAc;AAC1B,MAAA,GAAA,CAAI,QAAA,CAAS;AAAA,QACX,IAAA,EAAMA,MAAE,YAAA,CAAa,MAAA;AAAA,QACrB,OAAA,EAAS,kDAAA;AAAA,QACT,IAAA,EAAM,CAAC,MAAM;AAAA,OACd,CAAA;AAAA,IACH;AACA,IAAA,MAAM,UAAA,GAAa,QAAA,CAAS,kBAAA,EAAoB,IAAA,EAAK;AACrD,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,aAAA,EAAe,IAAA,EAAK;AAC3C,IAAA,IAAI,CAAC,UAAA,IAAc,CAAC,KAAA,EAAO;AACzB,MAAA,GAAA,CAAI,QAAA,CAAS;AAAA,QACX,IAAA,EAAMA,MAAE,YAAA,CAAa,MAAA;AAAA,QACrB,OAAA,EACE,uEAAA;AAAA,QACF,IAAA,EAAM,CAAC,eAAe;AAAA,OACvB,CAAA;AAAA,IACH;AACA,IAAA,IAAI,UAAA,IAAc,QAAA,CAAS,SAAA,CAAU,MAAA,GAAS,CAAA,EAAG;AAC/C,MAAA,GAAA,CAAI,QAAA,CAAS;AAAA,QACX,IAAA,EAAMA,MAAE,YAAA,CAAa,MAAA;AAAA,QACrB,OAAA,EACE,wIAAA;AAAA,QACF,IAAA,EAAM,CAAC,oBAAoB;AAAA,OAC5B,CAAA;AAAA,IACH;AAAA,EACF,CAAC;AACH,CAAC;AAEM,MAAM,oBAAA,GAAuBA,MAAE,MAAA,CAAO;AAAA,EAC3C,UAAA,EAAYA,MAAE,MAAA,EAAO;AAAA,EACrB,YAAA,EAAcA,MAAE,MAAA,EAAO;AAAA,EACvB,WAAA,EAAaA,MAAE,MAAA,EAAO;AAAA,EACtB,UAAA,EAAYA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AACzB,CAAC;AAMD,SAAS,4BAA4B,IAAA,EAGnC;AACA,EAAA,MAAM,aACH,OAAO,IAAA,EAAM,UAAA,KAAe,QAAA,IAAY,KAAK,UAAA,CAAW,IAAA,EAAK,IAC7D,OAAO,MAAM,EAAA,KAAO,QAAA,IAAY,IAAA,CAAK,EAAA,CAAG,MAAK,IAC9C,EAAA;AACF,EAAA,MAAM,aACH,OAAO,IAAA,EAAM,IAAA,KAAS,QAAA,IAAY,KAAK,IAAA,CAAK,IAAA,EAAK,IACjD,OAAO,MAAM,UAAA,KAAe,QAAA,IAAY,KAAK,UAAA,CAAW,IAAA,MACzD,UAAA,IACA,EAAA;AACF,EAAA,OAAO,EAAE,YAAY,UAAA,EAAW;AAClC;AAEA,MAAM,8BAAA,GAAiC,sCAAA;AAEvC,SAAS,cAAA,CAAe,QAA4B,YAAA,EAAwB;AAC1E,EAAA,IAAI,YAAA,CAAa,WAAW,CAAA,EAAG;AAC/B,EAAA,IAAI,MAAA,IAAU,CAAC,YAAA,CAAa,QAAA,CAAS,MAAM,CAAA,EAAG;AAC5C,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,QAAA,EAAW,MAAM,CAAA,gBAAA,CAAkB,CAAA;AAAA,EACrD;AACF;AAEA,SAAS,aAAA,CAAc,WAAkB,KAAA,EAAsC;AAC7E,EAAA,KAAA,MAAW,YAAY,SAAA,EAAW;AAChC,IAAA,KAAA,CAAM,QAAQ,CAAA;AACd,IAAA,IAAI,KAAA,CAAM,QAAQ,QAAA,EAAU,QAAQ,KAAK,QAAA,CAAS,QAAA,CAAS,SAAS,CAAA,EAAG;AACrE,MAAA,aAAA,CAAc,QAAA,CAAS,UAAU,KAAK,CAAA;AAAA,IACxC;AAAA,EACF;AACF;AAEA,SAAS,UAAA,CAAW,WAAkB,KAAA,EAAuB;AAC3D,EAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,EAAA,aAAA,CAAc,WAAW,CAAA,QAAA,KAAY;AACnC,IAAA,IAAI,QAAA,IAAY,QAAA,CAAS,KAAK,CAAA,KAAM,MAAA,EAAW;AAC7C,MAAA,KAAA,IAAS,CAAA;AAAA,IACX;AAAA,EACF,CAAC,CAAA;AACD,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,eAAe,SAAA,EAA0B;AAChD,EAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,EAAA,aAAA,CAAc,WAAW,MAAM;AAC7B,IAAA,KAAA,IAAS,CAAA;AAAA,EACX,CAAC,CAAA;AACD,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,aAAa,YAAA,EAA4C;AAChE,EAAA,OAAO,aAAa,WAAA,EAAY,CAAE,QAAA,CAAS,MAAM,IAAI,MAAA,GAAS,WAAA;AAChE;AAGA,SAAS,2BAA2B,KAAA,EAAuB;AACzD,EAAA,MAAM,OAAA,GAAU,CAAC,EAAA,KAAe,EAAA,CAAG,MAAK,KAAM,EAAA;AAC9C,EAAA,IAAI,MAAM,KAAA,CAAM,MAAA;AAChB,EAAA,OAAO,GAAA,GAAM,KAAK,OAAA,CAAQ,KAAA,CAAM,OAAO,GAAA,GAAM,CAAC,CAAC,CAAA,EAAG;AAChD,IAAA,GAAA,IAAO,CAAA;AAAA,EACT;AACA,EAAA,IAAI,QAAQ,CAAA,IAAK,KAAA,CAAM,OAAO,GAAA,GAAM,CAAC,MAAM,GAAA,EAAK;AAC9C,IAAA,OAAO,MAAM,IAAA,EAAK;AAAA,EACpB;AACA,EAAA,MAAM,QAAQ,GAAA,GAAM,CAAA;AACpB,EAAA,MAAM,IAAA,GAAO,KAAA,CAAM,WAAA,CAAY,GAAA,EAAK,KAAK,CAAA;AACzC,EAAA,IAAI,IAAA,GAAO,CAAA,IAAK,KAAA,CAAM,KAAA,CAAM,IAAA,GAAO,GAAG,KAAK,CAAA,CAAE,QAAA,CAAS,GAAG,CAAA,EAAG;AAC1D,IAAA,OAAO,MAAM,IAAA,EAAK;AAAA,EACpB;AACA,EAAA,IAAI,KAAA,GAAQ,IAAA;AACZ,EAAA,OAAO,KAAA,GAAQ,KAAK,OAAA,CAAQ,KAAA,CAAM,OAAO,KAAA,GAAQ,CAAC,CAAC,CAAA,EAAG;AACpD,IAAA,KAAA,IAAS,CAAA;AAAA,EACX;AACA,EAAA,OAAO,CAAA,EAAG,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,KAAK,CAAC,CAAA,EAAG,KAAA,CAAM,KAAA,CAAM,GAAG,CAAC,CAAA,CAAA,CAAG,IAAA,EAAK;AAC5D;AAEA,SAAS,gBAAA,CACP,SACA,YAAA,EACsB;AACtB,EAAA,IAAI,OAAO,YAAY,QAAA,EAAU;AAC/B,IAAA,MAAM,UAAA,GAAa,OAAA,CAAQ,IAAA,EAAK,CAAE,WAAA,EAAY;AAC9C,IAAA,IAAI,UAAA,KAAe,QAAQ,OAAO,MAAA;AAClC,IAAA,IAAI,UAAA,KAAe,aAAa,OAAO,WAAA;AAAA,EACzC;AACA,EAAA,OAAO,aAAa,YAAY,CAAA;AAClC;AAEA,SAAS,mBAAA,CAAoB,UAAe,IAAA,EAAsB;AAChE,EAAA,MAAM,YAAA,GACJ,OAAO,QAAA,EAAU,IAAA,KAAS,WAAW,QAAA,CAAS,IAAA,CAAK,MAAK,GAAI,EAAA;AAC9D,EAAA,IAAI,cAAc,OAAO,YAAA;AAEzB,EAAA,MAAM,UAAA,GACJ,OAAO,QAAA,EAAU,aAAA,EAAe,IAAA,KAAS,WACrC,QAAA,CAAS,aAAA,CAAc,IAAA,CAAK,IAAA,EAAK,GACjC,EAAA;AACN,EAAA,IAAI,YAAY,OAAO,UAAA;AAEvB,EAAA,OAAO,CAAA,EAAG,QAAA,CAAS,YAAY,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA;AACzC;AAIA,SAAS,wBAAA,CAAyB,SAAA,EAAkB,UAAA,GAAa,EAAA,EAAW;AAC1E,EAAA,OAAO,SAAA,CAAU,GAAA,CAAI,CAAC,GAAA,EAAK,KAAA,KAAU;AACnC,IAAA,MAAM,YAAA,GAAe,aAAa,CAAA,EAAG,UAAU,IAAI,KAAK,CAAA,CAAA,GAAK,GAAG,KAAK,CAAA,CAAA;AACrE,IAAA,MAAM,wBACJ,GAAA,IACA,OAAO,QAAQ,QAAA,IACf,OAAO,IAAI,EAAA,KAAO,QAAA,IAClB,GAAA,CAAI,EAAA,IACJ,CAAC,GAAA,CAAI,YAAA,IACL,CAAC,GAAA,CAAI,UAAA,IACL,CAAC,GAAA,CAAI,cAAA;AAEP,IAAA,MAAM,SAAS,qBAAA,GACX;AAAA,MACE,YAAA,EAAc,mBAAA;AAAA,MACd,OAAA,EAAS,WAAA;AAAA,MACT,YAAY,GAAA,CAAI,EAAA;AAAA,MAChB,IAAA,EACE,OAAO,GAAA,CAAI,KAAA,KAAU,YAAY,GAAA,CAAI,KAAA,CAAM,IAAA,EAAK,GAC5C,2BAA2B,GAAA,CAAI,KAAK,CAAA,GACpC,GAAA,CAAI,cAAc,GAAA,CAAI;AAAA,KAC9B,GACA,GAAA;AAEJ,IAAA,MAAM,EAAE,QAAA,EAAU,GAAG,IAAA,EAAK,GAAI,MAAA;AAC9B,IAAA,MAAM,UAAA,GAAkB;AAAA,MACtB,GAAG,IAAA;AAAA,MACH,OAAA,EAAS,gBAAA,CAAiB,IAAA,CAAK,OAAA,EAAS,KAAK,YAAY,CAAA;AAAA,MACzD,IAAA,EAAM,mBAAA,CAAoB,IAAA,EAAM,YAAY;AAAA,KAC9C;AAEA,IAAA,IAAI,MAAM,OAAA,CAAQ,QAAQ,CAAA,IAAK,QAAA,CAAS,SAAS,CAAA,EAAG;AAClD,MAAA,UAAA,CAAW,QAAA,GAAW,wBAAA,CAAyB,QAAA,EAAU,YAAY,CAAA;AAAA,IACvE;AAEA,IAAA,OAAO,UAAA;AAAA,EACT,CAAC,CAAA;AACH;AAEA,SAAS,4BAAA,CACP,cACA,QAAA,EACM;AACN,EAAA,MAAM,OAAA,GAAU,aAAa,IAAA,EAAK;AAClC,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,OAAA,GAAU,QAAQ,WAAA,EAAY;AACpC,EAAA,IACE,OAAA,KAAY,YACZ,OAAA,CAAQ,UAAA,CAAW,gBAAgB,CAAA,IACnC,OAAA,CAAQ,UAAA,CAAW,OAAO,CAAA,EAC1B;AACA,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,gCAAgC,QAAQ,CAAA,sDAAA;AAAA,KAC1C;AAAA,EACF;AAEA,EAAA,IAAI,EAAE,QAAQ,UAAA,CAAW,GAAG,KAAK,OAAA,CAAQ,UAAA,CAAW,GAAG,CAAA,CAAA,EAAI;AACzD,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,6CAA6C,QAAQ,CAAA,EAAA,EAAK,QAAQ,KAAA,CAAM,CAAA,EAAG,GAAG,CAAC,CAAA;AAAA,KACjF;AAAA,EACF;AACF;AAEA,SAAS,qBAAqB,GAAA,EAKnB;AACT,EAAA,OAAOC,2BAAA,CAAiB,IAAI,MAAA,EAAQ,GAAA,CAAI,QAAQ,GAAA,CAAI,IAAA,EAAM,IAAI,SAAS,CAAA;AACzE;AAGA,eAAe,sBAAsB,KAAA,EAAiC;AACpE,EAAA,IAAK,OAAkC,QAAA,EAAU;AAC/C,IAAA,OAAOC,oCAAyB,KAAK,CAAA;AAAA,EACvC;AACA,EAAA,IAAI,iBAAiB,KAAA,EAAO;AAC1B,IAAA,OAAO,KAAA,CAAM,OAAA;AAAA,EACf;AACA,EAAA,OAAO,OAAO,KAAK,CAAA;AACrB;AAEA,eAAe,kCAAkC,MAAA,EAU/B;AAChB,EAAA,MAAM;AAAA,IACJ,YAAA;AAAA,IACA,KAAA;AAAA,IACA,aAAA;AAAA,IACA,kBAAA;AAAA,IACA,aAAA;AAAA,IACA,cAAA;AAAA,IACA,OAAA;AAAA,IACA,OAAA;AAAA,IACA;AAAA,GACF,GAAI,MAAA;AACJ,EAAA,MAAM,IAAA,GAAO;AAAA,IACX,UAAA,EAAY,aAAA;AAAA,IACZ,aAAA,EAAe,kBAAA;AAAA,IACf,aAAA;AAAA,IACA,cAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,MAAA,CAAO,IAAA;AAAA,IACL,CAAA,CAAA,EAAI,OAAO,CAAA,0CAAA,EAA6C,kBAAkB,SAAS,aAAa,CAAA;AAAA,GAClG;AACA,EAAA,MAAM,MAAM,MAAMC,4BAAA;AAAA,IAChB,MACE,YAAA,CAAa,gBAAA,CAAiB,cAAA,CAAe;AAAA,MAC3C,KAAA;AAAA,MACA,kBAAA,EAAoB;AAAA,KACrB,CAAA;AAAA,IACH;AAAA,GACF;AACA,EAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,iDAAA,EAAoD,oBAAA,CAAqB,GAAG,CAAC,CAAA;AAAA,KAC/E;AAAA,EACF;AACA,EAAA,4BAAA;AAAA,IACE,GAAA,CAAI,IAAA;AAAA,IACJ;AAAA,GACF;AACF;AAiBA,SAAS,iCACP,SAAA,EACkC;AAClC,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,SAAS,CAAA,EAAG;AAC7B,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,KAAA,MAAW,SAAS,SAAA,EAAW;AAC7B,IAAA,IAAI,KAAA,KAAU,MAAA,IAAU,KAAA,KAAU,WAAA,EAAa;AAC7C,MAAA,OAAO,KAAA;AAAA,IACT;AACA,IAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,MAAA,MAAM,CAAA,GAAI,MAAM,IAAA,EAAK;AACrB,MAAA,IAAI,CAAA,KAAM,MAAA,IAAU,CAAA,KAAM,WAAA,EAAa;AACrC,QAAA,OAAO,CAAA;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACA,EAAA,OAAO,MAAA;AACT;AAMA,eAAe,6BAA6B,MAAA,EAKK;AAC/C,EAAA,MAAM,EAAE,YAAA,EAAc,YAAA,EAAc,OAAA,EAAS,QAAO,GAAI,MAAA;AACxD,EAAA,MAAM,QAAA,GAAW,GAAA;AACjB,EAAA,IAAI,MAAA,GAAS,CAAA;AAEb,EAAA,WAAS;AACP,IAAA,MAAA,CAAO,IAAA;AAAA,MACL,CAAA,CAAA,EAAI,OAAO,CAAA,8BAAA,EAAiC,YAAY,CAAA,0BAAA;AAAA,KAC1D;AACA,IAAA,MAAM,UAAA,GAAa,MAAA;AACnB,IAAA,MAAM,MAAM,MAAMA,4BAAA;AAAA,MAAkB,MAClC,YAAA,CAAa,eAAA,CAAgB,oBAAA,CAAqB;AAAA,QAChD,KAAA,EAAO,QAAA;AAAA,QACP,MAAA,EAAQ;AAAA,OACT;AAAA,KACH;AACA,IAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,8CAAA,EAAiD,oBAAA,CAAqB,GAAG,CAAC,CAAA;AAAA,OAC5E;AAAA,IACF;AACA,IAAA,4BAAA,CAA6B,GAAA,CAAI,MAAM,sCAAsC,CAAA;AAE7E,IAAA,MAAM,IAAA,GAAO,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,MAAA,EAAQ,SAAS,CAAA,GAAI,GAAA,CAAI,MAAA,CAAO,SAAA,GAAY,EAAC;AAC5E,IAAA,MAAM,QAAQ,IAAA,CAAK,IAAA;AAAA,MACjB,CAAC,QACC,MAAA,CAAO,GAAA,EAAK,cAAc,EAAE,CAAA,CAAE,MAAK,KAAM;AAAA,KAC7C;AACA,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,MAAM,aAAA,GACJ,OAAO,KAAA,CAAM,aAAA,KAAkB,WAC3B,KAAA,CAAM,aAAA,CAAc,MAAK,GACzB,MAAA;AACN,MAAA,MAAM,KAAA,GACJ,OAAO,KAAA,CAAM,KAAA,KAAU,WAAW,KAAA,CAAM,KAAA,CAAM,MAAK,GAAI,MAAA;AACzD,MAAA,MAAM,IAAA,GAAO,OAAO,KAAA,CAAM,IAAA,KAAS,WAAW,KAAA,CAAM,IAAA,CAAK,MAAK,GAAI,MAAA;AAClE,MAAA,OAAO;AAAA,QACL,UAAA,EAAY,YAAA;AAAA,QACZ,OAAO,KAAA,IAAS,MAAA;AAAA,QAChB,eAAe,aAAA,IAAiB,MAAA;AAAA,QAChC,MAAM,IAAA,IAAQ;AAAA,OAChB;AAAA,IACF;AAEA,IAAA,IAAI,IAAA,CAAK,SAAS,QAAA,EAAU;AAC1B,MAAA,OAAO,MAAA;AAAA,IACT;AACA,IAAA,MAAA,IAAU,QAAA;AACV,IAAA,IAAI,SAAS,GAAA,EAAQ;AACnB,MAAA,MAAA,CAAO,IAAA;AAAA,QACL,CAAA,CAAA,EAAI,OAAO,CAAA,iDAAA,EAAoD,MAAM,oBAAoB,YAAY,CAAA;AAAA,OACvG;AACA,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,EACF;AACF;AAOA,eAAe,sCAAsC,MAAA,EAMH;AAChD,EAAA,MAAM;AAAA,IACJ,YAAA;AAAA,IACA,KAAA;AAAA,IACA,YAAA;AAAA,IACA,OAAA;AAAA,IACA;AAAA,GACF,GAAI,MAAA;AACJ,EAAA,MAAA,CAAO,IAAA;AAAA,IACL,IAAI,OAAO,CAAA,8CAAA;AAAA,GACb;AACA,EAAA,MAAM,MAAM,MAAMA,4BAAA;AAAA,IAAkB,MAClC,YAAA,CAAa,eAAA,CAAgB,WAAA,CAAY;AAAA,MACvC,IAAA,EAAM,YAAA;AAAA,MACN;AAAA,KACD;AAAA,GACH;AACA,EAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,IAAA,MAAA,CAAO,IAAA;AAAA,MACL,IAAI,OAAO,CAAA,0BAAA,EAA6B,YAAY,CAAA,gBAAA,EAAmB,oBAAA,CAAqB,GAAG,CAAC,CAAA,qDAAA;AAAA,KAClG;AACA,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,4BAAA,CAA6B,GAAA,CAAI,MAAM,6BAA6B,CAAA;AACpE,EAAA,MAAM,EAAA,GAAK,IAAI,MAAA,EAAQ,UAAA;AACvB,EAAA,OAAO;AAAA,IACL,QAAA,EAAU,OAAO,EAAA,EAAI,QAAA,KAAa,WAAW,EAAA,CAAG,QAAA,CAAS,MAAK,GAAI,MAAA;AAAA,IAClE,aAAA,EACE,OAAO,EAAA,EAAI,aAAA,KAAkB,WAAW,EAAA,CAAG,aAAA,CAAc,MAAK,GAAI,MAAA;AAAA,IACpE,WAAW,EAAA,EAAI;AAAA,GACjB;AACF;AAEA,SAAS,uBAAA,CACP,MAAA,EACA,UAAA,EACA,YAAA,EACS;AACT,EAAA,MAAM,UAAU,CAAA,EAAG,UAAA,EAAY,GAAA,IAAO,EAAE,IAAI,UAAA,EAAY,OAAA,IAAW,EAAE,CAAA,CAAA,EAAI,YAAY,KAAA,IAAS,EAAE,IAAI,YAAA,IAAgB,EAAE,GACnH,WAAA,EAAY;AACf,EAAA,IAAI,MAAA,KAAW,QAAQ,OAAA,CAAQ,QAAA,CAAS,SAAS,CAAA,IAAK,OAAA,CAAQ,QAAA,CAAS,QAAQ,CAAA,CAAA,EAAI;AACjF,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,OAAO,QAAQ,QAAA,CAAS,gBAAgB,CAAA,IAAK,OAAA,CAAQ,SAAS,gBAAgB,CAAA;AAChF;AAEA,eAAe,yCAAyC,MAAA,EAMC;AACvD,EAAA,MAAM,EAAE,YAAA,EAAc,SAAA,EAAW,MAAA,EAAQ,OAAA,EAAS,QAAO,GAAI,MAAA;AAC7D,EAAA,MAAA,CAAO,IAAA,CAAK,CAAA,CAAA,EAAI,OAAO,CAAA,mCAAA,CAAqC,CAAA;AAE5D,EAAA,MAAM,aAAa,MAAMA,4BAAA;AAAA,IACvB,MAAM,YAAA,CAAa,uBAAA,CAAwB,KAAA;AAAM,GACnD;AAEA,EAAA,IAAI,CAAC,WAAW,EAAA,EAAI;AAClB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,uCAAA,EAA0C,oBAAA,CAAqB,UAAU,CAAC,CAAA;AAAA,KAC5E;AAAA,EACF;AACA,EAAA,4BAAA,CAA6B,UAAA,CAAW,MAAM,+BAA+B,CAAA;AAE7E,EAAA,MAAM,SAAS,MAAA,CAAO,UAAA,CAAW,QAAQ,MAAA,IAAU,EAAE,EAAE,IAAA,EAAK;AAC5D,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,MAAM,cAAA,GAAiB;AAAA,IACrB,eAAA,EAAiB,CAAC,EAAE,MAAA,EAAQ,QAAQ;AAAA,GACtC;AACA,EAAA,MAAA,CAAO,IAAA;AAAA,IACL,IAAI,OAAO,CAAA,qBAAA,EAAwB,MAAM,CAAA,YAAA,EAAe,SAAS,cAAc,MAAM,CAAA;AAAA,GACvF;AAEA,EAAA,MAAM,kBAAkB,MAAMA,4BAAA;AAAA,IAC5B,MACE,YAAA,CAAa,gBAAA,CAAiB,gBAAA,CAAiB;AAAA,MAC7C,KAAA,EAAO,SAAA;AAAA,MACP,uBAAA,EAAyB;AAAA,KAC1B,CAAA;AAAA,IACH;AAAA,GACF;AAEA,EAAA,IAAI,CAAC,gBAAgB,EAAA,EAAI;AACvB,IAAA,IACE,uBAAA;AAAA,MACE,eAAA,CAAgB,MAAA;AAAA,MAChB,eAAA,CAAgB,MAAA;AAAA,MAChB,eAAA,CAAgB;AAAA,KAClB,EACA;AACA,MAAA,MAAA,CAAO,IAAA;AAAA,QACL,CAAA,CAAA,EAAI,OAAO,CAAA,WAAA,EAAc,MAAM,mCAAmC,SAAS,CAAA,YAAA;AAAA,OAC7E;AACA,MAAA,OAAO;AAAA,QACL,MAAA;AAAA,QACA,cAAA,EAAgB;AAAA,OAClB;AAAA,IACF;AACA,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,+DAAA,EAAkE,oBAAA,CAAqB,eAAe,CAAC,CAAA;AAAA,KACzG;AAAA,EACF;AACA,EAAA,4BAAA;AAAA,IACE,eAAA,CAAgB,IAAA;AAAA,IAChB;AAAA,GACF;AACA,EAAA,OAAO;AAAA,IACL,MAAA;AAAA,IACA,cAAA,EAAgB;AAAA,GAClB;AACF;AAEA,SAAS,6BAA6B,SAAA,EAAyB;AAC7D,EAAA,MAAM,YAAmB,EAAC;AAC1B,EAAA,aAAA,CAAc,WAAW,CAAA,QAAA,KAAY;AACnC,IAAA,IAAI,UAAU,cAAA,EAAgB;AAC5B,MAAA,SAAA,CAAU,KAAK,QAAQ,CAAA;AAAA,IACzB;AAAA,EACF,CAAC,CAAA;AACD,EAAA,OAAO,SAAA;AACT;AAEA,SAAS,gBAAA,CACP,OAAA,EACA,UAAA,EACA,WAAA,EACQ;AACR,EAAA,MAAM,YAAA,GAAe,QAAQ,QAAA,CAAS,GAAG,IAAI,OAAA,CAAQ,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,GAAI,OAAA;AACpE,EAAA,IAAI,CAAC,UAAA,EAAY;AACf,IAAA,OAAO,GAAG,YAAY,CAAA,UAAA,CAAA;AAAA,EACxB;AACA,EAAA,IAAI,WAAA,EAAa;AACf,IAAA,OAAO,CAAA,EAAG,YAAY,CAAA,SAAA,EAAY,kBAAA;AAAA,MAChC;AAAA,KACD,CAAA,WAAA,EAAc,kBAAA,CAAmB,UAAU,CAAC,CAAA,eAAA,CAAA;AAAA,EAC/C;AACA,EAAA,OAAO,CAAA,EAAG,YAAY,CAAA,WAAA,EAAc,kBAAA,CAAmB,UAAU,CAAC,CAAA,CAAA;AACpE;AAEA,eAAe,qBAAA,CACb,YAAA,EACA,MAAA,EACA,MAAA,EACA,OAAA,EAC6B;AAC7B,EAAA,IAAI;AACF,IAAA,MAAM,WAAW,MAAMA,4BAAA;AAAA,MAAkB,MACvC,YAAA,CAAa,sBAAA,CAAuB,UAAU,EAAE,UAAA,EAAY,MAAM;AAAA,KACpE;AAEA,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAA,CAAO,IAAA;AAAA,QACL,CAAA,CAAA,EAAI,OAAO,CAAA,uDAAA,EAA0D,QAAA,CAAS,MAAM,CAAA,CAAA;AAAA,OACtF;AACA,MAAA,OAAO,KAAA,CAAA;AAAA,IACT;AAEA,IAAA,4BAAA,CAA6B,QAAA,CAAS,MAAM,kCAAkC,CAAA;AAC9E,IAAA,IAAI,QAAe,EAAC;AACpB,IAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,QAAA,CAAS,MAAM,CAAA,EAAG;AAClC,MAAA,KAAA,GAAQ,QAAA,CAAS,MAAA;AAAA,IACnB,WAAW,KAAA,CAAM,OAAA,CAAQ,QAAA,CAAS,MAAA,EAAQ,KAAK,CAAA,EAAG;AAChD,MAAA,KAAA,GAAQ,SAAS,MAAA,CAAO,KAAA;AAAA,IAC1B;AACA,IAAA,MAAM,cAAc,KAAA,CAAM,IAAA;AAAA,MACxB,CAAC,UAAe,IAAA,EAAM,EAAA,IAAM,MAAM,MAAA,IAAU,EAAA,EAAI,MAAK,KAAM;AAAA,KAC7D;AACA,IAAA,IAAI,QAAA;AACJ,IAAA,IAAI,WAAA,EAAa;AACf,MAAA,QAAA,GACE,WAAA,EAAa,IAAA,EAAM,IAAA,EAAK,IACxB,WAAA,EAAa,UAAU,IAAA,EAAK,IAC5B,WAAA,EAAa,WAAA,EAAa,IAAA,EAAK;AAAA,IACnC;AACA,IAAA,OAAO,QAAA,IAAY,KAAA,CAAA;AAAA,EACrB,SAAS,KAAA,EAAO;AACd,IAAA,MAAA,CAAO,IAAA;AAAA,MACL,IAAI,OAAO,CAAA,gDAAA,EAAmD,MAAM,qBAAA,CAAsB,KAAK,CAAC,CAAA;AAAA,KAClG;AACA,IAAA,OAAO,MAAA;AAAA,EACT;AACF;AAEO,MAAM,oBAAA,GAAuB,CAAC,MAAA,EAAgB,MAAA,KAA0B;AAC7E,EAAA,OAAOC,yCAAA,CAAqB;AAAA,IAC1B,EAAA,EAAI,yBAAA;AAAA,IACJ,WAAA,EACE,gEAAA;AAAA,IACF,MAAA,EAAQ;AAAA;AAAA;AAAA,MAGN,OAAO,MAAM,yBAAA;AAAA,MACb,QAAQ,MAAM;AAAA,KAChB;AAAA,IAEA,MAAM,QAAQ,GAAA,EAAU;AACtB,MAAA,IAAI,0BAAA;AACJ,MAAA,MAAM,OAAA,GAAU,CAAA,gBAAA,EAAmB,IAAA,CAAK,GAAA,EAAK,CAAA,CAAA;AAC7C,MAAA,IAAI;AACF,QAAA,MAAM,YAAA,GACJ,MAAA,CACG,iBAAA,CAAkB,uBAAuB,GACxC,KAAA,CAAM,GAAG,CAAA,CACV,GAAA,CAAI,CAAC,EAAA,KAAe,EAAA,CAAG,IAAA,EAAM,KAAK,EAAC;AAExC,QAAA,cAAA,CAAe,GAAA,CAAI,KAAA,CAAM,QAAA,CAAS,MAAA,EAAQ,YAAY,CAAA;AAEtD,QAAA,MAAM,YAAA,GAAeC,iCAAsB,MAAM,CAAA;AACjD,QAAA,MAAM,EAAE,QAAA,EAAS,GAAI,GAAA,CAAI,KAAA;AACzB,QAAA,MAAM,oBAAA,GACJ,SAAS,IAAA,EAAM,IAAA,MAAU,QAAA,CAAS,YAAA,EAAc,MAAK,IAAK,EAAA;AAC5D,QAAA,MAAM,iBAAA,GAAoB,QAAA,CAAS,SAAA,IAAa,EAAC;AACjD,QAAA,MAAM,sBACJ,MAAA,CAAO,iBAAA,CAAkB,8BAA8B,CAAA,EAAG,MAAK,IAC/D,8BAAA;AAEF,QAAA,IAAI,CAAC,oBAAA,EAAsB;AACzB,UAAA,GAAA,CAAI,MAAA,CAAO,KAAA;AAAA,YACT,IAAI,OAAO,CAAA,8DAAA;AAAA,WACb;AACA,UAAA,MAAM,IAAI,MAAM,+CAA+C,CAAA;AAAA,QACjE;AAEA,QAAA,MAAM,eAAe,YAAA,CAAa,OAAA;AAClC,QAAA,MAAM,kBAAA,GAAqB,yBAAyB,iBAAiB,CAAA;AACrE,QAAA,MAAM,wBAAA,GAA2B,UAAA,CAAW,iBAAA,EAAmB,gBAAgB,CAAA;AAC/E,QAAA,MAAM,yBAAA,GAA4B,UAAA,CAAW,kBAAA,EAAoB,gBAAgB,CAAA;AACjF,QAAA,MAAM,YAAA,GAAe,UAAA,CAAW,kBAAA,EAAoB,SAAS,CAAA;AAC7D,QAAA,MAAM,SAAA,GAAY,UAAA,CAAW,kBAAA,EAAoB,MAAM,CAAA;AACvD,QAAA,MAAM,eAAA,GAAkB,UAAA,CAAW,kBAAA,EAAoB,YAAY,CAAA;AACnE,QAAA,MAAM,kBAAA,GAAqB,eAAe,kBAAkB,CAAA;AAE5D,QAAA,MAAM,oBAAA,GAAuB,QAAA,CAAS,kBAAA,EAAoB,IAAA,EAAK;AAC/D,QAAA,MAAM,mBACJ,MAAA,CAAO,iBAAA,CAAkB,gBAAgB,CAAA,EAAG,IAAA,MAC5C,QAAA,CAAS,MAAA;AAEX,QAAA,IAAI,eAAA;AACJ,QAAA,IAAI,gBAAA;AACJ,QAAA,IAAI,oBAAA,EAAsB;AACxB,UAAA,eAAA,GAAkB,MAAM,4BAAA,CAA6B;AAAA,YACnD,YAAA;AAAA,YACA,YAAA,EAAc,oBAAA;AAAA,YACd,OAAA;AAAA,YACA,QAAQ,GAAA,CAAI;AAAA,WACb,CAAA;AACD,UAAA,IAAI,CAAC,eAAA,EAAiB;AACpB,YAAA,GAAA,CAAI,MAAA,CAAO,IAAA;AAAA,cACT,CAAA,CAAA,EAAI,OAAO,CAAA,oBAAA,EAAuB,oBAAoB,CAAA,0FAAA;AAAA,aACxD;AAAA,UACF;AAEA,UAAA,MAAM,mBAAA,GACJ,iBAAiB,KAAA,IAAS,gBAAA;AAC5B,UAAA,gBAAA,GAAmB,MAAM,qCAAA,CAAsC;AAAA,YAC7D,YAAA;AAAA,YACA,KAAA,EAAO,mBAAA;AAAA,YACP,YAAA,EAAc,oBAAA;AAAA,YACd,OAAA;AAAA,YACA,QAAQ,GAAA,CAAI;AAAA,WACb,CAAA;AAAA,QACH;AAEA,QAAA,MAAM,sBAAA,GAAA,CACJ,QAAA,CAAS,aAAA,EAAe,IAAA,EAAK,IAC7B,kBAAkB,QAAA,IAClB,eAAA,EAAiB,aAAA,IACjB,EAAA,EACA,IAAA,EAAK;AACP,QAAA,IAAI,CAAC,sBAAA,EAAwB;AAC3B,UAAA,MAAM,IAAI,KAAA;AAAA,YACR,oBAAA,GACI,CAAA,wDAAA,EAA2D,oBAAoB,CAAA,mHAAA,CAAA,GAC/E;AAAA,WACN;AAAA,QACF;AAEA,QAAA,MAAM,8BAAA,GACJ,gBAAA,EAAkB,aAAA,EAAe,IAAA,EAAK,IACtC,gCAAA;AAEF,QAAA,MAAM,uBAAA,GACJ,gCAAA,CAAiC,gBAAA,EAAkB,SAAS,CAAA,IAC5D,WAAA;AAEF,QAAA,GAAA,CAAI,MAAA,CAAO,IAAA;AAAA,UACT,CAAA,CAAA,EAAI,OAAO,CAAA,gCAAA,EAAmC,IAAA,CAAK,SAAA,CAAU;AAAA,YAC3D,QAAQ,QAAA,CAAS,MAAA;AAAA,YACjB,kBAAA,EAAoB,QAAA,CAAS,aAAA,EAAe,IAAA,EAAK,IAAK,KAAA,CAAA;AAAA,YACtD,sBAAA;AAAA,YACA,oBAAA;AAAA,YACA,kBAAA;AAAA,YACA,wBAAA;AAAA,YACA,yBAAA;AAAA,YACA,YAAA;AAAA,YACA,SAAA;AAAA,YACA,oBAAoB,oBAAA,IAAwB,KAAA,CAAA;AAAA,YAC5C,8BAAA;AAAA,YACA,uBAAA;AAAA,YACA,YAAA,EAAc,YAAA;AAAA,YACd,MAAA,EAAQ;AAAA,WACT,CAAC,CAAA;AAAA,SACJ;AAEA,QAAA,IAAI;AACF,UAAA,MAAM,gBAAA,GAAmB,MAAM,wCAAA,CAAyC;AAAA,YACtE,YAAA;AAAA,YACA,WAAW,QAAA,CAAS,MAAA;AAAA,YACpB,MAAA,EAAQ,mBAAA;AAAA,YACR,OAAA;AAAA,YACA;AAAA,WACD,CAAA;AACD,UAAA,IAAI,iBAAiB,cAAA,EAAgB;AACnC,YAAA,MAAA,CAAO,IAAA;AAAA,cACL,IAAI,OAAO,CAAA,WAAA,EAAc,iBAAiB,MAAM,CAAA,2BAAA,EAA8B,SAAS,MAAM,CAAA,qBAAA;AAAA,aAC/F;AAAA,UACF;AACA,UAAA,MAAA,CAAO,IAAA;AAAA,YACL,CAAA,CAAA,EAAI,OAAO,CAAA,gDAAA,EAAmD,QAAA,CAAS,MAAM,CAAA,yBAAA;AAAA,WAC/E;AAAA,QACF,SAAS,eAAA,EAAiB;AACxB,UAAA,0BAAA,GAA6B,OAAO,eAAe,CAAA;AACnD,UAAA,MAAA,CAAO,IAAA;AAAA,YACL,CAAA,CAAA,EAAI,OAAO,CAAA,kEAAA,EAAqE,0BAA0B,CAAA;AAAA,WAC5G;AAAA,QACF;AAEA,QAAA,MAAM,uBAAuB,wBAAA,GAA2B,CAAA;AACxD,QAAA,MAAM,uBAAuB,eAAA,GAAkB,CAAA;AAE/C,QAAA,IAAI,wBAAwB,oBAAA,EAAsB;AAGhD,UAAA,MAAM,cAAA,GAAiB,CAAA,EAAG,YAAY,CAAA,8BAAA,EAAiC,SAAS,MAAM,CAAA,UAAA,CAAA;AACtF,UAAA,MAAM,kBAAA,GAAqB;AAAA,YACzB,IAAA,EAAM,oBAAA;AAAA,YACN,aAAA,EAAe,sBAAA;AAAA,YACf,QAAA,EAAU;AAAA,cACR,MAAA,EAAQ,EAAE,IAAA,EAAM,WAAA,EAAY;AAAA,cAC5B,WAAW,EAAC;AAAA,cACZ,qBAAqB;AAAC;AACxB,WACF;AAEA,UAAA,MAAA,CAAO,IAAA;AAAA,YACL,IAAI,OAAO,CAAA,gDAAA,EAAmD,wBAAwB,CAAA,gBAAA,EAAmB,eAAe,iCAAiC,cAAc,CAAA;AAAA,WACzK;AAEA,UAAA,MAAM,sBAAsB,MAAMF,4BAAA;AAAA,YAChC,MACE,YAAA,CAAa,0BAAA,CAA2B,qBAAA,CAAsB;AAAA,cAC5D,WAAW,QAAA,CAAS,MAAA;AAAA,cACpB,eAAA,EAAiB;AAAA,aAClB,CAAA;AAAA,YACH;AAAA,WACF;AACA,UAAA,MAAM,kBAAkB,mBAAA,CAAoB,MAAA;AAC5C,UAAA,MAAM,kBAAkB,mBAAA,CAAoB,IAAA;AAE5C,UAAA,IAAI,CAAC,oBAAoB,EAAA,EAAI;AAC3B,YAAA,MAAM,YAAA,GAAe,qBAAqB,mBAAmB,CAAA;AAE7D,YAAA,MAAM,mBAAA,GACJ,mBAAA,CAAoB,MAAA,KAAW,GAAA,IAC/B,oBAAoB,MAAA,KAAW,GAAA;AAEjC,YAAA,IAAI,mBAAA,EAAqB;AAEvB,cAAA,IAAI;AACF,gBAAA,MAAM,eAAe,MAAMA,4BAAA;AAAA,kBAAkB,MAC3C,YAAA,CAAa,0BAAA,CAA2B,oBAAA,CAAqB;AAAA,oBAC3D,WAAW,QAAA,CAAS,MAAA;AAAA,oBACpB,IAAA,EAAM;AAAA,mBACP;AAAA,iBACH;AAEA,gBAAA,IAAI,aAAa,EAAA,EAAI;AACnB,kBAAA,MAAM,WAAW,YAAA,CAAa,MAAA;AAC9B,kBAAA,GAAA,CAAI,MAAA,CAAO,KAAK,CAAA,CAAA,EAAI,OAAO,6CAA6C,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAC,CAAA,CAAE,CAAA;AAElG,kBAAA,IAAI,YAAmB,EAAC;AACxB,kBAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,QAAQ,CAAA,EAAG;AAC3B,oBAAA,SAAA,GAAY,QAAA;AAAA,kBACd,CAAA,MAAA,IAAW,KAAA,CAAM,OAAA,CAAQ,QAAA,EAAU,KAAK,CAAA,EAAG;AACzC,oBAAA,SAAA,GAAY,QAAA,CAAS,KAAA;AAAA,kBACvB;AAEA,kBAAA,GAAA,CAAI,OAAO,IAAA,CAAK,CAAA,CAAA,EAAI,OAAO,CAAA,QAAA,EAAW,SAAA,CAAU,MAAM,CAAA,uBAAA,CAAyB,CAAA;AAE/E,kBAAA,MAAM,UAAA,GAAa,SAAA,CAAU,IAAA,CAAK,CAAC,SAAA,KAAmB;AACpD,oBAAA,MAAM,iBACH,SAAA,EAAW,YAAA,IAAgB,SAAA,EAAW,IAAA,IAAQ,IAAI,IAAA,EAAK;AAC1D,oBAAA,MAAM,QAAQ,aAAA,KAAkB,oBAAA;AAChC,oBAAA,IAAI,CAAC,KAAA,EAAO;AACV,sBAAA,GAAA,CAAI,MAAA,CAAO,KAAK,CAAA,CAAA,EAAI,OAAO,gBAAgB,aAAa,CAAA,MAAA,EAAS,oBAAoB,CAAA,CAAA,CAAG,CAAA;AAAA,oBAC1F;AACA,oBAAA,OAAO,KAAA;AAAA,kBACT,CAAC,CAAA;AAED,kBAAA,IAAI,UAAA,EAAY;AACd,oBAAA,GAAA,CAAI,OAAO,IAAA,CAAK,CAAA,CAAA,EAAI,OAAO,CAAA,2CAAA,EAA8C,UAAA,CAAW,UAAU,CAAA,CAAE,CAAA;AAChG,oBAAA,MAAM,kBAAA,GACJ,UAAA,CAAW,UAAA,IAAc,UAAA,CAAW,EAAA;AACtC,oBAAA,MAAMG,kBAAiB,MAAM,qBAAA;AAAA,sBAC3B,YAAA;AAAA,sBACA,QAAA,CAAS,MAAA;AAAA,sBACT,MAAA;AAAA,sBACA;AAAA,qBACF;AACA,oBAAA,MAAM,WAAA,GAAc,gBAAA;AAAA,sBAClB,YAAA;AAAA,sBACA,kBAAA;AAAA,sBACAA;AAAA,qBACF;AACA,oBAAA,MAAM,IAAI,KAAA;AAAA,sBACR,CAAA,UAAA,EAAa,oBAAoB,CAAA,gCAAA,EAAmC,WAAW,CAAA;AAAA,qBACjF;AAAA,kBACF,CAAA,MAAO;AACL,oBAAA,GAAA,CAAI,MAAA,CAAO,KAAK,CAAA,CAAA,EAAI,OAAO,+BAA+B,oBAAoB,CAAA,KAAA,EAAQ,SAAA,CAAU,MAAM,CAAA,MAAA,CAAQ,CAAA;AAAA,kBAChH;AAAA,gBACF,CAAA,MAAO;AACL,kBAAA,GAAA,CAAI,OAAO,IAAA,CAAK,CAAA,CAAA,EAAI,OAAO,CAAA,oCAAA,EAAuC,YAAA,CAAa,MAAM,CAAA,CAAE,CAAA;AAAA,gBACzF;AAAA,cACF,SAAS,YAAA,EAAc;AACrB,gBAAA,MAAM,WAAA,GAAc,OAAO,YAAY,CAAA;AACvC,gBAAA,IAAI,WAAA,CAAY,QAAA,CAAS,8BAA8B,CAAA,EAAG;AACxD,kBAAA,MAAM,YAAA;AAAA,gBACR;AAEA,gBAAA,MAAM,aAAA,GAAgB,MAAM,qBAAA,CAAsB,YAAY,CAAA;AAC9D,gBAAA,GAAA,CAAI,MAAA,CAAO,IAAA;AAAA,kBACT,CAAA,CAAA,EAAI,OAAO,CAAA,yDAAA,EAA4D,aAAa,CAAA;AAAA,iBACtF;AAAA,cACF;AAAA,YACF;AAEA,YAAA,IAAI,cAAA,GAAiB,EAAA;AACrB,YAAA,IACE,mBAAA,CAAoB,MAAA,KAAW,GAAA,IAC/B,MAAA,CAAO,eAAA,EAAiB,WAAW,EAAE,CAAA,CAAE,WAAA,EAAY,KACnD,uBAAA,EACA;AACA,cAAA,MAAM,kBAAkB,MAAM,qBAAA;AAAA,gBAC5B,YAAA;AAAA,gBACA,QAAA,CAAS,MAAA;AAAA,gBACT,MAAA;AAAA,gBACA;AAAA,eACF;AACA,cAAA,IAAI,CAAC,eAAA,EAAiB;AACpB,gBAAA,cAAA,GACE,0IAAA;AAAA,cACJ;AAAA,YACF;AAEA,YAAA,MAAM,IAAI,KAAA;AAAA,cACR,CAAA,iCAAA,EAAoC,YAAY,CAAA,CAAA,EAAI,cAAc,CAAA;AAAA,aACpE;AAAA,UACF,CAAA,MAAO;AACL,YAAA,4BAAA,CAA6B,iBAAiB,cAAc,CAAA;AAAA,UAC9D;AAEA,UAAA,MAAM,SAAA,GAAY,4BAA4B,eAAe,CAAA;AAC7D,UAAA,IAAI,qBAAqB,SAAA,CAAU,UAAA;AACnC,UAAA,IAAI,qBAAqB,SAAA,CAAU,UAAA;AAEnC,UAAA,IAAI,CAAC,kBAAA,EAAoB;AACvB,YAAA,MAAM,UAAU,CAAA,EAAG,YAAY,CAAA,8BAAA,EAAiC,QAAA,CAAS,MAAM,CAAA,gBAAA,EAAmB,kBAAA;AAAA,cAChG;AAAA,aACD,CAAA,CAAA;AACD,YAAA,MAAA,CAAO,IAAA;AAAA,cACL,CAAA,CAAA,EAAI,OAAO,CAAA,oCAAA,EAAuC,OAAO,CAAA;AAAA,aAC3D;AAEA,YAAA,MAAM,eAAe,MAAMH,4BAAA;AAAA,cAAkB,MAC3C,YAAA,CAAa,0BAAA,CAA2B,oBAAA,CAAqB;AAAA,gBAC3D,WAAW,QAAA,CAAS,MAAA;AAAA,gBACpB,IAAA,EAAM;AAAA,eACP;AAAA,aACH;AACA,YAAA,MAAM,WAAW,YAAA,CAAa,MAAA;AAC9B,YAAA,MAAM,WAAW,YAAA,CAAa,IAAA;AAE9B,YAAA,IAAI,CAAC,aAAa,EAAA,EAAI;AACpB,cAAA,MAAM,IAAI,KAAA;AAAA,gBACR,CAAA,+BAAA,EAAkC,oBAAA,CAAqB,YAAY,CAAC,CAAA;AAAA,eACtE;AAAA,YACF;AACA,YAAA,4BAAA,CAA6B,UAAU,OAAO,CAAA;AAE9C,YAAA,IAAI,YAAmB,EAAC;AACxB,YAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,QAAQ,CAAA,EAAG;AAC3B,cAAA,SAAA,GAAY,QAAA;AAAA,YACd,CAAA,MAAA,IAAW,KAAA,CAAM,OAAA,CAAQ,QAAA,EAAU,KAAK,CAAA,EAAG;AACzC,cAAA,SAAA,GAAY,QAAA,CAAS,KAAA;AAAA,YACvB;AACA,YAAA,MAAM,UAAA,GAAa,SAAA,CAAU,IAAA,CAAK,CAAC,SAAA,KAAmB;AACpD,cAAA,MAAM,iBACH,SAAA,EAAW,YAAA,IAAgB,SAAA,EAAW,IAAA,IAAQ,IAAI,IAAA,EAAK;AAC1D,cAAA,OAAO,aAAA,KAAkB,oBAAA;AAAA,YAC3B,CAAC,CAAA;AAED,YAAA,MAAM,QAAA,GAAW,4BAA4B,UAAU,CAAA;AACvD,YAAA,kBAAA,GAAqB,QAAA,CAAS,UAAA;AAC9B,YAAA,kBAAA,GAAqB,SAAS,UAAA,IAAc,kBAAA;AAAA,UAC9C;AAEA,UAAA,IAAI,CAAC,kBAAA,EAAoB;AACvB,YAAA,MAAM,IAAI,KAAA;AAAA,cACR,sCAAsC,oBAAoB,CAAA,oBAAA;AAAA,aAC5D;AAAA,UACF;AACA,UAAA,IAAI,CAAC,kBAAA,EAAoB;AACvB,YAAA,kBAAA,GAAqB,kBAAA;AAAA,UACvB;AAEA,UAAA,MAAM,qBAAA,GAAwB,4BAAA;AAAA,YAC5B;AAAA,WACF;AACA,UAAA,IAAI,qBAAA,CAAsB,MAAA,KAAW,CAAA,IAAK,oBAAA,EAAsB;AAC9D,YAAA,MAAM,IAAI,KAAA;AAAA,cACR;AAAA,aACF;AAAA,UACF;AAEA,UAAA,MAAM,WACJ,MAAA,CAAO,iBAAA,CAAkB,gBAAgB,CAAA,EAAG,IAAA,MAAU,QAAA,CAAS,MAAA;AAEjE,UAAA,KAAA,MAAW,YAAY,qBAAA,EAAuB;AAC5C,YAAA,MAAM,iBAAA,GAAoB,CAAA,EAAG,YAAY,CAAA,uBAAA,EAA0B,kBAAA;AAAA,cACjE;AAAA,aACD,aAAa,QAAA,GAAW,CAAA,OAAA,EAAU,mBAAmB,QAAQ,CAAC,KAAK,EAAE,CAAA,CAAA;AACtE,YAAA,MAAM,qBAAA,GAAwB;AAAA,cAC5B,YAAA,EAAc,SAAS,YAAA,IAAgB,cAAA;AAAA,cACvC,MAAM,QAAA,CAAS,IAAA;AAAA,cACf,OAAA,EAAS,SAAS,OAAA,IAAW,WAAA;AAAA,cAC7B,gBAAgB,QAAA,CAAS;AAAA,aAC3B;AACA,YAAA,MAAA,CAAO,IAAA;AAAA,cACL,CAAA,CAAA,EAAI,OAAO,CAAA,mCAAA,EAAsC,kBAAkB,QAAQ,iBAAiB,CAAA;AAAA,aAC9F;AAEA,YAAA,MAAM,yBAAyB,MAAMA,4BAAA;AAAA,cACnC,MACE,YAAA,CAAa,gBAAA,CAAiB,cAAA,CAAe;AAAA,gBAC3C,UAAA,EAAY,kBAAA;AAAA,gBACZ,OAAO,QAAA,IAAY,KAAA,CAAA;AAAA,gBACnB,gBAAA,EAAkB;AAAA,eACnB,CAAA;AAAA,cACH;AAAA,aACF;AACA,YAAA,MAAM,qBAAqB,sBAAA,CAAuB,IAAA;AAElD,YAAA,IAAI,CAAC,uBAAuB,EAAA,EAAI;AAC9B,cAAA,MAAM,IAAI,KAAA;AAAA,gBACR,CAAA,yCAAA,EAA4C,oBAAA,CAAqB,sBAAsB,CAAC,CAAA;AAAA,eAC1F;AAAA,YACF;AACA,YAAA,4BAAA,CAA6B,oBAAoB,iBAAiB,CAAA;AAAA,UACpE;AAIA,UAAA,MAAM,mBAAmB,kBAAA,CAAmB,MAAA;AAAA,YAC1C,CAAC,CAAA,KAAW,CAAC,CAAA,CAAE;AAAA,WACjB;AACA,UAAA,KAAA,MAAW,YAAY,gBAAA,EAAkB;AACvC,YAAA,MAAM,cAAA,GAAiB,CAAA,EAAG,YAAY,CAAA,uBAAA,EAA0B,kBAAA;AAAA,cAC9D;AAAA,aACD,aAAa,QAAA,GAAW,CAAA,OAAA,EAAU,mBAAmB,QAAQ,CAAC,KAAK,EAAE,CAAA,CAAA;AACtE,YAAA,MAAM,kBAAA,GAA0B;AAAA,cAC9B,cAAc,QAAA,CAAS,YAAA;AAAA,cACvB,MAAM,QAAA,CAAS,IAAA;AAAA,cACf,OAAA,EAAS,SAAS,OAAA,IAAW;AAAA,aAC/B;AACA,YAAA,IAAI,SAAS,UAAA,EAAY;AACvB,cAAA,kBAAA,CAAmB,aAAa,QAAA,CAAS,UAAA;AAAA,YAC3C;AACA,YAAA,IAAI,SAAS,aAAA,EAAe;AAC1B,cAAA,kBAAA,CAAmB,gBAAgB,QAAA,CAAS,aAAA;AAAA,YAC9C;AACA,YAAA,MAAA,CAAO,IAAA;AAAA,cACL,CAAA,CAAA,EAAI,OAAO,CAAA,4BAAA,EAA+B,QAAA,CAAS,YAAY,CAAA,QAAA,EAAW,QAAA,CAAS,IAAI,CAAA,cAAA,EAAiB,kBAAkB,CAAA;AAAA,aAC5H;AAEA,YAAA,MAAM,sBAAsB,MAAMA,4BAAA;AAAA,cAChC,MACE,YAAA,CAAa,gBAAA,CAAiB,cAAA,CAAe;AAAA,gBAC3C,UAAA,EAAY,kBAAA;AAAA,gBACZ,OAAO,QAAA,IAAY,KAAA,CAAA;AAAA,gBACnB,gBAAA,EAAkB;AAAA,eACnB,CAAA;AAAA,cACH;AAAA,aACF;AACA,YAAA,MAAM,kBAAkB,mBAAA,CAAoB,IAAA;AAE5C,YAAA,IAAI,CAAC,oBAAoB,EAAA,EAAI;AAC3B,cAAA,MAAM,IAAI,KAAA;AAAA,gBACR,2BAA2B,QAAA,CAAS,YAAY,CAAA,eAAA,EAAkB,oBAAA,CAAqB,mBAAmB,CAAC,CAAA;AAAA,eAC7G;AAAA,YACF;AACA,YAAA,4BAAA,CAA6B,iBAAiB,cAAc,CAAA;AAAA,UAC9D;AAEA,UAAA,GAAA,CAAI,MAAA,CAAO,IAAA;AAAA,YACT,CAAA,CAAA,EAAI,OAAO,CAAA,wDAAA,EAA2D,IAAA,CAAK,SAAA,CAAU;AAAA,cACnF,UAAA,EAAY,kBAAA;AAAA,cACZ,UAAA,EAAY,kBAAA;AAAA,cACZ,YAAA,EAAc,oBAAA;AAAA,cACd,mBAAmB,qBAAA,CAAsB,MAAA;AAAA,cACzC,sBAAsB,gBAAA,CAAiB;AAAA,aACxC,CAAC,CAAA;AAAA,WACJ;AACA,UAAA,GAAA,CAAI,MAAA,CAAO,cAAc,kBAAkB,CAAA;AAC3C,UAAA,GAAA,CAAI,MAAA,CAAO,gBAAgB,oBAAoB,CAAA;AAC/C,UAAA,GAAA,CAAI,MAAA,CAAO,cAAc,kBAAkB,CAAA;AAC3C,UAAA,MAAMG,kBAAiB,MAAM,qBAAA;AAAA,YAC3B,YAAA;AAAA,YACA,QAAA,CAAS,MAAA;AAAA,YACT,MAAA;AAAA,YACA;AAAA,WACF;AACA,UAAA,GAAA,CAAI,MAAA;AAAA,YACF,aAAA;AAAA,YACA,gBAAA,CAAiB,YAAA,EAAc,kBAAA,EAAoBA,eAAc;AAAA,WACnE;AACA,UAAA;AAAA,QACF;AAGA,QAAA,MAAM,UAAA,GAAa;AAAA,UACjB,IAAA,EAAM,oBAAA;AAAA,UACN,aAAA,EAAe,sBAAA;AAAA,UACf,QAAA,EAAU;AAAA,YACR,MAAA,EAAQ,EAAE,IAAA,EAAM,WAAA,EAAY;AAAA,YAC5B,SAAA,EAAW,kBAAA;AAAA,YACX,qBAAqB;AAAC;AACxB,SACF;AAEA,QAAA,MAAM,aAAa,CAAA,EAAG,YAAY,iCAAiC,kBAAA,CAAmB,QAAA,CAAS,MAAM,CAAC,CAAA,UAAA,CAAA;AACtG,QAAA,MAAA,CAAO,IAAA;AAAA,UACL,CAAA,CAAA,EAAI,OAAO,CAAA,wCAAA,EAA2C,UAAU,CAAA;AAAA,SAClE;AACA,QAAA,MAAA,CAAO,IAAA;AAAA,UACL,CAAA,CAAA,EAAI,OAAO,CAAA,oCAAA,EAAuC,IAAA,CAAK,SAAA,CAAU;AAAA,YAC/D,MAAM,UAAA,CAAW,IAAA;AAAA,YACjB,eAAe,UAAA,CAAW,aAAA;AAAA,YAC1B,eAAe,kBAAA,CAAmB;AAAA,WACnC,CAAC,CAAA;AAAA,SACJ;AAEA,QAAA,MAAM,WAAW,MAAMH,4BAAA;AAAA,UACrB,MACE,YAAA,CAAa,0BAAA,CAA2B,qBAAA,CAAsB;AAAA,YAC5D,WAAW,QAAA,CAAS,MAAA;AAAA,YACpB,eAAA,EAAiB;AAAA,WAClB,CAAA;AAAA,UACH;AAAA,SACF;AAEA,QAAA,MAAM,eAAe,QAAA,CAAS,MAAA;AAC9B,QAAA,MAAM,eAAe,QAAA,CAAS,IAAA;AAC9B,QAAA,GAAA,CAAI,OAAO,IAAA,CAAK,CAAA,CAAA,EAAI,OAAO,CAAA,mBAAA,EAAsB,QAAA,CAAS,MAAM,CAAA,CAAE,CAAA;AAElE,QAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,UAAA,MAAM,YAAA,GAAe,qBAAqB,QAAQ,CAAA;AAClD,UAAA,GAAA,CAAI,MAAA,CAAO,KAAA;AAAA,YACT,IAAI,OAAO,CAAA,kBAAA,EAAqB,YAAY,CAAA,eAAA,EAAkB,KAAK,SAAA,CAAU;AAAA,cAC3E,QAAQ,QAAA,CAAS,MAAA;AAAA,cACjB,YAAA,EAAc,oBAAA;AAAA,cACd,aAAA,EAAe,sBAAA;AAAA,cACf,kBAAA;AAAA,cACA,wBAAA;AAAA,cACA,yBAAA;AAAA,cACA,YAAA;AAAA,cACA;AAAA,aACD,CAAC,CAAA;AAAA,WACJ;AACA,UAAA,MAAM,IAAI,KAAA;AAAA,YACR,8BAA8B,YAAY,CAAA;AAAA,WAC5C;AAAA,QACF;AACA,QAAA,4BAAA,CAA6B,cAAc,UAAU,CAAA;AAErD,QAAA,MAAM,UAAA,GAAa,4BAA4B,YAAY,CAAA;AAC3D,QAAA,IAAI,oBAAA,EAAsB;AACxB,UAAA,MAAM,iCAAA,CAAkC;AAAA,YACtC,YAAA;AAAA,YACA,KAAA,EAAO,gBAAA;AAAA,YACP,eAAe,UAAA,CAAW,UAAA;AAAA,YAC1B,kBAAA,EAAoB,oBAAA;AAAA,YACpB,aAAA,EAAe,sBAAA;AAAA,YACf,cAAA,EAAgB,8BAAA;AAAA,YAChB,OAAA,EAAS,uBAAA;AAAA,YACT,OAAA;AAAA,YACA,QAAQ,GAAA,CAAI;AAAA,WACb,CAAA;AAAA,QACH;AACA,QAAA,GAAA,CAAI,MAAA,CAAO,IAAA;AAAA,UACT,CAAA,CAAA,EAAI,OAAO,CAAA,iCAAA,EAAoC,IAAA,CAAK,SAAA,CAAU;AAAA,YAC5D,YAAY,UAAA,CAAW,UAAA;AAAA,YACvB,YAAY,UAAA,CAAW,UAAA;AAAA,YACvB,YAAA,EAAc,aAAa,YAAA,IAAgB,oBAAA;AAAA,YAC3C,kBAAA,EAAoB,QAAQ,oBAAoB;AAAA,WACjD,CAAC,CAAA;AAAA,SACJ;AACA,QAAA,GAAA,CAAI,MAAA,CAAO,YAAA,EAAc,UAAA,CAAW,UAAU,CAAA;AAC9C,QAAA,GAAA,CAAI,MAAA;AAAA,UACF,cAAA;AAAA,UACA,aAAa,YAAA,IAAgB;AAAA,SAC/B;AACA,QAAA,GAAA,CAAI,MAAA,CAAO,YAAA,EAAc,UAAA,CAAW,UAAU,CAAA;AAC9C,QAAA,MAAM,iBAAiB,MAAM,qBAAA;AAAA,UAC3B,YAAA;AAAA,UACA,QAAA,CAAS,MAAA;AAAA,UACT,MAAA;AAAA,UACA;AAAA,SACF;AACA,QAAA,GAAA,CAAI,MAAA;AAAA,UACF,aAAA;AAAA,UACA,gBAAA;AAAA,YACE,YAAA;AAAA,YACA,UAAA,CAAW,UAAA;AAAA,YACX;AAAA;AACF,SACF;AAAA,MACF,SAAS,KAAA,EAAY;AACnB,QAAA,MAAM,WAAA,GAAc,MAAM,qBAAA,CAAsB,KAAK,CAAA;AAErD,QAAA,IAAI,YAAA,GAAe,8BAA8B,WAAW,CAAA,CAAA;AAG5D,QAAA,IACE,0BAAA,IACA,CAAC,WAAA,CAAY,QAAA,CAAS,8BAA8B,CAAA,EACpD;AACA,UAAA,YAAA,IAAgB,mCAAmC,0BAA0B,CAAA,CAAA,CAAA;AAAA,QAC/E;AAEA,QAAA,GAAA,CAAI,MAAA,CAAO,MAAM,YAAY,CAAA;AAC7B,QAAA,MAAM,IAAI,MAAM,YAAY,CAAA;AAAA,MAC9B;AAAA,IACF;AAAA,GACD,CAAA;AACH;;;;;;"}
@@ -0,0 +1,243 @@
1
+ 'use strict';
2
+
3
+ var pluginScaffolderNode = require('@backstage/plugin-scaffolder-node');
4
+ var zod = require('zod');
5
+ var http = require('../../exporter/http.cjs.js');
6
+ var apiObjects = require('../../utils/api-objects.cjs.js');
7
+
8
+ const gitConfigParametersSchema = zod.z.object({
9
+ scmType: zod.z.enum(["GITHUB", "GITLAB", "BITBUCKET", "AZUREDEV"]).optional(),
10
+ repoUrl: zod.z.string().optional(),
11
+ targetBranch: zod.z.string().optional(),
12
+ path: zod.z.string().optional()
13
+ });
14
+ const gitConfigSchema = zod.z.object({
15
+ name: zod.z.string().optional(),
16
+ type: zod.z.string().optional(),
17
+ parameters: gitConfigParametersSchema.optional(),
18
+ vaultReference: zod.z.string().optional(),
19
+ default: zod.z.boolean().optional()
20
+ });
21
+ const stateBackendTemplateSchema = zod.z.object({
22
+ type: zod.z.enum(["S3", "GCS", "AZURERM", "LOCAL", "POSTGRES", "REMOTE", "CLOUD"]).optional(),
23
+ configJson: zod.z.string().optional(),
24
+ hcl: zod.z.string().optional(),
25
+ editorMode: zod.z.boolean().optional()
26
+ });
27
+ const environmentTemplateSchema = zod.z.object({
28
+ name: zod.z.string().optional(),
29
+ color: zod.z.string().optional(),
30
+ stateBackendTemplate: stateBackendTemplateSchema.optional()
31
+ });
32
+ const environmentConfigVariableSchema = zod.z.object({
33
+ name: zod.z.string().optional(),
34
+ type: zod.z.string().optional(),
35
+ defaultValueJson: zod.z.string().optional(),
36
+ description: zod.z.string().optional()
37
+ });
38
+ const environmentConfigVariableOverrideSchema = zod.z.object({
39
+ variableName: zod.z.string().optional(),
40
+ environmentTemplateName: zod.z.string().optional(),
41
+ valueJson: zod.z.string().optional()
42
+ });
43
+ const environmentConfigSchema = zod.z.object({
44
+ name: zod.z.string().optional(),
45
+ environmentTemplates: zod.z.array(environmentTemplateSchema).optional(),
46
+ variables: zod.z.array(environmentConfigVariableSchema).optional(),
47
+ variableOverrides: zod.z.array(environmentConfigVariableOverrideSchema).optional()
48
+ });
49
+ const createProjectInputSchema = zod.z.object({
50
+ project: zod.z.object({
51
+ name: zod.z.string(),
52
+ description: zod.z.string(),
53
+ gitConfig: gitConfigSchema.optional(),
54
+ environmentConfig: environmentConfigSchema.optional()
55
+ })
56
+ });
57
+ const createProjectOutputSchema = zod.z.object({
58
+ projectId: zod.z.string(),
59
+ projectName: zod.z.string(),
60
+ alreadyExisted: zod.z.boolean(),
61
+ teamId: zod.z.string(),
62
+ /** StackGen UI URL: `{baseUrl}/project/{projectName}/` */
63
+ projectURL: zod.z.string()
64
+ });
65
+ const createProjectAction = (config, logger) => {
66
+ return pluginScaffolderNode.createTemplateAction({
67
+ id: "stackGen:createProject",
68
+ description: "Creates a Project in StackGen with optional git and environment configuration",
69
+ schema: {
70
+ // Backstage parseSchemas only accepts (z) => ZodType or per-field callbacks.
71
+ input: () => createProjectInputSchema,
72
+ output: () => createProjectOutputSchema
73
+ },
74
+ async handler(ctx) {
75
+ const stackgenApis = apiObjects.getStackgenApiObjects(config);
76
+ const payload = {
77
+ name: ctx.input.project.name,
78
+ description: ctx.input.project.description,
79
+ gitConfig: ctx.input.project.gitConfig,
80
+ environmentConfig: ctx.input.project.environmentConfig
81
+ };
82
+ logger.info("Stackgen: Creating project with generated client");
83
+ let responseStatus;
84
+ let responseBody = {};
85
+ let responseRequestId;
86
+ try {
87
+ responseBody = await stackgenApis.integrationsProjectApiObj.createProject({
88
+ projectRequest: payload
89
+ });
90
+ responseStatus = 201;
91
+ } catch (error) {
92
+ const parsedError = await apiObjects.readClientError(error);
93
+ if (parsedError.status === 500 && parsedError.text === String(error)) {
94
+ throw error;
95
+ }
96
+ responseStatus = parsedError.status;
97
+ responseBody = parsedError.body;
98
+ responseRequestId = parsedError.requestId;
99
+ }
100
+ const normalizeName = (value) => value.trim().toLowerCase().replace(/[\s_-]+/g, "-");
101
+ const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
102
+ const getTeamIdFromGlobalAppstackSearch = async (teamName) => {
103
+ let appstacks = [];
104
+ try {
105
+ appstacks = await stackgenApis.integrationsAppstackApiObj.listAppStacks({
106
+ searchAllProjects: true
107
+ });
108
+ } catch (error) {
109
+ const detail = await apiObjects.formatClientErrorMessage(error);
110
+ ctx.logger.warn(
111
+ `Unable to run global appstack search fallback: ${detail}`
112
+ );
113
+ return void 0;
114
+ }
115
+ const normalizedTeamName = normalizeName(teamName);
116
+ const matchingTeamIds = Array.from(
117
+ new Set(
118
+ appstacks.filter((a) => {
119
+ const ownedBy = String(a?.ownedBy ?? "");
120
+ return ownedBy === teamName || ownedBy.toLowerCase() === teamName.toLowerCase() || normalizeName(ownedBy) === normalizedTeamName;
121
+ }).map((a) => a?.teamId).filter((id) => typeof id === "string" && id.length > 0)
122
+ )
123
+ );
124
+ if (matchingTeamIds.length === 1) {
125
+ return matchingTeamIds[0];
126
+ }
127
+ if (matchingTeamIds.length > 1) {
128
+ throw new Error(
129
+ `Found multiple team IDs for project/team name "${teamName}" via global appstack lookup: ${matchingTeamIds.join(", ")}`
130
+ );
131
+ }
132
+ return void 0;
133
+ };
134
+ const getTeamIdByName = async (teamName) => {
135
+ const normalizedTeamName = normalizeName(teamName);
136
+ const maxAttempts = 5;
137
+ const delayMs = 1e3;
138
+ let lastSeenTeamNames = [];
139
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
140
+ let teams;
141
+ try {
142
+ teams = await stackgenApis.integrationsTeamApiObj.listTeams({
143
+ includeAll: true
144
+ });
145
+ } catch (error) {
146
+ const detail = await apiObjects.formatClientErrorMessage(error);
147
+ throw new Error(
148
+ `Failed to resolve teamId for existing project "${teamName}" via listTeams: ${detail}`
149
+ );
150
+ }
151
+ lastSeenTeamNames = teams.map((t) => t?.name).filter(Boolean);
152
+ const team = teams.find((t) => t?.name === teamName) || teams.find((t) => String(t?.name ?? "").toLowerCase() === teamName.toLowerCase()) || teams.find((t) => normalizeName(String(t?.name ?? "")) === normalizedTeamName);
153
+ if (team?.id) {
154
+ return team.id;
155
+ }
156
+ if (attempt < maxAttempts) {
157
+ await sleep(delayMs);
158
+ }
159
+ }
160
+ const teamIdFromGlobalAppstackSearch = await getTeamIdFromGlobalAppstackSearch(teamName);
161
+ if (teamIdFromGlobalAppstackSearch) {
162
+ ctx.logger.info(
163
+ `Resolved teamId for "${teamName}" using /integrations/api/v1/appstacks?searchAllProjects=true fallback`
164
+ );
165
+ return teamIdFromGlobalAppstackSearch;
166
+ }
167
+ throw new Error(
168
+ `Team with name "${teamName}" not found. Visible teams: ${lastSeenTeamNames.join(", ")}`
169
+ );
170
+ };
171
+ const resolveTeamId = async (teamName, body) => {
172
+ const directTeamId = body?.id || body?.projectId || body?.teamId || body?.project?.teamId || body?.project?.id;
173
+ if (typeof directTeamId === "string" && directTeamId.length > 0) {
174
+ return directTeamId;
175
+ }
176
+ return getTeamIdByName(teamName);
177
+ };
178
+ const buildProjectUrl = (projectName) => {
179
+ let base = stackgenApis.baseUrl;
180
+ while (base.endsWith("/")) {
181
+ base = base.slice(0, -1);
182
+ }
183
+ return `${base}/project/${encodeURIComponent(projectName)}/`;
184
+ };
185
+ if (responseStatus === 201) {
186
+ ctx.logger.info(
187
+ `Project created successfully: ${responseBody.project?.name}`
188
+ );
189
+ const teamId = await resolveTeamId(payload.name, responseBody);
190
+ const projectName = responseBody.project?.name || payload.name;
191
+ ctx.output("projectId", responseBody.project?.id || teamId || "");
192
+ ctx.output("projectName", projectName);
193
+ ctx.output("teamId", teamId);
194
+ ctx.output("alreadyExisted", false);
195
+ ctx.output("projectURL", buildProjectUrl(projectName));
196
+ return;
197
+ }
198
+ if (responseStatus === 409) {
199
+ ctx.logger.info(`Project already exists: ${payload.name}`);
200
+ const teamId = await resolveTeamId(payload.name, responseBody);
201
+ ctx.output("projectId", responseBody.project?.id || teamId || "");
202
+ ctx.output("projectName", payload.name);
203
+ ctx.output("teamId", teamId);
204
+ ctx.output("alreadyExisted", true);
205
+ ctx.output("projectURL", buildProjectUrl(payload.name));
206
+ return;
207
+ }
208
+ if (responseStatus === 403) {
209
+ throw new Error(
210
+ `Invalid token permissions for project creation. ${apiObjects.formatApiFailure(
211
+ responseStatus,
212
+ responseBody,
213
+ http.apiErrorMessage(responseBody) || "forbidden",
214
+ responseRequestId
215
+ )}`
216
+ );
217
+ }
218
+ if (responseStatus === 400) {
219
+ throw new Error(
220
+ `Failed to create project: ${apiObjects.formatApiFailure(
221
+ responseStatus,
222
+ responseBody,
223
+ "Invalid project name",
224
+ responseRequestId
225
+ )}`
226
+ );
227
+ }
228
+ throw new Error(
229
+ `Failed to create project: ${apiObjects.formatApiFailure(
230
+ responseStatus,
231
+ responseBody,
232
+ "Unknown error",
233
+ responseRequestId
234
+ )}`
235
+ );
236
+ }
237
+ });
238
+ };
239
+
240
+ exports.createProjectAction = createProjectAction;
241
+ exports.createProjectInputSchema = createProjectInputSchema;
242
+ exports.createProjectOutputSchema = createProjectOutputSchema;
243
+ //# sourceMappingURL=create_project_action.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create_project_action.cjs.js","sources":["../../../src/actions/core/create_project_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 { apiErrorMessage } from \"../../exporter/http\";\nimport {\n formatApiFailure,\n formatClientErrorMessage,\n getStackgenApiObjects,\n readClientError,\n} from \"../../utils/api-objects\";\n\n// Git config schemas\nconst gitConfigParametersSchema = z.object({\n scmType: z.enum(['GITHUB', 'GITLAB', 'BITBUCKET', 'AZUREDEV']).optional(),\n repoUrl: z.string().optional(),\n targetBranch: z.string().optional(),\n path: z.string().optional(),\n});\n\nconst gitConfigSchema = z.object({\n name: z.string().optional(),\n type: z.string().optional(),\n parameters: gitConfigParametersSchema.optional(),\n vaultReference: z.string().optional(),\n default: z.boolean().optional(),\n});\n\n// Environment config schemas\nconst stateBackendTemplateSchema = z.object({\n type: z.enum(['S3', 'GCS', 'AZURERM', 'LOCAL', 'POSTGRES', 'REMOTE', 'CLOUD']).optional(),\n configJson: z.string().optional(),\n hcl: z.string().optional(),\n editorMode: z.boolean().optional(),\n});\n\nconst environmentTemplateSchema = z.object({\n name: z.string().optional(),\n color: z.string().optional(),\n stateBackendTemplate: stateBackendTemplateSchema.optional(),\n});\n\nconst environmentConfigVariableSchema = z.object({\n name: z.string().optional(),\n type: z.string().optional(),\n defaultValueJson: z.string().optional(),\n description: z.string().optional(),\n});\n\nconst environmentConfigVariableOverrideSchema = z.object({\n variableName: z.string().optional(),\n environmentTemplateName: z.string().optional(),\n valueJson: z.string().optional(),\n});\n\nconst environmentConfigSchema = z.object({\n name: z.string().optional(),\n environmentTemplates: z.array(environmentTemplateSchema).optional(),\n variables: z.array(environmentConfigVariableSchema).optional(),\n variableOverrides: z.array(environmentConfigVariableOverrideSchema).optional(),\n});\n\n// Main input/output schemas\nexport const createProjectInputSchema = z.object({\n project: z.object({\n name: z.string(),\n description: z.string(),\n gitConfig: gitConfigSchema.optional(),\n environmentConfig: environmentConfigSchema.optional(),\n }),\n});\n\nexport const createProjectOutputSchema = z.object({\n projectId: z.string(),\n projectName: z.string(),\n alreadyExisted: z.boolean(),\n teamId: z.string(),\n /** StackGen UI URL: `{baseUrl}/project/{projectName}/` */\n projectURL: z.string(),\n});\n\nexport const createProjectAction = (config: Config, logger: LoggerService) => {\n return createTemplateAction({\n id: \"stackGen:createProject\",\n description:\n \"Creates a Project in StackGen with optional git and environment configuration\",\n schema: {\n // Backstage parseSchemas only accepts (z) => ZodType or per-field callbacks.\n input: () => createProjectInputSchema,\n output: () => createProjectOutputSchema,\n },\n\n async handler(ctx) {\n const stackgenApis = getStackgenApiObjects(config);\n\n const payload = {\n name: ctx.input.project.name,\n description: ctx.input.project.description,\n gitConfig: ctx.input.project.gitConfig,\n environmentConfig: ctx.input.project.environmentConfig,\n };\n\n logger.info(\"Stackgen: Creating project with generated client\");\n let responseStatus: number;\n let responseBody: any = {};\n let responseRequestId: string | undefined;\n try {\n responseBody = await stackgenApis.integrationsProjectApiObj.createProject({\n projectRequest: payload as never,\n });\n responseStatus = 201;\n } catch (error) {\n const parsedError = await readClientError(error);\n if (parsedError.status === 500 && parsedError.text === String(error)) {\n throw error;\n }\n responseStatus = parsedError.status;\n responseBody = parsedError.body;\n responseRequestId = parsedError.requestId;\n }\n\n const normalizeName = (value: string) =>\n value.trim().toLowerCase().replace(/[\\s_-]+/g, \"-\");\n\n const sleep = (ms: number) =>\n new Promise(resolve => setTimeout(resolve, ms));\n\n const getTeamIdFromGlobalAppstackSearch = async (teamName: string) => {\n let appstacks: any[] = [];\n try {\n appstacks = await stackgenApis.integrationsAppstackApiObj.listAppStacks({\n searchAllProjects: true,\n }) as any[];\n } catch (error) {\n const detail = await formatClientErrorMessage(error);\n ctx.logger.warn(\n `Unable to run global appstack search fallback: ${detail}`,\n );\n return undefined;\n }\n const normalizedTeamName = normalizeName(teamName);\n const matchingTeamIds = Array.from(\n new Set(\n appstacks\n .filter((a: any) => {\n const ownedBy = String(a?.ownedBy ?? \"\");\n return (\n ownedBy === teamName ||\n ownedBy.toLowerCase() === teamName.toLowerCase() ||\n normalizeName(ownedBy) === normalizedTeamName\n );\n })\n .map((a: any) => a?.teamId)\n .filter((id: any) => typeof id === \"string\" && id.length > 0)\n )\n );\n\n if (matchingTeamIds.length === 1) {\n return matchingTeamIds[0];\n }\n\n if (matchingTeamIds.length > 1) {\n throw new Error(\n `Found multiple team IDs for project/team name \"${teamName}\" via global appstack lookup: ${matchingTeamIds.join(\", \")}`\n );\n }\n\n return undefined;\n };\n\n // Fallback for APIs that do not include teamId/projectId in conflict responses.\n const getTeamIdByName = async (teamName: string) => {\n const normalizedTeamName = normalizeName(teamName);\n const maxAttempts = 5;\n const delayMs = 1000;\n let lastSeenTeamNames: string[] = [];\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n let teams: any[];\n try {\n teams = await stackgenApis.integrationsTeamApiObj.listTeams({\n includeAll: true,\n });\n } catch (error) {\n const detail = await formatClientErrorMessage(error);\n throw new Error(\n `Failed to resolve teamId for existing project \"${teamName}\" via listTeams: ${detail}`,\n );\n }\n lastSeenTeamNames = teams.map((t: any) => t?.name).filter(Boolean);\n\n const team =\n teams.find((t: any) => t?.name === teamName) ||\n teams.find((t: any) => String(t?.name ?? \"\").toLowerCase() === teamName.toLowerCase()) ||\n teams.find((t: any) => normalizeName(String(t?.name ?? \"\")) === normalizedTeamName);\n\n if (team?.id) {\n return team.id;\n }\n\n if (attempt < maxAttempts) {\n await sleep(delayMs);\n }\n }\n\n const teamIdFromGlobalAppstackSearch =\n await getTeamIdFromGlobalAppstackSearch(teamName);\n if (teamIdFromGlobalAppstackSearch) {\n ctx.logger.info(\n `Resolved teamId for \"${teamName}\" using /integrations/api/v1/appstacks?searchAllProjects=true fallback`\n );\n return teamIdFromGlobalAppstackSearch;\n }\n\n throw new Error(\n `Team with name \"${teamName}\" not found. Visible teams: ${lastSeenTeamNames.join(\", \")}`\n );\n };\n\n const resolveTeamId = async (teamName: string, body: any) => {\n const directTeamId =\n body?.id ||\n body?.projectId ||\n body?.teamId ||\n body?.project?.teamId ||\n body?.project?.id;\n\n if (typeof directTeamId === \"string\" && directTeamId.length > 0) {\n return directTeamId;\n }\n\n return getTeamIdByName(teamName);\n };\n\n const buildProjectUrl = (projectName: string) => {\n let base = stackgenApis.baseUrl;\n while (base.endsWith(\"/\")) {\n base = base.slice(0, -1);\n }\n return `${base}/project/${encodeURIComponent(projectName)}/`;\n };\n\n // Handle specific status codes\n if (responseStatus === 201) {\n ctx.logger.info(\n `Project created successfully: ${responseBody.project?.name}`\n );\n const teamId = await resolveTeamId(payload.name, responseBody);\n const projectName = responseBody.project?.name || payload.name;\n ctx.output(\"projectId\", responseBody.project?.id || teamId || \"\");\n ctx.output(\"projectName\", projectName);\n ctx.output(\"teamId\", teamId);\n ctx.output(\"alreadyExisted\", false);\n ctx.output(\"projectURL\", buildProjectUrl(projectName));\n return;\n }\n\n if (responseStatus === 409) {\n ctx.logger.info(`Project already exists: ${payload.name}`);\n const teamId = await resolveTeamId(payload.name, responseBody);\n ctx.output(\"projectId\", responseBody.project?.id || teamId || \"\");\n ctx.output(\"projectName\", payload.name);\n ctx.output(\"teamId\", teamId);\n ctx.output(\"alreadyExisted\", true);\n ctx.output(\"projectURL\", buildProjectUrl(payload.name));\n return;\n }\n\n if (responseStatus === 403) {\n throw new Error(\n `Invalid token permissions for project creation. ${formatApiFailure(\n responseStatus,\n responseBody,\n apiErrorMessage(responseBody) || \"forbidden\",\n responseRequestId,\n )}`,\n );\n }\n\n if (responseStatus === 400) {\n throw new Error(\n `Failed to create project: ${formatApiFailure(\n responseStatus,\n responseBody,\n \"Invalid project name\",\n responseRequestId,\n )}`,\n );\n }\n\n // Generic error for other status codes\n throw new Error(\n `Failed to create project: ${formatApiFailure(\n responseStatus,\n responseBody,\n \"Unknown error\",\n responseRequestId,\n )}`,\n );\n },\n });\n};\n"],"names":["z","createTemplateAction","getStackgenApiObjects","readClientError","formatClientErrorMessage","formatApiFailure","apiErrorMessage"],"mappings":"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"}
@@ -0,0 +1,133 @@
1
+ 'use strict';
2
+
3
+ var pluginScaffolderNode = require('@backstage/plugin-scaffolder-node');
4
+ var zod = require('zod');
5
+ var path = require('path');
6
+ var fs = require('fs/promises');
7
+ var topologyResolve = require('../../exporter/topologyResolve.cjs.js');
8
+ var extractArchive = require('../../lib/extractArchive.cjs.js');
9
+ var apiObjects = require('../../utils/api-objects.cjs.js');
10
+
11
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
12
+
13
+ var path__default = /*#__PURE__*/_interopDefaultCompat(path);
14
+ var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
15
+
16
+ const downloadIacInputSchema = zod.z.object({
17
+ teamId: zod.z.string().min(1, "teamId is required for IaC download"),
18
+ appstackName: zod.z.string().optional(),
19
+ appstackId: zod.z.string().optional(),
20
+ topologyId: zod.z.string().optional(),
21
+ extractedIaCPath: zod.z.string().optional().default("./")
22
+ }).refine(
23
+ (data) => data.topologyId || data.appstackName || data.appstackId,
24
+ { message: "At least one of 'topologyId', 'appstackName', or 'appstackId' must be provided" }
25
+ );
26
+ const downloadIacOutputSchema = zod.z.object({
27
+ extractedIacPath: zod.z.string()
28
+ });
29
+ async function resolveTopologyIdForDownload(config, teamId, appstackName, appstackId, logger) {
30
+ if (!appstackId && !appstackName) {
31
+ throw new Error("Either topologyId, appstackId, or appstackName must be provided");
32
+ }
33
+ logger.info(
34
+ `Resolving topologyId from appstack ${appstackId ? `id ${appstackId}` : `name '${appstackName}'`}`
35
+ );
36
+ return topologyResolve.resolveTopologyId({
37
+ config,
38
+ teamId,
39
+ appstackId,
40
+ appstackName});
41
+ }
42
+ async function fetchIacZipBuffer(stackgenApis, topologyId, teamId, logger) {
43
+ logger.info(
44
+ `Downloading IaC ZIP via generated client (project=${teamId}, topology=${topologyId})`
45
+ );
46
+ const blob = await stackgenApis.integrationsTopologyApiObj.v1ProjectExportTopologyIaC({
47
+ projectId: teamId,
48
+ topologyId
49
+ });
50
+ return Buffer.from(await blob.arrayBuffer());
51
+ }
52
+ function validateTeamId(teamId, allowedTeams) {
53
+ if (allowedTeams.length === 0) return;
54
+ if (!allowedTeams.includes(teamId)) {
55
+ throw new Error(`Team ID ${teamId} is not allowed.`);
56
+ }
57
+ }
58
+ const downloadIaCAction = (config, logger) => {
59
+ return pluginScaffolderNode.createTemplateAction({
60
+ id: "stackGen:downloadIaC",
61
+ description: "Downloads the IaC from StackGen for an appstack topology",
62
+ schema: {
63
+ // Backstage parseSchemas only accepts (z) => ZodType or per-field callbacks.
64
+ input: () => downloadIacInputSchema,
65
+ output: () => downloadIacOutputSchema
66
+ },
67
+ async handler(ctx) {
68
+ const { teamId, appstackName, appstackId, topologyId: inputTopologyId } = ctx.input;
69
+ const stackgenApis = apiObjects.getStackgenApiObjects(config);
70
+ try {
71
+ const allowedTeams = config.getOptionalString("stackGen.allowedTeams")?.split(",").map((id) => id.trim()) || [];
72
+ validateTeamId(teamId, allowedTeams);
73
+ const topologyId = inputTopologyId || await resolveTopologyIdForDownload(
74
+ config,
75
+ teamId,
76
+ appstackName,
77
+ appstackId,
78
+ logger
79
+ );
80
+ const zipBuffer = await fetchIacZipBuffer(
81
+ stackgenApis,
82
+ topologyId,
83
+ teamId,
84
+ logger
85
+ );
86
+ const fileLabel = path__default.default.basename(
87
+ appstackName || appstackId || topologyId
88
+ );
89
+ const zipPath = path__default.default.resolve(
90
+ ctx.workspacePath,
91
+ `${fileLabel}-iac.zip`
92
+ );
93
+ if (!extractArchive.isPathInsideRoot(ctx.workspacePath, zipPath)) {
94
+ throw new Error(
95
+ `Refusing ZIP path outside workspace: ${zipPath}`
96
+ );
97
+ }
98
+ await fs__default.default.writeFile(zipPath, zipBuffer);
99
+ logger.info(`Saved IaC ZIP to ${zipPath}`);
100
+ ctx.input.extractedIaCPath = ctx.input.extractedIaCPath || "./";
101
+ const extractedPath = path__default.default.resolve(
102
+ ctx.workspacePath,
103
+ ctx.input.extractedIaCPath
104
+ );
105
+ if (!extractArchive.isPathInsideRoot(ctx.workspacePath, extractedPath)) {
106
+ throw new Error(
107
+ `Refusing extractedIaCPath outside workspace: ${ctx.input.extractedIaCPath}`
108
+ );
109
+ }
110
+ await extractArchive.extractArchiveToDir(zipPath, extractedPath);
111
+ logger.info(`Extracted IaC to ${extractedPath}`);
112
+ ctx.logger.info(`IaC files extracted to ${extractedPath}`);
113
+ await fs__default.default.unlink(zipPath);
114
+ } catch (err) {
115
+ if (err?.response) {
116
+ const detail2 = await apiObjects.formatClientErrorMessage(err);
117
+ logger.error(`Download IaC Error: ${detail2}`);
118
+ ctx.logger.error(`Download IaC Error: ${detail2}`);
119
+ throw new Error(`Download IaC Error: ${detail2}`);
120
+ }
121
+ const detail = err instanceof Error ? err.message : String(err);
122
+ logger.error(`Download IaC Error: ${detail}`);
123
+ ctx.logger.error(`Download IaC Error: ${detail}`);
124
+ throw err;
125
+ }
126
+ }
127
+ });
128
+ };
129
+
130
+ exports.downloadIaCAction = downloadIaCAction;
131
+ exports.downloadIacInputSchema = downloadIacInputSchema;
132
+ exports.downloadIacOutputSchema = downloadIacOutputSchema;
133
+ //# sourceMappingURL=download_iac_action.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"download_iac_action.cjs.js","sources":["../../../src/actions/core/download_iac_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 path from \"path\";\nimport fs from \"fs/promises\";\nimport { resolveTopologyId } from '../../exporter/topologyResolve';\nimport {\n extractArchiveToDir,\n isPathInsideRoot,\n} from \"../../lib/extractArchive\";\nimport { getStackgenApiObjects, formatClientErrorMessage } from \"../../utils/api-objects\";\n\nexport const downloadIacInputSchema = z.object({\n teamId: z.string().min(1, \"teamId is required for IaC download\"),\n appstackName: z.string().optional(),\n appstackId: z.string().optional(),\n topologyId: z.string().optional(),\n extractedIaCPath: z.string().optional().default(\"./\"),\n}).refine(\n (data) => data.topologyId || data.appstackName || data.appstackId,\n { message: \"At least one of 'topologyId', 'appstackName', or 'appstackId' must be provided\" },\n);\n\nexport const downloadIacOutputSchema = z.object({\n extractedIacPath: z.string(),\n});\n\nasync function resolveTopologyIdForDownload(\n config: Config,\n teamId: string,\n appstackName: string | undefined,\n appstackId: string | undefined,\n logger: LoggerService,\n): Promise<string> {\n if (!appstackId && !appstackName) {\n throw new Error(\"Either topologyId, appstackId, or appstackName must be provided\");\n }\n\n logger.info(\n `Resolving topologyId from appstack ${appstackId ? `id ${appstackId}` : `name '${appstackName}'`}`,\n );\n return resolveTopologyId({\n config,\n teamId,\n appstackId,\n appstackName,\n logger,\n });\n}\n\nasync function fetchIacZipBuffer(\n stackgenApis: ReturnType<typeof getStackgenApiObjects>,\n topologyId: string,\n teamId: string,\n logger: LoggerService,\n): Promise<Buffer> {\n logger.info(\n `Downloading IaC ZIP via generated client (project=${teamId}, topology=${topologyId})`,\n );\n const blob = await stackgenApis.integrationsTopologyApiObj.v1ProjectExportTopologyIaC({\n projectId: teamId,\n topologyId,\n });\n return Buffer.from(await blob.arrayBuffer());\n}\n\nfunction validateTeamId(teamId: string, allowedTeams: string[]) {\n if (allowedTeams.length === 0) return;\n if (!allowedTeams.includes(teamId)) {\n throw new Error(`Team ID ${teamId} is not allowed.`);\n }\n}\n\nexport const downloadIaCAction = (config: Config, logger: LoggerService) => {\n return createTemplateAction({\n id: \"stackGen:downloadIaC\",\n description:\n \"Downloads the IaC from StackGen for an appstack topology\",\n schema: {\n // Backstage parseSchemas only accepts (z) => ZodType or per-field callbacks.\n input: () => downloadIacInputSchema,\n output: () => downloadIacOutputSchema,\n },\n async handler(ctx) {\n const { teamId, appstackName, appstackId, topologyId: inputTopologyId } = ctx.input;\n const stackgenApis = getStackgenApiObjects(config);\n\n try {\n const allowedTeams = config\n .getOptionalString(\"stackGen.allowedTeams\")\n ?.split(\",\")\n .map((id) => id.trim()) || [];\n\n validateTeamId(teamId, allowedTeams);\n\n // Resolve topologyId if not provided directly\n const topologyId =\n inputTopologyId ||\n (await resolveTopologyIdForDownload(\n config,\n teamId,\n appstackName,\n appstackId,\n logger,\n ));\n\n const zipBuffer = await fetchIacZipBuffer(\n stackgenApis,\n topologyId,\n teamId,\n logger,\n );\n\n // Save ZIP to workspace (basename so labels cannot escape via path segments)\n const fileLabel = path.basename(\n appstackName || appstackId || topologyId,\n );\n const zipPath = path.resolve(\n ctx.workspacePath,\n `${fileLabel}-iac.zip`,\n );\n if (!isPathInsideRoot(ctx.workspacePath, zipPath)) {\n throw new Error(\n `Refusing ZIP path outside workspace: ${zipPath}`,\n );\n }\n await fs.writeFile(zipPath, zipBuffer);\n logger.info(`Saved IaC ZIP to ${zipPath}`);\n\n ctx.input.extractedIaCPath = ctx.input.extractedIaCPath || \"./\";\n const extractedPath = path.resolve(\n ctx.workspacePath,\n ctx.input.extractedIaCPath,\n );\n if (!isPathInsideRoot(ctx.workspacePath, extractedPath)) {\n throw new Error(\n `Refusing extractedIaCPath outside workspace: ${ctx.input.extractedIaCPath}`,\n );\n }\n // Archives come from StackGen over TLS; still use a maintained extractor\n // with path containment checks (Zip Slip defense in depth).\n await extractArchiveToDir(zipPath, extractedPath);\n logger.info(`Extracted IaC to ${extractedPath}`);\n ctx.logger.info(`IaC files extracted to ${extractedPath}`);\n // Delete the ZIP after extraction\n await fs.unlink(zipPath);\n } catch (err: unknown) {\n if ((err as { response?: unknown })?.response) {\n const detail = await formatClientErrorMessage(err);\n logger.error(`Download IaC Error: ${detail}`);\n ctx.logger.error(`Download IaC Error: ${detail}`);\n throw new Error(`Download IaC Error: ${detail}`);\n }\n\n const detail =\n err instanceof Error ? err.message : String(err);\n logger.error(`Download IaC Error: ${detail}`);\n ctx.logger.error(`Download IaC Error: ${detail}`);\n throw err;\n }\n },\n });\n};\n"],"names":["z","resolveTopologyId","createTemplateAction","getStackgenApiObjects","path","isPathInsideRoot","fs","extractArchiveToDir","detail","formatClientErrorMessage"],"mappings":"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"}