@quadnix/octo-build 0.0.17 → 0.2.0

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 (195) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +117 -8
  3. package/dist/commands/apply/apply.command.d.ts +25 -0
  4. package/dist/commands/apply/apply.command.js +130 -0
  5. package/dist/commands/apply/apply.command.js.map +1 -0
  6. package/dist/commands/apply/index.d.ts +1 -0
  7. package/dist/commands/apply/index.js +2 -0
  8. package/dist/commands/apply/index.js.map +1 -0
  9. package/dist/commands/build/build.command.d.ts +1 -1
  10. package/dist/commands/build/build.command.js +4 -4
  11. package/dist/commands/build/build.command.js.map +1 -1
  12. package/dist/commands/build/main.d.ts +22 -0
  13. package/dist/commands/build/main.js +22 -0
  14. package/dist/commands/build/main.js.map +1 -1
  15. package/dist/commands/build/parsers/build-file.parser.d.ts +6 -0
  16. package/dist/commands/build/parsers/build-file.parser.js +6 -0
  17. package/dist/commands/build/parsers/build-file.parser.js.map +1 -1
  18. package/dist/commands/build/streams/stream-manager.d.ts +6 -0
  19. package/dist/commands/build/streams/stream-manager.js +7 -1
  20. package/dist/commands/build/streams/stream-manager.js.map +1 -1
  21. package/dist/commands/commit/commit.command.d.ts +23 -0
  22. package/dist/commands/commit/commit.command.js +81 -0
  23. package/dist/commands/commit/commit.command.js.map +1 -0
  24. package/dist/commands/commit/index.d.ts +1 -0
  25. package/dist/commands/commit/index.js +2 -0
  26. package/dist/commands/commit/index.js.map +1 -0
  27. package/dist/commands/create-anchor/create-anchor.command.js +1 -1
  28. package/dist/commands/create-anchor/create-anchor.command.js.map +1 -1
  29. package/dist/commands/create-anchor/generator-octo-anchor-template/generators/app/index.d.ts +18 -3
  30. package/dist/commands/create-anchor/generator-octo-anchor-template/generators/app/index.js +29 -11
  31. package/dist/commands/create-anchor/generator-octo-anchor-template/generators/app/index.js.map +1 -1
  32. package/dist/commands/create-anchor/generator-octo-anchor-template/generators/app/templates/anchors/anchor/anchor.schema.ts.ejs +9 -1
  33. package/dist/commands/create-app/create-app.command.d.ts +1 -1
  34. package/dist/commands/create-app/create-app.command.js +7 -3
  35. package/dist/commands/create-app/create-app.command.js.map +1 -1
  36. package/dist/commands/create-app/generator-octo-app-template/generators/app/index.d.ts +17 -1
  37. package/dist/commands/create-app/generator-octo-app-template/generators/app/index.js +72 -16
  38. package/dist/commands/create-app/generator-octo-app-template/generators/app/index.js.map +1 -1
  39. package/dist/commands/create-app/generator-octo-app-template/generators/app/templates/README.md.ejs +73 -14
  40. package/dist/commands/create-app/generator-octo-app-template/generators/app/templates/gitignore.ejs +14 -0
  41. package/dist/commands/create-app/generator-octo-app-template/generators/app/templates/index.ts.ejs +19 -0
  42. package/dist/commands/create-app/generator-octo-app-template/generators/app/templates/package.json.ejs +9 -1
  43. package/dist/commands/create-app/generator-octo-app-template/generators/app/templates/src/aws-dynamodb-service/octo.yaml.ejs +111 -0
  44. package/dist/commands/create-app/generator-octo-app-template/generators/app/templates/src/aws-ecs-server/octo.yaml.ejs +28 -16
  45. package/dist/commands/create-app/generator-octo-app-template/generators/app/templates/src/aws-s3-website/octo.yaml.ejs +25 -3
  46. package/dist/commands/create-app/generator-octo-app-template/generators/app/templates/tsconfig.json.ejs +0 -3
  47. package/dist/commands/{create-resource/create-resource.command.d.ts → create-external-resource/create-external-resource.command.d.ts} +1 -1
  48. package/dist/commands/create-external-resource/create-external-resource.command.js +64 -0
  49. package/dist/commands/create-external-resource/create-external-resource.command.js.map +1 -0
  50. package/dist/commands/{create-resource/generator-octo-resource-template → create-external-resource/generator-octo-external-resource-template}/generators/app/index.d.ts +17 -2
  51. package/dist/commands/{create-resource/generator-octo-resource-template → create-external-resource/generator-octo-external-resource-template}/generators/app/index.js +36 -35
  52. package/dist/commands/create-external-resource/generator-octo-external-resource-template/generators/app/index.js.map +1 -0
  53. package/dist/commands/{create-resource/generator-octo-resource-template → create-external-resource/generator-octo-external-resource-template}/generators/app/templates/resources/resource/actions/add.resource.action.ts.ejs +7 -16
  54. package/dist/commands/{create-resource/generator-octo-resource-template → create-external-resource/generator-octo-external-resource-template}/generators/app/templates/resources/resource/actions/delete.resource.action.ts.ejs +21 -3
  55. package/dist/commands/create-external-resource/generator-octo-external-resource-template/generators/app/templates/resources/resource/actions/update.resource.action.ts.ejs +63 -0
  56. package/dist/commands/{create-resource/generator-octo-resource-template → create-external-resource/generator-octo-external-resource-template}/generators/app/templates/resources/resource/index.ts.ejs +1 -2
  57. package/dist/commands/create-external-resource/generator-octo-external-resource-template/generators/app/templates/resources/resource/resource.ts.ejs +28 -0
  58. package/dist/commands/create-external-resource/index.d.ts +1 -0
  59. package/dist/commands/create-external-resource/index.js +2 -0
  60. package/dist/commands/create-external-resource/index.js.map +1 -0
  61. package/dist/commands/create-model/create-model.command.js +1 -1
  62. package/dist/commands/create-model/create-model.command.js.map +1 -1
  63. package/dist/commands/create-model/generator-octo-model-template/generators/app/index.d.ts +17 -2
  64. package/dist/commands/create-model/generator-octo-model-template/generators/app/index.js +26 -9
  65. package/dist/commands/create-model/generator-octo-model-template/generators/app/index.js.map +1 -1
  66. package/dist/commands/create-model/generator-octo-model-template/generators/app/templates/models/model/model.ts.ejs +41 -1
  67. package/dist/commands/create-model/generator-octo-model-template/generators/app/templates/models/model/schema.ts.ejs +6 -1
  68. package/dist/commands/create-module/create-module.command.js +1 -1
  69. package/dist/commands/create-module/create-module.command.js.map +1 -1
  70. package/dist/commands/create-module/generator-octo-module-template/generators/app/index.d.ts +17 -2
  71. package/dist/commands/create-module/generator-octo-module-template/generators/app/index.js +27 -10
  72. package/dist/commands/create-module/generator-octo-module-template/generators/app/index.js.map +1 -1
  73. package/dist/commands/create-overlay/create-overlay.command.js +4 -3
  74. package/dist/commands/create-overlay/create-overlay.command.js.map +1 -1
  75. package/dist/commands/create-overlay/generator-octo-overlay-template/generators/app/index.d.ts +17 -2
  76. package/dist/commands/create-overlay/generator-octo-overlay-template/generators/app/index.js +26 -9
  77. package/dist/commands/create-overlay/generator-octo-overlay-template/generators/app/index.js.map +1 -1
  78. package/dist/commands/{create-cdk/create-cdk.command.d.ts → create-terraform-resource/create-terraform-resource.command.d.ts} +3 -3
  79. package/dist/commands/{create-resource/create-resource.command.js → create-terraform-resource/create-terraform-resource.command.js} +17 -11
  80. package/dist/commands/create-terraform-resource/create-terraform-resource.command.js.map +1 -0
  81. package/dist/commands/create-terraform-resource/generator-octo-terraform-resource-template/generators/app/index.d.ts +25 -0
  82. package/dist/commands/create-terraform-resource/generator-octo-terraform-resource-template/generators/app/index.js +71 -0
  83. package/dist/commands/create-terraform-resource/generator-octo-terraform-resource-template/generators/app/index.js.map +1 -0
  84. package/dist/commands/create-terraform-resource/generator-octo-terraform-resource-template/generators/app/templates/resources/resource/index.schema.ts.ejs +43 -0
  85. package/dist/commands/create-terraform-resource/generator-octo-terraform-resource-template/generators/app/templates/resources/resource/index.ts.ejs +1 -0
  86. package/dist/commands/create-terraform-resource/generator-octo-terraform-resource-template/generators/app/templates/resources/resource/resource.ts.ejs +83 -0
  87. package/dist/commands/create-terraform-resource/index.d.ts +1 -0
  88. package/dist/commands/create-terraform-resource/index.js +2 -0
  89. package/dist/commands/create-terraform-resource/index.js.map +1 -0
  90. package/dist/commands/generate/generate.command.d.ts +16 -0
  91. package/dist/commands/generate/generate.command.js +35 -0
  92. package/dist/commands/generate/generate.command.js.map +1 -0
  93. package/dist/commands/generate/index.d.ts +1 -0
  94. package/dist/commands/generate/index.js +2 -0
  95. package/dist/commands/generate/index.js.map +1 -0
  96. package/dist/commands/get-response/get-response.command.d.ts +18 -0
  97. package/dist/commands/get-response/get-response.command.js +39 -0
  98. package/dist/commands/get-response/get-response.command.js.map +1 -0
  99. package/dist/commands/get-response/index.d.ts +1 -0
  100. package/dist/commands/get-response/index.js +2 -0
  101. package/dist/commands/get-response/index.js.map +1 -0
  102. package/dist/commands/lock/index.d.ts +1 -0
  103. package/dist/commands/lock/index.js +2 -0
  104. package/dist/commands/lock/index.js.map +1 -0
  105. package/dist/commands/lock/lock.command.d.ts +18 -0
  106. package/dist/commands/lock/lock.command.js +31 -0
  107. package/dist/commands/lock/lock.command.js.map +1 -0
  108. package/dist/commands/run-action/index.d.ts +1 -0
  109. package/dist/commands/run-action/index.js +2 -0
  110. package/dist/commands/run-action/index.js.map +1 -0
  111. package/dist/commands/run-action/run-action.command.d.ts +12 -0
  112. package/dist/commands/run-action/run-action.command.js +40 -0
  113. package/dist/commands/run-action/run-action.command.js.map +1 -0
  114. package/dist/commands/unlock/index.d.ts +1 -0
  115. package/dist/commands/unlock/index.js +2 -0
  116. package/dist/commands/unlock/index.js.map +1 -0
  117. package/dist/commands/unlock/unlock.command.d.ts +18 -0
  118. package/dist/commands/unlock/unlock.command.js +35 -0
  119. package/dist/commands/unlock/unlock.command.js.map +1 -0
  120. package/dist/commands/validate/index.d.ts +1 -0
  121. package/dist/commands/validate/index.js +2 -0
  122. package/dist/commands/validate/index.js.map +1 -0
  123. package/dist/commands/validate/validate.command.d.ts +17 -0
  124. package/dist/commands/validate/validate.command.js +62 -0
  125. package/dist/commands/validate/validate.command.js.map +1 -0
  126. package/dist/index.js +20 -8
  127. package/dist/index.js.map +1 -1
  128. package/dist/resources/octo-v1.schema.json +108 -27
  129. package/dist/utilities/definition/yaml/yaml-definition.utility.d.ts +103 -13
  130. package/dist/utilities/definition/yaml/yaml-definition.utility.js +215 -68
  131. package/dist/utilities/definition/yaml/yaml-definition.utility.js.map +1 -1
  132. package/dist/utilities/octo/octo.utility.d.ts +65 -0
  133. package/dist/utilities/octo/octo.utility.js +178 -0
  134. package/dist/utilities/octo/octo.utility.js.map +1 -0
  135. package/dist/utilities/process/process.utility.d.ts +8 -0
  136. package/dist/utilities/process/process.utility.js +8 -0
  137. package/dist/utilities/process/process.utility.js.map +1 -1
  138. package/dist/utilities/project-index/project-index.utility.d.ts +27 -0
  139. package/dist/utilities/project-index/project-index.utility.js +71 -0
  140. package/dist/utilities/project-index/project-index.utility.js.map +1 -0
  141. package/dist/utilities/string/string.utility.d.ts +22 -0
  142. package/dist/utilities/string/string.utility.js +27 -0
  143. package/dist/utilities/string/string.utility.js.map +1 -1
  144. package/package.json +11 -8
  145. package/dist/commands/create-cdk/create-cdk.command.js +0 -70
  146. package/dist/commands/create-cdk/create-cdk.command.js.map +0 -1
  147. package/dist/commands/create-cdk/generator-octo-cdk-template/generators/app/index.d.ts +0 -10
  148. package/dist/commands/create-cdk/generator-octo-cdk-template/generators/app/index.js +0 -107
  149. package/dist/commands/create-cdk/generator-octo-cdk-template/generators/app/index.js.map +0 -1
  150. package/dist/commands/create-cdk/generator-octo-cdk-template/generators/app/templates/README.md.ejs +0 -23
  151. package/dist/commands/create-cdk/generator-octo-cdk-template/generators/app/templates/eslint.config.js.ejs +0 -337
  152. package/dist/commands/create-cdk/generator-octo-cdk-template/generators/app/templates/gitignore.ejs +0 -82
  153. package/dist/commands/create-cdk/generator-octo-cdk-template/generators/app/templates/gitkeep.ejs +0 -0
  154. package/dist/commands/create-cdk/generator-octo-cdk-template/generators/app/templates/package.json.ejs +0 -57
  155. package/dist/commands/create-cdk/generator-octo-cdk-template/generators/app/templates/prettierrc.ejs +0 -5
  156. package/dist/commands/create-cdk/generator-octo-cdk-template/generators/app/templates/src/anchors/app/app.anchor.schema.ts.ejs +0 -19
  157. package/dist/commands/create-cdk/generator-octo-cdk-template/generators/app/templates/src/anchors/app/app.anchor.ts.ejs +0 -17
  158. package/dist/commands/create-cdk/generator-octo-cdk-template/generators/app/templates/src/factories/dummy-credentials.factory.ts.ejs +0 -28
  159. package/dist/commands/create-cdk/generator-octo-cdk-template/generators/app/templates/src/modules/app/dummy-app/dummy-app.module.spec.ts.ejs +0 -90
  160. package/dist/commands/create-cdk/generator-octo-cdk-template/generators/app/templates/src/modules/app/dummy-app/dummy-app.module.ts.ejs +0 -16
  161. package/dist/commands/create-cdk/generator-octo-cdk-template/generators/app/templates/src/modules/app/dummy-app/index.schema.ts.ejs +0 -10
  162. package/dist/commands/create-cdk/generator-octo-cdk-template/generators/app/templates/src/modules/app/dummy-app/index.ts.ejs +0 -3
  163. package/dist/commands/create-cdk/generator-octo-cdk-template/generators/app/templates/src/modules/app/dummy-app/models/app/actions/add-dummy-app.model.action.ts.ejs +0 -59
  164. package/dist/commands/create-cdk/generator-octo-cdk-template/generators/app/templates/src/modules/app/dummy-app/models/app/index.ts.ejs +0 -1
  165. package/dist/commands/create-cdk/generator-octo-cdk-template/generators/app/templates/src/resources/http-fetch/actions/add-http-fetch.resource.action.ts.ejs +0 -55
  166. package/dist/commands/create-cdk/generator-octo-cdk-template/generators/app/templates/src/resources/http-fetch/http-fetch.resource.ts.ejs +0 -12
  167. package/dist/commands/create-cdk/generator-octo-cdk-template/generators/app/templates/src/resources/http-fetch/index.schema.ts.ejs +0 -35
  168. package/dist/commands/create-cdk/generator-octo-cdk-template/generators/app/templates/src/resources/http-fetch/index.ts.ejs +0 -3
  169. package/dist/commands/create-cdk/generator-octo-cdk-template/generators/app/templates/src/utilities/dummy/dummy.utility.ts.ejs +0 -11
  170. package/dist/commands/create-cdk/generator-octo-cdk-template/generators/app/templates/tsconfig.build.json.ejs +0 -11
  171. package/dist/commands/create-cdk/generator-octo-cdk-template/generators/app/templates/tsconfig.json.ejs +0 -39
  172. package/dist/commands/create-cdk/index.d.ts +0 -1
  173. package/dist/commands/create-cdk/index.js +0 -2
  174. package/dist/commands/create-cdk/index.js.map +0 -1
  175. package/dist/commands/create-resource/create-resource.command.js.map +0 -1
  176. package/dist/commands/create-resource/generator-octo-resource-template/generators/app/index.js.map +0 -1
  177. package/dist/commands/create-resource/generator-octo-resource-template/generators/app/templates/resources/resource/actions/update-tags.resource.action.ts.ejs +0 -86
  178. package/dist/commands/create-resource/generator-octo-resource-template/generators/app/templates/resources/resource/actions/validate.resource.action.ts.ejs +0 -40
  179. package/dist/commands/create-resource/generator-octo-resource-template/generators/app/templates/resources/resource/resource.ts.ejs +0 -12
  180. package/dist/commands/create-resource/index.d.ts +0 -1
  181. package/dist/commands/create-resource/index.js +0 -2
  182. package/dist/commands/create-resource/index.js.map +0 -1
  183. package/dist/commands/run/index.d.ts +0 -1
  184. package/dist/commands/run/index.js +0 -2
  185. package/dist/commands/run/index.js.map +0 -1
  186. package/dist/commands/run/run.command.d.ts +0 -11
  187. package/dist/commands/run/run.command.js +0 -96
  188. package/dist/commands/run/run.command.js.map +0 -1
  189. package/dist/commands/state/index.d.ts +0 -1
  190. package/dist/commands/state/index.js +0 -2
  191. package/dist/commands/state/index.js.map +0 -1
  192. package/dist/commands/state/state.command.d.ts +0 -14
  193. package/dist/commands/state/state.command.js +0 -79
  194. package/dist/commands/state/state.command.js.map +0 -1
  195. /package/dist/commands/{create-resource/generator-octo-resource-template → create-external-resource/generator-octo-external-resource-template}/generators/app/templates/resources/resource/index.schema.ts.ejs +0 -0
@@ -0,0 +1,178 @@
1
+ import { existsSync } from 'fs';
2
+ import { delimiter, dirname, resolve } from 'path';
3
+ import { CommandFailedEvent, CommandFinishedEvent, CommandStartedEvent, Container, Octo, StateManagementService, } from '@quadnix/octo';
4
+ import chalk from 'chalk';
5
+ import { YamlDefinitionUtility } from '../definition/yaml/yaml-definition.utility.js';
6
+ /**
7
+ * Boots octo the way every lifecycle command does, from the definition file `OCTO_DEFINITION_FILE_PATH`
8
+ * names, and reports what went wrong when a command fails.
9
+ */
10
+ export class OctoUtility {
11
+ /**
12
+ * Boots octo with every listener, hook, module and terraform provider the definition lists, and
13
+ * composes the app. Prints nothing, so stdout carries only the command's own output.
14
+ */
15
+ static async bootOcto() {
16
+ const definition = new YamlDefinitionUtility(OctoUtility.resolveDefinitionFilePath());
17
+ const hooks = await definition.resolveHooks();
18
+ const imports = await definition.resolveImports();
19
+ const listeners = await definition.resolveListeners();
20
+ const modules = definition.resolveModules(imports);
21
+ const stateProvider = definition.resolveStateProvider();
22
+ const tags = definition.resolveTags();
23
+ const terraformOptions = definition.resolveTerraformOptions();
24
+ // Initialize.
25
+ const octo = new Octo();
26
+ await octo.initialize(stateProvider.type, listeners.map((l) => ({
27
+ options: {
28
+ args: l.args,
29
+ metadata: l.metadata,
30
+ },
31
+ type: l.type,
32
+ })));
33
+ // Register hooks.
34
+ octo.registerHooks(hooks);
35
+ // Register terraform config + providers.
36
+ octo.registerTerraformConfig({
37
+ minTerraformVersion: terraformOptions.requiredVersion,
38
+ providers: terraformOptions.requiredProviders,
39
+ });
40
+ for (const provider of terraformOptions.providers) {
41
+ octo.registerTerraformProvider(provider.providerType, provider.accountId, provider.regionId, provider.spec, {
42
+ accountName: provider.accountName,
43
+ setRegionAttribute: provider.setRegionAttribute,
44
+ });
45
+ }
46
+ // Load modules.
47
+ for (const moduleDefinition of modules) {
48
+ octo.loadModule(moduleDefinition.moduleClass, moduleDefinition.moduleId, moduleDefinition.moduleInputs);
49
+ }
50
+ octo.orderModules(modules.map((m) => m.moduleClass));
51
+ // Compose.
52
+ await octo.compose();
53
+ const app = octo.getRootModel();
54
+ // Register tags. A module-scoped tag names a module that only exists once compose has run it.
55
+ octo.registerTags(tags);
56
+ return { app, octo };
57
+ }
58
+ /**
59
+ * Boots only the state provider the definition names, without loading a single module, and returns
60
+ * how often terraform state is checked into it during a terraform command. Loads every listener the definition lists.
61
+ *
62
+ * `apply` is a terraform action rather than an octo mode, so it has no reason to compose a model
63
+ * graph - but terraform state is checked out of the state provider and back into it around every
64
+ * terraform command, so the provider still has to be there, and terraform's output reaches the
65
+ * terminal only through the listeners.
66
+ */
67
+ static async bootStateProvider() {
68
+ const definition = new YamlDefinitionUtility(OctoUtility.resolveDefinitionFilePath());
69
+ const stateProvider = definition.resolveStateProvider();
70
+ await Container.getInstance().get(StateManagementService, {
71
+ args: [stateProvider.type],
72
+ });
73
+ for (const listener of await definition.resolveListeners()) {
74
+ await Container.getInstance().get(listener.type, {
75
+ args: listener.args,
76
+ metadata: listener.metadata,
77
+ });
78
+ }
79
+ return { stateCheckInIntervalInMs: definition.resolveStateCheckInIntervalInMs() };
80
+ }
81
+ /**
82
+ * Makes the environment survive the trip into terraform's `local-exec`.
83
+ *
84
+ * An external resource shells back out to `octo` from the terraform that terragrunt runs -
85
+ * `run-action` from its `local-exec` provisioner, `get-response` from its `data "external"` - and
86
+ * those commands inherit this process's environment. Two things about it are wrong by default, and
87
+ * both fail only after real infrastructure exists:
88
+ *
89
+ * - **`octo` is a bare binary name**, resolved through `PATH`. Invoking a binary by path -
90
+ * `node_modules/.bin/octo apply` - does not put its directory on `PATH` for child processes, so
91
+ * the callback dies with `octo: command not found`. The generated app runs the flow through
92
+ * package scripts, and `npm run` does put that directory on `PATH`, but running the binary
93
+ * directly is still supported and has to work the same. The project's bin directory is prepended
94
+ * here, and the directory this CLI is running from after it, so a globally installed or linked
95
+ * octo still wins over nothing at all.
96
+ * - **`OCTO_DEFINITION_FILE_PATH` is usually relative** (`octo.yaml` - the package scripts set
97
+ * exactly that), and terraform runs `local-exec` with a terragrunt cache directory as its cwd,
98
+ * where that resolves to nothing. It is made absolute here, against the cwd the user actually
99
+ * invoked from.
100
+ */
101
+ static prepareCallbackEnvironment() {
102
+ const definitionFilePath = process.env.OCTO_DEFINITION_FILE_PATH;
103
+ if (definitionFilePath) {
104
+ process.env.OCTO_DEFINITION_FILE_PATH = resolve(process.cwd(), definitionFilePath);
105
+ }
106
+ const binDirectories = [resolve(process.cwd(), 'node_modules', '.bin'), dirname(process.argv[1] ?? '')].filter((directory) => directory && existsSync(directory));
107
+ const pathEntries = (process.env.PATH ?? '').split(delimiter).filter(Boolean);
108
+ process.env.PATH = [...binDirectories.filter((d) => !pathEntries.includes(d)), ...pathEntries].join(delimiter);
109
+ }
110
+ /**
111
+ * Prints an octo error to stderr, including the properties it carries - the diff that matched no
112
+ * action, most of all - which a bare stack trace would hide.
113
+ */
114
+ static reportError(error) {
115
+ console.error(chalk.red(error.stack));
116
+ for (const errorProperty of Object.getOwnPropertyNames(error) || []) {
117
+ if (errorProperty !== 'message' && errorProperty !== 'stack') {
118
+ // Serialized rather than interpolated: the properties worth attaching to an octo error are
119
+ // objects - the diff that matched no action, most of all - and `${}` renders those as
120
+ // "[object Object]", which hides the only thing that would identify the node and field.
121
+ const value = error[errorProperty];
122
+ const renderedValue = value !== null && typeof value === 'object' ? JSON.stringify(value, undefined, 2) : String(value);
123
+ console.error(chalk.red(`${errorProperty}: ${renderedValue}`));
124
+ }
125
+ }
126
+ const failures = error.failures || [];
127
+ if (failures.length > 0) {
128
+ console.error('\n');
129
+ console.error(chalk.red('FAILURES'));
130
+ console.error(chalk.red('========'));
131
+ }
132
+ for (let i = 0; i < failures.length; i++) {
133
+ console.error(chalk.red(`${i + 1}. ${failures[i]}`));
134
+ }
135
+ }
136
+ /**
137
+ * Runs one lifecycle command: announces it, runs `body`, and exits with 1 after reporting what it
138
+ * threw. The command's end is announced, and awaited by listeners such as the journal, before the
139
+ * process exits.
140
+ */
141
+ static async runCommand(command, body) {
142
+ const eventService = (await Container.getInstance().get('EventService'));
143
+ const startedAt = Date.now();
144
+ eventService.emit(new CommandStartedEvent(undefined, { command }));
145
+ // Run the command, announcing how it ended.
146
+ try {
147
+ await body();
148
+ }
149
+ catch (error) {
150
+ await eventService.emitAndWait(new CommandFailedEvent(undefined, {
151
+ command,
152
+ durationInMs: Date.now() - startedAt,
153
+ error: error instanceof Error ? error : new Error(String(error)),
154
+ }));
155
+ OctoUtility.reportError(error);
156
+ process.exit(1);
157
+ return;
158
+ }
159
+ await eventService.emitAndWait(new CommandFinishedEvent(undefined, { command, durationInMs: Date.now() - startedAt }));
160
+ }
161
+ /**
162
+ * The absolute path of the definition file, from `OCTO_DEFINITION_FILE_PATH`.
163
+ *
164
+ * @throws If the variable is unset, or names a file that does not exist.
165
+ */
166
+ static resolveDefinitionFilePath() {
167
+ const fromEnv = process.env.OCTO_DEFINITION_FILE_PATH;
168
+ if (!fromEnv) {
169
+ throw new Error(`Environment variable "OCTO_DEFINITION_FILE_PATH" is not set! Set it to the path of your Octo definition YAML file.`);
170
+ }
171
+ const definitionFilePath = resolve(process.cwd(), fromEnv);
172
+ if (!existsSync(definitionFilePath)) {
173
+ throw new Error(`Octo definition file not found at "${definitionFilePath}"!`);
174
+ }
175
+ return definitionFilePath;
176
+ }
177
+ }
178
+ //# sourceMappingURL=octo.utility.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"octo.utility.js","sourceRoot":"","sources":["../../../src/utilities/octo/octo.utility.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACnD,OAAO,EAEL,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,SAAS,EAET,IAAI,EACJ,sBAAsB,GACvB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,qBAAqB,EAAE,MAAM,+CAA+C,CAAC;AAEtF;;;GAGG;AACH,MAAM,OAAO,WAAW;IACtB;;;OAGG;IACH,MAAM,CAAC,KAAK,CAAC,QAAQ;QAInB,MAAM,UAAU,GAAG,IAAI,qBAAqB,CAAC,WAAW,CAAC,yBAAyB,EAAE,CAAC,CAAC;QAEtF,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,YAAY,EAAE,CAAC;QAC9C,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,cAAc,EAAE,CAAC;QAClD,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,gBAAgB,EAAE,CAAC;QACtD,MAAM,OAAO,GAAG,UAAU,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QACnD,MAAM,aAAa,GAAG,UAAU,CAAC,oBAAoB,EAAE,CAAC;QACxD,MAAM,IAAI,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;QACtC,MAAM,gBAAgB,GAAG,UAAU,CAAC,uBAAuB,EAAE,CAAC;QAE9D,cAAc;QACd,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;QACxB,MAAM,IAAI,CAAC,UAAU,CACnB,aAAa,CAAC,IAAI,EAClB,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACpB,OAAO,EAAE;gBACP,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,QAAQ,EAAE,CAAC,CAAC,QAAQ;aACrB;YACD,IAAI,EAAE,CAAC,CAAC,IAAI;SACb,CAAC,CAAC,CACJ,CAAC;QAEF,kBAAkB;QAClB,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAE1B,yCAAyC;QACzC,IAAI,CAAC,uBAAuB,CAAC;YAC3B,mBAAmB,EAAE,gBAAgB,CAAC,eAAe;YACrD,SAAS,EAAE,gBAAgB,CAAC,iBAAiB;SAC9C,CAAC,CAAC;QACH,KAAK,MAAM,QAAQ,IAAI,gBAAgB,CAAC,SAAS,EAAE,CAAC;YAClD,IAAI,CAAC,yBAAyB,CAAC,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,EAAE;gBAC1G,WAAW,EAAE,QAAQ,CAAC,WAAW;gBACjC,kBAAkB,EAAE,QAAQ,CAAC,kBAAkB;aAChD,CAAC,CAAC;QACL,CAAC;QAED,gBAAgB;QAChB,KAAK,MAAM,gBAAgB,IAAI,OAAO,EAAE,CAAC;YACvC,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,WAAW,EAAE,gBAAgB,CAAC,QAAQ,EAAE,gBAAgB,CAAC,YAAY,CAAC,CAAC;QAC1G,CAAC;QACD,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;QAErD,WAAW;QACX,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACrB,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QAEhC,8FAA8F;QAC9F,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAExB,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;IACvB,CAAC;IAED;;;;;;;;OAQG;IACH,MAAM,CAAC,KAAK,CAAC,iBAAiB;QAC5B,MAAM,UAAU,GAAG,IAAI,qBAAqB,CAAC,WAAW,CAAC,yBAAyB,EAAE,CAAC,CAAC;QACtF,MAAM,aAAa,GAAG,UAAU,CAAC,oBAAoB,EAAE,CAAC;QAExD,MAAM,SAAS,CAAC,WAAW,EAAE,CAAC,GAAG,CAA8B,sBAAsB,EAAE;YACrF,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC;SAC3B,CAAC,CAAC;QAEH,KAAK,MAAM,QAAQ,IAAI,MAAM,UAAU,CAAC,gBAAgB,EAAE,EAAE,CAAC;YAC3D,MAAM,SAAS,CAAC,WAAW,EAAE,CAAC,GAAG,CAAe,QAAQ,CAAC,IAAI,EAAE;gBAC7D,IAAI,EAAE,QAAQ,CAAC,IAAI;gBACnB,QAAQ,EAAE,QAAQ,CAAC,QAAQ;aAC5B,CAAC,CAAC;QACL,CAAC;QAED,OAAO,EAAE,wBAAwB,EAAE,UAAU,CAAC,+BAA+B,EAAE,EAAE,CAAC;IACpF,CAAC;IAED;;;;;;;;;;;;;;;;;;;OAmBG;IACH,MAAM,CAAC,0BAA0B;QAC/B,MAAM,kBAAkB,GAAG,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC;QACjE,IAAI,kBAAkB,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,yBAAyB,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,kBAAkB,CAAC,CAAC;QACrF,CAAC;QAED,MAAM,cAAc,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,CAC5G,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,IAAI,UAAU,CAAC,SAAS,CAAC,CAClD,CAAC;QACF,MAAM,WAAW,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC9E,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,WAAW,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACjH,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,WAAW,CAAC,KAAU;QAC3B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;QACtC,KAAK,MAAM,aAAa,IAAI,MAAM,CAAC,mBAAmB,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;YACpE,IAAI,aAAa,KAAK,SAAS,IAAI,aAAa,KAAK,OAAO,EAAE,CAAC;gBAC7D,2FAA2F;gBAC3F,sFAAsF;gBACtF,wFAAwF;gBACxF,MAAM,KAAK,GAAG,KAAK,CAAC,aAAa,CAAC,CAAC;gBACnC,MAAM,aAAa,GACjB,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBACpG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,aAAa,KAAK,aAAa,EAAE,CAAC,CAAC,CAAC;YACjE,CAAC;QACH,CAAC;QAED,MAAM,QAAQ,GAAa,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAC;QAChD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACpB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC;YACrC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC;QACvC,CAAC;QACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,OAAe,EAAE,IAAyB;QAChE,MAAM,YAAY,GAAG,CAAC,MAAM,SAAS,CAAC,WAAW,EAAE,CAAC,GAAG,CAAC,cAAc,CAAC,CAGtE,CAAC;QACF,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE7B,YAAY,CAAC,IAAI,CAAC,IAAI,mBAAmB,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;QAEnE,4CAA4C;QAC5C,IAAI,CAAC;YACH,MAAM,IAAI,EAAE,CAAC;QACf,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,YAAY,CAAC,WAAW,CAC5B,IAAI,kBAAkB,CAAC,SAAS,EAAE;gBAChC,OAAO;gBACP,YAAY,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;gBACpC,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;aACjE,CAAC,CACH,CAAC;YACF,WAAW,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAChB,OAAO;QACT,CAAC;QACD,MAAM,YAAY,CAAC,WAAW,CAC5B,IAAI,oBAAoB,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,EAAE,CAAC,CACvF,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACK,MAAM,CAAC,yBAAyB;QACtC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC;QACtD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CACb,oHAAoH,CACrH,CAAC;QACJ,CAAC;QAED,MAAM,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,CAAC;QAC3D,IAAI,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,sCAAsC,kBAAkB,IAAI,CAAC,CAAC;QAChF,CAAC;QAED,OAAO,kBAAkB,CAAC;IAC5B,CAAC;CACF"}
@@ -1,4 +1,12 @@
1
1
  import { type ChildProcessWithoutNullStreams, type SpawnOptionsWithoutStdio } from 'child_process';
2
+ /**
3
+ * Spawns the child processes a build job runs.
4
+ */
2
5
  export declare class ProcessUtility {
6
+ /**
7
+ * Runs a shell command detached, with its output piped to `outputWriter`.
8
+ *
9
+ * @returns The child process, so the caller can watch or kill it.
10
+ */
3
11
  static runDetachedProcess(command: string, options: SpawnOptionsWithoutStdio, outputWriter: any): ChildProcessWithoutNullStreams;
4
12
  }
@@ -1,5 +1,13 @@
1
1
  import { spawn } from 'child_process';
2
+ /**
3
+ * Spawns the child processes a build job runs.
4
+ */
2
5
  export class ProcessUtility {
6
+ /**
7
+ * Runs a shell command detached, with its output piped to `outputWriter`.
8
+ *
9
+ * @returns The child process, so the caller can watch or kill it.
10
+ */
3
11
  static runDetachedProcess(command, options, outputWriter) {
4
12
  options = options || {};
5
13
  options.detached = true;
@@ -1 +1 @@
1
- {"version":3,"file":"process.utility.js","sourceRoot":"","sources":["../../../src/utilities/process/process.utility.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsE,KAAK,EAAE,MAAM,eAAe,CAAC;AAE1G,MAAM,OAAO,cAAc;IACzB,MAAM,CAAC,kBAAkB,CACvB,OAAe,EACf,OAAiC,EACjC,YAAiB;QAEjB,OAAO,GAAG,OAAO,IAAI,EAAE,CAAC;QACxB,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;QACxB,OAAO,CAAC,KAAK,GAAG,CAAC,QAAQ,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC;QACvD,OAAO,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,EAAE,CAAC;QAEhC,IAAI,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC3C,eAAe,GAAG,eAAe,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC;QAE5E,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC;QACtD,MAAM,UAAU,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,eAAe,GAAG,CAAC,CAAC,CAAC,CAAC;QAC5D,OAAO,KAAK,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;IAC7C,CAAC;CACF"}
1
+ {"version":3,"file":"process.utility.js","sourceRoot":"","sources":["../../../src/utilities/process/process.utility.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsE,KAAK,EAAE,MAAM,eAAe,CAAC;AAE1G;;GAEG;AACH,MAAM,OAAO,cAAc;IACzB;;;;OAIG;IACH,MAAM,CAAC,kBAAkB,CACvB,OAAe,EACf,OAAiC,EACjC,YAAiB;QAEjB,OAAO,GAAG,OAAO,IAAI,EAAE,CAAC;QACxB,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;QACxB,OAAO,CAAC,KAAK,GAAG,CAAC,QAAQ,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC;QACvD,OAAO,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,EAAE,CAAC;QAEhC,IAAI,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC3C,eAAe,GAAG,eAAe,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC;QAE5E,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC;QACtD,MAAM,UAAU,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,eAAe,GAAG,CAAC,CAAC,CAAC,CAAC;QAC5D,OAAO,KAAK,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;IAC7C,CAAC;CACF"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Keeps `src/index.ts` - the file an app's definition points at with
3
+ * `importPath: "./dist/index.js"` - in step with what the generators have written.
4
+ *
5
+ * Without this, every `create-*` command produced a construct that nothing reached. A module was not
6
+ * exported, so the definition could not name it; a resource and its actions were never imported, so
7
+ * their decorators never ran and nothing was registered. Both compile and both load: an unresolved
8
+ * *side-effect* import is not a type error, and a construct that is simply never imported is not an
9
+ * error at all. The failure surfaces much later, as a module that cannot be found or an action that
10
+ * never fires.
11
+ */
12
+ export declare class ProjectIndexUtility {
13
+ private static readonly HEADER;
14
+ /**
15
+ * Adds a re-export for a construct the definition file names by class - modules, in practice.
16
+ */
17
+ static addExport(projectRootDir: string, className: string, modulePath: string): boolean;
18
+ /**
19
+ * Adds a side-effect import (`import './x.js';`) for a construct that only needs registering.
20
+ */
21
+ static addImport(projectRootDir: string, modulePath: string): boolean;
22
+ /**
23
+ * @returns Whether the file was changed - false when the entry was already there, or when there is
24
+ * no `src` directory to own an index (a construct generated into something that is not an app).
25
+ */
26
+ private static addEntry;
27
+ }
@@ -0,0 +1,71 @@
1
+ import { existsSync, readFileSync, writeFileSync } from 'fs';
2
+ import { join, resolve } from 'path';
3
+ /**
4
+ * Keeps `src/index.ts` - the file an app's definition points at with
5
+ * `importPath: "./dist/index.js"` - in step with what the generators have written.
6
+ *
7
+ * Without this, every `create-*` command produced a construct that nothing reached. A module was not
8
+ * exported, so the definition could not name it; a resource and its actions were never imported, so
9
+ * their decorators never ran and nothing was registered. Both compile and both load: an unresolved
10
+ * *side-effect* import is not a type error, and a construct that is simply never imported is not an
11
+ * error at all. The failure surfaces much later, as a module that cannot be found or an action that
12
+ * never fires.
13
+ */
14
+ export class ProjectIndexUtility {
15
+ static { this.HEADER = [
16
+ '/**',
17
+ ' * Custom Octo constructs for this app.',
18
+ ' *',
19
+ ' * The `create-*` commands maintain this file. Modules are exported because the definition file',
20
+ ' * names them; everything else is imported for the registration side effect its decorator',
21
+ ' * performs, which is what makes a construct known to Octo at boot.',
22
+ ' */',
23
+ '',
24
+ ].join('\n'); }
25
+ /**
26
+ * Adds a re-export for a construct the definition file names by class - modules, in practice.
27
+ */
28
+ static addExport(projectRootDir, className, modulePath) {
29
+ return ProjectIndexUtility.addEntry(projectRootDir, `export { ${className} } from '${modulePath}';`);
30
+ }
31
+ /**
32
+ * Adds a side-effect import (`import './x.js';`) for a construct that only needs registering.
33
+ */
34
+ static addImport(projectRootDir, modulePath) {
35
+ return ProjectIndexUtility.addEntry(projectRootDir, `import '${modulePath}';`);
36
+ }
37
+ /**
38
+ * @returns Whether the file was changed - false when the entry was already there, or when there is
39
+ * no `src` directory to own an index (a construct generated into something that is not an app).
40
+ */
41
+ static addEntry(projectRootDir, entry) {
42
+ const sourceDir = resolve(join(projectRootDir, 'src'));
43
+ if (!existsSync(sourceDir)) {
44
+ return false;
45
+ }
46
+ const indexPath = join(sourceDir, 'index.ts');
47
+ const contents = existsSync(indexPath) ? readFileSync(indexPath, 'utf-8') : ProjectIndexUtility.HEADER;
48
+ if (contents.includes(entry)) {
49
+ return false;
50
+ }
51
+ const lines = contents.split('\n');
52
+ const imports = lines.filter((line) => line.startsWith('import '));
53
+ const exports = lines.filter((line) => line.startsWith('export ') && line !== 'export {};');
54
+ // Everything that is neither: the header comment, and any hand-written code below it. Trailing
55
+ // blank lines go with it and are normalized away when the file is rebuilt.
56
+ const preamble = lines
57
+ .filter((line) => !line.startsWith('import ') && !line.startsWith('export '))
58
+ .join('\n')
59
+ .trim();
60
+ if (entry.startsWith('import ')) {
61
+ imports.push(entry);
62
+ }
63
+ else {
64
+ exports.push(entry);
65
+ }
66
+ const blocks = [preamble, imports.sort().join('\n'), exports.sort().join('\n')].filter(Boolean);
67
+ writeFileSync(indexPath, blocks.join('\n\n') + '\n');
68
+ return true;
69
+ }
70
+ }
71
+ //# sourceMappingURL=project-index.utility.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-index.utility.js","sourceRoot":"","sources":["../../../src/utilities/project-index/project-index.utility.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAC7D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAErC;;;;;;;;;;GAUG;AACH,MAAM,OAAO,mBAAmB;aACN,WAAM,GAAG;QAC/B,KAAK;QACL,yCAAyC;QACzC,IAAI;QACJ,iGAAiG;QACjG,2FAA2F;QAC3F,qEAAqE;QACrE,KAAK;QACL,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb;;OAEG;IACH,MAAM,CAAC,SAAS,CAAC,cAAsB,EAAE,SAAiB,EAAE,UAAkB;QAC5E,OAAO,mBAAmB,CAAC,QAAQ,CAAC,cAAc,EAAE,YAAY,SAAS,YAAY,UAAU,IAAI,CAAC,CAAC;IACvG,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,SAAS,CAAC,cAAsB,EAAE,UAAkB;QACzD,OAAO,mBAAmB,CAAC,QAAQ,CAAC,cAAc,EAAE,WAAW,UAAU,IAAI,CAAC,CAAC;IACjF,CAAC;IAED;;;OAGG;IACK,MAAM,CAAC,QAAQ,CAAC,cAAsB,EAAE,KAAa;QAC3D,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC,CAAC;QACvD,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3B,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QAC9C,MAAM,QAAQ,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,MAAM,CAAC;QACvG,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7B,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;QACnE,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,IAAI,KAAK,YAAY,CAAC,CAAC;QAC5F,+FAA+F;QAC/F,2EAA2E;QAC3E,MAAM,QAAQ,GAAG,KAAK;aACnB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;aAC5E,IAAI,CAAC,IAAI,CAAC;aACV,IAAI,EAAE,CAAC;QAEV,IAAI,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAChC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;QAED,MAAM,MAAM,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAChG,aAAa,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;QAErD,OAAO,IAAI,CAAC;IACd,CAAC"}
@@ -1,5 +1,27 @@
1
+ /**
2
+ * Name checks and case conversions the `create-*` scaffolding commands run on user input.
3
+ */
1
4
  export declare class StringUtility {
2
5
  static AVAILABLE_MODEL_TYPES: readonly ["account", "app", "deployment", "environment", "execution", "filesystem", "image", "pipeline", "region", "server", "service", "subnet"];
6
+ /**
7
+ * Whether a name is kebab-case, the shape every generated file and folder uses.
8
+ */
3
9
  static isKebabCase(subject: string): boolean;
10
+ /**
11
+ * Mirrors the check the `@Resource`/`@Model`/`@Module`/`@Overlay`/`@Anchor` decorators run in
12
+ * `packages/octo`. Kept identical to theirs on purpose: a name this accepts and they reject would
13
+ * generate happily and fail much later, at registration, with `Invalid package name`.
14
+ *
15
+ * Note it admits a leading `@` but no `/` - `@octo` is the shape in use, `@my/pkg` is not a
16
+ * package name here.
17
+ */
18
+ static isValidPackageName(subject: string): boolean;
19
+ /**
20
+ * `my-thing` to `myThing`, for generated variable names.
21
+ */
22
+ static toCamelCase(subject: string): string;
23
+ /**
24
+ * `my-thing` to `MyThing`, for generated class names.
25
+ */
4
26
  static toPascalCase(subject: string): string;
5
27
  }
@@ -1,3 +1,6 @@
1
+ /**
2
+ * Name checks and case conversions the `create-*` scaffolding commands run on user input.
3
+ */
1
4
  export class StringUtility {
2
5
  static { this.AVAILABLE_MODEL_TYPES = [
3
6
  'account',
@@ -13,9 +16,33 @@ export class StringUtility {
13
16
  'service',
14
17
  'subnet',
15
18
  ]; }
19
+ /**
20
+ * Whether a name is kebab-case, the shape every generated file and folder uses.
21
+ */
16
22
  static isKebabCase(subject) {
17
23
  return /^[a-z][a-z0-9-]*[a-z0-9]$/.test(subject);
18
24
  }
25
+ /**
26
+ * Mirrors the check the `@Resource`/`@Model`/`@Module`/`@Overlay`/`@Anchor` decorators run in
27
+ * `packages/octo`. Kept identical to theirs on purpose: a name this accepts and they reject would
28
+ * generate happily and fail much later, at registration, with `Invalid package name`.
29
+ *
30
+ * Note it admits a leading `@` but no `/` - `@octo` is the shape in use, `@my/pkg` is not a
31
+ * package name here.
32
+ */
33
+ static isValidPackageName(subject) {
34
+ return /^[@A-Za-z][\w-]+[A-Za-z]$/.test(subject);
35
+ }
36
+ /**
37
+ * `my-thing` to `myThing`, for generated variable names.
38
+ */
39
+ static toCamelCase(subject) {
40
+ const pascal = StringUtility.toPascalCase(subject);
41
+ return pascal.charAt(0).toLowerCase() + pascal.slice(1);
42
+ }
43
+ /**
44
+ * `my-thing` to `MyThing`, for generated class names.
45
+ */
19
46
  static toPascalCase(subject) {
20
47
  return subject
21
48
  .split('-')
@@ -1 +1 @@
1
- {"version":3,"file":"string.utility.js","sourceRoot":"","sources":["../../../src/utilities/string/string.utility.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,aAAa;aACjB,0BAAqB,GAAG;QAC7B,SAAS;QACT,KAAK;QACL,YAAY;QACZ,aAAa;QACb,WAAW;QACX,YAAY;QACZ,OAAO;QACP,UAAU;QACV,QAAQ;QACR,QAAQ;QACR,SAAS;QACT,QAAQ;KACA,CAAC;IAEX,MAAM,CAAC,WAAW,CAAC,OAAe;QAChC,OAAO,2BAA2B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,CAAC,YAAY,CAAC,OAAe;QACjC,OAAO,OAAO;aACX,KAAK,CAAC,GAAG,CAAC;aACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;aAC3D,IAAI,CAAC,EAAE,CAAC,CAAC;IACd,CAAC"}
1
+ {"version":3,"file":"string.utility.js","sourceRoot":"","sources":["../../../src/utilities/string/string.utility.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,OAAO,aAAa;aACjB,0BAAqB,GAAG;QAC7B,SAAS;QACT,KAAK;QACL,YAAY;QACZ,aAAa;QACb,WAAW;QACX,YAAY;QACZ,OAAO;QACP,UAAU;QACV,QAAQ;QACR,QAAQ;QACR,SAAS;QACT,QAAQ;KACA,CAAC;IAEX;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,OAAe;QAChC,OAAO,2BAA2B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACnD,CAAC;IAED;;;;;;;OAOG;IACH,MAAM,CAAC,kBAAkB,CAAC,OAAe;QACvC,OAAO,2BAA2B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACnD,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,OAAe;QAChC,MAAM,MAAM,GAAG,aAAa,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QACnD,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,YAAY,CAAC,OAAe;QACjC,OAAO,OAAO;aACX,KAAK,CAAC,GAAG,CAAC;aACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;aAC3D,IAAI,CAAC,EAAE,CAAC,CAAC;IACd,CAAC"}
package/package.json CHANGED
@@ -6,8 +6,8 @@
6
6
  "url": "https://github.com/quadnix/octo/issues"
7
7
  },
8
8
  "dependencies": {
9
- "@quadnix/octo": "~0.0.30",
10
- "@quadnix/octo-event-listeners": "~0.0.9",
9
+ "@quadnix/octo": "~0.2.0",
10
+ "@quadnix/octo-event-listeners": "~0.2.0",
11
11
  "ajv": "~8.17.1",
12
12
  "chalk": "~5.5.0",
13
13
  "js-yaml": "~4.1.0",
@@ -43,6 +43,7 @@
43
43
  "moduleNameMapper": {
44
44
  "(.+)\\.js": "$1"
45
45
  },
46
+ "passWithNoTests": true,
46
47
  "preset": "ts-jest/presets/default-esm",
47
48
  "rootDir": ".",
48
49
  "testEnvironment": "node",
@@ -77,11 +78,16 @@
77
78
  "type": "git",
78
79
  "url": "git+https://github.com/quadnix/octo.git"
79
80
  },
81
+ "type": "module",
82
+ "types": "./dist/index.d.ts",
83
+ "version": "0.2.0",
80
84
  "scripts": {
81
- "build": "rimraf dist && tsc -p tsconfig.build.json && npm run copy-assets && chmod +x ./dist/index.js",
85
+ "build": "rimraf dist && tsc -p tsconfig.build.json && pnpm run copy-assets && chmod +x ./dist/index.js",
82
86
  "check:circular-dependency": "dpdm --no-tree --exit-code circular:1 --no-warning ./dist/index.js",
87
+ "check:types": "tsc --noEmit -p tsconfig.json",
83
88
  "copy-assets": "copyfiles -u 1 \"src/**/*.{ejs,json}\" dist/",
84
89
  "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
90
+ "format:check": "prettier --check \"src/**/*.ts\" \"test/**/*.ts\"",
85
91
  "lint": "eslint .",
86
92
  "lint:fix": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
87
93
  "test": "NODE_OPTIONS=--experimental-vm-modules jest --testRegex=\"\\.spec.ts$\"",
@@ -90,8 +96,5 @@
90
96
  "test:e2e": "NODE_OPTIONS=--experimental-vm-modules jest --testRegex=\"\\.e2e-spec.ts$\"",
91
97
  "test:integration": "NODE_OPTIONS=--experimental-vm-modules jest --testRegex=\"\\.ispec.ts$\"",
92
98
  "test:watch": "jest --watch"
93
- },
94
- "type": "module",
95
- "types": "./dist/index.d.ts",
96
- "version": "0.0.17"
97
- }
99
+ }
100
+ }
@@ -1,70 +0,0 @@
1
- import { dirname, resolve } from 'path';
2
- import { fileURLToPath } from 'url';
3
- import chalk from 'chalk';
4
- import {} from 'yargs';
5
- import { createEnv } from 'yeoman-environment';
6
- const __dirname = dirname(fileURLToPath(import.meta.url));
7
- export const createCdkCommand = {
8
- builder: (yargs) => {
9
- return yargs
10
- .option('name', {
11
- alias: 'n',
12
- demandOption: true,
13
- description: 'Name of the CDK to create. A new directory will be created with the same name.',
14
- type: 'string',
15
- })
16
- .option('path', {
17
- alias: 'p',
18
- default: '.',
19
- description: 'Path to create the CDK.',
20
- type: 'string',
21
- })
22
- .option('options', {
23
- alias: 'o',
24
- description: `Options to create the CDK.
25
-
26
- Allowed options:
27
-
28
- withExamples [boolean] Whether to include examples in the CDK. Default: false
29
- `,
30
- type: 'array',
31
- });
32
- },
33
- command: 'create-cdk',
34
- describe: 'Create a new Octo CDK.',
35
- handler: async (argv) => {
36
- const { name, path, options } = argv;
37
- // Parse options.
38
- const parsedOptions = { withExamples: false };
39
- if (options && options.length > 0) {
40
- for (let i = 0; i < options.length;) {
41
- const optionValues = options[i].split('=');
42
- if (optionValues.length !== 2) {
43
- parsedOptions[options[i]] = options[i + 1];
44
- i += 2;
45
- }
46
- else {
47
- parsedOptions[optionValues[0]] = optionValues[1];
48
- i += 1;
49
- }
50
- }
51
- }
52
- console.log(chalk.blue(`Creating CDK...`));
53
- const env = createEnv();
54
- env.register(resolve(__dirname, 'generator-octo-cdk-template/generators/app/index.js'), {
55
- namespace: 'generator-octo-cdk-template:app',
56
- });
57
- try {
58
- await env.run(['generator-octo-cdk-template:app', name, path, String(parsedOptions.withExamples || false)], {
59
- skipCache: true,
60
- skipInstall: false,
61
- });
62
- console.log(chalk.green(`Successfully created CDK!`));
63
- }
64
- catch (error) {
65
- console.error(chalk.red(`Failed to create CDK! ${error.message}`));
66
- process.exit(1);
67
- }
68
- },
69
- };
70
- //# sourceMappingURL=create-cdk.command.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"create-cdk.command.js","sourceRoot":"","sources":["../../../src/commands/create-cdk/create-cdk.command.ts"],"names":[],"mappings":"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"}
@@ -1,10 +0,0 @@
1
- import Generator, { type BaseOptions } from 'yeoman-generator';
2
- export default class extends Generator {
3
- private readonly cdkName;
4
- private readonly cdkOptions;
5
- private readonly cdkPath;
6
- constructor(args: string[], opts: BaseOptions);
7
- initializing(): Promise<void>;
8
- writing(): Promise<void>;
9
- end(): void;
10
- }