libmodulor 0.22.0 → 0.24.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 (92) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +154 -2
  3. package/dist/esm/apps/Helper/src/lib/project.js +4 -4
  4. package/dist/esm/apps/Helper/src/ucds/TestAppUCD.d.ts +2 -1
  5. package/dist/esm/apps/Helper/src/ucds/TestAppUCD.js +8 -0
  6. package/dist/esm/convention.d.ts +3 -0
  7. package/dist/esm/convention.js +3 -0
  8. package/dist/esm/dt/DataTypes.d.ts +1 -2
  9. package/dist/esm/dt/base/TObject.js +1 -1
  10. package/dist/esm/i18n/index.d.ts +1 -1
  11. package/dist/esm/i18n/locales/de.d.ts +2 -0
  12. package/dist/esm/i18n/locales/de.js +54 -0
  13. package/dist/esm/i18n/locales/es.d.ts +2 -0
  14. package/dist/esm/i18n/locales/es.js +54 -0
  15. package/dist/esm/i18n/types.d.ts +3 -2
  16. package/dist/esm/index.babel.d.ts +1 -0
  17. package/dist/esm/index.babel.js +1 -0
  18. package/dist/esm/index.node-stricli-cli.d.ts +2 -0
  19. package/dist/esm/index.node-stricli-cli.js +2 -0
  20. package/dist/esm/index.react.d.ts +1 -1
  21. package/dist/esm/index.react.js +1 -1
  22. package/dist/esm/index.vite.d.ts +1 -1
  23. package/dist/esm/index.vite.js +1 -1
  24. package/dist/esm/index.webpack.d.ts +1 -0
  25. package/dist/esm/index.webpack.js +1 -0
  26. package/dist/esm/std/I18nManager.d.ts +12 -0
  27. package/dist/esm/std/JWTManager.d.ts +16 -1
  28. package/dist/esm/std/impl/JoseJWTManager.d.ts +3 -2
  29. package/dist/esm/std/impl/JoseJWTManager.js +4 -0
  30. package/dist/esm/std/impl/NodeFSManager.js +1 -1
  31. package/dist/esm/std/impl/SimpleHTTPAPICaller.js +4 -2
  32. package/dist/esm/std/impl/SimpleMapI18nManager.d.ts +6 -1
  33. package/dist/esm/std/impl/SimpleMapI18nManager.js +41 -12
  34. package/dist/esm/target/lib/client/consts.js +1 -0
  35. package/dist/esm/target/lib/react/UCPanel.d.ts +7 -8
  36. package/dist/esm/target/lib/react/useUC.js +11 -1
  37. package/dist/esm/target/lib/server/AuthenticationChecker.js +1 -1
  38. package/dist/esm/target/lib/server/PublicApiKeyChecker.js +1 -1
  39. package/dist/esm/target/lib/server/ServerManager.d.ts +1 -0
  40. package/dist/esm/target/lib/server/ServerRequestHandler.js +2 -2
  41. package/dist/esm/target/lib/server/consts.js +1 -0
  42. package/dist/esm/target/lib/server-express/funcs.js +5 -4
  43. package/dist/esm/target/lib/server-hono/funcs.js +2 -2
  44. package/dist/esm/target/lib/server-node/funcs.d.ts +2 -2
  45. package/dist/esm/target/lib/server-node/funcs.js +11 -1
  46. package/dist/esm/target/lib/server-node/types.d.ts +1 -0
  47. package/dist/esm/target/node-express-server/NodeExpressServerManager.d.ts +2 -2
  48. package/dist/esm/target/node-express-server/NodeExpressServerManager.js +2 -1
  49. package/dist/esm/target/node-hono-server/NodeHonoServerManager.d.ts +2 -2
  50. package/dist/esm/target/node-hono-server/NodeHonoServerManager.js +2 -1
  51. package/dist/esm/target/node-stricli-cli/NodeStricliCLIManager.d.ts +12 -0
  52. package/dist/esm/target/node-stricli-cli/NodeStricliCLIManager.js +118 -0
  53. package/dist/esm/testing/AppTester.js +4 -5
  54. package/dist/esm/testing/UCDefASTParser.d.ts +24 -6
  55. package/dist/esm/testing/impl/SimpleAppDocsEmitter.js +4 -5
  56. package/dist/esm/testing/impl/TypeScriptLibUCDefASTParser.js +38 -11
  57. package/dist/esm/testing/impl/VitestAppTestSuiteRunner.d.ts +1 -1
  58. package/dist/esm/testing/impl/VitestAppTestSuiteRunner.js +17 -2
  59. package/dist/esm/testing/impl/newNodeAppTester.js +3 -2
  60. package/dist/esm/testing/opts.js +1 -1
  61. package/dist/esm/testing/workers/AppTestSuiteRunner.d.ts +2 -0
  62. package/dist/esm/testing/workers/UCExecutor.js +1 -1
  63. package/dist/esm/testing/workers/checkers/AppI18nChecker.d.ts +8 -2
  64. package/dist/esm/testing/workers/checkers/AppI18nChecker.js +44 -2
  65. package/dist/esm/testing/workers/checkers/UCDefSourcesChecker.js +12 -12
  66. package/dist/esm/uc/impl/HTTPUCTransporter.js +2 -2
  67. package/dist/esm/uc/impl/KnexUCDataStore.js +2 -2
  68. package/dist/esm/uc/index.d.ts +0 -1
  69. package/dist/esm/uc/index.js +0 -1
  70. package/dist/esm/uc/workers/UCExecChecker.js +1 -1
  71. package/dist/esm/utils/bundling/babel/plugin.d.ts +2 -0
  72. package/dist/esm/utils/bundling/babel/plugin.js +38 -0
  73. package/dist/esm/utils/bundling/funcs.d.ts +6 -0
  74. package/dist/esm/utils/bundling/funcs.js +20 -0
  75. package/dist/esm/utils/bundling/typescript.d.ts +3 -0
  76. package/dist/esm/utils/bundling/typescript.js +61 -0
  77. package/dist/esm/utils/bundling/vite/plugin.d.ts +6 -0
  78. package/dist/esm/utils/bundling/vite/plugin.js +17 -0
  79. package/dist/esm/utils/bundling/webpack/loader.d.ts +2 -0
  80. package/dist/esm/utils/bundling/webpack/loader.js +12 -0
  81. package/dist/esm/utils/http/HTTPRequestBuilder.js +1 -1
  82. package/dist/esm/utils/http/NDJSONStreamManager.d.ts +2 -1
  83. package/dist/esm/utils/http/NDJSONStreamManager.js +4 -1
  84. package/dist/esm/utils/http/SSEStreamManager.d.ts +2 -1
  85. package/dist/esm/utils/http/SSEStreamManager.js +4 -1
  86. package/dist/esm/utils/ioc/bindCommon.js +1 -1
  87. package/dist/esm/utils/terminal/fmt.js +1 -1
  88. package/package.json +32 -10
  89. package/pnpm-workspace.yaml +1 -4
  90. package/tsconfig.build.examples.json +8 -0
  91. package/tsconfig.json +1 -0
  92. package/vitest.config.ts +16 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## v0.24.0 (2025-12-07)
4
+
5
+ **Highlights**
6
+
7
+ - Introduced `babel`, `vite` plugins and `webpack` loader => https://libmodulor.c100k.eu/docs/guides/bundle-target
8
+ - Introduced the `node-stricli-cli` target using @bloomberg's `stricli` library
9
+ - Introduced the `Playground` example, runnable locally, to play with all the features of `libmodulor` => https://libmodulor.c100k.eu/docs/examples/Playground
10
+ - Improved apps testing by making sure non-english languages are fully translated
11
+ - Improved apps testing performance by optimizing use cases testing using the `stream` transport
12
+ - Introduced `de` 🇩🇪 and `es` 🇪🇸 locales (see them in action in the `Playground`)
13
+
14
+ Some breaking changes but at the very low level. If your apps break, just follow the TypeScript errors and you should be good to go.
15
+
16
+ Also bumped React versions for the infamous [React2Shell vulnerability](https://react.dev/blog/2025/12/03/critical-security-vulnerability-in-react-server-components).
17
+
18
+ See all the changes here : https://github.com/c100k/libmodulor/compare/v0.23.0...master
19
+
20
+ ## v0.23.0 (2025-11-11)
21
+
22
+ See all the changes here : https://github.com/c100k/libmodulor/compare/v0.22.0...master
23
+
3
24
  ## v0.22.0 (2025-10-25)
4
25
 
5
26
  **Added**
package/README.md CHANGED
@@ -7,14 +7,166 @@ A TypeScript library to create platform-agnostic applications.
7
7
 
8
8
  ## 🚀 Getting Started
9
9
 
10
- If you're discovering `libmodulor`, we recommend reading the [📖 Documentation](https://libmodulor.c100k.eu/docs) first. You'll find everything you need to get started : Concepts, Examples and Guides.
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.
11
12
 
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.
13
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
+ ```
51
+
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
+ ```
134
+
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
+ ```
154
+
155
+ ### Target
156
+
157
+ ```ts
158
+ const container = new Container(CONTAINER_OPTS);
159
+
160
+ bindCommon(container);
161
+ bindNodeCore(container);
162
+ bindProduct(container, productManifest, productI18n);
163
+ ```
164
+
165
+
14
166
  ## 👨‍💻 Contribute
15
167
 
16
168
  If you think you can help in any way, feel free to contact me (cf. `author` in `package.json`). I'd love to chat.
17
169
 
18
170
  ## ⚖️ License
19
171
 
20
- [LGPL-3.0](https://github.com/c100k/libmodulor/blob/v0.22.0/LICENSE)
172
+ [LGPL-3.0](https://github.com/c100k/libmodulor/blob/v0.24.0/LICENSE)
@@ -81,13 +81,13 @@ export const PACKAGE_JSON = (name) => `{
81
81
  "test": "tsc && vitest run --passWithNoTests"
82
82
  },
83
83
  "dependencies": {
84
- "inversify": "^7.10.3",
84
+ "inversify": "^7.10.4",
85
85
  "libmodulor": "latest",
86
86
  "reflect-metadata": "^0.2.2"
87
87
  },
88
88
  "devDependencies": {
89
- "@biomejs/biome": "^2.2.7",
90
- "@types/node": "^24.9.1",
89
+ "@biomejs/biome": "^2.3.8",
90
+ "@types/node": "^24.10.1",
91
91
  "@vitest/coverage-v8": "^3.2.4",
92
92
  "buffer": "^6.0.3",
93
93
  "cookie-parser": "^1.4.7",
@@ -95,7 +95,7 @@ export const PACKAGE_JSON = (name) => `{
95
95
  "express-fileupload": "^1.5.2",
96
96
  "fast-check": "^4.3.0",
97
97
  "helmet": "^8.1.0",
98
- "jose": "^6.1.0",
98
+ "jose": "^6.1.2",
99
99
  "typescript": "^5.9.3",
100
100
  "vite": "^6.4.1",
101
101
  "vitest": "^3.2.4"
@@ -1,8 +1,9 @@
1
1
  import type { AppName } from '../../../../app/index.js';
2
- import { type UCDef, type UCInputFieldValue } from '../../../../uc/index.js';
2
+ import { type UCDef, type UCInputFieldValue, type UCName } from '../../../../uc/index.js';
3
3
  import { type AppInput } from '../lib/app.js';
4
4
  export interface TestAppInput extends AppInput {
5
5
  appName: UCInputFieldValue<AppName>;
6
+ only: UCInputFieldValue<UCName>;
6
7
  skipCoverage: UCInputFieldValue<boolean>;
7
8
  updateSnapshots: UCInputFieldValue<boolean>;
8
9
  }
@@ -34,6 +34,7 @@ let TestAppClientMain = class TestAppClientMain {
34
34
  async exec({ uc }) {
35
35
  const appsPath = uc.reqVal0('appsPath');
36
36
  const appName = uc.reqVal0('appName');
37
+ const only = uc.rVal0('only');
37
38
  const skipCoverage = uc.reqVal0('skipCoverage');
38
39
  const updateSnapshots = uc.reqVal0('updateSnapshots');
39
40
  const appPath = this.fsManager.path(appsPath, appName);
@@ -42,6 +43,7 @@ let TestAppClientMain = class TestAppClientMain {
42
43
  }
43
44
  await this.appTestSuiteRunner.exec({
44
45
  appPath,
46
+ only,
45
47
  skipCoverage,
46
48
  updateSnapshots,
47
49
  });
@@ -84,6 +86,12 @@ export const TestAppUCD = {
84
86
  appName: {
85
87
  type: new TString().setExamples([APP_NAME_PLACEHOLDER]),
86
88
  },
89
+ only: {
90
+ cardinality: {
91
+ min: 0,
92
+ },
93
+ type: new TString().setExamples(['CreatePost']),
94
+ },
87
95
  skipCoverage: {
88
96
  type: new TBoolean().setDefaultValue(false),
89
97
  },
@@ -36,6 +36,9 @@ export declare const UC_DEF_TYPE: string;
36
36
  export declare const UC_INPUT_BASE: string;
37
37
  export declare const UC_INPUT_FIELD_PATTERN: string;
38
38
  export declare const UC_INPUT_SUFFIX: string;
39
+ export declare const UC_LIFECYCLE_PROP_NAME: string;
40
+ export declare const UC_LIFECYCLE_CLIENT_PROP_NAME: string;
41
+ export declare const UC_LIFECYCLE_SERVER_PROP_NAME: string;
39
42
  export declare const UC_MAIN_SUFFIX: string;
40
43
  export declare const UC_MAIN_CLIENT_SUFFIX: string;
41
44
  export declare const UC_MAIN_SERVER_SUFFIX: string;
@@ -46,6 +46,9 @@ export const UC_DEF_TYPE = 'UCDef';
46
46
  export const UC_INPUT_BASE = 'UCInput';
47
47
  export const UC_INPUT_FIELD_PATTERN = '^UCInputFieldValue<(.*)>$';
48
48
  export const UC_INPUT_SUFFIX = 'Input';
49
+ export const UC_LIFECYCLE_PROP_NAME = 'lifecycle';
50
+ export const UC_LIFECYCLE_CLIENT_PROP_NAME = 'client';
51
+ export const UC_LIFECYCLE_SERVER_PROP_NAME = 'server';
49
52
  export const UC_MAIN_SUFFIX = 'Main';
50
53
  export const UC_MAIN_CLIENT_SUFFIX = `Client${UC_MAIN_SUFFIX}`;
51
54
  export const UC_MAIN_SERVER_SUFFIX = `Server${UC_MAIN_SUFFIX}`;
@@ -1,2 +1 @@
1
- import type { DataType } from './DataType.js';
2
- export declare const DataTypes: DataType[];
1
+ export declare const DataTypes: readonly ["Address", "Amount", "ApiKey", "BarCode", "CSS", "Color", "ColorRGBA", "CompanyName", "CountryISO3166Alpha2", "CurrencyISO4217", "DateISO8601", "DateTimeFormat", "DirPath", "DomainName", "Email", "EmbeddedObject", "Emoji", "EncryptionKey", "ErrorMessage", "ExternalServiceId", "File", "FileExtension", "FileMimeType", "FileName", "FilePath", "FreeTextLong", "FreeTextShort", "Geolocation", "GitSSHURL", "HTML", "HTTPContentType", "HTTPMethod", "HTTPStatusNumber", "HostAddress", "HostPort", "IPv4", "IPv6", "JSONString", "JWT", "JavaScript", "JobTitle", "Markdown", "NumIndex", "Password", "Percentage", "PersonFirstname", "PersonFullname", "PersonInitials", "PersonLastname", "QRCode", "SQLQuery", "SSHPrivateKey", "SSHPublicKey", "SearchQuery", "SemVerVersion", "ShellCommand", "Slug", "Time", "Timestamp", "TransportType", "UIntDuration", "UIntQuantity", "URL", "URLPath", "UUID", "Username", "Year", "YesNo"];
@@ -65,7 +65,7 @@ export class TObject extends TBase {
65
65
  break;
66
66
  }
67
67
  default:
68
- ((_) => { })(strategy);
68
+ strategy;
69
69
  }
70
70
  }
71
71
  return validation;
@@ -1,3 +1,3 @@
1
1
  export { I18N_DEFAULT_LANG } from './consts.js';
2
- export type { I18n, I18nCoreKey, I18nCoreTranslations, I18nLanguageCode, I18nSource, I18nSourceSafe, I18nTranslation, I18nTranslationKey, } from './types.js';
2
+ export type { I18n, I18nCoreKey, I18nCoreTranslations, I18nEntry, I18nLanguageCode, I18nSource, I18nSourceSafe, I18nTranslation, I18nTranslationKey, } from './types.js';
3
3
  export { WordingManager, type WordingManagerKey } from './WordingManager.js';
@@ -0,0 +1,2 @@
1
+ import type { I18nCoreTranslations } from '../types.js';
2
+ export declare const I18nDE: I18nCoreTranslations;
@@ -0,0 +1,54 @@
1
+ export const I18nDE = {
2
+ dt_YesNo_N_desc: '',
3
+ dt_YesNo_N_label: 'Nein',
4
+ dt_YesNo_Y_desc: '',
5
+ dt_YesNo_Y_label: 'Ja',
6
+ uc_client_confirm_cancel: 'Abbrechen',
7
+ uc_client_confirm_confirm: 'Ja',
8
+ uc_client_confirm_message: '',
9
+ uc_client_confirm_title: 'Sind Sie sicher?',
10
+ uc_i_submit_changing: 'Laden',
11
+ uc_i_submit_idle: 'Speichern',
12
+ uc_i_submit_initializing: 'Laden',
13
+ uc_i_submit_submitting: 'Speichern',
14
+ validation_fieldsOr: 'Mindestens eines dieser Felder muss ausgefüllt werden: {{expected}}',
15
+ validation_format_ColorRGBA: 'Muss eine gültige RGBA-Farbe sein',
16
+ validation_format_DateISO8601: 'Muss ein gültiges Datum im ISO8601-Format sein',
17
+ validation_format_DirPath: 'Muss ein gültiger Verzeichnispfad sein',
18
+ validation_format_DomainName: 'Muss ein gültiger Domainname sein',
19
+ validation_format_Email: 'Muss eine gültige E-Mail-Adresse sein',
20
+ validation_format_FilePath: 'Muss ein gültiger Dateipfad sein',
21
+ validation_format_GitSSHURL: 'Muss eine gültige Git-SSH-URL sein',
22
+ validation_format_IPv4: 'Muss eine gültige IPv4-Adresse sein',
23
+ validation_format_IPv6: 'Muss eine gültige IPv6-Adresse sein',
24
+ validation_format_JSON: 'Muss ein gültiger JSON-String sein',
25
+ validation_format_JWT: 'Muss ein gültiges JWT sein',
26
+ validation_format_PersonFirstname: 'Muss ein gültiger Vorname sein, beginnend mit einem Großbuchstaben',
27
+ validation_format_PersonFullname: 'Muss ein gültiger vollständiger Name sein, beginnend mit einem Großbuchstaben',
28
+ validation_format_PersonInitials: 'Muss gültige Initialen aus Großbuchstaben enthalten',
29
+ validation_format_PersonLastname: 'Muss ein gültiger Nachname sein, beginnend mit einem Großbuchstaben',
30
+ validation_format_QRCode: 'Muss ein gültiger QR-Code im Base64-Format sein',
31
+ validation_format_SemVerVersion: 'Muss eine gültige SemVer-Version sein (X.X.X)',
32
+ validation_format_Slug: 'Darf nur Kleinbuchstaben, Ziffern und Bindestriche (-) enthalten',
33
+ validation_format_SSHPrivateKey: 'Muss ein gültiger privater SSH-Schlüssel sein',
34
+ validation_format_SSHPublicKey: 'Muss ein gültiger öffentlicher SSH-Schlüssel sein',
35
+ validation_format_Time: 'Muss eine gültige Uhrzeit sein',
36
+ validation_format_URL: 'Muss eine gültige URL sein',
37
+ validation_format_UUID: 'Muss eine gültige UUID sein',
38
+ validation_mandatory: 'Muss ausgefüllt werden',
39
+ validation_max: 'Muss kleiner oder gleich {{expected}} sein',
40
+ validation_maxCount: 'Darf höchstens {{expected}} Element(e) enthalten',
41
+ validation_maxLength: 'Darf höchstens {{expected}} Zeichen enthalten',
42
+ validation_min: 'Muss größer oder gleich {{expected}} sein',
43
+ validation_minCount: 'Muss mindestens {{expected}} Element(e) enthalten',
44
+ validation_minLength: 'Muss mindestens {{expected}} Zeichen enthalten',
45
+ validation_oneOf: 'Muss eines der Elemente der Liste sein',
46
+ validation_shape: 'Muss der erwarteten Objektstruktur entsprechen',
47
+ validation_type_array: 'Muss ein Array sein',
48
+ validation_type_boolean: 'Muss ein Boolescher Wert sein',
49
+ validation_type_int: 'Muss eine ganze Zahl sein',
50
+ validation_type_number: 'Muss eine Zahl sein',
51
+ validation_type_object: 'Muss ein Objekt sein',
52
+ validation_type_scalar: 'Muss ein Skalar sein',
53
+ validation_type_string: 'Muss ein String sein',
54
+ };
@@ -0,0 +1,2 @@
1
+ import type { I18nCoreTranslations } from '../types.js';
2
+ export declare const I18nES: I18nCoreTranslations;
@@ -0,0 +1,54 @@
1
+ export const I18nES = {
2
+ dt_YesNo_N_desc: '',
3
+ dt_YesNo_N_label: 'No',
4
+ dt_YesNo_Y_desc: '',
5
+ dt_YesNo_Y_label: 'Sí',
6
+ uc_client_confirm_cancel: 'Cancelar',
7
+ uc_client_confirm_confirm: 'Sí',
8
+ uc_client_confirm_message: '',
9
+ uc_client_confirm_title: '¿Estás seguro?',
10
+ uc_i_submit_changing: 'Cargando',
11
+ uc_i_submit_idle: 'Guardar',
12
+ uc_i_submit_initializing: 'Cargando',
13
+ uc_i_submit_submitting: 'Guardando',
14
+ validation_fieldsOr: 'Al menos uno de estos campos debe estar completado: {{expected}}',
15
+ validation_format_ColorRGBA: 'Debe ser un color RGBA válido',
16
+ validation_format_DateISO8601: 'Debe ser una fecha válida con formato ISO8601',
17
+ validation_format_DirPath: 'Debe ser una ruta de directorio válida',
18
+ validation_format_DomainName: 'Debe ser un nombre de dominio válido',
19
+ validation_format_Email: 'Debe ser una dirección de correo válida',
20
+ validation_format_FilePath: 'Debe ser una ruta de archivo válida',
21
+ validation_format_GitSSHURL: 'Debe ser una URL SSH de Git válida',
22
+ validation_format_IPv4: 'Debe ser una dirección IPv4 válida',
23
+ validation_format_IPv6: 'Debe ser una dirección IPv6 válida',
24
+ validation_format_JSON: 'Debe ser una cadena JSON válida',
25
+ validation_format_JWT: 'Debe ser un JWT válido',
26
+ validation_format_PersonFirstname: 'Debe ser un nombre válido comenzando con mayúscula',
27
+ validation_format_PersonFullname: 'Debe ser un nombre completo válido comenzando con mayúscula',
28
+ validation_format_PersonInitials: 'Debe contener iniciales válidas compuestas por letras mayúsculas',
29
+ validation_format_PersonLastname: 'Debe ser un apellido válido comenzando con mayúscula',
30
+ validation_format_QRCode: 'Debe ser un código QR válido en formato base64',
31
+ validation_format_SemVerVersion: 'Debe ser una versión SemVer válida (X.X.X)',
32
+ validation_format_Slug: 'Debe contener solo letras minúsculas, dígitos y guiones (-)',
33
+ validation_format_SSHPrivateKey: 'Debe ser una clave privada SSH válida',
34
+ validation_format_SSHPublicKey: 'Debe ser una clave pública SSH válida',
35
+ validation_format_Time: 'Debe ser una hora válida',
36
+ validation_format_URL: 'Debe ser una URL válida',
37
+ validation_format_UUID: 'Debe ser un UUID válido',
38
+ validation_mandatory: 'Debe completarse',
39
+ validation_max: 'Debe ser menor o igual que {{expected}}',
40
+ validation_maxCount: 'Debe contener como máximo {{expected}} elemento(s)',
41
+ validation_maxLength: 'Debe contener como máximo {{expected}} carácter(es)',
42
+ validation_min: 'Debe ser mayor o igual que {{expected}}',
43
+ validation_minCount: 'Debe contener al menos {{expected}} elemento(s)',
44
+ validation_minLength: 'Debe contener al menos {{expected}} carácter(es)',
45
+ validation_oneOf: 'Debe ser uno de los elementos de la lista',
46
+ validation_shape: 'Debe respetar la estructura esperada del objeto',
47
+ validation_type_array: 'Debe ser un array',
48
+ validation_type_boolean: 'Debe ser un valor booleano',
49
+ validation_type_int: 'Debe ser un número entero',
50
+ validation_type_number: 'Debe ser un número',
51
+ validation_type_object: 'Debe ser un objeto',
52
+ validation_type_scalar: 'Debe ser un escalar',
53
+ validation_type_string: 'Debe ser una cadena',
54
+ };
@@ -1,6 +1,6 @@
1
1
  import type { ViolationI18nable, YesNo } from '../dt/index.js';
2
2
  import type { UCClientConfirmConfig, UCExecState, UCWording } from '../uc/index.js';
3
- export type I18nLanguageCode = 'en' | 'fr';
3
+ export type I18nLanguageCode = 'de' | 'en' | 'es' | 'fr';
4
4
  /**
5
5
  * A translation value
6
6
  *
@@ -14,6 +14,7 @@ export type I18nSource = any;
14
14
  export type I18nSourceSafe = {
15
15
  I18n: I18n;
16
16
  };
17
+ export type I18nEntry = Record<I18nTranslationKey, I18nTranslation>;
17
18
  export type I18n = {
18
- [key in I18nLanguageCode]?: Record<I18nTranslationKey, I18nTranslation>;
19
+ [key in I18nLanguageCode]?: I18nEntry;
19
20
  };
@@ -0,0 +1 @@
1
+ export { Plugin } from './utils/bundling/babel/plugin.js';
@@ -0,0 +1 @@
1
+ export { Plugin } from './utils/bundling/babel/plugin.js';
@@ -0,0 +1,2 @@
1
+ export { NodeStricliCLIManager } from './target/node-stricli-cli/NodeStricliCLIManager.js';
2
+ export { bindNodeCLI } from './utils/ioc/bindNodeCLI.js';
@@ -0,0 +1,2 @@
1
+ export { NodeStricliCLIManager } from './target/node-stricli-cli/NodeStricliCLIManager.js';
2
+ export { bindNodeCLI } from './utils/ioc/bindNodeCLI.js';
@@ -6,7 +6,7 @@ export type { RenderUCEntrypointTouchable, RenderUCExecTouchable, UCEntrypointTo
6
6
  export { UCContainer } from './target/lib/react/UCContainer.js';
7
7
  export { UCEntrypoint } from './target/lib/react/UCEntrypoint.js';
8
8
  export { type Props as UCOutputFieldValueFragmentProps, UCOutputFieldValueFragment, } from './target/lib/react/UCOutputFieldValueFragment.js';
9
- export { UCPanel } from './target/lib/react/UCPanel.js';
9
+ export { type Props as UCPanelProps, UCPanel, } from './target/lib/react/UCPanel.js';
10
10
  export { type UseActionOpts, useAction, } from './target/lib/react/useAction.js';
11
11
  export { type CloneFunc, type DivertFunc, type RefillFunc, useUC, } from './target/lib/react/useUC.js';
12
12
  export { type AppendFunc, type RemoveFunc, type UpdateFunc, useUCOR, } from './target/lib/react/useUCOR.js';
@@ -3,7 +3,7 @@ export { StyleContext, StyleContextProvider, styleDef, useStyleContext, } from '
3
3
  export { UCContainer } from './target/lib/react/UCContainer.js';
4
4
  export { UCEntrypoint } from './target/lib/react/UCEntrypoint.js';
5
5
  export { UCOutputFieldValueFragment, } from './target/lib/react/UCOutputFieldValueFragment.js';
6
- export { UCPanel } from './target/lib/react/UCPanel.js';
6
+ export { UCPanel, } from './target/lib/react/UCPanel.js';
7
7
  export { useAction, } from './target/lib/react/useAction.js';
8
8
  export { useUC, } from './target/lib/react/useUC.js';
9
9
  export { useUCOR, } from './target/lib/react/useUCOR.js';
@@ -1 +1 @@
1
- export { StripUCDLifecycleServerPlugin } from './utils/bundling/vite/StripUCDLifecycleServerPlugin.js';
1
+ export { Plugin } from './utils/bundling/vite/plugin.js';
@@ -1 +1 @@
1
- export { StripUCDLifecycleServerPlugin } from './utils/bundling/vite/StripUCDLifecycleServerPlugin.js';
1
+ export { Plugin } from './utils/bundling/vite/plugin.js';
@@ -0,0 +1 @@
1
+ export { default } from './utils/bundling/webpack/loader.js';
@@ -0,0 +1 @@
1
+ export { default } from './utils/bundling/webpack/loader.js';
@@ -16,6 +16,18 @@ export interface I18nManager extends Initializable {
16
16
  * @param value
17
17
  */
18
18
  add<K extends I18nTranslationKey>(key: K, value: string): Promise<void>;
19
+ /**
20
+ * Get the list of available languages
21
+ */
22
+ availableLangs(): I18nLanguageCode[];
23
+ /**
24
+ * Change the current language
25
+ *
26
+ * It might not work for all the implementations, depending on how langs are managed.
27
+ *
28
+ * @param lang
29
+ */
30
+ changeLang(lang: I18nLanguageCode): Promise<void>;
19
31
  /**
20
32
  * Get the current lang code
21
33
  */
@@ -41,6 +41,19 @@ export interface JWTManager {
41
41
  * @param opts
42
42
  */
43
43
  decode<T extends JWTManagerPayload>(value: JWT, opts?: JWTManagerDecodeOpts): Promise<T>;
44
+ /**
45
+ * Decode the token without checking the signature
46
+ *
47
+ * IMPORTANT : IT DOES NOT CHECK THE SIGNATURE
48
+ *
49
+ * The main purpose of this method is to be used client side to decode the JWT in order to update some state including :
50
+ * - displaying the firstname in the UI
51
+ * - set the payload in some state
52
+ * - etc.
53
+ *
54
+ * @param value
55
+ */
56
+ decodeUnsafe<T extends JWTManagerPayload>(value: JWT): Promise<T>;
44
57
  /**
45
58
  * Encode the payload
46
59
  *
@@ -53,7 +66,9 @@ export interface JWTManager {
53
66
  /**
54
67
  * Check whether the token is usable or not
55
68
  *
56
- * Note that the signature is not checked. Indeed, the main purpose of this method is to be used client side to save some requests (e.g. when the token is expired).
69
+ * IMPORTANT : IT DOES NOT CHECK THE SIGNATURE
70
+ *
71
+ * The main purpose of this method is to be used client side to save some requests (e.g. when the token is expired).
57
72
  * In this case, no need to send a request that will trigger an error. Better to renew the token at the client's initiative.
58
73
  */
59
74
  isUsable(value: JWT): Promise<boolean>;
@@ -1,6 +1,6 @@
1
1
  import type { JWT } from '../../dt/index.js';
2
2
  import type { ClockManager } from '../ClockManager.js';
3
- import type { JWTManager, JWTManagerDecodeOpts, JWTManagerEncodeOpts, JWTManagerSettings } from '../JWTManager.js';
3
+ import type { JWTManager, JWTManagerDecodeOpts, JWTManagerEncodeOpts, JWTManagerPayload, JWTManagerSettings } from '../JWTManager.js';
4
4
  import type { SettingsManager } from '../SettingsManager.js';
5
5
  export type S = Omit<JWTManagerSettings, 'jwt_manager_invalidate_issued_before'>;
6
6
  export declare class JoseJWTManager implements JWTManager {
@@ -8,7 +8,8 @@ export declare class JoseJWTManager implements JWTManager {
8
8
  private settingsManager;
9
9
  constructor(clockManager: ClockManager, settingsManager: SettingsManager<S>);
10
10
  s(): S;
11
- decode<T extends object>(value: JWT, opts?: JWTManagerDecodeOpts): Promise<T>;
11
+ decode<T extends JWTManagerPayload>(value: JWT, opts?: JWTManagerDecodeOpts): Promise<T>;
12
+ decodeUnsafe<T extends JWTManagerPayload>(value: JWT): Promise<T>;
12
13
  encode<T extends object>(payload: T, opts?: JWTManagerEncodeOpts): Promise<JWT>;
13
14
  isUsable(value: JWT): Promise<boolean>;
14
15
  }
@@ -54,6 +54,10 @@ let JoseJWTManager = class JoseJWTManager {
54
54
  }
55
55
  throw new Error(`Unsupported alg ${alg}`);
56
56
  }
57
+ async decodeUnsafe(value) {
58
+ const decoded = decodeJwt(value);
59
+ return decoded;
60
+ }
57
61
  async encode(payload, opts) {
58
62
  const alg = opts?.alg ?? this.s().jwt_manager_algorithm;
59
63
  const aud = opts?.aud ?? this.s().jwt_manager_audience;
@@ -110,7 +110,7 @@ let NodeFSManager = class NodeFSManager {
110
110
  case 'library':
111
111
  return [];
112
112
  default:
113
- ((_) => { })(source);
113
+ source;
114
114
  return [];
115
115
  }
116
116
  }
@@ -90,7 +90,7 @@ let SimpleHTTPAPICaller = class SimpleHTTPAPICaller {
90
90
  });
91
91
  const { ok, redirected } = response;
92
92
  if (ok || redirected) {
93
- return this.processResGood({ opts, outputBuilder, stream }, isFormURLEncoded, isJSON, isNDJSON, isSSE, isXML, response);
93
+ return this.processResGood({ opts, outputBuilder, stream }, abortController, isFormURLEncoded, isJSON, isNDJSON, isSSE, isXML, response);
94
94
  }
95
95
  const message = await this.processResBad({ errBuilder, opts }, isJSON, isXML, response);
96
96
  this.throwError(message ?? unknownErrorMessage, status);
@@ -173,13 +173,14 @@ let SimpleHTTPAPICaller = class SimpleHTTPAPICaller {
173
173
  return JSON.stringify(error);
174
174
  }
175
175
  }
176
- async processResGood({ opts, outputBuilder, stream, }, isFormURLEncoded, isJSON, isNDJSON, isSSE, isXML, response) {
176
+ async processResGood({ opts, outputBuilder, stream, }, abortController, isFormURLEncoded, isJSON, isNDJSON, isSSE, isXML, response) {
177
177
  let payload;
178
178
  if (isNDJSON && stream) {
179
179
  if (!response.body) {
180
180
  throw new Error(ERR_STREAM_UNAVAILABLE);
181
181
  }
182
182
  await this.ndJSONStreamManager.exec({
183
+ abortController,
183
184
  onData: async (data) => {
184
185
  if (outputBuilder) {
185
186
  stream.onData(await outputBuilder(data));
@@ -196,6 +197,7 @@ let SimpleHTTPAPICaller = class SimpleHTTPAPICaller {
196
197
  throw new Error(ERR_STREAM_UNAVAILABLE);
197
198
  }
198
199
  await this.sseStreamManager.exec({
200
+ abortController,
199
201
  onData: async (data) => {
200
202
  if (outputBuilder) {
201
203
  stream.onData(await outputBuilder(data));
@@ -1,18 +1,23 @@
1
- import { type I18n, type I18nLanguageCode, type I18nTranslationKey } from '../../i18n/index.js';
1
+ import type { I18n, I18nLanguageCode, I18nTranslationKey } from '../../i18n/index.js';
2
2
  import type { I18nManager, I18nManagerTOpts } from '../I18nManager.js';
3
3
  import type { Logger } from '../Logger.js';
4
4
  export declare class SimpleMapI18nManager implements I18nManager {
5
5
  private i18n;
6
6
  private logger;
7
7
  private static PLACEHOLDERS_REGEX;
8
+ private langs;
8
9
  private entries;
10
+ private currentLang;
9
11
  constructor(i18n: I18n, logger: Logger);
10
12
  add<K extends I18nTranslationKey>(key: K, value: string): Promise<void>;
13
+ availableLangs(): I18nLanguageCode[];
14
+ changeLang(lang: I18nLanguageCode): Promise<void>;
11
15
  init(): Promise<void>;
12
16
  initSync(): void;
13
17
  l(): I18nLanguageCode;
14
18
  t<K extends I18nTranslationKey>(key: K, opts?: I18nManagerTOpts): string;
15
19
  private initCommon;
16
20
  tOrNull<K extends I18nTranslationKey>(key: K, _opts?: I18nManagerTOpts): string | null;
21
+ private current;
17
22
  private replacePlaceholders;
18
23
  }