@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,109 @@
1
+ """
2
+ Filesystem Setup Dockerfile Fragment
3
+
4
+ Generates the RUN/COPY instructions that:
5
+ - Install Alpine utilities needed by migrate.sh at runtime (curl, jq, nc)
6
+ - Create required directories and fix ownership so Prisma can write generated files
7
+ - Ensure @prisma/engines is resolvable for the CLI (engines may land under
8
+ prisma/node_modules in Bun hoisting layouts)
9
+
10
+ All functions return Dockerfile instruction strings.
11
+ """
12
+
13
+ load(
14
+ '../bun_helpers.star',
15
+ 'bun_hoisted_packages_symlink_fix',
16
+ )
17
+ load(
18
+ './constants.star',
19
+ 'APP_BUN_STORE_DIR',
20
+ 'APP_GENERATED_CLIENT_DIR',
21
+ 'APP_NODE_MODULES_BIN_DIR',
22
+ 'APP_NODE_MODULES_DIR',
23
+ 'APP_PRISMA_DIR',
24
+ 'APP_PRISMA_PACKAGE_DIR',
25
+ 'APP_PRISMA_SCOPE_DIR',
26
+ 'APP_SRC_DIR',
27
+ 'BUN_USER',
28
+ 'PRISMA_BIN_ABS_PATH',
29
+ 'PRISMA_BIN_SYMLINK_TARGET',
30
+ 'PRISMA_CONFIG_ABS_PATH',
31
+ 'PRISMA_SCHEMA_PATH',
32
+ )
33
+
34
+
35
+ def apk_runtime_tools():
36
+ """
37
+ Install runtime utilities required by migrate.sh: bash, curl, jq, netcat-openbsd, postgresql-client.
38
+ """
39
+ return "RUN apk add --no-cache bash curl jq netcat-openbsd postgresql-client\n"
40
+
41
+
42
+ def prisma_dir_and_permissions():
43
+ """
44
+ Create directories that Prisma writes to at runtime and ensure the `bun` user owns
45
+ them. Handles both the standard `node_modules/.prisma/client` path and custom
46
+ output paths like `../src/generated` or `../generated-client`.
47
+ """
48
+ return (
49
+ "# Ensure Prisma can write generated files including custom output paths\n"
50
+ + "RUN mkdir -p " + APP_NODE_MODULES_DIR + " " + APP_SRC_DIR + " " + APP_GENERATED_CLIENT_DIR
51
+ + " && chown -R " + BUN_USER + ":" + BUN_USER
52
+ + " " + APP_PRISMA_DIR + " " + APP_NODE_MODULES_DIR + " " + APP_SRC_DIR + " " + APP_GENERATED_CLIENT_DIR
53
+ + " " + PRISMA_CONFIG_ABS_PATH + " || true\n"
54
+ )
55
+
56
+
57
+ def prisma_engines_symlink():
58
+ """
59
+ Rebuild @prisma links from Bun's isolated store after cross-stage COPY.
60
+ Service-level node_modules symlinks are relative and can break when copied to
61
+ `/app/node_modules`. We relink from `/app/node_modules/.bun`.
62
+
63
+ Handles two types of packages:
64
+ 1. Nested packages: @prisma/client, @prisma/adapter-pg (under node_modules/@prisma/)
65
+ 2. Top-level package: @prisma/engines (copied as real files, not symlinked)
66
+ """
67
+ return (
68
+ "# Re-link @prisma packages from Bun store so Prisma CLI can resolve engines\n"
69
+ + "COPY shared-platform-engineering/docker-templates/prisma-runtime-relink.sh /usr/local/bin/prisma-runtime-relink.sh\n"
70
+ + "RUN chmod +x /usr/local/bin/prisma-runtime-relink.sh && /usr/local/bin/prisma-runtime-relink.sh\n"
71
+ )
72
+
73
+
74
+ def prisma_config_inline():
75
+ """
76
+ Inline-generate /app/prisma.config.ts so Prisma v7 migration commands pick up
77
+ the datasource URL from the environment without requiring a build-time file copy.
78
+ """
79
+ return (
80
+ "# Prisma v7 migration commands require datasource.url in prisma.config.ts\n"
81
+ + "RUN cat > " + PRISMA_CONFIG_ABS_PATH + " << 'EOF'\n"
82
+ + "export default {\n"
83
+ + " schema: '" + PRISMA_SCHEMA_PATH + "',\n"
84
+ + " datasource: {\n"
85
+ + " url: process.env.DATABASE_URL,\n"
86
+ + " },\n"
87
+ + "};\n"
88
+ + "EOF\n"
89
+ )
90
+
91
+
92
+ def migrator_filesystem_setup():
93
+ """
94
+ Convenience wrapper – returns all filesystem setup instructions in order:
95
+ 1. Inline prisma.config.ts
96
+ 2. Permission fixes
97
+ 3. @prisma/engines symlink
98
+ 4. Alpine utilities
99
+ 5. General Bun hoisted packages symlink fix
100
+
101
+ The caller is responsible for wrapping these in `USER root` / `USER bun` guards.
102
+ """
103
+ return (
104
+ prisma_config_inline()
105
+ + prisma_dir_and_permissions()
106
+ + prisma_engines_symlink()
107
+ + apk_runtime_tools()
108
+ + bun_hoisted_packages_symlink_fix()
109
+ )
@@ -0,0 +1,98 @@
1
+ """
2
+ Migrate Script Builder
3
+
4
+ Assembles the complete /app/migrate.sh entrypoint that runs inside the
5
+ l4_migrator_runtime container. Delegates each logical section to a
6
+ dedicated module so this file stays focused on overall script structure.
7
+
8
+ secret_resolution – resolves DATABASE_URL (Infisical or env vars)
9
+ db_readiness – waits for PostgreSQL to accept connections
10
+ """
11
+
12
+ load('../../../../tilt/common/utils_debug.star', 'DEBUG_MODE')
13
+ load('./secret_resolution.star', 'secret_resolution_script')
14
+ load('./db_readiness.star', 'db_readiness_script')
15
+ load(
16
+ './constants.star',
17
+ 'APP_DIR',
18
+ 'MIGRATE_SH_ABS_PATH',
19
+ 'PRISMA_BIN_ABS_PATH',
20
+ 'PRISMA_GENERATE_SUBCOMMAND',
21
+ 'PRISMA_MIGRATE_DEPLOY_SUBCOMMAND',
22
+ )
23
+
24
+
25
+ def _log(debug_msg, prod_msg = ""):
26
+ """Return debug_msg when DEBUG_MODE is on, prod_msg otherwise."""
27
+ return debug_msg if DEBUG_MODE else prod_msg
28
+
29
+
30
+ def _prisma_run_block():
31
+ """
32
+ Shell fragment that locates the local Prisma CLI binary and runs
33
+ `migrate deploy` followed by `generate`. Avoids `bunx prisma` to
34
+ prevent accidental network fetches of the latest Prisma version.
35
+ """
36
+ return (
37
+ "# Use locally installed Prisma CLI – avoids bunx fetching prisma@latest\n"
38
+ + "PRISMA_BIN=\"" + PRISMA_BIN_ABS_PATH + "\"\n"
39
+ + "if [ ! -x \"$PRISMA_BIN\" ]; then\n"
40
+ + " echo \"\\u274c ERROR: Prisma CLI not found at $PRISMA_BIN\"\n"
41
+ + " exit 1\n"
42
+ + "fi\n"
43
+ + "# Ensure DATABASE_URL is exported for Prisma CLI\n"
44
+ + "export DATABASE_URL\n"
45
+ + _log("echo \"\\U0001f504 Running Prisma migrations...\"\n")
46
+ + "cd " + APP_DIR + " && \"$PRISMA_BIN\" " + PRISMA_MIGRATE_DEPLOY_SUBCOMMAND + "\n"
47
+ + _log("echo \"\\U0001f527 Generating Prisma client...\"\n")
48
+ + "\"$PRISMA_BIN\" " + PRISMA_GENERATE_SUBCOMMAND + "\n"
49
+ )
50
+
51
+
52
+ def migrate_sh_content(resource_name):
53
+ """
54
+ Return the full text of migrate.sh for the given service.
55
+
56
+ Args:
57
+ resource_name: Used in RESOURCE_NAME env var and Infisical secret path
58
+ (e.g. 'user-service', 'order-service').
59
+ """
60
+ done_msg = (
61
+ _log("echo \"\\U0001f389 Database migration completed successfully!\"\n")
62
+ or "echo \"Database migration completed\"\n"
63
+ )
64
+
65
+ return (
66
+ "#!/bin/sh\n"
67
+ + "set -e\n"
68
+ + _log(
69
+ "echo \"\\U0001f5c4\\ufe0f Starting database migration for $RESOURCE_NAME...\"\n",
70
+ "echo \"Starting database migration...\"\n",
71
+ )
72
+ + "\n# --- 1. Resolve DATABASE_URL ---\n"
73
+ + secret_resolution_script()
74
+ + "\n# --- 2. Wait for PostgreSQL ---\n"
75
+ + db_readiness_script()
76
+ + "\n# --- 3. Run Prisma migrate + generate ---\n"
77
+ + _prisma_run_block()
78
+ + "\n"
79
+ + done_msg
80
+ )
81
+
82
+
83
+ def migrate_sh_dockerfile_block(resource_name):
84
+ """
85
+ Return the Dockerfile fragment that writes migrate.sh and makes it executable.
86
+
87
+ Args:
88
+ resource_name: Forwarded to migrate_sh_content().
89
+ """
90
+ return (
91
+ "# Provide the migrate entrypoint\n"
92
+ + "RUN cat > " + MIGRATE_SH_ABS_PATH + " << 'EOF'\n"
93
+ + migrate_sh_content(resource_name)
94
+ + "EOF\n"
95
+ + "RUN chmod +x " + MIGRATE_SH_ABS_PATH + "\n"
96
+ )
97
+
98
+ DEBUG = {}
@@ -0,0 +1,126 @@
1
+ # === INLINED CONSTANTS for pure extension loading ===
2
+ OUTPUT = struct(AUTOGENERATED_FOLDER = ".autogenerated")
3
+ # === END INLINED CONSTANTS ===
4
+
5
+
6
+ """
7
+ Prisma Build Layers - L3 Prisma Client Generation and Migration Engine
8
+
9
+ Encapsulates all Prisma-related Dockerfile instructions for the build stage:
10
+ - Client generation (`bunx prisma generate`)
11
+ - Output normalization (generated-client ↔ node_modules/.prisma/client)
12
+ - Default module shim for Prisma v7 / @prisma/client compatibility
13
+ - Migration engine stage for Prisma migrate deploy
14
+ """
15
+
16
+ load('../l1_base_layers.star', 'BUN_BASE')
17
+ load('../l2_dependency_layers.star', 'normalize_res_path')
18
+ load('../../../../../../discovery/config.star', 'GLOBAL_CONFIG')
19
+ load('../../../../tilt/manifest/constants.star', 'AUTOGENERATED_CONFIG_PATHS')
20
+
21
+ load(
22
+ './constants.star',
23
+ 'APP_BUN_STORE_DIR',
24
+ 'DEFAULT_GOLDEN_L3_MIGRATOR_IMAGE',
25
+ 'NODE_MODULES_DIR',
26
+ 'PRISMA_CONFIG_WORKDIR_PATH',
27
+ 'PRISMA_DIR_NAME',
28
+ 'PRISMA_GENERATE_RUN',
29
+ 'PRISMA_PACKAGE_NODE_MODULES_REL_PATH',
30
+ 'PRISMA_SCHEMA_PATH',
31
+ 'app_resource_dir',
32
+ 'prisma_normalize_output_block',
33
+ )
34
+
35
+ _docker_cfg = GLOBAL_CONFIG['docker']
36
+ GOLDEN_L3_MIGRATOR_IMAGE = _docker_cfg.get('golden_l3_migrator_image', DEFAULT_GOLDEN_L3_MIGRATOR_IMAGE)
37
+
38
+
39
+ def prisma_copy_instructions(res_path, has_prisma_config = False):
40
+ """
41
+ Generate Dockerfile COPY instructions for Prisma schema and config.
42
+
43
+ Args:
44
+ res_path: Resource path (service directory)
45
+ has_prisma_config: Whether prisma.config.ts exists (Prisma v7)
46
+
47
+ Returns:
48
+ Dockerfile content string for copying Prisma files
49
+ """
50
+ # Normalize res_path for Docker COPY (must be relative to build context)
51
+ res_path_rel = normalize_res_path(res_path)
52
+
53
+ parts = "COPY " + res_path_rel + "/" + PRISMA_DIR_NAME + " ./" + PRISMA_DIR_NAME + "\n"
54
+ if has_prisma_config:
55
+ # Prisma v7 requires prisma.config.ts in CWD for correct client generation
56
+ parts += "COPY " + res_path_rel + "/" + AUTOGENERATED_CONFIG_PATHS['prisma'] + " " + PRISMA_CONFIG_WORKDIR_PATH + "\n"
57
+ return parts
58
+
59
+
60
+ def prisma_generate_instructions():
61
+ """
62
+ Generate Dockerfile RUN instruction for Prisma client generation.
63
+
64
+ Returns:
65
+ Dockerfile content string that runs `bunx prisma generate`
66
+ """
67
+ return PRISMA_GENERATE_RUN
68
+
69
+
70
+ def prisma_normalize_output():
71
+ """
72
+ Generate Dockerfile instructions to normalize Prisma output for both
73
+ import styles: ../generated-client and node_modules/.prisma/client.
74
+
75
+ Also creates a default.js shim required by @prisma/client v7 which
76
+ resolves `.prisma/client/default` at runtime.
77
+
78
+ Returns:
79
+ Dockerfile content string for Prisma output normalization
80
+ """
81
+ return prisma_normalize_output_block(include_generated_client_export = True)
82
+
83
+
84
+ def L3_generate_migration_engine(res_path, use_golden = True):
85
+ """
86
+ Generate the migration engine layer for Prisma database migrations.
87
+
88
+ Args:
89
+ res_path: Resource path (service directory)
90
+ use_golden: Whether to use golden L3-migrator image (default: True)
91
+
92
+ Returns:
93
+ Dockerfile content string for the l3_migration_build stage
94
+ """
95
+ # Normalize res_path for Docker COPY (must be relative to build context)
96
+ res_path_rel = normalize_res_path(res_path)
97
+
98
+ # Use golden L3-migrator image if enabled (Prisma pre-installed)
99
+ base_image = GOLDEN_L3_MIGRATOR_IMAGE if use_golden else BUN_BASE
100
+ app_res_path = app_resource_dir(res_path)
101
+
102
+ return (
103
+ "# ---- L3: migration_engine ----\n"
104
+ + "FROM " + base_image + " AS l3_migration_build\n"
105
+ + "WORKDIR " + app_res_path + "\n"
106
+ + "# Copy manifest files for dependency installation\n"
107
+ + "COPY " + res_path_rel + "/package.json ./package.json\n"
108
+ + "COPY " + res_path_rel + "/" + PRISMA_DIR_NAME + " ./" + PRISMA_DIR_NAME + "\n"
109
+ + "COPY " + res_path_rel + "/" + OUTPUT.AUTOGENERATED_FOLDER + "/.npmrc.docker.autogenerated .npmrc\n"
110
+ + "COPY " + res_path_rel + "/" + OUTPUT.AUTOGENERATED_FOLDER + "/bunfig.docker.autogenerated.toml ./bunfig.toml\n"
111
+ + "COPY bun.lock* ./\n"
112
+ + "# Install runtime deps only for migrator image (skip test/dev toolchain)\n"
113
+ + "# NOTE: keep bunfig.toml (it carries the @beauty-crm/@tdk-landscape registry\n"
114
+ + "# scopes pointing at Verdaccio) - deleting it forces scoped packages to fall\n"
115
+ + "# back to the public npm registry and fail with ConnectionRefused/404.\n"
116
+ + "RUN --mount=type=cache,target=/cache/bun,sharing=shared rm -f bun.lock bun.lockb && env -u CI BUN_CONFIG_FROZEN_LOCKFILE=false BUN_TMPDIR=/tmp BUN_INSTALL=/tmp/bun-install bun install --production --no-frozen-lockfile --concurrent-scripts --cache-dir=/cache/bun\n"
117
+ + "# Prisma CLI is often in devDependencies; install it explicitly without mutating manifest files\n"
118
+ + "RUN --mount=type=cache,target=/cache/bun,sharing=shared PRISMA_VERSION=$(sed -n 's/.*\"prisma\"[[:space:]]*:[[:space:]]*\"[~^]*\\([^\"]*\\)\".*/\\1/p' package.json | head -n 1) && [ -n \"$PRISMA_VERSION\" ] && BUN_TMPDIR=/tmp BUN_INSTALL=/tmp/bun-install bun add --no-save --exact prisma@\"$PRISMA_VERSION\" --cache-dir=/cache/bun\n"
119
+ + "# Generate Prisma client and normalize output location for runtime compatibility\n"
120
+ + PRISMA_GENERATE_RUN
121
+ + prisma_normalize_output_block(include_generated_client_export = False)
122
+ + "RUN mkdir -p " + PRISMA_PACKAGE_NODE_MODULES_REL_PATH + "\n"
123
+ + "RUN test -f " + PRISMA_SCHEMA_PATH + "\n"
124
+ )
125
+
126
+ GLOBAL_CONFIG = {}
@@ -0,0 +1,161 @@
1
+ """
2
+ Prisma Runtime Layers - L4 Prisma Runtime Copy and Resolution
3
+
4
+ Public API (preserved for backward compatibility with l4_runtime_layers.star):
5
+ prisma_runtime_copy(res_path) – copy .prisma artifacts from build stage
6
+ prisma_bun_symlink_fix() – fix Bun linker resolution for .prisma/client
7
+ prisma_config_copy(res_path) – copy prisma.config.ts (Prisma v7)
8
+ L4_generate_migrator_runtime(...) – full migrator stage (delegates to sub-modules)
9
+
10
+ Internal heavy-lifting is split across:
11
+ filesystem_setup.star – apk, dirs, permissions, engines symlink
12
+ shared docker template – generic migrate.sh entrypoint script
13
+ """
14
+
15
+ load('../l1_base_layers.star', 'BUN_BASE')
16
+ load('../l2_dependency_layers.star', 'normalize_res_path')
17
+ load('../../../../../../discovery/config.star', 'GLOBAL_CONFIG')
18
+ load('../../../../tilt/manifest/constants.star', 'AUTOGENERATED_CONFIG_PATHS')
19
+ load('./filesystem_setup.star', 'migrator_filesystem_setup')
20
+ load(
21
+ './constants.star',
22
+ 'APP_DIR',
23
+ 'BUN_USER',
24
+ 'DEFAULT_GOLDEN_L4_MIGRATOR_IMAGE',
25
+ 'MIGRATE_SH_ABS_PATH',
26
+ 'PRISMA_CONFIG_WORKDIR_PATH',
27
+ 'PRISMA_DOT_DIR_REL_PATH',
28
+ 'PRISMA_DIR_NAME',
29
+ 'ROOT_USER',
30
+ 'app_resource_dir',
31
+ 'resource_node_modules_dir',
32
+ )
33
+
34
+ _docker_cfg = GLOBAL_CONFIG['docker']
35
+ GOLDEN_L4_MIGRATOR_IMAGE = _docker_cfg.get('golden_l4_migrator_image', DEFAULT_GOLDEN_L4_MIGRATOR_IMAGE)
36
+ MIGRATE_SH_TEMPLATE_PATH = "shared-platform-engineering/docker-templates/migrate.sh"
37
+
38
+
39
+ # ---------------------------------------------------------------------------
40
+ # Small copy/fix helpers (used by l4_runtime_layers.star for backend runtime)
41
+ # ---------------------------------------------------------------------------
42
+
43
+ def prisma_runtime_copy(res_path):
44
+ """
45
+ Copy .prisma generated client and prisma schema from the build stage.
46
+
47
+ Args:
48
+ res_path: Service directory relative to /app (e.g. 'services/product/users/...')
49
+ """
50
+ base = app_resource_dir(res_path)
51
+ return (
52
+ "COPY --from=l3_backend_build " + base + "/" + PRISMA_DOT_DIR_REL_PATH + " ./" + PRISMA_DOT_DIR_REL_PATH + "\n"
53
+ + "COPY --from=l3_backend_build " + base + "/" + PRISMA_DIR_NAME + " ./" + PRISMA_DIR_NAME + "\n"
54
+ )
55
+
56
+
57
+ def prisma_bun_symlink_fix():
58
+ """
59
+ Symlink .prisma/client into every Bun linker path so runtime imports resolve.
60
+
61
+ Bun hoists @prisma/client under node_modules/.bun/@prisma+client*/node_modules/
62
+ and looks for .prisma relative to that path. The loop below covers all versions
63
+ that may be present.
64
+ """
65
+ return (
66
+ "# Fix Bun module resolution: .prisma/client must be reachable from .bun/ linker paths\n"
67
+ + "USER " + ROOT_USER + "\n"
68
+ + "COPY shared-platform-engineering/docker-templates/prisma-bun-client-link-fix.sh /usr/local/bin/prisma-bun-client-link-fix.sh\n"
69
+ + "RUN chmod +x /usr/local/bin/prisma-bun-client-link-fix.sh && /usr/local/bin/prisma-bun-client-link-fix.sh\n"
70
+ + "USER " + BUN_USER + "\n"
71
+ )
72
+
73
+
74
+ def prisma_config_copy(res_path):
75
+ """
76
+ Copy the auto-generated prisma.config.ts into the WORKDIR (required by Prisma v7).
77
+
78
+ Args:
79
+ res_path: Service directory relative to workspace root
80
+ """
81
+ # Normalize res_path for Docker COPY (must be relative to build context)
82
+ res_path_rel = normalize_res_path(res_path)
83
+ return "COPY " + res_path_rel + "/" + AUTOGENERATED_CONFIG_PATHS['prisma'] + " " + PRISMA_CONFIG_WORKDIR_PATH + "\n"
84
+
85
+
86
+ # ---------------------------------------------------------------------------
87
+ # Migrator stage builder
88
+ # ---------------------------------------------------------------------------
89
+
90
+ def _migrator_artifact_copies(res_path):
91
+ """
92
+ Runtime setup for migrator:
93
+ 1. Copy schema from l3 migration build stage
94
+ 2. Copy resolved node_modules from l3 migration build stage
95
+
96
+ This avoids Bun lockfile/frozen-lockfile edge cases in the l4 runtime image
97
+ while still keeping migrator logic simple (no pruner stage).
98
+ """
99
+ app_res_path = app_resource_dir(res_path)
100
+ base = resource_node_modules_dir(res_path)
101
+ return (
102
+ "# Copy migration schema + resolved deps from l3 stage\n"
103
+ + "COPY --from=l3_migration_build " + app_res_path + "/" + PRISMA_DIR_NAME + " ./" + PRISMA_DIR_NAME + "\n"
104
+ + "COPY --from=l3_migration_build " + base + " ./node_modules\n"
105
+ )
106
+
107
+
108
+ def _migrate_script_copy_block():
109
+ """
110
+ Keep Dockerfile concise by copying the shared migrate entrypoint script
111
+ instead of inlining a long heredoc.
112
+ """
113
+ return (
114
+ "# Provide the migrate entrypoint\n"
115
+ + "COPY " + MIGRATE_SH_TEMPLATE_PATH + " " + MIGRATE_SH_ABS_PATH + "\n"
116
+ + "RUN chmod +x " + MIGRATE_SH_ABS_PATH + "\n"
117
+ )
118
+
119
+
120
+ def L4_generate_migrator_runtime(res_path, resource_name = 'migrator', use_golden = True):
121
+ """
122
+ Generate the complete l4_migrator_runtime Dockerfile stage.
123
+
124
+ The stage:
125
+ 1. Copies Prisma artifacts from l3_migration_build
126
+ 2. Writes prisma.config.ts, fixes permissions, symlinks engines (filesystem_setup)
127
+ 3. Installs Alpine utilities (curl, jq, nc) needed at runtime
128
+ 4. Copies and chmod's /app/migrate.sh from shared docker templates
129
+ 5. Sets ENTRYPOINT to migrate.sh
130
+
131
+ Args:
132
+ res_path: Service directory relative to /app
133
+ resource_name: Used in RESOURCE_NAME env and Infisical secret path
134
+ use_golden: Always True – golden image is always preferred
135
+ """
136
+ # Golden image is mandatory – it ships Prisma + Infisical pre-built.
137
+ base_image = GOLDEN_L4_MIGRATOR_IMAGE
138
+
139
+ return (
140
+ "# ---- L4: migrator_runtime ----\n"
141
+ + "FROM " + base_image + " AS l4_migrator_runtime\n"
142
+ + "WORKDIR " + APP_DIR + "\n"
143
+ + "# Build argument to skip Infisical setup (for local dev / fast builds)\n"
144
+ + "ARG SKIP_INFISICAL_SETUP=0\n"
145
+ + "ENV NODE_ENV=production RESOURCE_NAME=" + resource_name + "\n"
146
+ + _migrator_artifact_copies(res_path)
147
+ + "USER " + ROOT_USER + "\n"
148
+ + migrator_filesystem_setup()
149
+ + "USER " + ROOT_USER + "\n"
150
+ + _migrate_script_copy_block()
151
+ # Migrators are one-shot jobs; they should not inherit long-running
152
+ # service healthchecks (e.g. HTTP probes on localhost:3000) from base layers.
153
+ + "HEALTHCHECK NONE\n"
154
+ + "USER " + BUN_USER + "\n"
155
+ + "ENTRYPOINT [\"" + MIGRATE_SH_ABS_PATH + "\"]\n"
156
+ + "\nFROM l4_migrator_runtime AS migrator\n"
157
+ + "FROM l4_migrator_runtime AS production\n"
158
+ + "FROM l4_migrator_runtime AS development\n"
159
+ )
160
+
161
+ GLOBAL_CONFIG = {}
@@ -0,0 +1,119 @@
1
+ """
2
+ Secret Resolution Shell Fragment
3
+
4
+ Generates the shell script block responsible for resolving DATABASE_URL at
5
+ runtime. Priority order:
6
+ 1. Infisical API (when INFISICAL_TOKEN + INFISICAL_PROJECT_ID are present)
7
+ 2. Individual DB_* env vars assembled into a connection string
8
+ 3. Pre-injected DATABASE_URL (docker-compose / Tilt direct injection)
9
+
10
+ Returns a plain string that is embedded verbatim inside migrate.sh.
11
+ """
12
+
13
+ load('../../../../tilt/common/utils_debug.star', 'DEBUG_MODE')
14
+ load(
15
+ './constants.star',
16
+ 'DATABASE_URL_UNSET_CONDITION',
17
+ 'DB_URL_COMPONENT_ENV_KEYS',
18
+ 'DB_URL_FROM_COMPONENTS',
19
+ 'DEFAULT_INFISICAL_URL',
20
+ 'INFISICAL_SECRET_ENV_KEYS',
21
+ )
22
+ load('../../../../tilt/generators/infisical/path_manager.star', 'PathManager')
23
+
24
+
25
+ def _export_secret_line(secret_key):
26
+ return (
27
+ " export " + secret_key + "=$(echo \"$RESPONSE\" | jq -r --arg k \"" + secret_key + "\" "
28
+ + "'.secrets[] | select(.secretKey==$k) | .secretValue' || true)\n"
29
+ )
30
+
31
+
32
+ def _infisical_export_block():
33
+ lines = []
34
+ for secret_key in INFISICAL_SECRET_ENV_KEYS:
35
+ lines.append(_export_secret_line(secret_key))
36
+ return "".join(lines)
37
+
38
+
39
+ def _all_env_present_condition(env_keys):
40
+ checks = []
41
+ for env_key in env_keys:
42
+ checks.append("[ -n \"$" + env_key + "\" ]")
43
+ return " && ".join(checks)
44
+
45
+
46
+ def _infisical_fetch_block(log_fetch, log_fetch_ok, log_fetch_fail):
47
+ """Build the Infisical curl block using Starlark path manager."""
48
+ else_block = (" else\n" + log_fetch_fail + " fi\n") if log_fetch_fail else " fi\n"
49
+ # Use default database subpath from PathManager constants
50
+ default_secret_path = PathManager.RESOURCE_SUBPATHS[0] if PathManager.RESOURCE_SUBPATHS else ""
51
+ # Note: In shell, we use env var with fallback. The actual path resolution
52
+ # happens at runtime, but we document the Starlark-managed path convention here.
53
+ return (
54
+ "if [ -n \"$INFISICAL_TOKEN\" ] && [ -n \"$INFISICAL_PROJECT_ID\" ]; then\n"
55
+ + log_fetch
56
+ + " INFISICAL_URL=\"${INFISICAL_API_URL:-${INFISICAL_URL:-" + DEFAULT_INFISICAL_URL + "}}\"\n"
57
+ + " INFISICAL_ENV=\"${INFISICAL_ENVIRONMENT:-dev}\"\n"
58
+ + " # Using Starlark-managed path: /services/$RESOURCE_NAME" + default_secret_path + "\n"
59
+ + " SECRET_PATH=\"${INFISICAL_SECRET_PATH:-/services/$RESOURCE_NAME/database}\"\n"
60
+ + " RESPONSE=$(curl -s -f -H \"Authorization: Bearer $INFISICAL_TOKEN\" "
61
+ + "\"${INFISICAL_URL}/api/v3/secrets/raw?environment=${INFISICAL_ENV}"
62
+ + "&workspaceId=${INFISICAL_PROJECT_ID}&secretPath=${SECRET_PATH}\") || true\n"
63
+ + " if [ -n \"$RESPONSE\" ]; then\n"
64
+ + log_fetch_ok
65
+ + _infisical_export_block()
66
+ + else_block
67
+ + "fi\n"
68
+ )
69
+
70
+
71
+ def _component_url_build_block(log_built):
72
+ """Build DATABASE_URL from individual DB_* parts when it is absent."""
73
+ components_ready = _all_env_present_condition(DB_URL_COMPONENT_ENV_KEYS)
74
+ return (
75
+ "# Build DATABASE_URL from components if not present\n"
76
+ + "if " + DATABASE_URL_UNSET_CONDITION + "; then\n"
77
+ + " if " + components_ready + "; then\n"
78
+ + " export DATABASE_URL=\"" + DB_URL_FROM_COMPONENTS + "\"\n"
79
+ + log_built
80
+ + " fi\n"
81
+ + "fi\n"
82
+ )
83
+
84
+
85
+ def _validate_url_block():
86
+ """Hard-fail when DATABASE_URL is still missing after all attempts."""
87
+ return (
88
+ "if " + DATABASE_URL_UNSET_CONDITION + "; then\n"
89
+ + " echo \"\\u274c ERROR: DATABASE_URL is not set."
90
+ + " Set it via Infisical or environment variables.\"\n"
91
+ + " exit 1\n"
92
+ + "fi\n"
93
+ )
94
+
95
+
96
+ def secret_resolution_script():
97
+ """
98
+ Return the complete shell fragment that resolves DATABASE_URL.
99
+
100
+ Uses DEBUG_MODE to include/suppress verbose log lines.
101
+ """
102
+ if DEBUG_MODE:
103
+ log_fetch = " echo \"\\U0001f510 Fetching secrets from Infisical...\"\n"
104
+ log_fetch_ok = " echo \"\\u2705 Successfully fetched secrets from Infisical\"\n"
105
+ log_fetch_fail = " echo \"\\u26a0\\ufe0f Infisical did not return secrets (or not reachable)\"\n"
106
+ log_built = " echo \"\\U0001f511 Built DATABASE_URL from components\"\n"
107
+ else:
108
+ log_fetch = ""
109
+ log_fetch_ok = ""
110
+ log_fetch_fail = ""
111
+ log_built = ""
112
+
113
+ return (
114
+ _infisical_fetch_block(log_fetch, log_fetch_ok, log_fetch_fail)
115
+ + _component_url_build_block(log_built)
116
+ + _validate_url_block()
117
+ )
118
+
119
+ DEBUG = {}