@webda/compiler 4.0.0-beta.3
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/LICENSE +166 -0
- package/README.md +125 -0
- package/lib/compiler.d.ts +88 -0
- package/lib/compiler.d.ts.map +1 -0
- package/lib/compiler.js +230 -0
- package/lib/compiler.js.map +1 -0
- package/lib/configuration.d.ts +35 -0
- package/lib/configuration.d.ts.map +1 -0
- package/lib/configuration.js +170 -0
- package/lib/configuration.js.map +1 -0
- package/lib/definition.d.ts +787 -0
- package/lib/definition.d.ts.map +1 -0
- package/lib/definition.js +189 -0
- package/lib/definition.js.map +1 -0
- package/lib/index.d.ts +5 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +5 -0
- package/lib/index.js.map +1 -0
- package/lib/module.d.ts +36 -0
- package/lib/module.d.ts.map +1 -0
- package/lib/module.js +119 -0
- package/lib/module.js.map +1 -0
- package/lib/morpher/capabilities.d.ts +35 -0
- package/lib/morpher/capabilities.d.ts.map +1 -0
- package/lib/morpher/capabilities.js +66 -0
- package/lib/morpher/capabilities.js.map +1 -0
- package/lib/morpher/imports.d.ts +10 -0
- package/lib/morpher/imports.d.ts.map +1 -0
- package/lib/morpher/imports.js +97 -0
- package/lib/morpher/imports.js.map +1 -0
- package/lib/morpher/morpher.d.ts +34 -0
- package/lib/morpher/morpher.d.ts.map +1 -0
- package/lib/morpher/morpher.js +87 -0
- package/lib/morpher/morpher.js.map +1 -0
- package/lib/operations.d.ts +29 -0
- package/lib/operations.d.ts.map +1 -0
- package/lib/operations.js +197 -0
- package/lib/operations.js.map +1 -0
- package/lib/schema-backend.d.ts +55 -0
- package/lib/schema-backend.d.ts.map +1 -0
- package/lib/schema-backend.js +86 -0
- package/lib/schema-backend.js.map +1 -0
- package/lib/session-types.d.ts +14 -0
- package/lib/session-types.d.ts.map +1 -0
- package/lib/session-types.js +79 -0
- package/lib/session-types.js.map +1 -0
- package/lib/shell-build-dispatch.d.ts +54 -0
- package/lib/shell-build-dispatch.d.ts.map +1 -0
- package/lib/shell-build-dispatch.js +77 -0
- package/lib/shell-build-dispatch.js.map +1 -0
- package/lib/shell.d.ts +3 -0
- package/lib/shell.d.ts.map +1 -0
- package/lib/shell.js +297 -0
- package/lib/shell.js.map +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Project, ProjectOptions, SourceFile } from "ts-morph";
|
|
2
|
+
type WebdaMorpherOptions = {
|
|
3
|
+
project?: ProjectOptions;
|
|
4
|
+
pretend?: boolean;
|
|
5
|
+
/**
|
|
6
|
+
* List of modules to check
|
|
7
|
+
*/
|
|
8
|
+
modules?: string[];
|
|
9
|
+
};
|
|
10
|
+
/** Applies a set of source migration modules (import moves, capability registrations) to project source files */
|
|
11
|
+
export declare class WebdaMorpher {
|
|
12
|
+
protected options: WebdaMorpherOptions;
|
|
13
|
+
project: Project;
|
|
14
|
+
modules: {
|
|
15
|
+
[key: string]: (sourceFile: SourceFile) => void;
|
|
16
|
+
};
|
|
17
|
+
/** Create a new WebdaMorpher.
|
|
18
|
+
* @param options - morpher configuration options
|
|
19
|
+
*/
|
|
20
|
+
constructor(options?: WebdaMorpherOptions);
|
|
21
|
+
/**
|
|
22
|
+
* Update the source files
|
|
23
|
+
* @returns promise resolving when all files are saved
|
|
24
|
+
*/
|
|
25
|
+
check(): Promise<void[]>;
|
|
26
|
+
/**
|
|
27
|
+
* Parse on file and return the updated content
|
|
28
|
+
* @param input - file path or SourceFile to process
|
|
29
|
+
* @returns the updated file content
|
|
30
|
+
*/
|
|
31
|
+
update(input: string | SourceFile): string;
|
|
32
|
+
}
|
|
33
|
+
export {};
|
|
34
|
+
//# sourceMappingURL=morpher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"morpher.d.ts","sourceRoot":"","sources":["../../src/morpher/morpher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAmC/D,KAAK,mBAAmB,GAAG;IACzB,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB,CAAC;AAEF,iHAAiH;AACjH,qBAAa,YAAY;IAUX,SAAS,CAAC,OAAO,EAAE,mBAAmB;IATlD,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAA;KAAE,CAG1D;IAEF;;OAEG;IACH,YAAsB,OAAO,GAAE,mBAAwB,EAGtD;IAED;;;OAGG;IACG,KAAK,oBAiCV;IAED;;;;OAIG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,CAUzC;CACF"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { Project } from "ts-morph";
|
|
2
|
+
import { updateImports } from "./imports.js";
|
|
3
|
+
import { removeFilterRegistrations } from "./capabilities.js";
|
|
4
|
+
import { useLog, useWorkerOutput } from "@webda/workout";
|
|
5
|
+
import { diffLines } from "diff";
|
|
6
|
+
// Replace all imports
|
|
7
|
+
// Specify after a : the exported name to replace
|
|
8
|
+
const replacePackages = {
|
|
9
|
+
// Move to tsc-esm
|
|
10
|
+
"@webda/core:DeepPartial,NotEnumerable,FilterAttributes": "@webda/tsc-esm",
|
|
11
|
+
// Move to @webda/fs
|
|
12
|
+
"@webda/core:FileStore,FileBinary,FileQueue,FileQueueParameters": "@webda/fs",
|
|
13
|
+
// Move to @webda/utils
|
|
14
|
+
"@webda/core:Throttler,NDJSONStream,NDJSonReader,BufferWritableStream,GunzipConditional,StorageFinder,YAMLUtils,TransformCase,TransformCaseType,getCommonJS,JSONUtils,FileUtils,WaitFor,WaitLinearDelay,WaitDelayer,sleep,WaitExponentialDelay,WaitDelayerFactory,WaitDelayerDefinition,WaitDelayerFactories,CancelablePromise,CancelableLoopPromise": "@webda/utils",
|
|
15
|
+
// Move to @webda/test
|
|
16
|
+
"@testdeck/mocha": "@webda/test",
|
|
17
|
+
// Rename WebdaQL to WebdaQL in its own module
|
|
18
|
+
"@webda/core:WebdaQL": "@webda/ql:*WebdaQL",
|
|
19
|
+
// Rename CoreModelDefinition to ModelClass
|
|
20
|
+
"@webda/core:CoreModelDefinition": "@webda/core:ModelClass",
|
|
21
|
+
"@webda/core/lib/test:WebdaTest": "@webda/core/lib/test/test:WebdaApplicationTest",
|
|
22
|
+
"@webda/core/lib/test:WebdaSimpleTest": "@webda/core/lib/test/test:WebdaSimpleTest"
|
|
23
|
+
};
|
|
24
|
+
/** Applies a set of source migration modules (import moves, capability registrations) to project source files */
|
|
25
|
+
export class WebdaMorpher {
|
|
26
|
+
options;
|
|
27
|
+
project;
|
|
28
|
+
modules = {
|
|
29
|
+
updateImports: sourceFile => updateImports(sourceFile, replacePackages),
|
|
30
|
+
capabilities: removeFilterRegistrations
|
|
31
|
+
};
|
|
32
|
+
/** Create a new WebdaMorpher.
|
|
33
|
+
* @param options - morpher configuration options
|
|
34
|
+
*/
|
|
35
|
+
constructor(options = {}) {
|
|
36
|
+
this.options = options;
|
|
37
|
+
this.project = new Project(options.project);
|
|
38
|
+
this.options.modules ??= Object.keys(this.modules);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Update the source files
|
|
42
|
+
* @returns promise resolving when all files are saved
|
|
43
|
+
*/
|
|
44
|
+
async check() {
|
|
45
|
+
const p = [];
|
|
46
|
+
const sourceFiles = this.project.getSourceFiles();
|
|
47
|
+
useWorkerOutput().startProgress("check", sourceFiles.length, "Updating source files");
|
|
48
|
+
sourceFiles.forEach(sourceFile => {
|
|
49
|
+
const origin = sourceFile.getFullText();
|
|
50
|
+
const update = this.update(sourceFile);
|
|
51
|
+
if (origin !== update) {
|
|
52
|
+
if (this.options.pretend) {
|
|
53
|
+
useLog("INFO", sourceFile.getFilePath(), "\n", diffLines(origin, update, {
|
|
54
|
+
ignoreWhitespace: true,
|
|
55
|
+
ignoreNewlineAtEof: true,
|
|
56
|
+
newlineIsToken: false
|
|
57
|
+
}));
|
|
58
|
+
useWorkerOutput().incrementProgress();
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
p.push(sourceFile
|
|
62
|
+
.save()
|
|
63
|
+
.catch(e => useLog("ERROR", "Error saving", sourceFile.getFilePath(), e))
|
|
64
|
+
.finally(() => {
|
|
65
|
+
useWorkerOutput().incrementProgress();
|
|
66
|
+
}));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
return await Promise.all(p);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Parse on file and return the updated content
|
|
74
|
+
* @param input - file path or SourceFile to process
|
|
75
|
+
* @returns the updated file content
|
|
76
|
+
*/
|
|
77
|
+
update(input) {
|
|
78
|
+
const sourceFile = typeof input === "string" ? this.project.addSourceFileAtPath(input) : input;
|
|
79
|
+
for (const key in this.modules) {
|
|
80
|
+
if (this.options.modules.includes(key)) {
|
|
81
|
+
this.modules[key](sourceFile);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return sourceFile.getFullText();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=morpher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"morpher.js","sourceRoot":"","sources":["../../src/morpher/morpher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAA8B,MAAM,UAAU,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAGjC,sBAAsB;AACtB,iDAAiD;AACjD,MAAM,eAAe,GAAG;IACtB,kBAAkB;IAClB,wDAAwD,EAAE,gBAAgB;IAC1E,oBAAoB;IACpB,gEAAgE,EAAE,WAAW;IAC7E,uBAAuB;IACvB,qVAAqV,EACnV,cAAc;IAChB,sBAAsB;IACtB,iBAAiB,EAAE,aAAa;IAChC,8CAA8C;IAC9C,qBAAqB,EAAE,oBAAoB;IAC3C,2CAA2C;IAC3C,iCAAiC,EAAE,wBAAwB;IAC3D,gCAAgC,EAAE,gDAAgD;IAClF,sCAAsC,EAAE,2CAA2C;CACpF,CAAC;AAmBF,iHAAiH;AACjH,MAAM,OAAO,YAAY;IAUD,OAAO;IAT7B,OAAO,CAAU;IACjB,OAAO,GAAwD;QAC7D,aAAa,EAAE,UAAU,CAAC,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,eAAe,CAAC;QACvE,YAAY,EAAE,yBAAyB;KACxC,CAAC;IAEF;;OAEG;IACH,YAAsB,OAAO,GAAwB,EAAE;uBAAjC,OAAO;QAC3B,IAAI,CAAC,OAAO,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC5C,IAAI,CAAC,OAAO,CAAC,OAAO,KAAK,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACrD,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,KAAK;QACT,MAAM,CAAC,GAAoB,EAAE,CAAC;QAC9B,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;QAClD,eAAe,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;QACtF,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE;YAC/B,MAAM,MAAM,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;YACxC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACvC,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;gBACtB,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;oBACzB,MAAM,CACJ,MAAM,EACN,UAAU,CAAC,WAAW,EAAE,EACxB,IAAI,EACJ,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE;wBACxB,gBAAgB,EAAE,IAAI;wBACtB,kBAAkB,EAAE,IAAI;wBACxB,cAAc,EAAE,KAAK;qBACtB,CAAC,CACH,CAAC;oBACF,eAAe,EAAE,CAAC,iBAAiB,EAAE,CAAC;gBACxC,CAAC;qBAAM,CAAC;oBACN,CAAC,CAAC,IAAI,CACJ,UAAU;yBACP,IAAI,EAAE;yBACN,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,cAAc,EAAE,UAAU,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC;yBACxE,OAAO,CAAC,GAAG,EAAE;wBACZ,eAAe,EAAE,CAAC,iBAAiB,EAAE,CAAC;oBACxC,CAAC,CAAC,CACL,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;QACH,OAAO,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC9B,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,KAA0B;QAC/B,MAAM,UAAU,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QAE/F,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAC/B,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACvC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC;YAChC,CAAC;QACH,CAAC;QAED,OAAO,UAAU,CAAC,WAAW,EAAE,CAAC;IAClC,CAAC;CACF"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { JSONSchema7 } from "json-schema";
|
|
2
|
+
import { WebdaModule } from "./definition.js";
|
|
3
|
+
/**
|
|
4
|
+
* Format for exported operations
|
|
5
|
+
*/
|
|
6
|
+
export interface OperationsExportFormat {
|
|
7
|
+
operations: {
|
|
8
|
+
[key: string]: OperationEntry;
|
|
9
|
+
};
|
|
10
|
+
schemas: {
|
|
11
|
+
[key: string]: JSONSchema7;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export interface OperationEntry {
|
|
15
|
+
id: string;
|
|
16
|
+
input: string;
|
|
17
|
+
output: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Generate operations from a WebdaModule
|
|
21
|
+
*
|
|
22
|
+
* This replicates at compile time what DomainService.initOperations() does at runtime.
|
|
23
|
+
* It derives operations from model Actions metadata and service/bean operation schemas.
|
|
24
|
+
*
|
|
25
|
+
* @param mod The merged WebdaModule (including dependencies)
|
|
26
|
+
* @returns OperationsExportFormat with operations and referenced schemas
|
|
27
|
+
*/
|
|
28
|
+
export declare function generateOperations(mod: WebdaModule): OperationsExportFormat;
|
|
29
|
+
//# sourceMappingURL=operations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operations.d.ts","sourceRoot":"","sources":["../src/operations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAiB,MAAM,iBAAiB,CAAC;AAG7D;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAAA;KAAE,CAAC;IAC9C,OAAO,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAAA;KAAE,CAAC;CACzC;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAOD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,WAAW,GAAG,sBAAsB,CAiB3E"}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { useLog } from "@webda/workout";
|
|
2
|
+
/**
|
|
3
|
+
* Standard CRUD action names that map to DomainService operations
|
|
4
|
+
*/
|
|
5
|
+
const CRUD_ACTIONS = new Set(["create", "update", "delete", "get", "query"]);
|
|
6
|
+
/**
|
|
7
|
+
* Generate operations from a WebdaModule
|
|
8
|
+
*
|
|
9
|
+
* This replicates at compile time what DomainService.initOperations() does at runtime.
|
|
10
|
+
* It derives operations from model Actions metadata and service/bean operation schemas.
|
|
11
|
+
*
|
|
12
|
+
* @param mod The merged WebdaModule (including dependencies)
|
|
13
|
+
* @returns OperationsExportFormat with operations and referenced schemas
|
|
14
|
+
*/
|
|
15
|
+
export function generateOperations(mod) {
|
|
16
|
+
const result = {
|
|
17
|
+
operations: {},
|
|
18
|
+
schemas: {}
|
|
19
|
+
};
|
|
20
|
+
// Process model operations
|
|
21
|
+
if (mod.models) {
|
|
22
|
+
for (const modelKey of Object.keys(mod.models)) {
|
|
23
|
+
processModelOperations(mod, modelKey, mod.models[modelKey], result);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
// Process service/bean operations from schemas
|
|
27
|
+
processServiceOperations(mod, result);
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Process operations for a single model
|
|
32
|
+
* @param mod - the Webda module
|
|
33
|
+
* @param modelKey - the model identifier
|
|
34
|
+
* @param model - the model metadata
|
|
35
|
+
* @param result - the result to populate
|
|
36
|
+
*/
|
|
37
|
+
function processModelOperations(mod, modelKey, model, result) {
|
|
38
|
+
const shortId = modelKey.split("/").pop();
|
|
39
|
+
const plural = model.Plural || shortId + "s";
|
|
40
|
+
const actions = model.Actions || {};
|
|
41
|
+
const actionNames = Object.keys(actions);
|
|
42
|
+
if (actionNames.length === 0) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
// CRUD operations
|
|
46
|
+
for (const action of actionNames) {
|
|
47
|
+
if (!CRUD_ACTIONS.has(action)) {
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
const capitalized = action.charAt(0).toUpperCase() + action.slice(1);
|
|
51
|
+
switch (action) {
|
|
52
|
+
case "create":
|
|
53
|
+
addOperation(result, `${shortId}.${capitalized}`, {
|
|
54
|
+
output: modelKey
|
|
55
|
+
});
|
|
56
|
+
addModelSchema(mod, modelKey, result);
|
|
57
|
+
break;
|
|
58
|
+
case "update":
|
|
59
|
+
addOperation(result, `${shortId}.${capitalized}`, {
|
|
60
|
+
input: "uuidRequest",
|
|
61
|
+
output: modelKey
|
|
62
|
+
});
|
|
63
|
+
// Also add Patch operation
|
|
64
|
+
addOperation(result, `${shortId}.Patch`, {
|
|
65
|
+
input: "uuidRequest"
|
|
66
|
+
});
|
|
67
|
+
addModelSchema(mod, modelKey, result);
|
|
68
|
+
break;
|
|
69
|
+
case "delete":
|
|
70
|
+
addOperation(result, `${shortId}.${capitalized}`, {
|
|
71
|
+
input: "uuidRequest"
|
|
72
|
+
});
|
|
73
|
+
break;
|
|
74
|
+
case "get":
|
|
75
|
+
addOperation(result, `${shortId}.${capitalized}`, {
|
|
76
|
+
input: "uuidRequest",
|
|
77
|
+
output: modelKey
|
|
78
|
+
});
|
|
79
|
+
addModelSchema(mod, modelKey, result);
|
|
80
|
+
break;
|
|
81
|
+
case "query":
|
|
82
|
+
addOperation(result, `${plural}.Query`, {
|
|
83
|
+
input: "searchRequest"
|
|
84
|
+
});
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Custom action operations
|
|
89
|
+
for (const action of actionNames) {
|
|
90
|
+
if (CRUD_ACTIONS.has(action)) {
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
const capitalized = action.charAt(0).toUpperCase() + action.slice(1);
|
|
94
|
+
const id = `${shortId}.${capitalized}`;
|
|
95
|
+
const inputSchema = `${modelKey}.${action}.input`;
|
|
96
|
+
const outputSchema = `${modelKey}.${action}.output`;
|
|
97
|
+
const entry = {};
|
|
98
|
+
// Instance actions require a uuid; global (static) ones use their own input schema
|
|
99
|
+
if (!actions[action].global) {
|
|
100
|
+
entry.input = "uuidRequest";
|
|
101
|
+
}
|
|
102
|
+
else if (mod.schemas?.[inputSchema]) {
|
|
103
|
+
entry.input = inputSchema;
|
|
104
|
+
result.schemas[inputSchema] = mod.schemas[inputSchema];
|
|
105
|
+
}
|
|
106
|
+
if (mod.schemas?.[outputSchema]) {
|
|
107
|
+
entry.output = outputSchema;
|
|
108
|
+
result.schemas[outputSchema] = mod.schemas[outputSchema];
|
|
109
|
+
}
|
|
110
|
+
addOperation(result, id, entry);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Process service and bean operations from schema naming convention
|
|
115
|
+
*
|
|
116
|
+
* Operations on services/beans are detected by schemas following the pattern:
|
|
117
|
+
* {ClassName}.{methodName}.input / {ClassName}.{methodName}.output
|
|
118
|
+
* @param mod - the Webda module
|
|
119
|
+
* @param result - the result to populate
|
|
120
|
+
*/
|
|
121
|
+
function processServiceOperations(mod, result) {
|
|
122
|
+
if (!mod.schemas) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
// Collect all service/bean class names (short names without namespace)
|
|
126
|
+
const serviceClasses = new Set();
|
|
127
|
+
for (const key of Object.keys(mod.beans || {})) {
|
|
128
|
+
serviceClasses.add(key.split("/").pop());
|
|
129
|
+
}
|
|
130
|
+
for (const key of Object.keys(mod.moddas || {})) {
|
|
131
|
+
serviceClasses.add(key.split("/").pop());
|
|
132
|
+
}
|
|
133
|
+
// Find operation schemas that belong to services/beans (not models)
|
|
134
|
+
// Pattern: {ClassName}.{methodName}.input
|
|
135
|
+
const operationPattern = /^([^.]+)\.([^.]+)\.(input|output)$/;
|
|
136
|
+
const detectedOps = new Map();
|
|
137
|
+
for (const schemaName of Object.keys(mod.schemas)) {
|
|
138
|
+
const match = schemaName.match(operationPattern);
|
|
139
|
+
if (!match) {
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
const [, className, methodName, kind] = match;
|
|
143
|
+
// Only process if this class is a known service/bean
|
|
144
|
+
if (!serviceClasses.has(className)) {
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
const capitalized = methodName.charAt(0).toUpperCase() + methodName.slice(1);
|
|
148
|
+
const opId = `${className}.${capitalized}`;
|
|
149
|
+
if (!detectedOps.has(opId)) {
|
|
150
|
+
detectedOps.set(opId, {});
|
|
151
|
+
}
|
|
152
|
+
const op = detectedOps.get(opId);
|
|
153
|
+
op[kind] = schemaName;
|
|
154
|
+
}
|
|
155
|
+
// Register detected operations
|
|
156
|
+
for (const [opId, schemas] of detectedOps) {
|
|
157
|
+
const entry = {};
|
|
158
|
+
if (schemas.input) {
|
|
159
|
+
entry.input = schemas.input;
|
|
160
|
+
result.schemas[schemas.input] = mod.schemas[schemas.input];
|
|
161
|
+
}
|
|
162
|
+
if (schemas.output) {
|
|
163
|
+
entry.output = schemas.output;
|
|
164
|
+
result.schemas[schemas.output] = mod.schemas[schemas.output];
|
|
165
|
+
}
|
|
166
|
+
// addOperation defaults missing input/output to "void"
|
|
167
|
+
addOperation(result, opId, entry);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Add an operation to the result
|
|
172
|
+
* @param result - the operations result
|
|
173
|
+
* @param id - the operation identifier
|
|
174
|
+
* @param entry - the operation entry data
|
|
175
|
+
*/
|
|
176
|
+
function addOperation(result, id, entry) {
|
|
177
|
+
result.operations[id] = {
|
|
178
|
+
id,
|
|
179
|
+
input: "void",
|
|
180
|
+
output: "void",
|
|
181
|
+
...entry
|
|
182
|
+
};
|
|
183
|
+
useLog("DEBUG", `Registered operation: ${id}`);
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Add model schema to the result if available
|
|
187
|
+
* @param mod - the Webda module
|
|
188
|
+
* @param modelKey - the model identifier
|
|
189
|
+
* @param result - the operations result
|
|
190
|
+
*/
|
|
191
|
+
function addModelSchema(mod, modelKey, result) {
|
|
192
|
+
const model = mod.models?.[modelKey];
|
|
193
|
+
if (model?.Schemas?.Input) {
|
|
194
|
+
result.schemas[modelKey] ??= model.Schemas.Input;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=operations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operations.js","sourceRoot":"","sources":["../src/operations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/** A Webda class declared in a file the content mapper cannot claim. */
|
|
2
|
+
export interface NamingViolation {
|
|
3
|
+
/** Absolute path of the offending source file. */
|
|
4
|
+
fileName: string;
|
|
5
|
+
/** Class that triggered the requirement. */
|
|
6
|
+
className: string;
|
|
7
|
+
/** Section it was classified into. */
|
|
8
|
+
section: string;
|
|
9
|
+
/** Suffix the file is required to carry. */
|
|
10
|
+
expectedSuffix: string;
|
|
11
|
+
}
|
|
12
|
+
/** What the generator answers for `webda.module.json`. */
|
|
13
|
+
export interface GeneratedModule {
|
|
14
|
+
/** Every section of the module. */
|
|
15
|
+
module: Record<string, unknown>;
|
|
16
|
+
/** Classes in files the mapper cannot claim. */
|
|
17
|
+
namingViolations: NamingViolation[];
|
|
18
|
+
/** Conditions the TypeScript 6 generator threw on. */
|
|
19
|
+
errors: string[];
|
|
20
|
+
}
|
|
21
|
+
/** What the emit reports. */
|
|
22
|
+
export interface EmitReport {
|
|
23
|
+
/** Pass-2 diagnostics, formatted as `tsc` prints them. */
|
|
24
|
+
diagnostics: string;
|
|
25
|
+
/** Number of diagnostics; nothing was written unless it is zero. */
|
|
26
|
+
diagnosticCount: number;
|
|
27
|
+
/** Files written. */
|
|
28
|
+
written: number;
|
|
29
|
+
/** Edits per generator. */
|
|
30
|
+
editCounts: Record<string, number>;
|
|
31
|
+
}
|
|
32
|
+
/** One build's answer. */
|
|
33
|
+
export interface BuildResult {
|
|
34
|
+
emit: EmitReport;
|
|
35
|
+
/** Absent when `emit` failed, since the module is not generated then. */
|
|
36
|
+
module?: GeneratedModule;
|
|
37
|
+
}
|
|
38
|
+
/** Options the build passes through to the generator. */
|
|
39
|
+
export interface BuildOptions {
|
|
40
|
+
/** Namespace prefix for unqualified names. */
|
|
41
|
+
namespace?: string;
|
|
42
|
+
/** `webda.capabilities` from the application's package.json. */
|
|
43
|
+
capabilities?: unknown;
|
|
44
|
+
/** Skip module generation; emit only. */
|
|
45
|
+
emitOnly?: boolean;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Emit a project and generate its module, in one worker round trip.
|
|
49
|
+
* @param projectRoot - application root, used as cwd and project path
|
|
50
|
+
* @param options - namespace and capabilities
|
|
51
|
+
* @returns the emit report and, when it succeeded, the generated module
|
|
52
|
+
* @throws when the worker cannot be run or rejects a request outright
|
|
53
|
+
*/
|
|
54
|
+
export declare function build(projectRoot: string, options?: BuildOptions): BuildResult;
|
|
55
|
+
//# sourceMappingURL=schema-backend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-backend.d.ts","sourceRoot":"","sources":["../src/schema-backend.ts"],"names":[],"mappings":"AAyBA,wEAAwE;AACxE,MAAM,WAAW,eAAe;IAC9B,kDAAkD;IAClD,QAAQ,EAAE,MAAM,CAAC;IACjB,4CAA4C;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,0DAA0D;AAC1D,MAAM,WAAW,eAAe;IAC9B,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,gDAAgD;IAChD,gBAAgB,EAAE,eAAe,EAAE,CAAC;IACpC,sDAAsD;IACtD,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,6BAA6B;AAC7B,MAAM,WAAW,UAAU;IACzB,0DAA0D;IAC1D,WAAW,EAAE,MAAM,CAAC;IACpB,oEAAoE;IACpE,eAAe,EAAE,MAAM,CAAC;IACxB,qBAAqB;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,2BAA2B;IAC3B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAED,0BAA0B;AAC1B,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,UAAU,CAAC;IACjB,yEAAyE;IACzE,MAAM,CAAC,EAAE,eAAe,CAAC;CAC1B;AAED,yDAAyD;AACzD,MAAM,WAAW,YAAY;IAC3B,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gEAAgE;IAChE,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAgCD;;;;;;GAMG;AACH,wBAAgB,KAAK,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,WAAW,CAwBlF"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The TypeScript 7.1 build, driven out of process.
|
|
3
|
+
*
|
|
4
|
+
* `webdac build` used to emit with `tsProgram.emit` and four
|
|
5
|
+
* `@webda/ts-plugin` transformers, then walk the TypeScript 6 program to
|
|
6
|
+
* generate `webda.module.json`. TypeScript 7 removed emit transformers, so
|
|
7
|
+
* both halves now run in `@webda/content-mapper` on the 7.1 checker:
|
|
8
|
+
*
|
|
9
|
+
* - **emit** — the two-pass build: generate accessors, behaviours and
|
|
10
|
+
* WebdaQL rewrites into the source, type-check that, and write what was
|
|
11
|
+
* checked. Nothing is written when pass 2 reports a diagnostic.
|
|
12
|
+
* - **module** — every section of `webda.module.json`, byte for byte as the
|
|
13
|
+
* TypeScript 6 generator produced it.
|
|
14
|
+
*
|
|
15
|
+
* It is spawned rather than imported: the content mapper peers on
|
|
16
|
+
* `typescript@>=7.1.0-dev`, and a process boundary is what lets it run
|
|
17
|
+
* whatever TypeScript this package resolves. One spawn per build, because
|
|
18
|
+
* opening the program dominates.
|
|
19
|
+
*/
|
|
20
|
+
import { spawnSync } from "node:child_process";
|
|
21
|
+
import { createRequire } from "node:module";
|
|
22
|
+
import { existsSync } from "node:fs";
|
|
23
|
+
import { dirname, join } from "node:path";
|
|
24
|
+
import { useLog } from "@webda/workout";
|
|
25
|
+
/**
|
|
26
|
+
* Locate the content mapper's worker.
|
|
27
|
+
*
|
|
28
|
+
* `WEBDA_SCHEMA_WORKER` overrides it, for running a generator that is not the
|
|
29
|
+
* installed one — bisecting a change, or building from source. Otherwise the
|
|
30
|
+
* application is searched first, so it can pin a version, then this package.
|
|
31
|
+
* @param projectRoot - application root
|
|
32
|
+
* @returns absolute path of the worker entry point
|
|
33
|
+
* @throws when the package is not installed
|
|
34
|
+
*/
|
|
35
|
+
function resolveWorker(projectRoot) {
|
|
36
|
+
const override = process.env.WEBDA_SCHEMA_WORKER;
|
|
37
|
+
if (override) {
|
|
38
|
+
if (!existsSync(override))
|
|
39
|
+
throw new Error(`WEBDA_SCHEMA_WORKER does not exist: ${override}`);
|
|
40
|
+
return override;
|
|
41
|
+
}
|
|
42
|
+
for (const base of [projectRoot, dirname(new URL(import.meta.url).pathname)]) {
|
|
43
|
+
try {
|
|
44
|
+
const worker = createRequire(join(base, "index.js")).resolve("@webda/content-mapper/schema-worker-cli");
|
|
45
|
+
if (existsSync(worker))
|
|
46
|
+
return worker;
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// Not resolvable from here; try the next base.
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
throw new Error("Building requires @webda/content-mapper to be installed and built (lib/schema/worker-cli.js). " +
|
|
53
|
+
"Install it alongside @webda/compiler, or point WEBDA_SCHEMA_WORKER at the worker.");
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Emit a project and generate its module, in one worker round trip.
|
|
57
|
+
* @param projectRoot - application root, used as cwd and project path
|
|
58
|
+
* @param options - namespace and capabilities
|
|
59
|
+
* @returns the emit report and, when it succeeded, the generated module
|
|
60
|
+
* @throws when the worker cannot be run or rejects a request outright
|
|
61
|
+
*/
|
|
62
|
+
export function build(projectRoot, options = {}) {
|
|
63
|
+
const requests = [{ id: "emit", kind: "emit" }];
|
|
64
|
+
if (!options.emitOnly) {
|
|
65
|
+
requests.push({ id: "module", kind: "module", namespace: options.namespace, capabilities: options.capabilities });
|
|
66
|
+
}
|
|
67
|
+
const started = Date.now();
|
|
68
|
+
const run = spawnSync(process.execPath, [resolveWorker(projectRoot)], {
|
|
69
|
+
cwd: projectRoot,
|
|
70
|
+
input: JSON.stringify({ project: projectRoot, requests }),
|
|
71
|
+
encoding: "utf8",
|
|
72
|
+
maxBuffer: 256 * 1024 * 1024
|
|
73
|
+
});
|
|
74
|
+
if (run.status !== 0) {
|
|
75
|
+
throw new Error(`Build worker failed (${run.status}): ${(run.stderr || "").trim().slice(0, 4000)}`);
|
|
76
|
+
}
|
|
77
|
+
const response = JSON.parse(run.stdout);
|
|
78
|
+
const failed = Object.entries(response.errors ?? {});
|
|
79
|
+
if (failed.length) {
|
|
80
|
+
throw new Error(`Build worker rejected ${failed.map(([id, message]) => `${id}: ${message}`).join("; ")}`);
|
|
81
|
+
}
|
|
82
|
+
const emit = response.results.emit;
|
|
83
|
+
useLog("DEBUG", `Build worker: ${emit.written} files, edits ${JSON.stringify(emit.editCounts)}, ${Date.now() - started}ms`);
|
|
84
|
+
return { emit, module: emit.diagnosticCount === 0 ? response.results.module : undefined };
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=schema-backend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-backend.js","sourceRoot":"","sources":["../src/schema-backend.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read `webda.config.json#session` (a model id like `MyApp/Session`),
|
|
3
|
+
* resolve it via `webda.module.json` to an import path, and emit
|
|
4
|
+
* `.webda/session-types.d.ts` with a module augmentation that fills the
|
|
5
|
+
* `WebdaSessionRegistry["session"]` slot.
|
|
6
|
+
*
|
|
7
|
+
* The augmentation is a plain `.d.ts` file under the project — it is picked
|
|
8
|
+
* up by `tsc` via the user's standard tsconfig include, so editor feedback
|
|
9
|
+
* works without a content mapper loaded.
|
|
10
|
+
*
|
|
11
|
+
* @param projectRoot absolute path to the project root (where webda.config.json lives)
|
|
12
|
+
*/
|
|
13
|
+
export declare function generateSessionTypes(projectRoot: string): void;
|
|
14
|
+
//# sourceMappingURL=session-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-types.d.ts","sourceRoot":"","sources":["../src/session-types.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAiD9D"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join, relative } from "node:path";
|
|
3
|
+
import { useLog } from "@webda/workout";
|
|
4
|
+
/**
|
|
5
|
+
* Read `webda.config.json#session` (a model id like `MyApp/Session`),
|
|
6
|
+
* resolve it via `webda.module.json` to an import path, and emit
|
|
7
|
+
* `.webda/session-types.d.ts` with a module augmentation that fills the
|
|
8
|
+
* `WebdaSessionRegistry["session"]` slot.
|
|
9
|
+
*
|
|
10
|
+
* The augmentation is a plain `.d.ts` file under the project — it is picked
|
|
11
|
+
* up by `tsc` via the user's standard tsconfig include, so editor feedback
|
|
12
|
+
* works without a content mapper loaded.
|
|
13
|
+
*
|
|
14
|
+
* @param projectRoot absolute path to the project root (where webda.config.json lives)
|
|
15
|
+
*/
|
|
16
|
+
export function generateSessionTypes(projectRoot) {
|
|
17
|
+
const configPath = join(projectRoot, "webda.config.json");
|
|
18
|
+
if (!existsSync(configPath))
|
|
19
|
+
return;
|
|
20
|
+
const config = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
21
|
+
if (!config.session)
|
|
22
|
+
return;
|
|
23
|
+
const modulePath = join(projectRoot, "webda.module.json");
|
|
24
|
+
if (!existsSync(modulePath)) {
|
|
25
|
+
throw new Error(`Cannot resolve session model "${config.session}": webda.module.json is missing`);
|
|
26
|
+
}
|
|
27
|
+
const mod = JSON.parse(readFileSync(modulePath, "utf-8"));
|
|
28
|
+
const models = mod.models?.list ?? {};
|
|
29
|
+
const importDescriptor = resolveModelImport(models, config.session);
|
|
30
|
+
if (!importDescriptor) {
|
|
31
|
+
throw new Error(`Cannot resolve session model "${config.session}" in webda.module.json: not declared`);
|
|
32
|
+
}
|
|
33
|
+
const [importFile, exportName] = importDescriptor.split(":");
|
|
34
|
+
const outDir = join(projectRoot, ".webda");
|
|
35
|
+
if (!existsSync(outDir))
|
|
36
|
+
mkdirSync(outDir, { recursive: true });
|
|
37
|
+
const outPath = join(outDir, "session-types.d.ts");
|
|
38
|
+
let importTarget;
|
|
39
|
+
if (importFile.startsWith(".") || importFile.startsWith("/")) {
|
|
40
|
+
const absImportFile = importFile.startsWith("/") ? importFile : join(projectRoot, importFile);
|
|
41
|
+
importTarget = relative(outDir, absImportFile)
|
|
42
|
+
.replace(/\\/g, "/")
|
|
43
|
+
.replace(/\.tsx?$/, ".js");
|
|
44
|
+
if (!importTarget.startsWith("."))
|
|
45
|
+
importTarget = "./" + importTarget;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
importTarget = importFile;
|
|
49
|
+
}
|
|
50
|
+
const content = `// AUTO-GENERATED by @webda/compiler — do not edit\n` +
|
|
51
|
+
`import type { ${exportName} as __ResolvedSession } from "${importTarget}";\n` +
|
|
52
|
+
`declare module "@webda/core" {\n` +
|
|
53
|
+
` interface WebdaSessionRegistry {\n` +
|
|
54
|
+
` session: __ResolvedSession;\n` +
|
|
55
|
+
` }\n` +
|
|
56
|
+
`}\n`;
|
|
57
|
+
writeFileSync(outPath, content);
|
|
58
|
+
useLog("INFO", `Generated session types at ${relative(projectRoot, outPath)}`);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Look up a model id in the module's models list. Accepts both fully
|
|
62
|
+
* qualified ids (`MyApp/Session`) and bare class names (`Session`); for the
|
|
63
|
+
* latter, returns the first matching declaration.
|
|
64
|
+
* @param models - the flat record of model ids to import descriptors from webda.module.json
|
|
65
|
+
* @param id - the model id to look up (e.g. `MyApp/Session` or bare `Session`)
|
|
66
|
+
* @returns the import descriptor string `"<file>:<ExportName>"`, or undefined if not found
|
|
67
|
+
*/
|
|
68
|
+
function resolveModelImport(models, id) {
|
|
69
|
+
if (models[id])
|
|
70
|
+
return models[id];
|
|
71
|
+
if (!id.includes("/")) {
|
|
72
|
+
for (const key of Object.keys(models)) {
|
|
73
|
+
if (key.split("/").pop() === id)
|
|
74
|
+
return models[key];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=session-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-types.js","sourceRoot":"","sources":["../src/session-types.ts"],"names":[],"mappings":"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"}
|