libmodulor 0.24.0 → 0.26.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 (190) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +32 -151
  3. package/dist/esm/app/workers/AppUCsLoader.d.ts +2 -3
  4. package/dist/esm/apps/Helper/src/i18n.d.ts +39 -2
  5. package/dist/esm/apps/Helper/src/i18n.js +15 -1
  6. package/dist/esm/apps/Helper/src/lib/SrcFilesGenerator.d.ts +13 -0
  7. package/dist/esm/apps/Helper/src/lib/SrcFilesGenerator.js +37 -0
  8. package/dist/esm/apps/Helper/src/lib/consts.d.ts +2 -0
  9. package/dist/esm/apps/Helper/src/lib/consts.js +2 -0
  10. package/dist/esm/apps/Helper/src/lib/funcs.d.ts +4 -0
  11. package/dist/esm/apps/Helper/src/lib/funcs.js +9 -0
  12. package/dist/esm/apps/Helper/src/lib/io.d.ts +10 -0
  13. package/dist/esm/apps/Helper/src/lib/io.js +22 -0
  14. package/dist/esm/apps/Helper/src/lib/layers/app.d.ts +3 -0
  15. package/dist/esm/apps/Helper/src/lib/layers/app.js +30 -0
  16. package/dist/esm/apps/Helper/src/lib/layers/product.d.ts +3 -0
  17. package/dist/esm/apps/Helper/src/lib/layers/product.js +27 -0
  18. package/dist/esm/apps/Helper/src/lib/layers/project.d.ts +4 -0
  19. package/dist/esm/apps/Helper/src/lib/layers/project.js +163 -0
  20. package/dist/esm/apps/Helper/src/lib/layers/target.d.ts +3 -0
  21. package/dist/esm/apps/Helper/src/lib/layers/target.js +202 -0
  22. package/dist/esm/apps/Helper/src/lib/layers/uc.d.ts +3 -0
  23. package/dist/esm/apps/Helper/src/lib/layers/uc.js +113 -0
  24. package/dist/esm/apps/Helper/src/lib/project.js +21 -23
  25. package/dist/esm/apps/Helper/src/lib/types.d.ts +3 -0
  26. package/dist/esm/apps/Helper/src/lib/types.js +1 -0
  27. package/dist/esm/apps/Helper/src/manifest.d.ts +20 -0
  28. package/dist/esm/apps/Helper/src/manifest.js +20 -0
  29. package/dist/esm/apps/Helper/src/ucds/CreateAppUCD.d.ts +7 -0
  30. package/dist/esm/apps/Helper/src/ucds/CreateAppUCD.js +101 -0
  31. package/dist/esm/apps/Helper/src/ucds/CreateProductUCD.d.ts +7 -0
  32. package/dist/esm/apps/Helper/src/ucds/CreateProductUCD.js +101 -0
  33. package/dist/esm/apps/Helper/src/ucds/CreateProjectUCD.d.ts +1 -17
  34. package/dist/esm/apps/Helper/src/ucds/CreateProjectUCD.js +40 -34
  35. package/dist/esm/apps/Helper/src/ucds/CreateTargetUCD.d.ts +9 -0
  36. package/dist/esm/apps/Helper/src/ucds/CreateTargetUCD.js +109 -0
  37. package/dist/esm/apps/Helper/src/ucds/CreateUCUCD.d.ts +8 -0
  38. package/dist/esm/apps/Helper/src/ucds/CreateUCUCD.js +87 -0
  39. package/dist/esm/apps/Helper/src/ucds/DeleteGeneratedAppsTestsUCD.d.ts +1 -1
  40. package/dist/esm/apps/Helper/src/ucds/DeleteGeneratedAppsTestsUCD.js +1 -1
  41. package/dist/esm/apps/Helper/src/ucds/GenerateAppsTestsUCD.d.ts +1 -1
  42. package/dist/esm/apps/Helper/src/ucds/GenerateAppsTestsUCD.js +1 -1
  43. package/dist/esm/apps/Helper/src/ucds/TestAppUCD.d.ts +1 -1
  44. package/dist/esm/apps/Helper/src/ucds/TestAppUCD.js +1 -1
  45. package/dist/esm/convention.d.ts +15 -4
  46. package/dist/esm/convention.js +33 -9
  47. package/dist/esm/dt/Validation.d.ts +2 -2
  48. package/dist/esm/dt/base/TBase.d.ts +2 -0
  49. package/dist/esm/dt/base/TBase.js +3 -0
  50. package/dist/esm/dt/base/TObject.d.ts +6 -4
  51. package/dist/esm/dt/base/TObject.js +4 -5
  52. package/dist/esm/dt/base/TString.d.ts +2 -1
  53. package/dist/esm/dt/base/TString.js +22 -0
  54. package/dist/esm/dt/final/TFile.d.ts +13 -4
  55. package/dist/esm/dt/final/TFile.js +70 -8
  56. package/dist/esm/dt/final/TFileExtension.d.ts +1 -1
  57. package/dist/esm/dt/final/TFileMimeType.d.ts +2 -6
  58. package/dist/esm/dt/final/TFileMimeType.js +0 -6
  59. package/dist/esm/dt/final/TFilePath.d.ts +7 -0
  60. package/dist/esm/dt/final/TFilePath.js +5 -1
  61. package/dist/esm/dt/index.d.ts +1 -1
  62. package/dist/esm/error/funcs.d.ts +2 -0
  63. package/dist/esm/error/funcs.js +20 -0
  64. package/dist/esm/error/index.d.ts +1 -1
  65. package/dist/esm/error/index.js +1 -1
  66. package/dist/esm/i18n/WordingManager.d.ts +2 -1
  67. package/dist/esm/i18n/WordingManager.js +23 -2
  68. package/dist/esm/i18n/locales/de.js +8 -0
  69. package/dist/esm/i18n/locales/en.js +8 -0
  70. package/dist/esm/i18n/locales/es.js +8 -0
  71. package/dist/esm/i18n/locales/fr.js +8 -0
  72. package/dist/esm/i18n/types.d.ts +2 -2
  73. package/dist/esm/index.d.ts +2 -0
  74. package/dist/esm/index.js +2 -0
  75. package/dist/esm/index.node-test.d.ts +1 -1
  76. package/dist/esm/index.node-test.js +1 -1
  77. package/dist/esm/product/index.d.ts +1 -1
  78. package/dist/esm/product/index.js +1 -1
  79. package/dist/esm/product/workers/ProductUCsLoader.d.ts +8 -6
  80. package/dist/esm/product/workers/ProductUCsLoader.js +19 -5
  81. package/dist/esm/products/Helper/cli-node-core/container.d.ts +3 -0
  82. package/dist/esm/products/Helper/cli-node-core/container.js +26 -0
  83. package/dist/esm/products/Helper/cli-node-core/index.d.ts +1 -0
  84. package/dist/esm/products/Helper/cli-node-core/index.js +9 -0
  85. package/dist/esm/products/Helper/i18n.d.ts +101 -2
  86. package/dist/esm/products/Helper/targets/node-core-cli/container.d.ts +3 -0
  87. package/dist/esm/products/Helper/targets/node-core-cli/container.js +26 -0
  88. package/dist/esm/products/Helper/targets/node-core-cli/index.d.ts +1 -0
  89. package/dist/esm/products/Helper/targets/node-core-cli/index.js +9 -0
  90. package/dist/esm/std/FSManager.d.ts +7 -5
  91. package/dist/esm/std/FSManager.js +5 -6
  92. package/dist/esm/std/FormDataBuilder.d.ts +2 -1
  93. package/dist/esm/std/SettingsManager.d.ts +3 -16
  94. package/dist/esm/std/SettingsManager.js +1 -16
  95. package/dist/esm/std/ShellCommandExecutor.d.ts +1 -1
  96. package/dist/esm/std/consts.js +4 -4
  97. package/dist/esm/std/impl/EnvSettingsManager.d.ts +5 -4
  98. package/dist/esm/std/impl/EnvSettingsManager.js +40 -62
  99. package/dist/esm/std/impl/FakeFSManager.d.ts +3 -1
  100. package/dist/esm/std/impl/FakeFSManager.js +3 -0
  101. package/dist/esm/std/impl/FakeShellCommandExecutor.d.ts +12 -0
  102. package/dist/esm/std/impl/FakeShellCommandExecutor.js +30 -0
  103. package/dist/esm/std/impl/NodeFSManager.js +3 -2
  104. package/dist/esm/std/impl/StaticSettingsManager.d.ts +1 -1
  105. package/dist/esm/std/impl/StaticSettingsManager.js +3 -0
  106. package/dist/esm/std/index.d.ts +1 -0
  107. package/dist/esm/std/index.js +1 -0
  108. package/dist/esm/std/lib/settings.d.ts +5 -0
  109. package/dist/esm/std/lib/settings.js +39 -0
  110. package/dist/esm/target/edge-worker-hono-server/SyncEdgeWorkerHonoServerManager.d.ts +3 -1
  111. package/dist/esm/target/edge-worker-hono-server/SyncEdgeWorkerHonoServerManager.js +12 -7
  112. package/dist/esm/target/index.d.ts +1 -0
  113. package/dist/esm/target/index.js +1 -0
  114. package/dist/esm/target/lib/cli/CLIManager.d.ts +2 -2
  115. package/dist/esm/target/lib/client/consts.js +2 -1
  116. package/dist/esm/target/lib/entrypoint.d.ts +2 -0
  117. package/dist/esm/target/lib/entrypoint.js +1 -0
  118. package/dist/esm/target/lib/manifest.d.ts +13 -0
  119. package/dist/esm/target/lib/manifest.js +11 -0
  120. package/dist/esm/target/lib/mcp-server/MCPServerBooter.d.ts +2 -2
  121. package/dist/esm/target/lib/react/StyleContextProvider.d.ts +1 -0
  122. package/dist/esm/target/lib/react/form.d.ts +1 -1
  123. package/dist/esm/target/lib/react/form.js +1 -0
  124. package/dist/esm/target/lib/react/useAction.d.ts +1 -1
  125. package/dist/esm/target/lib/react/useAction.js +13 -12
  126. package/dist/esm/target/lib/server/CustomerFacingErrorBuilder.js +6 -1
  127. package/dist/esm/target/lib/server/ServerBooter.d.ts +2 -2
  128. package/dist/esm/target/lib/server/ServerRequestHandler.js +6 -2
  129. package/dist/esm/target/lib/server/consts.js +2 -1
  130. package/dist/esm/target/lib/server-express/funcs.d.ts +2 -0
  131. package/dist/esm/target/lib/server-express/funcs.js +8 -1
  132. package/dist/esm/target/lib/server-hono/funcs.d.ts +2 -1
  133. package/dist/esm/target/lib/server-hono/funcs.js +7 -3
  134. package/dist/esm/target/lib/web/input.d.ts +1 -0
  135. package/dist/esm/target/lib/web/input.js +5 -1
  136. package/dist/esm/target/node-express-server/NodeExpressServerManager.d.ts +3 -1
  137. package/dist/esm/target/node-express-server/NodeExpressServerManager.js +17 -12
  138. package/dist/esm/target/node-hono-server/NodeHonoServerManager.d.ts +3 -1
  139. package/dist/esm/target/node-hono-server/NodeHonoServerManager.js +15 -10
  140. package/dist/esm/target/node-stricli-cli/NodeStricliCLIManager.d.ts +3 -1
  141. package/dist/esm/target/node-stricli-cli/NodeStricliCLIManager.js +9 -5
  142. package/dist/esm/target/react-native-pure/UCFormField.js +2 -1
  143. package/dist/esm/target/react-native-pure/UCFormFieldControl.js +6 -4
  144. package/dist/esm/target/react-native-pure/UCFormFieldErr.d.ts +1 -1
  145. package/dist/esm/target/react-native-pure/UCFormFieldErr.js +4 -1
  146. package/dist/esm/target/react-native-pure/UCFormFieldHelp.d.ts +4 -0
  147. package/dist/esm/target/react-native-pure/UCFormFieldHelp.js +15 -0
  148. package/dist/esm/target/react-web-pure/UCFormField.js +2 -1
  149. package/dist/esm/target/react-web-pure/UCFormFieldErr.d.ts +1 -1
  150. package/dist/esm/target/react-web-pure/UCFormFieldErr.js +4 -1
  151. package/dist/esm/target/react-web-pure/UCFormFieldHelp.d.ts +4 -0
  152. package/dist/esm/target/react-web-pure/UCFormFieldHelp.js +14 -0
  153. package/dist/esm/testing/impl/NodeAppTesterConfigurator.d.ts +15 -0
  154. package/dist/esm/testing/impl/NodeAppTesterConfigurator.js +68 -0
  155. package/dist/esm/testing/impl/SimpleAppDocsEmitter/SimpleAppDocsEmitter.d.ts +7 -0
  156. package/dist/esm/testing/impl/SimpleAppDocsEmitter/SimpleAppDocsEmitter.js +59 -0
  157. package/dist/esm/testing/impl/SimpleAppDocsEmitter/markdown.d.ts +2 -0
  158. package/dist/esm/testing/impl/SimpleAppDocsEmitter/markdown.js +10 -0
  159. package/dist/esm/testing/impl/SimpleAppDocsEmitter/sequence-diagram.d.ts +2 -0
  160. package/dist/esm/testing/impl/SimpleAppDocsEmitter/sequence-diagram.js +92 -0
  161. package/dist/esm/testing/impl/SimpleAppDocsEmitter/tech-summary.d.ts +2 -0
  162. package/dist/esm/testing/impl/SimpleAppDocsEmitter/tech-summary.js +27 -0
  163. package/dist/esm/testing/impl/SimpleAppDocsEmitter/uc-summary.d.ts +2 -0
  164. package/dist/esm/testing/impl/SimpleAppDocsEmitter/uc-summary.js +63 -0
  165. package/dist/esm/testing/impl/VitestAppTestSuiteEmitter.d.ts +2 -0
  166. package/dist/esm/testing/impl/VitestAppTestSuiteEmitter.js +27 -10
  167. package/dist/esm/testing/impl/newNodeAppTester.js +4 -5
  168. package/dist/esm/testing/opts.d.ts +1 -1
  169. package/dist/esm/testing/uc-input.js +5 -2
  170. package/dist/esm/uc/exec.d.ts +42 -21
  171. package/dist/esm/uc/exec.js +48 -13
  172. package/dist/esm/uc/input-field.d.ts +6 -4
  173. package/dist/esm/uc/input-field.js +4 -5
  174. package/dist/esm/uc/side-effect.d.ts +10 -8
  175. package/dist/esm/uc/side-effect.js +5 -6
  176. package/dist/esm/uc/workers/UCInputFilesProcessor.js +3 -3
  177. package/dist/esm/uc/workers/UCInputValidator.js +2 -1
  178. package/dist/esm/uc/workers/UCOutputFilesProcessor.js +1 -1
  179. package/dist/esm/utils/bundling/webpack/loader.js +1 -1
  180. package/dist/esm/utils/index.d.ts +1 -1
  181. package/dist/esm/utils/ioc/bindCommon.d.ts +4 -4
  182. package/dist/esm/utils/ioc/bindCommon.js +17 -15
  183. package/dist/esm/utils/ioc/bindNodeCore.js +5 -0
  184. package/dist/esm/utils/ioc/bindServer.js +8 -2
  185. package/dist/esm/utils/types/utility-types.d.ts +4 -0
  186. package/package.json +19 -16
  187. package/pnpm-workspace.yaml +0 -8
  188. package/tsconfig.build.examples.json +0 -8
  189. package/tsconfig.json +0 -36
  190. package/vitest.config.ts +0 -16
package/CHANGELOG.md CHANGED
@@ -1,5 +1,37 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## v0.26.0 (2026-01-01)
4
+
5
+ **Highlights**
6
+
7
+ Added new CLI helper commands to create each element of the `libmodulor` 4-layer architecture faster : `CreateApp`, `CreateUC`, `CreateProduct`, `CreateTarget`.
8
+ Check them out with `npx libmodulor --help` (or `pnpm libmodulor --help` within a project with `libmodulor` installed).
9
+
10
+ Simplified settings management : moved to more and better defaults so you don't have to provide any settings when creating new product targets (see [Create a target](https://libmodulor.c100k.eu/docs/guides/create-target)).
11
+
12
+ Simplified testing : replaced `SimpleAppTesterConfigurator` by `NodeAppTesterConfigurator` including the necessary bindings to have tests working out of the box (see [Test an app](https://libmodulor.c100k.eu/docs/guides/test-app)). The `GenerateAppsTests` CLI command now generates a default `Configurator.ts` if it does not exist yet.
13
+
14
+ Moved all the targets of a product into a dedicated `targets` dir so they are not mixed with other types of directories you might have in a product (e.g. specific utilities, implementations, etc.).
15
+
16
+ See all the changes here : https://github.com/c100k/libmodulor/compare/v0.25.0...master
17
+
18
+ ## v0.25.0 (2025-12-21)
19
+
20
+ **Highlights**
21
+
22
+ - Added use case summary in the auto-generated app docs : In addition to the existing mermaid diagram, there is now a summary of the lifecyle, input and output in a dedicated table
23
+ - Example : https://github.com/c100k/libmodulor/tree/42fd11307cdd9f8cdec19b4de75d4959bc9f9a9e/examples/apps/Spotify#createalbum
24
+ - Improved the `File` data type
25
+ - Changed the property `path` to `uri` to conform to the `FormData` spec (this is a breaking change)
26
+ - Simplified the declaration by inlining the accepted types via `accept` instead of `type.allowed` (this is also a breaking change)
27
+ - Added `maxSizeInBytes` and `minSizeInBytes` for size validation
28
+ - Added `getConstraintsForHuman` to format constraints for the end user in the targets. For instance :
29
+ - For `FreeTextShort`, it displays `Max length: 150` 🇬🇧 when present
30
+ - For `File`, it displays `Max size: 8MB - Accepted types: application/png, application/jpg` 🇬🇧 when present
31
+ - Applied to the `react-native-pure` and `react-native-web` targets (see `UCFormFieldHelp.tsx`)
32
+
33
+ See all the changes here : https://github.com/c100k/libmodulor/compare/v0.24.0...master
34
+
3
35
  ## v0.24.0 (2025-12-07)
4
36
 
5
37
  **Highlights**
package/README.md CHANGED
@@ -5,163 +5,44 @@
5
5
 
6
6
  A TypeScript library to create platform-agnostic applications.
7
7
 
8
- ## 🚀 Getting Started
9
-
10
- If you're discovering `libmodulor`, we recommend reading the [📖 Documentation](https://libmodulor.c100k.eu/docs) first.
11
- You'll find everything you need to get started : Concepts, Examples and Guides.
12
-
13
- When you're ready, [🚀 Create a project](https://libmodulor.c100k.eu/docs/guides/create-project) and build the awesome idea you have in mind.
14
-
15
- In the meantime, here is how to declare the four layers of `libmodulor`.
16
-
17
- _These snippets are extracted from the [`Basic`](https://libmodulor.c100k.eu/docs/examples/Basic) example (check out the full example to get the full picture)._
18
-
19
- ### App
20
-
21
- ```ts
22
- const appManifest = {
23
- languageCodes: ['en', 'fr'],
24
- name: 'Event',
25
- ucReg: {
26
- Register: {
27
- action: 'Create',
28
- icon: 'user',
29
- name: 'Register',
30
- },
31
- },
32
- } satisfies AppManifest;
33
-
34
- const appI18n: AppI18n = {
35
- en: {
36
- ucif_email_label: 'Your email address',
37
- ucif_firstname_label: 'Your firstname',
38
- ucif_lastname_label: 'Your lastname',
39
- ucof_id_label: 'Your registration #',
40
- ucof_ticketNumber_label: 'Your ticket #',
41
- },
42
- fr: {
43
- ucif_email_label: 'Votre adresse email',
44
- ucif_firstname_label: 'Votre prénom',
45
- ucif_lastname_label: 'Votre nom',
46
- ucof_id_label: "Votre # d'inscription",
47
- ucof_ticketNumber_label: 'Votre # de ticket',
48
- },
49
- };
50
- ```
8
+ ## Links
51
9
 
52
- ### Use Case
53
-
54
- ```ts
55
- interface RegisterInput extends UCInput {
56
- email: UCInputFieldValue<Email>;
57
- firstname: UCInputFieldValue<PersonFirstname>;
58
- lastname: UCInputFieldValue<PersonLastname>;
59
- }
60
-
61
- interface RegisterOPI0 extends AggregateOPI0 {
62
- amount: Amount;
63
- ticketNumber: TicketNumber;
64
- }
65
-
66
- @injectable()
67
- class RegisterClientMain implements UCMain<RegisterInput, RegisterOPI0> {
68
- constructor(@inject('UCManager') private ucManager: UCManager) {}
69
-
70
- public async exec({
71
- uc,
72
- }: UCMainInput<RegisterInput, RegisterOPI0>): Promise<
73
- UCOutput<RegisterOPI0>
74
- > {
75
- const { aggregateId } = await this.ucManager.persist(uc);
76
-
77
- const amount: Amount = 99.99; // Should come from some catalog in a real application
78
- const ticketNumber: TicketNumber = 1; // Should come from a safely auto-generated sequence in a real application
79
-
80
- return new UCOutputBuilder<RegisterOPI0>()
81
- .add({
82
- amount,
83
- id: aggregateId,
84
- ticketNumber,
85
- })
86
- .get();
87
- }
88
- }
89
-
90
- const RegisterUCD: UCDef<RegisterInput, RegisterOPI0> = {
91
- io: {
92
- i: {
93
- fields: {
94
- email: {
95
- type: new TEmail(),
96
- },
97
- firstname: {
98
- type: new TPersonFirstname(),
99
- },
100
- lastname: {
101
- type: new TPersonLastname(),
102
- },
103
- },
104
- },
105
- o: {
106
- parts: {
107
- _0: {
108
- fields: {
109
- amount: {
110
- type: new TAmount('EUR'),
111
- },
112
- ticketNumber: {
113
- type: new TTicketNumber(),
114
- },
115
- },
116
- order: ['ticketNumber', 'amount', 'id'],
117
- },
118
- },
119
- },
120
- },
121
- lifecycle: {
122
- client: {
123
- main: RegisterClientMain,
124
- policy: EverybodyUCPolicy,
125
- },
126
- },
127
- metadata: {
128
- action: 'Create',
129
- icon: 'user',
130
- name: 'Register',
131
- },
132
- };
133
- ```
10
+ - [Website](https://libmodulor.c100k.eu)
11
+ - [Documentation](https://libmodulor.c100k.eu/docs)
12
+ - [Concepts > Philosophy](https://libmodulor.c100k.eu/docs/concepts/philosophy)
13
+ - [Examples > Playground](https://libmodulor.c100k.eu/docs/examples/Playground)
14
+ - [Guides > Playground](https://libmodulor.c100k.eu/docs/guides/create-project)
134
15
 
135
- ### Product
136
-
137
- ```ts
138
- const productManifest: ProductManifest = {
139
- appReg: [{ name: 'Event' }],
140
- name: 'Eventer',
141
- };
142
-
143
- const productI18n: ProductI18n = {
144
- en: {
145
- ...I18nEN,
146
- ...appI18n.en,
147
- },
148
- fr: {
149
- ...I18nFR,
150
- ...appI18n.fr,
151
- },
152
- };
153
- ```
16
+ ## Getting Started
17
+
18
+ As described in the [Architecture](https://libmodulor.c100k.eu/docs/concepts/architecture) concept, `libmodulor` follows a 4-layer architecture with `UseCase`, `App`, `Product`, and `Target`.
154
19
 
155
- ### Target
20
+ Here is how to easily create all of them, in a brand new project :
156
21
 
157
- ```ts
158
- const container = new Container(CONTAINER_OPTS);
22
+ ```sh
23
+ # Create a project
24
+ npx libmodulor CreateProject --projectName my-super-project
25
+ cd my-super-project
159
26
 
160
- bindCommon(container);
161
- bindNodeCore(container);
162
- bindProduct(container, productManifest, productI18n);
27
+ # Create an app
28
+ pnpm libmodulor CreateApp --appName Banking
29
+
30
+ # Create a use case
31
+ pnpm libmodulor CreateUC --appName Banking --ucName CreateAccount
32
+
33
+ # Create a product
34
+ pnpm libmodulor CreateProduct --productName CustomerPortal
35
+
36
+ # Create a target
37
+ pnpm libmodulor CreateTarget --productName CustomerPortal --targetName node-express-server
38
+ pnpm libmodulor CreateTarget --productName CustomerPortal --targetName node-hono-server
39
+ pnpm libmodulor CreateTarget --productName CustomerPortal --targetName node-core-cli
40
+ pnpm libmodulor CreateTarget --productName CustomerPortal --targetName node-mcp-server
163
41
  ```
164
42
 
43
+ For more params, checkout the help section : `pnpm libmodulor --help`.
44
+
45
+ And for more details on the code, follow the ad-hoc guides in the documentation.
165
46
 
166
47
  ## 👨‍💻 Contribute
167
48
 
@@ -169,4 +50,4 @@ If you think you can help in any way, feel free to contact me (cf. `author` in `
169
50
 
170
51
  ## ⚖️ License
171
52
 
172
- [LGPL-3.0](https://github.com/c100k/libmodulor/blob/v0.24.0/LICENSE)
53
+ [LGPL-3.0](https://github.com/c100k/libmodulor/blob/v0.26.0/LICENSE)
@@ -6,11 +6,10 @@ import type { AppManifestSourceSafe } from '../manifest.js';
6
6
  import { AppManifestLoader } from './AppManifestLoader.js';
7
7
  import type { Input as AppSrcFilePathBuilderInput } from './AppSrcFilePathBuilder.js';
8
8
  import { UCDefLoader } from './UCDefLoader.js';
9
- export interface Input {
9
+ export type Input = Pick<AppSrcFilePathBuilderInput, 'appsRootPath'> & {
10
10
  app: ProductAppReg;
11
- appsRootPath?: AppSrcFilePathBuilderInput['appsRootPath'];
12
11
  srcImporter: SrcImporter<AppManifestSourceSafe | UCDefSourceSafe>;
13
- }
12
+ };
14
13
  export type Output = UC<any, any, any>[];
15
14
  export declare class AppUCsLoader implements Worker<Input, Promise<Output>> {
16
15
  private appManifestLoader;
@@ -1,2 +1,39 @@
1
- import type { AppI18n } from '../../../index.js';
2
- export declare const I18n: AppI18n;
1
+ export declare const I18n: {
2
+ en: {
3
+ err_existing_app: string;
4
+ err_existing_product: string;
5
+ err_existing_target: string;
6
+ err_target_generator_not_available: string;
7
+ err_unknown_app: string;
8
+ uc_CreateApp_desc: string;
9
+ uc_CreateApp_label: string;
10
+ uc_CreateProduct_desc: string;
11
+ uc_CreateProduct_label: string;
12
+ uc_CreateProject_desc: string;
13
+ uc_CreateProject_label: string;
14
+ uc_CreateTarget_desc: string;
15
+ uc_CreateTarget_label: string;
16
+ uc_CreateUC_desc: string;
17
+ uc_CreateUC_label: string;
18
+ uc_DeleteGeneratedAppsTests_desc: string;
19
+ uc_DeleteGeneratedAppsTests_label: string;
20
+ uc_GenerateAppsTests_desc: string;
21
+ uc_GenerateAppsTests_label: string;
22
+ uc_TestApp_desc: string;
23
+ uc_TestApp_label: string;
24
+ ucif_appName_desc: string;
25
+ ucif_appPath_desc: string;
26
+ ucif_appsPath_desc: string;
27
+ ucif_depsMapping_desc: string;
28
+ ucif_initialCommit_desc: string;
29
+ ucif_monkeyTestingTimeoutInMs_desc: string;
30
+ ucif_outPath_desc: string;
31
+ ucif_pkgManagerBin_desc: string;
32
+ ucif_productName_desc: string;
33
+ ucif_projectName_desc: string;
34
+ ucif_scmBin_desc: string;
35
+ ucif_serverPortRangeStart_desc: string;
36
+ ucif_skipCoverage_desc: string;
37
+ ucif_updateSnapshots_desc: string;
38
+ };
39
+ };
@@ -1,14 +1,27 @@
1
1
  export const I18n = {
2
2
  en: {
3
- err_unknown_app: 'Unknown app : {{appPath}}',
3
+ err_existing_app: 'App "{{appPath}}" already exists',
4
+ err_existing_product: 'Product "{{productPath}}" already exists',
5
+ err_existing_target: 'Target "{{targetPath}}" already exists',
6
+ err_target_generator_not_available: 'This target has not been implemented yet via the generator. In the meantime, you can create it manually by following the examples.',
7
+ err_unknown_app: 'App "{{appPath}}" does not exist',
8
+ uc_CreateApp_desc: 'Create the basics of an app (index, i18n, manifest)',
9
+ uc_CreateApp_label: 'Create an app',
10
+ uc_CreateProduct_desc: 'Create the basics of a product (i18n, manifest)',
11
+ uc_CreateProduct_label: 'Create a product',
4
12
  uc_CreateProject_desc: 'Create a project by initializing a git repo, creating basic config files and installing the required dependencies',
5
13
  uc_CreateProject_label: 'Create a project',
14
+ uc_CreateTarget_desc: 'Create a target based on the ones provided by the lib (see https://libmodulor.c100k.eu/docs/references/targets)',
15
+ uc_CreateTarget_label: 'Create a target',
16
+ uc_CreateUC_desc: 'Create a basic use case',
17
+ uc_CreateUC_label: 'Create a use case',
6
18
  uc_DeleteGeneratedAppsTests_desc: 'Delete the automated test suite generated for each app',
7
19
  uc_DeleteGeneratedAppsTests_label: 'Delete generated apps tests',
8
20
  uc_GenerateAppsTests_desc: 'Generate an automated test suite for each app',
9
21
  uc_GenerateAppsTests_label: 'Generate apps tests',
10
22
  uc_TestApp_desc: 'Test an app and generate coverage report',
11
23
  uc_TestApp_label: 'Test app',
24
+ ucif_appName_desc: 'Name of the app conforming to the spec (i.e. PascalCase : A-Z, 0-9)',
12
25
  ucif_appPath_desc: 'The path of the app',
13
26
  ucif_appsPath_desc: 'The path to the directory containing all the apps',
14
27
  ucif_depsMapping_desc: 'The mapping of dependencies in case some of them need a specific pattern (e.g. one directory above the default)',
@@ -16,6 +29,7 @@ export const I18n = {
16
29
  ucif_monkeyTestingTimeoutInMs_desc: 'These tests can take longer than the usual default of 5000ms because they try lots of possibilities',
17
30
  ucif_outPath_desc: 'Path to a directory where to create the project. Do not include the project name in it. It is created recursively if missing.',
18
31
  ucif_pkgManagerBin_desc: "The package manager to use to install the deps and run the dev commands (must conform to npm's API)",
32
+ ucif_productName_desc: 'Name of the product conforming to the spec (i.e. PascalCase : A-Z, 0-9)',
19
33
  ucif_projectName_desc: "Name of the project conforming to the package.json's spec (i.e. a-z, 0-9, -)",
20
34
  ucif_scmBin_desc: "The source control manager to use to init and commit (must conform to git's API)",
21
35
  ucif_serverPortRangeStart_desc: 'The port number to start with when generating the server to test (incremented by 1) for each app',
@@ -0,0 +1,13 @@
1
+ import type { DirPath, FilePath } from '../../../../dt/index.js';
2
+ import type { FSManager, Worker } from '../../../../std/index.js';
3
+ export type Files = Map<FilePath[], string>;
4
+ interface Input {
5
+ files: Files;
6
+ rootPath: DirPath;
7
+ }
8
+ export declare class SrcFilesGenerator implements Worker<Input, Promise<void>> {
9
+ private fsManager;
10
+ constructor(fsManager: FSManager);
11
+ exec({ files, rootPath }: Input): Promise<void>;
12
+ }
13
+ export {};
@@ -0,0 +1,37 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
11
+ return function (target, key) { decorator(target, key, paramIndex); }
12
+ };
13
+ import { inject, injectable } from 'inversify';
14
+ let SrcFilesGenerator = class SrcFilesGenerator {
15
+ fsManager;
16
+ constructor(fsManager) {
17
+ this.fsManager = fsManager;
18
+ }
19
+ async exec({ files, rootPath }) {
20
+ for await (const [filePath, content] of files) {
21
+ const fileName = filePath[filePath.length - 1];
22
+ if (!fileName) {
23
+ throw new Error(`Incorrect file path : ${filePath}`);
24
+ }
25
+ const rest = filePath.slice(0, -1);
26
+ const path = this.fsManager.path(rootPath, ...rest);
27
+ await this.fsManager.mkdir(path, { recursive: true });
28
+ await this.fsManager.touch(this.fsManager.path(rootPath, ...filePath), content);
29
+ }
30
+ }
31
+ };
32
+ SrcFilesGenerator = __decorate([
33
+ injectable(),
34
+ __param(0, inject('FSManager')),
35
+ __metadata("design:paramtypes", [Object])
36
+ ], SrcFilesGenerator);
37
+ export { SrcFilesGenerator };
@@ -0,0 +1,2 @@
1
+ export declare const LIB_NAME = "libmodulor";
2
+ export declare const GIT_KEEP_FILE_NAME = ".gitkeep";
@@ -0,0 +1,2 @@
1
+ export const LIB_NAME = 'libmodulor';
2
+ export const GIT_KEEP_FILE_NAME = '.gitkeep';
@@ -0,0 +1,4 @@
1
+ import type { FileName } from '../../../../dt/index.js';
2
+ import type { Creatable } from './types.js';
3
+ export declare function fileImportName(name: FileName): FileName;
4
+ export declare function successMessage(item: Creatable): string;
@@ -0,0 +1,9 @@
1
+ export function fileImportName(name) {
2
+ if (name.endsWith('.ts')) {
3
+ return name.replaceAll('.ts', '.js');
4
+ }
5
+ return `${name}.js`;
6
+ }
7
+ export function successMessage(item) {
8
+ return `${item} created successfully !`;
9
+ }
@@ -0,0 +1,10 @@
1
+ import { type DirPath } from '../../../../dt/index.js';
2
+ import type { UCInput, UCInputDef, UCInputFieldValue } from '../../../../uc/index.js';
3
+ export interface AppInput extends UCInput {
4
+ appsPath: UCInputFieldValue<DirPath>;
5
+ }
6
+ export declare const AppInputFieldsDef: UCInputDef<AppInput>['fields'];
7
+ export interface ProductInput extends UCInput {
8
+ productsPath: UCInputFieldValue<DirPath>;
9
+ }
10
+ export declare const ProductInputFieldsDef: UCInputDef<ProductInput>['fields'];
@@ -0,0 +1,22 @@
1
+ import { APPS_ROOT_PATH, PRODUCTS_ROOT_PATH } from '../../../../convention.js';
2
+ import { TDirPath } from '../../../../dt/index.js';
3
+ export const AppInputFieldsDef = {
4
+ appsPath: {
5
+ cardinality: {
6
+ min: 0,
7
+ },
8
+ type: new TDirPath()
9
+ .setDefaultValue(APPS_ROOT_PATH.join('/'))
10
+ .setExamples([APPS_ROOT_PATH.join('/')]),
11
+ },
12
+ };
13
+ export const ProductInputFieldsDef = {
14
+ productsPath: {
15
+ cardinality: {
16
+ min: 0,
17
+ },
18
+ type: new TDirPath()
19
+ .setDefaultValue(PRODUCTS_ROOT_PATH.join('/'))
20
+ .setExamples([PRODUCTS_ROOT_PATH.join('/')]),
21
+ },
22
+ };
@@ -0,0 +1,3 @@
1
+ import type { AppName } from '../../../../../app/index.js';
2
+ import type { Files } from '../types.js';
3
+ export declare function files(name: AppName): Files;
@@ -0,0 +1,30 @@
1
+ import { APP_I18N_FILE_NAME, APP_I18N_NAME, APP_INDEX_FILE_NAME, APP_MANIFEST_FILE_NAME, APP_MANIFEST_NAME, APP_SRC_DIR_NAME, } from '../../../../../convention.js';
2
+ import { I18N_DEFAULT_LANG } from '../../../../../i18n/index.js';
3
+ import { LIB_NAME } from '../consts.js';
4
+ import { fileImportName } from '../funcs.js';
5
+ const INDEX_TS = `// Expose only what's necessary
6
+
7
+ export { ${APP_I18N_NAME} } from './${APP_SRC_DIR_NAME}/${fileImportName(APP_I18N_FILE_NAME)}';
8
+ export { ${APP_MANIFEST_NAME} } from './${APP_SRC_DIR_NAME}/${fileImportName(APP_MANIFEST_FILE_NAME)}';
9
+ `;
10
+ const I18N_TS = `import type { AppI18n } from '${LIB_NAME}';
11
+
12
+ export const ${APP_I18N_NAME} = {
13
+ ${I18N_DEFAULT_LANG}: {},
14
+ } satisfies AppI18n;
15
+ `;
16
+ const MANIFEST_TS = (name) => `import type { AppManifest } from '${LIB_NAME}';
17
+
18
+ export const ${APP_MANIFEST_NAME} = {
19
+ languageCodes: ['${I18N_DEFAULT_LANG}'],
20
+ name: '${name}',
21
+ ucReg: {},
22
+ } satisfies AppManifest;
23
+ `;
24
+ export function files(name) {
25
+ return new Map([
26
+ [['.', APP_INDEX_FILE_NAME], INDEX_TS],
27
+ [[APP_SRC_DIR_NAME, APP_I18N_FILE_NAME], I18N_TS],
28
+ [[APP_SRC_DIR_NAME, APP_MANIFEST_FILE_NAME], MANIFEST_TS(name)],
29
+ ]);
30
+ }
@@ -0,0 +1,3 @@
1
+ import type { ProductName } from '../../../../../product/index.js';
2
+ import type { Files } from '../types.js';
3
+ export declare function files(name: ProductName): Files;
@@ -0,0 +1,27 @@
1
+ import { PRODUCT_I18N_FILE_NAME, PRODUCT_I18N_NAME, PRODUCT_MANIFEST_FILE_NAME, PRODUCT_MANIFEST_NAME, } from '../../../../../convention.js';
2
+ import { I18N_DEFAULT_LANG } from '../../../../../i18n/index.js';
3
+ import { LIB_NAME } from '../consts.js';
4
+ const I18N_TS = `import type { ProductI18n } from '${LIB_NAME}';
5
+ import { I18n${I18N_DEFAULT_LANG.toLocaleUpperCase()} } from 'libmodulor/locales/${I18N_DEFAULT_LANG}';
6
+
7
+ export const ${PRODUCT_I18N_NAME} = {
8
+ ${I18N_DEFAULT_LANG}: {
9
+ ...I18n${I18N_DEFAULT_LANG.toLocaleUpperCase()},
10
+ p_desc: '',
11
+ p_slogan: '',
12
+ },
13
+ } satisfies ProductI18n;
14
+ `;
15
+ const MANIFEST_TS = (name) => `import type { ProductManifest } from '${LIB_NAME}';
16
+
17
+ export const ${PRODUCT_MANIFEST_NAME} = {
18
+ appReg: [],
19
+ name: '${name}',
20
+ } satisfies ProductManifest;
21
+ `;
22
+ export function files(name) {
23
+ return new Map([
24
+ [['.', PRODUCT_I18N_FILE_NAME], I18N_TS],
25
+ [['.', PRODUCT_MANIFEST_FILE_NAME], MANIFEST_TS(name)],
26
+ ]);
27
+ }
@@ -0,0 +1,4 @@
1
+ import type { Slug } from '../../../../../dt/index.js';
2
+ import type { Files } from '../types.js';
3
+ export declare const PACKAGE_JSON: (name: Slug) => string;
4
+ export declare function files(name: Slug): Files;