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.
- package/CHANGELOG.md +21 -0
- package/README.md +154 -2
- package/dist/esm/apps/Helper/src/lib/project.js +4 -4
- 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/base/TObject.js +1 -1
- 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 +54 -0
- package/dist/esm/i18n/locales/es.d.ts +2 -0
- package/dist/esm/i18n/locales/es.js +54 -0
- package/dist/esm/i18n/types.d.ts +3 -2
- 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.react.d.ts +1 -1
- package/dist/esm/index.react.js +1 -1
- 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/I18nManager.d.ts +12 -0
- package/dist/esm/std/JWTManager.d.ts +16 -1
- package/dist/esm/std/impl/JoseJWTManager.d.ts +3 -2
- package/dist/esm/std/impl/JoseJWTManager.js +4 -0
- package/dist/esm/std/impl/NodeFSManager.js +1 -1
- package/dist/esm/std/impl/SimpleHTTPAPICaller.js +4 -2
- package/dist/esm/std/impl/SimpleMapI18nManager.d.ts +6 -1
- package/dist/esm/std/impl/SimpleMapI18nManager.js +41 -12
- package/dist/esm/target/lib/client/consts.js +1 -0
- package/dist/esm/target/lib/react/UCPanel.d.ts +7 -8
- package/dist/esm/target/lib/react/useUC.js +11 -1
- 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/ServerManager.d.ts +1 -0
- package/dist/esm/target/lib/server/ServerRequestHandler.js +2 -2
- package/dist/esm/target/lib/server/consts.js +1 -0
- package/dist/esm/target/lib/server-express/funcs.js +5 -4
- package/dist/esm/target/lib/server-hono/funcs.js +2 -2
- package/dist/esm/target/lib/server-node/funcs.d.ts +2 -2
- package/dist/esm/target/lib/server-node/funcs.js +11 -1
- package/dist/esm/target/lib/server-node/types.d.ts +1 -0
- package/dist/esm/target/node-express-server/NodeExpressServerManager.d.ts +2 -2
- package/dist/esm/target/node-express-server/NodeExpressServerManager.js +2 -1
- package/dist/esm/target/node-hono-server/NodeHonoServerManager.d.ts +2 -2
- package/dist/esm/target/node-hono-server/NodeHonoServerManager.js +2 -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/testing/AppTester.js +4 -5
- package/dist/esm/testing/UCDefASTParser.d.ts +24 -6
- 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 +3 -2
- package/dist/esm/testing/opts.js +1 -1
- 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/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/workers/UCExecChecker.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/http/NDJSONStreamManager.d.ts +2 -1
- package/dist/esm/utils/http/NDJSONStreamManager.js +4 -1
- package/dist/esm/utils/http/SSEStreamManager.d.ts +2 -1
- package/dist/esm/utils/http/SSEStreamManager.js +4 -1
- package/dist/esm/utils/ioc/bindCommon.js +1 -1
- package/dist/esm/utils/terminal/fmt.js +1 -1
- package/package.json +32 -10
- package/pnpm-workspace.yaml +1 -4
- package/tsconfig.build.examples.json +8 -0
- package/tsconfig.json +1 -0
- package/vitest.config.ts +16 -0
|
@@ -12,20 +12,34 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
12
12
|
};
|
|
13
13
|
var SimpleMapI18nManager_1;
|
|
14
14
|
import { inject, injectable } from 'inversify';
|
|
15
|
-
import { I18N_DEFAULT_LANG, } from '../../i18n/index.js';
|
|
16
15
|
let SimpleMapI18nManager = class SimpleMapI18nManager {
|
|
17
16
|
static { SimpleMapI18nManager_1 = this; }
|
|
18
17
|
i18n;
|
|
19
18
|
logger;
|
|
20
19
|
static PLACEHOLDERS_REGEX = /{{([A-Z-a-z0-9]+)}}/g; // Note the 'g' so it can be used with `matchAll`
|
|
20
|
+
langs;
|
|
21
21
|
entries;
|
|
22
|
+
currentLang;
|
|
22
23
|
constructor(i18n, logger) {
|
|
23
24
|
this.i18n = i18n;
|
|
24
25
|
this.logger = logger;
|
|
26
|
+
this.langs = Object.keys(i18n);
|
|
27
|
+
if (this.langs.length === 0) {
|
|
28
|
+
throw new Error('I18n must define at least one lang');
|
|
29
|
+
}
|
|
25
30
|
this.entries = new Map();
|
|
31
|
+
// biome-ignore lint/style/noNonNullAssertion: we want it
|
|
32
|
+
this.currentLang = this.langs[0];
|
|
26
33
|
}
|
|
27
34
|
async add(key, value) {
|
|
28
|
-
this.
|
|
35
|
+
this.current().set(key, value);
|
|
36
|
+
}
|
|
37
|
+
availableLangs() {
|
|
38
|
+
return this.langs;
|
|
39
|
+
}
|
|
40
|
+
async changeLang(lang) {
|
|
41
|
+
this.currentLang = lang;
|
|
42
|
+
this.initCommon();
|
|
29
43
|
}
|
|
30
44
|
async init() {
|
|
31
45
|
this.initCommon();
|
|
@@ -34,10 +48,10 @@ let SimpleMapI18nManager = class SimpleMapI18nManager {
|
|
|
34
48
|
this.initCommon();
|
|
35
49
|
}
|
|
36
50
|
l() {
|
|
37
|
-
return
|
|
51
|
+
return this.currentLang;
|
|
38
52
|
}
|
|
39
53
|
t(key, opts) {
|
|
40
|
-
const v = this.
|
|
54
|
+
const v = this.current().get(key);
|
|
41
55
|
if (v) {
|
|
42
56
|
return this.replacePlaceholders(v, opts);
|
|
43
57
|
}
|
|
@@ -47,17 +61,32 @@ let SimpleMapI18nManager = class SimpleMapI18nManager {
|
|
|
47
61
|
return key; // Mimic the behavior of some common libraries like i18next
|
|
48
62
|
}
|
|
49
63
|
initCommon() {
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
64
|
+
for (const lang of this.langs) {
|
|
65
|
+
const translations = this.i18n[lang];
|
|
66
|
+
this.logger.trace('Initializing I18nManager', {
|
|
67
|
+
lang,
|
|
68
|
+
translations,
|
|
69
|
+
});
|
|
70
|
+
if (!translations) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (!this.entries.has(lang)) {
|
|
74
|
+
this.entries.set(lang, new Map());
|
|
75
|
+
}
|
|
76
|
+
for (const [k, v] of Object.entries(translations)) {
|
|
77
|
+
this.entries.get(lang)?.set(k, v);
|
|
78
|
+
}
|
|
57
79
|
}
|
|
58
80
|
}
|
|
59
81
|
tOrNull(key, _opts) {
|
|
60
|
-
return this.
|
|
82
|
+
return this.current().get(key) || null;
|
|
83
|
+
}
|
|
84
|
+
current() {
|
|
85
|
+
const entry = this.entries.get(this.currentLang);
|
|
86
|
+
if (!entry) {
|
|
87
|
+
throw new Error(`I18nManager must contain an entry for lang : ${this.currentLang}`);
|
|
88
|
+
}
|
|
89
|
+
return entry;
|
|
61
90
|
}
|
|
62
91
|
replacePlaceholders(v, opts) {
|
|
63
92
|
// DO NOT USE THIS IN PRODUCTION
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* @see TARGET_DEFAULT_SERVER_MANAGER_SETTINGS
|
|
3
3
|
*/
|
|
4
4
|
export const TARGET_DEFAULT_SERVER_CLIENT_MANAGER_SETTINGS = {
|
|
5
|
+
server_cookies_name_auth: 'auth',
|
|
5
6
|
server_public_api_key: 'PublicApiKeyToBeChangedWhenDeploying',
|
|
6
7
|
server_public_api_key_header_name: 'X-API-Key',
|
|
7
8
|
server_public_url: 'http://localhost:7443',
|
|
@@ -6,17 +6,16 @@ import type { RenderUCForm } from './form.js';
|
|
|
6
6
|
import type { RenderUCAutoExecLoader } from './loader.js';
|
|
7
7
|
import type { UCPanelCtx, UCPanelOnDone, UCPanelOnError, UCPanelOnInit, UCPanelOnStartSubmitting } from './panel.js';
|
|
8
8
|
import type { RenderUCExecTouchable } from './touchable.js';
|
|
9
|
-
type Props<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined> = Pick<UCPanelCtx<I, OPI0, OPI1>, 'clearAfterExec' | 'uc'> & {
|
|
10
|
-
autoExec?: boolean;
|
|
11
|
-
onDone?: UCPanelOnDone<I, OPI0, OPI1
|
|
12
|
-
onInit?: UCPanelOnInit<I, OPI0, OPI1
|
|
13
|
-
onError?: UCPanelOnError;
|
|
14
|
-
onStartSubmitting?: UCPanelOnStartSubmitting;
|
|
9
|
+
export type Props<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined> = Pick<UCPanelCtx<I, OPI0, OPI1>, 'clearAfterExec' | 'uc'> & {
|
|
10
|
+
autoExec?: boolean | undefined;
|
|
11
|
+
onDone?: UCPanelOnDone<I, OPI0, OPI1> | undefined;
|
|
12
|
+
onInit?: UCPanelOnInit<I, OPI0, OPI1> | undefined;
|
|
13
|
+
onError?: UCPanelOnError | undefined;
|
|
14
|
+
onStartSubmitting?: UCPanelOnStartSubmitting | undefined;
|
|
15
15
|
renderAutoExecLoader: RenderUCAutoExecLoader;
|
|
16
16
|
renderExecTouchable: RenderUCExecTouchable<I, OPI0, OPI1>;
|
|
17
17
|
renderForm: RenderUCForm<I, OPI0, OPI1>;
|
|
18
|
-
sleepInMs?: UIntDuration;
|
|
18
|
+
sleepInMs?: UIntDuration | undefined;
|
|
19
19
|
stream?: StreamConfig<UCOutputReader<I, OPI0, OPI1>> | undefined;
|
|
20
20
|
};
|
|
21
21
|
export declare function UCPanel<I extends UCInput | undefined = undefined, OPI0 extends UCOPIBase | undefined = undefined, OPI1 extends UCOPIBase | undefined = undefined>({ autoExec, clearAfterExec, onDone, onError, onInit, onStartSubmitting, renderAutoExecLoader, renderForm, renderExecTouchable, sleepInMs, stream, uc, }: Props<I, OPI0, OPI1>): ReactElement;
|
|
22
|
-
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useState } from 'react';
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
2
|
import { UC, } from '../../../uc/index.js';
|
|
3
3
|
/**
|
|
4
4
|
* This hook provides utilities to init a use case and perform actions on it in a React way
|
|
@@ -21,6 +21,16 @@ export function useUC(appManifest, def, auth, opts) {
|
|
|
21
21
|
}
|
|
22
22
|
return v;
|
|
23
23
|
});
|
|
24
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies(appManifest): avoid infinite re-rendering
|
|
25
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies(def): avoid infinite re-rendering
|
|
26
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies(opts?.fillWith): avoid infinite re-rendering
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
const v = new UC(appManifest, def, auth);
|
|
29
|
+
if (opts?.fillWith) {
|
|
30
|
+
v.fill(opts?.fillWith);
|
|
31
|
+
}
|
|
32
|
+
setUC(v);
|
|
33
|
+
}, [auth]);
|
|
24
34
|
/**
|
|
25
35
|
* Get a new `UC` based on the initial one
|
|
26
36
|
* @param i
|
|
@@ -27,6 +27,7 @@ export interface ServerManagerSettings extends ServerManagerAuthSettings, Settin
|
|
|
27
27
|
server_ssl_fullchain_path: FilePath | null;
|
|
28
28
|
server_ssl_key_path: FilePath | null;
|
|
29
29
|
server_static_dir_path: DirPath | null;
|
|
30
|
+
server_stop_mode: 'aggressive' | 'patient';
|
|
30
31
|
server_tmp_path: FilePath;
|
|
31
32
|
}
|
|
32
33
|
export interface ServerManager extends Initializable {
|
|
@@ -127,7 +127,7 @@ let ServerRequestHandler = class ServerRequestHandler {
|
|
|
127
127
|
uc.fill((await req.bodyFromQueryParams()));
|
|
128
128
|
break;
|
|
129
129
|
default:
|
|
130
|
-
|
|
130
|
+
envelope;
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
async applySideEffects(res, ucd, output) {
|
|
@@ -154,7 +154,7 @@ let ServerRequestHandler = class ServerRequestHandler {
|
|
|
154
154
|
await this.applySetAuthSideEffect(res, item);
|
|
155
155
|
break;
|
|
156
156
|
default:
|
|
157
|
-
(
|
|
157
|
+
(type);
|
|
158
158
|
}
|
|
159
159
|
}
|
|
160
160
|
return { status: undefined };
|
|
@@ -14,7 +14,9 @@ export function buildHandler(appManifest, ucd, contract, serverRequestHandler, u
|
|
|
14
14
|
case 'stream': {
|
|
15
15
|
execOpts = {
|
|
16
16
|
stream: {
|
|
17
|
-
onClose: async () => {
|
|
17
|
+
onClose: async () => {
|
|
18
|
+
throw new Error('execOpts.stream.onClose needs to be set in the UC ServerMain');
|
|
19
|
+
},
|
|
18
20
|
onData: async (output) => {
|
|
19
21
|
if (!output) {
|
|
20
22
|
return;
|
|
@@ -31,13 +33,12 @@ export function buildHandler(appManifest, ucd, contract, serverRequestHandler, u
|
|
|
31
33
|
}
|
|
32
34
|
res.flushHeaders();
|
|
33
35
|
res.on('close', async () => {
|
|
34
|
-
res.end();
|
|
35
36
|
await execOpts?.stream?.onClose();
|
|
36
37
|
});
|
|
37
38
|
break;
|
|
38
39
|
}
|
|
39
40
|
default:
|
|
40
|
-
|
|
41
|
+
transportType;
|
|
41
42
|
}
|
|
42
43
|
const { body, status } = await serverRequestHandler.exec({
|
|
43
44
|
appManifest,
|
|
@@ -66,7 +67,7 @@ export function buildHandler(appManifest, ucd, contract, serverRequestHandler, u
|
|
|
66
67
|
return;
|
|
67
68
|
}
|
|
68
69
|
default:
|
|
69
|
-
|
|
70
|
+
transportType;
|
|
70
71
|
}
|
|
71
72
|
};
|
|
72
73
|
return handler;
|
|
@@ -51,7 +51,7 @@ export function buildHandler(appManifest, ucd, contract, serverRequestHandler, u
|
|
|
51
51
|
break;
|
|
52
52
|
}
|
|
53
53
|
default:
|
|
54
|
-
|
|
54
|
+
transportType;
|
|
55
55
|
}
|
|
56
56
|
const { body, status } = await serverRequestHandler.exec({
|
|
57
57
|
appManifest,
|
|
@@ -80,7 +80,7 @@ export function buildHandler(appManifest, ucd, contract, serverRequestHandler, u
|
|
|
80
80
|
});
|
|
81
81
|
}
|
|
82
82
|
default:
|
|
83
|
-
|
|
83
|
+
transportType;
|
|
84
84
|
}
|
|
85
85
|
return c.json(body, status);
|
|
86
86
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Logger, SettingsManager } from '../../../std/index.js';
|
|
2
2
|
import type { EntrypointsBuilder } from '../server/EntrypointsBuilder.js';
|
|
3
|
-
import type { ListenSettings, Server } from './types.js';
|
|
3
|
+
import type { ListenSettings, Server, StopSettings } from './types.js';
|
|
4
4
|
export declare function listen(server: Server, entrypointsBuilder: EntrypointsBuilder, logger: Logger, settingsManager: SettingsManager<ListenSettings>): void;
|
|
5
|
-
export declare function stop(server: Server): Promise<void>;
|
|
5
|
+
export declare function stop(server: Server, settingsManager: SettingsManager<StopSettings>): Promise<void>;
|
|
@@ -5,16 +5,26 @@ export function listen(server, entrypointsBuilder, logger, settingsManager) {
|
|
|
5
5
|
logger.info(`Listening on ${entrypointsBuilder.exec().http}`);
|
|
6
6
|
});
|
|
7
7
|
}
|
|
8
|
-
export async function stop(server) {
|
|
8
|
+
export async function stop(server, settingsManager) {
|
|
9
9
|
if (!server?.listening) {
|
|
10
10
|
return;
|
|
11
11
|
}
|
|
12
|
+
const mode = settingsManager.get()('server_stop_mode');
|
|
12
13
|
// As stated in the docs of `close`, only awaiting `.close` is not enough to make sure all the connections are closed.
|
|
13
14
|
// Hence the wrapping in a promise, where the callback is called when the 'close' event is emitted.
|
|
14
15
|
return new Promise((resolve, reject) => {
|
|
15
16
|
if (!server) {
|
|
16
17
|
return resolve();
|
|
17
18
|
}
|
|
19
|
+
switch (mode) {
|
|
20
|
+
case 'aggressive':
|
|
21
|
+
server.closeAllConnections();
|
|
22
|
+
break;
|
|
23
|
+
case 'patient':
|
|
24
|
+
break;
|
|
25
|
+
default:
|
|
26
|
+
mode;
|
|
27
|
+
}
|
|
18
28
|
server.close((err) => {
|
|
19
29
|
if (err) {
|
|
20
30
|
return reject(err);
|
|
@@ -3,3 +3,4 @@ import type https from 'node:https';
|
|
|
3
3
|
import type { ServerManagerSettings } from '../server/ServerManager.js';
|
|
4
4
|
export type Server = http.Server | https.Server;
|
|
5
5
|
export type ListenSettings = Pick<ServerManagerSettings, 'server_binding_host' | 'server_binding_port'>;
|
|
6
|
+
export type StopSettings = Pick<ServerManagerSettings, 'server_stop_mode'>;
|
|
@@ -8,8 +8,8 @@ import type { ServerManager, ServerManagerSettings } from '../lib/server/ServerM
|
|
|
8
8
|
import { ServerRequestHandler } from '../lib/server/ServerRequestHandler.js';
|
|
9
9
|
import { ServerSSLCertLoader } from '../lib/server/ServerSSLCertLoader.js';
|
|
10
10
|
import { HelmetMiddlewareBuilder } from '../lib/server-express/HelmetMiddlewareBuilder.js';
|
|
11
|
-
import type { ListenSettings } from '../lib/server-node/types.js';
|
|
12
|
-
type S = ListenSettings & Pick<LoggerSettings, 'logger_level'> & Pick<ServerManagerSettings, 'server_tmp_path'
|
|
11
|
+
import type { ListenSettings, StopSettings } from '../lib/server-node/types.js';
|
|
12
|
+
type S = ListenSettings & Pick<LoggerSettings, 'logger_level'> & Pick<ServerManagerSettings, 'server_tmp_path'> & StopSettings;
|
|
13
13
|
export declare class NodeExpressServerManager implements Configurable<S>, ServerManager {
|
|
14
14
|
private entrypointsBuilder;
|
|
15
15
|
protected environmentManager: EnvironmentManager;
|
|
@@ -47,6 +47,7 @@ let NodeExpressServerManager = class NodeExpressServerManager {
|
|
|
47
47
|
logger_level: this.settingsManager.get()('logger_level'),
|
|
48
48
|
server_binding_host: this.settingsManager.get()('server_binding_host'),
|
|
49
49
|
server_binding_port: this.settingsManager.get()('server_binding_port'),
|
|
50
|
+
server_stop_mode: this.settingsManager.get()('server_stop_mode'),
|
|
50
51
|
server_tmp_path: this.settingsManager.get()('server_tmp_path'),
|
|
51
52
|
};
|
|
52
53
|
}
|
|
@@ -79,7 +80,7 @@ let NodeExpressServerManager = class NodeExpressServerManager {
|
|
|
79
80
|
listen(this.server, this.entrypointsBuilder, this.logger, this.settingsManager);
|
|
80
81
|
}
|
|
81
82
|
async stop() {
|
|
82
|
-
await stop(this.server);
|
|
83
|
+
await stop(this.server, this.settingsManager);
|
|
83
84
|
}
|
|
84
85
|
async warmUp() {
|
|
85
86
|
// Nothing to do
|
|
@@ -7,8 +7,8 @@ import { EntrypointsBuilder } from '../lib/server/EntrypointsBuilder.js';
|
|
|
7
7
|
import type { ServerManager } from '../lib/server/ServerManager.js';
|
|
8
8
|
import { ServerRequestHandler } from '../lib/server/ServerRequestHandler.js';
|
|
9
9
|
import { ServerSSLCertLoader } from '../lib/server/ServerSSLCertLoader.js';
|
|
10
|
-
import type { ListenSettings } from '../lib/server-node/types.js';
|
|
11
|
-
type S = ListenSettings;
|
|
10
|
+
import type { ListenSettings, StopSettings } from '../lib/server-node/types.js';
|
|
11
|
+
type S = ListenSettings & StopSettings;
|
|
12
12
|
export declare class NodeHonoServerManager implements Configurable<S>, ServerManager {
|
|
13
13
|
private entrypointsBuilder;
|
|
14
14
|
protected environmentManager: EnvironmentManager;
|
|
@@ -44,6 +44,7 @@ let NodeHonoServerManager = class NodeHonoServerManager {
|
|
|
44
44
|
return {
|
|
45
45
|
server_binding_host: this.settingsManager.get()('server_binding_host'),
|
|
46
46
|
server_binding_port: this.settingsManager.get()('server_binding_port'),
|
|
47
|
+
server_stop_mode: this.settingsManager.get()('server_stop_mode'),
|
|
47
48
|
};
|
|
48
49
|
}
|
|
49
50
|
getRuntime() {
|
|
@@ -75,7 +76,7 @@ let NodeHonoServerManager = class NodeHonoServerManager {
|
|
|
75
76
|
listen(this.server, this.entrypointsBuilder, this.logger, this.settingsManager);
|
|
76
77
|
}
|
|
77
78
|
async stop() {
|
|
78
|
-
await stop(this.server);
|
|
79
|
+
await stop(this.server, this.settingsManager);
|
|
79
80
|
}
|
|
80
81
|
async warmUp() {
|
|
81
82
|
// Nothing to do
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { WordingManager } from '../../i18n/index.js';
|
|
2
|
+
import { type ProductManifest, ProductUCsLoader } from '../../product/index.js';
|
|
3
|
+
import type { CLIManager, Input, Output } from '../lib/cli/CLIManager.js';
|
|
4
|
+
import { CommandExecutor } from '../lib/cli/CommandExecutor.js';
|
|
5
|
+
export declare class NodeStricliCLIManager implements CLIManager {
|
|
6
|
+
private commandExecutor;
|
|
7
|
+
private productManifest;
|
|
8
|
+
private productUCsLoader;
|
|
9
|
+
private wordingManager;
|
|
10
|
+
constructor(commandExecutor: CommandExecutor, productManifest: ProductManifest, productUCsLoader: ProductUCsLoader, wordingManager: WordingManager);
|
|
11
|
+
handleCommand({ appsRootPath, srcImporter, }: Input): Promise<Output>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
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 { buildApplication, buildCommand, buildRouteMap, run, } from '@stricli/core';
|
|
14
|
+
import { inject, injectable } from 'inversify';
|
|
15
|
+
import { WordingManager } from '../../i18n/index.js';
|
|
16
|
+
import { ProductUCsLoader } from '../../product/index.js';
|
|
17
|
+
import { ucifHint, ucifIsMandatory, ucifRepeatability, ucMountingPoint, } from '../../uc/index.js';
|
|
18
|
+
import { CommandExecutor } from '../lib/cli/CommandExecutor.js';
|
|
19
|
+
let NodeStricliCLIManager = class NodeStricliCLIManager {
|
|
20
|
+
commandExecutor;
|
|
21
|
+
productManifest;
|
|
22
|
+
productUCsLoader;
|
|
23
|
+
wordingManager;
|
|
24
|
+
constructor(commandExecutor, productManifest, productUCsLoader, wordingManager) {
|
|
25
|
+
this.commandExecutor = commandExecutor;
|
|
26
|
+
this.productManifest = productManifest;
|
|
27
|
+
this.productUCsLoader = productUCsLoader;
|
|
28
|
+
this.wordingManager = wordingManager;
|
|
29
|
+
}
|
|
30
|
+
async handleCommand({ appsRootPath, srcImporter, }) {
|
|
31
|
+
const ucs = await this.productUCsLoader.exec({
|
|
32
|
+
appsRootPath,
|
|
33
|
+
srcImporter,
|
|
34
|
+
});
|
|
35
|
+
const routes = {};
|
|
36
|
+
for (const uc of ucs) {
|
|
37
|
+
const mountingPoint = uc.def.ext?.cmd?.mountAt ?? ucMountingPoint(uc);
|
|
38
|
+
routes[mountingPoint] = buildCommand({
|
|
39
|
+
docs: {
|
|
40
|
+
brief: this.wordingManager.uc(uc.def).desc ?? '',
|
|
41
|
+
},
|
|
42
|
+
func: async (flags) => {
|
|
43
|
+
uc.fill(flags);
|
|
44
|
+
await this.commandExecutor.exec({ uc });
|
|
45
|
+
},
|
|
46
|
+
parameters: {
|
|
47
|
+
flags: {},
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
const { flags } = routes[mountingPoint].parameters;
|
|
51
|
+
if (!flags) {
|
|
52
|
+
throw new Error('Init the flags first');
|
|
53
|
+
}
|
|
54
|
+
for (const f of this.commandExecutor.fieldsForFlags(uc)) {
|
|
55
|
+
const { def } = f;
|
|
56
|
+
const { desc, label } = this.wordingManager.ucif(f);
|
|
57
|
+
const brief = desc ?? label;
|
|
58
|
+
const defaultValue = def.type.getDefaultValue();
|
|
59
|
+
const [isRepeatable, _max] = ucifRepeatability(def);
|
|
60
|
+
const options = def.type.getOptions();
|
|
61
|
+
const hasOptions = options && options.length > 0;
|
|
62
|
+
const hint = ucifHint(def);
|
|
63
|
+
const common = {
|
|
64
|
+
brief,
|
|
65
|
+
default: defaultValue,
|
|
66
|
+
optional: !ucifIsMandatory(def),
|
|
67
|
+
placeholder: hint ?? '',
|
|
68
|
+
variadic: isRepeatable,
|
|
69
|
+
};
|
|
70
|
+
if (hasOptions) {
|
|
71
|
+
flags[f.key] = {
|
|
72
|
+
...common,
|
|
73
|
+
kind: 'enum',
|
|
74
|
+
values: options?.map((o) => o.value),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
flags[f.key] = {
|
|
79
|
+
...common,
|
|
80
|
+
kind: 'parsed',
|
|
81
|
+
parse: (raw) => {
|
|
82
|
+
def.type.assign(raw);
|
|
83
|
+
const val = def.type.val();
|
|
84
|
+
def.type.clear();
|
|
85
|
+
return val;
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
const { desc, slogan } = this.wordingManager.p();
|
|
92
|
+
const root = buildRouteMap({
|
|
93
|
+
docs: {
|
|
94
|
+
brief: desc ?? slogan ?? '',
|
|
95
|
+
},
|
|
96
|
+
routes,
|
|
97
|
+
});
|
|
98
|
+
const app = buildApplication(root, {
|
|
99
|
+
name: this.productManifest.name,
|
|
100
|
+
versionInfo: {
|
|
101
|
+
currentVersion: await this.commandExecutor.version(),
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
await run(app, process.argv.slice(2), {
|
|
105
|
+
process: process,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
NodeStricliCLIManager = __decorate([
|
|
110
|
+
injectable(),
|
|
111
|
+
__param(0, inject(CommandExecutor)),
|
|
112
|
+
__param(1, inject('ProductManifest')),
|
|
113
|
+
__param(2, inject(ProductUCsLoader)),
|
|
114
|
+
__param(3, inject(WordingManager)),
|
|
115
|
+
__metadata("design:paramtypes", [CommandExecutor, Object, ProductUCsLoader,
|
|
116
|
+
WordingManager])
|
|
117
|
+
], NodeStricliCLIManager);
|
|
118
|
+
export { NodeStricliCLIManager };
|
|
@@ -12,7 +12,6 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
12
12
|
};
|
|
13
13
|
import { inject, injectable } from 'inversify';
|
|
14
14
|
import { I18nEN } from '../i18n/locales/en.js';
|
|
15
|
-
import { I18nFR } from '../i18n/locales/fr.js';
|
|
16
15
|
import { FAKE_USER_ADMIN, UCBuilder, ucHTTPContract, } from '../uc/index.js';
|
|
17
16
|
// We inject directly the implementation because we'll generate all the reports and not only the one that is bound to the interface.
|
|
18
17
|
// We can plan a setting à la Vitest where we specify the types of reports to generate though.
|
|
@@ -88,9 +87,13 @@ let AppTester = class AppTester {
|
|
|
88
87
|
}
|
|
89
88
|
}
|
|
90
89
|
async checkAppI18n() {
|
|
90
|
+
if (!this.ucDefSourcesCheckerOutput) {
|
|
91
|
+
throw new Error('checkUCDSources must be called before checkAppI18n');
|
|
92
|
+
}
|
|
91
93
|
const { errors } = await this.appI18nChecker.exec({
|
|
92
94
|
appI18n: this.ctx.appI18n,
|
|
93
95
|
appManifest: this.ctx.appManifest,
|
|
96
|
+
ucDefSourcesCheckerOutput: this.ucDefSourcesCheckerOutput,
|
|
94
97
|
});
|
|
95
98
|
if (errors.length > 0) {
|
|
96
99
|
throw new Error(errors[0]);
|
|
@@ -302,15 +305,11 @@ let AppTester = class AppTester {
|
|
|
302
305
|
const appLangCodes = Object.keys(appI18n);
|
|
303
306
|
const coreI18n = {
|
|
304
307
|
en: I18nEN,
|
|
305
|
-
fr: I18nFR,
|
|
306
308
|
};
|
|
307
309
|
const productI18n = {
|
|
308
310
|
en: {
|
|
309
311
|
...I18nEN,
|
|
310
312
|
},
|
|
311
|
-
fr: {
|
|
312
|
-
...I18nFR,
|
|
313
|
-
},
|
|
314
313
|
};
|
|
315
314
|
for (const l of appLangCodes) {
|
|
316
315
|
if (!(l in coreI18n)) {
|
|
@@ -1,21 +1,39 @@
|
|
|
1
1
|
import type { ErrorMessage, FilePath } from '../dt/index.js';
|
|
2
2
|
import type { UCDefLifecycle, UCMetadata, UCOutputPartIdx } from '../uc/index.js';
|
|
3
3
|
import type { AppTesterOptsAllSet } from './opts.js';
|
|
4
|
-
export interface OutputItemField<T
|
|
4
|
+
export interface OutputItemField<T = string> {
|
|
5
5
|
err: ErrorMessage | null;
|
|
6
6
|
value: T;
|
|
7
7
|
}
|
|
8
|
+
export type OutputItemFieldIOField = OutputItemField<{
|
|
9
|
+
/**
|
|
10
|
+
* @example `FreeTextShort`
|
|
11
|
+
*/
|
|
12
|
+
dataType: string | null;
|
|
13
|
+
/**
|
|
14
|
+
* @example `name`
|
|
15
|
+
*/
|
|
16
|
+
name: string | null;
|
|
17
|
+
/**
|
|
18
|
+
* @example `name: UCInputField<FreeTextShort>`
|
|
19
|
+
*/
|
|
20
|
+
raw: string | null;
|
|
21
|
+
/**
|
|
22
|
+
* @example `UCInputField<FreeTextShort>`
|
|
23
|
+
*/
|
|
24
|
+
type: string | null;
|
|
25
|
+
}>;
|
|
8
26
|
export interface OutputItem {
|
|
9
27
|
constName: OutputItemField | null;
|
|
10
28
|
externalImports: OutputItemField[] | null;
|
|
11
29
|
filePath: OutputItemField | null;
|
|
12
30
|
internalImports: OutputItemField[] | null;
|
|
13
31
|
ioI: OutputItemField | null;
|
|
14
|
-
ioIFields:
|
|
32
|
+
ioIFields: OutputItemFieldIOField[] | null;
|
|
15
33
|
ioOPI0: OutputItemField | null;
|
|
16
|
-
ioOPI0Fields:
|
|
34
|
+
ioOPI0Fields: OutputItemFieldIOField[] | null;
|
|
17
35
|
ioOPI1: OutputItemField | null;
|
|
18
|
-
ioOPI1Fields:
|
|
36
|
+
ioOPI1Fields: OutputItemFieldIOField[] | null;
|
|
19
37
|
lifecycleClientPolicy: OutputItemField | null;
|
|
20
38
|
lifecycleClientSteps: OutputItemField[] | null;
|
|
21
39
|
lifecycleServerPolicy: OutputItemField | null;
|
|
@@ -29,10 +47,10 @@ export interface OutputItem {
|
|
|
29
47
|
}
|
|
30
48
|
export declare const OUTPUT_ITEM_FIELDS: (keyof OutputItem)[];
|
|
31
49
|
export type OnImport = (name: string) => void;
|
|
32
|
-
export type OnInputType = (name: string, fields:
|
|
50
|
+
export type OnInputType = (name: string, fields: OutputItemFieldIOField[]) => void;
|
|
33
51
|
export type OnMainStep = (lifecycle: UCDefLifecycle, step: string) => void;
|
|
34
52
|
export type OnMetadata = (metadata: UCMetadata) => void;
|
|
35
|
-
export type OnOPIType = (name: string, fields:
|
|
53
|
+
export type OnOPIType = (name: string, fields: OutputItemFieldIOField[], idx: UCOutputPartIdx) => void;
|
|
36
54
|
export type OnPolicy = (lifecycle: UCDefLifecycle, name: string) => void;
|
|
37
55
|
export type OnVariable = (name: string) => void;
|
|
38
56
|
export interface UCDefASTParser {
|
|
@@ -11,7 +11,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
11
11
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
12
|
};
|
|
13
13
|
import { inject, injectable } from 'inversify';
|
|
14
|
-
import { APP_DOCS_FILE_NAME,
|
|
14
|
+
import { APP_DOCS_FILE_NAME, UC_MAIN_STEP_PREFIX_REGULAR, } from '../../convention.js';
|
|
15
15
|
import { OUTPUT_ITEM_FIELDS, } from '../UCDefASTParser.js';
|
|
16
16
|
let SimpleAppDocsEmitter = class SimpleAppDocsEmitter {
|
|
17
17
|
fsManager;
|
|
@@ -142,9 +142,8 @@ function diagramUCClientConfirm(participant, caller) {
|
|
|
142
142
|
];
|
|
143
143
|
}
|
|
144
144
|
function diagramUCFields(fields) {
|
|
145
|
-
return (fields
|
|
146
|
-
|
|
147
|
-
.join(LB) || '');
|
|
145
|
+
return (fields?.map((f) => `${f.value.name}: ${f.value.dataType}`).join(LB) ||
|
|
146
|
+
'');
|
|
148
147
|
}
|
|
149
148
|
function diagramUCMainSteps(participant, field) {
|
|
150
149
|
return field.map((f) => `${participant}->>${participant}: ${f.value.replace(UC_MAIN_STEP_PREFIX_REGULAR, '').trim()}`);
|
|
@@ -171,7 +170,7 @@ function fmtTechSummaryField(field) {
|
|
|
171
170
|
}
|
|
172
171
|
function fmtTechSummaryFieldVal(field) {
|
|
173
172
|
const { err, value } = field;
|
|
174
|
-
let res = value;
|
|
173
|
+
let res = (typeof value === 'string' ? value : value.raw) ?? '';
|
|
175
174
|
if (err) {
|
|
176
175
|
res += `❌ ${err}`;
|
|
177
176
|
}
|