@decohere/scaffold 0.0.1-dev.125 → 0.0.1-dev.18

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 (264) hide show
  1. package/package.json +9 -19
  2. package/src/add-api.action.ts +25 -0
  3. package/src/add-api.command.ts +31 -0
  4. package/src/add.command.ts +20 -0
  5. package/src/add.module.ts +11 -0
  6. package/src/cli.ts +4 -0
  7. package/src/create.command.ts +20 -0
  8. package/src/create.module.ts +11 -0
  9. package/src/domain/prompt.ts +50 -0
  10. package/{types/src/index.d.ts → src/index.ts} +0 -4
  11. package/src/models/compose.model.ts +205 -0
  12. package/src/models/config-yaml.model.ts +83 -0
  13. package/src/models/const.ts +20 -0
  14. package/src/models/dev-container.model.ts +136 -0
  15. package/src/models/docker-image.model.ts +343 -0
  16. package/src/models/env-file.model.ts +45 -0
  17. package/src/models/gitignore.model.ts +35 -0
  18. package/src/models/launch-json.model.ts +60 -0
  19. package/src/models/package-json.model.ts +169 -0
  20. package/src/models/project.model.ts +141 -0
  21. package/{types/src/models/source-file.d.ts → src/models/source-file.ts} +6 -4
  22. package/src/models/tsconfig.model.ts +29 -0
  23. package/src/models/vitest-config.model.ts +26 -0
  24. package/src/models/vscode-settings.model.ts +24 -0
  25. package/src/program.ts +63 -0
  26. package/{types/src/resolve-target-dir.d.ts → src/resolve-target-dir.ts} +4 -1
  27. package/src/services/scaffold.service.ts +89 -0
  28. package/src/version.ts +56 -0
  29. package/src/webapi/api-name.ts +73 -0
  30. package/src/webapi/cli-options.ts +56 -0
  31. package/{types/src/webapi/const.d.ts → src/webapi/const.ts} +21 -9
  32. package/src/webapi/create-api.ts +275 -0
  33. package/src/webapi/devcontainer/host-scripts.ts +35 -0
  34. package/src/webapi/features/auth.feature.ts +454 -0
  35. package/src/webapi/features/auth0-cli.ts +421 -0
  36. package/src/webapi/features/biome-format.ts +34 -0
  37. package/src/webapi/features/database.feature.ts +522 -0
  38. package/src/webapi/features/finalize.feature.ts +112 -0
  39. package/src/webapi/features/postman.feature.ts +287 -0
  40. package/src/webapi/models/api-package-json.model.ts +60 -0
  41. package/src/webapi/models/auth-config.model.ts +36 -0
  42. package/src/webapi/models/controller-source-file.model.ts +232 -0
  43. package/{es6/src/webapi/models/github-ci.model.js → src/webapi/models/github-ci.model.ts} +29 -27
  44. package/src/webapi/models/main-source-file.model.ts +208 -0
  45. package/src/webapi/models/production-dockerfile.model.ts +162 -0
  46. package/src/webapi/models/sample-files.model.ts +45 -0
  47. package/src/webapi/models/webapi-image.model.ts +21 -0
  48. package/src/webapi/postman/hello-openapi.ts +92 -0
  49. package/src/webapi/postman/local-view.ts +195 -0
  50. package/src/webapi/postman/openapi-to-postman.ts +208 -0
  51. package/src/webapi/workspace-readme.ts +192 -0
  52. package/src/webapi.action.ts +22 -0
  53. package/src/webapi.command.ts +41 -0
  54. package/tests/auth-postman.wiring.spec.ts +263 -0
  55. package/tests/auth0-cli.spec.ts +232 -0
  56. package/tests/biome-format.spec.ts +49 -0
  57. package/tests/cli.integration.spec.ts +658 -0
  58. package/tests/compose.model.spec.ts +51 -0
  59. package/tests/container-image.model.spec.ts +162 -0
  60. package/tests/dev-container.model.spec.ts +29 -0
  61. package/tests/devcontainer-base-image.spec.ts +32 -0
  62. package/tests/hello-di-inject.scaffold.spec.ts +18 -0
  63. package/tests/hello-route.contract.spec.ts +94 -0
  64. package/tests/package-json.order.spec.ts +59 -0
  65. package/tests/postman-from-openapi.spec.ts +197 -0
  66. package/tests/seed-devcontainer-templates.ts +40 -0
  67. package/tests/webapi/devcontainer/codebase-rag-mcp.spec.ts +96 -0
  68. package/LICENSE +0 -15
  69. package/commonjs/src/add-api.action.js +0 -37
  70. package/commonjs/src/add-api.command.js +0 -39
  71. package/commonjs/src/add.command.js +0 -22
  72. package/commonjs/src/add.module.js +0 -24
  73. package/commonjs/src/auth0-configure.action.js +0 -28
  74. package/commonjs/src/auth0-configure.command.js +0 -24
  75. package/commonjs/src/auth0-login.action.js +0 -28
  76. package/commonjs/src/auth0-login.command.js +0 -23
  77. package/commonjs/src/auth0.command.js +0 -22
  78. package/commonjs/src/auth0.module.js +0 -28
  79. package/commonjs/src/cli.js +0 -8
  80. package/commonjs/src/create.command.js +0 -22
  81. package/commonjs/src/create.module.js +0 -24
  82. package/commonjs/src/domain/prompt.js +0 -62
  83. package/commonjs/src/index.js +0 -48
  84. package/commonjs/src/models/compose.model.js +0 -258
  85. package/commonjs/src/models/config-yaml.model.js +0 -86
  86. package/commonjs/src/models/const.js +0 -30
  87. package/commonjs/src/models/dev-container.model.js +0 -172
  88. package/commonjs/src/models/docker-image.model.js +0 -277
  89. package/commonjs/src/models/env-file.model.js +0 -48
  90. package/commonjs/src/models/gitignore.model.js +0 -48
  91. package/commonjs/src/models/launch-json.model.js +0 -70
  92. package/commonjs/src/models/package-json.model.js +0 -156
  93. package/commonjs/src/models/project.model.js +0 -132
  94. package/commonjs/src/models/source-file.js +0 -4
  95. package/commonjs/src/models/tsconfig.model.js +0 -32
  96. package/commonjs/src/models/vitest-config.model.js +0 -33
  97. package/commonjs/src/models/vscode-settings.model.js +0 -29
  98. package/commonjs/src/program.js +0 -64
  99. package/commonjs/src/resolve-target-dir.js +0 -17
  100. package/commonjs/src/services/scaffold.service.js +0 -60
  101. package/commonjs/src/version.js +0 -55
  102. package/commonjs/src/webapi/api-name.js +0 -93
  103. package/commonjs/src/webapi/auth0-commands.js +0 -250
  104. package/commonjs/src/webapi/authorize-scopes.js +0 -79
  105. package/commonjs/src/webapi/cli-options.js +0 -99
  106. package/commonjs/src/webapi/const.js +0 -54
  107. package/commonjs/src/webapi/create-api.js +0 -265
  108. package/commonjs/src/webapi/devcontainer/codebase-rag-mcp.js +0 -164
  109. package/commonjs/src/webapi/devcontainer/codebase-rag-mcp.ts +0 -182
  110. package/commonjs/src/webapi/devcontainer/host-scripts.js +0 -50
  111. package/commonjs/src/webapi/devcontainer/templates/codebase-rag.env.example +0 -3
  112. package/commonjs/src/webapi/devcontainer/templates/initialize.sh +0 -169
  113. package/commonjs/src/webapi/devcontainer/templates/post-create.sh +0 -35
  114. package/commonjs/src/webapi/devcontainer/templates/post-start.sh +0 -65
  115. package/commonjs/src/webapi/devcontainer/templates/tty-prompt.sh +0 -38
  116. package/commonjs/src/webapi/features/auth.feature.js +0 -408
  117. package/commonjs/src/webapi/features/auth0-cli.js +0 -472
  118. package/commonjs/src/webapi/features/biome-format.js +0 -47
  119. package/commonjs/src/webapi/features/database.feature.js +0 -433
  120. package/commonjs/src/webapi/features/finalize.feature.js +0 -93
  121. package/commonjs/src/webapi/features/postman.feature.js +0 -322
  122. package/commonjs/src/webapi/models/api-package-json.model.js +0 -58
  123. package/commonjs/src/webapi/models/auth-config.model.js +0 -24
  124. package/commonjs/src/webapi/models/controller-source-file.model.js +0 -190
  125. package/commonjs/src/webapi/models/github-ci.model.js +0 -193
  126. package/commonjs/src/webapi/models/main-source-file.model.js +0 -165
  127. package/commonjs/src/webapi/models/production-dockerfile.model.js +0 -75
  128. package/commonjs/src/webapi/models/sample-files.model.js +0 -58
  129. package/commonjs/src/webapi/models/webapi-image.model.js +0 -25
  130. package/commonjs/src/webapi/postman/hello-openapi.js +0 -173
  131. package/commonjs/src/webapi/postman/local-view.js +0 -182
  132. package/commonjs/src/webapi/postman/openapi-to-postman.js +0 -238
  133. package/commonjs/src/webapi/workspace-readme.js +0 -109
  134. package/commonjs/src/webapi.action.js +0 -28
  135. package/commonjs/src/webapi.command.js +0 -43
  136. package/es6/src/add-api.action.js +0 -27
  137. package/es6/src/add-api.command.js +0 -29
  138. package/es6/src/add.command.js +0 -12
  139. package/es6/src/add.module.js +0 -14
  140. package/es6/src/auth0-configure.action.js +0 -18
  141. package/es6/src/auth0-configure.command.js +0 -14
  142. package/es6/src/auth0-login.action.js +0 -18
  143. package/es6/src/auth0-login.command.js +0 -13
  144. package/es6/src/auth0.command.js +0 -12
  145. package/es6/src/auth0.module.js +0 -18
  146. package/es6/src/cli.js +0 -4
  147. package/es6/src/create.command.js +0 -12
  148. package/es6/src/create.module.js +0 -14
  149. package/es6/src/domain/prompt.js +0 -41
  150. package/es6/src/index.js +0 -9
  151. package/es6/src/models/compose.model.js +0 -254
  152. package/es6/src/models/config-yaml.model.js +0 -74
  153. package/es6/src/models/const.js +0 -20
  154. package/es6/src/models/dev-container.model.js +0 -162
  155. package/es6/src/models/docker-image.model.js +0 -235
  156. package/es6/src/models/env-file.model.js +0 -44
  157. package/es6/src/models/gitignore.model.js +0 -38
  158. package/es6/src/models/launch-json.model.js +0 -60
  159. package/es6/src/models/package-json.model.js +0 -141
  160. package/es6/src/models/project.model.js +0 -117
  161. package/es6/src/models/source-file.js +0 -1
  162. package/es6/src/models/tsconfig.model.js +0 -22
  163. package/es6/src/models/vitest-config.model.js +0 -23
  164. package/es6/src/models/vscode-settings.model.js +0 -19
  165. package/es6/src/program.js +0 -50
  166. package/es6/src/resolve-target-dir.js +0 -7
  167. package/es6/src/services/scaffold.service.js +0 -50
  168. package/es6/src/version.js +0 -34
  169. package/es6/src/webapi/api-name.js +0 -57
  170. package/es6/src/webapi/auth0-commands.js +0 -185
  171. package/es6/src/webapi/authorize-scopes.js +0 -55
  172. package/es6/src/webapi/cli-options.js +0 -34
  173. package/es6/src/webapi/const.js +0 -21
  174. package/es6/src/webapi/create-api.js +0 -245
  175. package/es6/src/webapi/devcontainer/codebase-rag-mcp.js +0 -154
  176. package/es6/src/webapi/devcontainer/codebase-rag-mcp.ts +0 -182
  177. package/es6/src/webapi/devcontainer/host-scripts.js +0 -29
  178. package/es6/src/webapi/devcontainer/templates/codebase-rag.env.example +0 -3
  179. package/es6/src/webapi/devcontainer/templates/initialize.sh +0 -169
  180. package/es6/src/webapi/devcontainer/templates/post-create.sh +0 -35
  181. package/es6/src/webapi/devcontainer/templates/post-start.sh +0 -65
  182. package/es6/src/webapi/devcontainer/templates/tty-prompt.sh +0 -38
  183. package/es6/src/webapi/features/auth.feature.js +0 -357
  184. package/es6/src/webapi/features/auth0-cli.js +0 -406
  185. package/es6/src/webapi/features/biome-format.js +0 -40
  186. package/es6/src/webapi/features/database.feature.js +0 -423
  187. package/es6/src/webapi/features/finalize.feature.js +0 -83
  188. package/es6/src/webapi/features/postman.feature.js +0 -256
  189. package/es6/src/webapi/models/api-package-json.model.js +0 -53
  190. package/es6/src/webapi/models/auth-config.model.js +0 -20
  191. package/es6/src/webapi/models/controller-source-file.model.js +0 -181
  192. package/es6/src/webapi/models/main-source-file.model.js +0 -161
  193. package/es6/src/webapi/models/production-dockerfile.model.js +0 -66
  194. package/es6/src/webapi/models/sample-files.model.js +0 -40
  195. package/es6/src/webapi/models/webapi-image.model.js +0 -18
  196. package/es6/src/webapi/postman/hello-openapi.js +0 -166
  197. package/es6/src/webapi/postman/local-view.js +0 -167
  198. package/es6/src/webapi/postman/openapi-to-postman.js +0 -179
  199. package/es6/src/webapi/workspace-readme.js +0 -88
  200. package/es6/src/webapi.action.js +0 -18
  201. package/es6/src/webapi.command.js +0 -33
  202. package/types/src/add-api.action.d.ts +0 -13
  203. package/types/src/add-api.command.d.ts +0 -7
  204. package/types/src/add.command.d.ts +0 -6
  205. package/types/src/add.module.d.ts +0 -14
  206. package/types/src/auth0-configure.action.d.ts +0 -7
  207. package/types/src/auth0-configure.command.d.ts +0 -6
  208. package/types/src/auth0-login.action.d.ts +0 -4
  209. package/types/src/auth0-login.command.d.ts +0 -6
  210. package/types/src/auth0.command.d.ts +0 -6
  211. package/types/src/auth0.module.d.ts +0 -18
  212. package/types/src/cli.d.ts +0 -2
  213. package/types/src/create.command.d.ts +0 -6
  214. package/types/src/create.module.d.ts +0 -14
  215. package/types/src/domain/prompt.d.ts +0 -4
  216. package/types/src/models/compose.model.d.ts +0 -73
  217. package/types/src/models/config-yaml.model.d.ts +0 -27
  218. package/types/src/models/const.d.ts +0 -20
  219. package/types/src/models/dev-container.model.d.ts +0 -49
  220. package/types/src/models/docker-image.model.d.ts +0 -90
  221. package/types/src/models/env-file.model.d.ts +0 -16
  222. package/types/src/models/gitignore.model.d.ts +0 -9
  223. package/types/src/models/launch-json.model.d.ts +0 -7
  224. package/types/src/models/package-json.model.d.ts +0 -36
  225. package/types/src/models/project.model.d.ts +0 -60
  226. package/types/src/models/tsconfig.model.d.ts +0 -5
  227. package/types/src/models/vitest-config.model.d.ts +0 -5
  228. package/types/src/models/vscode-settings.model.d.ts +0 -7
  229. package/types/src/program.d.ts +0 -8
  230. package/types/src/services/scaffold.service.d.ts +0 -22
  231. package/types/src/version.d.ts +0 -6
  232. package/types/src/webapi/api-name.d.ts +0 -14
  233. package/types/src/webapi/auth0-commands.d.ts +0 -11
  234. package/types/src/webapi/authorize-scopes.d.ts +0 -7
  235. package/types/src/webapi/cli-options.d.ts +0 -6
  236. package/types/src/webapi/create-api.d.ts +0 -15
  237. package/types/src/webapi/devcontainer/codebase-rag-mcp.d.ts +0 -32
  238. package/types/src/webapi/devcontainer/codebase-rag-mcp.ts +0 -182
  239. package/types/src/webapi/devcontainer/host-scripts.d.ts +0 -7
  240. package/types/src/webapi/devcontainer/templates/codebase-rag.env.example +0 -3
  241. package/types/src/webapi/devcontainer/templates/initialize.sh +0 -169
  242. package/types/src/webapi/devcontainer/templates/post-create.sh +0 -35
  243. package/types/src/webapi/devcontainer/templates/post-start.sh +0 -65
  244. package/types/src/webapi/devcontainer/templates/tty-prompt.sh +0 -38
  245. package/types/src/webapi/features/auth.feature.d.ts +0 -10
  246. package/types/src/webapi/features/auth0-cli.d.ts +0 -84
  247. package/types/src/webapi/features/biome-format.d.ts +0 -5
  248. package/types/src/webapi/features/database.feature.d.ts +0 -7
  249. package/types/src/webapi/features/finalize.feature.d.ts +0 -2
  250. package/types/src/webapi/features/postman.feature.d.ts +0 -16
  251. package/types/src/webapi/models/api-package-json.model.d.ts +0 -18
  252. package/types/src/webapi/models/auth-config.model.d.ts +0 -26
  253. package/types/src/webapi/models/controller-source-file.model.d.ts +0 -46
  254. package/types/src/webapi/models/github-ci.model.d.ts +0 -9
  255. package/types/src/webapi/models/main-source-file.model.d.ts +0 -54
  256. package/types/src/webapi/models/production-dockerfile.model.d.ts +0 -18
  257. package/types/src/webapi/models/sample-files.model.d.ts +0 -7
  258. package/types/src/webapi/models/webapi-image.model.d.ts +0 -12
  259. package/types/src/webapi/postman/hello-openapi.d.ts +0 -19
  260. package/types/src/webapi/postman/local-view.d.ts +0 -17
  261. package/types/src/webapi/postman/openapi-to-postman.d.ts +0 -62
  262. package/types/src/webapi/workspace-readme.d.ts +0 -18
  263. package/types/src/webapi.action.d.ts +0 -14
  264. package/types/src/webapi.command.d.ts +0 -11
@@ -1,277 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- function _export(target, all) {
6
- for(var name in all)Object.defineProperty(target, name, {
7
- enumerable: true,
8
- get: Object.getOwnPropertyDescriptor(all, name).get
9
- });
10
- }
11
- _export(exports, {
12
- get AppDevContainerBaseImage () {
13
- return AppDevContainerBaseImage;
14
- },
15
- get DevContainerImageModel () {
16
- return DevContainerImageModel;
17
- },
18
- get DockerStep () {
19
- return DockerStep;
20
- },
21
- get DockerfileModel () {
22
- return DockerfileModel;
23
- },
24
- get commandHistory () {
25
- return commandHistory;
26
- },
27
- get withCommandHistory () {
28
- return withCommandHistory;
29
- },
30
- get withGithubCli () {
31
- return withGithubCli;
32
- },
33
- get withNodeUser () {
34
- return withNodeUser;
35
- },
36
- get withPnpm () {
37
- return withPnpm;
38
- },
39
- get withPostgresqlClient () {
40
- return withPostgresqlClient;
41
- },
42
- get withVsCodeJsDebugBootloaderFix () {
43
- return withVsCodeJsDebugBootloaderFix;
44
- },
45
- get withWorkspaceNodeModulesOwnership () {
46
- return withWorkspaceNodeModulesOwnership;
47
- }
48
- });
49
- const _nodefs = require("node:fs");
50
- const _const = require("./const.js");
51
- class DockerStep {
52
- key;
53
- content;
54
- order;
55
- constructor(key, content, order = 0){
56
- this.key = key;
57
- this.content = content;
58
- this.order = order;
59
- }
60
- static run(key, command, order = 0) {
61
- return new DockerStep(key, `RUN ${command}`, order);
62
- }
63
- static raw(key, content, order = 0) {
64
- return new DockerStep(key, content, order);
65
- }
66
- static entrypoint(key, value, order = 0) {
67
- const content = typeof value === "string" ? `ENTRYPOINT ${value}` : `ENTRYPOINT ${JSON.stringify(value)}`;
68
- return new DockerStep(key, content, order);
69
- }
70
- }
71
- const StepOrder = {
72
- base: 1_000,
73
- features: 5_000,
74
- user: 9_000,
75
- entrypoint: 10_000
76
- };
77
- const VSCODE_BOOTLOADER_FIX_BASH_SNIPPET = `if [[ -n "\${NODE_OPTIONS:-}" && "\${NODE_OPTIONS}" == *"bootloader.js"* ]]; then
78
- _bootloader_path="$(printf '%s\\n' "$NODE_OPTIONS" | sed -n 's/.*--require[= ]\\([^[:space:]]*bootloader\\.js\\).*/\\1/p')"
79
- if [[ -n "\${_bootloader_path}" && ! -f "\${_bootloader_path}" ]]; then
80
- _stable_bootloader="$(find /vscode/vscode-server /home/node/.vscode-server/extensions -name "bootloader.js" -path "*/ms-vscode.js-debug/*" 2>/dev/null | head -1)"
81
- if [[ -n "\${_stable_bootloader}" ]]; then
82
- NODE_OPTIONS="\${NODE_OPTIONS//\${_bootloader_path}/\${_stable_bootloader}}"
83
- else
84
- NODE_OPTIONS="$(printf '%s\\n' "$NODE_OPTIONS" | sed -E 's#(^| )--require(=| )[[:graph:]]*bootloader\\.js( |$)# #g; s# +# #g; s#^ ##; s# $##')"
85
- unset VSCODE_INSPECTOR_OPTIONS
86
- fi
87
- export NODE_OPTIONS
88
- if [[ -z "$NODE_OPTIONS" ]]; then
89
- unset NODE_OPTIONS
90
- fi
91
- fi
92
- unset _bootloader_path _stable_bootloader
93
- fi`;
94
- const commandHistory = {
95
- volumeName: "bashhistory",
96
- dir: "/commandhistory",
97
- fileName: ".bash_history",
98
- histFile: "/commandhistory/.bash_history"
99
- };
100
- function withCommandHistory(options) {
101
- const historyDir = options?.historyDir ?? commandHistory.dir;
102
- const historyFileName = options?.historyFileName ?? commandHistory.fileName;
103
- const username = options?.username ?? "node";
104
- const order = options?.order ?? StepOrder.base;
105
- const historyFile = `${historyDir}/${historyFileName}`;
106
- return (dockerfile)=>{
107
- dockerfile.addStep(DockerStep.run("history-dir", `mkdir -p ${historyDir} && touch ${historyFile} && chown -R ${username} ${historyDir}`, order)).addStep(DockerStep.raw("history-env", `ENV HISTFILE=${historyFile}`, order + 1)).addStep(DockerStep.raw("history-bashrc", `RUN SNIPPET="export PROMPT_COMMAND='history -a' && export HISTFILE=${historyFile}" \\\n\t&& echo "$SNIPPET" >> "/home/${username}/.bashrc"`, order + 2));
108
- };
109
- }
110
- function withNodeUser(options) {
111
- const username = options?.username ?? "node";
112
- const includeUserInstruction = options?.includeUserInstruction ?? true;
113
- const order = options?.order ?? StepOrder.features;
114
- return (dockerfile)=>{
115
- dockerfile.addStep(DockerStep.raw("arg-username", `ARG USERNAME=${username}`, order));
116
- if (includeUserInstruction) {
117
- dockerfile.addStep(DockerStep.raw("user", "USER ${USERNAME}", StepOrder.user));
118
- }
119
- };
120
- }
121
- function withPnpm(options) {
122
- const version = options?.version ?? "10";
123
- const usernameExpr = options?.usernameExpr ?? "${USERNAME}";
124
- const order = options?.order ?? StepOrder.features + 100;
125
- return (dockerfile)=>{
126
- dockerfile.addStep(DockerStep.run("pnpm-install", `npm install --global npm@latest && npm add --global pnpm@${version}`, order)).addStep(DockerStep.run("pnpm-config", `mkdir -p /home/${usernameExpr}/.config/pnpm /home/${usernameExpr}/.pnpm-store && chown -R ${usernameExpr}:${usernameExpr} /home/${usernameExpr}/.config /home/${usernameExpr}/.pnpm-store && printf "store-dir=/home/${usernameExpr}/.pnpm-store\\n" > /home/${usernameExpr}/.config/pnpm/rc`, order + 1));
127
- };
128
- }
129
- function withPostgresqlClient(options) {
130
- const order = options?.order ?? StepOrder.features + 150;
131
- const username = options?.username ?? "node";
132
- return (dockerfile)=>{
133
- dockerfile.addStep(DockerStep.raw("postgresql-client-root", "USER root", order)).addStep(DockerStep.run("postgresql-client", "apt-get update && apt-get install -y --no-install-recommends postgresql-client && rm -rf /var/lib/apt/lists/*", order + 1)).addStep(DockerStep.raw("postgresql-client-user", `USER ${username}`, order + 2));
134
- };
135
- }
136
- function withGithubCli(options) {
137
- const order = options?.order ?? StepOrder.features + 140;
138
- return (dockerfile)=>{
139
- dockerfile.addStep(DockerStep.run("github-cli", "apt-get update && apt-get install -y --no-install-recommends gh && rm -rf /var/lib/apt/lists/*", order));
140
- };
141
- }
142
- function withWorkspaceNodeModulesOwnership(options) {
143
- const workspaceDir = options?.workspaceDir ?? "/workspace";
144
- const usernameExpr = options?.usernameExpr ?? "${USERNAME}";
145
- const order = options?.order ?? StepOrder.features + 200;
146
- return (dockerfile)=>{
147
- dockerfile.addStep(DockerStep.raw("workspace-node-modules", `RUN mkdir -p ${workspaceDir}/node_modules && chown ${usernameExpr}:${usernameExpr} ${workspaceDir}/node_modules`, order));
148
- };
149
- }
150
- function withVsCodeJsDebugBootloaderFix(options) {
151
- const bashrcPath = options?.bashrcPath ?? "/home/${USERNAME}/.bashrc";
152
- const order = options?.order ?? StepOrder.features + 300;
153
- return (dockerfile)=>{
154
- dockerfile.addStep(DockerStep.raw("vscode-bootloader-fix", [
155
- "# VS Code / Cursor js-debug Auto Attach injects --require …/bootloader.js into",
156
- "# NODE_OPTIONS. On a fresh Dev Container that path often does not exist yet",
157
- "# (workspaceStorage file is only created after toggling Auto Attach), which crashes",
158
- "# every Node command. If the injected path is missing, prefer the stable",
159
- "# bootloader from the server extension install; otherwise strip the bad require.",
160
- `RUN cat <<'EOF' >> "${bashrcPath}"`,
161
- VSCODE_BOOTLOADER_FIX_BASH_SNIPPET,
162
- "EOF"
163
- ].join("\n"), order));
164
- };
165
- }
166
- class DockerfileModel {
167
- key = _const.WELL_KNOWN_FILES.DOCKERFILE;
168
- _steps = new Map();
169
- _layerWriters = [];
170
- _fromImage;
171
- _layerCounter = 0;
172
- _existing;
173
- constructor(baseImage){
174
- this._fromImage = baseImage;
175
- this.registerBaseLayers();
176
- }
177
- /**
178
- * Load an existing Dockerfile so `decohere add api` can append feature layers.
179
- * The new steps are appended as one block, unless the file already contains it.
180
- */ static fromFile(absolutePath, filePath) {
181
- const dockerfile = new DockerfileModel("");
182
- dockerfile._existing = {
183
- content: (0, _nodefs.readFileSync)(absolutePath, "utf8"),
184
- filePath
185
- };
186
- return dockerfile;
187
- }
188
- from(baseImage) {
189
- this._fromImage = baseImage;
190
- return this;
191
- }
192
- addLayer(layer, order = StepOrder.features) {
193
- if (typeof layer === "string") {
194
- const idx = ++this._layerCounter;
195
- const key = `layer-run-${idx}`;
196
- this._layerWriters.push((dockerfile)=>{
197
- dockerfile.addStep(DockerStep.run(key, layer, order + idx));
198
- });
199
- return this;
200
- }
201
- this._layerWriters.push(layer);
202
- return this;
203
- }
204
- addStep(step) {
205
- this._steps.set(step.key, step);
206
- return this;
207
- }
208
- removeStep(key) {
209
- this._steps.delete(key);
210
- return this;
211
- }
212
- entrypoint(value, order = StepOrder.entrypoint) {
213
- this.addStep(DockerStep.entrypoint("entrypoint", value, order));
214
- return this;
215
- }
216
- addRunStep(cmd) {
217
- return this.addLayer(cmd);
218
- }
219
- build() {
220
- for (const layerWriter of this._layerWriters){
221
- layerWriter(this);
222
- }
223
- const sortedSteps = [
224
- ...this._steps.values()
225
- ].sort((left, right)=>{
226
- if (left.order !== right.order) {
227
- return left.order - right.order;
228
- }
229
- return left.key.localeCompare(right.key, "en");
230
- });
231
- if (this._existing) {
232
- // All or nothing: skipping one step of a layer (e.g. its `USER root`) would break the rest.
233
- const { content } = this._existing;
234
- const block = sortedSteps.map((step)=>step.content).join("\n\n");
235
- if (block === "" || content.includes(block)) return content;
236
- return `${content.replace(/\n*$/, "\n")}\n${block}\n`;
237
- }
238
- const lines = [
239
- `FROM ${this._fromImage}`
240
- ];
241
- for (const step of sortedSteps){
242
- lines.push("", step.content);
243
- }
244
- return `${lines.join("\n")}\n`;
245
- }
246
- registerBaseLayers() {
247
- // Generic base model intentionally has no default layers.
248
- }
249
- files() {
250
- return [
251
- {
252
- filePath: this._existing?.filePath ?? "./Dockerfile",
253
- content: this.build()
254
- }
255
- ];
256
- }
257
- }
258
- class AppDevContainerBaseImage extends DockerfileModel {
259
- registerBaseLayers() {
260
- super.registerBaseLayers();
261
- this.addLayer(withCommandHistory()).addLayer(withNodeUser()).addLayer(withPnpm()).addLayer(withGithubCli()).addLayer(withWorkspaceNodeModulesOwnership()).addLayer(withVsCodeJsDebugBootloaderFix());
262
- }
263
- }
264
- class DevContainerImageModel extends DockerfileModel {
265
- registerBaseLayers() {
266
- super.registerBaseLayers();
267
- this.addLayer(withCommandHistory()).addLayer(withVsCodeJsDebugBootloaderFix());
268
- }
269
- files() {
270
- return [
271
- {
272
- filePath: ".devcontainer/Dockerfile",
273
- content: this.build()
274
- }
275
- ];
276
- }
277
- }
@@ -1,48 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- Object.defineProperty(exports, "EnvFile", {
6
- enumerable: true,
7
- get: function() {
8
- return EnvFile;
9
- }
10
- });
11
- const _nodefs = require("node:fs");
12
- const _const = require("./const.js");
13
- class EnvFile {
14
- key = _const.WELL_KNOWN_FILES.ENV_FILE;
15
- _entries = new Map();
16
- addEntry(key, value) {
17
- this._entries.set(key, value);
18
- return this;
19
- }
20
- hasEntry(key) {
21
- return this._entries.has(key);
22
- }
23
- static fromFile(absolutePath) {
24
- const env = new EnvFile();
25
- const raw = (0, _nodefs.readFileSync)(absolutePath, "utf8");
26
- for (const line of raw.split("\n")){
27
- const trimmed = line.trim();
28
- if (trimmed === "" || trimmed.startsWith("#")) continue;
29
- const eq = line.indexOf("=");
30
- if (eq <= 0) continue;
31
- env.addEntry(line.slice(0, eq).trim(), line.slice(eq + 1));
32
- }
33
- return env;
34
- }
35
- files() {
36
- if (this._entries.size === 0) return [];
37
- const body = [
38
- ...this._entries.entries()
39
- ].map(([k, v])=>`${k}=${v}`).join("\n");
40
- const content = `${body}\n`;
41
- return [
42
- {
43
- filePath: ".env",
44
- content
45
- }
46
- ];
47
- }
48
- }
@@ -1,48 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- Object.defineProperty(exports, "Gitignore", {
6
- enumerable: true,
7
- get: function() {
8
- return Gitignore;
9
- }
10
- });
11
- const _nodefs = require("node:fs");
12
- const _const = require("./const.js");
13
- class Gitignore {
14
- key = _const.WELL_KNOWN_FILES.GITIGNORE;
15
- ignoreList = [
16
- "node_modules",
17
- "dist",
18
- ".package",
19
- ".pnpm-store",
20
- ".env",
21
- ".devcontainer/gh.env",
22
- ".cursor/codebase-rag.env",
23
- ".cursor/mcp.json",
24
- ".DS_Store",
25
- "logs"
26
- ];
27
- /** Load an existing .gitignore so `decohere add api` appends instead of replacing. */ static fromFile(absolutePath) {
28
- const gitignore = new Gitignore();
29
- gitignore.ignoreList = (0, _nodefs.readFileSync)(absolutePath, "utf8").replace(/\n+$/, "").split("\n");
30
- return gitignore;
31
- }
32
- add(...patterns) {
33
- for (const pattern of patterns){
34
- if (!this.ignoreList.includes(pattern)) {
35
- this.ignoreList.push(pattern);
36
- }
37
- }
38
- return this;
39
- }
40
- files() {
41
- return [
42
- {
43
- filePath: ".gitignore",
44
- content: `${this.ignoreList.join("\n")}\n`
45
- }
46
- ];
47
- }
48
- }
@@ -1,70 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- Object.defineProperty(exports, "LaunchJson", {
6
- enumerable: true,
7
- get: function() {
8
- return LaunchJson;
9
- }
10
- });
11
- const _const = require("./const.js");
12
- class LaunchJson {
13
- apiNames;
14
- key = _const.WELL_KNOWN_FILES.LAUNCH_JSON;
15
- constructor(apiNames = [
16
- "api"
17
- ]){
18
- this.apiNames = apiNames;
19
- }
20
- files() {
21
- const configurations = [
22
- {
23
- name: "Build",
24
- type: "node",
25
- request: "launch",
26
- runtimeExecutable: "pnpm",
27
- runtimeArgs: [
28
- "build"
29
- ],
30
- console: "integratedTerminal",
31
- cwd: "${workspaceFolder}"
32
- }
33
- ];
34
- const first = this.apiNames[0] ?? "api";
35
- const defaultDevArgs = first === "api" && this.apiNames.length === 1 ? [
36
- "dev"
37
- ] : [
38
- "run",
39
- `dev:${first}`
40
- ];
41
- configurations.push(serveConfig("Serve / Dev", defaultDevArgs));
42
- for (const apiName of this.apiNames){
43
- if (apiName === first && this.apiNames.length === 1 && apiName === "api") continue;
44
- configurations.push(serveConfig(`Serve / Dev (${apiName})`, [
45
- "run",
46
- `dev:${apiName}`
47
- ]));
48
- }
49
- return [
50
- {
51
- filePath: ".vscode/launch.json",
52
- content: JSON.stringify({
53
- version: "0.2.0",
54
- configurations
55
- }, null, 2)
56
- }
57
- ];
58
- }
59
- }
60
- function serveConfig(name, runtimeArgs) {
61
- return {
62
- name,
63
- type: "node",
64
- request: "launch",
65
- runtimeExecutable: "pnpm",
66
- runtimeArgs,
67
- console: "integratedTerminal",
68
- cwd: "${workspaceFolder}"
69
- };
70
- }
@@ -1,156 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- function _export(target, all) {
6
- for(var name in all)Object.defineProperty(target, name, {
7
- enumerable: true,
8
- get: Object.getOwnPropertyDescriptor(all, name).get
9
- });
10
- }
11
- _export(exports, {
12
- get PackageJson () {
13
- return PackageJson;
14
- },
15
- get packageScript () {
16
- return packageScript;
17
- },
18
- get sortStringMap () {
19
- return sortStringMap;
20
- }
21
- });
22
- const _nodefs = require("node:fs");
23
- const _version = require("../version.js");
24
- const _const = require("../webapi/const.js");
25
- const _const1 = require("./const.js");
26
- class PackageJson {
27
- name;
28
- key = _const1.WELL_KNOWN_FILES.PACKAGE_JSON;
29
- _dependencies;
30
- _devDependencies;
31
- _scripts;
32
- _version = "0.0.1";
33
- _type = "module";
34
- _rest = {};
35
- constructor(name, options){
36
- this.name = name;
37
- const apiNames = options?.apiNames ?? [
38
- _const.DEFAULT_WEBAPI_NAME
39
- ];
40
- const first = apiNames[0] ?? _const.DEFAULT_WEBAPI_NAME;
41
- const startEntry = options?.startEntry ?? (0, _const.webapiReleaseEntry)(first);
42
- const workspaceName = options?.workspaceName ?? stripApiSuffix(name);
43
- const namedOrMany = apiNames.length > 1 || first !== _const.DEFAULT_WEBAPI_NAME;
44
- this._scripts = {
45
- build: "forge build --configuration release",
46
- "build:watch": "forge build --watch",
47
- // Release build, then `.package/` in every API (what its Dockerfile copies).
48
- package: "pnpm run build && forge package",
49
- start: `node ${startEntry}`,
50
- dev: namedOrMany ? fluxDevScript(workspaceName, first, (0, _const.webapiPort)(0)) : "flux serve --env-file-if-exists .env",
51
- "lint:check": "biome check .",
52
- typecheck: "forge typecheck",
53
- test: "vitest run --passWithNoTests"
54
- };
55
- for (const [index, apiName] of apiNames.entries()){
56
- this._scripts[`start:${apiName}`] = `node ${(0, _const.webapiReleaseEntry)(apiName)}`;
57
- this._scripts[`package:${apiName}`] = packageScript(workspaceName, apiName);
58
- this._scripts[`dev:${apiName}`] = fluxDevScript(workspaceName, apiName, (0, _const.webapiPort)(index));
59
- }
60
- this._dependencies = {
61
- "@decohere/http": _version.CREATE_VERSION,
62
- "@decohere/crucible": _version.CREATE_VERSION,
63
- "@decohere/core": _version.CREATE_VERSION,
64
- "@decohere/config": _version.CREATE_VERSION,
65
- "@decohere/scribe": _version.CREATE_VERSION,
66
- "@decohere/scribe-pino": _version.CREATE_VERSION,
67
- "pino-pretty": "^13.0.0",
68
- "pino-roll": "^4.0.0"
69
- };
70
- this._devDependencies = {
71
- "@decohere/forge": _version.CREATE_VERSION,
72
- "@decohere/cli": _version.CREATE_VERSION,
73
- typescript: "^6.0.3",
74
- "@biomejs/biome": "^2.0.0",
75
- vitest: "^3.2.4"
76
- };
77
- }
78
- /** Load an existing root package.json so `webapi add` can merge scripts/deps. */ static fromFile(filePath) {
79
- const raw = JSON.parse((0, _nodefs.readFileSync)(filePath, "utf8"));
80
- const pkg = new PackageJson(typeof raw.name === "string" ? raw.name : "app", {
81
- apiNames: []
82
- });
83
- pkg._version = typeof raw.version === "string" ? raw.version : "0.0.1";
84
- pkg._type = typeof raw.type === "string" ? raw.type : "module";
85
- pkg._scripts = {
86
- ...asStringMap(raw.scripts)
87
- };
88
- pkg._dependencies = {
89
- ...asStringMap(raw.dependencies)
90
- };
91
- pkg._devDependencies = {
92
- ...asStringMap(raw.devDependencies)
93
- };
94
- const reserved = new Set([
95
- "name",
96
- "version",
97
- "type",
98
- "scripts",
99
- "dependencies",
100
- "devDependencies"
101
- ]);
102
- pkg._rest = Object.fromEntries(Object.entries(raw).filter(([key])=>!reserved.has(key)));
103
- return pkg;
104
- }
105
- addDependency(name, version) {
106
- this._dependencies[name] = version;
107
- return this;
108
- }
109
- addDevDependency(name, version) {
110
- this._devDependencies[name] = version;
111
- return this;
112
- }
113
- addScript(name, command) {
114
- this._scripts[name] = command;
115
- return this;
116
- }
117
- hasScript(name) {
118
- return typeof this._scripts[name] === "string";
119
- }
120
- files() {
121
- return [
122
- {
123
- filePath: "package.json",
124
- content: JSON.stringify({
125
- name: this.name,
126
- version: this._version,
127
- type: this._type,
128
- ...this._rest,
129
- scripts: this._scripts,
130
- dependencies: sortStringMap(this._dependencies),
131
- devDependencies: sortStringMap(this._devDependencies)
132
- }, null, 2)
133
- }
134
- ];
135
- }
136
- }
137
- function stripApiSuffix(name) {
138
- return name.endsWith(".api") ? name.slice(0, -".api".length) : name;
139
- }
140
- function asStringMap(value) {
141
- if (value == null || typeof value !== "object") return {};
142
- const result = {};
143
- for (const [key, entry] of Object.entries(value)){
144
- if (typeof entry === "string") result[key] = entry;
145
- }
146
- return result;
147
- }
148
- function sortStringMap(map) {
149
- return Object.fromEntries(Object.entries(map).sort(([left], [right])=>left.localeCompare(right, "en")));
150
- }
151
- function packageScript(workspaceName, apiName) {
152
- return `pnpm run build && forge package ${(0, _const.webapiPackageName)(workspaceName, apiName)}`;
153
- }
154
- function fluxDevScript(workspaceName, apiName, port) {
155
- return `PORT=${port} flux serve --env-file-if-exists .env --project ${(0, _const.webapiPackageName)(workspaceName, apiName)}`;
156
- }