libmodulor 0.23.0 → 0.25.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.
- package/CHANGELOG.md +34 -0
- package/README.md +154 -2
- package/dist/esm/apps/Helper/src/lib/project.js +6 -6
- package/dist/esm/apps/Helper/src/ucds/TestAppUCD.d.ts +2 -1
- package/dist/esm/apps/Helper/src/ucds/TestAppUCD.js +8 -0
- package/dist/esm/convention.d.ts +3 -0
- package/dist/esm/convention.js +3 -0
- package/dist/esm/dt/DataTypes.d.ts +1 -2
- package/dist/esm/dt/Validation.d.ts +2 -2
- package/dist/esm/dt/base/TBase.d.ts +2 -0
- package/dist/esm/dt/base/TBase.js +3 -0
- package/dist/esm/dt/base/TObject.d.ts +6 -4
- package/dist/esm/dt/base/TObject.js +5 -6
- package/dist/esm/dt/base/TString.d.ts +2 -1
- package/dist/esm/dt/base/TString.js +22 -0
- package/dist/esm/dt/final/TFile.d.ts +13 -4
- package/dist/esm/dt/final/TFile.js +70 -8
- package/dist/esm/dt/final/TFileExtension.d.ts +1 -1
- package/dist/esm/dt/final/TFileMimeType.d.ts +2 -6
- package/dist/esm/dt/final/TFileMimeType.js +0 -6
- package/dist/esm/dt/final/TFilePath.d.ts +7 -0
- package/dist/esm/dt/final/TFilePath.js +5 -1
- package/dist/esm/dt/index.d.ts +1 -1
- package/dist/esm/i18n/WordingManager.d.ts +2 -1
- package/dist/esm/i18n/WordingManager.js +23 -2
- package/dist/esm/i18n/index.d.ts +1 -1
- package/dist/esm/i18n/locales/de.d.ts +2 -0
- package/dist/esm/i18n/locales/de.js +62 -0
- package/dist/esm/i18n/locales/en.js +8 -0
- package/dist/esm/i18n/locales/es.d.ts +2 -0
- package/dist/esm/i18n/locales/es.js +62 -0
- package/dist/esm/i18n/locales/fr.js +8 -0
- package/dist/esm/i18n/types.d.ts +5 -4
- package/dist/esm/index.babel.d.ts +1 -0
- package/dist/esm/index.babel.js +1 -0
- package/dist/esm/index.node-stricli-cli.d.ts +2 -0
- package/dist/esm/index.node-stricli-cli.js +2 -0
- package/dist/esm/index.vite.d.ts +1 -1
- package/dist/esm/index.vite.js +1 -1
- package/dist/esm/index.webpack.d.ts +1 -0
- package/dist/esm/index.webpack.js +1 -0
- package/dist/esm/std/FSManager.d.ts +7 -5
- package/dist/esm/std/FSManager.js +5 -6
- package/dist/esm/std/FormDataBuilder.d.ts +2 -1
- package/dist/esm/std/I18nManager.d.ts +12 -0
- package/dist/esm/std/impl/NodeFSManager.js +4 -3
- package/dist/esm/std/impl/SimpleMapI18nManager.d.ts +6 -1
- package/dist/esm/std/impl/SimpleMapI18nManager.js +41 -12
- package/dist/esm/target/lib/react/StyleContextProvider.d.ts +1 -0
- package/dist/esm/target/lib/react/form.d.ts +1 -1
- package/dist/esm/target/lib/react/form.js +1 -0
- package/dist/esm/target/lib/react/useAction.d.ts +1 -1
- package/dist/esm/target/lib/react/useAction.js +13 -12
- package/dist/esm/target/lib/server/AuthenticationChecker.js +1 -1
- package/dist/esm/target/lib/server/PublicApiKeyChecker.js +1 -1
- package/dist/esm/target/lib/server/ServerRequestHandler.js +2 -2
- package/dist/esm/target/lib/server-express/funcs.js +4 -3
- package/dist/esm/target/lib/server-hono/funcs.js +2 -2
- package/dist/esm/target/lib/server-node/funcs.js +1 -1
- package/dist/esm/target/lib/web/input.d.ts +1 -0
- package/dist/esm/target/lib/web/input.js +5 -1
- package/dist/esm/target/node-stricli-cli/NodeStricliCLIManager.d.ts +12 -0
- package/dist/esm/target/node-stricli-cli/NodeStricliCLIManager.js +118 -0
- package/dist/esm/target/react-native-pure/UCFormField.js +2 -1
- package/dist/esm/target/react-native-pure/UCFormFieldControl.js +6 -4
- package/dist/esm/target/react-native-pure/UCFormFieldErr.d.ts +1 -1
- package/dist/esm/target/react-native-pure/UCFormFieldErr.js +4 -1
- package/dist/esm/target/react-native-pure/UCFormFieldHelp.d.ts +4 -0
- package/dist/esm/target/react-native-pure/UCFormFieldHelp.js +15 -0
- package/dist/esm/target/react-web-pure/UCFormField.js +2 -1
- package/dist/esm/target/react-web-pure/UCFormFieldErr.d.ts +1 -1
- package/dist/esm/target/react-web-pure/UCFormFieldErr.js +4 -1
- package/dist/esm/target/react-web-pure/UCFormFieldHelp.d.ts +4 -0
- package/dist/esm/target/react-web-pure/UCFormFieldHelp.js +14 -0
- package/dist/esm/testing/AppTester.js +4 -5
- package/dist/esm/testing/UCDefASTParser.d.ts +24 -6
- package/dist/esm/testing/impl/SimpleAppDocsEmitter/SimpleAppDocsEmitter.d.ts +7 -0
- package/dist/esm/testing/impl/SimpleAppDocsEmitter/SimpleAppDocsEmitter.js +59 -0
- package/dist/esm/testing/impl/SimpleAppDocsEmitter/markdown.d.ts +2 -0
- package/dist/esm/testing/impl/SimpleAppDocsEmitter/markdown.js +10 -0
- package/dist/esm/testing/impl/SimpleAppDocsEmitter/sequence-diagram.d.ts +2 -0
- package/dist/esm/testing/impl/SimpleAppDocsEmitter/sequence-diagram.js +92 -0
- package/dist/esm/testing/impl/SimpleAppDocsEmitter/tech-summary.d.ts +2 -0
- package/dist/esm/testing/impl/SimpleAppDocsEmitter/tech-summary.js +27 -0
- package/dist/esm/testing/impl/SimpleAppDocsEmitter/uc-summary.d.ts +2 -0
- package/dist/esm/testing/impl/SimpleAppDocsEmitter/uc-summary.js +63 -0
- package/dist/esm/testing/impl/SimpleAppDocsEmitter.js +4 -5
- package/dist/esm/testing/impl/TypeScriptLibUCDefASTParser.js +38 -11
- package/dist/esm/testing/impl/VitestAppTestSuiteRunner.d.ts +1 -1
- package/dist/esm/testing/impl/VitestAppTestSuiteRunner.js +17 -2
- package/dist/esm/testing/impl/newNodeAppTester.js +1 -1
- package/dist/esm/testing/opts.js +1 -1
- package/dist/esm/testing/uc-input.js +5 -2
- package/dist/esm/testing/workers/AppTestSuiteRunner.d.ts +2 -0
- package/dist/esm/testing/workers/UCExecutor.js +1 -1
- package/dist/esm/testing/workers/checkers/AppI18nChecker.d.ts +8 -2
- package/dist/esm/testing/workers/checkers/AppI18nChecker.js +44 -2
- package/dist/esm/testing/workers/checkers/UCDefSourcesChecker.js +12 -12
- package/dist/esm/uc/exec.d.ts +42 -21
- package/dist/esm/uc/exec.js +48 -13
- package/dist/esm/uc/impl/HTTPUCTransporter.js +2 -2
- package/dist/esm/uc/impl/KnexUCDataStore.js +2 -2
- package/dist/esm/uc/index.d.ts +0 -1
- package/dist/esm/uc/index.js +0 -1
- package/dist/esm/uc/input-field.d.ts +6 -4
- package/dist/esm/uc/input-field.js +4 -5
- package/dist/esm/uc/side-effect.d.ts +10 -8
- package/dist/esm/uc/side-effect.js +5 -6
- package/dist/esm/uc/workers/UCExecChecker.js +1 -1
- package/dist/esm/uc/workers/UCInputFilesProcessor.js +3 -3
- package/dist/esm/uc/workers/UCInputValidator.js +2 -1
- package/dist/esm/uc/workers/UCOutputFilesProcessor.js +1 -1
- package/dist/esm/utils/bundling/babel/plugin.d.ts +2 -0
- package/dist/esm/utils/bundling/babel/plugin.js +38 -0
- package/dist/esm/utils/bundling/funcs.d.ts +6 -0
- package/dist/esm/utils/bundling/funcs.js +20 -0
- package/dist/esm/utils/bundling/typescript.d.ts +3 -0
- package/dist/esm/utils/bundling/typescript.js +61 -0
- package/dist/esm/utils/bundling/vite/plugin.d.ts +6 -0
- package/dist/esm/utils/bundling/vite/plugin.js +17 -0
- package/dist/esm/utils/bundling/webpack/loader.d.ts +2 -0
- package/dist/esm/utils/bundling/webpack/loader.js +12 -0
- package/dist/esm/utils/http/HTTPRequestBuilder.js +1 -1
- package/dist/esm/utils/index.d.ts +1 -1
- package/dist/esm/utils/ioc/bindCommon.js +1 -1
- package/dist/esm/utils/terminal/fmt.js +1 -1
- package/dist/esm/utils/types/utility-types.d.ts +4 -0
- package/package.json +36 -12
- package/pnpm-workspace.yaml +1 -4
- package/tsconfig.build.examples.json +8 -0
- package/tsconfig.json +1 -0
- package/vitest.config.ts +16 -0
package/dist/esm/uc/exec.js
CHANGED
|
@@ -1,20 +1,55 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Mode of execution of a use case
|
|
3
|
-
*
|
|
4
|
-
* Unlike all the other enums, the values are lowercased for compatibility reasons.
|
|
5
|
-
* Indeed, this value is persisted in the database so we need to support all existing deployments.
|
|
6
3
|
*/
|
|
7
|
-
export
|
|
8
|
-
(function (UCExecMode) {
|
|
4
|
+
export const UCExecMode = {
|
|
9
5
|
/**
|
|
10
6
|
* The use case has been executed programmatically
|
|
11
7
|
*/
|
|
12
|
-
|
|
8
|
+
AUTO: 'auto',
|
|
13
9
|
/**
|
|
14
10
|
* The use case has been executed explicitly by a user
|
|
15
11
|
*/
|
|
16
|
-
|
|
17
|
-
}
|
|
12
|
+
USER: 'user',
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Result of execution of a use case
|
|
16
|
+
*/
|
|
17
|
+
export const UCExecRes = {
|
|
18
|
+
/**
|
|
19
|
+
* The user aborted the exec (e.g. by not confirming)
|
|
20
|
+
*/
|
|
21
|
+
ABORTED: 'aborted',
|
|
22
|
+
/**
|
|
23
|
+
* The execution failed
|
|
24
|
+
*/
|
|
25
|
+
FAILED: 'failed',
|
|
26
|
+
/**
|
|
27
|
+
* The execution succeeded
|
|
28
|
+
*/
|
|
29
|
+
SUCCEEDED: 'succeeded',
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* State of execution of a use case
|
|
33
|
+
* It applies to a form, but it can be applied and generalized to any other interaction mechanism (i.e. cli, voice...).
|
|
34
|
+
*/
|
|
35
|
+
export const UCExecState = {
|
|
36
|
+
/**
|
|
37
|
+
* An action triggered a change, fields should be disabled
|
|
38
|
+
*/
|
|
39
|
+
CHANGING: 'changing',
|
|
40
|
+
/**
|
|
41
|
+
* It can be touched and filled by the user
|
|
42
|
+
*/
|
|
43
|
+
IDLE: 'idle',
|
|
44
|
+
/**
|
|
45
|
+
* It's initializing in some way, fields should be disabled
|
|
46
|
+
*/
|
|
47
|
+
INITIALIZING: 'initializing',
|
|
48
|
+
/**
|
|
49
|
+
* It's submitting, fields should be disabled and some indicator should show the processing
|
|
50
|
+
*/
|
|
51
|
+
SUBMITTING: 'submitting',
|
|
52
|
+
};
|
|
18
53
|
/**
|
|
19
54
|
* Check whether the execution corresponds to a "disabled" state
|
|
20
55
|
*
|
|
@@ -24,19 +59,19 @@ export var UCExecMode;
|
|
|
24
59
|
* @returns
|
|
25
60
|
*/
|
|
26
61
|
export function ucIsDisabled(execState) {
|
|
27
|
-
return execState !==
|
|
62
|
+
return execState !== UCExecState.IDLE;
|
|
28
63
|
}
|
|
29
64
|
/**
|
|
30
65
|
* Check whether the execution corresponds to a "loading" state
|
|
31
66
|
*
|
|
32
|
-
* Typically, this is used to show a `loading` indicator. Thus, it's `true` when `execState ===
|
|
33
|
-
* Note that it's not for `
|
|
67
|
+
* Typically, this is used to show a `loading` indicator. Thus, it's `true` when `execState === UCExecState.SUBMITTING`.
|
|
68
|
+
* Note that it's not for `UCExecState.CHANGING` or `UCExecState.INITIALIZING` because these are not triggered by the user per sé.
|
|
34
69
|
*
|
|
35
70
|
* @param execState
|
|
36
71
|
* @returns
|
|
37
72
|
*/
|
|
38
73
|
export function ucIsLoading(execState) {
|
|
39
|
-
return execState ===
|
|
74
|
+
return execState === UCExecState.SUBMITTING;
|
|
40
75
|
}
|
|
41
76
|
/**
|
|
42
77
|
* Check whether the execution corresponds to an "error" result
|
|
@@ -45,5 +80,5 @@ export function ucIsLoading(execState) {
|
|
|
45
80
|
* @returns
|
|
46
81
|
*/
|
|
47
82
|
export function ucIsOnErr(execRes) {
|
|
48
|
-
return execRes ===
|
|
83
|
+
return execRes === UCExecRes.FAILED;
|
|
49
84
|
}
|
|
@@ -51,7 +51,7 @@ let HTTPUCTransporter = class HTTPUCTransporter {
|
|
|
51
51
|
break;
|
|
52
52
|
}
|
|
53
53
|
default:
|
|
54
|
-
|
|
54
|
+
publicApiKeyCheckType;
|
|
55
55
|
}
|
|
56
56
|
if (auth) {
|
|
57
57
|
switch (authType) {
|
|
@@ -86,7 +86,7 @@ let HTTPUCTransporter = class HTTPUCTransporter {
|
|
|
86
86
|
break;
|
|
87
87
|
}
|
|
88
88
|
default:
|
|
89
|
-
|
|
89
|
+
authType;
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
const res = await this.httpAPICaller.exec({
|
|
@@ -112,7 +112,7 @@ let KnexUCDataStore = class KnexUCDataStore {
|
|
|
112
112
|
case 'sqlite3':
|
|
113
113
|
return [];
|
|
114
114
|
default:
|
|
115
|
-
(
|
|
115
|
+
(type);
|
|
116
116
|
return [];
|
|
117
117
|
}
|
|
118
118
|
}
|
|
@@ -156,7 +156,7 @@ let KnexUCDataStore = class KnexUCDataStore {
|
|
|
156
156
|
this.fillConfigForSQLite3();
|
|
157
157
|
break;
|
|
158
158
|
default:
|
|
159
|
-
(
|
|
159
|
+
(type);
|
|
160
160
|
}
|
|
161
161
|
}
|
|
162
162
|
fillConfigForPG() {
|
package/dist/esm/uc/index.d.ts
CHANGED
|
@@ -48,7 +48,6 @@ export * from './utils/fmtVal.js';
|
|
|
48
48
|
export * from './utils/recIs.js';
|
|
49
49
|
export * from './utils/rInput.js';
|
|
50
50
|
export * from './utils/rVal.js';
|
|
51
|
-
export * from './utils/stripUCDLifecycleServer.js';
|
|
52
51
|
export * from './utils/ucHTTPContract.js';
|
|
53
52
|
export * from './utils/ucMountingPoint.js';
|
|
54
53
|
export * from './value.js';
|
package/dist/esm/uc/index.js
CHANGED
|
@@ -48,7 +48,6 @@ export * from './utils/fmtVal.js';
|
|
|
48
48
|
export * from './utils/recIs.js';
|
|
49
49
|
export * from './utils/rInput.js';
|
|
50
50
|
export * from './utils/rVal.js';
|
|
51
|
-
export * from './utils/stripUCDLifecycleServer.js';
|
|
52
51
|
export * from './utils/ucHTTPContract.js';
|
|
53
52
|
export * from './utils/ucMountingPoint.js';
|
|
54
53
|
export * from './value.js';
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import type { DataType, TBase, UIntQuantity } from '../dt/index.js';
|
|
2
|
+
import type { EnumOf } from '../utils/index.js';
|
|
2
3
|
import type { UCFieldKey } from './def.js';
|
|
3
4
|
import type { Value } from './value.js';
|
|
4
|
-
export declare
|
|
5
|
+
export declare const UCInputFieldFillingMode: {
|
|
5
6
|
/**
|
|
6
7
|
* Set programmatically on behalf of the user (e.g. a foreign key id for a given object)
|
|
7
8
|
*/
|
|
8
|
-
AUTO_PRE
|
|
9
|
+
readonly AUTO_PRE: "AUTO_PRE";
|
|
9
10
|
/**
|
|
10
11
|
* Set manually by the user (e.g. a form field, a cli flag, etc.)
|
|
11
12
|
*/
|
|
12
|
-
MANUAL
|
|
13
|
-
}
|
|
13
|
+
readonly MANUAL: "MANUAL";
|
|
14
|
+
};
|
|
15
|
+
export type UCInputFieldFillingMode = EnumOf<typeof UCInputFieldFillingMode>;
|
|
14
16
|
export interface UCInputFieldDefCardinality {
|
|
15
17
|
max?: UIntQuantity;
|
|
16
18
|
min?: UIntQuantity;
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
export
|
|
2
|
-
(function (UCInputFieldFillingMode) {
|
|
1
|
+
export const UCInputFieldFillingMode = {
|
|
3
2
|
/**
|
|
4
3
|
* Set programmatically on behalf of the user (e.g. a foreign key id for a given object)
|
|
5
4
|
*/
|
|
6
|
-
|
|
5
|
+
AUTO_PRE: 'AUTO_PRE',
|
|
7
6
|
/**
|
|
8
7
|
* Set manually by the user (e.g. a form field, a cli flag, etc.)
|
|
9
8
|
*/
|
|
10
|
-
|
|
11
|
-
}
|
|
9
|
+
MANUAL: 'MANUAL',
|
|
10
|
+
};
|
|
12
11
|
export function ucifExamples(def) {
|
|
13
12
|
const { type } = def;
|
|
14
13
|
const examples = type.getExamples();
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import type { EnumOf } from '../utils/index.js';
|
|
2
|
+
export declare const UCOutputSideEffectType: {
|
|
2
3
|
/**
|
|
3
4
|
* Trigger a clearing of the auth on the calling system (e.g. `SignOut`).
|
|
4
5
|
*/
|
|
5
|
-
CLEAR_AUTH
|
|
6
|
+
readonly CLEAR_AUTH: "CLEAR_AUTH";
|
|
6
7
|
/**
|
|
7
8
|
* Trigger a redirect on the calling system (e.g. after the final round of an OAuth1 flow)
|
|
8
9
|
*
|
|
@@ -11,18 +12,19 @@ export declare enum UCOutputSideEffectType {
|
|
|
11
12
|
*
|
|
12
13
|
* It expects a field `redirect: URL` in `output.parts._0.items[0]`.
|
|
13
14
|
*/
|
|
14
|
-
REDIRECT
|
|
15
|
+
readonly REDIRECT: "REDIRECT";
|
|
15
16
|
/**
|
|
16
17
|
* Trigger a setting of the auth on the calling system (e.g. `SignIn` / `SignUp`).
|
|
17
18
|
*
|
|
18
19
|
* It expects a field `jwt: JWT` in `output.parts._0.items[0]`.
|
|
19
20
|
*/
|
|
20
|
-
SET_AUTH
|
|
21
|
-
}
|
|
21
|
+
readonly SET_AUTH: "SET_AUTH";
|
|
22
|
+
};
|
|
23
|
+
export type UCOutputSideEffectType = EnumOf<typeof UCOutputSideEffectType>;
|
|
22
24
|
export type UCOutputSideEffect = {
|
|
23
|
-
type: UCOutputSideEffectType.CLEAR_AUTH;
|
|
25
|
+
type: typeof UCOutputSideEffectType.CLEAR_AUTH;
|
|
24
26
|
} | {
|
|
25
|
-
type: UCOutputSideEffectType.REDIRECT;
|
|
27
|
+
type: typeof UCOutputSideEffectType.REDIRECT;
|
|
26
28
|
} | {
|
|
27
|
-
type: UCOutputSideEffectType.SET_AUTH;
|
|
29
|
+
type: typeof UCOutputSideEffectType.SET_AUTH;
|
|
28
30
|
};
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
export
|
|
2
|
-
(function (UCOutputSideEffectType) {
|
|
1
|
+
export const UCOutputSideEffectType = {
|
|
3
2
|
/**
|
|
4
3
|
* Trigger a clearing of the auth on the calling system (e.g. `SignOut`).
|
|
5
4
|
*/
|
|
6
|
-
|
|
5
|
+
CLEAR_AUTH: 'CLEAR_AUTH',
|
|
7
6
|
/**
|
|
8
7
|
* Trigger a redirect on the calling system (e.g. after the final round of an OAuth1 flow)
|
|
9
8
|
*
|
|
@@ -12,11 +11,11 @@ export var UCOutputSideEffectType;
|
|
|
12
11
|
*
|
|
13
12
|
* It expects a field `redirect: URL` in `output.parts._0.items[0]`.
|
|
14
13
|
*/
|
|
15
|
-
|
|
14
|
+
REDIRECT: 'REDIRECT',
|
|
16
15
|
/**
|
|
17
16
|
* Trigger a setting of the auth on the calling system (e.g. `SignIn` / `SignUp`).
|
|
18
17
|
*
|
|
19
18
|
* It expects a field `jwt: JWT` in `output.parts._0.items[0]`.
|
|
20
19
|
*/
|
|
21
|
-
|
|
22
|
-
}
|
|
20
|
+
SET_AUTH: 'SET_AUTH',
|
|
21
|
+
};
|
|
@@ -66,9 +66,9 @@ let UCInputFilesProcessor = class UCInputFilesProcessor {
|
|
|
66
66
|
await this.fsManager.touch(destPath, await file.arrayBuffer());
|
|
67
67
|
}
|
|
68
68
|
else {
|
|
69
|
-
const {
|
|
70
|
-
await this.fsManager.cp(
|
|
71
|
-
await this.fsManager.rm(
|
|
69
|
+
const { uri } = file;
|
|
70
|
+
await this.fsManager.cp(uri, destPath);
|
|
71
|
+
await this.fsManager.rm(uri);
|
|
72
72
|
}
|
|
73
73
|
return fileNameRef;
|
|
74
74
|
}
|
|
@@ -34,7 +34,8 @@ let UCInputValidator = class UCInputValidator {
|
|
|
34
34
|
let message = this.i18nManager.t(key, { vars: { expected } });
|
|
35
35
|
if (field) {
|
|
36
36
|
const { label } = this.wordingManager.ucif(field);
|
|
37
|
-
message = `${
|
|
37
|
+
message = `${message.charAt(0).toLowerCase()}${message.slice(1)}`;
|
|
38
|
+
message = `${label} ${message}`.trim();
|
|
38
39
|
}
|
|
39
40
|
throw new IllegalArgumentError(message);
|
|
40
41
|
}
|
|
@@ -44,7 +44,7 @@ let UCOutputFilesProcessor = class UCOutputFilesProcessor {
|
|
|
44
44
|
filePath = this.fsManager.path(this.s().uc_files_directory_path, fileName); // => /path/to/files/20230110143732-155eb8d3-9af5-430e-b856-248007859df1.jpg
|
|
45
45
|
}
|
|
46
46
|
else {
|
|
47
|
-
filePath = fileNameRef.
|
|
47
|
+
filePath = fileNameRef.uri;
|
|
48
48
|
}
|
|
49
49
|
if (keepOnlyFileName) {
|
|
50
50
|
const { base } = await this.fsManager.info(filePath);
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { types as t } from '@babel/core';
|
|
2
|
+
import { UC_LIFECYCLE_PROP_NAME, UC_LIFECYCLE_SERVER_PROP_NAME, } from '../../../convention.js';
|
|
3
|
+
import { isFileEligible } from '../funcs.js';
|
|
4
|
+
// Using `PluginObj` instead of `satisfies PluginObj`.
|
|
5
|
+
// Otherwise TypeScript is not happy and triggers a TS2209.
|
|
6
|
+
export const Plugin = {
|
|
7
|
+
name: 'libmodulor-plugin',
|
|
8
|
+
visitor: {
|
|
9
|
+
ObjectExpression(path, state) {
|
|
10
|
+
if (!isFileEligible(state.filename, ['js', 'ts'])) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const lifecycle = findLifecycleProp(path);
|
|
14
|
+
if (!lifecycle) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const lifecycleObj = lifecycle.value;
|
|
18
|
+
const server = findServerProp(lifecycleObj);
|
|
19
|
+
if (!server) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
server.value = t.booleanLiteral(true);
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
function findLifecycleProp(path) {
|
|
27
|
+
return path.node.properties.find((p) => t.isObjectProperty(p) &&
|
|
28
|
+
t.isIdentifier(p.key, {
|
|
29
|
+
name: UC_LIFECYCLE_PROP_NAME,
|
|
30
|
+
}) &&
|
|
31
|
+
t.isObjectExpression(p.value));
|
|
32
|
+
}
|
|
33
|
+
function findServerProp(lifecycleObj) {
|
|
34
|
+
return lifecycleObj.properties.find((p) => t.isObjectProperty(p) &&
|
|
35
|
+
t.isIdentifier(p.key, {
|
|
36
|
+
name: UC_LIFECYCLE_SERVER_PROP_NAME,
|
|
37
|
+
}));
|
|
38
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { FileName } from '../../dt/index.js';
|
|
2
|
+
export type InputCode = string;
|
|
3
|
+
export type OutputCode = string;
|
|
4
|
+
export type StrippableFileExtension = 'js' | 'ts';
|
|
5
|
+
export declare function isFileEligible(fileName: FileName | undefined, exts: StrippableFileExtension[]): boolean;
|
|
6
|
+
export declare function assertTransformedCorrectly(transformed: OutputCode, fileName: FileName | undefined): void;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { UC_DEF_SUFFIX } from '../../convention.js';
|
|
2
|
+
export function isFileEligible(fileName, exts) {
|
|
3
|
+
if (!fileName) {
|
|
4
|
+
return false;
|
|
5
|
+
}
|
|
6
|
+
for (const ext of exts) {
|
|
7
|
+
if (fileName.endsWith(`${UC_DEF_SUFFIX}.${ext}`)) {
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
export function assertTransformedCorrectly(transformed, fileName) {
|
|
14
|
+
const match = transformed.match(/server: (.*)ServerMain/g);
|
|
15
|
+
if (match !== null) {
|
|
16
|
+
// biome-ignore lint/suspicious/noConsole: we want it
|
|
17
|
+
console.warn(transformed);
|
|
18
|
+
throw new Error(`[WARNING] The following file might not have been transformed correctly : ${fileName} (see transformed above)`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
import { UC_DEF_SUFFIX, UC_LIFECYCLE_PROP_NAME, UC_LIFECYCLE_SERVER_PROP_NAME, } from '../../convention.js';
|
|
3
|
+
export function transform(code, fileName) {
|
|
4
|
+
const sourceFile = ts.createSourceFile(fileName, code, ts.ScriptTarget.ESNext);
|
|
5
|
+
const result = ts.transform(sourceFile, [transformer()]);
|
|
6
|
+
const transformed = result.transformed[0];
|
|
7
|
+
if (!transformed) {
|
|
8
|
+
throw new Error(`Could not transform file : ${fileName}`);
|
|
9
|
+
}
|
|
10
|
+
const printer = ts.createPrinter();
|
|
11
|
+
return printer.printFile(transformed);
|
|
12
|
+
}
|
|
13
|
+
function transformer() {
|
|
14
|
+
return (context) => {
|
|
15
|
+
return (sourceFile) => {
|
|
16
|
+
const { factory } = context;
|
|
17
|
+
function visit(node) {
|
|
18
|
+
if (!isUCDDeclaration(sourceFile, node)) {
|
|
19
|
+
return ts.visitEachChild(node, visit, context);
|
|
20
|
+
}
|
|
21
|
+
const rootObj = node.initializer;
|
|
22
|
+
const lifecycle = findLifecycleProp(sourceFile, rootObj);
|
|
23
|
+
if (!lifecycle) {
|
|
24
|
+
return ts.visitEachChild(node, visit, context);
|
|
25
|
+
}
|
|
26
|
+
const lifecycleObj = lifecycle.initializer;
|
|
27
|
+
const server = findServerProp(sourceFile, lifecycleObj);
|
|
28
|
+
if (!server) {
|
|
29
|
+
return ts.visitEachChild(node, visit, context);
|
|
30
|
+
}
|
|
31
|
+
// Nodes are immutable so we need to re-create the whole tree
|
|
32
|
+
const newServer = factory.updatePropertyAssignment(server, server.name, factory.createTrue());
|
|
33
|
+
const newLifecycleObj = factory.updateObjectLiteralExpression(lifecycleObj, lifecycleObj.properties.map((p) => p === server ? newServer : p));
|
|
34
|
+
const newLifecycle = factory.updatePropertyAssignment(lifecycle, lifecycle.name, newLifecycleObj);
|
|
35
|
+
const newRootObj = factory.updateObjectLiteralExpression(rootObj, rootObj.properties.map((p) => p === lifecycle ? newLifecycle : p));
|
|
36
|
+
return factory.updateVariableDeclaration(node, node.name, node.exclamationToken, node.type, newRootObj);
|
|
37
|
+
}
|
|
38
|
+
return ts.visitNode(sourceFile, visit);
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function isUCDDeclaration(sourceFile, node) {
|
|
43
|
+
if (!ts.isVariableDeclaration(node)) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
const name = node.name.getText(sourceFile);
|
|
47
|
+
return (name.endsWith(UC_DEF_SUFFIX) &&
|
|
48
|
+
!!node.initializer &&
|
|
49
|
+
ts.isObjectLiteralExpression(node.initializer));
|
|
50
|
+
}
|
|
51
|
+
function findLifecycleProp(sourceFile, rootObj) {
|
|
52
|
+
return rootObj.properties.find((p) => ts.isPropertyAssignment(p) &&
|
|
53
|
+
ts.isIdentifier(p.name) &&
|
|
54
|
+
p.name.getText(sourceFile) === UC_LIFECYCLE_PROP_NAME &&
|
|
55
|
+
ts.isObjectLiteralExpression(p.initializer));
|
|
56
|
+
}
|
|
57
|
+
function findServerProp(sourceFile, lifecycleObj) {
|
|
58
|
+
return lifecycleObj.properties.find((p) => ts.isPropertyAssignment(p) &&
|
|
59
|
+
ts.isIdentifier(p.name) &&
|
|
60
|
+
p.name.getText(sourceFile) === UC_LIFECYCLE_SERVER_PROP_NAME);
|
|
61
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { assertTransformedCorrectly, isFileEligible } from '../funcs.js';
|
|
2
|
+
import { transform } from '../typescript.js';
|
|
3
|
+
export const Plugin = {
|
|
4
|
+
name: 'libmodulor-plugin',
|
|
5
|
+
transform: (code, id) => {
|
|
6
|
+
if (!isFileEligible(id, ['ts'])) {
|
|
7
|
+
return {
|
|
8
|
+
code,
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
const transformed = transform(code, id);
|
|
12
|
+
assertTransformedCorrectly(transformed, id);
|
|
13
|
+
return {
|
|
14
|
+
code: transformed,
|
|
15
|
+
};
|
|
16
|
+
},
|
|
17
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { assertTransformedCorrectly, isFileEligible, } from '../funcs.js';
|
|
2
|
+
import { transform } from '../typescript.js';
|
|
3
|
+
export default function loader(source) {
|
|
4
|
+
// @ts-expect-error : magically made available by Webpack at execution
|
|
5
|
+
const fileName = this.resourcePath;
|
|
6
|
+
if (!isFileEligible(fileName, ['ts'])) {
|
|
7
|
+
return source;
|
|
8
|
+
}
|
|
9
|
+
const transformed = transform(source, fileName);
|
|
10
|
+
assertTransformedCorrectly(transformed, fileName);
|
|
11
|
+
return transformed;
|
|
12
|
+
}
|
|
@@ -23,4 +23,4 @@ export { humanize } from './strings/humanize.js';
|
|
|
23
23
|
export { truncate } from './strings/truncate.js';
|
|
24
24
|
export { fmtBold, fmtCommand, fmtPadEndFor, fmtSection, } from './terminal/fmt.js';
|
|
25
25
|
export { assertIsDefined, isBlank, range, sample, tupleOf, } from './types/funcs.js';
|
|
26
|
-
export type { ExtractStrict, RecursiveNonNullable, StringKeys, } from './types/utility-types.js';
|
|
26
|
+
export type { EnumOf, ExtractStrict, RecursiveNonNullable, StringKeys, } from './types/utility-types.js';
|
|
@@ -49,7 +49,7 @@ export function bindCommon(container, settingsFunc) {
|
|
|
49
49
|
.bind('I18nManager')
|
|
50
50
|
.to(SimpleMapI18nManager)
|
|
51
51
|
.inSingletonScope();
|
|
52
|
-
container.bind('I18n').toConstantValue({});
|
|
52
|
+
container.bind('I18n').toConstantValue({ en: {} });
|
|
53
53
|
container.bind('Logger').to(ConsoleLogger);
|
|
54
54
|
container.bind('Settings').toConstantValue(settings);
|
|
55
55
|
container
|
|
@@ -5,7 +5,7 @@ export function fmtCommand(cmd, details, padEnd) {
|
|
|
5
5
|
return ` ${cmd.padEnd(padEnd)}${details ?? ''}`;
|
|
6
6
|
}
|
|
7
7
|
export function fmtPadEndFor(s) {
|
|
8
|
-
const longest = s.sort((a, b) => a.length - b.length).reverse()[0];
|
|
8
|
+
const longest = [...s].sort((a, b) => a.length - b.length).reverse()[0];
|
|
9
9
|
return (longest?.length ?? 1) + 10;
|
|
10
10
|
}
|
|
11
11
|
export function fmtSection(s) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "libmodulor",
|
|
3
3
|
"description": "A TypeScript library to create platform-agnostic applications",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.25.0",
|
|
5
5
|
"license": "LGPL-3.0",
|
|
6
6
|
"author": "Chafik H'nini <chafik.hnini@gmail.com>",
|
|
7
7
|
"homepage": "https://libmodulor.c100k.eu",
|
|
@@ -23,12 +23,21 @@
|
|
|
23
23
|
".": {
|
|
24
24
|
"import": "./dist/esm/index.js"
|
|
25
25
|
},
|
|
26
|
+
"./babel": {
|
|
27
|
+
"import": "./dist/esm/index.babel.js"
|
|
28
|
+
},
|
|
26
29
|
"./cloudflare-worker-hono": {
|
|
27
30
|
"import": "./dist/esm/index.cloudflare-worker-hono.js"
|
|
28
31
|
},
|
|
32
|
+
"./locales/de": {
|
|
33
|
+
"import": "./dist/esm/i18n/locales/de.js"
|
|
34
|
+
},
|
|
29
35
|
"./locales/en": {
|
|
30
36
|
"import": "./dist/esm/i18n/locales/en.js"
|
|
31
37
|
},
|
|
38
|
+
"./locales/es": {
|
|
39
|
+
"import": "./dist/esm/i18n/locales/es.js"
|
|
40
|
+
},
|
|
32
41
|
"./locales/fr": {
|
|
33
42
|
"import": "./dist/esm/i18n/locales/fr.js"
|
|
34
43
|
},
|
|
@@ -44,6 +53,9 @@
|
|
|
44
53
|
"./node-mcp": {
|
|
45
54
|
"import": "./dist/esm/index.node-mcp.js"
|
|
46
55
|
},
|
|
56
|
+
"./node-stricli-cli": {
|
|
57
|
+
"import": "./dist/esm/index.node-stricli-cli.js"
|
|
58
|
+
},
|
|
47
59
|
"./node-test": {
|
|
48
60
|
"import": "./dist/esm/index.node-test.js"
|
|
49
61
|
},
|
|
@@ -73,6 +85,9 @@
|
|
|
73
85
|
},
|
|
74
86
|
"./web": {
|
|
75
87
|
"import": "./dist/esm/index.web.js"
|
|
88
|
+
},
|
|
89
|
+
"./webpack": {
|
|
90
|
+
"import": "./dist/esm/index.webpack.js"
|
|
76
91
|
}
|
|
77
92
|
},
|
|
78
93
|
"bin": "./dist/esm/products/Helper/index.js",
|
|
@@ -81,26 +96,35 @@
|
|
|
81
96
|
"lint:ci": "biome check"
|
|
82
97
|
},
|
|
83
98
|
"devDependencies": {
|
|
84
|
-
"@biomejs/biome": "^2.3.
|
|
99
|
+
"@biomejs/biome": "^2.3.10",
|
|
100
|
+
"@react-native-community/slider": "^4.5.7",
|
|
101
|
+
"@types/react": "^19.2.7",
|
|
102
|
+
"@types/react-dom": "^19.2.3",
|
|
103
|
+
"babel-plugin-parameter-decorator": "^1.0.16",
|
|
104
|
+
"babel-plugin-transform-typescript-metadata": "^0.3.2",
|
|
105
|
+
"expo": "^54.0.29",
|
|
106
|
+
"expo-document-picker": "~14.0.8",
|
|
107
|
+
"expo-image-picker": "^17.0.10",
|
|
108
|
+
"wrangler": "^4.55.0"
|
|
85
109
|
},
|
|
86
110
|
"peerDependencies": {
|
|
87
|
-
"@hono/node-server": "^1.19.
|
|
88
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
111
|
+
"@hono/node-server": "^1.19.7",
|
|
112
|
+
"@modelcontextprotocol/sdk": "^1.25.1",
|
|
89
113
|
"@stricli/core": "^1.2.4",
|
|
90
114
|
"buffer": "^6.0.3",
|
|
91
115
|
"cookie-parser": "^1.4.7",
|
|
92
|
-
"express": "^5.1
|
|
116
|
+
"express": "^5.2.1",
|
|
93
117
|
"express-fileupload": "^1.5.2",
|
|
94
|
-
"fast-check": "^4.
|
|
118
|
+
"fast-check": "^4.4.0",
|
|
95
119
|
"helmet": "^8.1.0",
|
|
96
|
-
"hono": "^4.
|
|
97
|
-
"inversify": "^7.10.
|
|
98
|
-
"jose": "^6.1.
|
|
120
|
+
"hono": "^4.11.1",
|
|
121
|
+
"inversify": "^7.10.7",
|
|
122
|
+
"jose": "^6.1.3",
|
|
99
123
|
"knex": "^3.1.0",
|
|
100
|
-
"next": "^15.5.
|
|
124
|
+
"next": "^15.5.9",
|
|
101
125
|
"pg": "^8.16.3",
|
|
102
|
-
"react": "^19.2.
|
|
103
|
-
"react-dom": "^19.2.
|
|
126
|
+
"react": "^19.2.3",
|
|
127
|
+
"react-dom": "^19.2.3",
|
|
104
128
|
"react-native": "^0.81.5",
|
|
105
129
|
"reflect-metadata": "^0.2.2",
|
|
106
130
|
"sqlite3": "^5.1.7",
|
package/pnpm-workspace.yaml
CHANGED