libmodulor 0.23.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 +17 -0
- package/README.md +154 -2
- package/dist/esm/apps/Helper/src/lib/project.js +3 -3
- 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.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/impl/NodeFSManager.js +1 -1
- package/dist/esm/std/impl/SimpleMapI18nManager.d.ts +6 -1
- package/dist/esm/std/impl/SimpleMapI18nManager.js +41 -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 +2 -2
- 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/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/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/ioc/bindCommon.js +1 -1
- package/dist/esm/utils/terminal/fmt.js +1 -1
- package/package.json +30 -8
- package/pnpm-workspace.yaml +1 -4
- package/tsconfig.build.examples.json +8 -0
- package/tsconfig.json +1 -0
- package/vitest.config.ts +16 -0
|
@@ -38,7 +38,7 @@ export function buildHandler(appManifest, ucd, contract, serverRequestHandler, u
|
|
|
38
38
|
break;
|
|
39
39
|
}
|
|
40
40
|
default:
|
|
41
|
-
|
|
41
|
+
transportType;
|
|
42
42
|
}
|
|
43
43
|
const { body, status } = await serverRequestHandler.exec({
|
|
44
44
|
appManifest,
|
|
@@ -67,7 +67,7 @@ export function buildHandler(appManifest, ucd, contract, serverRequestHandler, u
|
|
|
67
67
|
return;
|
|
68
68
|
}
|
|
69
69
|
default:
|
|
70
|
-
|
|
70
|
+
transportType;
|
|
71
71
|
}
|
|
72
72
|
};
|
|
73
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
|
};
|
|
@@ -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
|
}
|
|
@@ -11,7 +11,8 @@ 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 typescript, { isClassDeclaration, isObjectLiteralExpression, isPropertyAssignment, } from 'typescript';
|
|
14
|
+
import typescript, { isClassDeclaration, isObjectLiteralExpression, isPropertyAssignment, SyntaxKind, } from 'typescript';
|
|
15
|
+
// https://ts-ast-viewer.com
|
|
15
16
|
// To avoid the following error when used in a consumer :
|
|
16
17
|
// SyntaxError: Named export 'ModuleKind' not found. The requested module 'typescript' is a CommonJS module, which may not support all module.exports as named exports.
|
|
17
18
|
// CommonJS modules can always be imported via the default export
|
|
@@ -99,20 +100,46 @@ let TypeScriptLibUCDefASTParser = class TypeScriptLibUCDefASTParser {
|
|
|
99
100
|
}
|
|
100
101
|
getTypeFields(node) {
|
|
101
102
|
const type = this.typeChecker.getTypeAtLocation(node);
|
|
102
|
-
const fields = type
|
|
103
|
+
const fields = type
|
|
104
|
+
.getProperties()
|
|
105
|
+
.map((p) => {
|
|
103
106
|
const field = {
|
|
104
107
|
err: null,
|
|
105
|
-
value:
|
|
108
|
+
value: {
|
|
109
|
+
dataType: null,
|
|
110
|
+
name: null,
|
|
111
|
+
raw: null,
|
|
112
|
+
type: null,
|
|
113
|
+
},
|
|
106
114
|
};
|
|
107
115
|
const declarations = p.getDeclarations();
|
|
108
|
-
if (declarations) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
+
if (!declarations) {
|
|
117
|
+
return field;
|
|
118
|
+
}
|
|
119
|
+
const [first] = declarations;
|
|
120
|
+
if (first && isPropertySignature(first)) {
|
|
121
|
+
field.value.raw = first
|
|
122
|
+
.getText()
|
|
123
|
+
.replaceAll('\n', '')
|
|
124
|
+
.replaceAll(';', '')
|
|
125
|
+
.replaceAll(/\s+/g, ' ');
|
|
126
|
+
first.forEachChild((node1) => {
|
|
127
|
+
if (isIdentifier(node1)) {
|
|
128
|
+
field.value.name = node1.getText();
|
|
129
|
+
}
|
|
130
|
+
else if (isTypeReferenceNode(node1)) {
|
|
131
|
+
field.value.type = node1.getText();
|
|
132
|
+
node1.forEachChild((node2) => {
|
|
133
|
+
if (isIdentifier(node2) ||
|
|
134
|
+
isTypeReferenceNode(node2) ||
|
|
135
|
+
node2.kind === SyntaxKind.BooleanKeyword ||
|
|
136
|
+
node2.kind === SyntaxKind.NumberKeyword ||
|
|
137
|
+
node2.kind === SyntaxKind.StringKeyword) {
|
|
138
|
+
field.value.dataType = node2.getText();
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
});
|
|
116
143
|
}
|
|
117
144
|
return field;
|
|
118
145
|
});
|
|
@@ -5,7 +5,7 @@ export declare class VitestAppTestSuiteRunner implements AppTestSuiteRunner {
|
|
|
5
5
|
private fsManager;
|
|
6
6
|
private shellCommandExecutor;
|
|
7
7
|
constructor(fsManager: FSManager, shellCommandExecutor: ShellCommandExecutor);
|
|
8
|
-
exec({ appPath, skipCoverage, updateSnapshots, }: Input): Promise<void>;
|
|
8
|
+
exec({ appPath, only, skipCoverage, updateSnapshots, }: Input): Promise<void>;
|
|
9
9
|
coverageReportEntrypointPath(appPath: FilePath): Promise<FilePath>;
|
|
10
10
|
private coverageReportPath;
|
|
11
11
|
}
|
|
@@ -19,18 +19,33 @@ let VitestAppTestSuiteRunner = class VitestAppTestSuiteRunner {
|
|
|
19
19
|
this.fsManager = fsManager;
|
|
20
20
|
this.shellCommandExecutor = shellCommandExecutor;
|
|
21
21
|
}
|
|
22
|
-
async exec({ appPath, skipCoverage, updateSnapshots, }) {
|
|
22
|
+
async exec({ appPath, only, skipCoverage, updateSnapshots, }) {
|
|
23
23
|
const testPath = this.fsManager.path(appPath, APP_TEST_DIR_NAME);
|
|
24
24
|
const args = [
|
|
25
25
|
'run',
|
|
26
26
|
'--color',
|
|
27
|
+
// https://vitest.dev/guide/cli.html#dir
|
|
27
28
|
'--dir',
|
|
28
29
|
appPath,
|
|
29
30
|
];
|
|
31
|
+
if (only) {
|
|
32
|
+
args.push(
|
|
33
|
+
// https://vitest.dev/guide/cli.html#testnamepattern
|
|
34
|
+
'--testNamePattern', only);
|
|
35
|
+
}
|
|
30
36
|
if (!skipCoverage) {
|
|
31
|
-
args.push(
|
|
37
|
+
args.push(
|
|
38
|
+
// https://vitest.dev/guide/cli.html#coverage-enabled
|
|
39
|
+
'--coverage.enabled',
|
|
40
|
+
// https://vitest.dev/guide/cli.html#coverage-exclude
|
|
41
|
+
'--coverage.exclude', testPath,
|
|
42
|
+
// https://vitest.dev/guide/cli.html#coverage-include
|
|
43
|
+
'--coverage.include', appPath,
|
|
44
|
+
// https://vitest.dev/guide/cli.html#coverage-reportsdirectory
|
|
45
|
+
'--coverage.reportsDirectory', this.coverageReportPath(appPath));
|
|
32
46
|
}
|
|
33
47
|
if (updateSnapshots) {
|
|
48
|
+
// https://vitest.dev/guide/cli.html#update
|
|
34
49
|
args.push('--update');
|
|
35
50
|
}
|
|
36
51
|
await this.shellCommandExecutor.exec({
|
package/dist/esm/testing/opts.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { FilePath } from '../../dt/index.js';
|
|
2
2
|
import type { Worker } from '../../std/index.js';
|
|
3
|
+
import type { UCName } from '../../uc/index.js';
|
|
3
4
|
export interface Input {
|
|
4
5
|
appPath: FilePath;
|
|
6
|
+
only: UCName | null;
|
|
5
7
|
skipCoverage: boolean;
|
|
6
8
|
updateSnapshots: boolean;
|
|
7
9
|
}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import type { AppManifest } from '../../../app/index.js';
|
|
2
2
|
import type { ErrorMessage } from '../../../dt/index.js';
|
|
3
|
-
import type
|
|
3
|
+
import { type I18n } from '../../../i18n/index.js';
|
|
4
4
|
import type { Worker } from '../../../std/index.js';
|
|
5
|
+
import type { Output as UCDefSourcesCheckerOutput } from './UCDefSourcesChecker.js';
|
|
5
6
|
export interface Input {
|
|
6
7
|
appI18n: I18n;
|
|
7
8
|
appManifest: Pick<AppManifest, 'languageCodes'>;
|
|
9
|
+
ucDefSourcesCheckerOutput: UCDefSourcesCheckerOutput;
|
|
8
10
|
}
|
|
9
11
|
export interface Output {
|
|
10
12
|
errors: ErrorMessage[];
|
|
@@ -13,7 +15,11 @@ export declare class AppI18nChecker implements Worker<Input, Promise<Output>> {
|
|
|
13
15
|
private static I18N_KEY_PATTERN;
|
|
14
16
|
private output;
|
|
15
17
|
constructor();
|
|
16
|
-
exec({ appI18n, appManifest }: Input): Promise<Output>;
|
|
18
|
+
exec({ appI18n, appManifest, ucDefSourcesCheckerOutput, }: Input): Promise<Output>;
|
|
17
19
|
private makeSureLanguagesAreConsistent;
|
|
18
20
|
private makeSureKeysAndLabelsAreValid;
|
|
21
|
+
private makeSureNonDefaultLanguagesAreFullyTranslated;
|
|
22
|
+
private checkUC;
|
|
23
|
+
private checkIOFields;
|
|
24
|
+
private checkKey;
|
|
19
25
|
}
|
|
@@ -9,9 +9,11 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
9
9
|
};
|
|
10
10
|
var AppI18nChecker_1;
|
|
11
11
|
import { injectable } from 'inversify';
|
|
12
|
+
import { I18N_DEFAULT_LANG, } from '../../../i18n/index.js';
|
|
12
13
|
const ERR_I18N_MISMATCH = () => 'The languageCodes in app manifest must match with the keys in i18n';
|
|
13
14
|
const ERR_I18N_KEY_INVALID = (key) => `The i18n key '${key}' must respect the i18n key pattern`;
|
|
14
|
-
const ERR_I18N_LABEL_NO_DOT = (key) => `The i18n key '${key}' is a label, thus should not
|
|
15
|
+
const ERR_I18N_LABEL_NO_DOT = (key) => `The i18n key '${key}' is a label, thus it should not end with a dot`;
|
|
16
|
+
const ERR_I18N_MISSING_TRANS = (key, lang) => `The i18n key '${key}' is missing for lang '${lang}'`;
|
|
15
17
|
let AppI18nChecker = class AppI18nChecker {
|
|
16
18
|
static { AppI18nChecker_1 = this; }
|
|
17
19
|
static I18N_KEY_PATTERN = /(dt_([A-Z][A-Za-z0-9]+)_([A-Za-z0-9]+)_(desc|label))|(err_([A-Za-z_]+))|(uc_([A-Z][A-Za-z0-9]+)_(client_confirm_(cancel|confirm|message|title)|desc|label|i_submit_(changing|idle|initializing|submitting)|op_(0|1)_(empty|label)))|(ucif_([a-z]([A-Za-z0-9]+)?)_(desc|label))|(ucof_([a-z]([A-Za-z0-9]+)?)_(desc|label))|(validation_([a-z]+)_([A-Z][A-Za-z0-9]+))/;
|
|
@@ -19,9 +21,10 @@ let AppI18nChecker = class AppI18nChecker {
|
|
|
19
21
|
constructor() {
|
|
20
22
|
this.output = { errors: [] };
|
|
21
23
|
}
|
|
22
|
-
async exec({ appI18n, appManifest }) {
|
|
24
|
+
async exec({ appI18n, appManifest, ucDefSourcesCheckerOutput, }) {
|
|
23
25
|
this.makeSureLanguagesAreConsistent(appI18n, appManifest);
|
|
24
26
|
this.makeSureKeysAndLabelsAreValid(appI18n);
|
|
27
|
+
this.makeSureNonDefaultLanguagesAreFullyTranslated(appI18n, ucDefSourcesCheckerOutput);
|
|
25
28
|
return this.output;
|
|
26
29
|
}
|
|
27
30
|
makeSureLanguagesAreConsistent(appI18n, appManifest) {
|
|
@@ -44,6 +47,45 @@ let AppI18nChecker = class AppI18nChecker {
|
|
|
44
47
|
}
|
|
45
48
|
}
|
|
46
49
|
}
|
|
50
|
+
makeSureNonDefaultLanguagesAreFullyTranslated(i18n, ucDefSourcesCheckerOutput) {
|
|
51
|
+
for (const [lang, translations] of Object.entries(i18n)) {
|
|
52
|
+
if (lang === I18N_DEFAULT_LANG) {
|
|
53
|
+
// We assume the code is in English so it's fine not to have all the translations in this language.
|
|
54
|
+
// For instance, a field named "name" will be humanized as "Name", which is totally ok.
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
for (const { metadataName, ioIFields, ioOPI0Fields, ioOPI1Fields, } of ucDefSourcesCheckerOutput.items) {
|
|
58
|
+
this.checkUC(lang, translations, 'label', metadataName);
|
|
59
|
+
for (const [prefix, fields] of [
|
|
60
|
+
['ucif', ioIFields],
|
|
61
|
+
['ucof', ioOPI0Fields],
|
|
62
|
+
['ucof', ioOPI1Fields],
|
|
63
|
+
]) {
|
|
64
|
+
this.checkIOFields(lang, translations, prefix, 'label', fields);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
checkUC(lang, translations, suffix, metadataName) {
|
|
70
|
+
if (!metadataName) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
this.checkKey(lang, translations, `uc_${metadataName.value}_${suffix}`);
|
|
74
|
+
}
|
|
75
|
+
checkIOFields(lang, translations, prefix, suffix, fields) {
|
|
76
|
+
if (!fields) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
for (const f of fields) {
|
|
80
|
+
this.checkKey(lang, translations, `${prefix}_${f.value.name}_${suffix}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
checkKey(lang, translations, key) {
|
|
84
|
+
if (key in translations) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
this.output.errors.push(ERR_I18N_MISSING_TRANS(key, lang));
|
|
88
|
+
}
|
|
47
89
|
};
|
|
48
90
|
AppI18nChecker = AppI18nChecker_1 = __decorate([
|
|
49
91
|
injectable(),
|
|
@@ -18,7 +18,7 @@ const ERR_UCD_CONST_NAME = (name) => `The UCD const name '${name}' must follow t
|
|
|
18
18
|
const ERR_UCD_FILE_SUFFIX = (fileName) => `The file '${fileName}' must end with ${UC_DEF_FILE_NAME_SUFFIX}`;
|
|
19
19
|
const ERR_UCD_IMPORTS_EXTERNAL_ALLOWED = (aliasPrefix, allowed, text) => `External imports must be an alias '${aliasPrefix}*' or be one of ${allowed} (Got ${text})`;
|
|
20
20
|
const ERR_UCD_IMPORTS_INTERNAL_MAX_DEPTH = (maxDepth) => `Internal imports must not be deeper than ${maxDepth}`;
|
|
21
|
-
const
|
|
21
|
+
const ERR_UCD_INPUT_FIELD_DECLARATION = (raw) => `The input field def must match 'name: UCInputFieldValue<DataType>' (Got '${raw}')`;
|
|
22
22
|
const ERR_UCD_INPUT_TYPE_NAME = (ucName) => `The input type must be named ${ucName}${UC_INPUT_SUFFIX}`;
|
|
23
23
|
const ERR_UCD_OPI_TYPE_NAME = (ucName, idx) => `The OPI must be named ${ucName}${UC_OPI_SUFFIX}${idx}`;
|
|
24
24
|
// TODO : Improve the check* methods that look a little bit hacky
|
|
@@ -93,16 +93,16 @@ let UCDefSourcesChecker = class UCDefSourcesChecker {
|
|
|
93
93
|
};
|
|
94
94
|
item.ioIFields = fields;
|
|
95
95
|
for (const f of item.ioIFields) {
|
|
96
|
-
const
|
|
97
|
-
if (
|
|
98
|
-
|
|
96
|
+
const { dataType, name, raw, type } = f.value;
|
|
97
|
+
if (dataType &&
|
|
98
|
+
name &&
|
|
99
|
+
raw &&
|
|
100
|
+
type &&
|
|
101
|
+
type.match(new RegExp(UC_INPUT_FIELD_PATTERN)) !== null) {
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
f.err = ERR_UCD_INPUT_FIELD_DECLARATION(raw);
|
|
99
105
|
}
|
|
100
|
-
const [_name, type] = parts;
|
|
101
|
-
// trim because we process `name: Type` if the code is linted correctly
|
|
102
|
-
f.err =
|
|
103
|
-
type?.trim().match(new RegExp(UC_INPUT_FIELD_PATTERN)) !== null
|
|
104
|
-
? null
|
|
105
|
-
: ERR_UCD_INPUT_FIELD_PATTERN();
|
|
106
106
|
}
|
|
107
107
|
}
|
|
108
108
|
checkMainStep(lifecycle, step, item) {
|
|
@@ -120,7 +120,7 @@ let UCDefSourcesChecker = class UCDefSourcesChecker {
|
|
|
120
120
|
item.lifecycleServerSteps.push({ err: null, value: step });
|
|
121
121
|
break;
|
|
122
122
|
default:
|
|
123
|
-
|
|
123
|
+
lifecycle;
|
|
124
124
|
}
|
|
125
125
|
}
|
|
126
126
|
checkMetadata(metadata, item) {
|
|
@@ -177,7 +177,7 @@ let UCDefSourcesChecker = class UCDefSourcesChecker {
|
|
|
177
177
|
};
|
|
178
178
|
break;
|
|
179
179
|
default:
|
|
180
|
-
|
|
180
|
+
lifecycle;
|
|
181
181
|
}
|
|
182
182
|
}
|
|
183
183
|
async processFiles(appPath, paths) {
|
|
@@ -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';
|