@better-fullstack/types 1.8.1 → 2.0.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.
- package/dist/{defaults-05kDqAVs.d.mts → defaults-ByJzfP7_.d.mts} +2 -2
- package/dist/defaults-ByJzfP7_.d.mts.map +1 -0
- package/dist/{defaults-D23vxGYl.mjs → defaults-DNmNiuxG.mjs} +1 -1
- package/dist/{defaults-D23vxGYl.mjs.map → defaults-DNmNiuxG.mjs.map} +1 -1
- package/dist/defaults.d.mts +3 -3
- package/dist/defaults.mjs +1 -1
- package/dist/index.d.mts +6 -5
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +5 -4
- package/dist/index.mjs.map +1 -1
- package/dist/json-schema.d.mts +522 -46
- package/dist/json-schema.d.mts.map +1 -1
- package/dist/json-schema.mjs +1 -1
- package/dist/{schemas-CUFM_Cdl.d.mts → schemas-62dqb8iS.d.mts} +510 -46
- package/dist/schemas-62dqb8iS.d.mts.map +1 -0
- package/dist/{schemas-Hj_Gbdf0.mjs → schemas-DnEGgQzA.mjs} +68 -6
- package/dist/schemas-DnEGgQzA.mjs.map +1 -0
- package/dist/schemas.d.mts +2 -2
- package/dist/schemas.mjs +2 -2
- package/dist/stack-graph-C2tzuzRe.mjs +585 -0
- package/dist/stack-graph-C2tzuzRe.mjs.map +1 -0
- package/dist/stack-graph-UgPd4sup.d.mts +68 -0
- package/dist/stack-graph-UgPd4sup.d.mts.map +1 -0
- package/dist/stack-graph.d.mts +4 -0
- package/dist/stack-graph.mjs +4 -0
- package/dist/{stack-translation-BpsvxDrw.mjs → stack-translation-COVG5IPm.mjs} +248 -16
- package/dist/stack-translation-COVG5IPm.mjs.map +1 -0
- package/dist/{stack-translation-D7H3h8Vs.d.mts → stack-translation-CYNMQUUu.d.mts} +13 -6
- package/dist/stack-translation-CYNMQUUu.d.mts.map +1 -0
- package/dist/stack-translation.d.mts +5 -5
- package/dist/stack-translation.mjs +4 -3
- package/dist/{types-C0KHWyJI.d.mts → types-CWpfWGSN.d.mts} +7 -3
- package/dist/{types-C0KHWyJI.d.mts.map → types-CWpfWGSN.d.mts.map} +1 -1
- package/dist/types.d.mts +3 -3
- package/package.json +5 -1
- package/dist/defaults-05kDqAVs.d.mts.map +0 -1
- package/dist/schemas-CUFM_Cdl.d.mts.map +0 -1
- package/dist/schemas-Hj_Gbdf0.mjs.map +0 -1
- package/dist/stack-translation-BpsvxDrw.mjs.map +0 -1
- package/dist/stack-translation-D7H3h8Vs.d.mts.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stack-graph-C2tzuzRe.mjs","names":["ROLE_TARGET_PATHS: Record<StackPrimaryRole, string>","STACK_TOOL_DEFINITIONS: readonly ToolDefinition[]","parts: StackPart[]","backendPart: StackPart | undefined","config: Partial<ProjectConfig>","diagnostics: StackGraphDiagnostic[]","issues: StackGraphIssue[]","primaryToolIdsByRole: Partial<Record<StackPrimaryRole, string>>","siblingToolIdsByRole: Partial<Record<StackPartRole, string>>"],"sources":["../src/stack-graph.ts"],"sourcesContent":["import type {\n Ecosystem,\n ProjectConfig,\n StackPart,\n StackPartEcosystem,\n StackPartRole,\n StackPartSource,\n} from \"./types\";\n\nimport {\n API_VALUES,\n AUTH_VALUES,\n BACKEND_VALUES,\n DATABASE_VALUES,\n ELIXIR_API_VALUES,\n ELIXIR_AUTH_VALUES,\n ELIXIR_CACHING_VALUES,\n ELIXIR_DEPLOY_VALUES,\n ELIXIR_EMAIL_VALUES,\n ELIXIR_JOBS_VALUES,\n ELIXIR_OBSERVABILITY_VALUES,\n ELIXIR_ORM_VALUES,\n ELIXIR_REALTIME_VALUES,\n ELIXIR_TESTING_VALUES,\n ELIXIR_VALIDATION_VALUES,\n ELIXIR_WEB_FRAMEWORK_VALUES,\n FRONTEND_VALUES,\n GO_API_VALUES,\n GO_AUTH_VALUES,\n GO_ORM_VALUES,\n GO_WEB_FRAMEWORK_VALUES,\n JAVA_AUTH_VALUES,\n JAVA_ORM_VALUES,\n JAVA_WEB_FRAMEWORK_VALUES,\n ORM_VALUES,\n PYTHON_API_VALUES,\n PYTHON_AUTH_VALUES,\n PYTHON_GRAPHQL_VALUES,\n PYTHON_ORM_VALUES,\n PYTHON_TASK_QUEUE_VALUES,\n PYTHON_VALIDATION_VALUES,\n PYTHON_WEB_FRAMEWORK_VALUES,\n RUST_API_VALUES,\n RUST_AUTH_VALUES,\n RUST_CACHING_VALUES,\n RUST_FRONTEND_VALUES,\n RUST_ORM_VALUES,\n RUST_WEB_FRAMEWORK_VALUES,\n StackPartRoleSchema,\n} from \"./schemas\";\n\nexport type StackPrimaryRole = Extract<\n StackPartRole,\n \"frontend\" | \"backend\" | \"mobile\" | \"database\"\n>;\n\nexport type ProvidedCapabilityDefinition = {\n role: StackPartRole;\n toolId: string;\n ecosystem?: StackPartEcosystem;\n overrideable?: boolean;\n};\n\nexport type ToolDefinition = {\n toolId: string;\n label?: string;\n roles: readonly StackPartRole[];\n ecosystems: readonly StackPartEcosystem[];\n legacyCategory?: keyof ProjectConfig;\n selectable?: boolean;\n provides?: readonly ProvidedCapabilityDefinition[];\n};\n\nexport type StackPartOptionContext = {\n role: StackPartRole;\n ecosystem?: StackPartEcosystem;\n ownerRole?: StackPrimaryRole;\n ownerToolId?: string;\n ownerEcosystem?: StackPartEcosystem;\n siblingToolIdsByRole?: Partial<Record<StackPartRole, string | undefined>>;\n primaryToolIdsByRole?: Partial<Record<StackPrimaryRole, string | undefined>>;\n};\n\nexport type StackGraphIssue = {\n code: string;\n message: string;\n partId?: string;\n role?: StackPartRole;\n toolId?: string;\n};\n\nexport type StackGraphValidationResult = {\n issues: StackGraphIssue[];\n};\n\nexport type StackGraphDiagnostic = {\n code: string;\n message: string;\n path?: string;\n};\n\nconst PRIMARY_ROLES = new Set<StackPartRole>([\"frontend\", \"backend\", \"mobile\", \"database\"]);\nconst NATIVE_FRONTENDS = new Set([\"native-bare\", \"native-uniwind\", \"native-unistyles\"]);\nconst WEB_FRONTENDS = FRONTEND_VALUES.filter(\n (value) => value !== \"none\" && !NATIVE_FRONTENDS.has(value),\n);\nconst DJANGO_API_TOOLS = new Set([\"django-rest-framework\", \"django-ninja\"]);\nconst JAVA_SPRING_CAPABILITY_TOOLS = new Set([\"spring-data-jpa\", \"spring-security\"]);\nconst TYPESCRIPT_TRPC_INCOMPATIBLE_FRONTENDS = new Set([\n \"nuxt\",\n \"svelte\",\n \"solid\",\n \"solid-start\",\n]);\nconst BETTER_AUTH_UNSUPPORTED_ORM_TOOLS = new Set([\"typeorm\", \"mikroorm\", \"sequelize\"]);\nconst ELIXIR_ECTO_REQUIRED_TOOLS = new Set([\"absinthe\", \"phx-gen-auth\"]);\nconst ELIXIR_ECTO_SQL_REQUIRED_TOOLS = new Set([\"oban\"]);\nconst ELIXIR_UNSUPPORTED_GRAPH_TOOLS = new Set([\n \"ecto\",\n \"ueberauth\",\n \"guardian\",\n \"nimble-options\",\n \"nebulex\",\n \"opentelemetry\",\n \"prom_ex\",\n \"mox\",\n \"bypass\",\n \"wallaby\",\n \"fly\",\n \"gigalixir\",\n]);\n\nconst ROLE_TARGET_PATHS: Record<StackPrimaryRole, string> = {\n frontend: \"apps/web\",\n backend: \"apps/server\",\n mobile: \"apps/native\",\n database: \"packages/database\",\n};\n\nfunction defineTools(\n values: readonly string[],\n role: StackPartRole,\n ecosystem: StackPartEcosystem,\n legacyCategory?: keyof ProjectConfig,\n): ToolDefinition[] {\n return values\n .filter((toolId) => toolId !== \"none\")\n .map((toolId) => ({\n toolId,\n roles: [role],\n ecosystems: [ecosystem],\n legacyCategory,\n }));\n}\n\nexport const STACK_TOOL_DEFINITIONS: readonly ToolDefinition[] = [\n ...defineTools(WEB_FRONTENDS, \"frontend\", \"typescript\", \"frontend\"),\n ...defineTools([...NATIVE_FRONTENDS], \"mobile\", \"react-native\", \"frontend\"),\n ...defineTools(\n BACKEND_VALUES.filter((value) => value !== \"convex\"),\n \"backend\",\n \"typescript\",\n \"backend\",\n ),\n ...defineTools(DATABASE_VALUES, \"database\", \"universal\", \"database\"),\n ...defineTools(DATABASE_VALUES, \"database\", \"typescript\", \"database\"),\n ...defineTools(ORM_VALUES, \"orm\", \"typescript\", \"orm\"),\n ...defineTools(API_VALUES, \"api\", \"typescript\", \"api\"),\n ...defineTools(AUTH_VALUES, \"auth\", \"typescript\", \"auth\"),\n ...defineTools(AUTH_VALUES, \"auth\", \"react-native\", \"auth\"),\n ...defineTools(RUST_WEB_FRAMEWORK_VALUES, \"backend\", \"rust\", \"rustWebFramework\"),\n ...defineTools(RUST_FRONTEND_VALUES, \"frontend\", \"rust\", \"rustFrontend\"),\n ...defineTools(RUST_ORM_VALUES, \"orm\", \"rust\", \"rustOrm\"),\n ...defineTools(RUST_API_VALUES, \"api\", \"rust\", \"rustApi\"),\n ...defineTools(RUST_AUTH_VALUES, \"auth\", \"rust\", \"rustAuth\"),\n ...defineTools(RUST_CACHING_VALUES, \"caching\", \"rust\", \"rustCaching\"),\n ...defineTools(PYTHON_WEB_FRAMEWORK_VALUES, \"backend\", \"python\", \"pythonWebFramework\"),\n ...defineTools(PYTHON_ORM_VALUES, \"orm\", \"python\", \"pythonOrm\"),\n ...defineTools(PYTHON_VALIDATION_VALUES, \"validation\", \"python\", \"pythonValidation\"),\n ...defineTools(PYTHON_API_VALUES, \"api\", \"python\", \"pythonApi\"),\n ...defineTools(PYTHON_AUTH_VALUES, \"auth\", \"python\", \"pythonAuth\"),\n ...defineTools(PYTHON_TASK_QUEUE_VALUES, \"jobQueue\", \"python\", \"pythonTaskQueue\"),\n ...defineTools(PYTHON_GRAPHQL_VALUES, \"api\", \"python\", \"pythonGraphql\"),\n ...defineTools(GO_WEB_FRAMEWORK_VALUES, \"backend\", \"go\", \"goWebFramework\"),\n ...defineTools(GO_ORM_VALUES, \"orm\", \"go\", \"goOrm\"),\n ...defineTools(GO_API_VALUES, \"api\", \"go\", \"goApi\"),\n ...defineTools(GO_AUTH_VALUES, \"auth\", \"go\", \"goAuth\"),\n ...defineTools(JAVA_WEB_FRAMEWORK_VALUES, \"backend\", \"java\", \"javaWebFramework\"),\n ...defineTools(JAVA_ORM_VALUES, \"orm\", \"java\", \"javaOrm\"),\n ...defineTools(JAVA_AUTH_VALUES, \"auth\", \"java\", \"javaAuth\"),\n ...defineTools(ELIXIR_WEB_FRAMEWORK_VALUES, \"backend\", \"elixir\", \"elixirWebFramework\"),\n ...defineTools(ELIXIR_ORM_VALUES, \"orm\", \"elixir\", \"elixirOrm\"),\n ...defineTools(ELIXIR_AUTH_VALUES, \"auth\", \"elixir\", \"elixirAuth\"),\n ...defineTools(ELIXIR_API_VALUES, \"api\", \"elixir\", \"elixirApi\"),\n ...defineTools(ELIXIR_REALTIME_VALUES, \"api\", \"elixir\", \"elixirRealtime\"),\n ...defineTools(ELIXIR_JOBS_VALUES, \"jobQueue\", \"elixir\", \"elixirJobs\"),\n ...defineTools(ELIXIR_VALIDATION_VALUES, \"validation\", \"elixir\", \"elixirValidation\"),\n ...defineTools(ELIXIR_EMAIL_VALUES, \"email\", \"elixir\", \"elixirEmail\"),\n ...defineTools(ELIXIR_CACHING_VALUES, \"caching\", \"elixir\", \"elixirCaching\"),\n ...defineTools(ELIXIR_OBSERVABILITY_VALUES, \"observability\", \"elixir\", \"elixirObservability\"),\n ...defineTools(ELIXIR_TESTING_VALUES, \"testing\", \"elixir\", \"elixirTesting\"),\n ...defineTools(ELIXIR_DEPLOY_VALUES, \"deploy\", \"elixir\", \"elixirDeploy\"),\n {\n toolId: \"convex\",\n roles: [\"backend\"],\n ecosystems: [\"typescript\"],\n legacyCategory: \"backend\",\n provides: [\n { role: \"database\", toolId: \"convex\", ecosystem: \"typescript\", overrideable: false },\n { role: \"api\", toolId: \"convex\", ecosystem: \"typescript\", overrideable: false },\n ],\n },\n {\n toolId: \"convex\",\n roles: [\"database\", \"api\"],\n ecosystems: [\"typescript\"],\n selectable: false,\n },\n];\n\nfunction sanitizePartId(input: string): string {\n return input\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9:._-]+/g, \"-\")\n .replace(/-+/g, \"-\")\n .replace(/^-|-$/g, \"\");\n}\n\nexport function getRoleTargetPath(role: StackPartRole): string | undefined {\n return PRIMARY_ROLES.has(role) ? ROLE_TARGET_PATHS[role as StackPrimaryRole] : undefined;\n}\n\nexport function createStackPart(input: {\n role: StackPartRole;\n toolId: string;\n ecosystem: StackPartEcosystem;\n ownerPartId?: string;\n source?: StackPartSource;\n providedByPartId?: string;\n id?: string;\n targetPath?: string;\n settings?: Record<string, unknown>;\n}): StackPart {\n const roleKey = input.ownerPartId ? `${input.ownerPartId}.${input.role}` : input.role;\n return {\n id: input.id ?? sanitizePartId(`${roleKey}:${input.ecosystem}:${input.toolId}`),\n role: input.role,\n toolId: input.toolId,\n ecosystem: input.ecosystem,\n ownerPartId: input.ownerPartId,\n source: input.source ?? \"selected\",\n providedByPartId: input.providedByPartId,\n targetPath: input.targetPath ?? getRoleTargetPath(input.role),\n settings: input.settings,\n };\n}\n\nfunction isNoneTool(toolId: string | undefined) {\n return !toolId || toolId === \"none\";\n}\n\nfunction allowsCrossEcosystemOwner(\n part: Pick<StackPart, \"role\" | \"ecosystem\">,\n context: StackPartOptionContext,\n) {\n if (part.ecosystem === \"universal\") return true;\n if (\n part.role === \"auth\" &&\n context.ownerRole === \"mobile\" &&\n part.ecosystem === \"react-native\"\n ) {\n return true;\n }\n return false;\n}\n\nfunction createStackGraphIssue(input: {\n code: string;\n message: string;\n partId?: string;\n role: StackPartRole;\n toolId: string;\n}): StackGraphIssue {\n return {\n code: input.code,\n message: input.message,\n partId: input.partId,\n role: input.role,\n toolId: input.toolId,\n };\n}\n\nfunction getStackPartCompatibilityIssue(\n part: Pick<StackPart, \"id\" | \"role\" | \"toolId\" | \"ecosystem\">,\n context: StackPartOptionContext,\n): StackGraphIssue | undefined {\n if (\n context.ownerEcosystem &&\n part.ecosystem !== context.ownerEcosystem &&\n !allowsCrossEcosystemOwner(part, context)\n ) {\n return createStackGraphIssue({\n code: \"INCOMPATIBLE_OWNER_ECOSYSTEM\",\n partId: part.id,\n role: part.role,\n toolId: part.toolId,\n message: `'${part.toolId}' uses the ${part.ecosystem} adapter but its owner uses ${context.ownerEcosystem}.`,\n });\n }\n\n if (part.ecosystem === \"python\" && part.role === \"api\" && DJANGO_API_TOOLS.has(part.toolId)) {\n if (context.ownerToolId !== \"django\") {\n return createStackGraphIssue({\n code: \"INCOMPATIBLE_OWNER_TOOL\",\n partId: part.id,\n role: part.role,\n toolId: part.toolId,\n message: `'${part.toolId}' can only be selected for a Django backend.`,\n });\n }\n }\n\n if (\n part.ecosystem === \"java\" &&\n (part.role === \"orm\" || part.role === \"auth\") &&\n JAVA_SPRING_CAPABILITY_TOOLS.has(part.toolId)\n ) {\n if (context.ownerToolId !== \"spring-boot\") {\n return createStackGraphIssue({\n code: \"INCOMPATIBLE_OWNER_TOOL\",\n partId: part.id,\n role: part.role,\n toolId: part.toolId,\n message: `'${part.toolId}' can only be selected for a Spring Boot backend.`,\n });\n }\n }\n\n if (part.ecosystem === \"typescript\" && part.role === \"api\" && part.toolId === \"trpc\") {\n const frontendTool = context.primaryToolIdsByRole?.frontend;\n if (frontendTool && TYPESCRIPT_TRPC_INCOMPATIBLE_FRONTENDS.has(frontendTool)) {\n return createStackGraphIssue({\n code: \"INCOMPATIBLE_GRAPH_SELECTION\",\n partId: part.id,\n role: part.role,\n toolId: part.toolId,\n message: `'trpc' cannot be selected with the '${frontendTool}' frontend.`,\n });\n }\n }\n\n if (part.ecosystem === \"typescript\" && part.role === \"auth\" && part.toolId === \"better-auth\") {\n const databaseTool = context.primaryToolIdsByRole?.database;\n if (databaseTool === \"redis\") {\n return createStackGraphIssue({\n code: \"INCOMPATIBLE_GRAPH_SELECTION\",\n partId: part.id,\n role: part.role,\n toolId: part.toolId,\n message: \"'better-auth' cannot use Redis as the primary database.\",\n });\n }\n\n const ormTool = context.siblingToolIdsByRole?.orm;\n if (ormTool && BETTER_AUTH_UNSUPPORTED_ORM_TOOLS.has(ormTool)) {\n return createStackGraphIssue({\n code: \"INCOMPATIBLE_GRAPH_SELECTION\",\n partId: part.id,\n role: part.role,\n toolId: part.toolId,\n message: `'better-auth' is not compatible with the '${ormTool}' ORM selection.`,\n });\n }\n }\n\n if (\n part.ecosystem === \"elixir\" &&\n ELIXIR_ECTO_REQUIRED_TOOLS.has(part.toolId) &&\n (part.role === \"api\" || part.role === \"auth\")\n ) {\n const ormTool = context.siblingToolIdsByRole?.orm;\n if (isNoneTool(ormTool)) {\n return createStackGraphIssue({\n code: \"INCOMPATIBLE_GRAPH_SELECTION\",\n partId: part.id,\n role: part.role,\n toolId: part.toolId,\n message: `'${part.toolId}' requires an Ecto database layer.`,\n });\n }\n }\n\n if (part.ecosystem === \"elixir\" && ELIXIR_ECTO_SQL_REQUIRED_TOOLS.has(part.toolId)) {\n const ormTool = context.siblingToolIdsByRole?.orm;\n if (ormTool !== \"ecto-sql\") {\n return createStackGraphIssue({\n code: \"INCOMPATIBLE_GRAPH_SELECTION\",\n partId: part.id,\n role: part.role,\n toolId: part.toolId,\n message: `'${part.toolId}' requires the Ecto SQL database layer.`,\n });\n }\n }\n\n if (part.ecosystem === \"elixir\" && part.toolId === \"live-view-streams\") {\n if (context.ownerToolId !== \"phoenix-live-view\") {\n return createStackGraphIssue({\n code: \"INCOMPATIBLE_OWNER_TOOL\",\n partId: part.id,\n role: part.role,\n toolId: part.toolId,\n message: \"'live-view-streams' can only be selected for a Phoenix LiveView backend.\",\n });\n }\n }\n\n if (part.ecosystem === \"elixir\" && ELIXIR_UNSUPPORTED_GRAPH_TOOLS.has(part.toolId)) {\n return createStackGraphIssue({\n code: \"UNSUPPORTED_GRAPH_TOOL\",\n partId: part.id,\n role: part.role,\n toolId: part.toolId,\n message: `'${part.toolId}' is not generated by the current Elixir scaffold.`,\n });\n }\n\n return undefined;\n}\n\nexport function getStackToolDefinitions(context?: StackPartOptionContext): ToolDefinition[] {\n if (!context) return [...STACK_TOOL_DEFINITIONS];\n return STACK_TOOL_DEFINITIONS.filter((definition) => {\n if (!definition.roles.includes(context.role)) return false;\n if (context.ecosystem && !definition.ecosystems.includes(context.ecosystem)) return false;\n if (definition.selectable === false) return false;\n const ecosystem = context.ecosystem ?? definition.ecosystems[0];\n if (\n getStackPartCompatibilityIssue(\n {\n id: `${context.ownerRole ?? \"root\"}:${context.role}:${definition.toolId}`,\n role: context.role,\n toolId: definition.toolId,\n ecosystem,\n },\n context,\n )\n ) {\n return false;\n }\n return true;\n });\n}\n\nexport function getStackPartOptions(context: StackPartOptionContext): string[] {\n return [...new Set(getStackToolDefinitions(context).map((definition) => definition.toolId))];\n}\n\nfunction findDefinition(part: Pick<StackPart, \"role\" | \"toolId\" | \"ecosystem\">) {\n return STACK_TOOL_DEFINITIONS.find(\n (definition) =>\n definition.toolId === part.toolId &&\n definition.roles.includes(part.role) &&\n definition.ecosystems.includes(part.ecosystem),\n );\n}\n\nfunction parseRolePath(rolePath: string): { role: StackPartRole; ownerRole?: StackPrimaryRole } {\n const segments = rolePath.split(\".\");\n const rawRole = segments.length === 1 ? segments[0] : segments[segments.length - 1];\n const rawOwnerRole = segments.length > 1 ? segments[0] : undefined;\n const role = StackPartRoleSchema.parse(rawRole);\n const ownerRole = rawOwnerRole ? StackPartRoleSchema.parse(rawOwnerRole) : undefined;\n\n if (ownerRole && !PRIMARY_ROLES.has(ownerRole)) {\n throw new Error(`Stack part owner role '${ownerRole}' must be a primary role.`);\n }\n\n return { role, ownerRole: ownerRole as StackPrimaryRole | undefined };\n}\n\nexport function parseStackPartSpecs(\n specs: readonly string[],\n source: StackPartSource = \"selected\",\n): StackPart[] {\n const unresolved = specs.map((spec) => {\n const [rolePath, ecosystem, toolId, customId] = spec.split(\":\");\n if (!rolePath || !ecosystem || !toolId || spec.split(\":\").length > 4) {\n throw new Error(\n `Invalid --part '${spec}'. Use role:ecosystem:tool or owner.role:ecosystem:tool.`,\n );\n }\n const { role, ownerRole } = parseRolePath(rolePath);\n return {\n role,\n ownerRole,\n ecosystem: ecosystem as StackPartEcosystem,\n toolId,\n customId,\n };\n });\n\n const primaryParts = unresolved\n .filter((part) => !part.ownerRole)\n .map((part) =>\n createStackPart({\n role: part.role,\n ecosystem: part.ecosystem,\n toolId: part.toolId,\n source,\n id: part.customId,\n }),\n );\n\n const primaryByRole = new Map(primaryParts.map((part) => [part.role, part]));\n const scopedParts = unresolved\n .filter(\n (part): part is typeof part & { ownerRole: StackPrimaryRole } =>\n part.ownerRole !== undefined,\n )\n .map((part) =>\n createStackPart({\n role: part.role,\n ecosystem: part.ecosystem,\n toolId: part.toolId,\n ownerPartId: primaryByRole.get(part.ownerRole)?.id,\n source,\n id: part.customId,\n }),\n );\n\n return materializeProvidedStackParts([...primaryParts, ...scopedParts]);\n}\n\nexport function formatStackPartSpec(part: StackPart, parts: readonly StackPart[] = []): string {\n const owner = part.ownerPartId\n ? parts.find((candidate) => candidate.id === part.ownerPartId)\n : undefined;\n const rolePath = owner ? `${owner.role}.${part.role}` : part.role;\n return `${rolePath}:${part.ecosystem}:${part.toolId}`;\n}\n\nexport function materializeProvidedStackParts(parts: readonly StackPart[]): StackPart[] {\n const next = [...parts];\n\n for (const part of parts) {\n const definition = findDefinition(part);\n for (const provided of definition?.provides ?? []) {\n next.push(\n createStackPart({\n role: provided.role,\n toolId: provided.toolId,\n ecosystem: provided.ecosystem ?? part.ecosystem,\n ownerPartId: part.id,\n source: \"provided\",\n providedByPartId: part.id,\n }),\n );\n }\n }\n\n return next;\n}\n\nfunction getPrimaryPart(parts: readonly StackPart[], role: StackPrimaryRole) {\n return parts.find((part) => part.role === role && !part.ownerPartId);\n}\n\nfunction addLegacyPart(\n parts: StackPart[],\n role: StackPartRole,\n ecosystem: StackPartEcosystem,\n toolId: string | undefined,\n source: StackPartSource,\n ownerPartId?: string,\n) {\n if (!toolId || toolId === \"none\") return undefined;\n const part = createStackPart({ role, ecosystem, toolId, source, ownerPartId });\n parts.push(part);\n return part;\n}\n\nexport function legacyProjectConfigToStackParts(\n config: Partial<ProjectConfig>,\n source: StackPartSource = \"legacy\",\n): StackPart[] {\n const parts: StackPart[] = [];\n const frontends = config.frontend ?? [];\n const webFrontends = frontends.filter(\n (frontend) => frontend !== \"none\" && !NATIVE_FRONTENDS.has(frontend),\n );\n const nativeFrontends = frontends.filter((frontend) => NATIVE_FRONTENDS.has(frontend));\n\n if (webFrontends.length > 1) {\n throw new Error(\"Multiple primary web frontends are not supported in the stack graph.\");\n }\n if (nativeFrontends.length > 1) {\n throw new Error(\"Multiple primary mobile frontends are not supported in the stack graph.\");\n }\n\n const webFrontend = webFrontends[0];\n const nativeFrontend = nativeFrontends[0];\n const frontendPart = addLegacyPart(parts, \"frontend\", \"typescript\", webFrontend, source);\n addLegacyPart(parts, \"mobile\", \"react-native\", nativeFrontend, source);\n\n let backendPart: StackPart | undefined;\n if (\n (config.ecosystem === undefined || config.ecosystem === \"typescript\") &&\n config.backend &&\n config.backend !== \"none\"\n ) {\n backendPart = addLegacyPart(parts, \"backend\", \"typescript\", config.backend, source);\n }\n\n if (\n config.ecosystem === \"rust\" &&\n config.rustWebFramework &&\n config.rustWebFramework !== \"none\"\n ) {\n backendPart = addLegacyPart(parts, \"backend\", \"rust\", config.rustWebFramework, source);\n }\n if (config.ecosystem === \"rust\" && config.rustFrontend && config.rustFrontend !== \"none\") {\n addLegacyPart(parts, \"frontend\", \"rust\", config.rustFrontend, source);\n }\n if (\n config.ecosystem === \"python\" &&\n config.pythonWebFramework &&\n config.pythonWebFramework !== \"none\"\n ) {\n backendPart = addLegacyPart(parts, \"backend\", \"python\", config.pythonWebFramework, source);\n }\n if (config.ecosystem === \"go\" && config.goWebFramework && config.goWebFramework !== \"none\") {\n backendPart = addLegacyPart(parts, \"backend\", \"go\", config.goWebFramework, source);\n }\n if (\n config.ecosystem === \"java\" &&\n config.javaWebFramework &&\n config.javaWebFramework !== \"none\"\n ) {\n backendPart = addLegacyPart(parts, \"backend\", \"java\", config.javaWebFramework, source);\n }\n if (\n config.ecosystem === \"elixir\" &&\n config.elixirWebFramework &&\n config.elixirWebFramework !== \"none\"\n ) {\n backendPart = addLegacyPart(parts, \"backend\", \"elixir\", config.elixirWebFramework, source);\n }\n\n const databasePart = addLegacyPart(parts, \"database\", \"universal\", config.database, source);\n const capabilityOwner = backendPart?.id ?? frontendPart?.id ?? databasePart?.id;\n\n // The generic `orm`/`api`/`auth` fields only describe TypeScript and React Native\n // stacks. For other ecosystems these are inert TS defaults and the ecosystem-specific\n // blocks below own the real bindings — mapping the generic fields there would emit\n // invalid or duplicate capability parts (e.g. `auth:go:better-auth` alongside `goAuth`).\n if (\n config.ecosystem === undefined ||\n config.ecosystem === \"typescript\" ||\n config.ecosystem === \"react-native\"\n ) {\n addLegacyPart(parts, \"orm\", \"typescript\", config.orm, source, capabilityOwner);\n addLegacyPart(parts, \"api\", \"typescript\", config.api, source, capabilityOwner);\n addLegacyPart(\n parts,\n \"auth\",\n config.ecosystem ?? \"typescript\",\n config.auth,\n source,\n capabilityOwner,\n );\n }\n if (config.ecosystem === \"rust\") {\n addLegacyPart(parts, \"orm\", \"rust\", config.rustOrm, source, backendPart?.id);\n addLegacyPart(parts, \"api\", \"rust\", config.rustApi, source, backendPart?.id);\n addLegacyPart(parts, \"auth\", \"rust\", config.rustAuth, source, backendPart?.id);\n }\n if (config.ecosystem === \"python\") {\n addLegacyPart(parts, \"orm\", \"python\", config.pythonOrm, source, backendPart?.id);\n addLegacyPart(parts, \"api\", \"python\", config.pythonApi, source, backendPart?.id);\n addLegacyPart(parts, \"auth\", \"python\", config.pythonAuth, source, backendPart?.id);\n }\n if (config.ecosystem === \"go\") {\n addLegacyPart(parts, \"orm\", \"go\", config.goOrm, source, backendPart?.id);\n addLegacyPart(parts, \"api\", \"go\", config.goApi, source, backendPart?.id);\n addLegacyPart(parts, \"auth\", \"go\", config.goAuth, source, backendPart?.id);\n }\n if (config.ecosystem === \"java\") {\n addLegacyPart(parts, \"orm\", \"java\", config.javaOrm, source, backendPart?.id);\n addLegacyPart(parts, \"auth\", \"java\", config.javaAuth, source, backendPart?.id);\n }\n if (config.ecosystem === \"elixir\") {\n addLegacyPart(parts, \"orm\", \"elixir\", config.elixirOrm, source, backendPart?.id);\n addLegacyPart(parts, \"api\", \"elixir\", config.elixirApi, source, backendPart?.id);\n addLegacyPart(parts, \"auth\", \"elixir\", config.elixirAuth, source, backendPart?.id);\n }\n\n return materializeProvidedStackParts(parts);\n}\n\nfunction ecosystemForLegacy(parts: readonly StackPart[]): Ecosystem {\n const frontend = getPrimaryPart(parts, \"frontend\");\n if (frontend?.ecosystem && frontend.ecosystem !== \"universal\") return frontend.ecosystem;\n const mobile = getPrimaryPart(parts, \"mobile\");\n if (mobile) return \"react-native\";\n const backend = getPrimaryPart(parts, \"backend\");\n if (backend?.ecosystem && backend.ecosystem !== \"universal\") return backend.ecosystem;\n return \"typescript\";\n}\n\nexport function stackPartsToLegacyProjectConfigPartial(\n parts: readonly StackPart[],\n): Partial<ProjectConfig> {\n const config: Partial<ProjectConfig> = {\n stackParts: [...parts],\n ecosystem: ecosystemForLegacy(parts),\n frontend: [],\n backend: \"none\",\n database: \"none\",\n orm: \"none\",\n api: \"none\",\n auth: \"none\",\n };\n\n for (const part of parts) {\n if (part.source === \"provided\") continue;\n if (!part.ownerPartId) {\n if (part.role === \"frontend\" && part.ecosystem === \"typescript\") {\n config.frontend = [\n ...(config.frontend ?? []),\n part.toolId as ProjectConfig[\"frontend\"][number],\n ];\n } else if (part.role === \"frontend\" && part.ecosystem === \"rust\") {\n config.rustFrontend = part.toolId as ProjectConfig[\"rustFrontend\"];\n } else if (part.role === \"mobile\") {\n config.frontend = [\n ...(config.frontend ?? []),\n part.toolId as ProjectConfig[\"frontend\"][number],\n ];\n } else if (part.role === \"backend\") {\n if (part.ecosystem === \"typescript\")\n config.backend = part.toolId as ProjectConfig[\"backend\"];\n if (part.ecosystem === \"rust\")\n config.rustWebFramework = part.toolId as ProjectConfig[\"rustWebFramework\"];\n if (part.ecosystem === \"python\")\n config.pythonWebFramework = part.toolId as ProjectConfig[\"pythonWebFramework\"];\n if (part.ecosystem === \"go\")\n config.goWebFramework = part.toolId as ProjectConfig[\"goWebFramework\"];\n if (part.ecosystem === \"java\")\n config.javaWebFramework = part.toolId as ProjectConfig[\"javaWebFramework\"];\n if (part.ecosystem === \"elixir\")\n config.elixirWebFramework = part.toolId as ProjectConfig[\"elixirWebFramework\"];\n } else if (part.role === \"database\") {\n config.database = part.toolId as ProjectConfig[\"database\"];\n }\n continue;\n }\n\n const definition = findDefinition(part);\n if (definition?.legacyCategory) {\n (config as Record<string, unknown>)[definition.legacyCategory] = part.toolId;\n continue;\n }\n\n if (part.role === \"orm\") {\n if (part.ecosystem === \"typescript\") config.orm = part.toolId as ProjectConfig[\"orm\"];\n if (part.ecosystem === \"rust\") config.rustOrm = part.toolId as ProjectConfig[\"rustOrm\"];\n if (part.ecosystem === \"python\") config.pythonOrm = part.toolId as ProjectConfig[\"pythonOrm\"];\n if (part.ecosystem === \"go\") config.goOrm = part.toolId as ProjectConfig[\"goOrm\"];\n if (part.ecosystem === \"java\") config.javaOrm = part.toolId as ProjectConfig[\"javaOrm\"];\n if (part.ecosystem === \"elixir\") config.elixirOrm = part.toolId as ProjectConfig[\"elixirOrm\"];\n }\n if (part.role === \"api\") {\n if (part.ecosystem === \"typescript\") config.api = part.toolId as ProjectConfig[\"api\"];\n if (part.ecosystem === \"rust\") config.rustApi = part.toolId as ProjectConfig[\"rustApi\"];\n if (part.ecosystem === \"python\") config.pythonApi = part.toolId as ProjectConfig[\"pythonApi\"];\n if (part.ecosystem === \"go\") config.goApi = part.toolId as ProjectConfig[\"goApi\"];\n if (part.ecosystem === \"elixir\") config.elixirApi = part.toolId as ProjectConfig[\"elixirApi\"];\n }\n if (part.role === \"auth\") {\n if (part.ecosystem === \"typescript\" || part.ecosystem === \"react-native\") {\n config.auth = part.toolId as ProjectConfig[\"auth\"];\n }\n if (part.ecosystem === \"rust\") config.rustAuth = part.toolId as ProjectConfig[\"rustAuth\"];\n if (part.ecosystem === \"python\")\n config.pythonAuth = part.toolId as ProjectConfig[\"pythonAuth\"];\n if (part.ecosystem === \"go\") config.goAuth = part.toolId as ProjectConfig[\"goAuth\"];\n if (part.ecosystem === \"java\") config.javaAuth = part.toolId as ProjectConfig[\"javaAuth\"];\n if (part.ecosystem === \"elixir\")\n config.elixirAuth = part.toolId as ProjectConfig[\"elixirAuth\"];\n }\n }\n\n return config;\n}\n\nexport function compareLegacyConfigToStackParts(\n config: Partial<ProjectConfig>,\n stackParts: readonly StackPart[],\n): StackGraphDiagnostic[] {\n const derived = stackPartsToLegacyProjectConfigPartial(stackParts);\n const diagnostics: StackGraphDiagnostic[] = [];\n for (const key of [\n \"ecosystem\",\n \"frontend\",\n \"backend\",\n \"database\",\n \"orm\",\n \"api\",\n \"auth\",\n \"rustWebFramework\",\n \"pythonWebFramework\",\n \"goWebFramework\",\n \"javaWebFramework\",\n \"elixirWebFramework\",\n ] as const) {\n const current = config[key];\n const next = derived[key];\n if (current === undefined || next === undefined) continue;\n if (JSON.stringify(current) !== JSON.stringify(next)) {\n diagnostics.push({\n code: \"LEGACY_CONFIG_MISMATCH\",\n path: key,\n message: `Legacy field '${key}' differs from stackParts and will be derived from the graph.`,\n });\n }\n }\n return diagnostics;\n}\n\nexport function validateStackParts(parts: readonly StackPart[]): StackGraphValidationResult {\n const issues: StackGraphIssue[] = [];\n const partsById = new Map(parts.map((part) => [part.id, part]));\n const primaryToolIdsByRole: Partial<Record<StackPrimaryRole, string>> = {};\n\n for (const role of PRIMARY_ROLES) {\n const primaryPart = getPrimaryPart(parts, role as StackPrimaryRole);\n if (primaryPart) primaryToolIdsByRole[role as StackPrimaryRole] = primaryPart.toolId;\n }\n\n for (const role of PRIMARY_ROLES) {\n const matching = parts.filter((part) => part.role === role && !part.ownerPartId);\n if (matching.length > 1) {\n issues.push({\n code: \"DUPLICATE_PRIMARY_ROLE\",\n role,\n message: `Only one primary '${role}' stack part is supported in v1.`,\n });\n }\n }\n\n for (const part of parts) {\n const definition = findDefinition(part);\n if (!definition) {\n issues.push({\n code: \"UNSUPPORTED_ROLE_BINDING\",\n partId: part.id,\n role: part.role,\n toolId: part.toolId,\n message: `'${part.toolId}' is not a valid ${part.ecosystem} tool for role '${part.role}'.`,\n });\n }\n\n if (!PRIMARY_ROLES.has(part.role) && !part.ownerPartId) {\n issues.push({\n code: \"MISSING_OWNER_PART\",\n partId: part.id,\n role: part.role,\n toolId: part.toolId,\n message: `Capability stack part '${part.id}' must reference an owning primary part.`,\n });\n }\n\n if (part.ownerPartId && !partsById.has(part.ownerPartId)) {\n issues.push({\n code: \"MISSING_OWNER_PART\",\n partId: part.id,\n role: part.role,\n toolId: part.toolId,\n message: `Stack part '${part.id}' references missing owner '${part.ownerPartId}'.`,\n });\n }\n\n const owner = part.ownerPartId ? partsById.get(part.ownerPartId) : undefined;\n if (definition && (PRIMARY_ROLES.has(part.role) || owner)) {\n const siblingToolIdsByRole: Partial<Record<StackPartRole, string>> = {};\n for (const sibling of parts) {\n if (sibling.ownerPartId !== part.ownerPartId || sibling.source === \"provided\") continue;\n siblingToolIdsByRole[sibling.role] = sibling.toolId;\n }\n\n const compatibilityIssue = getStackPartCompatibilityIssue(part, {\n role: part.role,\n ecosystem: part.ecosystem,\n ownerRole:\n owner && PRIMARY_ROLES.has(owner.role) ? (owner.role as StackPrimaryRole) : undefined,\n ownerToolId: owner?.toolId,\n ownerEcosystem: owner?.ecosystem,\n siblingToolIdsByRole,\n primaryToolIdsByRole,\n });\n\n if (compatibilityIssue) {\n issues.push(compatibilityIssue);\n }\n }\n }\n\n const byScope = new Map<string, StackPart[]>();\n for (const part of parts) {\n const key = `${part.ownerPartId ?? \"root\"}:${part.role}`;\n byScope.set(key, [...(byScope.get(key) ?? []), part]);\n }\n\n for (const scopedParts of byScope.values()) {\n const selectedParts = scopedParts.filter((part) => part.source !== \"provided\");\n if (selectedParts.length > 1) {\n const [first] = selectedParts;\n issues.push({\n code: \"DUPLICATE_ROLE_SCOPE\",\n partId: first?.id,\n role: first?.role,\n toolId: first?.toolId,\n message: `Only one selected '${first?.role}' stack part is supported per owner scope.`,\n });\n }\n\n const selected = scopedParts.find((part) => part.source !== \"provided\");\n const provided = scopedParts.find((part) => part.source === \"provided\");\n if (!selected || !provided || selected.toolId === provided.toolId) continue;\n\n const provider = provided.providedByPartId\n ? partsById.get(provided.providedByPartId)\n : undefined;\n const providerDefinition = provider ? findDefinition(provider) : undefined;\n const providedDefinition = providerDefinition?.provides?.find(\n (capability) => capability.role === provided.role && capability.toolId === provided.toolId,\n );\n\n if (!providedDefinition?.overrideable) {\n issues.push({\n code: \"PROVIDED_CAPABILITY_CONFLICT\",\n partId: selected.id,\n role: selected.role,\n toolId: selected.toolId,\n message: `'${selected.toolId}' conflicts with '${provided.toolId}' provided by '${provider?.toolId ?? \"another part\"}'.`,\n });\n }\n }\n\n return { issues };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { $t as StackPartRole, Qt as StackPartEcosystem, Zt as StackPart, en as StackPartSource, yt as ProjectConfig } from "./types-CWpfWGSN.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/stack-graph.d.ts
|
|
4
|
+
type StackPrimaryRole = Extract<StackPartRole, "frontend" | "backend" | "mobile" | "database">;
|
|
5
|
+
type ProvidedCapabilityDefinition = {
|
|
6
|
+
role: StackPartRole;
|
|
7
|
+
toolId: string;
|
|
8
|
+
ecosystem?: StackPartEcosystem;
|
|
9
|
+
overrideable?: boolean;
|
|
10
|
+
};
|
|
11
|
+
type ToolDefinition = {
|
|
12
|
+
toolId: string;
|
|
13
|
+
label?: string;
|
|
14
|
+
roles: readonly StackPartRole[];
|
|
15
|
+
ecosystems: readonly StackPartEcosystem[];
|
|
16
|
+
legacyCategory?: keyof ProjectConfig;
|
|
17
|
+
selectable?: boolean;
|
|
18
|
+
provides?: readonly ProvidedCapabilityDefinition[];
|
|
19
|
+
};
|
|
20
|
+
type StackPartOptionContext = {
|
|
21
|
+
role: StackPartRole;
|
|
22
|
+
ecosystem?: StackPartEcosystem;
|
|
23
|
+
ownerRole?: StackPrimaryRole;
|
|
24
|
+
ownerToolId?: string;
|
|
25
|
+
ownerEcosystem?: StackPartEcosystem;
|
|
26
|
+
siblingToolIdsByRole?: Partial<Record<StackPartRole, string | undefined>>;
|
|
27
|
+
primaryToolIdsByRole?: Partial<Record<StackPrimaryRole, string | undefined>>;
|
|
28
|
+
};
|
|
29
|
+
type StackGraphIssue = {
|
|
30
|
+
code: string;
|
|
31
|
+
message: string;
|
|
32
|
+
partId?: string;
|
|
33
|
+
role?: StackPartRole;
|
|
34
|
+
toolId?: string;
|
|
35
|
+
};
|
|
36
|
+
type StackGraphValidationResult = {
|
|
37
|
+
issues: StackGraphIssue[];
|
|
38
|
+
};
|
|
39
|
+
type StackGraphDiagnostic = {
|
|
40
|
+
code: string;
|
|
41
|
+
message: string;
|
|
42
|
+
path?: string;
|
|
43
|
+
};
|
|
44
|
+
declare const STACK_TOOL_DEFINITIONS: readonly ToolDefinition[];
|
|
45
|
+
declare function getRoleTargetPath(role: StackPartRole): string | undefined;
|
|
46
|
+
declare function createStackPart(input: {
|
|
47
|
+
role: StackPartRole;
|
|
48
|
+
toolId: string;
|
|
49
|
+
ecosystem: StackPartEcosystem;
|
|
50
|
+
ownerPartId?: string;
|
|
51
|
+
source?: StackPartSource;
|
|
52
|
+
providedByPartId?: string;
|
|
53
|
+
id?: string;
|
|
54
|
+
targetPath?: string;
|
|
55
|
+
settings?: Record<string, unknown>;
|
|
56
|
+
}): StackPart;
|
|
57
|
+
declare function getStackToolDefinitions(context?: StackPartOptionContext): ToolDefinition[];
|
|
58
|
+
declare function getStackPartOptions(context: StackPartOptionContext): string[];
|
|
59
|
+
declare function parseStackPartSpecs(specs: readonly string[], source?: StackPartSource): StackPart[];
|
|
60
|
+
declare function formatStackPartSpec(part: StackPart, parts?: readonly StackPart[]): string;
|
|
61
|
+
declare function materializeProvidedStackParts(parts: readonly StackPart[]): StackPart[];
|
|
62
|
+
declare function legacyProjectConfigToStackParts(config: Partial<ProjectConfig>, source?: StackPartSource): StackPart[];
|
|
63
|
+
declare function stackPartsToLegacyProjectConfigPartial(parts: readonly StackPart[]): Partial<ProjectConfig>;
|
|
64
|
+
declare function compareLegacyConfigToStackParts(config: Partial<ProjectConfig>, stackParts: readonly StackPart[]): StackGraphDiagnostic[];
|
|
65
|
+
declare function validateStackParts(parts: readonly StackPart[]): StackGraphValidationResult;
|
|
66
|
+
//#endregion
|
|
67
|
+
export { parseStackPartSpecs as _, StackGraphValidationResult as a, ToolDefinition as c, formatStackPartSpec as d, getRoleTargetPath as f, materializeProvidedStackParts as g, legacyProjectConfigToStackParts as h, StackGraphIssue as i, compareLegacyConfigToStackParts as l, getStackToolDefinitions as m, STACK_TOOL_DEFINITIONS as n, StackPartOptionContext as o, getStackPartOptions as p, StackGraphDiagnostic as r, StackPrimaryRole as s, ProvidedCapabilityDefinition as t, createStackPart as u, stackPartsToLegacyProjectConfigPartial as v, validateStackParts as y };
|
|
68
|
+
//# sourceMappingURL=stack-graph-UgPd4sup.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stack-graph-UgPd4sup.d.mts","names":[],"sources":["../src/stack-graph.ts"],"sourcesContent":[],"mappings":";;;KAmDY,gBAAA,GAAmB,QAC7B;KAIU,4BAAA;EALA,IAAA,EAMJ,aANoB;EAKhB,MAAA,EAAA,MAAA;EAOA,SAAA,CAAA,EAJE,kBAIY;EAGR,YAAA,CAAA,EAAA,OAAA;CACK;AACE,KALb,cAAA,GAKa;EAEH,MAAA,EAAA,MAAA;EAA4B,KAAA,CAAA,EAAA,MAAA;EAGtC,KAAA,EAAA,SAPM,aAOgB,EAAA;EAC1B,UAAA,EAAA,SAPe,kBAOf,EAAA;EACM,cAAA,CAAA,EAAA,MAPW,aAOX;EACA,UAAA,CAAA,EAAA,OAAA;EAEK,QAAA,CAAA,EAAA,SARG,4BAQH,EAAA;CACqB;AAAP,KANrB,sBAAA,GAMqB;EAAR,IAAA,EALjB,aAKiB;EACe,SAAA,CAAA,EAL1B,kBAK0B;EAAP,SAAA,CAAA,EAJnB,gBAImB;EAAR,WAAA,CAAA,EAAA,MAAA;EAAO,cAAA,CAAA,EAFb,kBAEa;EAGpB,oBAAe,CAAA,EAJF,OAIE,CAJM,MAQxB,CAR+B,aAQlB,EAAA,MAAA,GAAA,SAAA,CAAA,CAAA;EAIV,oBAAA,CAAA,EAXa,OAWa,CAXL,MAWK,CAXE,gBAY9B,EAAA,MAAe,GAAA,SAAA,CAAA,CAAA;AAGzB,CAAA;AA4Da,KAxED,eAAA,GAuIX;EAWe,IAAA,EAAA,MAAA;EAIA,OAAA,EAAA,MAAA;EACR,MAAA,CAAA,EAAA,MAAA;EAEK,IAAA,CAAA,EArJJ,aAqJI;EAEF,MAAA,CAAA,EAAA,MAAA;CAIE;AACT,KAxJQ,0BAAA,GAwJR;EAAS,MAAA,EAvJH,eAuJG,EAAA;AA4Lb,CAAA;AAwBgB,KAxWJ,oBAAA,GAwWuB;EA2BnB,IAAA,EAAA,MAAA;EAqDA,OAAA,EAAA,MAAA;EAQA,IAAA,CAAA,EAAA,MAAA;AAwChB,CAAA;AACkB,cA7aL,sBA6aK,EAAA,SA7a4B,cA6a5B,EAAA;AAAR,iBAnWM,iBAAA,CAmWN,IAAA,EAnW8B,aAmW9B,CAAA,EAAA,MAAA,GAAA,SAAA;AACA,iBAhWM,eAAA,CAgWN,KAAA,EAAA;EACP,IAAA,EAhWK,aAgWL;EAAS,MAAA,EAAA,MAAA;EA6HI,SAAA,EA3dH,kBA2dG;EACE,WAAA,CAAA,EAAA,MAAA;EACP,MAAA,CAAA,EA3dA,eA2dA;EAAR,gBAAA,CAAA,EAAA,MAAA;EAAO,EAAA,CAAA,EAAA,MAAA;EAoFM,UAAA,CAAA,EAAA,MAAA;EACE,QAAA,CAAA,EA5iBL,MA4iBK,CAAA,MAAA,EAAA,OAAA,CAAA;CAAR,CAAA,EA3iBN,SA2iBM;AACa,iBAhXP,uBAAA,CAgXO,OAAA,CAAA,EAhX2B,sBAgX3B,CAAA,EAhXoD,cAgXpD,EAAA;AACpB,iBAzVa,mBAAA,CAyVb,OAAA,EAzV0C,sBAyV1C,CAAA,EAAA,MAAA,EAAA;AAAoB,iBA9TP,mBAAA,CA8TO,KAAA,EAAA,SAAA,MAAA,EAAA,EAAA,MAAA,CAAA,EA5Tb,eA4Ta,CAAA,EA3TpB,SA2ToB,EAAA;AA+BP,iBAxSA,mBAAA,CAwSmC,IAAA,EAxST,SAwSuB,EAAA,KAA0B,CAA1B,EAAA,SAxSI,SAwSsB,EAAA,CAAA,EAAA,MAAA;iBAhS3E,6BAAA,iBAA8C,cAAc;iBAwC5D,+BAAA,SACN,QAAQ,yBACR,kBACP;iBA6Ha,sCAAA,iBACE,cACf,QAAQ;iBAoFK,+BAAA,SACN,QAAQ,qCACK,cACpB;iBA+Ba,kBAAA,iBAAmC,cAAc"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import "./schemas-62dqb8iS.mjs";
|
|
2
|
+
import "./types-CWpfWGSN.mjs";
|
|
3
|
+
import { _ as parseStackPartSpecs, a as StackGraphValidationResult, c as ToolDefinition, d as formatStackPartSpec, f as getRoleTargetPath, g as materializeProvidedStackParts, h as legacyProjectConfigToStackParts, i as StackGraphIssue, l as compareLegacyConfigToStackParts, m as getStackToolDefinitions, n as STACK_TOOL_DEFINITIONS, o as StackPartOptionContext, p as getStackPartOptions, r as StackGraphDiagnostic, s as StackPrimaryRole, t as ProvidedCapabilityDefinition, u as createStackPart, v as stackPartsToLegacyProjectConfigPartial, y as validateStackParts } from "./stack-graph-UgPd4sup.mjs";
|
|
4
|
+
export { ProvidedCapabilityDefinition, STACK_TOOL_DEFINITIONS, StackGraphDiagnostic, StackGraphIssue, StackGraphValidationResult, StackPartOptionContext, StackPrimaryRole, ToolDefinition, compareLegacyConfigToStackParts, createStackPart, formatStackPartSpec, getRoleTargetPath, getStackPartOptions, getStackToolDefinitions, legacyProjectConfigToStackParts, materializeProvidedStackParts, parseStackPartSpecs, stackPartsToLegacyProjectConfigPartial, validateStackParts };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import "./schemas-DnEGgQzA.mjs";
|
|
2
|
+
import { a as getRoleTargetPath, c as legacyProjectConfigToStackParts, d as stackPartsToLegacyProjectConfigPartial, f as validateStackParts, i as formatStackPartSpec, l as materializeProvidedStackParts, n as compareLegacyConfigToStackParts, o as getStackPartOptions, r as createStackPart, s as getStackToolDefinitions, t as STACK_TOOL_DEFINITIONS, u as parseStackPartSpecs } from "./stack-graph-C2tzuzRe.mjs";
|
|
3
|
+
|
|
4
|
+
export { STACK_TOOL_DEFINITIONS, compareLegacyConfigToStackParts, createStackPart, formatStackPartSpec, getRoleTargetPath, getStackPartOptions, getStackToolDefinitions, legacyProjectConfigToStackParts, materializeProvidedStackParts, parseStackPartSpecs, stackPartsToLegacyProjectConfigPartial, validateStackParts };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { $ as ELIXIR_VALIDATION_VALUES, $n as RUST_API_VALUES, $t as JOB_QUEUE_VALUES, An as PYTHON_API_VALUES, Ar as STATE_MANAGEMENT_VALUES, B as ELIXIR_API_VALUES, Cn as OBSERVABILITY_VALUES, Cr as SHADCN_BASE_COLOR_VALUES, Ct as FILE_STORAGE_VALUES, D as CMS_VALUES, Dn as PACKAGE_MANAGER_VALUES, Dr as SHADCN_ICON_LIBRARY_VALUES, Er as SHADCN_FONT_VALUES, Fn as PYTHON_TASK_QUEUE_VALUES, Ft as GO_LOGGING_VALUES, G as ELIXIR_HTTP_VALUES, H as ELIXIR_CACHING_VALUES,
|
|
2
|
-
import { t as createCliDefaultProjectConfigBase } from "./defaults-
|
|
1
|
+
import { $ as ELIXIR_VALIDATION_VALUES, $n as RUST_API_VALUES, $t as JOB_QUEUE_VALUES, An as PYTHON_API_VALUES, Ar as STATE_MANAGEMENT_VALUES, B as ELIXIR_API_VALUES, Cn as OBSERVABILITY_VALUES, Cr as SHADCN_BASE_COLOR_VALUES, Ct as FILE_STORAGE_VALUES, D as CMS_VALUES, Dn as PACKAGE_MANAGER_VALUES, Dr as SHADCN_ICON_LIBRARY_VALUES, Er as SHADCN_FONT_VALUES, Fn as PYTHON_TASK_QUEUE_VALUES, Ft as GO_LOGGING_VALUES, G as ELIXIR_HTTP_VALUES, H as ELIXIR_CACHING_VALUES, In as PYTHON_VALIDATION_VALUES, It as GO_ORM_VALUES, J as ELIXIR_OBSERVABILITY_VALUES, Jt as JAVA_BUILD_TOOL_VALUES, K as ELIXIR_JOBS_VALUES, Kr as TESTING_VALUES, Ln as PYTHON_WEB_FRAMEWORK_VALUES, Lt as GO_WEB_FRAMEWORK_VALUES, M as DATABASE_SETUP_VALUES, Mn as PYTHON_GRAPHQL_VALUES, Mt as GO_API_VALUES, N as DATABASE_VALUES, Nn as PYTHON_ORM_VALUES, Nt as GO_AUTH_VALUES, On as PAYMENTS_VALUES, Or as SHADCN_RADIUS_VALUES, Pn as PYTHON_QUALITY_VALUES, Pt as GO_CLI_VALUES, Q as ELIXIR_TESTING_VALUES, Qn as RUNTIME_VALUES, Qr as VERSION_CHANNEL_VALUES, Qt as JAVA_WEB_FRAMEWORK_VALUES, Sr as SERVER_DEPLOY_VALUES, St as FEATURE_FLAGS_VALUES, Tn as ORM_VALUES, Tr as SHADCN_COLOR_THEME_VALUES, Tt as FORMS_VALUES, U as ELIXIR_DEPLOY_VALUES, V as ELIXIR_AUTH_VALUES, W as ELIXIR_EMAIL_VALUES, Wt as I18N_VALUES, X as ELIXIR_QUALITY_VALUES, Xr as UI_LIBRARY_VALUES, Xt as JAVA_ORM_VALUES, Y as ELIXIR_ORM_VALUES, Yt as JAVA_LIBRARIES_VALUES, Z as ELIXIR_REALTIME_VALUES, Zn as REALTIME_VALUES, Zr as VALIDATION_VALUES, Zt as JAVA_TESTING_LIBRARIES_VALUES, a as ANALYTICS_VALUES, ar as RUST_LIBRARIES_VALUES, c as API_VALUES, cr as RUST_WEB_FRAMEWORK_VALUES, dn as MOBILE_OTA_VALUES, er as RUST_AUTH_VALUES, et as ELIXIR_WEB_FRAMEWORK_VALUES, fn as MOBILE_PUSH_VALUES, hn as MOBILE_UI_VALUES, i as AI_VALUES, ir as RUST_FRONTEND_VALUES, jn as PYTHON_AUTH_VALUES, k as CSS_FRAMEWORK_VALUES, kn as PYTHON_AI_VALUES, kr as SHADCN_STYLE_VALUES, l as ASTRO_INTEGRATION_VALUES, ln as MOBILE_DEEP_LINKING_VALUES, mn as MOBILE_TESTING_VALUES, nr as RUST_CLI_VALUES, o as ANIMATION_VALUES, or as RUST_LOGGING_VALUES, pn as MOBILE_STORAGE_VALUES, q as ELIXIR_JSON_VALUES, qt as JAVA_AUTH_VALUES, r as AI_DOCS_VALUES, rr as RUST_ERROR_HANDLING_VALUES, sn as LOGGING_VALUES, sr as RUST_ORM_VALUES, ti as WEB_DEPLOY_VALUES, tr as RUST_CACHING_VALUES, tt as EMAIL_VALUES, u as AUTH_VALUES, un as MOBILE_NAVIGATION_VALUES, w as CACHING_VALUES, wr as SHADCN_BASE_VALUES, wt as FILE_UPLOAD_VALUES, xr as SEARCH_VALUES, z as EFFECT_VALUES } from "./schemas-DnEGgQzA.mjs";
|
|
2
|
+
import { t as createCliDefaultProjectConfigBase } from "./defaults-DNmNiuxG.mjs";
|
|
3
|
+
import { d as stackPartsToLegacyProjectConfigPartial, f as validateStackParts, i as formatStackPartSpec, u as parseStackPartSpecs } from "./stack-graph-C2tzuzRe.mjs";
|
|
3
4
|
|
|
4
5
|
//#region src/capabilities.ts
|
|
5
6
|
const CAPABILITY_DEFINITIONS = { auth: [
|
|
@@ -1128,15 +1129,6 @@ const analyzeStackCompatibility = (stack) => {
|
|
|
1128
1129
|
});
|
|
1129
1130
|
}
|
|
1130
1131
|
}
|
|
1131
|
-
if (nextStack.ecosystem === "typescript" && nextStack.nativeFrontend.some((frontend) => frontend !== "none")) {
|
|
1132
|
-
nextStack.nativeFrontend = ["none"];
|
|
1133
|
-
hasNativeFrontend = false;
|
|
1134
|
-
changed = true;
|
|
1135
|
-
changes.push({
|
|
1136
|
-
category: "nativeFrontend",
|
|
1137
|
-
message: "Native frontend set to 'None' (use React Native ecosystem for Expo apps)"
|
|
1138
|
-
});
|
|
1139
|
-
}
|
|
1140
1132
|
if (!hasNativeFrontend) {
|
|
1141
1133
|
for (const [category, value, message] of [
|
|
1142
1134
|
[
|
|
@@ -3749,6 +3741,8 @@ function normalizeOptionId(category, value) {
|
|
|
3749
3741
|
//#endregion
|
|
3750
3742
|
//#region src/stack-translation.ts
|
|
3751
3743
|
const DEFAULT_STACK_SELECTION = {
|
|
3744
|
+
stackMode: "solo",
|
|
3745
|
+
stackPartSpecs: [],
|
|
3752
3746
|
ecosystem: "typescript",
|
|
3753
3747
|
projectName: "my-app",
|
|
3754
3748
|
webFrontend: ["tanstack-router"],
|
|
@@ -3858,6 +3852,8 @@ const DEFAULT_STACK_SELECTION = {
|
|
|
3858
3852
|
elixirDeploy: "none"
|
|
3859
3853
|
};
|
|
3860
3854
|
const NON_OPTION_STACK_SELECTION_KEYS = [
|
|
3855
|
+
"stackMode",
|
|
3856
|
+
"stackPartSpecs",
|
|
3861
3857
|
"ecosystem",
|
|
3862
3858
|
"projectName",
|
|
3863
3859
|
"yolo"
|
|
@@ -3979,6 +3975,8 @@ function usesVirtualNoneStackSelection(key) {
|
|
|
3979
3975
|
return VIRTUAL_NONE_MULTI_SELECT_STACK_SELECTION_KEYS.includes(key);
|
|
3980
3976
|
}
|
|
3981
3977
|
const STACK_SELECTION_URL_KEYS = {
|
|
3978
|
+
stackMode: "mode",
|
|
3979
|
+
stackPartSpecs: "part",
|
|
3982
3980
|
ecosystem: "eco",
|
|
3983
3981
|
projectName: "name",
|
|
3984
3982
|
webFrontend: "fe-w",
|
|
@@ -4116,8 +4114,12 @@ function normalizeStackSelectionValue(key, value) {
|
|
|
4116
4114
|
if (typeof value === "string") return normalizeOptionId(category, value);
|
|
4117
4115
|
return value;
|
|
4118
4116
|
}
|
|
4117
|
+
function normalizeStackSelectionMode(value) {
|
|
4118
|
+
return value === "multi" || value === "graph" ? "multi" : "solo";
|
|
4119
|
+
}
|
|
4119
4120
|
function normalizeStackSelection(selection) {
|
|
4120
4121
|
const normalized = { ...selection };
|
|
4122
|
+
normalized.stackMode = normalizeStackSelectionMode(normalized.stackMode);
|
|
4121
4123
|
for (const key of Object.keys(STACK_SELECTION_OPTION_CATEGORY_BY_KEY)) normalized[key] = normalizeStackSelectionValue(key, normalized[key]);
|
|
4122
4124
|
return normalized;
|
|
4123
4125
|
}
|
|
@@ -4418,11 +4420,122 @@ function formatTypeScriptAddonsFlag(selection) {
|
|
|
4418
4420
|
if (addons.length === 0) return "--addons none";
|
|
4419
4421
|
return `--addons ${addons.filter((addon) => COMMAND_ADDONS.has(addon)).join(" ") || "none"}`;
|
|
4420
4422
|
}
|
|
4423
|
+
const GRAPH_TYPESCRIPT_FRONTEND_FLAG_KEYS = [
|
|
4424
|
+
["cssFramework", "css-framework"],
|
|
4425
|
+
["uiLibrary", "ui-library"],
|
|
4426
|
+
["stateManagement", "state-management"],
|
|
4427
|
+
["forms", "forms"],
|
|
4428
|
+
["validation", "validation"],
|
|
4429
|
+
["testing", "testing"],
|
|
4430
|
+
["animation", "animation"]
|
|
4431
|
+
];
|
|
4432
|
+
const GRAPH_SHADCN_FLAG_KEYS = [
|
|
4433
|
+
["shadcnBase", "shadcn-base"],
|
|
4434
|
+
["shadcnStyle", "shadcn-style"],
|
|
4435
|
+
["shadcnIconLibrary", "shadcn-icon-library"],
|
|
4436
|
+
["shadcnColorTheme", "shadcn-color-theme"],
|
|
4437
|
+
["shadcnBaseColor", "shadcn-base-color"],
|
|
4438
|
+
["shadcnFont", "shadcn-font"],
|
|
4439
|
+
["shadcnRadius", "shadcn-radius"]
|
|
4440
|
+
];
|
|
4441
|
+
const GRAPH_MOBILE_FLAG_KEYS = [
|
|
4442
|
+
["mobileNavigation", "mobile-navigation"],
|
|
4443
|
+
["mobileUI", "mobile-ui"],
|
|
4444
|
+
["mobileStorage", "mobile-storage"],
|
|
4445
|
+
["mobileTesting", "mobile-testing"],
|
|
4446
|
+
["mobilePush", "mobile-push"],
|
|
4447
|
+
["mobileOTA", "mobile-ota"],
|
|
4448
|
+
["mobileDeepLinking", "mobile-deep-linking"]
|
|
4449
|
+
];
|
|
4450
|
+
const GRAPH_GLOBAL_FLAG_KEYS = [
|
|
4451
|
+
["dbSetup", "db-setup"],
|
|
4452
|
+
["webDeploy", "web-deploy"],
|
|
4453
|
+
["serverDeploy", "server-deploy"]
|
|
4454
|
+
];
|
|
4455
|
+
const GRAPH_TYPESCRIPT_BACKEND_FLAG_KEYS = [
|
|
4456
|
+
["payments", "payments"],
|
|
4457
|
+
["email", "email"],
|
|
4458
|
+
["fileUpload", "file-upload"],
|
|
4459
|
+
["backendLibraries", "effect"],
|
|
4460
|
+
["aiSdk", "ai"],
|
|
4461
|
+
["realtime", "realtime"],
|
|
4462
|
+
["jobQueue", "job-queue"],
|
|
4463
|
+
["logging", "logging"],
|
|
4464
|
+
["observability", "observability"],
|
|
4465
|
+
["featureFlags", "feature-flags"],
|
|
4466
|
+
["caching", "caching"],
|
|
4467
|
+
["i18n", "i18n"],
|
|
4468
|
+
["cms", "cms"],
|
|
4469
|
+
["search", "search"],
|
|
4470
|
+
["fileStorage", "file-storage"]
|
|
4471
|
+
];
|
|
4472
|
+
const GRAPH_SHARED_BACKEND_FLAG_KEYS = [
|
|
4473
|
+
["email", "email"],
|
|
4474
|
+
["observability", "observability"],
|
|
4475
|
+
["caching", "caching"],
|
|
4476
|
+
["search", "search"]
|
|
4477
|
+
];
|
|
4478
|
+
const GRAPH_RUST_BACKEND_FLAG_KEYS = [
|
|
4479
|
+
["rustCli", "rust-cli"],
|
|
4480
|
+
["rustLogging", "rust-logging"],
|
|
4481
|
+
["rustErrorHandling", "rust-error-handling"],
|
|
4482
|
+
["rustCaching", "rust-caching"]
|
|
4483
|
+
];
|
|
4484
|
+
const GRAPH_PYTHON_BACKEND_FLAG_KEYS = [
|
|
4485
|
+
["pythonValidation", "python-validation"],
|
|
4486
|
+
["pythonTaskQueue", "python-task-queue"],
|
|
4487
|
+
["pythonGraphql", "python-graphql"],
|
|
4488
|
+
["pythonQuality", "python-quality"]
|
|
4489
|
+
];
|
|
4490
|
+
const GRAPH_GO_BACKEND_FLAG_KEYS = [["goCli", "go-cli"], ["goLogging", "go-logging"]];
|
|
4491
|
+
const GRAPH_JAVA_BACKEND_FLAG_KEYS = [["javaBuildTool", "java-build-tool"]];
|
|
4492
|
+
const GRAPH_ELIXIR_BACKEND_FLAG_KEYS = [
|
|
4493
|
+
["elixirRealtime", "elixir-realtime"],
|
|
4494
|
+
["elixirJobs", "elixir-jobs"],
|
|
4495
|
+
["elixirValidation", "elixir-validation"],
|
|
4496
|
+
["elixirHttp", "elixir-http"],
|
|
4497
|
+
["elixirJson", "elixir-json"],
|
|
4498
|
+
["elixirEmail", "elixir-email"],
|
|
4499
|
+
["elixirCaching", "elixir-caching"],
|
|
4500
|
+
["elixirObservability", "elixir-observability"],
|
|
4501
|
+
["elixirTesting", "elixir-testing"],
|
|
4502
|
+
["elixirQuality", "elixir-quality"],
|
|
4503
|
+
["elixirDeploy", "elixir-deploy"]
|
|
4504
|
+
];
|
|
4505
|
+
function formatChangedStringFlag(selection, key, flag) {
|
|
4506
|
+
return selection[key] === DEFAULT_STACK_SELECTION[key] ? void 0 : `--${flag} ${selection[key]}`;
|
|
4507
|
+
}
|
|
4508
|
+
function formatChangedArraySelectionFlag(selection, key, flag) {
|
|
4509
|
+
return areStringArraysEqual(selection[key], DEFAULT_STACK_SELECTION[key]) ? void 0 : formatArrayFlag(flag, selection[key]);
|
|
4510
|
+
}
|
|
4511
|
+
function formatChangedStringFlags(selection, keys) {
|
|
4512
|
+
return keys.flatMap(([key, flag]) => {
|
|
4513
|
+
const formattedFlag = formatChangedStringFlag(selection, key, flag);
|
|
4514
|
+
return formattedFlag ? [formattedFlag] : [];
|
|
4515
|
+
});
|
|
4516
|
+
}
|
|
4517
|
+
function hasGraphPrimaryPart(parts, role, ecosystem, toolId) {
|
|
4518
|
+
return parts.some((part) => part.role === role && !part.ownerPartId && (!ecosystem || part.ecosystem === ecosystem) && (!toolId || part.toolId === toolId));
|
|
4519
|
+
}
|
|
4421
4520
|
function mapBackendToCli(backend) {
|
|
4422
4521
|
return SELF_BACKENDS.has(backend) ? "self" : backend;
|
|
4423
4522
|
}
|
|
4523
|
+
function isGraphStackSelection(selection) {
|
|
4524
|
+
return (selection.stackMode === "multi" || String(selection.stackMode) === "graph") && selection.stackPartSpecs.length > 0;
|
|
4525
|
+
}
|
|
4526
|
+
function getGraphStackParts(selection) {
|
|
4527
|
+
const stackParts = parseStackPartSpecs(selection.stackPartSpecs, "selected");
|
|
4528
|
+
const validation = validateStackParts(stackParts);
|
|
4529
|
+
if (validation.issues.length > 0) throw new Error(validation.issues.map((issue) => issue.message).join("\n"));
|
|
4530
|
+
return stackParts;
|
|
4531
|
+
}
|
|
4424
4532
|
function getAdjustedSelection(selection) {
|
|
4425
|
-
|
|
4533
|
+
const compatibility = analyzeStackCompatibility(selection);
|
|
4534
|
+
if (!compatibility.adjustedStack) return selection;
|
|
4535
|
+
return {
|
|
4536
|
+
...selection,
|
|
4537
|
+
...compatibility.adjustedStack
|
|
4538
|
+
};
|
|
4426
4539
|
}
|
|
4427
4540
|
function getProjectName(selection, projectName) {
|
|
4428
4541
|
return projectName?.trim() || selection.projectName?.trim() || "my-app";
|
|
@@ -4432,6 +4545,9 @@ function areStringArraysEqual(left, right) {
|
|
|
4432
4545
|
const sortedRight = [...right].sort();
|
|
4433
4546
|
return sortedLeft.length === sortedRight.length && sortedLeft.every((value, index) => value === sortedRight[index]);
|
|
4434
4547
|
}
|
|
4548
|
+
function isStringArray(value) {
|
|
4549
|
+
return value.every((item) => typeof item === "string");
|
|
4550
|
+
}
|
|
4435
4551
|
function isStackSelectionDefault(selection, key, value) {
|
|
4436
4552
|
const defaultValue = DEFAULT_STACK_SELECTION[key];
|
|
4437
4553
|
if (selection.backend === "convex") {
|
|
@@ -4461,12 +4577,57 @@ function cliInputToProjectConfigPartial(input, projectName) {
|
|
|
4461
4577
|
const value = input[inputKey];
|
|
4462
4578
|
if (Array.isArray(value)) assignableConfig[configKey] = processCliArrayOption(value);
|
|
4463
4579
|
}
|
|
4580
|
+
if (Array.isArray(input.part) && input.part.length > 0) {
|
|
4581
|
+
const stackParts = getCliGraphStackParts(input);
|
|
4582
|
+
Object.assign(config, stackPartsToLegacyProjectConfigPartial(stackParts), { stackParts });
|
|
4583
|
+
}
|
|
4464
4584
|
return config;
|
|
4465
4585
|
}
|
|
4586
|
+
function getCliGraphStackParts(input) {
|
|
4587
|
+
const stackParts = parseStackPartSpecs(input.part ?? [], "selected");
|
|
4588
|
+
const stackPartSpecs = stackParts.map((part) => formatStackPartSpec(part, stackParts));
|
|
4589
|
+
const stackPartSpecSet = new Set(stackPartSpecs);
|
|
4590
|
+
const hasPrimary = (role, ecosystem) => stackParts.some((part) => part.role === role && part.ecosystem === ecosystem && !part.ownerPartId && part.source !== "provided");
|
|
4591
|
+
const hasScoped = (role, ecosystem) => stackParts.some((part) => part.role === role && part.ecosystem === ecosystem && part.source !== "provided");
|
|
4592
|
+
const addScopedBackendPart = (ecosystem, role, value) => {
|
|
4593
|
+
if (!value || value === "none" || !hasPrimary("backend", ecosystem) || hasScoped(role, ecosystem)) return;
|
|
4594
|
+
const spec = `backend.${role}:${ecosystem}:${value}`;
|
|
4595
|
+
if (!stackPartSpecSet.has(spec)) {
|
|
4596
|
+
stackPartSpecs.push(spec);
|
|
4597
|
+
stackPartSpecSet.add(spec);
|
|
4598
|
+
}
|
|
4599
|
+
};
|
|
4600
|
+
if (input.database && input.database !== "none" && !hasPrimary("database", "universal")) {
|
|
4601
|
+
const spec = `database:universal:${input.database}`;
|
|
4602
|
+
if (!stackPartSpecSet.has(spec)) {
|
|
4603
|
+
stackPartSpecs.push(spec);
|
|
4604
|
+
stackPartSpecSet.add(spec);
|
|
4605
|
+
}
|
|
4606
|
+
}
|
|
4607
|
+
addScopedBackendPart("typescript", "orm", input.orm);
|
|
4608
|
+
addScopedBackendPart("typescript", "api", input.api);
|
|
4609
|
+
addScopedBackendPart("typescript", "auth", input.auth);
|
|
4610
|
+
addScopedBackendPart("rust", "orm", input.rustOrm);
|
|
4611
|
+
addScopedBackendPart("rust", "api", input.rustApi);
|
|
4612
|
+
addScopedBackendPart("rust", "auth", input.rustAuth);
|
|
4613
|
+
addScopedBackendPart("python", "orm", input.pythonOrm);
|
|
4614
|
+
addScopedBackendPart("python", "api", input.pythonApi);
|
|
4615
|
+
addScopedBackendPart("python", "api", input.pythonGraphql);
|
|
4616
|
+
addScopedBackendPart("python", "auth", input.pythonAuth);
|
|
4617
|
+
addScopedBackendPart("go", "orm", input.goOrm);
|
|
4618
|
+
addScopedBackendPart("go", "api", input.goApi);
|
|
4619
|
+
addScopedBackendPart("go", "auth", input.goAuth);
|
|
4620
|
+
addScopedBackendPart("java", "orm", input.javaOrm);
|
|
4621
|
+
addScopedBackendPart("java", "auth", input.javaAuth);
|
|
4622
|
+
addScopedBackendPart("elixir", "orm", input.elixirOrm);
|
|
4623
|
+
addScopedBackendPart("elixir", "api", input.elixirApi);
|
|
4624
|
+
addScopedBackendPart("elixir", "auth", input.elixirAuth);
|
|
4625
|
+
return parseStackPartSpecs(stackPartSpecs, "selected");
|
|
4626
|
+
}
|
|
4466
4627
|
function buildProjectConfigBase(selection, projectName, relativePath, install) {
|
|
4467
4628
|
const stack = getAdjustedSelection(selection);
|
|
4468
4629
|
const frontend = [...toUniqueNonNoneArray(stack.webFrontend), ...toUniqueNonNoneArray(stack.nativeFrontend)];
|
|
4469
|
-
|
|
4630
|
+
const baseConfig = {
|
|
4470
4631
|
projectName,
|
|
4471
4632
|
relativePath,
|
|
4472
4633
|
ecosystem: stack.ecosystem,
|
|
@@ -4576,6 +4737,21 @@ function buildProjectConfigBase(selection, projectName, relativePath, install) {
|
|
|
4576
4737
|
elixirDeploy: stack.elixirDeploy,
|
|
4577
4738
|
aiDocs: toUniqueNonNoneArray(stack.aiDocs)
|
|
4578
4739
|
};
|
|
4740
|
+
if (!isGraphStackSelection(stack)) return baseConfig;
|
|
4741
|
+
const stackParts = getGraphStackParts(stack);
|
|
4742
|
+
const loweredGraphConfig = stackPartsToLegacyProjectConfigPartial(stackParts);
|
|
4743
|
+
return {
|
|
4744
|
+
...baseConfig,
|
|
4745
|
+
...loweredGraphConfig,
|
|
4746
|
+
projectName,
|
|
4747
|
+
relativePath,
|
|
4748
|
+
git: stack.git === "true",
|
|
4749
|
+
packageManager: stack.packageManager,
|
|
4750
|
+
versionChannel: stack.versionChannel,
|
|
4751
|
+
install,
|
|
4752
|
+
aiDocs: toUniqueNonNoneArray(stack.aiDocs),
|
|
4753
|
+
stackParts
|
|
4754
|
+
};
|
|
4579
4755
|
}
|
|
4580
4756
|
function stackSelectionToProjectConfig(selection, options) {
|
|
4581
4757
|
const projectName = getProjectName(selection);
|
|
@@ -4589,6 +4765,7 @@ function stackSelectionToCliComparableConfig(selection, projectName = getProject
|
|
|
4589
4765
|
return buildProjectConfigBase(selection, projectName, projectName, selection.install === "true");
|
|
4590
4766
|
}
|
|
4591
4767
|
function isCliDefaultStackSelection(selection, projectName = getProjectName(selection)) {
|
|
4768
|
+
if (isGraphStackSelection(selection)) return false;
|
|
4592
4769
|
const comparableConfig = stackSelectionToCliComparableConfig(selection, projectName);
|
|
4593
4770
|
const cliDefaults = {
|
|
4594
4771
|
...createCliDefaultProjectConfigBase(selection.packageManager),
|
|
@@ -4607,13 +4784,67 @@ function isCliDefaultStackSelection(selection, projectName = getProjectName(sele
|
|
|
4607
4784
|
if (ignoredKeys.has(key)) return true;
|
|
4608
4785
|
const currentValue = comparableConfig[key];
|
|
4609
4786
|
const defaultValue = cliDefaults[key];
|
|
4610
|
-
if (Array.isArray(currentValue) && Array.isArray(defaultValue))
|
|
4787
|
+
if (Array.isArray(currentValue) && Array.isArray(defaultValue)) {
|
|
4788
|
+
const currentArray = currentValue;
|
|
4789
|
+
const defaultArray = defaultValue;
|
|
4790
|
+
if (isStringArray(currentArray) && isStringArray(defaultArray)) return areStringArraysEqual(currentArray, defaultArray);
|
|
4791
|
+
return JSON.stringify(currentValue) === JSON.stringify(defaultValue);
|
|
4792
|
+
}
|
|
4611
4793
|
return currentValue === defaultValue;
|
|
4612
4794
|
});
|
|
4613
4795
|
}
|
|
4614
4796
|
function getBaseCommand(selection) {
|
|
4615
4797
|
return PACKAGE_MANAGER_COMMANDS[selection.packageManager] ?? PACKAGE_MANAGER_COMMANDS.bun;
|
|
4616
4798
|
}
|
|
4799
|
+
function generateGraphCommand(selection, projectName) {
|
|
4800
|
+
const stackParts = getGraphStackParts(selection);
|
|
4801
|
+
const hasTypeScriptFrontend = hasGraphPrimaryPart(stackParts, "frontend", "typescript");
|
|
4802
|
+
const hasAstroFrontend = hasGraphPrimaryPart(stackParts, "frontend", "typescript", "astro");
|
|
4803
|
+
const hasTypeScriptBackend = hasGraphPrimaryPart(stackParts, "backend", "typescript");
|
|
4804
|
+
const hasRustBackend = hasGraphPrimaryPart(stackParts, "backend", "rust");
|
|
4805
|
+
const hasPythonBackend = hasGraphPrimaryPart(stackParts, "backend", "python");
|
|
4806
|
+
const hasGoBackend = hasGraphPrimaryPart(stackParts, "backend", "go");
|
|
4807
|
+
const hasJavaBackend = hasGraphPrimaryPart(stackParts, "backend", "java");
|
|
4808
|
+
const hasElixirBackend = hasGraphPrimaryPart(stackParts, "backend", "elixir");
|
|
4809
|
+
const hasNonTypeScriptBackend = hasRustBackend || hasPythonBackend || hasGoBackend || hasJavaBackend || hasElixirBackend;
|
|
4810
|
+
const hasMobile = hasGraphPrimaryPart(stackParts, "mobile");
|
|
4811
|
+
const flags = [
|
|
4812
|
+
...stackParts.filter((part) => part.source !== "provided").map((part) => `--part ${formatStackPartSpec(part, stackParts)}`),
|
|
4813
|
+
...hasTypeScriptFrontend ? formatChangedStringFlags(selection, GRAPH_TYPESCRIPT_FRONTEND_FLAG_KEYS) : [],
|
|
4814
|
+
...hasAstroFrontend && selection.astroIntegration !== "none" ? [`--astro-integration ${selection.astroIntegration}`] : [],
|
|
4815
|
+
...hasTypeScriptFrontend && selection.uiLibrary === "shadcn-ui" ? formatChangedStringFlags(selection, GRAPH_SHADCN_FLAG_KEYS) : [],
|
|
4816
|
+
...hasTypeScriptBackend ? formatChangedStringFlags(selection, GRAPH_TYPESCRIPT_BACKEND_FLAG_KEYS) : [],
|
|
4817
|
+
...hasNonTypeScriptBackend ? formatChangedStringFlags(selection, GRAPH_SHARED_BACKEND_FLAG_KEYS) : [],
|
|
4818
|
+
...hasRustBackend ? [...formatChangedStringFlags(selection, GRAPH_RUST_BACKEND_FLAG_KEYS), formatChangedArraySelectionFlag(selection, "rustLibraries", "rust-libraries")].filter((flag) => Boolean(flag)) : [],
|
|
4819
|
+
...hasPythonBackend ? [...formatChangedStringFlags(selection, GRAPH_PYTHON_BACKEND_FLAG_KEYS), formatChangedArraySelectionFlag(selection, "pythonAi", "python-ai")].filter((flag) => Boolean(flag)) : [],
|
|
4820
|
+
...hasGoBackend ? formatChangedStringFlags(selection, GRAPH_GO_BACKEND_FLAG_KEYS) : [],
|
|
4821
|
+
...hasJavaBackend ? [
|
|
4822
|
+
...formatChangedStringFlags(selection, GRAPH_JAVA_BACKEND_FLAG_KEYS),
|
|
4823
|
+
formatChangedArraySelectionFlag(selection, "javaLibraries", "java-libraries"),
|
|
4824
|
+
formatChangedArraySelectionFlag(selection, "javaTestingLibraries", "java-testing-libraries")
|
|
4825
|
+
].filter((flag) => Boolean(flag)) : [],
|
|
4826
|
+
...hasElixirBackend ? formatChangedStringFlags(selection, GRAPH_ELIXIR_BACKEND_FLAG_KEYS) : [],
|
|
4827
|
+
...hasMobile ? formatChangedStringFlags(selection, GRAPH_MOBILE_FLAG_KEYS) : [],
|
|
4828
|
+
...formatChangedStringFlags(selection, GRAPH_GLOBAL_FLAG_KEYS),
|
|
4829
|
+
...areStringArraysEqual([
|
|
4830
|
+
...selection.codeQuality,
|
|
4831
|
+
...selection.documentation,
|
|
4832
|
+
...selection.appPlatforms
|
|
4833
|
+
], [
|
|
4834
|
+
...DEFAULT_STACK_SELECTION.codeQuality,
|
|
4835
|
+
...DEFAULT_STACK_SELECTION.documentation,
|
|
4836
|
+
...DEFAULT_STACK_SELECTION.appPlatforms
|
|
4837
|
+
]) ? [] : [formatTypeScriptAddonsFlag(selection)],
|
|
4838
|
+
...areStringArraysEqual(selection.examples, DEFAULT_STACK_SELECTION.examples) ? [] : [formatArrayFlag("examples", selection.examples)],
|
|
4839
|
+
`--package-manager ${selection.packageManager}`,
|
|
4840
|
+
...selection.versionChannel !== "stable" ? [`--version-channel ${selection.versionChannel}`] : [],
|
|
4841
|
+
selection.git === "false" ? "--no-git" : "--git",
|
|
4842
|
+
selection.install === "false" ? "--no-install" : "--install",
|
|
4843
|
+
formatArrayFlag("ai-docs", selection.aiDocs)
|
|
4844
|
+
];
|
|
4845
|
+
if (selection.yolo === "true") flags.push("--yolo");
|
|
4846
|
+
return `${getBaseCommand(selection)} ${projectName} ${flags.join(" ")}`;
|
|
4847
|
+
}
|
|
4617
4848
|
function generateTypeScriptCommand(selection, projectName) {
|
|
4618
4849
|
const base = getBaseCommand(selection);
|
|
4619
4850
|
if (isCliDefaultStackSelection(selection, projectName)) return `${base} ${projectName} --yes`;
|
|
@@ -4803,6 +5034,7 @@ function generateElixirCommand(selection, projectName) {
|
|
|
4803
5034
|
}
|
|
4804
5035
|
function generateStackSelectionCommand(selection) {
|
|
4805
5036
|
const projectName = getProjectName(selection);
|
|
5037
|
+
if (isGraphStackSelection(selection)) return generateGraphCommand(selection, projectName);
|
|
4806
5038
|
switch (selection.ecosystem) {
|
|
4807
5039
|
case "react-native": return generateReactNativeCommand(selection, projectName);
|
|
4808
5040
|
case "rust": return generateRustCommand(selection, projectName);
|
|
@@ -4816,5 +5048,5 @@ function generateStackSelectionCommand(selection) {
|
|
|
4816
5048
|
}
|
|
4817
5049
|
|
|
4818
5050
|
//#endregion
|
|
4819
|
-
export {
|
|
4820
|
-
//# sourceMappingURL=stack-translation-
|
|
5051
|
+
export { validateProjectName as $, analyzeStackCompatibility as A, hasDockerComposeCompatibleFrontend as B, OPTION_CATEGORY_METADATA as C, isMultiSelectCategory as D, getOptionMetadata as E, getCompatibleAddons as F, isExampleChatSdkAllowed as G, hasTauriCompatibleFrontend as H, getCompatibleCSSFrameworks as I, isWebFrontend as J, isFrontendAllowedWithBackend as K, getCompatibleFormLibraries as L, getAIFrontendCompatibilityIssue as M, getApiFrontendCompatibilityIssue as N, normalizeOptionId as O, getCategoryDisplayName as P, validateAddonCompatibility as Q, getCompatibleUILibraries as R, usesVirtualNoneStackSelection as S, getCategoryOptionIds as T, hasWebStyling as U, hasPWACompatibleFrontend as V, isExampleAIAllowed as W, requiresChatSdkVercelAIForSelection as X, requiresChatSdkVercelAI as Y, splitFrontends as Z, parseStackSelectionFromSearch as _, STACK_SELECTION_URL_KEYS as a, stackSelectionToCliComparableConfig as b, cloneDefaultStackSelection as c, isArrayStackSelectionKey as d, getCapabilityDefinitions as et, isCliDefaultStackSelection as f, normalizeStackSelectionValue as g, normalizeStackSelection as h, STACK_SELECTION_OPTION_CATEGORY_BY_KEY as i, evaluateCompatibility as j, allowedApisForFrontends as k, createStackSelectionSearchParams as l, isStackSelectionDefault as m, NON_OPTION_STACK_SELECTION_KEYS as n, getSupportedCapabilityOptions as nt, VIRTUAL_NONE_MULTI_SELECT_STACK_SELECTION_KEYS as o, isGraphStackSelection as p, isOptionCompatible as q, STACK_SELECTION_KEYS as r, normalizeCapabilitySelection as rt, cliInputToProjectConfigPartial as s, DEFAULT_STACK_SELECTION as t, getCapabilityDisabledReason as tt, generateStackSelectionCommand as u, parseStackSelectionFromUrlRecord as v, getCategoryCliValues as w, stackSelectionToProjectConfig as x, processCliArrayOption as y, getDisabledReason as z };
|
|
5052
|
+
//# sourceMappingURL=stack-translation-COVG5IPm.mjs.map
|