@tdk-landscape/tdk-cli-core 1.3.14 → 1.3.22

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 (277) hide show
  1. package/README.md +3 -3
  2. package/Tiltfile +144 -0
  3. package/discovery/AGENTS.md +362 -0
  4. package/discovery/TILT_DISCOVERY.star +424 -0
  5. package/discovery/Tiltfile +58 -0
  6. package/discovery/config.star +258 -0
  7. package/discovery/constants.star +127 -0
  8. package/discovery/deterministic.star +211 -0
  9. package/discovery/discovery_daemon.star +191 -0
  10. package/discovery/discovery_orchestrator.star +460 -0
  11. package/discovery/filtering.star +5 -0
  12. package/discovery/identity-management-backend/service.yaml +26 -0
  13. package/discovery/identity-management-frontend/service.yaml +29 -0
  14. package/discovery/identity-sdk/service.yaml +9 -0
  15. package/discovery/incremental_discovery.star +213 -0
  16. package/discovery/indexing.star +7 -0
  17. package/discovery/json_manifest_scanner.star +51 -0
  18. package/discovery/libraries.star +46 -0
  19. package/discovery/loading.star +23 -0
  20. package/discovery/manifest/constants.star +104 -0
  21. package/discovery/manifest/loading.star +386 -0
  22. package/discovery/manifest/normalize.star +281 -0
  23. package/discovery/manifest/validation.star +108 -0
  24. package/discovery/normalization.star +11 -0
  25. package/discovery/registry.star +544 -0
  26. package/discovery/resource_snapshot.py +382 -0
  27. package/discovery/resource_snapshot.star +143 -0
  28. package/discovery/schemas.star +1 -0
  29. package/discovery/services/platform/cdc/debezium/nats-connector/service.yaml +9 -0
  30. package/discovery/services/platform/cdc/nats-http-bridge/service.yaml +9 -0
  31. package/discovery/services/platform/orchestrator/orchestrator-glue-backend/service.yaml +26 -0
  32. package/discovery/services/platform/synthetic-monitor/service.yaml +9 -0
  33. package/discovery/test_resource_snapshot.py +251 -0
  34. package/discovery/validation.star +78 -0
  35. package/discovery/versioning.star +1 -0
  36. package/dist/commands/config.d.ts.map +1 -1
  37. package/dist/commands/config.js +11 -0
  38. package/dist/commands/config.js.map +1 -1
  39. package/dist/commands/doctor.d.ts.map +1 -1
  40. package/dist/commands/doctor.js +1 -2
  41. package/dist/commands/doctor.js.map +1 -1
  42. package/dist/commands/project.d.ts.map +1 -1
  43. package/dist/commands/project.js +36 -41
  44. package/dist/commands/project.js.map +1 -1
  45. package/dist/commands/resource.d.ts.map +1 -1
  46. package/dist/commands/resource.js +51 -55
  47. package/dist/commands/resource.js.map +1 -1
  48. package/dist/commands/stack.d.ts.map +1 -1
  49. package/dist/commands/stack.js +22 -24
  50. package/dist/commands/stack.js.map +1 -1
  51. package/dist/commands/ui.d.ts.map +1 -1
  52. package/dist/commands/ui.js +1 -2
  53. package/dist/commands/ui.js.map +1 -1
  54. package/dist/commands/up.d.ts.map +1 -1
  55. package/dist/commands/up.js +1 -2
  56. package/dist/commands/up.js.map +1 -1
  57. package/dist/commands/upgrade.d.ts +8 -0
  58. package/dist/commands/upgrade.d.ts.map +1 -1
  59. package/dist/commands/upgrade.js +62 -21
  60. package/dist/commands/upgrade.js.map +1 -1
  61. package/dist/generator/extension-fetch.d.ts +19 -0
  62. package/dist/generator/extension-fetch.d.ts.map +1 -1
  63. package/dist/generator/extension-fetch.js +71 -5
  64. package/dist/generator/extension-fetch.js.map +1 -1
  65. package/dist/generator/template-engine.d.ts +1 -0
  66. package/dist/generator/template-engine.d.ts.map +1 -1
  67. package/dist/generator/template-engine.js +50 -6
  68. package/dist/generator/template-engine.js.map +1 -1
  69. package/dist/utils/command-helpers.d.ts.map +1 -1
  70. package/dist/utils/command-helpers.js +7 -9
  71. package/dist/utils/command-helpers.js.map +1 -1
  72. package/dist/utils/constants.d.ts +1 -0
  73. package/dist/utils/constants.d.ts.map +1 -1
  74. package/dist/utils/constants.js +1 -0
  75. package/dist/utils/constants.js.map +1 -1
  76. package/dist/utils/errors.d.ts +2 -0
  77. package/dist/utils/errors.d.ts.map +1 -1
  78. package/dist/utils/errors.js +6 -1
  79. package/dist/utils/errors.js.map +1 -1
  80. package/dist/utils/paths.js +1 -1
  81. package/dist/utils/paths.js.map +1 -1
  82. package/dist/utils/project-features.d.ts.map +1 -1
  83. package/dist/utils/project-features.js +1 -1
  84. package/dist/utils/project-features.js.map +1 -1
  85. package/dist/utils/resource-features.d.ts.map +1 -1
  86. package/dist/utils/resource-features.js +2 -2
  87. package/dist/utils/resource-features.js.map +1 -1
  88. package/dist/utils/tar.js +4 -4
  89. package/dist/utils/tar.js.map +1 -1
  90. package/dist/utils/validation.d.ts +7 -0
  91. package/dist/utils/validation.d.ts.map +1 -1
  92. package/dist/utils/validation.js +9 -0
  93. package/dist/utils/validation.js.map +1 -1
  94. package/engine/AGENTS.md +705 -0
  95. package/engine/README.md +29 -0
  96. package/engine/REFACTORING_MANIFEST_SYSTEM.md +974 -0
  97. package/engine/Tiltfile +80 -0
  98. package/engine/assets/docker/golden-layers.Dockerfile +221 -0
  99. package/engine/assets/scripts/cleanup-completed-migrator-images.sh +37 -0
  100. package/engine/assets/scripts/cleanup-tilt-images.sh +120 -0
  101. package/engine/assets/scripts/mac-m1-resource-monitor.sh +121 -0
  102. package/engine/config.star +3 -0
  103. package/engine/docs/AUTODISCOVERY_TEST.md +182 -0
  104. package/engine/docs/C4-ARCHITECTURE-operations.md +396 -0
  105. package/engine/docs/C4-ARCHITECTURE-overview.md +284 -0
  106. package/engine/docs/C4-ARCHITECTURE.md +17 -0
  107. package/engine/docs/GOLDEN_IMAGE_INTEGRATION.md +349 -0
  108. package/engine/docs/MANIFEST_DRIVEN_ARCHITECTURE.md +357 -0
  109. package/engine/docs/README.md +284 -0
  110. package/engine/entrypoint.star +97 -0
  111. package/engine/lifecycle/orchestrator.star +260 -0
  112. package/engine/paths.star +717 -0
  113. package/engine/schemas/manifest-schema.json +301 -0
  114. package/engine/schemas/service-schema.json +301 -0
  115. package/engine/scripts/README.md +89 -0
  116. package/engine/scripts/build-and-publish-lib.sh +205 -0
  117. package/engine/scripts/check-lib-publish.sh +85 -0
  118. package/engine/scripts/debug-container.sh +258 -0
  119. package/engine/scripts/generate-manifest.sh +197 -0
  120. package/engine/spec.master +702 -0
  121. package/engine/spec.master.example +341 -0
  122. package/engine/topologies/README.md +34 -0
  123. package/engine/topologies/platform/docker/AGENTS.md +59 -0
  124. package/engine/topologies/platform/docker/auth/auth.star +167 -0
  125. package/engine/topologies/platform/docker/build/golden_image.star +37 -0
  126. package/engine/topologies/platform/docker/build/golden_image_build.star +82 -0
  127. package/engine/topologies/platform/docker/build/golden_image_constants.star +93 -0
  128. package/engine/topologies/platform/docker/build/golden_image_dockerfile.star +291 -0
  129. package/engine/topologies/platform/docker/compose/compose.star +636 -0
  130. package/engine/topologies/platform/docker/compose/compose_helpers.star +52 -0
  131. package/engine/topologies/platform/docker/compose/traefik_standalone.star +53 -0
  132. package/engine/topologies/platform/docker/config/bunignore.star +142 -0
  133. package/engine/topologies/platform/docker/config/dockerignore.star +150 -0
  134. package/engine/topologies/platform/docker/constants.star +170 -0
  135. package/engine/topologies/platform/docker/dockerfile/dockerfile.star +54 -0
  136. package/engine/topologies/platform/docker/generators/golden_docker_generator_v2.star +73 -0
  137. package/engine/topologies/platform/docker/index.star +27 -0
  138. package/engine/topologies/platform/docker/layers/bun_helpers.star +23 -0
  139. package/engine/topologies/platform/docker/layers/infisical/index.star +40 -0
  140. package/engine/topologies/platform/docker/layers/infisical/infisical_docker.star +262 -0
  141. package/engine/topologies/platform/docker/layers/l1_base_layers.star +87 -0
  142. package/engine/topologies/platform/docker/layers/l2_dependency_layers.star +125 -0
  143. package/engine/topologies/platform/docker/layers/l3_builder_layers.star +209 -0
  144. package/engine/topologies/platform/docker/layers/l4_runtime_layers.star +214 -0
  145. package/engine/topologies/platform/docker/layers/prisma/constants.star +135 -0
  146. package/engine/topologies/platform/docker/layers/prisma/db_readiness.star +96 -0
  147. package/engine/topologies/platform/docker/layers/prisma/filesystem_setup.star +109 -0
  148. package/engine/topologies/platform/docker/layers/prisma/migrate_script.star +98 -0
  149. package/engine/topologies/platform/docker/layers/prisma/prisma_build.star +126 -0
  150. package/engine/topologies/platform/docker/layers/prisma/prisma_runtime.star +161 -0
  151. package/engine/topologies/platform/docker/layers/prisma/secret_resolution.star +119 -0
  152. package/engine/topologies/platform/docker/networking/api_path_constants.star +230 -0
  153. package/engine/topologies/platform/docker/networking/sablier_container_cycle.star +27 -0
  154. package/engine/topologies/platform/docker/networking/traefik.star +232 -0
  155. package/engine/topologies/platform/docker/networking/traefik_constants.star +146 -0
  156. package/engine/topologies/platform/docker/networking/traefik_helpers.star +160 -0
  157. package/engine/topologies/platform/docker/secrets/infisical.star +135 -0
  158. package/engine/topologies/platform/net/proxy.star +4 -0
  159. package/engine/topologies/platform/registries/local.star +4 -0
  160. package/engine/topologies/platform/security/secrets.star +239 -0
  161. package/engine/topologies/platform/state/relational.star +4 -0
  162. package/engine/topologies/tilt/common/AGENTS.md +59 -0
  163. package/engine/topologies/tilt/common/utils.star +364 -0
  164. package/engine/topologies/tilt/common/utils_debug.star +69 -0
  165. package/engine/topologies/tilt/common/utils_deterministic.star +168 -0
  166. package/engine/topologies/tilt/common/utils_docker_networks.star +46 -0
  167. package/engine/topologies/tilt/common/utils_env.star +43 -0
  168. package/engine/topologies/tilt/common/utils_output.star +97 -0
  169. package/engine/topologies/tilt/config/AGENTS.md +68 -0
  170. package/engine/topologies/tilt/config/defaults.star +3 -0
  171. package/engine/topologies/tilt/config/feature_flags.star +10 -0
  172. package/engine/topologies/tilt/config/global.star +55 -0
  173. package/engine/topologies/tilt/config/profiles.star +382 -0
  174. package/engine/topologies/tilt/generators/agents_md.star +62 -0
  175. package/engine/topologies/tilt/generators/api_gateway.star +145 -0
  176. package/engine/topologies/tilt/generators/index.star +124 -0
  177. package/engine/topologies/tilt/generators/infisical/README.md +424 -0
  178. package/engine/topologies/tilt/generators/infisical/examples.star +312 -0
  179. package/engine/topologies/tilt/generators/infisical/index.star +57 -0
  180. package/engine/topologies/tilt/generators/infisical/machine_identity.star +420 -0
  181. package/engine/topologies/tilt/generators/infisical/organization.star +534 -0
  182. package/engine/topologies/tilt/generators/infisical/path_manager.star +476 -0
  183. package/engine/topologies/tilt/generators/infisical/secrets_generator.star +420 -0
  184. package/engine/topologies/tilt/generators/nginx_conf.star +143 -0
  185. package/engine/topologies/tilt/generators/npmrc.star +111 -0
  186. package/engine/topologies/tilt/generators/tsconfig.star +23 -0
  187. package/engine/topologies/tilt/generators/typescript/backend_library_tsconfig.star +71 -0
  188. package/engine/topologies/tilt/generators/typescript/backend_tsconfig.star +124 -0
  189. package/engine/topologies/tilt/generators/typescript/common.star +7 -0
  190. package/engine/topologies/tilt/generators/typescript/frontend_library_tsconfig.star +76 -0
  191. package/engine/topologies/tilt/generators/typescript/frontend_tsconfig.star +110 -0
  192. package/engine/topologies/tilt/generators/typescript/include.star +23 -0
  193. package/engine/topologies/tilt/generators/typescript/playwright_config.star +40 -0
  194. package/engine/topologies/tilt/generators/typescript/prisma_config.star +49 -0
  195. package/engine/topologies/tilt/generators/validators.star +853 -0
  196. package/engine/topologies/tilt/generators/vite/backend.star +78 -0
  197. package/engine/topologies/tilt/generators/vite/frontend.star +98 -0
  198. package/engine/topologies/tilt/generators/vite/generators.star +43 -0
  199. package/engine/topologies/tilt/generators/vite/helpers.star +244 -0
  200. package/engine/topologies/tilt/generators/vite/library.star +65 -0
  201. package/engine/topologies/tilt/generators/vite/sdk.star +73 -0
  202. package/engine/topologies/tilt/generators/vite/templates.star +737 -0
  203. package/engine/topologies/tilt/generators/vite_config.star +22 -0
  204. package/engine/topologies/tilt/manifest/AGENTS.md +61 -0
  205. package/engine/topologies/tilt/manifest/README.md +693 -0
  206. package/engine/topologies/tilt/manifest/__init__.star +218 -0
  207. package/engine/topologies/tilt/manifest/constants.star +252 -0
  208. package/engine/topologies/tilt/manifest/errors.star +266 -0
  209. package/engine/topologies/tilt/manifest/integration.star +339 -0
  210. package/engine/topologies/tilt/manifest/json_to_yaml.py +54 -0
  211. package/engine/topologies/tilt/manifest/loader.star +214 -0
  212. package/engine/topologies/tilt/manifest/mapper.star +227 -0
  213. package/engine/topologies/tilt/manifest/parser.star +400 -0
  214. package/engine/topologies/tilt/manifest/schema.star +462 -0
  215. package/engine/topologies/tilt/manifest/tests/test_integration.star +276 -0
  216. package/engine/topologies/tilt/manifest/tests/test_loader_parser.star +397 -0
  217. package/engine/topologies/tilt/manifest/tests/test_manifest.star +316 -0
  218. package/engine/topologies/tilt/manifest/tests/test_validator.star +470 -0
  219. package/engine/topologies/tilt/manifest/validator.star +717 -0
  220. package/engine/topologies/tilt/manifest/yaml_to_json.py +18 -0
  221. package/engine/topologies/tilt/resources/AGENTS.md +71 -0
  222. package/engine/topologies/tilt/resources/conditions.star +3 -0
  223. package/engine/topologies/tilt/resources/databases.star +244 -0
  224. package/engine/topologies/tilt/resources/declaration.star +3 -0
  225. package/engine/topologies/tilt/resources/deps.star +3 -0
  226. package/engine/topologies/tilt/resources/infra-loader.star +437 -0
  227. package/engine/topologies/tilt/resources/libs.star +30 -0
  228. package/engine/topologies/tilt/resources/libs_discovery.star +102 -0
  229. package/engine/topologies/tilt/resources/libs_paths.star +79 -0
  230. package/engine/topologies/tilt/resources/libs_resource_definition.star +151 -0
  231. package/engine/topologies/tilt/resources/libs_setup.star +164 -0
  232. package/engine/topologies/tilt/resources/libs_tsconfig.star +37 -0
  233. package/engine/topologies/tilt/resources/orchestrator/apply.star +77 -0
  234. package/engine/topologies/tilt/resources/orchestrator/apply_compose_resource_registration.star +431 -0
  235. package/engine/topologies/tilt/resources/orchestrator/apply_manifest_orchestration.star +81 -0
  236. package/engine/topologies/tilt/resources/orchestrator/apply_migrator_orchestration.star +148 -0
  237. package/engine/topologies/tilt/resources/orchestrator/apply_resource_validation.star +36 -0
  238. package/engine/topologies/tilt/resources/orchestrator/apply_runtime_flags.star +44 -0
  239. package/engine/topologies/tilt/resources/orchestrator/builders/typescript.star +164 -0
  240. package/engine/topologies/tilt/resources/orchestrator/generators/dependencies/AGENTS.md +75 -0
  241. package/engine/topologies/tilt/resources/orchestrator/generators/dependencies/index.star +21 -0
  242. package/engine/topologies/tilt/resources/orchestrator/generators/dependencies/resolver.star +134 -0
  243. package/engine/topologies/tilt/resources/orchestrator/generators/env.star +258 -0
  244. package/engine/topologies/tilt/resources/orchestrator/generators/frontend.star +169 -0
  245. package/engine/topologies/tilt/resources/orchestrator/generators/manifest_resource.star +524 -0
  246. package/engine/topologies/tilt/resources/orchestrator/helpers.star +33 -0
  247. package/engine/topologies/tilt/resources/orchestrator.star +54 -0
  248. package/engine/topologies/tilt/resources/ordering.star +3 -0
  249. package/engine/topologies/tilt/resources/triggers.star +3 -0
  250. package/engine/topologies/tilt/resources/watchers.star +299 -0
  251. package/engine/where-things-live.star +717 -0
  252. package/ext/Tiltfile +66 -0
  253. package/ext/ide-components/README.md +219 -0
  254. package/ext/ide-components/code_executor/server.py +268 -0
  255. package/ext/ide-components/code_viewer/server.py +206 -0
  256. package/ext/ide-components/config_inspector/server.py +1050 -0
  257. package/ext/ide-components/file_browser/server.py +285 -0
  258. package/ext/ide-components/shared/config_service.py +469 -0
  259. package/ext/ide-components/shared/file_utils.py +298 -0
  260. package/ext/ide-components/shared/http_utils.py +232 -0
  261. package/ext/ide-components/shared/static/styles.css +1334 -0
  262. package/ext/ide-components/shared/syntax_highlighter.py +140 -0
  263. package/ext/ide-components/shared/template_engine.py +123 -0
  264. package/ext/ide-components/shared/templates/base.html +121 -0
  265. package/ext/ide-components/shared/test_config_service.py +326 -0
  266. package/ext/ide-components/shared/tilt_integration.py +158 -0
  267. package/ext/ui-enhancements/cron-status-server.sh +49 -0
  268. package/ext/ui-enhancements/cron-status-tracker.sh +146 -0
  269. package/ext/ui-enhancements/extension.yaml +36 -0
  270. package/ext/ui-enhancements/tiltfile.py +99 -0
  271. package/ext/ui-enhancements/ui/cron-jobs-tab.css +396 -0
  272. package/ext/ui-enhancements/ui/help-panel.css +279 -0
  273. package/ext/ui-enhancements/ui/icons.css +125 -0
  274. package/ext/ui-enhancements/ui/tooltips.css +114 -0
  275. package/package.json +13 -9
  276. package/specs/specs/TILT_SERVICE_DEFAULTS.star +205 -0
  277. package/specs/specs/TILT_TECH_STACK.star +159 -0
@@ -0,0 +1,209 @@
1
+ # === INLINED CONSTANTS for pure extension loading ===
2
+ WEB_FRAMEWORK = "hono"
3
+ RUNTIME_CONFIG = {"bun": {"image_base": "oven/bun:latest", "package_manager": "bun", "lockfile": "bun.lock", "backend_start_command": "bun run start", "frontend_start_command": "bun run dev"}, "node": {"image_base": "node:20-alpine", "package_manager": "npm", "lockfile": "package-lock.json", "backend_start_command": "node dist/index.js"}}
4
+ OUTPUT = struct(AUTOGENERATED_FOLDER = ".autogenerated")
5
+ # === END INLINED CONSTANTS ===
6
+
7
+
8
+ """
9
+ L3 Builder Layers - Compilation and Build Stages
10
+
11
+ Handles the build stages for different application types:
12
+ - l3_backend_compiler: TypeScript backend compilation
13
+ - l3_frontend_builder: Frontend application building
14
+ - l3_migration_engine: Prisma migration preparation
15
+ - l3_production_purger: Production dependency stripping
16
+ """
17
+
18
+ load('./l1_base_layers.star', 'BUN_BASE')
19
+ load('./l2_dependency_layers.star', 'GOLDEN_L2_IMAGE', 'normalize_res_path')
20
+ load('../../../../../discovery/config.star', 'GLOBAL_CONFIG')
21
+ load('../../../tilt/manifest/constants.star', 'AUTOGENERATED_CONFIG_PATHS')
22
+
23
+
24
+
25
+ load('./prisma/prisma_build.star',
26
+ 'prisma_copy_instructions',
27
+ 'prisma_generate_instructions',
28
+ 'prisma_normalize_output',
29
+ 'L3_generate_migration_engine',
30
+ )
31
+ load('./infisical/infisical_docker.star', 'InfisicalDocker')
32
+
33
+ # Load project name for dynamic golden image naming
34
+ # Use TDK_PROJECT_ROOT env var set by Tilt, fallback to current directory
35
+ def _load_golden_prefix():
36
+ project_root = os.environ.get('TDK_PROJECT_ROOT', '')
37
+ project_json_path = '.tdk/project.json'
38
+ if project_root:
39
+ project_json_path = project_root + '/' + project_json_path
40
+
41
+ if os.path.exists(project_json_path):
42
+ _project_json = read_json(project_json_path)
43
+ return _project_json.get('project', {}).get('name', 'tdk-project')
44
+ return 'tdk-project'
45
+
46
+ _GOLDEN_PREFIX = _load_golden_prefix()
47
+
48
+ _docker_cfg = GLOBAL_CONFIG['docker']
49
+ GOLDEN_L3_BACKEND_IMAGE = _docker_cfg.get('golden_l3_backend_image', _GOLDEN_PREFIX + '-l3-backend:latest')
50
+ GOLDEN_L3_FRONTEND_IMAGE = _docker_cfg.get('golden_l3_frontend_image', _GOLDEN_PREFIX + '-l3-frontend:latest')
51
+
52
+
53
+ def L3_generate_backend_compiler(res_path, build_cmd = RUNTIME_CONFIG["bun"]["backend_start_command"], use_prisma = True, use_shared_libs = True, use_infisical = True, use_golden = True, has_prisma_config = False):
54
+ """
55
+ Generate the backend compiler layer for TypeScript services.
56
+
57
+ Args:
58
+ res_path: Resource path (service directory)
59
+ build_cmd: Build command to run (default: from RUNTIME_CONFIG)
60
+ use_prisma: Include Prisma setup (default: True)
61
+ use_shared_libs: Include shared library copies (default: True)
62
+ use_infisical: Include Infisical CLI installation (default: True)
63
+ use_golden: Whether to use golden L3-backend image (default: True)
64
+ has_prisma_config: Whether the service has Prisma config (default: False)
65
+
66
+ Returns:
67
+ Dockerfile content string for the l3_backend_build stage
68
+ """
69
+ # Normalize res_path for Docker COPY (must be relative to build context)
70
+ res_path_rel = normalize_res_path(res_path)
71
+
72
+ base_image = GOLDEN_L3_BACKEND_IMAGE if use_golden else BUN_BASE
73
+ prisma_copy = prisma_copy_instructions(res_path) if use_prisma else ""
74
+ prisma_generate = prisma_generate_instructions() if use_prisma else ""
75
+ prisma_compat = prisma_normalize_output() if use_prisma else ""
76
+ parts = [
77
+ "# ---- L3: backend_compiler ----\n",
78
+ "FROM " + base_image + " AS l3_backend_build\n",
79
+ "WORKDIR /app/" + res_path + "\n",
80
+ "# Build argument to skip Infisical setup (for local dev / fast builds)\n",
81
+ "ARG SKIP_INFISICAL_SETUP=0\n",
82
+ "# Reuse resolved dependencies from l2_deps_manifest to avoid reinstalling in L3\n",
83
+ "COPY --link --from=l2_deps_manifest /app/" + res_path + "/node_modules ./node_modules\n",
84
+ "# Bun isolated linker symlinks may resolve through /app/node_modules/.bun\n",
85
+ "COPY --link --from=l2_deps_manifest /app/node_modules/.bun /app/node_modules/.bun\n",
86
+ "# Copy manifest files for dependency installation (in case L2 is stale)\n",
87
+ "COPY " + res_path_rel + "/package.json ./package.json\n",
88
+ "COPY " + res_path_rel + "/" + AUTOGENERATED_CONFIG_PATHS['bunfig_docker'] + " ./bunfig.toml\n",
89
+ "COPY " + res_path_rel + "/" + AUTOGENERATED_CONFIG_PATHS['npmrc_docker'] + " ./.npmrc\n",
90
+ "COPY " + res_path_rel + "/" + OUTPUT.AUTOGENERATED_FOLDER + "/tsconfig.docker.autogenerated.json ./tsconfig.json\n",
91
+ "COPY " + res_path_rel + "/" + OUTPUT.AUTOGENERATED_FOLDER + "/tsconfig.autogenerated.json ./" + OUTPUT.AUTOGENERATED_FOLDER + "/tsconfig.autogenerated.json\n",
92
+ "COPY " + res_path_rel + "/" + OUTPUT.AUTOGENERATED_FOLDER + "/*.ts ./" + OUTPUT.AUTOGENERATED_FOLDER + "/\n",
93
+ "COPY " + res_path_rel + "/src ./src\n",
94
+ prisma_copy,
95
+ prisma_generate,
96
+ prisma_compat,
97
+ ]
98
+ # shared libs (@{npm_scope}/*) are resolved from Verdaccio by l2_deps_manifest
99
+ # and already present in node_modules — no COPY of shared-* source dirs needed.
100
+ # Use InfisicalDocker generator for CLI setup (if not using golden image)
101
+ if use_infisical and not use_golden:
102
+ parts.append(InfisicalDocker.builder_setup(
103
+ use_infisical=use_infisical,
104
+ use_golden=use_golden,
105
+ ))
106
+ parts.append("ENV NODE_ENV=production\n")
107
+ parts.append("RUN " + build_cmd + "\n")
108
+ parts.append("# Fix " + WEB_FRAMEWORK + "/cors subpath import for Bun runtime compatibility\n")
109
+ parts.append("RUN find ./dist -type f -name \"*.js\" -exec sed -i \"s|from '" + WEB_FRAMEWORK + "/cors'|from '../node_modules/" + WEB_FRAMEWORK + "/dist/middleware/cors/index.js'|g\" {} + || true\n")
110
+ return "".join(parts)
111
+
112
+
113
+ def L3_generate_frontend_builder(res_path, build_cmd = RUNTIME_CONFIG["bun"]["backend_start_command"], use_infisical = False, use_shared_libs = True, use_golden = True):
114
+ """
115
+ Generate the frontend builder layer for Vue/React applications.
116
+
117
+ Args:
118
+ res_path: Resource path (service directory)
119
+ build_cmd: Build command to run (default: from RUNTIME_CONFIG)
120
+ use_infisical: Include Infisical CLI installation (default: False)
121
+ use_shared_libs: Include shared library copies (default: True)
122
+ use_golden: Whether to use golden L3-frontend image (default: True)
123
+
124
+ Returns:
125
+ Dockerfile content string for the l3_frontend_build stage
126
+ """
127
+ # Normalize res_path for Docker COPY (must be relative to build context)
128
+ res_path_rel = normalize_res_path(res_path)
129
+
130
+ # Use golden L3-frontend image if enabled (no Prisma)
131
+ base_image = GOLDEN_L3_FRONTEND_IMAGE if use_golden else BUN_BASE
132
+
133
+ parts = [
134
+ "# ---- L3: frontend_builder ----\n",
135
+ "FROM " + base_image + " AS l3_frontend_build\n",
136
+ "WORKDIR /app/" + res_path + "\n",
137
+ "# Build argument to skip Infisical setup (for local dev / fast builds)\n",
138
+ "ARG SKIP_INFISICAL_SETUP=1\n",
139
+ "# Reuse resolved dependencies from l2_deps_manifest to avoid reinstalling in L3\n",
140
+ "COPY --link --from=l2_deps_manifest /app/" + res_path + "/node_modules ./node_modules\n",
141
+ # Bun isolated linker symlinks may resolve through /app/node_modules/.bun.
142
+ "COPY --link --from=l2_deps_manifest /app/node_modules/.bun /app/node_modules/.bun\n",
143
+ "# Copy manifest files required by the build\n",
144
+ "COPY " + res_path_rel + "/package.json ./package.json\n",
145
+ "COPY " + res_path_rel + "/" + AUTOGENERATED_CONFIG_PATHS['bunfig_docker'] + " ./bunfig.toml\n",
146
+ "COPY " + res_path_rel + "/" + OUTPUT.AUTOGENERATED_FOLDER + "/tsconfig.docker.autogenerated.json ./tsconfig.json\n",
147
+ "COPY " + res_path_rel + "/" + OUTPUT.AUTOGENERATED_FOLDER + "/tsconfig.autogenerated.json ./" + OUTPUT.AUTOGENERATED_FOLDER + "/tsconfig.autogenerated.json\n",
148
+ # Copy ALL TypeScript files from autogenerated directory (env.ts, api-client.ts, vite configs, etc.)
149
+ "COPY " + res_path_rel + "/" + OUTPUT.AUTOGENERATED_FOLDER + "/*.ts ./" + OUTPUT.AUTOGENERATED_FOLDER + "/\n",
150
+ "COPY " + res_path_rel + "/src ./src\n",
151
+ "COPY " + res_path_rel + "/public ./public\n",
152
+ "COPY " + res_path_rel + "/index.html ./index.html\n",
153
+ ]
154
+ # shared libs (@{npm_scope}/*) are resolved from Verdaccio by l2_deps_manifest
155
+ # and already present in node_modules — no COPY of shared-* source dirs needed.
156
+ # Use InfisicalDocker generator for CLI setup (if not using golden image)
157
+ if use_infisical and not use_golden:
158
+ parts.append(InfisicalDocker.builder_setup(
159
+ use_infisical=use_infisical,
160
+ use_golden=use_golden,
161
+ ))
162
+ parts.append("ENV NODE_ENV=production\n")
163
+ parts.append("RUN " + build_cmd + "\n")
164
+ return "".join(parts)
165
+
166
+
167
+ # L3_generate_migration_engine is now loaded from prisma/prisma_build.star
168
+
169
+
170
+ def L3_generate_production_purger(res_path, use_golden = True):
171
+ """
172
+ Generate the production purger layer that removes development dependencies.
173
+
174
+ Implements Option 2: Reduce node_modules size by:
175
+ 1. Installing only production dependencies (--production flag)
176
+ 2. Removing unnecessary files (.md, .ts, .map, test files, etc.)
177
+ 3. Pruning package.json files from node_modules
178
+ 4. Removing optional dependencies not needed at runtime
179
+
180
+ Args:
181
+ res_path: Resource path (service directory)
182
+ use_golden: Whether to use golden L2 image (default: True)
183
+
184
+ Returns:
185
+ Dockerfile content string for the l3_production_purger stage
186
+ """
187
+ # Normalize res_path for Docker COPY (must be relative to build context)
188
+ res_path_rel = normalize_res_path(res_path)
189
+
190
+ # Use golden L2 image if enabled (Bun + system deps pre-installed)
191
+ base_image = GOLDEN_L2_IMAGE if use_golden else BUN_BASE
192
+
193
+ return (
194
+ "# ---- L3: production_purger ----\n"
195
+ + "FROM " + base_image + " AS l3_production_purger\n"
196
+ + "WORKDIR /app/" + res_path + "\n"
197
+ + "COPY " + res_path_rel + "/package.json ./package.json\n"
198
+ + "COPY " + res_path_rel + "/" + AUTOGENERATED_CONFIG_PATHS['bunfig_docker'] + " ./bunfig.toml\n"
199
+ + "COPY " + res_path_rel + "/" + AUTOGENERATED_CONFIG_PATHS['npmrc_docker'] + " ./.npmrc\n"
200
+ + "COPY --link --from=l2_deps_manifest /cache/bun /cache/bun\n"
201
+ # sharing=shared allows parallel builds without lock contention (Bun cache is atomic)
202
+ + "RUN --mount=type=cache,target=/cache/bun,sharing=shared bun install --production --cache-dir=/cache/bun\n"
203
+ + "# Option 2: Aggressive node_modules pruning to reduce size\n"
204
+ + "# NOTE: Keep .d.ts files - they are needed for Bun module resolution with subpath exports\n"
205
+ + "RUN find node_modules -type f \\( -name '*.md' -o -name '*.ts' ! -name '*.d.ts' -o -name '*.map' -o -name '*.test.js' -o -name '*.spec.js' -o -name 'README*' -o -name 'CHANGELOG*' -o -name 'LICENSE*' \\) -delete\n"
206
+ + "RUN find node_modules -type d \\( -name '.bin' -o -name 'test' -o -name 'tests' -o -name '__tests__' -o -name 'spec' -o -name 'specs' -o -name '.github' -o -name 'docs' -o -name 'examples' \\) -exec rm -rf {} + 2>/dev/null || true\n"
207
+ )
208
+
209
+ GLOBAL_CONFIG = {}
@@ -0,0 +1,214 @@
1
+ # === INLINED CONSTANTS for pure extension loading ===
2
+ BASE_PORT_FRONTEND = 3000
3
+ BASE_PORT_BACKEND = 4000
4
+ get_docker_healthcheck_config = lambda: {"path": "/health", "interval": "10s", "timeout": "5s"}
5
+ OUTPUT = struct(AUTOGENERATED_FOLDER = ".autogenerated")
6
+ # === END INLINED CONSTANTS ===
7
+
8
+
9
+ """
10
+ L4 Runtime Layers - Final Application Runtime Stages
11
+
12
+ Handles the final runtime stages for deployed applications:
13
+ - l4_backend_runtime: Backend service runtime with Bun
14
+ - l4_frontend_runtime: Frontend runtime with Nginx or Bun static
15
+ - l4_migrator_runtime: Database migration runner with Infisical integration
16
+ """
17
+
18
+ load('./l1_base_layers.star', 'BUN_BASE')
19
+ load('./l2_dependency_layers.star', 'normalize_res_path')
20
+ load('../../../../../discovery/config.star', 'GLOBAL_CONFIG')
21
+ load('../../../tilt/common/utils_debug.star', 'DEBUG_MODE')
22
+ load('../../../tilt/manifest/constants.star', 'AUTOGENERATED_CONFIG_PATHS')
23
+ load('./prisma/prisma_runtime.star',
24
+ 'prisma_runtime_copy',
25
+ 'prisma_bun_symlink_fix',
26
+ 'prisma_config_copy',
27
+ 'L4_generate_migrator_runtime',
28
+ )
29
+
30
+ load('./bun_helpers.star', 'bun_hoisted_packages_symlink_fix')
31
+ load('./infisical/infisical_docker.star', 'InfisicalDocker')
32
+
33
+
34
+ # Load project name for dynamic golden image naming
35
+ # Use TDK_PROJECT_ROOT env var set by Tilt, fallback to current directory
36
+ def _load_golden_prefix():
37
+ project_root = os.environ.get('TDK_PROJECT_ROOT', '')
38
+ project_json_path = '.tdk/project.json'
39
+ if project_root:
40
+ project_json_path = project_root + '/' + project_json_path
41
+
42
+ if os.path.exists(project_json_path):
43
+ _project_json = read_json(project_json_path)
44
+ return _project_json.get('project', {}).get('name', 'tdk-project')
45
+ return 'tdk-project'
46
+
47
+ _GOLDEN_PREFIX = _load_golden_prefix()
48
+
49
+ _docker_cfg = GLOBAL_CONFIG['docker']
50
+ GOLDEN_L4_BACKEND_IMAGE = _docker_cfg.get('golden_l4_backend_image', _GOLDEN_PREFIX + '-l4-backend:latest')
51
+ GOLDEN_L4_FRONTEND_IMAGE = _docker_cfg.get('golden_l4_frontend_image', _GOLDEN_PREFIX + '-l4-frontend:latest')
52
+
53
+ # Load Docker healthcheck configuration
54
+ _docker_health = get_docker_healthcheck_config()
55
+
56
+
57
+ def L4_generate_backend_runtime(res_path, port = BASE_PORT_BACKEND, cmd = 'bun run start', use_infisical = True, resource_name = 'service', use_golden = True, has_prisma_config = False, manifest = None):
58
+ """
59
+ Generate the backend runtime layer for deployed services.
60
+
61
+ Args:
62
+ res_path: Resource path (service directory)
63
+ port: Port to expose (default: BASE_PORT_BACKEND from master config)
64
+ cmd: Command to run (default: 'bun run start')
65
+ use_infisical: Enable Infisical secret management (default: True)
66
+ resource_name: Service name for logging and configuration (default: 'service')
67
+ use_golden: Whether to use golden L4-backend image (default: True)
68
+ has_prisma_config: Whether service has Prisma config (default: False)
69
+ manifest: Service manifest dict for feature detection (default: None)
70
+
71
+ Returns:
72
+ Dockerfile content string for the l4_backend_runtime stage
73
+ """
74
+ # Normalize res_path for Docker COPY (must be relative to build context)
75
+ res_path_rel = normalize_res_path(res_path)
76
+
77
+ # Use golden L4-backend image if enabled (production-optimized backend runtime)
78
+ base_image = GOLDEN_L4_BACKEND_IMAGE if use_golden else BUN_BASE
79
+
80
+ parts = [
81
+ "# ---- L4: backend_runtime ----\n",
82
+ "FROM " + base_image + " AS l4_backend_runtime\n",
83
+ "WORKDIR /app/" + res_path + "\n",
84
+ "# Build argument to skip Infisical setup (for local dev / fast builds)\n",
85
+ "ARG SKIP_INFISICAL_SETUP=0\n",
86
+ "ENV NODE_ENV=production\n",
87
+ "COPY --from=l3_production_purger /app/" + res_path + "/node_modules ./node_modules\n",
88
+ # Bun isolated linker creates service symlinks that resolve through /app/node_modules/.bun.
89
+ # Copy from production_purger to avoid dragging full dev dependency store into runtime.
90
+ "COPY --from=l3_production_purger /app/" + res_path + "/node_modules/.bun /app/node_modules/.bun\n",
91
+ prisma_runtime_copy(res_path),
92
+ "COPY --from=l3_backend_build /app/" + res_path + "/dist ./dist\n",
93
+ "COPY " + res_path_rel + "/package.json ./package.json\n",
94
+ prisma_bun_symlink_fix(),
95
+ bun_hoisted_packages_symlink_fix(),
96
+ ]
97
+
98
+ # Check for special tooling requirements from manifest features
99
+ # Services requiring Hugo (or other tools) should specify in manifest features array
100
+ manifest_features = manifest.get('features', []) if manifest else []
101
+ if "hugo" in manifest_features:
102
+ parts.append("USER root\n")
103
+ parts.append("RUN apk add --no-cache hugo\n")
104
+ parts.append("USER bun\n")
105
+
106
+ if has_prisma_config:
107
+ # Prisma v7 migrate deploy reads datasource.url from prisma.config.ts in CWD
108
+ parts.append(prisma_config_copy(res_path))
109
+
110
+ # Only set USER if not using golden image (already set in golden L4)
111
+ if not use_golden:
112
+ parts.append("USER bun\n")
113
+
114
+ parts.extend([
115
+ "EXPOSE " + str(port) + "\n",
116
+ ])
117
+
118
+ # Only add healthcheck if not using golden image (already in golden L4)
119
+ if not use_golden:
120
+ parts.append("HEALTHCHECK --interval={}s --timeout={}s --start-period={}s --retries={} CMD bun --version || exit 1\n".format(
121
+ _docker_health["interval_seconds"],
122
+ _docker_health["timeout_seconds"],
123
+ _docker_health["start_period_seconds"],
124
+ _docker_health["retries"],
125
+ ))
126
+
127
+ if use_infisical:
128
+ # Use InfisicalDocker generator for proper secret injection setup
129
+ # This uses Starlark generators instead of hardcoded values
130
+ infisical_setup = InfisicalDocker.runtime_setup(
131
+ resource_name=resource_name,
132
+ secret_path=None, # Auto-generate from resource_name
133
+ resource_type="backend",
134
+ command=cmd,
135
+ use_entrypoint=True,
136
+ )
137
+ parts.append(infisical_setup)
138
+ else:
139
+ parts.append("CMD [\"" + cmd + "\"]\n")
140
+
141
+ # Provide build targets that match external tooling (e.g. --target production/ development)
142
+ parts.append("\nFROM l4_backend_runtime AS production\nFROM l4_backend_runtime AS development\n")
143
+
144
+ return "".join(parts)
145
+
146
+
147
+ def L4_generate_frontend_runtime(res_path, target_path = '/usr/share/nginx/html', use_nginx = True, use_golden = True, port = None):
148
+ """
149
+ Generate the frontend runtime layer for static site serving.
150
+
151
+ Args:
152
+ res_path: Resource path (service directory)
153
+ target_path: Target path for static files (default: Nginx html directory)
154
+ use_nginx: Use Nginx for serving (default: True, uses Bun static if False)
155
+ use_golden: Whether to use golden L4-frontend image (default: True)
156
+ port: Port to expose (default: None, uses BASE_PORT_FRONTEND or 80 for nginx)
157
+
158
+ Returns:
159
+ Dockerfile content string for the l4_frontend_runtime stage
160
+ """
161
+ # Use provided port or fall back to base port constant
162
+ expose_port = port if port else BASE_PORT_FRONTEND
163
+ # Normalize res_path for Docker COPY (must be relative to build context)
164
+ res_path_rel = normalize_res_path(res_path)
165
+
166
+ if use_nginx:
167
+ # Use golden L4-frontend image if enabled (Nginx pre-configured)
168
+ base_image = GOLDEN_L4_FRONTEND_IMAGE if use_golden else "nginx:alpine"
169
+
170
+ # If using golden image, skip curl installation (already there)
171
+ healthcheck_setup = "" if use_golden else "RUN apk add --no-cache curl\n"
172
+
173
+ return (
174
+ "# ---- L4: frontend_runtime (nginx) ----\n"
175
+ + "FROM " + base_image + " AS l4_frontend_runtime\n"
176
+ + healthcheck_setup
177
+ + "COPY --from=l3_frontend_build /app/" + res_path + "/dist " + target_path + "\n"
178
+ + "COPY " + res_path_rel + "/" + OUTPUT.AUTOGENERATED_FOLDER + "/nginx.autogenerated.conf /etc/nginx/conf.d/default.conf\n"
179
+ + "EXPOSE 80\n"
180
+ + ("" if use_golden else "HEALTHCHECK --interval={}s --timeout={}s --start-period={}s --retries={} CMD curl -f http://localhost/ || exit 1\n".format(
181
+ _docker_health["interval_seconds"],
182
+ _docker_health["timeout_seconds"],
183
+ _docker_health["frontend_start_period_seconds"],
184
+ _docker_health["retries"],
185
+ ))
186
+ + "CMD [\"nginx\", \"-g\", \"daemon off;\"]\n"
187
+ + "FROM l4_frontend_runtime AS production\n"
188
+ + "FROM l4_frontend_runtime AS development\n"
189
+ )
190
+ # Use golden L4-frontend image even for Bun static serving (or BUN_BASE as fallback)
191
+ # NOTE: When use_nginx=False, we MUST use BUN_BASE because the golden L4 frontend
192
+ # image is nginx-based and doesn't have Bun installed
193
+ base_image = GOLDEN_L4_FRONTEND_IMAGE if (use_golden and use_nginx) else BUN_BASE
194
+
195
+ return (
196
+ "# ---- L4: frontend_runtime (bun static) ----\n"
197
+ + "FROM " + base_image + " AS l4_frontend_runtime\n"
198
+ + "WORKDIR /app/" + res_path + "\n"
199
+ + "COPY --from=l3_frontend_build /app/" + res_path + "/dist ./dist\n"
200
+ + "COPY --from=l3_frontend_build /app/" + res_path + "/node_modules ./node_modules\n"
201
+ + "COPY --from=l3_frontend_build /app/" + res_path + "/" + OUTPUT.AUTOGENERATED_FOLDER + " ./" + OUTPUT.AUTOGENERATED_FOLDER + "\n"
202
+ + "COPY " + res_path_rel + "/package.json ./package.json\n"
203
+ + "EXPOSE " + str(expose_port) + "\n"
204
+ + 'CMD ["bun", "run", "start"]\n'
205
+ + "FROM l4_frontend_runtime AS production\n"
206
+ + "FROM l4_frontend_runtime AS development\n"
207
+ )
208
+
209
+
210
+ # L4_generate_migrator_runtime is now loaded from prisma/prisma_runtime.star
211
+
212
+ DEBUG = {}
213
+
214
+ GLOBAL_CONFIG = {}
@@ -0,0 +1,135 @@
1
+ # === INLINED CONSTANTS for pure extension loading ===
2
+ RUNTIME = "bun"
3
+ # === END INLINED CONSTANTS ===
4
+
5
+
6
+ """
7
+ Shared constants/helpers for Prisma Docker layer generators.
8
+
9
+ Centralizes repeated paths/defaults used across prisma_*.star modules so
10
+ string-heavy Dockerfile/script fragments stay consistent and reusable.
11
+ """
12
+
13
+
14
+
15
+ APP_DIR = "/app"
16
+ NODE_MODULES_DIR = "node_modules"
17
+ NODE_MODULES_BIN_DIR = NODE_MODULES_DIR + "/.bin"
18
+ APP_NODE_MODULES_DIR = APP_DIR + "/" + NODE_MODULES_DIR
19
+ APP_NODE_MODULES_BIN_DIR = APP_NODE_MODULES_DIR + "/.bin"
20
+ APP_BUN_STORE_DIR = APP_NODE_MODULES_DIR + "/.bun"
21
+
22
+ PRISMA_DIR_NAME = "prisma"
23
+ PRISMA_SCOPE_DIR_NAME = "@prisma"
24
+ PRISMA_SCHEMA_PATH = PRISMA_DIR_NAME + "/schema.prisma"
25
+
26
+ PRISMA_CONFIG_FILE = "prisma.config.ts"
27
+ PRISMA_CONFIG_WORKDIR_PATH = "./" + PRISMA_CONFIG_FILE
28
+ PRISMA_CONFIG_ABS_PATH = APP_DIR + "/" + PRISMA_CONFIG_FILE
29
+
30
+ APP_SRC_DIR = APP_DIR + "/src"
31
+ APP_GENERATED_CLIENT_DIR = APP_DIR + "/generated-client"
32
+ APP_PRISMA_DIR = APP_DIR + "/" + PRISMA_DIR_NAME
33
+
34
+ PRISMA_DOT_DIR_REL_PATH = NODE_MODULES_DIR + "/.prisma"
35
+ PRISMA_DOT_CLIENT_REL_PATH = PRISMA_DOT_DIR_REL_PATH + "/client"
36
+ PRISMA_DOT_CLIENT_ABS_PATH = APP_DIR + "/" + PRISMA_DOT_CLIENT_REL_PATH
37
+
38
+ PRISMA_BIN_REL_PATH = NODE_MODULES_DIR + "/.bin/prisma"
39
+ PRISMA_BIN_ABS_PATH = APP_DIR + "/" + PRISMA_BIN_REL_PATH
40
+ PRISMA_BIN_SYMLINK_TARGET = "../prisma/build/index.js"
41
+
42
+ PRISMA_PACKAGE_REL_PATH = NODE_MODULES_DIR + "/prisma"
43
+ PRISMA_SCOPE_REL_PATH = NODE_MODULES_DIR + "/" + PRISMA_SCOPE_DIR_NAME
44
+ PRISMA_ENGINES_REL_PATH = PRISMA_SCOPE_REL_PATH + "/engines"
45
+ PRISMA_PACKAGE_NODE_MODULES_REL_PATH = PRISMA_PACKAGE_REL_PATH + "/node_modules"
46
+
47
+ APP_PRISMA_PACKAGE_DIR = APP_NODE_MODULES_DIR + "/" + PRISMA_DIR_NAME
48
+ APP_PRISMA_SCOPE_DIR = APP_NODE_MODULES_DIR + "/" + PRISMA_SCOPE_DIR_NAME
49
+ APP_PRISMA_ENGINES_DIR = APP_PRISMA_SCOPE_DIR + "/engines"
50
+ APP_PRISMA_PACKAGE_NODE_MODULES_DIR = APP_PRISMA_PACKAGE_DIR + "/node_modules"
51
+ APP_PRISMA_PACKAGE_ENGINES_DIR = APP_PRISMA_PACKAGE_NODE_MODULES_DIR + "/" + PRISMA_SCOPE_DIR_NAME + "/engines"
52
+
53
+ PRISMA_CLIENT_PACKAGE_REL_PATH = PRISMA_SCOPE_REL_PATH + "/client"
54
+ BUN_PRISMA_CLIENT_LINKER_NODE_MODULES_GLOB = NODE_MODULES_DIR + "/.bun/@prisma+client*/node_modules"
55
+
56
+ MIGRATE_SH_FILE = "migrate.sh"
57
+ MIGRATE_SH_ABS_PATH = APP_DIR + "/" + MIGRATE_SH_FILE
58
+
59
+ L3_MIGRATION_BUILD_STAGE = "l3_migration_build"
60
+
61
+ ROOT_USER = "root"
62
+ BUN_USER = RUNTIME
63
+
64
+ PRISMA_GENERATE_COMMAND = "bunx prisma generate"
65
+ PRISMA_GENERATE_RUN = "RUN " + PRISMA_GENERATE_COMMAND + "\n"
66
+ PRISMA_MIGRATE_DEPLOY_SUBCOMMAND = "migrate deploy"
67
+ PRISMA_GENERATE_SUBCOMMAND = "generate"
68
+
69
+ # Load project name for dynamic golden image naming
70
+ # Use TDK_PROJECT_ROOT env var set by Tilt, fallback to current directory
71
+ def _load_golden_prefix():
72
+ project_root = os.environ.get('TDK_PROJECT_ROOT', '')
73
+ project_json_path = '.tdk/project.json'
74
+ if project_root:
75
+ project_json_path = project_root + '/' + project_json_path
76
+
77
+ if os.path.exists(project_json_path):
78
+ _project_json = read_json(project_json_path)
79
+ return _project_json.get('project', {}).get('name', 'tdk-project')
80
+ return 'tdk-project'
81
+
82
+ _GOLDEN_PREFIX = _load_golden_prefix()
83
+
84
+ DEFAULT_GOLDEN_L3_MIGRATOR_IMAGE = _GOLDEN_PREFIX + "-l3-migrator:latest"
85
+ DEFAULT_GOLDEN_L4_MIGRATOR_IMAGE = _GOLDEN_PREFIX + "-l4-migrator:latest"
86
+
87
+ DEFAULT_DB_PORT = "5432"
88
+ DEFAULT_DB_WAIT_TIMEOUT_SECS = 120
89
+ DB_URL_HOSTPORT_WITH_AUTH_SED = "sed -n 's#^[^/]*//[^@]*@\\([^/]*\\)/.*#\\1#p'"
90
+ DB_URL_HOSTPORT_NO_AUTH_SED = "sed -n 's#^[^/]*//\\([^/]*\\)/.*#\\1#p'"
91
+
92
+ DEFAULT_INFISICAL_URL = "http://" + _GOLDEN_PREFIX + "-infisical:8081"
93
+ DATABASE_URL_UNSET_CONDITION = "[ -z \"$DATABASE_URL\" ] || [ \"$DATABASE_URL\" = \"null\" ]"
94
+ INFISICAL_SECRET_ENV_KEYS = [
95
+ "DATABASE_URL",
96
+ "DB_USER",
97
+ "DB_PASSWORD",
98
+ "DB_HOST",
99
+ "DB_PORT",
100
+ "DB_NAME",
101
+ ]
102
+ DB_URL_COMPONENT_ENV_KEYS = [
103
+ "DB_USER",
104
+ "DB_PASSWORD",
105
+ "DB_HOST",
106
+ "DB_PORT",
107
+ "DB_NAME",
108
+ ]
109
+ DB_URL_FROM_COMPONENTS = "postgresql://$DB_USER:$DB_PASSWORD@$DB_HOST:$DB_PORT/$DB_NAME"
110
+
111
+
112
+ def app_resource_dir(res_path):
113
+ return APP_DIR + "/" + res_path
114
+
115
+
116
+ def resource_node_modules_dir(res_path):
117
+ return app_resource_dir(res_path) + "/" + NODE_MODULES_DIR
118
+
119
+
120
+ def prisma_normalize_output_block(include_generated_client_export = True):
121
+ """
122
+ Shared Prisma client normalization instructions used in both generic and
123
+ migration-engine build flows.
124
+
125
+ Args:
126
+ include_generated_client_export: Include generated-client.ts shim line.
127
+ """
128
+ export_flag = "1" if include_generated_client_export else "0"
129
+ return (
130
+ "# Normalize Prisma output for both import styles using shared script\n"
131
+ + "COPY shared-platform-engineering/docker-templates/prisma-normalize-client.sh /usr/local/bin/prisma-normalize-client.sh\n"
132
+ + "RUN chmod +x /usr/local/bin/prisma-normalize-client.sh && PRISMA_EXPORT_GENERATED_CLIENT="
133
+ + export_flag
134
+ + " /usr/local/bin/prisma-normalize-client.sh\n"
135
+ )
@@ -0,0 +1,96 @@
1
+ """
2
+ DB Readiness Shell Fragment
3
+
4
+ Generates the shell script block that:
5
+ 1. Parses DB_HOST / DB_PORT from DATABASE_URL when the separate vars are absent
6
+ 2. Loops with `nc` until PostgreSQL accepts connections (120 s timeout)
7
+
8
+ Returns a plain string that is embedded verbatim inside migrate.sh.
9
+ """
10
+
11
+ load('../../../../tilt/common/utils_debug.star', 'DEBUG_MODE')
12
+ load(
13
+ './constants.star',
14
+ 'DB_URL_HOSTPORT_NO_AUTH_SED',
15
+ 'DB_URL_HOSTPORT_WITH_AUTH_SED',
16
+ 'DEFAULT_DB_PORT',
17
+ 'DEFAULT_DB_WAIT_TIMEOUT_SECS',
18
+ )
19
+
20
+
21
+ def _host_port_parse_block():
22
+ """
23
+ Extract DB_HOST_VAL / DB_PORT_VAL from DATABASE_URL when the individual
24
+ DB_HOST / DB_PORT env vars are not available.
25
+
26
+ Handles both:
27
+ postgresql://user:pass@host:port/db (with auth)
28
+ postgresql://host:port/db (without auth)
29
+ """
30
+ return (
31
+ "# Extract host and port for the readiness probe\n"
32
+ + "DB_HOST_VAL=\"$DB_HOST\"\n"
33
+ + "DB_PORT_VAL=\"$DB_PORT\"\n"
34
+ + "if [ -z \"$DB_HOST_VAL\" ]; then\n"
35
+ + " HOSTPORT=$(printf '%s\\n' \"$DATABASE_URL\" | "
36
+ + DB_URL_HOSTPORT_WITH_AUTH_SED + " | head -n1)\n"
37
+ + " if [ -z \"$HOSTPORT\" ]; then\n"
38
+ + " HOSTPORT=$(printf '%s\\n' \"$DATABASE_URL\" | "
39
+ + DB_URL_HOSTPORT_NO_AUTH_SED + " | head -n1)\n"
40
+ + " fi\n"
41
+ + " if printf '%s\\n' \"$HOSTPORT\" | grep -q '^\\['; then\n"
42
+ + " DB_HOST_VAL=$(printf '%s\\n' \"$HOSTPORT\" | sed -n 's/^\\[\\([^]]*\\)\\]\\(:[0-9][0-9]*\\)\\?$/\\1/p' || true)\n"
43
+ + " DB_PORT_VAL=$(printf '%s\\n' \"$HOSTPORT\" | sed -n 's/^\\[[^]]*\\]:\\([0-9][0-9]*\\)$/\\1/p' || true)\n"
44
+ + " else\n"
45
+ + " DB_HOST_VAL=$(printf '%s\\n' \"$HOSTPORT\" | awk -F: '{print $1}' || true)\n"
46
+ + " DB_PORT_VAL=$(printf '%s\\n' \"$HOSTPORT\" | awk -F: 'NF>1{print $NF}' || true)\n"
47
+ + " fi\n"
48
+ + "fi\n"
49
+ + "DB_PORT_VAL=\"${DB_PORT_VAL:-" + DEFAULT_DB_PORT + "}\"\n"
50
+ + "if [ -z \"$DB_HOST_VAL\" ]; then\n"
51
+ + " echo \"\\u274c ERROR: Unable to parse DB host from DATABASE_URL\"\n"
52
+ + " exit 1\n"
53
+ + "fi\n"
54
+ )
55
+
56
+
57
+ def _wait_loop_block(log_wait, log_ready, timeout_secs = DEFAULT_DB_WAIT_TIMEOUT_SECS):
58
+ """
59
+ nc-based polling loop. Retries every second up to `timeout_secs`.
60
+ """
61
+ return (
62
+ log_wait
63
+ + "i=0\n"
64
+ + "while ! nc -z \"${DB_HOST_VAL}\" \"${DB_PORT_VAL}\"; do\n"
65
+ + " i=$((i+1))\n"
66
+ + " if [ $i -gt " + str(timeout_secs) + " ]; then\n"
67
+ + " echo \"\\u274c Timeout waiting for DB at ${DB_HOST_VAL}:${DB_PORT_VAL}\"\n"
68
+ + " exit 1\n"
69
+ + " fi\n"
70
+ + " sleep 1\n"
71
+ + "done\n"
72
+ + log_ready
73
+ )
74
+
75
+
76
+ def db_readiness_script(timeout_secs = DEFAULT_DB_WAIT_TIMEOUT_SECS):
77
+ """
78
+ Return the complete shell fragment that waits for PostgreSQL to accept
79
+ connections before proceeding to migration.
80
+
81
+ Args:
82
+ timeout_secs: Seconds to wait before aborting (default: 120)
83
+ """
84
+ if DEBUG_MODE:
85
+ log_wait = "echo \"\\u23f3 Waiting for PostgreSQL at ${DB_HOST_VAL}:${DB_PORT_VAL}...\"\n"
86
+ log_ready = "echo \"\\u2705 PostgreSQL is ready!\"\n"
87
+ else:
88
+ log_wait = ""
89
+ log_ready = ""
90
+
91
+ return (
92
+ _host_port_parse_block()
93
+ + _wait_loop_block(log_wait, log_ready, timeout_secs)
94
+ )
95
+
96
+ DEBUG = {}