@decohere/create 0.0.1-dev.16 → 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 (186) hide show
  1. package/commonjs/src/cli.js +26 -5
  2. package/commonjs/src/models/compose.model.js +82 -0
  3. package/commonjs/src/models/config-yaml.model.js +34 -0
  4. package/commonjs/src/models/const.js +29 -0
  5. package/commonjs/src/models/container-image.model.js +88 -0
  6. package/commonjs/src/models/dev-container.model.js +73 -0
  7. package/commonjs/src/models/env-file.model.js +33 -0
  8. package/commonjs/src/models/gitignore.model.js +32 -0
  9. package/commonjs/src/models/launch-json.model.js +52 -0
  10. package/commonjs/src/models/package-json.model.js +64 -0
  11. package/commonjs/src/models/project.model.js +126 -0
  12. package/commonjs/src/models/source-file.js +6 -0
  13. package/commonjs/src/models/tsconfig.model.js +34 -0
  14. package/commonjs/src/models/vscode-settings.model.js +31 -0
  15. package/commonjs/src/services/scaffold.service.js +62 -0
  16. package/commonjs/src/webapi/create-api.js +169 -0
  17. package/commonjs/src/webapi/features/auth.feature.js +166 -0
  18. package/commonjs/src/webapi/features/auth0-cli.js +151 -0
  19. package/commonjs/src/webapi/features/database.feature.js +151 -0
  20. package/commonjs/src/webapi/features/finalize.feature.js +46 -0
  21. package/commonjs/src/webapi/features/postman.feature.js +309 -0
  22. package/commonjs/src/webapi/models/api-package-json.model.js +57 -0
  23. package/commonjs/src/webapi/models/auth-config.model.js +23 -0
  24. package/commonjs/src/webapi/models/controller-source-file.model.js +180 -0
  25. package/commonjs/src/webapi/models/main-source-file.model.js +132 -0
  26. package/commonjs/src/webapi/models/sample-files.model.js +60 -0
  27. package/commonjs/v1/cli.js +15 -0
  28. package/commonjs/v1/domain/class-model.js +106 -0
  29. package/commonjs/v1/domain/compose.model.js +74 -0
  30. package/commonjs/v1/domain/context.js +53 -0
  31. package/commonjs/v1/domain/devcontainer.model.js +116 -0
  32. package/commonjs/v1/domain/dockerfile.model.js +62 -0
  33. package/commonjs/v1/domain/feature.js +19 -0
  34. package/commonjs/v1/domain/import-map.js +74 -0
  35. package/commonjs/v1/domain/index.js +68 -0
  36. package/commonjs/v1/domain/prompt.js +45 -0
  37. package/commonjs/v1/domain/workflow.js +37 -0
  38. package/commonjs/v1/features/api-core/feature.js +103 -0
  39. package/commonjs/v1/features/api-core/hello-controller.model.js +100 -0
  40. package/commonjs/v1/features/api-core/main-ts.model.js +85 -0
  41. package/commonjs/v1/features/api-core/scaffold-files.template.js +158 -0
  42. package/commonjs/v1/features/auth0/auth0-cli.js +151 -0
  43. package/commonjs/v1/features/auth0/feature.js +187 -0
  44. package/commonjs/v1/features/auth0/models.js +14 -0
  45. package/commonjs/v1/features/auth0/prod-config.template.js +19 -0
  46. package/commonjs/v1/features/cli-core/feature.js +37 -0
  47. package/commonjs/v1/features/cli-core/scaffold-files.template.js +103 -0
  48. package/commonjs/v1/features/devcontainer/feature.js +38 -0
  49. package/commonjs/v1/features/finalize/feature.js +48 -0
  50. package/commonjs/v1/features/postgresql/feature.js +81 -0
  51. package/commonjs/v1/features/postgresql/models.js +14 -0
  52. package/commonjs/v1/features/postman/collection.template.js +80 -0
  53. package/commonjs/v1/features/postman/environment.template.js +24 -0
  54. package/commonjs/v1/features/postman/feature.js +192 -0
  55. package/commonjs/v1/features/typeorm/feature.js +66 -0
  56. package/commonjs/v1/features/typeorm/scaffold-files.template.js +80 -0
  57. package/commonjs/v1/scaffold.js +50 -0
  58. package/commonjs/v1/version.js +32 -0
  59. package/commonjs/v1/workflows/api.js +29 -0
  60. package/commonjs/v1/workflows/cli.js +19 -0
  61. package/es6/src/cli.js +26 -5
  62. package/es6/src/models/compose.model.js +77 -0
  63. package/es6/src/models/config-yaml.model.js +30 -0
  64. package/es6/src/models/const.js +19 -0
  65. package/es6/src/models/container-image.model.js +84 -0
  66. package/es6/src/models/dev-container.model.js +68 -0
  67. package/es6/src/models/env-file.model.js +29 -0
  68. package/es6/src/models/gitignore.model.js +22 -0
  69. package/es6/src/models/launch-json.model.js +42 -0
  70. package/es6/src/models/package-json.model.js +60 -0
  71. package/es6/src/models/project.model.js +111 -0
  72. package/es6/src/models/source-file.js +3 -0
  73. package/es6/src/models/tsconfig.model.js +24 -0
  74. package/es6/src/models/vscode-settings.model.js +21 -0
  75. package/es6/src/services/scaffold.service.js +52 -0
  76. package/es6/src/webapi/create-api.js +151 -0
  77. package/es6/src/webapi/features/auth.feature.js +115 -0
  78. package/es6/src/webapi/features/auth0-cli.js +116 -0
  79. package/es6/src/webapi/features/database.feature.js +141 -0
  80. package/es6/src/webapi/features/finalize.feature.js +36 -0
  81. package/es6/src/webapi/features/postman.feature.js +258 -0
  82. package/es6/src/webapi/models/api-package-json.model.js +52 -0
  83. package/es6/src/webapi/models/auth-config.model.js +19 -0
  84. package/es6/src/webapi/models/controller-source-file.model.js +171 -0
  85. package/es6/src/webapi/models/main-source-file.model.js +128 -0
  86. package/es6/src/webapi/models/sample-files.model.js +42 -0
  87. package/es6/v1/cli.js +11 -0
  88. package/es6/v1/domain/class-model.js +104 -0
  89. package/es6/v1/domain/compose.model.js +61 -0
  90. package/es6/v1/domain/context.js +37 -0
  91. package/es6/v1/domain/devcontainer.model.js +104 -0
  92. package/es6/v1/domain/dockerfile.model.js +52 -0
  93. package/es6/v1/domain/feature.js +9 -0
  94. package/es6/v1/domain/import-map.js +64 -0
  95. package/es6/v1/domain/index.js +11 -0
  96. package/es6/v1/domain/prompt.js +27 -0
  97. package/es6/v1/domain/workflow.js +24 -0
  98. package/es6/v1/features/api-core/feature.js +93 -0
  99. package/es6/v1/features/api-core/hello-controller.model.js +96 -0
  100. package/es6/v1/features/api-core/main-ts.model.js +74 -0
  101. package/es6/v1/features/api-core/scaffold-files.template.js +116 -0
  102. package/es6/v1/features/auth0/auth0-cli.js +116 -0
  103. package/es6/v1/features/auth0/feature.js +136 -0
  104. package/es6/v1/features/auth0/models.js +4 -0
  105. package/es6/v1/features/auth0/prod-config.template.js +9 -0
  106. package/es6/v1/features/cli-core/feature.js +27 -0
  107. package/es6/v1/features/cli-core/scaffold-files.template.js +73 -0
  108. package/es6/v1/features/devcontainer/feature.js +28 -0
  109. package/es6/v1/features/finalize/feature.js +38 -0
  110. package/es6/v1/features/postgresql/feature.js +71 -0
  111. package/es6/v1/features/postgresql/models.js +4 -0
  112. package/es6/v1/features/postman/collection.template.js +70 -0
  113. package/es6/v1/features/postman/environment.template.js +14 -0
  114. package/es6/v1/features/postman/feature.js +141 -0
  115. package/es6/v1/features/typeorm/feature.js +56 -0
  116. package/es6/v1/features/typeorm/scaffold-files.template.js +56 -0
  117. package/es6/v1/scaffold.js +40 -0
  118. package/es6/v1/version.js +22 -0
  119. package/es6/v1/workflows/api.js +25 -0
  120. package/es6/v1/workflows/cli.js +9 -0
  121. package/package.json +2 -2
  122. package/types/src/models/compose.model.d.ts +32 -0
  123. package/types/src/models/config-yaml.model.d.ts +16 -0
  124. package/types/src/models/const.d.ts +17 -0
  125. package/types/src/models/container-image.model.d.ts +15 -0
  126. package/types/src/models/dev-container.model.d.ts +21 -0
  127. package/types/src/models/env-file.model.d.ts +14 -0
  128. package/types/src/models/gitignore.model.d.ts +6 -0
  129. package/types/src/models/launch-json.model.d.ts +5 -0
  130. package/types/src/models/package-json.model.d.ts +18 -0
  131. package/types/src/models/project.model.d.ts +55 -0
  132. package/types/src/models/source-file.d.ts +11 -0
  133. package/types/src/models/tsconfig.model.d.ts +5 -0
  134. package/types/src/models/vscode-settings.model.d.ts +7 -0
  135. package/types/src/services/scaffold.service.d.ts +22 -0
  136. package/types/src/webapi/create-api.d.ts +7 -0
  137. package/types/src/webapi/features/auth.feature.d.ts +7 -0
  138. package/types/src/webapi/features/auth0-cli.d.ts +22 -0
  139. package/types/src/webapi/features/database.feature.d.ts +5 -0
  140. package/types/src/webapi/features/finalize.feature.d.ts +2 -0
  141. package/types/src/webapi/features/postman.feature.d.ts +7 -0
  142. package/types/src/webapi/models/api-package-json.model.d.ts +17 -0
  143. package/types/src/webapi/models/auth-config.model.d.ts +18 -0
  144. package/types/src/webapi/models/controller-source-file.model.d.ts +42 -0
  145. package/types/src/webapi/models/main-source-file.model.d.ts +36 -0
  146. package/types/src/webapi/models/sample-files.model.d.ts +7 -0
  147. package/types/v1/cli.d.ts +2 -0
  148. package/types/v1/domain/class-model.d.ts +70 -0
  149. package/types/v1/domain/compose.model.d.ts +25 -0
  150. package/types/v1/domain/context.d.ts +36 -0
  151. package/types/v1/domain/devcontainer.model.d.ts +35 -0
  152. package/types/v1/domain/dockerfile.model.d.ts +11 -0
  153. package/types/v1/domain/feature.d.ts +29 -0
  154. package/types/v1/domain/import-map.d.ts +24 -0
  155. package/types/v1/domain/index.d.ts +12 -0
  156. package/types/v1/domain/prompt.d.ts +2 -0
  157. package/types/v1/domain/workflow.d.ts +14 -0
  158. package/types/v1/features/api-core/feature.d.ts +2 -0
  159. package/types/v1/features/api-core/hello-controller.model.d.ts +9 -0
  160. package/types/v1/features/api-core/main-ts.model.d.ts +31 -0
  161. package/types/v1/features/api-core/scaffold-files.template.d.ts +10 -0
  162. package/types/v1/features/auth0/auth0-cli.d.ts +22 -0
  163. package/types/v1/features/auth0/feature.d.ts +2 -0
  164. package/types/v1/features/auth0/models.d.ts +5 -0
  165. package/types/v1/features/auth0/prod-config.template.d.ts +1 -0
  166. package/types/v1/features/cli-core/feature.d.ts +2 -0
  167. package/types/v1/features/cli-core/scaffold-files.template.d.ts +6 -0
  168. package/types/v1/features/devcontainer/feature.d.ts +2 -0
  169. package/types/v1/features/finalize/feature.d.ts +2 -0
  170. package/types/v1/features/postgresql/feature.d.ts +2 -0
  171. package/types/v1/features/postgresql/models.d.ts +6 -0
  172. package/types/v1/features/postman/collection.template.d.ts +1 -0
  173. package/types/v1/features/postman/environment.template.d.ts +6 -0
  174. package/types/v1/features/postman/feature.d.ts +2 -0
  175. package/types/v1/features/typeorm/feature.d.ts +2 -0
  176. package/types/v1/features/typeorm/scaffold-files.template.d.ts +9 -0
  177. package/types/v1/scaffold.d.ts +3 -0
  178. package/types/v1/version.d.ts +2 -0
  179. package/types/v1/workflows/api.d.ts +8 -0
  180. package/types/v1/workflows/cli.d.ts +1 -0
  181. package/commonjs/src/scaffold.js +0 -89
  182. package/commonjs/src/templates.js +0 -305
  183. package/es6/src/scaffold.js +0 -79
  184. package/es6/src/templates.js +0 -245
  185. package/types/src/scaffold.d.ts +0 -6
  186. package/types/src/templates.d.ts +0 -20
@@ -0,0 +1,37 @@
1
+ import { basename } from "node:path";
2
+ export function modelKey(name) {
3
+ return {
4
+ _sym: Symbol(name)
5
+ };
6
+ }
7
+ /**
8
+ * Immutable typed store of feature models. Each feature defines its own keys
9
+ * (typed via `modelKey<T>()`) and writes to / reads from the store during the
10
+ * `configure` and `render` phases. The store is the only mechanism by which
11
+ * features communicate.
12
+ */ export class FeatureModelStore {
13
+ _store;
14
+ constructor(store){
15
+ this._store = store ?? new Map();
16
+ }
17
+ get(key) {
18
+ return this._store.get(key._sym);
19
+ }
20
+ set(key, value) {
21
+ const next = new Map(this._store);
22
+ next.set(key._sym, value);
23
+ return new FeatureModelStore(next);
24
+ }
25
+ }
26
+ export function createContext(targetDir, opts, template = "api") {
27
+ return {
28
+ projectName: basename(targetDir),
29
+ targetDir,
30
+ opts,
31
+ template,
32
+ models: new FeatureModelStore(),
33
+ controllers: []
34
+ };
35
+ }
36
+
37
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2NyZWF0ZS92MS9kb21haW4vY29udGV4dC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBiYXNlbmFtZSB9IGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB0eXBlIHsgQ2xhc3NNb2RlbCB9IGZyb20gXCIuL2NsYXNzLW1vZGVsLmpzXCI7XG5cbi8qKiBUeXBlLXNhZmUga2V5IGZvciBhIHZhbHVlIGluIHRoZSBGZWF0dXJlTW9kZWxTdG9yZS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRmVhdHVyZU1vZGVsS2V5PFQ+IHtcblx0cmVhZG9ubHkgX3N5bTogc3ltYm9sO1xuXHRyZWFkb25seSBfdHlwZT86IFQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtb2RlbEtleTxUPihuYW1lPzogc3RyaW5nKTogRmVhdHVyZU1vZGVsS2V5PFQ+IHtcblx0cmV0dXJuIHsgX3N5bTogU3ltYm9sKG5hbWUpIH07XG59XG5cbi8qKlxuICogSW1tdXRhYmxlIHR5cGVkIHN0b3JlIG9mIGZlYXR1cmUgbW9kZWxzLiBFYWNoIGZlYXR1cmUgZGVmaW5lcyBpdHMgb3duIGtleXNcbiAqICh0eXBlZCB2aWEgYG1vZGVsS2V5PFQ+KClgKSBhbmQgd3JpdGVzIHRvIC8gcmVhZHMgZnJvbSB0aGUgc3RvcmUgZHVyaW5nIHRoZVxuICogYGNvbmZpZ3VyZWAgYW5kIGByZW5kZXJgIHBoYXNlcy4gVGhlIHN0b3JlIGlzIHRoZSBvbmx5IG1lY2hhbmlzbSBieSB3aGljaFxuICogZmVhdHVyZXMgY29tbXVuaWNhdGUuXG4gKi9cbmV4cG9ydCBjbGFzcyBGZWF0dXJlTW9kZWxTdG9yZSB7XG5cdHByaXZhdGUgcmVhZG9ubHkgX3N0b3JlOiBSZWFkb25seU1hcDxzeW1ib2wsIHVua25vd24+O1xuXG5cdHB1YmxpYyBjb25zdHJ1Y3RvcihzdG9yZT86IFJlYWRvbmx5TWFwPHN5bWJvbCwgdW5rbm93bj4pIHtcblx0XHR0aGlzLl9zdG9yZSA9IHN0b3JlID8/IG5ldyBNYXAoKTtcblx0fVxuXG5cdHB1YmxpYyBnZXQ8VD4oa2V5OiBGZWF0dXJlTW9kZWxLZXk8VD4pOiBUIHwgdW5kZWZpbmVkIHtcblx0XHRyZXR1cm4gdGhpcy5fc3RvcmUuZ2V0KGtleS5fc3ltKSBhcyBUIHwgdW5kZWZpbmVkO1xuXHR9XG5cblx0cHVibGljIHNldDxUPihrZXk6IEZlYXR1cmVNb2RlbEtleTxUPiwgdmFsdWU6IFQpOiBGZWF0dXJlTW9kZWxTdG9yZSB7XG5cdFx0Y29uc3QgbmV4dCA9IG5ldyBNYXAodGhpcy5fc3RvcmUpO1xuXHRcdG5leHQuc2V0KGtleS5fc3ltLCB2YWx1ZSk7XG5cdFx0cmV0dXJuIG5ldyBGZWF0dXJlTW9kZWxTdG9yZShuZXh0KTtcblx0fVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNjYWZmb2xkT3B0aW9ucyB7XG5cdHllcz86IGJvb2xlYW47XG5cdHRlbXBsYXRlPzogXCJhcGlcIiB8IFwiY2xpXCI7XG5cdGRhdGFiYXNlPzogXCJ0eXBlb3JtXCI7XG5cdGlkcD86IFwiYXV0aDBcIjtcblx0cG9zdG1hbj86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2NhZmZvbGRDb250ZXh0IHtcblx0cHJvamVjdE5hbWU6IHN0cmluZztcblx0dGFyZ2V0RGlyOiBzdHJpbmc7XG5cdG9wdHM6IFNjYWZmb2xkT3B0aW9ucztcblx0dGVtcGxhdGU6IFwiYXBpXCIgfCBcImNsaVwiO1xuXHRtb2RlbHM6IEZlYXR1cmVNb2RlbFN0b3JlO1xuXHQvKiogTGl2ZSBjb250cm9sbGVyIG1vZGVscyB0aGF0IGZlYXR1cmVzIGNvbnRyaWJ1dGUgdG8gZHVyaW5nIGNvbmZpZ3VyZS4gKi9cblx0Y29udHJvbGxlcnM6IENsYXNzTW9kZWxbXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUNvbnRleHQoXG5cdHRhcmdldERpcjogc3RyaW5nLFxuXHRvcHRzOiBTY2FmZm9sZE9wdGlvbnMsXG5cdHRlbXBsYXRlOiBcImFwaVwiIHwgXCJjbGlcIiA9IFwiYXBpXCIsXG4pOiBTY2FmZm9sZENvbnRleHQge1xuXHRyZXR1cm4ge1xuXHRcdHByb2plY3ROYW1lOiBiYXNlbmFtZSh0YXJnZXREaXIpLFxuXHRcdHRhcmdldERpcixcblx0XHRvcHRzLFxuXHRcdHRlbXBsYXRlLFxuXHRcdG1vZGVsczogbmV3IEZlYXR1cmVNb2RlbFN0b3JlKCksXG5cdFx0Y29udHJvbGxlcnM6IFtdLFxuXHR9O1xufVxuIl0sIm5hbWVzIjpbImJhc2VuYW1lIiwibW9kZWxLZXkiLCJuYW1lIiwiX3N5bSIsIlN5bWJvbCIsIkZlYXR1cmVNb2RlbFN0b3JlIiwiX3N0b3JlIiwic3RvcmUiLCJNYXAiLCJnZXQiLCJrZXkiLCJzZXQiLCJ2YWx1ZSIsIm5leHQiLCJjcmVhdGVDb250ZXh0IiwidGFyZ2V0RGlyIiwib3B0cyIsInRlbXBsYXRlIiwicHJvamVjdE5hbWUiLCJtb2RlbHMiLCJjb250cm9sbGVycyJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsUUFBUSxRQUFRLFlBQVk7QUFTckMsT0FBTyxTQUFTQyxTQUFZQyxJQUFhO0lBQ3hDLE9BQU87UUFBRUMsTUFBTUMsT0FBT0Y7SUFBTTtBQUM3QjtBQUVBOzs7OztDQUtDLEdBQ0QsT0FBTyxNQUFNRztJQUNLQyxPQUFxQztJQUV0RCxZQUFtQkMsS0FBb0MsQ0FBRTtRQUN4RCxJQUFJLENBQUNELE1BQU0sR0FBR0MsU0FBUyxJQUFJQztJQUM1QjtJQUVPQyxJQUFPQyxHQUF1QixFQUFpQjtRQUNyRCxPQUFPLElBQUksQ0FBQ0osTUFBTSxDQUFDRyxHQUFHLENBQUNDLElBQUlQLElBQUk7SUFDaEM7SUFFT1EsSUFBT0QsR0FBdUIsRUFBRUUsS0FBUSxFQUFxQjtRQUNuRSxNQUFNQyxPQUFPLElBQUlMLElBQUksSUFBSSxDQUFDRixNQUFNO1FBQ2hDTyxLQUFLRixHQUFHLENBQUNELElBQUlQLElBQUksRUFBRVM7UUFDbkIsT0FBTyxJQUFJUCxrQkFBa0JRO0lBQzlCO0FBQ0Q7QUFvQkEsT0FBTyxTQUFTQyxjQUNmQyxTQUFpQixFQUNqQkMsSUFBcUIsRUFDckJDLFdBQTBCLEtBQUs7SUFFL0IsT0FBTztRQUNOQyxhQUFhbEIsU0FBU2U7UUFDdEJBO1FBQ0FDO1FBQ0FDO1FBQ0FFLFFBQVEsSUFBSWQ7UUFDWmUsYUFBYSxFQUFFO0lBQ2hCO0FBQ0QifQ==
@@ -0,0 +1,104 @@
1
+ import { modelKey } from "./context.js";
2
+ import { DockerfileModel } from "./dockerfile.model.js";
3
+ export const DEVCONTAINER_KEY = modelKey("devcontainer");
4
+ /**
5
+ * Live builder for `.devcontainer/devcontainer.json`.
6
+ *
7
+ * The api-core feature creates an instance in its `configure` phase.
8
+ * Other features (typeorm, auth0, …) call `addExtension` / `addFeature` / etc.
9
+ * in their own `configure` phases. The devcontainer `render` phase calls `render()`.
10
+ */ export class DevcontainerModel {
11
+ _name;
12
+ _image;
13
+ _composeFile = null;
14
+ _composeService = "app";
15
+ _dockerfile = null;
16
+ _extensions = [];
17
+ _ports = [];
18
+ _postCreateCommands = [];
19
+ _postStartCommands = [];
20
+ _devcontainerFeatures = new Map();
21
+ constructor(name, image = "node:24"){
22
+ this._name = name;
23
+ this._image = image;
24
+ }
25
+ get image() {
26
+ return this._image;
27
+ }
28
+ setImage(image) {
29
+ this._image = image;
30
+ return this;
31
+ }
32
+ /** Switch to Docker Compose mode. Call from a feature that adds a compose service. */ useCompose(file = "docker-compose.yml", service = "devcontainer") {
33
+ this._composeFile = file;
34
+ this._composeService = service;
35
+ this._dockerfile = new DockerfileModel();
36
+ return this;
37
+ }
38
+ /** The Dockerfile model, available only when in compose mode. */ get dockerfile() {
39
+ return this._dockerfile;
40
+ }
41
+ addExtension(...ids) {
42
+ for (const id of ids){
43
+ if (!this._extensions.includes(id)) this._extensions.push(id);
44
+ }
45
+ return this;
46
+ }
47
+ forwardPort(...ports) {
48
+ for (const port of ports){
49
+ if (!this._ports.includes(port)) this._ports.push(port);
50
+ }
51
+ return this;
52
+ }
53
+ addPostCreateCommand(cmd) {
54
+ if (!this._postCreateCommands.includes(cmd)) this._postCreateCommands.push(cmd);
55
+ return this;
56
+ }
57
+ addPostStartCommand(cmd) {
58
+ if (!this._postStartCommands.includes(cmd)) this._postStartCommands.push(cmd);
59
+ return this;
60
+ }
61
+ /** Add a devcontainer Feature, e.g. `ghcr.io/devcontainers/features/node:1`. */ addFeature(id, options = {}) {
62
+ this._devcontainerFeatures.set(id, options);
63
+ return this;
64
+ }
65
+ render() {
66
+ const obj = {
67
+ name: this._name
68
+ };
69
+ if (this._composeFile) {
70
+ obj.dockerComposeFile = [
71
+ this._composeFile
72
+ ];
73
+ obj.service = this._composeService;
74
+ obj.workspaceFolder = "/workspace";
75
+ obj.mounts = [
76
+ "source=..,target=/workspace,type=bind,consistency=cached"
77
+ ];
78
+ } else {
79
+ obj.image = this._image;
80
+ }
81
+ if (this._devcontainerFeatures.size > 0) {
82
+ obj.features = Object.fromEntries(this._devcontainerFeatures);
83
+ }
84
+ if (this._extensions.length > 0) {
85
+ obj.customizations = {
86
+ vscode: {
87
+ extensions: this._extensions
88
+ }
89
+ };
90
+ }
91
+ if (this._ports.length > 0) {
92
+ obj.forwardPorts = this._ports;
93
+ }
94
+ if (this._postCreateCommands.length > 0) {
95
+ obj.postCreateCommand = this._postCreateCommands.length === 1 ? this._postCreateCommands[0] : this._postCreateCommands.join(" && ");
96
+ }
97
+ if (this._postStartCommands.length > 0) {
98
+ obj.postStartCommand = this._postStartCommands.length === 1 ? this._postStartCommands[0] : this._postStartCommands.join(" && ");
99
+ }
100
+ return `${JSON.stringify(obj, null, 2)}\n`;
101
+ }
102
+ }
103
+
104
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2NyZWF0ZS92MS9kb21haW4vZGV2Y29udGFpbmVyLm1vZGVsLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IG1vZGVsS2V5IH0gZnJvbSBcIi4vY29udGV4dC5qc1wiO1xuaW1wb3J0IHsgRG9ja2VyZmlsZU1vZGVsIH0gZnJvbSBcIi4vZG9ja2VyZmlsZS5tb2RlbC5qc1wiO1xuXG5leHBvcnQgY29uc3QgREVWQ09OVEFJTkVSX0tFWSA9IG1vZGVsS2V5PERldmNvbnRhaW5lck1vZGVsPihcImRldmNvbnRhaW5lclwiKTtcblxuLyoqXG4gKiBMaXZlIGJ1aWxkZXIgZm9yIGAuZGV2Y29udGFpbmVyL2RldmNvbnRhaW5lci5qc29uYC5cbiAqXG4gKiBUaGUgYXBpLWNvcmUgZmVhdHVyZSBjcmVhdGVzIGFuIGluc3RhbmNlIGluIGl0cyBgY29uZmlndXJlYCBwaGFzZS5cbiAqIE90aGVyIGZlYXR1cmVzICh0eXBlb3JtLCBhdXRoMCwg4oCmKSBjYWxsIGBhZGRFeHRlbnNpb25gIC8gYGFkZEZlYXR1cmVgIC8gZXRjLlxuICogaW4gdGhlaXIgb3duIGBjb25maWd1cmVgIHBoYXNlcy4gIFRoZSBkZXZjb250YWluZXIgYHJlbmRlcmAgcGhhc2UgY2FsbHMgYHJlbmRlcigpYC5cbiAqL1xuZXhwb3J0IGNsYXNzIERldmNvbnRhaW5lck1vZGVsIHtcblx0cHJpdmF0ZSByZWFkb25seSBfbmFtZTogc3RyaW5nO1xuXHRwcml2YXRlIF9pbWFnZTogc3RyaW5nO1xuXHRwcml2YXRlIF9jb21wb3NlRmlsZTogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cdHByaXZhdGUgX2NvbXBvc2VTZXJ2aWNlID0gXCJhcHBcIjtcblx0cHJpdmF0ZSBfZG9ja2VyZmlsZTogRG9ja2VyZmlsZU1vZGVsIHwgbnVsbCA9IG51bGw7XG5cdHByaXZhdGUgcmVhZG9ubHkgX2V4dGVuc2lvbnM6IHN0cmluZ1tdID0gW107XG5cdHByaXZhdGUgcmVhZG9ubHkgX3BvcnRzOiBudW1iZXJbXSA9IFtdO1xuXHRwcml2YXRlIHJlYWRvbmx5IF9wb3N0Q3JlYXRlQ29tbWFuZHM6IHN0cmluZ1tdID0gW107XG5cdHByaXZhdGUgcmVhZG9ubHkgX3Bvc3RTdGFydENvbW1hbmRzOiBzdHJpbmdbXSA9IFtdO1xuXHRwcml2YXRlIHJlYWRvbmx5IF9kZXZjb250YWluZXJGZWF0dXJlczogTWFwPHN0cmluZywgUmVjb3JkPHN0cmluZywgdW5rbm93bj4+ID0gbmV3IE1hcCgpO1xuXG5cdHB1YmxpYyBjb25zdHJ1Y3RvcihuYW1lOiBzdHJpbmcsIGltYWdlID0gXCJub2RlOjI0XCIpIHtcblx0XHR0aGlzLl9uYW1lID0gbmFtZTtcblx0XHR0aGlzLl9pbWFnZSA9IGltYWdlO1xuXHR9XG5cblx0cHVibGljIGdldCBpbWFnZSgpOiBzdHJpbmcge1xuXHRcdHJldHVybiB0aGlzLl9pbWFnZTtcblx0fVxuXG5cdHB1YmxpYyBzZXRJbWFnZShpbWFnZTogc3RyaW5nKTogdGhpcyB7XG5cdFx0dGhpcy5faW1hZ2UgPSBpbWFnZTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKiBTd2l0Y2ggdG8gRG9ja2VyIENvbXBvc2UgbW9kZS4gQ2FsbCBmcm9tIGEgZmVhdHVyZSB0aGF0IGFkZHMgYSBjb21wb3NlIHNlcnZpY2UuICovXG5cdHB1YmxpYyB1c2VDb21wb3NlKGZpbGUgPSBcImRvY2tlci1jb21wb3NlLnltbFwiLCBzZXJ2aWNlID0gXCJkZXZjb250YWluZXJcIik6IHRoaXMge1xuXHRcdHRoaXMuX2NvbXBvc2VGaWxlID0gZmlsZTtcblx0XHR0aGlzLl9jb21wb3NlU2VydmljZSA9IHNlcnZpY2U7XG5cdFx0dGhpcy5fZG9ja2VyZmlsZSA9IG5ldyBEb2NrZXJmaWxlTW9kZWwoKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKiBUaGUgRG9ja2VyZmlsZSBtb2RlbCwgYXZhaWxhYmxlIG9ubHkgd2hlbiBpbiBjb21wb3NlIG1vZGUuICovXG5cdHB1YmxpYyBnZXQgZG9ja2VyZmlsZSgpOiBEb2NrZXJmaWxlTW9kZWwgfCBudWxsIHtcblx0XHRyZXR1cm4gdGhpcy5fZG9ja2VyZmlsZTtcblx0fVxuXG5cdHB1YmxpYyBhZGRFeHRlbnNpb24oLi4uaWRzOiBzdHJpbmdbXSk6IHRoaXMge1xuXHRcdGZvciAoY29uc3QgaWQgb2YgaWRzKSB7XG5cdFx0XHRpZiAoIXRoaXMuX2V4dGVuc2lvbnMuaW5jbHVkZXMoaWQpKSB0aGlzLl9leHRlbnNpb25zLnB1c2goaWQpO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdHB1YmxpYyBmb3J3YXJkUG9ydCguLi5wb3J0czogbnVtYmVyW10pOiB0aGlzIHtcblx0XHRmb3IgKGNvbnN0IHBvcnQgb2YgcG9ydHMpIHtcblx0XHRcdGlmICghdGhpcy5fcG9ydHMuaW5jbHVkZXMocG9ydCkpIHRoaXMuX3BvcnRzLnB1c2gocG9ydCk7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0cHVibGljIGFkZFBvc3RDcmVhdGVDb21tYW5kKGNtZDogc3RyaW5nKTogdGhpcyB7XG5cdFx0aWYgKCF0aGlzLl9wb3N0Q3JlYXRlQ29tbWFuZHMuaW5jbHVkZXMoY21kKSkgdGhpcy5fcG9zdENyZWF0ZUNvbW1hbmRzLnB1c2goY21kKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdHB1YmxpYyBhZGRQb3N0U3RhcnRDb21tYW5kKGNtZDogc3RyaW5nKTogdGhpcyB7XG5cdFx0aWYgKCF0aGlzLl9wb3N0U3RhcnRDb21tYW5kcy5pbmNsdWRlcyhjbWQpKSB0aGlzLl9wb3N0U3RhcnRDb21tYW5kcy5wdXNoKGNtZCk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHQvKiogQWRkIGEgZGV2Y29udGFpbmVyIEZlYXR1cmUsIGUuZy4gYGdoY3IuaW8vZGV2Y29udGFpbmVycy9mZWF0dXJlcy9ub2RlOjFgLiAqL1xuXHRwdWJsaWMgYWRkRmVhdHVyZShpZDogc3RyaW5nLCBvcHRpb25zOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHt9KTogdGhpcyB7XG5cdFx0dGhpcy5fZGV2Y29udGFpbmVyRmVhdHVyZXMuc2V0KGlkLCBvcHRpb25zKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdHB1YmxpYyByZW5kZXIoKTogc3RyaW5nIHtcblx0XHRjb25zdCBvYmo6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0geyBuYW1lOiB0aGlzLl9uYW1lIH07XG5cblx0XHRpZiAodGhpcy5fY29tcG9zZUZpbGUpIHtcblx0XHRcdG9iai5kb2NrZXJDb21wb3NlRmlsZSA9IFt0aGlzLl9jb21wb3NlRmlsZV07XG5cdFx0XHRvYmouc2VydmljZSA9IHRoaXMuX2NvbXBvc2VTZXJ2aWNlO1xuXHRcdFx0b2JqLndvcmtzcGFjZUZvbGRlciA9IFwiL3dvcmtzcGFjZVwiO1xuXHRcdFx0b2JqLm1vdW50cyA9IFtcInNvdXJjZT0uLix0YXJnZXQ9L3dvcmtzcGFjZSx0eXBlPWJpbmQsY29uc2lzdGVuY3k9Y2FjaGVkXCJdO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRvYmouaW1hZ2UgPSB0aGlzLl9pbWFnZTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5fZGV2Y29udGFpbmVyRmVhdHVyZXMuc2l6ZSA+IDApIHtcblx0XHRcdG9iai5mZWF0dXJlcyA9IE9iamVjdC5mcm9tRW50cmllcyh0aGlzLl9kZXZjb250YWluZXJGZWF0dXJlcyk7XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMuX2V4dGVuc2lvbnMubGVuZ3RoID4gMCkge1xuXHRcdFx0b2JqLmN1c3RvbWl6YXRpb25zID0ge1xuXHRcdFx0XHR2c2NvZGU6IHtcblx0XHRcdFx0XHRleHRlbnNpb25zOiB0aGlzLl9leHRlbnNpb25zLFxuXHRcdFx0XHR9LFxuXHRcdFx0fTtcblx0XHR9XG5cblx0XHRpZiAodGhpcy5fcG9ydHMubGVuZ3RoID4gMCkge1xuXHRcdFx0b2JqLmZvcndhcmRQb3J0cyA9IHRoaXMuX3BvcnRzO1xuXHRcdH1cblxuXHRcdGlmICh0aGlzLl9wb3N0Q3JlYXRlQ29tbWFuZHMubGVuZ3RoID4gMCkge1xuXHRcdFx0b2JqLnBvc3RDcmVhdGVDb21tYW5kID1cblx0XHRcdFx0dGhpcy5fcG9zdENyZWF0ZUNvbW1hbmRzLmxlbmd0aCA9PT0gMVxuXHRcdFx0XHRcdD8gdGhpcy5fcG9zdENyZWF0ZUNvbW1hbmRzWzBdXG5cdFx0XHRcdFx0OiB0aGlzLl9wb3N0Q3JlYXRlQ29tbWFuZHMuam9pbihcIiAmJiBcIik7XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMuX3Bvc3RTdGFydENvbW1hbmRzLmxlbmd0aCA+IDApIHtcblx0XHRcdG9iai5wb3N0U3RhcnRDb21tYW5kID1cblx0XHRcdFx0dGhpcy5fcG9zdFN0YXJ0Q29tbWFuZHMubGVuZ3RoID09PSAxXG5cdFx0XHRcdFx0PyB0aGlzLl9wb3N0U3RhcnRDb21tYW5kc1swXVxuXHRcdFx0XHRcdDogdGhpcy5fcG9zdFN0YXJ0Q29tbWFuZHMuam9pbihcIiAmJiBcIik7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGAke0pTT04uc3RyaW5naWZ5KG9iaiwgbnVsbCwgMil9XFxuYDtcblx0fVxufVxuIl0sIm5hbWVzIjpbIm1vZGVsS2V5IiwiRG9ja2VyZmlsZU1vZGVsIiwiREVWQ09OVEFJTkVSX0tFWSIsIkRldmNvbnRhaW5lck1vZGVsIiwiX25hbWUiLCJfaW1hZ2UiLCJfY29tcG9zZUZpbGUiLCJfY29tcG9zZVNlcnZpY2UiLCJfZG9ja2VyZmlsZSIsIl9leHRlbnNpb25zIiwiX3BvcnRzIiwiX3Bvc3RDcmVhdGVDb21tYW5kcyIsIl9wb3N0U3RhcnRDb21tYW5kcyIsIl9kZXZjb250YWluZXJGZWF0dXJlcyIsIk1hcCIsIm5hbWUiLCJpbWFnZSIsInNldEltYWdlIiwidXNlQ29tcG9zZSIsImZpbGUiLCJzZXJ2aWNlIiwiZG9ja2VyZmlsZSIsImFkZEV4dGVuc2lvbiIsImlkcyIsImlkIiwiaW5jbHVkZXMiLCJwdXNoIiwiZm9yd2FyZFBvcnQiLCJwb3J0cyIsInBvcnQiLCJhZGRQb3N0Q3JlYXRlQ29tbWFuZCIsImNtZCIsImFkZFBvc3RTdGFydENvbW1hbmQiLCJhZGRGZWF0dXJlIiwib3B0aW9ucyIsInNldCIsInJlbmRlciIsIm9iaiIsImRvY2tlckNvbXBvc2VGaWxlIiwid29ya3NwYWNlRm9sZGVyIiwibW91bnRzIiwic2l6ZSIsImZlYXR1cmVzIiwiT2JqZWN0IiwiZnJvbUVudHJpZXMiLCJsZW5ndGgiLCJjdXN0b21pemF0aW9ucyIsInZzY29kZSIsImV4dGVuc2lvbnMiLCJmb3J3YXJkUG9ydHMiLCJwb3N0Q3JlYXRlQ29tbWFuZCIsImpvaW4iLCJwb3N0U3RhcnRDb21tYW5kIiwiSlNPTiIsInN0cmluZ2lmeSJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsUUFBUSxRQUFRLGVBQWU7QUFDeEMsU0FBU0MsZUFBZSxRQUFRLHdCQUF3QjtBQUV4RCxPQUFPLE1BQU1DLG1CQUFtQkYsU0FBNEIsZ0JBQWdCO0FBRTVFOzs7Ozs7Q0FNQyxHQUNELE9BQU8sTUFBTUc7SUFDS0MsTUFBYztJQUN2QkMsT0FBZTtJQUNmQyxlQUE4QixLQUFLO0lBQ25DQyxrQkFBa0IsTUFBTTtJQUN4QkMsY0FBc0MsS0FBSztJQUNsQ0MsY0FBd0IsRUFBRSxDQUFDO0lBQzNCQyxTQUFtQixFQUFFLENBQUM7SUFDdEJDLHNCQUFnQyxFQUFFLENBQUM7SUFDbkNDLHFCQUErQixFQUFFLENBQUM7SUFDbENDLHdCQUE4RCxJQUFJQyxNQUFNO0lBRXpGLFlBQW1CQyxJQUFZLEVBQUVDLFFBQVEsU0FBUyxDQUFFO1FBQ25ELElBQUksQ0FBQ1osS0FBSyxHQUFHVztRQUNiLElBQUksQ0FBQ1YsTUFBTSxHQUFHVztJQUNmO0lBRUEsSUFBV0EsUUFBZ0I7UUFDMUIsT0FBTyxJQUFJLENBQUNYLE1BQU07SUFDbkI7SUFFT1ksU0FBU0QsS0FBYSxFQUFRO1FBQ3BDLElBQUksQ0FBQ1gsTUFBTSxHQUFHVztRQUNkLE9BQU8sSUFBSTtJQUNaO0lBRUEsb0ZBQW9GLEdBQ3BGLEFBQU9FLFdBQVdDLE9BQU8sb0JBQW9CLEVBQUVDLFVBQVUsY0FBYyxFQUFRO1FBQzlFLElBQUksQ0FBQ2QsWUFBWSxHQUFHYTtRQUNwQixJQUFJLENBQUNaLGVBQWUsR0FBR2E7UUFDdkIsSUFBSSxDQUFDWixXQUFXLEdBQUcsSUFBSVA7UUFDdkIsT0FBTyxJQUFJO0lBQ1o7SUFFQSwrREFBK0QsR0FDL0QsSUFBV29CLGFBQXFDO1FBQy9DLE9BQU8sSUFBSSxDQUFDYixXQUFXO0lBQ3hCO0lBRU9jLGFBQWEsR0FBR0MsR0FBYSxFQUFRO1FBQzNDLEtBQUssTUFBTUMsTUFBTUQsSUFBSztZQUNyQixJQUFJLENBQUMsSUFBSSxDQUFDZCxXQUFXLENBQUNnQixRQUFRLENBQUNELEtBQUssSUFBSSxDQUFDZixXQUFXLENBQUNpQixJQUFJLENBQUNGO1FBQzNEO1FBQ0EsT0FBTyxJQUFJO0lBQ1o7SUFFT0csWUFBWSxHQUFHQyxLQUFlLEVBQVE7UUFDNUMsS0FBSyxNQUFNQyxRQUFRRCxNQUFPO1lBQ3pCLElBQUksQ0FBQyxJQUFJLENBQUNsQixNQUFNLENBQUNlLFFBQVEsQ0FBQ0ksT0FBTyxJQUFJLENBQUNuQixNQUFNLENBQUNnQixJQUFJLENBQUNHO1FBQ25EO1FBQ0EsT0FBTyxJQUFJO0lBQ1o7SUFFT0MscUJBQXFCQyxHQUFXLEVBQVE7UUFDOUMsSUFBSSxDQUFDLElBQUksQ0FBQ3BCLG1CQUFtQixDQUFDYyxRQUFRLENBQUNNLE1BQU0sSUFBSSxDQUFDcEIsbUJBQW1CLENBQUNlLElBQUksQ0FBQ0s7UUFDM0UsT0FBTyxJQUFJO0lBQ1o7SUFFT0Msb0JBQW9CRCxHQUFXLEVBQVE7UUFDN0MsSUFBSSxDQUFDLElBQUksQ0FBQ25CLGtCQUFrQixDQUFDYSxRQUFRLENBQUNNLE1BQU0sSUFBSSxDQUFDbkIsa0JBQWtCLENBQUNjLElBQUksQ0FBQ0s7UUFDekUsT0FBTyxJQUFJO0lBQ1o7SUFFQSw4RUFBOEUsR0FDOUUsQUFBT0UsV0FBV1QsRUFBVSxFQUFFVSxVQUFtQyxDQUFDLENBQUMsRUFBUTtRQUMxRSxJQUFJLENBQUNyQixxQkFBcUIsQ0FBQ3NCLEdBQUcsQ0FBQ1gsSUFBSVU7UUFDbkMsT0FBTyxJQUFJO0lBQ1o7SUFFT0UsU0FBaUI7UUFDdkIsTUFBTUMsTUFBK0I7WUFBRXRCLE1BQU0sSUFBSSxDQUFDWCxLQUFLO1FBQUM7UUFFeEQsSUFBSSxJQUFJLENBQUNFLFlBQVksRUFBRTtZQUN0QitCLElBQUlDLGlCQUFpQixHQUFHO2dCQUFDLElBQUksQ0FBQ2hDLFlBQVk7YUFBQztZQUMzQytCLElBQUlqQixPQUFPLEdBQUcsSUFBSSxDQUFDYixlQUFlO1lBQ2xDOEIsSUFBSUUsZUFBZSxHQUFHO1lBQ3RCRixJQUFJRyxNQUFNLEdBQUc7Z0JBQUM7YUFBMkQ7UUFDMUUsT0FBTztZQUNOSCxJQUFJckIsS0FBSyxHQUFHLElBQUksQ0FBQ1gsTUFBTTtRQUN4QjtRQUVBLElBQUksSUFBSSxDQUFDUSxxQkFBcUIsQ0FBQzRCLElBQUksR0FBRyxHQUFHO1lBQ3hDSixJQUFJSyxRQUFRLEdBQUdDLE9BQU9DLFdBQVcsQ0FBQyxJQUFJLENBQUMvQixxQkFBcUI7UUFDN0Q7UUFFQSxJQUFJLElBQUksQ0FBQ0osV0FBVyxDQUFDb0MsTUFBTSxHQUFHLEdBQUc7WUFDaENSLElBQUlTLGNBQWMsR0FBRztnQkFDcEJDLFFBQVE7b0JBQ1BDLFlBQVksSUFBSSxDQUFDdkMsV0FBVztnQkFDN0I7WUFDRDtRQUNEO1FBRUEsSUFBSSxJQUFJLENBQUNDLE1BQU0sQ0FBQ21DLE1BQU0sR0FBRyxHQUFHO1lBQzNCUixJQUFJWSxZQUFZLEdBQUcsSUFBSSxDQUFDdkMsTUFBTTtRQUMvQjtRQUVBLElBQUksSUFBSSxDQUFDQyxtQkFBbUIsQ0FBQ2tDLE1BQU0sR0FBRyxHQUFHO1lBQ3hDUixJQUFJYSxpQkFBaUIsR0FDcEIsSUFBSSxDQUFDdkMsbUJBQW1CLENBQUNrQyxNQUFNLEtBQUssSUFDakMsSUFBSSxDQUFDbEMsbUJBQW1CLENBQUMsRUFBRSxHQUMzQixJQUFJLENBQUNBLG1CQUFtQixDQUFDd0MsSUFBSSxDQUFDO1FBQ25DO1FBRUEsSUFBSSxJQUFJLENBQUN2QyxrQkFBa0IsQ0FBQ2lDLE1BQU0sR0FBRyxHQUFHO1lBQ3ZDUixJQUFJZSxnQkFBZ0IsR0FDbkIsSUFBSSxDQUFDeEMsa0JBQWtCLENBQUNpQyxNQUFNLEtBQUssSUFDaEMsSUFBSSxDQUFDakMsa0JBQWtCLENBQUMsRUFBRSxHQUMxQixJQUFJLENBQUNBLGtCQUFrQixDQUFDdUMsSUFBSSxDQUFDO1FBQ2xDO1FBRUEsT0FBTyxHQUFHRSxLQUFLQyxTQUFTLENBQUNqQixLQUFLLE1BQU0sR0FBRyxFQUFFLENBQUM7SUFDM0M7QUFDRCJ9
@@ -0,0 +1,52 @@
1
+ export class DockerfileModel {
2
+ _baseImage;
3
+ _runs = [];
4
+ constructor(baseImage = "node:24"){
5
+ this._baseImage = baseImage;
6
+ }
7
+ /**
8
+ * Append a RUN instruction executed as root, inserted after the base
9
+ * toolchain setup and before the USER switch.
10
+ */ addRun(cmd) {
11
+ this._runs.push(cmd);
12
+ return this;
13
+ }
14
+ render() {
15
+ const extras = this._runs.length > 0 ? `\n${this._runs.map((cmd)=>`RUN ${cmd}`).join("\n\n")}\n` : "";
16
+ return `FROM ${this._baseImage}
17
+
18
+ ARG USERNAME=node
19
+
20
+ # System tools: jq + ripgrep for scripting/search, python3 for AI tooling,
21
+ # gh for GitHub workflows, curl/gnupg for package sources.
22
+ RUN apt-get update \\
23
+ && apt-get install -y --no-install-recommends ca-certificates curl gnupg jq ripgrep python3 \\
24
+ && curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg -o /usr/share/keyrings/githubcli-archive-keyring.gpg \\
25
+ && chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \\
26
+ && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" > /etc/apt/sources.list.d/github-cli.list \\
27
+ && apt-get update \\
28
+ && apt-get install -y --no-install-recommends gh \\
29
+ && rm -rf /var/lib/apt/lists/*
30
+
31
+ RUN npm install --global npm@latest \\
32
+ && npm add --global pnpm@10
33
+
34
+ RUN mkdir -p /home/\${USERNAME}/.config/pnpm /home/\${USERNAME}/.pnpm-store \\
35
+ && chown -R \${USERNAME}:\${USERNAME} /home/\${USERNAME}/.config /home/\${USERNAME}/.pnpm-store \\
36
+ && printf "store-dir=/home/\${USERNAME}/.pnpm-store\\n" > /home/\${USERNAME}/.config/pnpm/rc
37
+
38
+ # Pre-create workspace node_modules so the named volume mount is owned by the user
39
+ RUN mkdir -p /workspace/node_modules && chown \${USERNAME}:\${USERNAME} /workspace/node_modules
40
+
41
+ RUN mkdir /commandhistory && touch /commandhistory/.bash_history \\
42
+ && chown -R \${USERNAME} /commandhistory
43
+
44
+ RUN SNIPPET="export PROMPT_COMMAND='history -a' && export HISTFILE=/commandhistory/.bash_history" \\
45
+ && echo "$SNIPPET" >> "/home/\${USERNAME}/.bashrc"
46
+ ${extras}
47
+ USER \${USERNAME}
48
+ `;
49
+ }
50
+ }
51
+
52
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2NyZWF0ZS92MS9kb21haW4vZG9ja2VyZmlsZS5tb2RlbC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY2xhc3MgRG9ja2VyZmlsZU1vZGVsIHtcblx0cHJpdmF0ZSByZWFkb25seSBfYmFzZUltYWdlOiBzdHJpbmc7XG5cdHByaXZhdGUgcmVhZG9ubHkgX3J1bnM6IHN0cmluZ1tdID0gW107XG5cblx0cHVibGljIGNvbnN0cnVjdG9yKGJhc2VJbWFnZSA9IFwibm9kZToyNFwiKSB7XG5cdFx0dGhpcy5fYmFzZUltYWdlID0gYmFzZUltYWdlO1xuXHR9XG5cblx0LyoqXG5cdCAqIEFwcGVuZCBhIFJVTiBpbnN0cnVjdGlvbiBleGVjdXRlZCBhcyByb290LCBpbnNlcnRlZCBhZnRlciB0aGUgYmFzZVxuXHQgKiB0b29sY2hhaW4gc2V0dXAgYW5kIGJlZm9yZSB0aGUgVVNFUiBzd2l0Y2guXG5cdCAqL1xuXHRwdWJsaWMgYWRkUnVuKGNtZDogc3RyaW5nKTogdGhpcyB7XG5cdFx0dGhpcy5fcnVucy5wdXNoKGNtZCk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cblxuXHRwdWJsaWMgcmVuZGVyKCk6IHN0cmluZyB7XG5cdFx0Y29uc3QgZXh0cmFzID1cblx0XHRcdHRoaXMuX3J1bnMubGVuZ3RoID4gMCA/IGBcXG4ke3RoaXMuX3J1bnMubWFwKChjbWQpID0+IGBSVU4gJHtjbWR9YCkuam9pbihcIlxcblxcblwiKX1cXG5gIDogXCJcIjtcblxuXHRcdHJldHVybiBgRlJPTSAke3RoaXMuX2Jhc2VJbWFnZX1cblxuQVJHIFVTRVJOQU1FPW5vZGVcblxuIyBTeXN0ZW0gdG9vbHM6IGpxICsgcmlwZ3JlcCBmb3Igc2NyaXB0aW5nL3NlYXJjaCwgcHl0aG9uMyBmb3IgQUkgdG9vbGluZyxcbiMgZ2ggZm9yIEdpdEh1YiB3b3JrZmxvd3MsIGN1cmwvZ251cGcgZm9yIHBhY2thZ2Ugc291cmNlcy5cblJVTiBhcHQtZ2V0IHVwZGF0ZSBcXFxcXG4gICAgJiYgYXB0LWdldCBpbnN0YWxsIC15IC0tbm8taW5zdGFsbC1yZWNvbW1lbmRzIGNhLWNlcnRpZmljYXRlcyBjdXJsIGdudXBnIGpxIHJpcGdyZXAgcHl0aG9uMyBcXFxcXG4gICAgJiYgY3VybCAtZnNTTCBodHRwczovL2NsaS5naXRodWIuY29tL3BhY2thZ2VzL2dpdGh1YmNsaS1hcmNoaXZlLWtleXJpbmcuZ3BnIC1vIC91c3Ivc2hhcmUva2V5cmluZ3MvZ2l0aHViY2xpLWFyY2hpdmUta2V5cmluZy5ncGcgXFxcXFxuICAgICYmIGNobW9kIGdvK3IgL3Vzci9zaGFyZS9rZXlyaW5ncy9naXRodWJjbGktYXJjaGl2ZS1rZXlyaW5nLmdwZyBcXFxcXG4gICAgJiYgZWNobyBcImRlYiBbYXJjaD0kKGRwa2cgLS1wcmludC1hcmNoaXRlY3R1cmUpIHNpZ25lZC1ieT0vdXNyL3NoYXJlL2tleXJpbmdzL2dpdGh1YmNsaS1hcmNoaXZlLWtleXJpbmcuZ3BnXSBodHRwczovL2NsaS5naXRodWIuY29tL3BhY2thZ2VzIHN0YWJsZSBtYWluXCIgPiAvZXRjL2FwdC9zb3VyY2VzLmxpc3QuZC9naXRodWItY2xpLmxpc3QgXFxcXFxuICAgICYmIGFwdC1nZXQgdXBkYXRlIFxcXFxcbiAgICAmJiBhcHQtZ2V0IGluc3RhbGwgLXkgLS1uby1pbnN0YWxsLXJlY29tbWVuZHMgZ2ggXFxcXFxuICAgICYmIHJtIC1yZiAvdmFyL2xpYi9hcHQvbGlzdHMvKlxuXG5SVU4gbnBtIGluc3RhbGwgLS1nbG9iYWwgbnBtQGxhdGVzdCBcXFxcXG4gICAgJiYgbnBtIGFkZCAtLWdsb2JhbCBwbnBtQDEwXG5cblJVTiBta2RpciAtcCAvaG9tZS9cXCR7VVNFUk5BTUV9Ly5jb25maWcvcG5wbSAvaG9tZS9cXCR7VVNFUk5BTUV9Ly5wbnBtLXN0b3JlIFxcXFxcbiAgICAmJiBjaG93biAtUiBcXCR7VVNFUk5BTUV9OlxcJHtVU0VSTkFNRX0gL2hvbWUvXFwke1VTRVJOQU1FfS8uY29uZmlnIC9ob21lL1xcJHtVU0VSTkFNRX0vLnBucG0tc3RvcmUgXFxcXFxuICAgICYmIHByaW50ZiBcInN0b3JlLWRpcj0vaG9tZS9cXCR7VVNFUk5BTUV9Ly5wbnBtLXN0b3JlXFxcXG5cIiA+IC9ob21lL1xcJHtVU0VSTkFNRX0vLmNvbmZpZy9wbnBtL3JjXG5cbiMgUHJlLWNyZWF0ZSB3b3Jrc3BhY2Ugbm9kZV9tb2R1bGVzIHNvIHRoZSBuYW1lZCB2b2x1bWUgbW91bnQgaXMgb3duZWQgYnkgdGhlIHVzZXJcblJVTiBta2RpciAtcCAvd29ya3NwYWNlL25vZGVfbW9kdWxlcyAmJiBjaG93biBcXCR7VVNFUk5BTUV9OlxcJHtVU0VSTkFNRX0gL3dvcmtzcGFjZS9ub2RlX21vZHVsZXNcblxuUlVOIG1rZGlyIC9jb21tYW5kaGlzdG9yeSAmJiB0b3VjaCAvY29tbWFuZGhpc3RvcnkvLmJhc2hfaGlzdG9yeSBcXFxcXG4gICAgJiYgY2hvd24gLVIgXFwke1VTRVJOQU1FfSAvY29tbWFuZGhpc3RvcnlcblxuUlVOIFNOSVBQRVQ9XCJleHBvcnQgUFJPTVBUX0NPTU1BTkQ9J2hpc3RvcnkgLWEnICYmIGV4cG9ydCBISVNURklMRT0vY29tbWFuZGhpc3RvcnkvLmJhc2hfaGlzdG9yeVwiIFxcXFxcbiAgICAmJiBlY2hvIFwiJFNOSVBQRVRcIiA+PiBcIi9ob21lL1xcJHtVU0VSTkFNRX0vLmJhc2hyY1wiXG4ke2V4dHJhc31cblVTRVIgXFwke1VTRVJOQU1FfVxuYDtcblx0fVxufVxuIl0sIm5hbWVzIjpbIkRvY2tlcmZpbGVNb2RlbCIsIl9iYXNlSW1hZ2UiLCJfcnVucyIsImJhc2VJbWFnZSIsImFkZFJ1biIsImNtZCIsInB1c2giLCJyZW5kZXIiLCJleHRyYXMiLCJsZW5ndGgiLCJtYXAiLCJqb2luIl0sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLE1BQU1BO0lBQ0tDLFdBQW1CO0lBQ25CQyxRQUFrQixFQUFFLENBQUM7SUFFdEMsWUFBbUJDLFlBQVksU0FBUyxDQUFFO1FBQ3pDLElBQUksQ0FBQ0YsVUFBVSxHQUFHRTtJQUNuQjtJQUVBOzs7RUFHQyxHQUNELEFBQU9DLE9BQU9DLEdBQVcsRUFBUTtRQUNoQyxJQUFJLENBQUNILEtBQUssQ0FBQ0ksSUFBSSxDQUFDRDtRQUNoQixPQUFPLElBQUk7SUFDWjtJQUVPRSxTQUFpQjtRQUN2QixNQUFNQyxTQUNMLElBQUksQ0FBQ04sS0FBSyxDQUFDTyxNQUFNLEdBQUcsSUFBSSxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUNQLEtBQUssQ0FBQ1EsR0FBRyxDQUFDLENBQUNMLE1BQVEsQ0FBQyxJQUFJLEVBQUVBLEtBQUssRUFBRU0sSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLEdBQUc7UUFFdkYsT0FBTyxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUNWLFVBQVUsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBOEJqQyxFQUFFTyxPQUFPOztBQUVULENBQUM7SUFDQTtBQUNEIn0=
@@ -0,0 +1,9 @@
1
+ export const PHASES = [
2
+ "resolve",
3
+ "configure",
4
+ "render",
5
+ "integrate",
6
+ "finalize"
7
+ ];
8
+
9
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2NyZWF0ZS92MS9kb21haW4vZmVhdHVyZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IFNjYWZmb2xkQ29udGV4dCB9IGZyb20gXCIuL2NvbnRleHQuanNcIjtcblxuZXhwb3J0IHR5cGUgU2NhZmZvbGRTdGVwID0gKGN0eDogU2NhZmZvbGRDb250ZXh0KSA9PiBQcm9taXNlPFNjYWZmb2xkQ29udGV4dD47XG5cbi8qKlxuICogQSBGZWF0dXJlIGlzIGEgc2VsZi1jb250YWluZWQgdW5pdCBvZiBzY2FmZm9sZGluZyBiZWhhdmlvci4gRWFjaCBmZWF0dXJlXG4gKiBtYXkgY29udHJpYnV0ZSB0byBvbmUgb3IgbW9yZSBwaGFzZXMuIFBoYXNlcyBydW4gaW4gb3JkZXIgYWNyb3NzIGFsbFxuICogZmVhdHVyZXMsIHNvIGFueSBjcm9zcy1mZWF0dXJlIGRlcGVuZGVuY3kgb24gc2hhcmVkIG1vZGVscyBpcyBuYXR1cmFsbHlcbiAqIHNhdGlzZmllZCAoZS5nLiBgdHlwZW9ybS5jb25maWd1cmVgIHJ1bnMgYmVmb3JlIGBhcGlDb3JlLnJlbmRlcmApLlxuICpcbiAqIFBoYXNlcyAoaW4gZXhlY3V0aW9uIG9yZGVyKTpcbiAqICAgMS4gcmVzb2x2ZSAgIOKAlCBpbnRlcmFjdGl2ZSBwcm9tcHRzOyBtYXkgdXBkYXRlIGN0eC5vcHRzIG9yIHNlZWQgbW9kZWxzXG4gKiAgIDIuIGNvbmZpZ3VyZSDigJQgcHVyZSBtb2RlbCBjb250cmlidXRpb25zIHRvIHRoZSBGZWF0dXJlTW9kZWxTdG9yZVxuICogICAzLiByZW5kZXIgICAg4oCUIHJlYWQgbW9kZWxzLCB3cml0ZSBmaWxlcyB0byBkaXNrXG4gKiAgIDQuIGludGVncmF0ZSDigJQgZXh0ZXJuYWwgc3lzdGVtIGNhbGxzIChDTEkgYmluYXJpZXMsIFJFU1QgQVBJcylcbiAqICAgNS4gZmluYWxpemUgIOKAlCBpbnN0YWxsIGRlcHMsIHByaW50IG5leHQgc3RlcHMsIGV0Yy5cbiAqXG4gKiBgZW5hYmxlZChjdHgpYCBpcyByZS1ldmFsdWF0ZWQgYmVmb3JlIGVhY2ggcGhhc2Ugc28gZmVhdHVyZXMgY2FuIG9wdCBpblxuICogYmFzZWQgb24gb3B0aW9ucyBzZXQgYnkgZWFybGllciBgcmVzb2x2ZWAgcGhhc2VzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEZlYXR1cmUge1xuXHRuYW1lOiBzdHJpbmc7XG5cdGVuYWJsZWQ/OiAoY3R4OiBTY2FmZm9sZENvbnRleHQpID0+IGJvb2xlYW47XG5cdHJlc29sdmU/OiBTY2FmZm9sZFN0ZXA7XG5cdGNvbmZpZ3VyZT86IFNjYWZmb2xkU3RlcDtcblx0cmVuZGVyPzogU2NhZmZvbGRTdGVwO1xuXHRpbnRlZ3JhdGU/OiBTY2FmZm9sZFN0ZXA7XG5cdGZpbmFsaXplPzogU2NhZmZvbGRTdGVwO1xufVxuXG5leHBvcnQgdHlwZSBQaGFzZSA9IFwicmVzb2x2ZVwiIHwgXCJjb25maWd1cmVcIiB8IFwicmVuZGVyXCIgfCBcImludGVncmF0ZVwiIHwgXCJmaW5hbGl6ZVwiO1xuXG5leHBvcnQgY29uc3QgUEhBU0VTOiByZWFkb25seSBQaGFzZVtdID0gW1xuXHRcInJlc29sdmVcIixcblx0XCJjb25maWd1cmVcIixcblx0XCJyZW5kZXJcIixcblx0XCJpbnRlZ3JhdGVcIixcblx0XCJmaW5hbGl6ZVwiLFxuXTtcbiJdLCJuYW1lcyI6WyJQSEFTRVMiXSwibWFwcGluZ3MiOiJBQWdDQSxPQUFPLE1BQU1BLFNBQTJCO0lBQ3ZDO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7Q0FDQSxDQUFDIn0=
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Groups imports from the same package, rendering mixed value+type imports
3
+ * as `import { A, type B } from "pkg"` rather than two separate statements.
4
+ */ export class ImportMap {
5
+ _packages = new Map();
6
+ _entry(pkg) {
7
+ const existing = this._packages.get(pkg);
8
+ if (existing) return existing;
9
+ const e = {
10
+ named: new Set(),
11
+ types: new Set(),
12
+ sideEffect: false
13
+ };
14
+ this._packages.set(pkg, e);
15
+ return e;
16
+ }
17
+ /**
18
+ * Add named value imports.
19
+ * Called with no names, registers a side-effect `import "pkg"`.
20
+ */ add(pkg, ...names) {
21
+ const e = this._entry(pkg);
22
+ if (names.length === 0) e.sideEffect = true;
23
+ else for (const n of names)e.named.add(n);
24
+ return this;
25
+ }
26
+ /** Add type-only named imports. */ addType(pkg, ...names) {
27
+ const e = this._entry(pkg);
28
+ for (const n of names)e.types.add(n);
29
+ return this;
30
+ }
31
+ /**
32
+ * Render to an array of import statement strings (insertion order preserved).
33
+ *
34
+ * - All-type package → `import type { A, B } from "pkg";`
35
+ * - All-value package → `import { A, B } from "pkg";`
36
+ * - Mixed package → `import { A, type B } from "pkg";`
37
+ * - Side-effect only → `import "pkg";`
38
+ */ render() {
39
+ const lines = [];
40
+ for (const [pkg, e] of this._packages){
41
+ if (e.sideEffect) lines.push(`import "${pkg}";`);
42
+ const named = [
43
+ ...e.named
44
+ ].sort();
45
+ const types = [
46
+ ...e.types
47
+ ].sort();
48
+ if (named.length === 0 && types.length > 0) {
49
+ lines.push(`import type { ${types.join(", ")} } from "${pkg}";`);
50
+ } else if (named.length > 0 && types.length === 0) {
51
+ lines.push(`import { ${named.join(", ")} } from "${pkg}";`);
52
+ } else if (named.length > 0 && types.length > 0) {
53
+ const all = [
54
+ ...named,
55
+ ...types.map((t)=>`type ${t}`)
56
+ ].join(", ");
57
+ lines.push(`import { ${all} } from "${pkg}";`);
58
+ }
59
+ }
60
+ return lines;
61
+ }
62
+ }
63
+
64
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2NyZWF0ZS92MS9kb21haW4vaW1wb3J0LW1hcC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEdyb3VwcyBpbXBvcnRzIGZyb20gdGhlIHNhbWUgcGFja2FnZSwgcmVuZGVyaW5nIG1peGVkIHZhbHVlK3R5cGUgaW1wb3J0c1xuICogYXMgYGltcG9ydCB7IEEsIHR5cGUgQiB9IGZyb20gXCJwa2dcImAgcmF0aGVyIHRoYW4gdHdvIHNlcGFyYXRlIHN0YXRlbWVudHMuXG4gKi9cblxuaW50ZXJmYWNlIFBhY2thZ2VFbnRyeSB7XG5cdG5hbWVkOiBTZXQ8c3RyaW5nPjtcblx0dHlwZXM6IFNldDxzdHJpbmc+O1xuXHRzaWRlRWZmZWN0OiBib29sZWFuO1xufVxuXG5leHBvcnQgY2xhc3MgSW1wb3J0TWFwIHtcblx0cHJpdmF0ZSByZWFkb25seSBfcGFja2FnZXMgPSBuZXcgTWFwPHN0cmluZywgUGFja2FnZUVudHJ5PigpO1xuXG5cdHByaXZhdGUgX2VudHJ5KHBrZzogc3RyaW5nKTogUGFja2FnZUVudHJ5IHtcblx0XHRjb25zdCBleGlzdGluZyA9IHRoaXMuX3BhY2thZ2VzLmdldChwa2cpO1xuXHRcdGlmIChleGlzdGluZykgcmV0dXJuIGV4aXN0aW5nO1xuXHRcdGNvbnN0IGU6IFBhY2thZ2VFbnRyeSA9IHsgbmFtZWQ6IG5ldyBTZXQoKSwgdHlwZXM6IG5ldyBTZXQoKSwgc2lkZUVmZmVjdDogZmFsc2UgfTtcblx0XHR0aGlzLl9wYWNrYWdlcy5zZXQocGtnLCBlKTtcblx0XHRyZXR1cm4gZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGQgbmFtZWQgdmFsdWUgaW1wb3J0cy5cblx0ICogQ2FsbGVkIHdpdGggbm8gbmFtZXMsIHJlZ2lzdGVycyBhIHNpZGUtZWZmZWN0IGBpbXBvcnQgXCJwa2dcImAuXG5cdCAqL1xuXHRwdWJsaWMgYWRkKHBrZzogc3RyaW5nLCAuLi5uYW1lczogc3RyaW5nW10pOiB0aGlzIHtcblx0XHRjb25zdCBlID0gdGhpcy5fZW50cnkocGtnKTtcblx0XHRpZiAobmFtZXMubGVuZ3RoID09PSAwKSBlLnNpZGVFZmZlY3QgPSB0cnVlO1xuXHRcdGVsc2UgZm9yIChjb25zdCBuIG9mIG5hbWVzKSBlLm5hbWVkLmFkZChuKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxuXG5cdC8qKiBBZGQgdHlwZS1vbmx5IG5hbWVkIGltcG9ydHMuICovXG5cdHB1YmxpYyBhZGRUeXBlKHBrZzogc3RyaW5nLCAuLi5uYW1lczogc3RyaW5nW10pOiB0aGlzIHtcblx0XHRjb25zdCBlID0gdGhpcy5fZW50cnkocGtnKTtcblx0XHRmb3IgKGNvbnN0IG4gb2YgbmFtZXMpIGUudHlwZXMuYWRkKG4pO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlbmRlciB0byBhbiBhcnJheSBvZiBpbXBvcnQgc3RhdGVtZW50IHN0cmluZ3MgKGluc2VydGlvbiBvcmRlciBwcmVzZXJ2ZWQpLlxuXHQgKlxuXHQgKiAtIEFsbC10eXBlIHBhY2thZ2UgIOKGkiBgaW1wb3J0IHR5cGUgeyBBLCBCIH0gZnJvbSBcInBrZ1wiO2Bcblx0ICogLSBBbGwtdmFsdWUgcGFja2FnZSDihpIgYGltcG9ydCB7IEEsIEIgfSBmcm9tIFwicGtnXCI7YFxuXHQgKiAtIE1peGVkIHBhY2thZ2UgICAgIOKGkiBgaW1wb3J0IHsgQSwgdHlwZSBCIH0gZnJvbSBcInBrZ1wiO2Bcblx0ICogLSBTaWRlLWVmZmVjdCBvbmx5ICDihpIgYGltcG9ydCBcInBrZ1wiO2Bcblx0ICovXG5cdHB1YmxpYyByZW5kZXIoKTogc3RyaW5nW10ge1xuXHRcdGNvbnN0IGxpbmVzOiBzdHJpbmdbXSA9IFtdO1xuXHRcdGZvciAoY29uc3QgW3BrZywgZV0gb2YgdGhpcy5fcGFja2FnZXMpIHtcblx0XHRcdGlmIChlLnNpZGVFZmZlY3QpIGxpbmVzLnB1c2goYGltcG9ydCBcIiR7cGtnfVwiO2ApO1xuXG5cdFx0XHRjb25zdCBuYW1lZCA9IFsuLi5lLm5hbWVkXS5zb3J0KCk7XG5cdFx0XHRjb25zdCB0eXBlcyA9IFsuLi5lLnR5cGVzXS5zb3J0KCk7XG5cblx0XHRcdGlmIChuYW1lZC5sZW5ndGggPT09IDAgJiYgdHlwZXMubGVuZ3RoID4gMCkge1xuXHRcdFx0XHRsaW5lcy5wdXNoKGBpbXBvcnQgdHlwZSB7ICR7dHlwZXMuam9pbihcIiwgXCIpfSB9IGZyb20gXCIke3BrZ31cIjtgKTtcblx0XHRcdH0gZWxzZSBpZiAobmFtZWQubGVuZ3RoID4gMCAmJiB0eXBlcy5sZW5ndGggPT09IDApIHtcblx0XHRcdFx0bGluZXMucHVzaChgaW1wb3J0IHsgJHtuYW1lZC5qb2luKFwiLCBcIil9IH0gZnJvbSBcIiR7cGtnfVwiO2ApO1xuXHRcdFx0fSBlbHNlIGlmIChuYW1lZC5sZW5ndGggPiAwICYmIHR5cGVzLmxlbmd0aCA+IDApIHtcblx0XHRcdFx0Y29uc3QgYWxsID0gWy4uLm5hbWVkLCAuLi50eXBlcy5tYXAoKHQpID0+IGB0eXBlICR7dH1gKV0uam9pbihcIiwgXCIpO1xuXHRcdFx0XHRsaW5lcy5wdXNoKGBpbXBvcnQgeyAke2FsbH0gfSBmcm9tIFwiJHtwa2d9XCI7YCk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBsaW5lcztcblx0fVxufVxuIl0sIm5hbWVzIjpbIkltcG9ydE1hcCIsIl9wYWNrYWdlcyIsIk1hcCIsIl9lbnRyeSIsInBrZyIsImV4aXN0aW5nIiwiZ2V0IiwiZSIsIm5hbWVkIiwiU2V0IiwidHlwZXMiLCJzaWRlRWZmZWN0Iiwic2V0IiwiYWRkIiwibmFtZXMiLCJsZW5ndGgiLCJuIiwiYWRkVHlwZSIsInJlbmRlciIsImxpbmVzIiwicHVzaCIsInNvcnQiLCJqb2luIiwiYWxsIiwibWFwIiwidCJdLCJtYXBwaW5ncyI6IkFBQUE7OztDQUdDLEdBUUQsT0FBTyxNQUFNQTtJQUNLQyxZQUFZLElBQUlDLE1BQTRCO0lBRXJEQyxPQUFPQyxHQUFXLEVBQWdCO1FBQ3pDLE1BQU1DLFdBQVcsSUFBSSxDQUFDSixTQUFTLENBQUNLLEdBQUcsQ0FBQ0Y7UUFDcEMsSUFBSUMsVUFBVSxPQUFPQTtRQUNyQixNQUFNRSxJQUFrQjtZQUFFQyxPQUFPLElBQUlDO1lBQU9DLE9BQU8sSUFBSUQ7WUFBT0UsWUFBWTtRQUFNO1FBQ2hGLElBQUksQ0FBQ1YsU0FBUyxDQUFDVyxHQUFHLENBQUNSLEtBQUtHO1FBQ3hCLE9BQU9BO0lBQ1I7SUFFQTs7O0VBR0MsR0FDRCxBQUFPTSxJQUFJVCxHQUFXLEVBQUUsR0FBR1UsS0FBZSxFQUFRO1FBQ2pELE1BQU1QLElBQUksSUFBSSxDQUFDSixNQUFNLENBQUNDO1FBQ3RCLElBQUlVLE1BQU1DLE1BQU0sS0FBSyxHQUFHUixFQUFFSSxVQUFVLEdBQUc7YUFDbEMsS0FBSyxNQUFNSyxLQUFLRixNQUFPUCxFQUFFQyxLQUFLLENBQUNLLEdBQUcsQ0FBQ0c7UUFDeEMsT0FBTyxJQUFJO0lBQ1o7SUFFQSxpQ0FBaUMsR0FDakMsQUFBT0MsUUFBUWIsR0FBVyxFQUFFLEdBQUdVLEtBQWUsRUFBUTtRQUNyRCxNQUFNUCxJQUFJLElBQUksQ0FBQ0osTUFBTSxDQUFDQztRQUN0QixLQUFLLE1BQU1ZLEtBQUtGLE1BQU9QLEVBQUVHLEtBQUssQ0FBQ0csR0FBRyxDQUFDRztRQUNuQyxPQUFPLElBQUk7SUFDWjtJQUVBOzs7Ozs7O0VBT0MsR0FDRCxBQUFPRSxTQUFtQjtRQUN6QixNQUFNQyxRQUFrQixFQUFFO1FBQzFCLEtBQUssTUFBTSxDQUFDZixLQUFLRyxFQUFFLElBQUksSUFBSSxDQUFDTixTQUFTLENBQUU7WUFDdEMsSUFBSU0sRUFBRUksVUFBVSxFQUFFUSxNQUFNQyxJQUFJLENBQUMsQ0FBQyxRQUFRLEVBQUVoQixJQUFJLEVBQUUsQ0FBQztZQUUvQyxNQUFNSSxRQUFRO21CQUFJRCxFQUFFQyxLQUFLO2FBQUMsQ0FBQ2EsSUFBSTtZQUMvQixNQUFNWCxRQUFRO21CQUFJSCxFQUFFRyxLQUFLO2FBQUMsQ0FBQ1csSUFBSTtZQUUvQixJQUFJYixNQUFNTyxNQUFNLEtBQUssS0FBS0wsTUFBTUssTUFBTSxHQUFHLEdBQUc7Z0JBQzNDSSxNQUFNQyxJQUFJLENBQUMsQ0FBQyxjQUFjLEVBQUVWLE1BQU1ZLElBQUksQ0FBQyxNQUFNLFNBQVMsRUFBRWxCLElBQUksRUFBRSxDQUFDO1lBQ2hFLE9BQU8sSUFBSUksTUFBTU8sTUFBTSxHQUFHLEtBQUtMLE1BQU1LLE1BQU0sS0FBSyxHQUFHO2dCQUNsREksTUFBTUMsSUFBSSxDQUFDLENBQUMsU0FBUyxFQUFFWixNQUFNYyxJQUFJLENBQUMsTUFBTSxTQUFTLEVBQUVsQixJQUFJLEVBQUUsQ0FBQztZQUMzRCxPQUFPLElBQUlJLE1BQU1PLE1BQU0sR0FBRyxLQUFLTCxNQUFNSyxNQUFNLEdBQUcsR0FBRztnQkFDaEQsTUFBTVEsTUFBTTt1QkFBSWY7dUJBQVVFLE1BQU1jLEdBQUcsQ0FBQyxDQUFDQyxJQUFNLENBQUMsS0FBSyxFQUFFQSxHQUFHO2lCQUFFLENBQUNILElBQUksQ0FBQztnQkFDOURILE1BQU1DLElBQUksQ0FBQyxDQUFDLFNBQVMsRUFBRUcsSUFBSSxTQUFTLEVBQUVuQixJQUFJLEVBQUUsQ0FBQztZQUM5QztRQUNEO1FBQ0EsT0FBT2U7SUFDUjtBQUNEIn0=
@@ -0,0 +1,11 @@
1
+ export { ClassModel } from "./class-model.js";
2
+ export { COMPOSE_KEY, ComposeModel } from "./compose.model.js";
3
+ export { createContext, FeatureModelStore, modelKey } from "./context.js";
4
+ export { DEVCONTAINER_KEY, DevcontainerModel } from "./devcontainer.model.js";
5
+ export { DockerfileModel } from "./dockerfile.model.js";
6
+ export { PHASES } from "./feature.js";
7
+ export { ImportMap } from "./import-map.js";
8
+ export { ask, pick } from "./prompt.js";
9
+ export { defineWorkflow, runWorkflow } from "./workflow.js";
10
+
11
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2NyZWF0ZS92MS9kb21haW4vaW5kZXgudHMiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IHtcblx0dHlwZSBCb2R5Q2xhc3NEZWYsXG5cdHR5cGUgQm9keUNsYXNzRmllbGQsXG5cdENsYXNzTW9kZWwsXG5cdHR5cGUgQ29uc3RydWN0b3JQYXJhbSxcblx0dHlwZSBNZXRob2REZWYsXG5cdHR5cGUgTWV0aG9kUGFyYW0sXG59IGZyb20gXCIuL2NsYXNzLW1vZGVsLmpzXCI7XG5leHBvcnQgeyBDT01QT1NFX0tFWSwgQ29tcG9zZU1vZGVsLCB0eXBlIENvbXBvc2VTZXJ2aWNlIH0gZnJvbSBcIi4vY29tcG9zZS5tb2RlbC5qc1wiO1xuZXhwb3J0IHR5cGUge1xuXHRGZWF0dXJlTW9kZWxLZXksXG5cdFNjYWZmb2xkQ29udGV4dCxcblx0U2NhZmZvbGRPcHRpb25zLFxufSBmcm9tIFwiLi9jb250ZXh0LmpzXCI7XG5leHBvcnQgeyBjcmVhdGVDb250ZXh0LCBGZWF0dXJlTW9kZWxTdG9yZSwgbW9kZWxLZXkgfSBmcm9tIFwiLi9jb250ZXh0LmpzXCI7XG5leHBvcnQgeyBERVZDT05UQUlORVJfS0VZLCBEZXZjb250YWluZXJNb2RlbCB9IGZyb20gXCIuL2RldmNvbnRhaW5lci5tb2RlbC5qc1wiO1xuZXhwb3J0IHsgRG9ja2VyZmlsZU1vZGVsIH0gZnJvbSBcIi4vZG9ja2VyZmlsZS5tb2RlbC5qc1wiO1xuZXhwb3J0IHR5cGUgeyBGZWF0dXJlLCBQaGFzZSwgU2NhZmZvbGRTdGVwIH0gZnJvbSBcIi4vZmVhdHVyZS5qc1wiO1xuZXhwb3J0IHsgUEhBU0VTIH0gZnJvbSBcIi4vZmVhdHVyZS5qc1wiO1xuZXhwb3J0IHsgSW1wb3J0TWFwIH0gZnJvbSBcIi4vaW1wb3J0LW1hcC5qc1wiO1xuZXhwb3J0IHsgYXNrLCBwaWNrIH0gZnJvbSBcIi4vcHJvbXB0LmpzXCI7XG5leHBvcnQgdHlwZSB7IFdvcmtmbG93IH0gZnJvbSBcIi4vd29ya2Zsb3cuanNcIjtcbmV4cG9ydCB7IGRlZmluZVdvcmtmbG93LCBydW5Xb3JrZmxvdyB9IGZyb20gXCIuL3dvcmtmbG93LmpzXCI7XG4iXSwibmFtZXMiOlsiQ2xhc3NNb2RlbCIsIkNPTVBPU0VfS0VZIiwiQ29tcG9zZU1vZGVsIiwiY3JlYXRlQ29udGV4dCIsIkZlYXR1cmVNb2RlbFN0b3JlIiwibW9kZWxLZXkiLCJERVZDT05UQUlORVJfS0VZIiwiRGV2Y29udGFpbmVyTW9kZWwiLCJEb2NrZXJmaWxlTW9kZWwiLCJQSEFTRVMiLCJJbXBvcnRNYXAiLCJhc2siLCJwaWNrIiwiZGVmaW5lV29ya2Zsb3ciLCJydW5Xb3JrZmxvdyJdLCJtYXBwaW5ncyI6IkFBQUEsU0FHQ0EsVUFBVSxRQUlKLG1CQUFtQjtBQUMxQixTQUFTQyxXQUFXLEVBQUVDLFlBQVksUUFBNkIscUJBQXFCO0FBTXBGLFNBQVNDLGFBQWEsRUFBRUMsaUJBQWlCLEVBQUVDLFFBQVEsUUFBUSxlQUFlO0FBQzFFLFNBQVNDLGdCQUFnQixFQUFFQyxpQkFBaUIsUUFBUSwwQkFBMEI7QUFDOUUsU0FBU0MsZUFBZSxRQUFRLHdCQUF3QjtBQUV4RCxTQUFTQyxNQUFNLFFBQVEsZUFBZTtBQUN0QyxTQUFTQyxTQUFTLFFBQVEsa0JBQWtCO0FBQzVDLFNBQVNDLEdBQUcsRUFBRUMsSUFBSSxRQUFRLGNBQWM7QUFFeEMsU0FBU0MsY0FBYyxFQUFFQyxXQUFXLFFBQVEsZ0JBQWdCIn0=
@@ -0,0 +1,27 @@
1
+ import { createInterface } from "node:readline/promises";
2
+ export async function ask(question, fallback = "") {
3
+ const rl = createInterface({
4
+ input: process.stdin,
5
+ output: process.stdout
6
+ });
7
+ const answer = (await rl.question(question)).trim();
8
+ rl.close();
9
+ return answer || fallback;
10
+ }
11
+ export async function pick(label, items, display) {
12
+ console.log(label.trimEnd());
13
+ for (const [i, item] of items.entries()){
14
+ console.log(` ${i + 1}. ${display(item)}`);
15
+ }
16
+ const rl = createInterface({
17
+ input: process.stdin,
18
+ output: process.stdout
19
+ });
20
+ const answer = (await rl.question(" > ")).trim();
21
+ rl.close();
22
+ const idx = Number.parseInt(answer, 10);
23
+ if (Number.isNaN(idx) || idx < 1 || idx > items.length) return null;
24
+ return items[idx - 1];
25
+ }
26
+
27
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2NyZWF0ZS92MS9kb21haW4vcHJvbXB0LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGNyZWF0ZUludGVyZmFjZSB9IGZyb20gXCJub2RlOnJlYWRsaW5lL3Byb21pc2VzXCI7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhc2socXVlc3Rpb246IHN0cmluZywgZmFsbGJhY2sgPSBcIlwiKTogUHJvbWlzZTxzdHJpbmc+IHtcblx0Y29uc3QgcmwgPSBjcmVhdGVJbnRlcmZhY2UoeyBpbnB1dDogcHJvY2Vzcy5zdGRpbiwgb3V0cHV0OiBwcm9jZXNzLnN0ZG91dCB9KTtcblx0Y29uc3QgYW5zd2VyID0gKGF3YWl0IHJsLnF1ZXN0aW9uKHF1ZXN0aW9uKSkudHJpbSgpO1xuXHRybC5jbG9zZSgpO1xuXHRyZXR1cm4gYW5zd2VyIHx8IGZhbGxiYWNrO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcGljazxUPihcblx0bGFiZWw6IHN0cmluZyxcblx0aXRlbXM6IFRbXSxcblx0ZGlzcGxheTogKGl0ZW06IFQpID0+IHN0cmluZyxcbik6IFByb21pc2U8VCB8IG51bGw+IHtcblx0Y29uc29sZS5sb2cobGFiZWwudHJpbUVuZCgpKTtcblx0Zm9yIChjb25zdCBbaSwgaXRlbV0gb2YgaXRlbXMuZW50cmllcygpKSB7XG5cdFx0Y29uc29sZS5sb2coYCAgICAke2kgKyAxfS4gJHtkaXNwbGF5KGl0ZW0pfWApO1xuXHR9XG5cdGNvbnN0IHJsID0gY3JlYXRlSW50ZXJmYWNlKHsgaW5wdXQ6IHByb2Nlc3Muc3RkaW4sIG91dHB1dDogcHJvY2Vzcy5zdGRvdXQgfSk7XG5cdGNvbnN0IGFuc3dlciA9IChhd2FpdCBybC5xdWVzdGlvbihcIiAgPiBcIikpLnRyaW0oKTtcblx0cmwuY2xvc2UoKTtcblx0Y29uc3QgaWR4ID0gTnVtYmVyLnBhcnNlSW50KGFuc3dlciwgMTApO1xuXHRpZiAoTnVtYmVyLmlzTmFOKGlkeCkgfHwgaWR4IDwgMSB8fCBpZHggPiBpdGVtcy5sZW5ndGgpIHJldHVybiBudWxsO1xuXHRyZXR1cm4gaXRlbXNbaWR4IC0gMV07XG59XG4iXSwibmFtZXMiOlsiY3JlYXRlSW50ZXJmYWNlIiwiYXNrIiwicXVlc3Rpb24iLCJmYWxsYmFjayIsInJsIiwiaW5wdXQiLCJwcm9jZXNzIiwic3RkaW4iLCJvdXRwdXQiLCJzdGRvdXQiLCJhbnN3ZXIiLCJ0cmltIiwiY2xvc2UiLCJwaWNrIiwibGFiZWwiLCJpdGVtcyIsImRpc3BsYXkiLCJjb25zb2xlIiwibG9nIiwidHJpbUVuZCIsImkiLCJpdGVtIiwiZW50cmllcyIsImlkeCIsIk51bWJlciIsInBhcnNlSW50IiwiaXNOYU4iLCJsZW5ndGgiXSwibWFwcGluZ3MiOiJBQUFBLFNBQVNBLGVBQWUsUUFBUSx5QkFBeUI7QUFFekQsT0FBTyxlQUFlQyxJQUFJQyxRQUFnQixFQUFFQyxXQUFXLEVBQUU7SUFDeEQsTUFBTUMsS0FBS0osZ0JBQWdCO1FBQUVLLE9BQU9DLFFBQVFDLEtBQUs7UUFBRUMsUUFBUUYsUUFBUUcsTUFBTTtJQUFDO0lBQzFFLE1BQU1DLFNBQVMsQUFBQyxDQUFBLE1BQU1OLEdBQUdGLFFBQVEsQ0FBQ0EsU0FBUSxFQUFHUyxJQUFJO0lBQ2pEUCxHQUFHUSxLQUFLO0lBQ1IsT0FBT0YsVUFBVVA7QUFDbEI7QUFFQSxPQUFPLGVBQWVVLEtBQ3JCQyxLQUFhLEVBQ2JDLEtBQVUsRUFDVkMsT0FBNEI7SUFFNUJDLFFBQVFDLEdBQUcsQ0FBQ0osTUFBTUssT0FBTztJQUN6QixLQUFLLE1BQU0sQ0FBQ0MsR0FBR0MsS0FBSyxJQUFJTixNQUFNTyxPQUFPLEdBQUk7UUFDeENMLFFBQVFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRUUsSUFBSSxFQUFFLEVBQUUsRUFBRUosUUFBUUssT0FBTztJQUM3QztJQUNBLE1BQU1qQixLQUFLSixnQkFBZ0I7UUFBRUssT0FBT0MsUUFBUUMsS0FBSztRQUFFQyxRQUFRRixRQUFRRyxNQUFNO0lBQUM7SUFDMUUsTUFBTUMsU0FBUyxBQUFDLENBQUEsTUFBTU4sR0FBR0YsUUFBUSxDQUFDLE9BQU0sRUFBR1MsSUFBSTtJQUMvQ1AsR0FBR1EsS0FBSztJQUNSLE1BQU1XLE1BQU1DLE9BQU9DLFFBQVEsQ0FBQ2YsUUFBUTtJQUNwQyxJQUFJYyxPQUFPRSxLQUFLLENBQUNILFFBQVFBLE1BQU0sS0FBS0EsTUFBTVIsTUFBTVksTUFBTSxFQUFFLE9BQU87SUFDL0QsT0FBT1osS0FBSyxDQUFDUSxNQUFNLEVBQUU7QUFDdEIifQ==
@@ -0,0 +1,24 @@
1
+ import { PHASES } from "./feature.js";
2
+ export function defineWorkflow(name, features) {
3
+ return {
4
+ name,
5
+ features
6
+ };
7
+ }
8
+ /**
9
+ * Runs a workflow by iterating phases × features. Within each phase, every
10
+ * enabled feature's step for that phase is executed in feature order. The
11
+ * `enabled` predicate is re-evaluated before each phase so a feature can
12
+ * become active based on options set by earlier `resolve` phases.
13
+ */ export async function runWorkflow(workflow, ctx) {
14
+ for (const phase of PHASES){
15
+ for (const feature of workflow.features){
16
+ const step = feature[phase];
17
+ if (step == null) continue;
18
+ if (feature.enabled != null && !feature.enabled(ctx)) continue;
19
+ ctx = await step(ctx);
20
+ }
21
+ }
22
+ }
23
+
24
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2NyZWF0ZS92MS9kb21haW4vd29ya2Zsb3cudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBTY2FmZm9sZENvbnRleHQgfSBmcm9tIFwiLi9jb250ZXh0LmpzXCI7XG5pbXBvcnQgeyB0eXBlIEZlYXR1cmUsIFBIQVNFUyB9IGZyb20gXCIuL2ZlYXR1cmUuanNcIjtcblxuZXhwb3J0IGludGVyZmFjZSBXb3JrZmxvdyB7XG5cdHJlYWRvbmx5IG5hbWU6IHN0cmluZztcblx0cmVhZG9ubHkgZmVhdHVyZXM6IHJlYWRvbmx5IEZlYXR1cmVbXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRlZmluZVdvcmtmbG93KG5hbWU6IHN0cmluZywgZmVhdHVyZXM6IEZlYXR1cmVbXSk6IFdvcmtmbG93IHtcblx0cmV0dXJuIHsgbmFtZSwgZmVhdHVyZXMgfTtcbn1cblxuLyoqXG4gKiBSdW5zIGEgd29ya2Zsb3cgYnkgaXRlcmF0aW5nIHBoYXNlcyDDlyBmZWF0dXJlcy4gV2l0aGluIGVhY2ggcGhhc2UsIGV2ZXJ5XG4gKiBlbmFibGVkIGZlYXR1cmUncyBzdGVwIGZvciB0aGF0IHBoYXNlIGlzIGV4ZWN1dGVkIGluIGZlYXR1cmUgb3JkZXIuIFRoZVxuICogYGVuYWJsZWRgIHByZWRpY2F0ZSBpcyByZS1ldmFsdWF0ZWQgYmVmb3JlIGVhY2ggcGhhc2Ugc28gYSBmZWF0dXJlIGNhblxuICogYmVjb21lIGFjdGl2ZSBiYXNlZCBvbiBvcHRpb25zIHNldCBieSBlYXJsaWVyIGByZXNvbHZlYCBwaGFzZXMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBydW5Xb3JrZmxvdyh3b3JrZmxvdzogV29ya2Zsb3csIGN0eDogU2NhZmZvbGRDb250ZXh0KTogUHJvbWlzZTx2b2lkPiB7XG5cdGZvciAoY29uc3QgcGhhc2Ugb2YgUEhBU0VTKSB7XG5cdFx0Zm9yIChjb25zdCBmZWF0dXJlIG9mIHdvcmtmbG93LmZlYXR1cmVzKSB7XG5cdFx0XHRjb25zdCBzdGVwID0gZmVhdHVyZVtwaGFzZV07XG5cdFx0XHRpZiAoc3RlcCA9PSBudWxsKSBjb250aW51ZTtcblx0XHRcdGlmIChmZWF0dXJlLmVuYWJsZWQgIT0gbnVsbCAmJiAhZmVhdHVyZS5lbmFibGVkKGN0eCkpIGNvbnRpbnVlO1xuXHRcdFx0Y3R4ID0gYXdhaXQgc3RlcChjdHgpO1xuXHRcdH1cblx0fVxufVxuIl0sIm5hbWVzIjpbIlBIQVNFUyIsImRlZmluZVdvcmtmbG93IiwibmFtZSIsImZlYXR1cmVzIiwicnVuV29ya2Zsb3ciLCJ3b3JrZmxvdyIsImN0eCIsInBoYXNlIiwiZmVhdHVyZSIsInN0ZXAiLCJlbmFibGVkIl0sIm1hcHBpbmdzIjoiQUFDQSxTQUF1QkEsTUFBTSxRQUFRLGVBQWU7QUFPcEQsT0FBTyxTQUFTQyxlQUFlQyxJQUFZLEVBQUVDLFFBQW1CO0lBQy9ELE9BQU87UUFBRUQ7UUFBTUM7SUFBUztBQUN6QjtBQUVBOzs7OztDQUtDLEdBQ0QsT0FBTyxlQUFlQyxZQUFZQyxRQUFrQixFQUFFQyxHQUFvQjtJQUN6RSxLQUFLLE1BQU1DLFNBQVNQLE9BQVE7UUFDM0IsS0FBSyxNQUFNUSxXQUFXSCxTQUFTRixRQUFRLENBQUU7WUFDeEMsTUFBTU0sT0FBT0QsT0FBTyxDQUFDRCxNQUFNO1lBQzNCLElBQUlFLFFBQVEsTUFBTTtZQUNsQixJQUFJRCxRQUFRRSxPQUFPLElBQUksUUFBUSxDQUFDRixRQUFRRSxPQUFPLENBQUNKLE1BQU07WUFDdERBLE1BQU0sTUFBTUcsS0FBS0g7UUFDbEI7SUFDRDtBQUNEIn0=
@@ -0,0 +1,93 @@
1
+ import { mkdir, writeFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { DEVCONTAINER_KEY, DevcontainerModel } from "../../domain/devcontainer.model.js";
4
+ import { ask, pick } from "../../domain/index.js";
5
+ import { createHelloController } from "./hello-controller.model.js";
6
+ import { MAIN_TS_KEY, MainTsModel } from "./main-ts.model.js";
7
+ import { apiPackageJson, CONFIG_DEV_YAML, configYaml, GITIGNORE, rootPackageJson, SAMPLE_CONFIG_TS, SAMPLE_SERVICE_TS, TSCONFIG, VSCODE_LAUNCH_JSON, vscodeSettingsJson } from "./scaffold-files.template.js";
8
+ async function resolve(ctx) {
9
+ if (ctx.opts.yes) return ctx;
10
+ let { database, idp, postman } = ctx.opts;
11
+ if (database == null) {
12
+ console.log("\n Select database:");
13
+ const db = await pick(" Choice (enter for none): ", [
14
+ "postgresql/typeorm"
15
+ ], (id)=>id);
16
+ database = db === "postgresql/typeorm" ? "typeorm" : undefined;
17
+ }
18
+ if (idp == null) {
19
+ console.log("\n Select identity provider:");
20
+ const provider = await pick(" Choice (enter for none): ", [
21
+ "Auth0"
22
+ ], (id)=>id);
23
+ idp = provider === "Auth0" ? "auth0" : undefined;
24
+ }
25
+ if (!postman) {
26
+ const answer = await ask("\n Configure Postman workspace? [yes/no] (no): ");
27
+ postman = answer === "yes" || undefined;
28
+ }
29
+ return {
30
+ ...ctx,
31
+ opts: {
32
+ ...ctx.opts,
33
+ database,
34
+ idp,
35
+ postman
36
+ }
37
+ };
38
+ }
39
+ async function configure(ctx) {
40
+ const helloController = createHelloController();
41
+ const devcontainer = new DevcontainerModel(`${ctx.projectName}.api`).addExtension("biomejs.biome", "vitest.explorer").forwardPort(3000).addPostStartCommand("npm whoami 2>/dev/null || npm login");
42
+ return {
43
+ ...ctx,
44
+ models: ctx.models.set(MAIN_TS_KEY, new MainTsModel(`${ctx.projectName}.api`)).set(DEVCONTAINER_KEY, devcontainer),
45
+ controllers: [
46
+ ...ctx.controllers,
47
+ helloController
48
+ ]
49
+ };
50
+ }
51
+ async function render(ctx) {
52
+ const { targetDir, projectName } = ctx;
53
+ await Promise.all([
54
+ mkdir(join(targetDir, ".vscode"), {
55
+ recursive: true
56
+ }),
57
+ mkdir(join(targetDir, "projects", "api", "src", "controllers"), {
58
+ recursive: true
59
+ }),
60
+ mkdir(join(targetDir, "config"), {
61
+ recursive: true
62
+ })
63
+ ]);
64
+ const { controllers } = ctx;
65
+ const mainTsModel = ctx.models.get(MAIN_TS_KEY);
66
+ const writes = [
67
+ writeFile(join(targetDir, "package.json"), rootPackageJson(projectName)),
68
+ writeFile(join(targetDir, "tsconfig.json"), TSCONFIG),
69
+ writeFile(join(targetDir, "projects", "api", "package.json"), apiPackageJson(projectName)),
70
+ writeFile(join(targetDir, "projects", "api", "src", "sample.config.ts"), SAMPLE_CONFIG_TS),
71
+ writeFile(join(targetDir, "projects", "api", "src", "sample.service.ts"), SAMPLE_SERVICE_TS),
72
+ writeFile(join(targetDir, "config", "config.yaml"), configYaml()),
73
+ writeFile(join(targetDir, "config", "config.dev.yaml"), CONFIG_DEV_YAML),
74
+ writeFile(join(targetDir, ".vscode", "launch.json"), VSCODE_LAUNCH_JSON),
75
+ writeFile(join(targetDir, ".vscode", "settings.json"), vscodeSettingsJson(projectName)),
76
+ writeFile(join(targetDir, ".gitignore"), GITIGNORE),
77
+ ...controllers.map((c)=>writeFile(join(targetDir, "projects", "api", "src", "controllers", c.fileName), c.render()))
78
+ ];
79
+ if (mainTsModel) {
80
+ for (const c of controllers)mainTsModel.addController(c);
81
+ writes.push(writeFile(join(targetDir, "projects", "api", "src", "main.ts"), mainTsModel.render()));
82
+ }
83
+ await Promise.all(writes);
84
+ return ctx;
85
+ }
86
+ export const apiCoreFeature = {
87
+ name: "api-core",
88
+ resolve,
89
+ configure,
90
+ render
91
+ };
92
+
93
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2NyZWF0ZS92MS9mZWF0dXJlcy9hcGktY29yZS9mZWF0dXJlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IG1rZGlyLCB3cml0ZUZpbGUgfSBmcm9tIFwibm9kZTpmcy9wcm9taXNlc1wiO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7IERFVkNPTlRBSU5FUl9LRVksIERldmNvbnRhaW5lck1vZGVsIH0gZnJvbSBcIi4uLy4uL2RvbWFpbi9kZXZjb250YWluZXIubW9kZWwuanNcIjtcbmltcG9ydCB7IGFzaywgdHlwZSBGZWF0dXJlLCBwaWNrLCB0eXBlIFNjYWZmb2xkQ29udGV4dCB9IGZyb20gXCIuLi8uLi9kb21haW4vaW5kZXguanNcIjtcbmltcG9ydCB7IGNyZWF0ZUhlbGxvQ29udHJvbGxlciB9IGZyb20gXCIuL2hlbGxvLWNvbnRyb2xsZXIubW9kZWwuanNcIjtcbmltcG9ydCB7IE1BSU5fVFNfS0VZLCBNYWluVHNNb2RlbCB9IGZyb20gXCIuL21haW4tdHMubW9kZWwuanNcIjtcbmltcG9ydCB7XG5cdGFwaVBhY2thZ2VKc29uLFxuXHRDT05GSUdfREVWX1lBTUwsXG5cdGNvbmZpZ1lhbWwsXG5cdEdJVElHTk9SRSxcblx0cm9vdFBhY2thZ2VKc29uLFxuXHRTQU1QTEVfQ09ORklHX1RTLFxuXHRTQU1QTEVfU0VSVklDRV9UUyxcblx0VFNDT05GSUcsXG5cdFZTQ09ERV9MQVVOQ0hfSlNPTixcblx0dnNjb2RlU2V0dGluZ3NKc29uLFxufSBmcm9tIFwiLi9zY2FmZm9sZC1maWxlcy50ZW1wbGF0ZS5qc1wiO1xuXG5hc3luYyBmdW5jdGlvbiByZXNvbHZlKGN0eDogU2NhZmZvbGRDb250ZXh0KTogUHJvbWlzZTxTY2FmZm9sZENvbnRleHQ+IHtcblx0aWYgKGN0eC5vcHRzLnllcykgcmV0dXJuIGN0eDtcblxuXHRsZXQgeyBkYXRhYmFzZSwgaWRwLCBwb3N0bWFuIH0gPSBjdHgub3B0cztcblxuXHRpZiAoZGF0YWJhc2UgPT0gbnVsbCkge1xuXHRcdGNvbnNvbGUubG9nKFwiXFxuICBTZWxlY3QgZGF0YWJhc2U6XCIpO1xuXHRcdGNvbnN0IGRiID0gYXdhaXQgcGljayhcIiAgQ2hvaWNlIChlbnRlciBmb3Igbm9uZSk6IFwiLCBbXCJwb3N0Z3Jlc3FsL3R5cGVvcm1cIl0sIChpZCkgPT4gaWQpO1xuXHRcdGRhdGFiYXNlID0gZGIgPT09IFwicG9zdGdyZXNxbC90eXBlb3JtXCIgPyBcInR5cGVvcm1cIiA6IHVuZGVmaW5lZDtcblx0fVxuXG5cdGlmIChpZHAgPT0gbnVsbCkge1xuXHRcdGNvbnNvbGUubG9nKFwiXFxuICBTZWxlY3QgaWRlbnRpdHkgcHJvdmlkZXI6XCIpO1xuXHRcdGNvbnN0IHByb3ZpZGVyID0gYXdhaXQgcGljayhcIiAgQ2hvaWNlIChlbnRlciBmb3Igbm9uZSk6IFwiLCBbXCJBdXRoMFwiXSwgKGlkKSA9PiBpZCk7XG5cdFx0aWRwID0gcHJvdmlkZXIgPT09IFwiQXV0aDBcIiA/IFwiYXV0aDBcIiA6IHVuZGVmaW5lZDtcblx0fVxuXG5cdGlmICghcG9zdG1hbikge1xuXHRcdGNvbnN0IGFuc3dlciA9IGF3YWl0IGFzayhcIlxcbiAgQ29uZmlndXJlIFBvc3RtYW4gd29ya3NwYWNlPyBbeWVzL25vXSAobm8pOiBcIik7XG5cdFx0cG9zdG1hbiA9IGFuc3dlciA9PT0gXCJ5ZXNcIiB8fCB1bmRlZmluZWQ7XG5cdH1cblxuXHRyZXR1cm4geyAuLi5jdHgsIG9wdHM6IHsgLi4uY3R4Lm9wdHMsIGRhdGFiYXNlLCBpZHAsIHBvc3RtYW4gfSB9O1xufVxuXG5hc3luYyBmdW5jdGlvbiBjb25maWd1cmUoY3R4OiBTY2FmZm9sZENvbnRleHQpOiBQcm9taXNlPFNjYWZmb2xkQ29udGV4dD4ge1xuXHRjb25zdCBoZWxsb0NvbnRyb2xsZXIgPSBjcmVhdGVIZWxsb0NvbnRyb2xsZXIoKTtcblx0Y29uc3QgZGV2Y29udGFpbmVyID0gbmV3IERldmNvbnRhaW5lck1vZGVsKGAke2N0eC5wcm9qZWN0TmFtZX0uYXBpYClcblx0XHQuYWRkRXh0ZW5zaW9uKFwiYmlvbWVqcy5iaW9tZVwiLCBcInZpdGVzdC5leHBsb3JlclwiKVxuXHRcdC5mb3J3YXJkUG9ydCgzMDAwKVxuXHRcdC5hZGRQb3N0U3RhcnRDb21tYW5kKFwibnBtIHdob2FtaSAyPi9kZXYvbnVsbCB8fCBucG0gbG9naW5cIik7XG5cdHJldHVybiB7XG5cdFx0Li4uY3R4LFxuXHRcdG1vZGVsczogY3R4Lm1vZGVsc1xuXHRcdFx0LnNldChNQUlOX1RTX0tFWSwgbmV3IE1haW5Uc01vZGVsKGAke2N0eC5wcm9qZWN0TmFtZX0uYXBpYCkpXG5cdFx0XHQuc2V0KERFVkNPTlRBSU5FUl9LRVksIGRldmNvbnRhaW5lciksXG5cdFx0Y29udHJvbGxlcnM6IFsuLi5jdHguY29udHJvbGxlcnMsIGhlbGxvQ29udHJvbGxlcl0sXG5cdH07XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJlbmRlcihjdHg6IFNjYWZmb2xkQ29udGV4dCk6IFByb21pc2U8U2NhZmZvbGRDb250ZXh0PiB7XG5cdGNvbnN0IHsgdGFyZ2V0RGlyLCBwcm9qZWN0TmFtZSB9ID0gY3R4O1xuXG5cdGF3YWl0IFByb21pc2UuYWxsKFtcblx0XHRta2Rpcihqb2luKHRhcmdldERpciwgXCIudnNjb2RlXCIpLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KSxcblx0XHRta2Rpcihqb2luKHRhcmdldERpciwgXCJwcm9qZWN0c1wiLCBcImFwaVwiLCBcInNyY1wiLCBcImNvbnRyb2xsZXJzXCIpLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KSxcblx0XHRta2Rpcihqb2luKHRhcmdldERpciwgXCJjb25maWdcIiksIHsgcmVjdXJzaXZlOiB0cnVlIH0pLFxuXHRdKTtcblxuXHRjb25zdCB7IGNvbnRyb2xsZXJzIH0gPSBjdHg7XG5cdGNvbnN0IG1haW5Uc01vZGVsID0gY3R4Lm1vZGVscy5nZXQoTUFJTl9UU19LRVkpO1xuXG5cdGNvbnN0IHdyaXRlczogQXJyYXk8UHJvbWlzZTx1bmtub3duPj4gPSBbXG5cdFx0d3JpdGVGaWxlKGpvaW4odGFyZ2V0RGlyLCBcInBhY2thZ2UuanNvblwiKSwgcm9vdFBhY2thZ2VKc29uKHByb2plY3ROYW1lKSksXG5cdFx0d3JpdGVGaWxlKGpvaW4odGFyZ2V0RGlyLCBcInRzY29uZmlnLmpzb25cIiksIFRTQ09ORklHKSxcblx0XHR3cml0ZUZpbGUoam9pbih0YXJnZXREaXIsIFwicHJvamVjdHNcIiwgXCJhcGlcIiwgXCJwYWNrYWdlLmpzb25cIiksIGFwaVBhY2thZ2VKc29uKHByb2plY3ROYW1lKSksXG5cdFx0d3JpdGVGaWxlKGpvaW4odGFyZ2V0RGlyLCBcInByb2plY3RzXCIsIFwiYXBpXCIsIFwic3JjXCIsIFwic2FtcGxlLmNvbmZpZy50c1wiKSwgU0FNUExFX0NPTkZJR19UUyksXG5cdFx0d3JpdGVGaWxlKFxuXHRcdFx0am9pbih0YXJnZXREaXIsIFwicHJvamVjdHNcIiwgXCJhcGlcIiwgXCJzcmNcIiwgXCJzYW1wbGUuc2VydmljZS50c1wiKSxcblx0XHRcdFNBTVBMRV9TRVJWSUNFX1RTLFxuXHRcdCksXG5cdFx0d3JpdGVGaWxlKGpvaW4odGFyZ2V0RGlyLCBcImNvbmZpZ1wiLCBcImNvbmZpZy55YW1sXCIpLCBjb25maWdZYW1sKCkpLFxuXHRcdHdyaXRlRmlsZShqb2luKHRhcmdldERpciwgXCJjb25maWdcIiwgXCJjb25maWcuZGV2LnlhbWxcIiksIENPTkZJR19ERVZfWUFNTCksXG5cdFx0d3JpdGVGaWxlKGpvaW4odGFyZ2V0RGlyLCBcIi52c2NvZGVcIiwgXCJsYXVuY2guanNvblwiKSwgVlNDT0RFX0xBVU5DSF9KU09OKSxcblx0XHR3cml0ZUZpbGUoam9pbih0YXJnZXREaXIsIFwiLnZzY29kZVwiLCBcInNldHRpbmdzLmpzb25cIiksIHZzY29kZVNldHRpbmdzSnNvbihwcm9qZWN0TmFtZSkpLFxuXHRcdHdyaXRlRmlsZShqb2luKHRhcmdldERpciwgXCIuZ2l0aWdub3JlXCIpLCBHSVRJR05PUkUpLFxuXHRcdC4uLmNvbnRyb2xsZXJzLm1hcCgoYykgPT5cblx0XHRcdHdyaXRlRmlsZShcblx0XHRcdFx0am9pbih0YXJnZXREaXIsIFwicHJvamVjdHNcIiwgXCJhcGlcIiwgXCJzcmNcIiwgXCJjb250cm9sbGVyc1wiLCBjLmZpbGVOYW1lKSxcblx0XHRcdFx0Yy5yZW5kZXIoKSxcblx0XHRcdCksXG5cdFx0KSxcblx0XTtcblxuXHRpZiAobWFpblRzTW9kZWwpIHtcblx0XHRmb3IgKGNvbnN0IGMgb2YgY29udHJvbGxlcnMpIG1haW5Uc01vZGVsLmFkZENvbnRyb2xsZXIoYyk7XG5cdFx0d3JpdGVzLnB1c2goXG5cdFx0XHR3cml0ZUZpbGUoam9pbih0YXJnZXREaXIsIFwicHJvamVjdHNcIiwgXCJhcGlcIiwgXCJzcmNcIiwgXCJtYWluLnRzXCIpLCBtYWluVHNNb2RlbC5yZW5kZXIoKSksXG5cdFx0KTtcblx0fVxuXG5cdGF3YWl0IFByb21pc2UuYWxsKHdyaXRlcyk7XG5cdHJldHVybiBjdHg7XG59XG5cbmV4cG9ydCBjb25zdCBhcGlDb3JlRmVhdHVyZTogRmVhdHVyZSA9IHtcblx0bmFtZTogXCJhcGktY29yZVwiLFxuXHRyZXNvbHZlLFxuXHRjb25maWd1cmUsXG5cdHJlbmRlcixcbn07XG4iXSwibmFtZXMiOlsibWtkaXIiLCJ3cml0ZUZpbGUiLCJqb2luIiwiREVWQ09OVEFJTkVSX0tFWSIsIkRldmNvbnRhaW5lck1vZGVsIiwiYXNrIiwicGljayIsImNyZWF0ZUhlbGxvQ29udHJvbGxlciIsIk1BSU5fVFNfS0VZIiwiTWFpblRzTW9kZWwiLCJhcGlQYWNrYWdlSnNvbiIsIkNPTkZJR19ERVZfWUFNTCIsImNvbmZpZ1lhbWwiLCJHSVRJR05PUkUiLCJyb290UGFja2FnZUpzb24iLCJTQU1QTEVfQ09ORklHX1RTIiwiU0FNUExFX1NFUlZJQ0VfVFMiLCJUU0NPTkZJRyIsIlZTQ09ERV9MQVVOQ0hfSlNPTiIsInZzY29kZVNldHRpbmdzSnNvbiIsInJlc29sdmUiLCJjdHgiLCJvcHRzIiwieWVzIiwiZGF0YWJhc2UiLCJpZHAiLCJwb3N0bWFuIiwiY29uc29sZSIsImxvZyIsImRiIiwiaWQiLCJ1bmRlZmluZWQiLCJwcm92aWRlciIsImFuc3dlciIsImNvbmZpZ3VyZSIsImhlbGxvQ29udHJvbGxlciIsImRldmNvbnRhaW5lciIsInByb2plY3ROYW1lIiwiYWRkRXh0ZW5zaW9uIiwiZm9yd2FyZFBvcnQiLCJhZGRQb3N0U3RhcnRDb21tYW5kIiwibW9kZWxzIiwic2V0IiwiY29udHJvbGxlcnMiLCJyZW5kZXIiLCJ0YXJnZXREaXIiLCJQcm9taXNlIiwiYWxsIiwicmVjdXJzaXZlIiwibWFpblRzTW9kZWwiLCJnZXQiLCJ3cml0ZXMiLCJtYXAiLCJjIiwiZmlsZU5hbWUiLCJhZGRDb250cm9sbGVyIiwicHVzaCIsImFwaUNvcmVGZWF0dXJlIiwibmFtZSJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsS0FBSyxFQUFFQyxTQUFTLFFBQVEsbUJBQW1CO0FBQ3BELFNBQVNDLElBQUksUUFBUSxZQUFZO0FBQ2pDLFNBQVNDLGdCQUFnQixFQUFFQyxpQkFBaUIsUUFBUSxxQ0FBcUM7QUFDekYsU0FBU0MsR0FBRyxFQUFnQkMsSUFBSSxRQUE4Qix3QkFBd0I7QUFDdEYsU0FBU0MscUJBQXFCLFFBQVEsOEJBQThCO0FBQ3BFLFNBQVNDLFdBQVcsRUFBRUMsV0FBVyxRQUFRLHFCQUFxQjtBQUM5RCxTQUNDQyxjQUFjLEVBQ2RDLGVBQWUsRUFDZkMsVUFBVSxFQUNWQyxTQUFTLEVBQ1RDLGVBQWUsRUFDZkMsZ0JBQWdCLEVBQ2hCQyxpQkFBaUIsRUFDakJDLFFBQVEsRUFDUkMsa0JBQWtCLEVBQ2xCQyxrQkFBa0IsUUFDWiwrQkFBK0I7QUFFdEMsZUFBZUMsUUFBUUMsR0FBb0I7SUFDMUMsSUFBSUEsSUFBSUMsSUFBSSxDQUFDQyxHQUFHLEVBQUUsT0FBT0Y7SUFFekIsSUFBSSxFQUFFRyxRQUFRLEVBQUVDLEdBQUcsRUFBRUMsT0FBTyxFQUFFLEdBQUdMLElBQUlDLElBQUk7SUFFekMsSUFBSUUsWUFBWSxNQUFNO1FBQ3JCRyxRQUFRQyxHQUFHLENBQUM7UUFDWixNQUFNQyxLQUFLLE1BQU12QixLQUFLLCtCQUErQjtZQUFDO1NBQXFCLEVBQUUsQ0FBQ3dCLEtBQU9BO1FBQ3JGTixXQUFXSyxPQUFPLHVCQUF1QixZQUFZRTtJQUN0RDtJQUVBLElBQUlOLE9BQU8sTUFBTTtRQUNoQkUsUUFBUUMsR0FBRyxDQUFDO1FBQ1osTUFBTUksV0FBVyxNQUFNMUIsS0FBSywrQkFBK0I7WUFBQztTQUFRLEVBQUUsQ0FBQ3dCLEtBQU9BO1FBQzlFTCxNQUFNTyxhQUFhLFVBQVUsVUFBVUQ7SUFDeEM7SUFFQSxJQUFJLENBQUNMLFNBQVM7UUFDYixNQUFNTyxTQUFTLE1BQU01QixJQUFJO1FBQ3pCcUIsVUFBVU8sV0FBVyxTQUFTRjtJQUMvQjtJQUVBLE9BQU87UUFBRSxHQUFHVixHQUFHO1FBQUVDLE1BQU07WUFBRSxHQUFHRCxJQUFJQyxJQUFJO1lBQUVFO1lBQVVDO1lBQUtDO1FBQVE7SUFBRTtBQUNoRTtBQUVBLGVBQWVRLFVBQVViLEdBQW9CO0lBQzVDLE1BQU1jLGtCQUFrQjVCO0lBQ3hCLE1BQU02QixlQUFlLElBQUloQyxrQkFBa0IsR0FBR2lCLElBQUlnQixXQUFXLENBQUMsSUFBSSxDQUFDLEVBQ2pFQyxZQUFZLENBQUMsaUJBQWlCLG1CQUM5QkMsV0FBVyxDQUFDLE1BQ1pDLG1CQUFtQixDQUFDO0lBQ3RCLE9BQU87UUFDTixHQUFHbkIsR0FBRztRQUNOb0IsUUFBUXBCLElBQUlvQixNQUFNLENBQ2hCQyxHQUFHLENBQUNsQyxhQUFhLElBQUlDLFlBQVksR0FBR1ksSUFBSWdCLFdBQVcsQ0FBQyxJQUFJLENBQUMsR0FDekRLLEdBQUcsQ0FBQ3ZDLGtCQUFrQmlDO1FBQ3hCTyxhQUFhO2VBQUl0QixJQUFJc0IsV0FBVztZQUFFUjtTQUFnQjtJQUNuRDtBQUNEO0FBRUEsZUFBZVMsT0FBT3ZCLEdBQW9CO0lBQ3pDLE1BQU0sRUFBRXdCLFNBQVMsRUFBRVIsV0FBVyxFQUFFLEdBQUdoQjtJQUVuQyxNQUFNeUIsUUFBUUMsR0FBRyxDQUFDO1FBQ2pCL0MsTUFBTUUsS0FBSzJDLFdBQVcsWUFBWTtZQUFFRyxXQUFXO1FBQUs7UUFDcERoRCxNQUFNRSxLQUFLMkMsV0FBVyxZQUFZLE9BQU8sT0FBTyxnQkFBZ0I7WUFBRUcsV0FBVztRQUFLO1FBQ2xGaEQsTUFBTUUsS0FBSzJDLFdBQVcsV0FBVztZQUFFRyxXQUFXO1FBQUs7S0FDbkQ7SUFFRCxNQUFNLEVBQUVMLFdBQVcsRUFBRSxHQUFHdEI7SUFDeEIsTUFBTTRCLGNBQWM1QixJQUFJb0IsTUFBTSxDQUFDUyxHQUFHLENBQUMxQztJQUVuQyxNQUFNMkMsU0FBa0M7UUFDdkNsRCxVQUFVQyxLQUFLMkMsV0FBVyxpQkFBaUIvQixnQkFBZ0J1QjtRQUMzRHBDLFVBQVVDLEtBQUsyQyxXQUFXLGtCQUFrQjVCO1FBQzVDaEIsVUFBVUMsS0FBSzJDLFdBQVcsWUFBWSxPQUFPLGlCQUFpQm5DLGVBQWUyQjtRQUM3RXBDLFVBQVVDLEtBQUsyQyxXQUFXLFlBQVksT0FBTyxPQUFPLHFCQUFxQjlCO1FBQ3pFZCxVQUNDQyxLQUFLMkMsV0FBVyxZQUFZLE9BQU8sT0FBTyxzQkFDMUM3QjtRQUVEZixVQUFVQyxLQUFLMkMsV0FBVyxVQUFVLGdCQUFnQmpDO1FBQ3BEWCxVQUFVQyxLQUFLMkMsV0FBVyxVQUFVLG9CQUFvQmxDO1FBQ3hEVixVQUFVQyxLQUFLMkMsV0FBVyxXQUFXLGdCQUFnQjNCO1FBQ3JEakIsVUFBVUMsS0FBSzJDLFdBQVcsV0FBVyxrQkFBa0IxQixtQkFBbUJrQjtRQUMxRXBDLFVBQVVDLEtBQUsyQyxXQUFXLGVBQWVoQztXQUN0QzhCLFlBQVlTLEdBQUcsQ0FBQyxDQUFDQyxJQUNuQnBELFVBQ0NDLEtBQUsyQyxXQUFXLFlBQVksT0FBTyxPQUFPLGVBQWVRLEVBQUVDLFFBQVEsR0FDbkVELEVBQUVULE1BQU07S0FHVjtJQUVELElBQUlLLGFBQWE7UUFDaEIsS0FBSyxNQUFNSSxLQUFLVixZQUFhTSxZQUFZTSxhQUFhLENBQUNGO1FBQ3ZERixPQUFPSyxJQUFJLENBQ1Z2RCxVQUFVQyxLQUFLMkMsV0FBVyxZQUFZLE9BQU8sT0FBTyxZQUFZSSxZQUFZTCxNQUFNO0lBRXBGO0lBRUEsTUFBTUUsUUFBUUMsR0FBRyxDQUFDSTtJQUNsQixPQUFPOUI7QUFDUjtBQUVBLE9BQU8sTUFBTW9DLGlCQUEwQjtJQUN0Q0MsTUFBTTtJQUNOdEM7SUFDQWM7SUFDQVU7QUFDRCxFQUFFIn0=
@@ -0,0 +1,96 @@
1
+ import { ClassModel } from "../../domain/class-model.js";
2
+ /**
3
+ * Create the seed controller scaffolded into every new api project.
4
+ *
5
+ * Defines only the base CRUD structure. Auth decorators, IPrincipalProvider
6
+ * injection, and other cross-cutting concerns are added by the relevant
7
+ * feature during its configure phase.
8
+ */ export function createHelloController() {
9
+ return new ClassModel("HelloController", "hello.controller.ts").addImport("@decohere/cortex", "Controller", "Delete", "Field", "Get", "Param", "Post", "Put", "Query").addImport("../sample.service.js", "SampleService").decorateClass(`@Controller({ prefix: "/hello" })`).addBodyClass({
10
+ name: "HelloBody",
11
+ fields: [
12
+ {
13
+ decorator: `@Field("body", "message")`,
14
+ name: "message",
15
+ typeName: "string"
16
+ }
17
+ ]
18
+ }).addConstructorParam({
19
+ paramDecorators: [],
20
+ name: "sample",
21
+ typeName: "SampleService",
22
+ isPrivate: true,
23
+ isReadonly: true
24
+ }).defineMethod({
25
+ decorators: [
26
+ "@Get()"
27
+ ],
28
+ name: "getAll",
29
+ isAsync: true,
30
+ params: [
31
+ {
32
+ decorator: `@Query("filter")`,
33
+ name: "filter",
34
+ typeName: "string"
35
+ }
36
+ ],
37
+ body: `const greeting = await this.sample.getGreeting();\n\t\treturn { filter, message: greeting };`
38
+ }).defineMethod({
39
+ decorators: [
40
+ `@Get("/:id")`
41
+ ],
42
+ name: "getOne",
43
+ params: [
44
+ {
45
+ decorator: `@Param("id")`,
46
+ name: "id",
47
+ typeName: "string"
48
+ }
49
+ ],
50
+ body: `return { id, message: \`Hello \${id}!\` };`
51
+ }).defineMethod({
52
+ decorators: [
53
+ `@Post("/")`
54
+ ],
55
+ name: "create",
56
+ params: [
57
+ {
58
+ name: "body",
59
+ typeName: "HelloBody"
60
+ }
61
+ ],
62
+ body: `return { message: body.message };`
63
+ }).defineMethod({
64
+ decorators: [
65
+ `@Put("/:id")`
66
+ ],
67
+ name: "update",
68
+ params: [
69
+ {
70
+ decorator: `@Param("id")`,
71
+ name: "id",
72
+ typeName: "string"
73
+ },
74
+ {
75
+ name: "body",
76
+ typeName: "HelloBody"
77
+ }
78
+ ],
79
+ body: `return { id, message: body.message };`
80
+ }).defineMethod({
81
+ decorators: [
82
+ `@Delete("/:id")`
83
+ ],
84
+ name: "remove",
85
+ params: [
86
+ {
87
+ decorator: `@Param("id")`,
88
+ name: "id",
89
+ typeName: "string"
90
+ }
91
+ ],
92
+ body: `return { id, deleted: true };`
93
+ });
94
+ }
95
+
96
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2NyZWF0ZS92MS9mZWF0dXJlcy9hcGktY29yZS9oZWxsby1jb250cm9sbGVyLm1vZGVsLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENsYXNzTW9kZWwgfSBmcm9tIFwiLi4vLi4vZG9tYWluL2NsYXNzLW1vZGVsLmpzXCI7XG5cbi8qKlxuICogQ3JlYXRlIHRoZSBzZWVkIGNvbnRyb2xsZXIgc2NhZmZvbGRlZCBpbnRvIGV2ZXJ5IG5ldyBhcGkgcHJvamVjdC5cbiAqXG4gKiBEZWZpbmVzIG9ubHkgdGhlIGJhc2UgQ1JVRCBzdHJ1Y3R1cmUuICBBdXRoIGRlY29yYXRvcnMsIElQcmluY2lwYWxQcm92aWRlclxuICogaW5qZWN0aW9uLCBhbmQgb3RoZXIgY3Jvc3MtY3V0dGluZyBjb25jZXJucyBhcmUgYWRkZWQgYnkgdGhlIHJlbGV2YW50XG4gKiBmZWF0dXJlIGR1cmluZyBpdHMgY29uZmlndXJlIHBoYXNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlSGVsbG9Db250cm9sbGVyKCk6IENsYXNzTW9kZWwge1xuXHRyZXR1cm4gbmV3IENsYXNzTW9kZWwoXCJIZWxsb0NvbnRyb2xsZXJcIiwgXCJoZWxsby5jb250cm9sbGVyLnRzXCIpXG5cdFx0LmFkZEltcG9ydChcblx0XHRcdFwiQGRlY29oZXJlL2NvcnRleFwiLFxuXHRcdFx0XCJDb250cm9sbGVyXCIsXG5cdFx0XHRcIkRlbGV0ZVwiLFxuXHRcdFx0XCJGaWVsZFwiLFxuXHRcdFx0XCJHZXRcIixcblx0XHRcdFwiUGFyYW1cIixcblx0XHRcdFwiUG9zdFwiLFxuXHRcdFx0XCJQdXRcIixcblx0XHRcdFwiUXVlcnlcIixcblx0XHQpXG5cdFx0LmFkZEltcG9ydChcIi4uL3NhbXBsZS5zZXJ2aWNlLmpzXCIsIFwiU2FtcGxlU2VydmljZVwiKVxuXHRcdC5kZWNvcmF0ZUNsYXNzKGBAQ29udHJvbGxlcih7IHByZWZpeDogXCIvaGVsbG9cIiB9KWApXG5cdFx0LmFkZEJvZHlDbGFzcyh7XG5cdFx0XHRuYW1lOiBcIkhlbGxvQm9keVwiLFxuXHRcdFx0ZmllbGRzOiBbXG5cdFx0XHRcdHsgZGVjb3JhdG9yOiBgQEZpZWxkKFwiYm9keVwiLCBcIm1lc3NhZ2VcIilgLCBuYW1lOiBcIm1lc3NhZ2VcIiwgdHlwZU5hbWU6IFwic3RyaW5nXCIgfSxcblx0XHRcdF0sXG5cdFx0fSlcblx0XHQuYWRkQ29uc3RydWN0b3JQYXJhbSh7XG5cdFx0XHRwYXJhbURlY29yYXRvcnM6IFtdLFxuXHRcdFx0bmFtZTogXCJzYW1wbGVcIixcblx0XHRcdHR5cGVOYW1lOiBcIlNhbXBsZVNlcnZpY2VcIixcblx0XHRcdGlzUHJpdmF0ZTogdHJ1ZSxcblx0XHRcdGlzUmVhZG9ubHk6IHRydWUsXG5cdFx0fSlcblx0XHQuZGVmaW5lTWV0aG9kKHtcblx0XHRcdGRlY29yYXRvcnM6IFtcIkBHZXQoKVwiXSxcblx0XHRcdG5hbWU6IFwiZ2V0QWxsXCIsXG5cdFx0XHRpc0FzeW5jOiB0cnVlLFxuXHRcdFx0cGFyYW1zOiBbeyBkZWNvcmF0b3I6IGBAUXVlcnkoXCJmaWx0ZXJcIilgLCBuYW1lOiBcImZpbHRlclwiLCB0eXBlTmFtZTogXCJzdHJpbmdcIiB9XSxcblx0XHRcdGJvZHk6IGBjb25zdCBncmVldGluZyA9IGF3YWl0IHRoaXMuc2FtcGxlLmdldEdyZWV0aW5nKCk7XFxuXFx0XFx0cmV0dXJuIHsgZmlsdGVyLCBtZXNzYWdlOiBncmVldGluZyB9O2AsXG5cdFx0fSlcblx0XHQuZGVmaW5lTWV0aG9kKHtcblx0XHRcdGRlY29yYXRvcnM6IFtgQEdldChcIi86aWRcIilgXSxcblx0XHRcdG5hbWU6IFwiZ2V0T25lXCIsXG5cdFx0XHRwYXJhbXM6IFt7IGRlY29yYXRvcjogYEBQYXJhbShcImlkXCIpYCwgbmFtZTogXCJpZFwiLCB0eXBlTmFtZTogXCJzdHJpbmdcIiB9XSxcblx0XHRcdGJvZHk6IGByZXR1cm4geyBpZCwgbWVzc2FnZTogXFxgSGVsbG8gXFwke2lkfSFcXGAgfTtgLFxuXHRcdH0pXG5cdFx0LmRlZmluZU1ldGhvZCh7XG5cdFx0XHRkZWNvcmF0b3JzOiBbYEBQb3N0KFwiL1wiKWBdLFxuXHRcdFx0bmFtZTogXCJjcmVhdGVcIixcblx0XHRcdHBhcmFtczogW3sgbmFtZTogXCJib2R5XCIsIHR5cGVOYW1lOiBcIkhlbGxvQm9keVwiIH1dLFxuXHRcdFx0Ym9keTogYHJldHVybiB7IG1lc3NhZ2U6IGJvZHkubWVzc2FnZSB9O2AsXG5cdFx0fSlcblx0XHQuZGVmaW5lTWV0aG9kKHtcblx0XHRcdGRlY29yYXRvcnM6IFtgQFB1dChcIi86aWRcIilgXSxcblx0XHRcdG5hbWU6IFwidXBkYXRlXCIsXG5cdFx0XHRwYXJhbXM6IFtcblx0XHRcdFx0eyBkZWNvcmF0b3I6IGBAUGFyYW0oXCJpZFwiKWAsIG5hbWU6IFwiaWRcIiwgdHlwZU5hbWU6IFwic3RyaW5nXCIgfSxcblx0XHRcdFx0eyBuYW1lOiBcImJvZHlcIiwgdHlwZU5hbWU6IFwiSGVsbG9Cb2R5XCIgfSxcblx0XHRcdF0sXG5cdFx0XHRib2R5OiBgcmV0dXJuIHsgaWQsIG1lc3NhZ2U6IGJvZHkubWVzc2FnZSB9O2AsXG5cdFx0fSlcblx0XHQuZGVmaW5lTWV0aG9kKHtcblx0XHRcdGRlY29yYXRvcnM6IFtgQERlbGV0ZShcIi86aWRcIilgXSxcblx0XHRcdG5hbWU6IFwicmVtb3ZlXCIsXG5cdFx0XHRwYXJhbXM6IFt7IGRlY29yYXRvcjogYEBQYXJhbShcImlkXCIpYCwgbmFtZTogXCJpZFwiLCB0eXBlTmFtZTogXCJzdHJpbmdcIiB9XSxcblx0XHRcdGJvZHk6IGByZXR1cm4geyBpZCwgZGVsZXRlZDogdHJ1ZSB9O2AsXG5cdFx0fSk7XG59XG4iXSwibmFtZXMiOlsiQ2xhc3NNb2RlbCIsImNyZWF0ZUhlbGxvQ29udHJvbGxlciIsImFkZEltcG9ydCIsImRlY29yYXRlQ2xhc3MiLCJhZGRCb2R5Q2xhc3MiLCJuYW1lIiwiZmllbGRzIiwiZGVjb3JhdG9yIiwidHlwZU5hbWUiLCJhZGRDb25zdHJ1Y3RvclBhcmFtIiwicGFyYW1EZWNvcmF0b3JzIiwiaXNQcml2YXRlIiwiaXNSZWFkb25seSIsImRlZmluZU1ldGhvZCIsImRlY29yYXRvcnMiLCJpc0FzeW5jIiwicGFyYW1zIiwiYm9keSJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsVUFBVSxRQUFRLDhCQUE4QjtBQUV6RDs7Ozs7O0NBTUMsR0FDRCxPQUFPLFNBQVNDO0lBQ2YsT0FBTyxJQUFJRCxXQUFXLG1CQUFtQix1QkFDdkNFLFNBQVMsQ0FDVCxvQkFDQSxjQUNBLFVBQ0EsU0FDQSxPQUNBLFNBQ0EsUUFDQSxPQUNBLFNBRUFBLFNBQVMsQ0FBQyx3QkFBd0IsaUJBQ2xDQyxhQUFhLENBQUMsQ0FBQyxpQ0FBaUMsQ0FBQyxFQUNqREMsWUFBWSxDQUFDO1FBQ2JDLE1BQU07UUFDTkMsUUFBUTtZQUNQO2dCQUFFQyxXQUFXLENBQUMseUJBQXlCLENBQUM7Z0JBQUVGLE1BQU07Z0JBQVdHLFVBQVU7WUFBUztTQUM5RTtJQUNGLEdBQ0NDLG1CQUFtQixDQUFDO1FBQ3BCQyxpQkFBaUIsRUFBRTtRQUNuQkwsTUFBTTtRQUNORyxVQUFVO1FBQ1ZHLFdBQVc7UUFDWEMsWUFBWTtJQUNiLEdBQ0NDLFlBQVksQ0FBQztRQUNiQyxZQUFZO1lBQUM7U0FBUztRQUN0QlQsTUFBTTtRQUNOVSxTQUFTO1FBQ1RDLFFBQVE7WUFBQztnQkFBRVQsV0FBVyxDQUFDLGdCQUFnQixDQUFDO2dCQUFFRixNQUFNO2dCQUFVRyxVQUFVO1lBQVM7U0FBRTtRQUMvRVMsTUFBTSxDQUFDLDRGQUE0RixDQUFDO0lBQ3JHLEdBQ0NKLFlBQVksQ0FBQztRQUNiQyxZQUFZO1lBQUMsQ0FBQyxZQUFZLENBQUM7U0FBQztRQUM1QlQsTUFBTTtRQUNOVyxRQUFRO1lBQUM7Z0JBQUVULFdBQVcsQ0FBQyxZQUFZLENBQUM7Z0JBQUVGLE1BQU07Z0JBQU1HLFVBQVU7WUFBUztTQUFFO1FBQ3ZFUyxNQUFNLENBQUMsMENBQTBDLENBQUM7SUFDbkQsR0FDQ0osWUFBWSxDQUFDO1FBQ2JDLFlBQVk7WUFBQyxDQUFDLFVBQVUsQ0FBQztTQUFDO1FBQzFCVCxNQUFNO1FBQ05XLFFBQVE7WUFBQztnQkFBRVgsTUFBTTtnQkFBUUcsVUFBVTtZQUFZO1NBQUU7UUFDakRTLE1BQU0sQ0FBQyxpQ0FBaUMsQ0FBQztJQUMxQyxHQUNDSixZQUFZLENBQUM7UUFDYkMsWUFBWTtZQUFDLENBQUMsWUFBWSxDQUFDO1NBQUM7UUFDNUJULE1BQU07UUFDTlcsUUFBUTtZQUNQO2dCQUFFVCxXQUFXLENBQUMsWUFBWSxDQUFDO2dCQUFFRixNQUFNO2dCQUFNRyxVQUFVO1lBQVM7WUFDNUQ7Z0JBQUVILE1BQU07Z0JBQVFHLFVBQVU7WUFBWTtTQUN0QztRQUNEUyxNQUFNLENBQUMscUNBQXFDLENBQUM7SUFDOUMsR0FDQ0osWUFBWSxDQUFDO1FBQ2JDLFlBQVk7WUFBQyxDQUFDLGVBQWUsQ0FBQztTQUFDO1FBQy9CVCxNQUFNO1FBQ05XLFFBQVE7WUFBQztnQkFBRVQsV0FBVyxDQUFDLFlBQVksQ0FBQztnQkFBRUYsTUFBTTtnQkFBTUcsVUFBVTtZQUFTO1NBQUU7UUFDdkVTLE1BQU0sQ0FBQyw2QkFBNkIsQ0FBQztJQUN0QztBQUNGIn0=