@open-rap/compiler 0.0.0-stage → 0.1.1
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 +21 -0
- package/README.md +21 -2
- package/dist/agent/server.d.ts +35 -0
- package/dist/agent/server.js +408 -0
- package/dist/agent/server.js.map +1 -0
- package/dist/authoring/abapgit.d.ts +38 -0
- package/dist/authoring/abapgit.js +242 -0
- package/dist/authoring/abapgit.js.map +1 -0
- package/dist/authoring/catalog.d.ts +48 -0
- package/dist/authoring/catalog.js +117 -0
- package/dist/authoring/catalog.js.map +1 -0
- package/dist/authoring/floorplan.d.ts +28 -0
- package/dist/authoring/floorplan.js +31 -0
- package/dist/authoring/floorplan.js.map +1 -0
- package/dist/authoring/generate.d.ts +57 -0
- package/dist/authoring/generate.js +630 -0
- package/dist/authoring/generate.js.map +1 -0
- package/dist/authoring/mcp.d.ts +15 -0
- package/dist/authoring/mcp.js +52 -0
- package/dist/authoring/mcp.js.map +1 -0
- package/dist/authoring/new.d.ts +35 -0
- package/dist/authoring/new.js +389 -0
- package/dist/authoring/new.js.map +1 -0
- package/dist/bdef/ast.d.ts +249 -0
- package/dist/bdef/ast.js +3 -0
- package/dist/bdef/ast.js.map +1 -0
- package/dist/bdef/lexer.d.ts +105 -0
- package/dist/bdef/lexer.js +148 -0
- package/dist/bdef/lexer.js.map +1 -0
- package/dist/bdef/parser.d.ts +22 -0
- package/dist/bdef/parser.js +1012 -0
- package/dist/bdef/parser.js.map +1 -0
- package/dist/build.d.ts +26 -0
- package/dist/build.js +62 -0
- package/dist/build.js.map +1 -0
- package/dist/cds/adapter.d.ts +91 -0
- package/dist/cds/adapter.js +381 -0
- package/dist/cds/adapter.js.map +1 -0
- package/dist/cds/expression-ast.d.ts +65 -0
- package/dist/cds/expression-ast.js +330 -0
- package/dist/cds/expression-ast.js.map +1 -0
- package/dist/cli.d.ts +9 -0
- package/dist/cli.js +485 -0
- package/dist/cli.js.map +1 -0
- package/dist/dcl/parser.d.ts +59 -0
- package/dist/dcl/parser.js +338 -0
- package/dist/dcl/parser.js.map +1 -0
- package/dist/ddic/catalog.d.ts +17 -0
- package/dist/ddic/catalog.js +211 -0
- package/dist/ddic/catalog.js.map +1 -0
- package/dist/ddic/cds-types.d.ts +47 -0
- package/dist/ddic/cds-types.js +131 -0
- package/dist/ddic/cds-types.js.map +1 -0
- package/dist/ddic/table-source.d.ts +70 -0
- package/dist/ddic/table-source.js +500 -0
- package/dist/ddic/table-source.js.map +1 -0
- package/dist/ddic/xml.d.ts +65 -0
- package/dist/ddic/xml.js +201 -0
- package/dist/ddic/xml.js.map +1 -0
- package/dist/dev.d.ts +128 -0
- package/dist/dev.js +434 -0
- package/dist/dev.js.map +1 -0
- package/dist/diagnostics.d.ts +33 -0
- package/dist/diagnostics.js +53 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/gen/abap/derived-types.d.ts +26 -0
- package/dist/gen/abap/derived-types.js +323 -0
- package/dist/gen/abap/derived-types.js.map +1 -0
- package/dist/gen/abap/eml.d.ts +118 -0
- package/dist/gen/abap/eml.js +362 -0
- package/dist/gen/abap/eml.js.map +1 -0
- package/dist/gen/abap/enums.d.ts +13 -0
- package/dist/gen/abap/enums.js +74 -0
- package/dist/gen/abap/enums.js.map +1 -0
- package/dist/gen/abap/framework-http.d.ts +14 -0
- package/dist/gen/abap/framework-http.js +1049 -0
- package/dist/gen/abap/framework-http.js.map +1 -0
- package/dist/gen/abap/framework-query.d.ts +14 -0
- package/dist/gen/abap/framework-query.js +225 -0
- package/dist/gen/abap/framework-query.js.map +1 -0
- package/dist/gen/abap/framework-utils.d.ts +29 -0
- package/dist/gen/abap/framework-utils.js +3707 -0
- package/dist/gen/abap/framework-utils.js.map +1 -0
- package/dist/gen/abap/framework.d.ts +12 -0
- package/dist/gen/abap/framework.js +480 -0
- package/dist/gen/abap/framework.js.map +1 -0
- package/dist/gen/abap/generate.d.ts +40 -0
- package/dist/gen/abap/generate.js +238 -0
- package/dist/gen/abap/generate.js.map +1 -0
- package/dist/gen/abap/rewrite.d.ts +82 -0
- package/dist/gen/abap/rewrite.js +957 -0
- package/dist/gen/abap/rewrite.js.map +1 -0
- package/dist/gen/abap/shadow.d.ts +25 -0
- package/dist/gen/abap/shadow.js +175 -0
- package/dist/gen/abap/shadow.js.map +1 -0
- package/dist/gen/abap/tokens.d.ts +33 -0
- package/dist/gen/abap/tokens.js +87 -0
- package/dist/gen/abap/tokens.js.map +1 -0
- package/dist/gen/app/index.d.ts +25 -0
- package/dist/gen/app/index.js +322 -0
- package/dist/gen/app/index.js.map +1 -0
- package/dist/gen/csdl.d.ts +11 -0
- package/dist/gen/csdl.js +562 -0
- package/dist/gen/csdl.js.map +1 -0
- package/dist/gen/deploy.d.ts +12 -0
- package/dist/gen/deploy.js +53 -0
- package/dist/gen/deploy.js.map +1 -0
- package/dist/gen/docs/index.d.ts +35 -0
- package/dist/gen/docs/index.js +267 -0
- package/dist/gen/docs/index.js.map +1 -0
- package/dist/gen/docs/markdown.d.ts +23 -0
- package/dist/gen/docs/markdown.js +187 -0
- package/dist/gen/docs/markdown.js.map +1 -0
- package/dist/gen/docs/site.d.ts +17 -0
- package/dist/gen/docs/site.js +106 -0
- package/dist/gen/docs/site.js.map +1 -0
- package/dist/gen/keycloak.d.ts +21 -0
- package/dist/gen/keycloak.js +90 -0
- package/dist/gen/keycloak.js.map +1 -0
- package/dist/gen/launchpad/index.d.ts +48 -0
- package/dist/gen/launchpad/index.js +302 -0
- package/dist/gen/launchpad/index.js.map +1 -0
- package/dist/gen/launchpad/ui.d.ts +14 -0
- package/dist/gen/launchpad/ui.js +350 -0
- package/dist/gen/launchpad/ui.js.map +1 -0
- package/dist/gen/mcp.d.ts +23 -0
- package/dist/gen/mcp.js +244 -0
- package/dist/gen/mcp.js.map +1 -0
- package/dist/gen/sql-expressions.d.ts +12 -0
- package/dist/gen/sql-expressions.js +136 -0
- package/dist/gen/sql-expressions.js.map +1 -0
- package/dist/gen/sql.d.ts +38 -0
- package/dist/gen/sql.js +612 -0
- package/dist/gen/sql.js.map +1 -0
- package/dist/gen/ui/index.d.ts +7 -0
- package/dist/gen/ui/index.js +27 -0
- package/dist/gen/ui/index.js.map +1 -0
- package/dist/gen/ui/layout.d.ts +230 -0
- package/dist/gen/ui/layout.js +511 -0
- package/dist/gen/ui/layout.js.map +1 -0
- package/dist/gen/ui/static.d.ts +55 -0
- package/dist/gen/ui/static.js +2901 -0
- package/dist/gen/ui/static.js.map +1 -0
- package/dist/gen/ui/views.d.ts +10 -0
- package/dist/gen/ui/views.js +511 -0
- package/dist/gen/ui/views.js.map +1 -0
- package/dist/gen/vendor.d.ts +23 -0
- package/dist/gen/vendor.js +68 -0
- package/dist/gen/vendor.js.map +1 -0
- package/dist/gen/xml.d.ts +9 -0
- package/dist/gen/xml.js +42 -0
- package/dist/gen/xml.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/input/project.d.ts +50 -0
- package/dist/input/project.js +128 -0
- package/dist/input/project.js.map +1 -0
- package/dist/ir/access-controls.d.ts +11 -0
- package/dist/ir/access-controls.js +148 -0
- package/dist/ir/access-controls.js.map +1 -0
- package/dist/ir/authorizations.d.ts +25 -0
- package/dist/ir/authorizations.js +178 -0
- package/dist/ir/authorizations.js.map +1 -0
- package/dist/ir/behaviors.d.ts +16 -0
- package/dist/ir/behaviors.js +548 -0
- package/dist/ir/behaviors.js.map +1 -0
- package/dist/ir/builder.d.ts +20 -0
- package/dist/ir/builder.js +505 -0
- package/dist/ir/builder.js.map +1 -0
- package/dist/ir/config.d.ts +25 -0
- package/dist/ir/config.js +130 -0
- package/dist/ir/config.js.map +1 -0
- package/dist/ir/dictionary.d.ts +54 -0
- package/dist/ir/dictionary.js +328 -0
- package/dist/ir/dictionary.js.map +1 -0
- package/dist/ir/entities.d.ts +58 -0
- package/dist/ir/entities.js +676 -0
- package/dist/ir/entities.js.map +1 -0
- package/dist/ir/expressions.d.ts +33 -0
- package/dist/ir/expressions.js +327 -0
- package/dist/ir/expressions.js.map +1 -0
- package/dist/ir/handlers.d.ts +63 -0
- package/dist/ir/handlers.js +398 -0
- package/dist/ir/handlers.js.map +1 -0
- package/dist/ir/number-ranges.d.ts +24 -0
- package/dist/ir/number-ranges.js +74 -0
- package/dist/ir/number-ranges.js.map +1 -0
- package/dist/ir/seed.d.ts +23 -0
- package/dist/ir/seed.js +78 -0
- package/dist/ir/seed.js.map +1 -0
- package/dist/ir/service.d.ts +21 -0
- package/dist/ir/service.js +96 -0
- package/dist/ir/service.js.map +1 -0
- package/dist/launchpad/config.d.ts +47 -0
- package/dist/launchpad/config.js +321 -0
- package/dist/launchpad/config.js.map +1 -0
- package/dist/launchpad/workspace.d.ts +48 -0
- package/dist/launchpad/workspace.js +166 -0
- package/dist/launchpad/workspace.js.map +1 -0
- package/dist/srvd/parser.d.ts +36 -0
- package/dist/srvd/parser.js +193 -0
- package/dist/srvd/parser.js.map +1 -0
- package/dist/standard/data.d.ts +18 -0
- package/dist/standard/data.js +534 -0
- package/dist/standard/data.js.map +1 -0
- package/dist/standard/index.d.ts +36 -0
- package/dist/standard/index.js +507 -0
- package/dist/standard/index.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.js +4 -0
- package/dist/version.js.map +1 -0
- package/docs/AGENTS.md +79 -0
- package/docs/ANNOTATIONS.md +76 -0
- package/docs/DECISIONS.md +1554 -0
- package/docs/DEPLOYMENT.md +113 -0
- package/docs/DIAGNOSTICS.md +116 -0
- package/docs/FEATURES.md +287 -0
- package/docs/GUIDE.md +560 -0
- package/docs/KNOWN_GAPS.md +216 -0
- package/docs/MCP.md +84 -0
- package/docs/PLAN.md +690 -0
- package/docs/README.md +148 -0
- package/docs/REMOTE_APIS.md +121 -0
- package/docs/ROADMAP.md +35 -0
- package/docs/UTILITIES.md +95 -0
- package/package.json +49 -3
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Behavior pools: ABAP syntax check (abaplint) and discovery of the handler methods that
|
|
3
|
+
* implement the validations, determinations, actions, authorizations and feature controls.
|
|
4
|
+
*/
|
|
5
|
+
import * as abaplint from "@abaplint/core";
|
|
6
|
+
import { same } from "@open-rap/model";
|
|
7
|
+
const ABAP_TYPES = new Set(["CLAS", "INTF", "BDEF", "DDLS", "DDLX", "TABL", "DTEL", "DOMA", "SRVD", "MSAG", "DEVC", "TTYP"]);
|
|
8
|
+
export function abaplintRegistry(project) {
|
|
9
|
+
const config = new abaplint.Config(JSON.stringify({
|
|
10
|
+
global: { files: "/**/*.*" },
|
|
11
|
+
syntax: { version: abaplint.Version.Cloud, errorNamespace: "^(Z|Y|LCL_|LHC_|LSC_|TY_|LIF_)" },
|
|
12
|
+
rules: { parser_error: true },
|
|
13
|
+
}));
|
|
14
|
+
const registry = new abaplint.Registry(config);
|
|
15
|
+
for (const file of project.files) {
|
|
16
|
+
if (ABAP_TYPES.has(file.type)) {
|
|
17
|
+
registry.addFile(new abaplint.MemoryFile(file.fileName, file.content));
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
registry.parse();
|
|
21
|
+
return registry;
|
|
22
|
+
}
|
|
23
|
+
const EML_START = /^\s*(?:(?:READ|MODIFY)\s+ENTIT|(?:COMMIT|ROLLBACK)\s+ENTITIES\b)/i;
|
|
24
|
+
/**
|
|
25
|
+
* Parser errors of the behavior pools, on the lines of the original sources. The complete check
|
|
26
|
+
* (types included) runs on the rewritten sources, where the derived types are known
|
|
27
|
+
* (gen/abap/generate.ts). EML statements are parsed by the rewrite pass: abaplint does not know
|
|
28
|
+
* every form of them.
|
|
29
|
+
*/
|
|
30
|
+
export function syntaxCheck(project, registry, classes, diagnostics) {
|
|
31
|
+
const wanted = new Set(classes.map((c) => c.toUpperCase()));
|
|
32
|
+
for (const issue of registry.findIssues()) {
|
|
33
|
+
const key = issue.getKey();
|
|
34
|
+
if (key !== "parser_error") {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
const fileName = issue.getFilename();
|
|
38
|
+
const file = project.files.find((f) => f.fileName === fileName);
|
|
39
|
+
if (file === undefined || (file.type === "CLAS" && !wanted.has(file.name))) {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (file.type !== "CLAS" && file.type !== "INTF") {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
const lines = file.content.split("\n");
|
|
46
|
+
const start = issue.getStart();
|
|
47
|
+
const rest = [(lines[start.getRow() - 1] ?? "").slice(start.getCol() - 1), ...lines.slice(start.getRow(), start.getRow() + 2)].join("\n");
|
|
48
|
+
if (EML_START.test(rest)) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
diagnostics.error("ABP004", `ABAP ${key === "parser_error" ? "syntax" : "check"} error: ${issue.getMessage()}`, {
|
|
52
|
+
file: file.path,
|
|
53
|
+
line: issue.getStart().getRow(),
|
|
54
|
+
column: issue.getStart().getCol(),
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/** Classifies a RAP handler method definition (`METHODS x FOR …`). */
|
|
59
|
+
export function classifyMethodDefinition(statement) {
|
|
60
|
+
const text = statement.replace(/\s+/g, " ").trim().replace(/\.$/, "").trim();
|
|
61
|
+
const head = /^(?:CLASS-)?METHODS (\S+) FOR (.*)$/i.exec(text);
|
|
62
|
+
if (head === null) {
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
const method = (head[1] ?? "").toLowerCase();
|
|
66
|
+
const rest = head[2] ?? "";
|
|
67
|
+
const params = {};
|
|
68
|
+
const lower = (s) => (s ?? "").toLowerCase();
|
|
69
|
+
let m;
|
|
70
|
+
if ((m = /^VALIDATE ON SAVE IMPORTING (\S+) FOR (\S+)~(\S+)$/i.exec(rest))) {
|
|
71
|
+
params.keys = lower(m[1]);
|
|
72
|
+
return { method, kind: { kind: "validation", alias: m[2] ?? "", name: m[3] ?? "" }, params };
|
|
73
|
+
}
|
|
74
|
+
if ((m = /^DETERMINE ON (?:MODIFY|SAVE) IMPORTING (\S+) FOR (\S+)~(\S+)$/i.exec(rest))) {
|
|
75
|
+
params.keys = lower(m[1]);
|
|
76
|
+
return { method, kind: { kind: "determination", alias: m[2] ?? "", name: m[3] ?? "" }, params };
|
|
77
|
+
}
|
|
78
|
+
if ((m = /^MODIFY (?:IMPORTING )?(\S+) FOR ACTION (\S+)~(\S+)(?: (?:REQUEST (\S+) )?RESULT (\S+))?$/i.exec(rest))) {
|
|
79
|
+
params.keys = lower(m[1]);
|
|
80
|
+
if (m[5] !== undefined) {
|
|
81
|
+
params.result = lower(m[5]);
|
|
82
|
+
}
|
|
83
|
+
return { method, kind: { kind: "action", alias: m[2] ?? "", name: m[3] ?? "" }, params };
|
|
84
|
+
}
|
|
85
|
+
if ((m = /^READ (?:IMPORTING )?(\S+) FOR FUNCTION (\S+)~(\S+)(?: (?:REQUEST (\S+) )?RESULT (\S+))?$/i.exec(rest))) {
|
|
86
|
+
params.keys = lower(m[1]);
|
|
87
|
+
if (m[5] !== undefined) {
|
|
88
|
+
params.result = lower(m[5]);
|
|
89
|
+
}
|
|
90
|
+
return { method, kind: { kind: "function", alias: m[2] ?? "", name: m[3] ?? "" }, params };
|
|
91
|
+
}
|
|
92
|
+
if ((m = /^GLOBAL AUTHORIZATION IMPORTING REQUEST (\S+) FOR (\S+) RESULT (\S+)$/i.exec(rest))) {
|
|
93
|
+
params.requested = lower(m[1]);
|
|
94
|
+
params.result = lower(m[3]);
|
|
95
|
+
return { method, kind: { kind: "globalAuthorization", alias: m[2] ?? "" }, params };
|
|
96
|
+
}
|
|
97
|
+
if ((m = /^(?:INSTANCE )?AUTHORIZATION IMPORTING (\S+) REQUEST (\S+) FOR (\S+) RESULT (\S+)$/i.exec(rest))) {
|
|
98
|
+
params.keys = lower(m[1]);
|
|
99
|
+
params.requested = lower(m[2]);
|
|
100
|
+
params.result = lower(m[4]);
|
|
101
|
+
return { method, kind: { kind: "instanceAuthorization", alias: m[3] ?? "" }, params };
|
|
102
|
+
}
|
|
103
|
+
if ((m = /^GLOBAL FEATURES IMPORTING REQUEST (\S+) FOR (\S+) RESULT (\S+)$/i.exec(rest))) {
|
|
104
|
+
params.requested = lower(m[1]);
|
|
105
|
+
params.result = lower(m[3]);
|
|
106
|
+
return { method, kind: { kind: "globalFeatures", alias: m[2] ?? "" }, params };
|
|
107
|
+
}
|
|
108
|
+
if ((m = /^INSTANCE FEATURES IMPORTING (\S+) REQUEST (\S+) FOR (\S+) RESULT (\S+)$/i.exec(rest))) {
|
|
109
|
+
params.keys = lower(m[1]);
|
|
110
|
+
params.requested = lower(m[2]);
|
|
111
|
+
params.result = lower(m[4]);
|
|
112
|
+
return { method, kind: { kind: "instanceFeatures", alias: m[3] ?? "" }, params };
|
|
113
|
+
}
|
|
114
|
+
if ((m = /^NUMBERING IMPORTING (\S+) FOR CREATE (\S+)$/i.exec(rest))) {
|
|
115
|
+
params.entities = lower(m[1]);
|
|
116
|
+
return { method, kind: { kind: "numbering", alias: m[2] ?? "" }, params };
|
|
117
|
+
}
|
|
118
|
+
if ((m = /^PRECHECK IMPORTING (\S+) FOR (CREATE|UPDATE|DELETE) (\S+)$/i.exec(rest))) {
|
|
119
|
+
params.entities = lower(m[1]);
|
|
120
|
+
const target = m[3] ?? "";
|
|
121
|
+
const byAssociation = /^(\S+?)\\(\S+)$/.exec(target);
|
|
122
|
+
if (byAssociation !== null) {
|
|
123
|
+
return { method, kind: { kind: "precheck", alias: byAssociation[1] ?? "", operation: `create:${byAssociation[2] ?? ""}` }, params };
|
|
124
|
+
}
|
|
125
|
+
return { method, kind: { kind: "precheck", alias: target, operation: lower(m[2]) }, params };
|
|
126
|
+
}
|
|
127
|
+
if ((m = /^PRECHECK IMPORTING (\S+) FOR ACTION (\S+)~(\S+)$/i.exec(rest))) {
|
|
128
|
+
params.entities = lower(m[1]);
|
|
129
|
+
return { method, kind: { kind: "precheck", alias: m[2] ?? "", operation: `action:${m[3] ?? ""}` }, params };
|
|
130
|
+
}
|
|
131
|
+
return { method, kind: { kind: "other", text: rest }, params };
|
|
132
|
+
}
|
|
133
|
+
/** Finds the local handler classes of a behavior pool and their RAP methods. */
|
|
134
|
+
function findHandlers(registry, poolName, project) {
|
|
135
|
+
const object = registry.getObject("CLAS", poolName);
|
|
136
|
+
if (!(object instanceof abaplint.Objects.Class)) {
|
|
137
|
+
return [];
|
|
138
|
+
}
|
|
139
|
+
const found = [];
|
|
140
|
+
for (const file of object.getABAPFiles()) {
|
|
141
|
+
const sourceFile = project.files.find((f) => f.fileName === file.getFilename());
|
|
142
|
+
for (const definition of file.getStructure()?.findAllStructures(abaplint.Structures.ClassDefinition) ?? []) {
|
|
143
|
+
const header = definition.findFirstStatement(abaplint.Statements.ClassDefinition);
|
|
144
|
+
const headerText = (header?.concatTokens() ?? "").replace(/\s+/g, " ").replace(/\s*\.$/, "");
|
|
145
|
+
const nameMatch = /^CLASS (\S+) DEFINITION/i.exec(headerText);
|
|
146
|
+
const superMatch = /INHERITING FROM (\S+)/i.exec(headerText);
|
|
147
|
+
const className = (nameMatch?.[1] ?? "").toUpperCase();
|
|
148
|
+
if (superMatch === null || !same(superMatch[1] ?? "", "CL_ABAP_BEHAVIOR_HANDLER")) {
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
for (const statement of definition.findAllStatements(abaplint.Statements.MethodDef)) {
|
|
152
|
+
const classified = classifyMethodDefinition(statement.concatTokens());
|
|
153
|
+
if (classified === undefined) {
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
const params = { failed: "failed", reported: "reported", ...classified.params };
|
|
157
|
+
if (classified.kind.kind === "action" || classified.kind.kind === "numbering") {
|
|
158
|
+
params.mapped = "mapped";
|
|
159
|
+
}
|
|
160
|
+
found.push({
|
|
161
|
+
ref: { classKey: `CLAS-${poolName.toUpperCase()}-${className}`, className, method: classified.method, params },
|
|
162
|
+
what: classified.kind,
|
|
163
|
+
file: sourceFile?.path ?? file.getFilename(),
|
|
164
|
+
line: statement.getStart().getRow(),
|
|
165
|
+
used: false,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return found;
|
|
171
|
+
}
|
|
172
|
+
/** The local saver class of a behavior pool (`INHERITING FROM cl_abap_behavior_saver[_failed]`). */
|
|
173
|
+
function findSaver(registry, poolName, project) {
|
|
174
|
+
const object = registry.getObject("CLAS", poolName);
|
|
175
|
+
if (!(object instanceof abaplint.Objects.Class)) {
|
|
176
|
+
return undefined;
|
|
177
|
+
}
|
|
178
|
+
for (const file of object.getABAPFiles()) {
|
|
179
|
+
const sourceFile = project.files.find((f) => f.fileName === file.getFilename());
|
|
180
|
+
for (const definition of file.getStructure()?.findAllStructures(abaplint.Structures.ClassDefinition) ?? []) {
|
|
181
|
+
const header = definition.findFirstStatement(abaplint.Statements.ClassDefinition);
|
|
182
|
+
const headerText = (header?.concatTokens() ?? "").replace(/\s+/g, " ");
|
|
183
|
+
const superMatch = /INHERITING FROM (\S+)/i.exec(headerText);
|
|
184
|
+
const superclass = (superMatch?.[1] ?? "").replace(/\.$/, "").toUpperCase();
|
|
185
|
+
if (superclass !== "CL_ABAP_BEHAVIOR_SAVER" && superclass !== "CL_ABAP_BEHAVIOR_SAVER_FAILED") {
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
const className = (/^CLASS (\S+) DEFINITION/i.exec(headerText)?.[1] ?? "").toUpperCase();
|
|
189
|
+
const methods = new Map();
|
|
190
|
+
for (const statement of definition.findAllStatements(abaplint.Statements.MethodDef)) {
|
|
191
|
+
const name = statement.getTokens()[1]?.getStr().toLowerCase();
|
|
192
|
+
if (name !== undefined) {
|
|
193
|
+
methods.set(name, statement.getStart().getRow());
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return {
|
|
197
|
+
saver: { classKey: `CLAS-${poolName.toUpperCase()}-${className}`, className, withFailed: superclass === "CL_ABAP_BEHAVIOR_SAVER_FAILED" },
|
|
198
|
+
methods,
|
|
199
|
+
file: sourceFile?.path ?? file.getFilename(),
|
|
200
|
+
line: header?.getStart().getRow() ?? 1,
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return undefined;
|
|
205
|
+
}
|
|
206
|
+
/** The saver class for additional and unmanaged save (save_modified, cleanup). */
|
|
207
|
+
function attachSaver(behavior, pools, registry, project, diagnostics) {
|
|
208
|
+
const needed = behavior.saving !== undefined || behavior.entities.some((e) => e.saving !== undefined);
|
|
209
|
+
let found;
|
|
210
|
+
for (const pool of pools) {
|
|
211
|
+
found ??= findSaver(registry, pool, project);
|
|
212
|
+
}
|
|
213
|
+
if (found === undefined) {
|
|
214
|
+
if (needed) {
|
|
215
|
+
diagnostics.error("ABP002", `${behavior.name}: with additional or unmanaged save, the behavior pool needs a saver class (INHERITING FROM cl_abap_behavior_saver) with save_modified`, behavior.src);
|
|
216
|
+
}
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
if (!needed) {
|
|
220
|
+
diagnostics.warning("ABP003", `saver class ${found.saver.className} is not called: the BDEF has no with additional save or with unmanaged save`, { file: found.file, line: found.line });
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
const ref = (method) => ({
|
|
224
|
+
classKey: found.saver.classKey,
|
|
225
|
+
className: found.saver.className,
|
|
226
|
+
method,
|
|
227
|
+
params: { reported: "reported", ...(found.saver.withFailed ? { failed: "failed" } : {}) },
|
|
228
|
+
});
|
|
229
|
+
if (found.methods.has("save_modified")) {
|
|
230
|
+
found.saver.saveModified = ref("save_modified");
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
diagnostics.error("ABP002", `saver class ${found.saver.className} must redefine save_modified`, { file: found.file, line: found.line });
|
|
234
|
+
}
|
|
235
|
+
if (found.methods.has("cleanup")) {
|
|
236
|
+
found.saver.cleanup = { ...ref("cleanup"), params: {} };
|
|
237
|
+
}
|
|
238
|
+
for (const [method, line] of found.methods) {
|
|
239
|
+
if (method !== "save_modified" && method !== "cleanup") {
|
|
240
|
+
diagnostics.warning("ABP003", `saver method ${method} is not available in a managed BO with additional or unmanaged save and is not called`, { file: found.file, line });
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
behavior.saver = found.saver;
|
|
244
|
+
}
|
|
245
|
+
/** Links the handlers of the behavior pools to the BDEF elements and reports what is missing. */
|
|
246
|
+
/** The behavior, in the same BDEF, of the target of an association of `entity`. */
|
|
247
|
+
function targetBehavior(behavior, entity, association, entities) {
|
|
248
|
+
const source = entities.find((e) => same(e.name, entity.entity));
|
|
249
|
+
const target = source?.associations.find((a) => same(a.name, association))?.target;
|
|
250
|
+
return target === undefined ? undefined : behavior.entities.find((e) => same(e.entity, target));
|
|
251
|
+
}
|
|
252
|
+
export function attachHandlers(behavior, registry, project, diagnostics, entities = []) {
|
|
253
|
+
if (behavior.implementationType !== "managed") {
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
const pools = new Set();
|
|
257
|
+
if (behavior.implementationClass !== undefined) {
|
|
258
|
+
pools.add(behavior.implementationClass);
|
|
259
|
+
}
|
|
260
|
+
for (const entity of behavior.entities) {
|
|
261
|
+
if (entity.implementationClass !== undefined) {
|
|
262
|
+
pools.add(entity.implementationClass);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
const handlers = [];
|
|
266
|
+
for (const pool of pools) {
|
|
267
|
+
const object = registry.getObject("CLAS", pool);
|
|
268
|
+
if (object === undefined) {
|
|
269
|
+
diagnostics.error("ABP001", `behavior pool ${pool} not found in the sources`, behavior.src);
|
|
270
|
+
continue;
|
|
271
|
+
}
|
|
272
|
+
handlers.push(...findHandlers(registry, pool, project));
|
|
273
|
+
}
|
|
274
|
+
attachSaver(behavior, pools, registry, project, diagnostics);
|
|
275
|
+
const take = (entity, predicate) => {
|
|
276
|
+
const handler = handlers.find((h) => "alias" in h.what && (same(h.what.alias, entity.alias) || same(h.what.alias, entity.entity)) && predicate(h));
|
|
277
|
+
if (handler !== undefined) {
|
|
278
|
+
handler.used = true;
|
|
279
|
+
}
|
|
280
|
+
return handler?.ref;
|
|
281
|
+
};
|
|
282
|
+
for (const entity of behavior.entities) {
|
|
283
|
+
for (const validation of entity.validations) {
|
|
284
|
+
const ref = take(entity, (h) => h.what.kind === "validation" && same(h.what.name, validation.name));
|
|
285
|
+
if (ref === undefined) {
|
|
286
|
+
diagnostics.error("ABP002", `no handler method FOR VALIDATE ON SAVE for ${entity.alias}~${validation.name}`, validation.src);
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
validation.handler = ref;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
for (const determination of entity.determinations) {
|
|
293
|
+
const ref = take(entity, (h) => h.what.kind === "determination" && same(h.what.name, determination.name));
|
|
294
|
+
if (ref === undefined) {
|
|
295
|
+
diagnostics.error("ABP002", `no handler method FOR DETERMINE ON ${determination.on.toUpperCase()} for ${entity.alias}~${determination.name}`, determination.src);
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
determination.handler = ref;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
for (const action of entity.actions) {
|
|
302
|
+
const ref = take(entity, (h) => (h.what.kind === "action" || h.what.kind === "function") && same(h.what.name, action.name));
|
|
303
|
+
if (ref === undefined) {
|
|
304
|
+
diagnostics.error("ABP002", `no handler method for ${action.kind} ${entity.alias}~${action.name}`, action.src);
|
|
305
|
+
}
|
|
306
|
+
else {
|
|
307
|
+
action.handler = ref;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
const needsInstanceFeatures = entity.operations.some((o) => o.features === "instance") ||
|
|
311
|
+
entity.actions.some((a) => a.features === "instance") ||
|
|
312
|
+
entity.associations.some((a) => a.createFeatures === "instance") ||
|
|
313
|
+
Object.values(entity.fieldCharacteristics).some((c) => c.includes("featuresInstance"));
|
|
314
|
+
const needsGlobalFeatures = entity.operations.some((o) => o.features === "global") ||
|
|
315
|
+
entity.actions.some((a) => a.features === "global") ||
|
|
316
|
+
entity.associations.some((a) => a.createFeatures === "global");
|
|
317
|
+
const instanceFeatures = take(entity, (h) => h.what.kind === "instanceFeatures");
|
|
318
|
+
if (instanceFeatures !== undefined) {
|
|
319
|
+
entity.instanceFeaturesHandler = instanceFeatures;
|
|
320
|
+
}
|
|
321
|
+
else if (needsInstanceFeatures) {
|
|
322
|
+
diagnostics.error("ABP002", `no handler method FOR INSTANCE FEATURES for ${entity.alias}`, entity.src);
|
|
323
|
+
}
|
|
324
|
+
const globalFeatures = take(entity, (h) => h.what.kind === "globalFeatures");
|
|
325
|
+
if (globalFeatures !== undefined) {
|
|
326
|
+
entity.globalFeaturesHandler = globalFeatures;
|
|
327
|
+
}
|
|
328
|
+
else if (needsGlobalFeatures) {
|
|
329
|
+
diagnostics.error("ABP002", `no handler method FOR GLOBAL FEATURES for ${entity.alias}`, entity.src);
|
|
330
|
+
}
|
|
331
|
+
if (entity.authorization?.kind === "master") {
|
|
332
|
+
const globalAuth = take(entity, (h) => h.what.kind === "globalAuthorization");
|
|
333
|
+
const instanceAuth = take(entity, (h) => h.what.kind === "instanceAuthorization");
|
|
334
|
+
if (globalAuth !== undefined) {
|
|
335
|
+
entity.globalAuthorizationHandler = globalAuth;
|
|
336
|
+
}
|
|
337
|
+
else if (entity.authorization.global) {
|
|
338
|
+
diagnostics.error("ABP002", `no handler method FOR GLOBAL AUTHORIZATION for ${entity.alias}`, entity.src);
|
|
339
|
+
}
|
|
340
|
+
if (instanceAuth !== undefined) {
|
|
341
|
+
entity.instanceAuthorizationHandler = instanceAuth;
|
|
342
|
+
}
|
|
343
|
+
else if (entity.authorization.instance) {
|
|
344
|
+
diagnostics.error("ABP002", `no handler method FOR INSTANCE AUTHORIZATION for ${entity.alias}`, entity.src);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
if (entity.earlyNumbering) {
|
|
348
|
+
// the numbering of the direct creation; an entity created by association only (a child)
|
|
349
|
+
// is numbered by the handlers of its parents' associations below
|
|
350
|
+
const numbering = take(entity, (h) => h.what.kind === "numbering");
|
|
351
|
+
if (numbering !== undefined) {
|
|
352
|
+
entity.earlyNumberingHandler = numbering;
|
|
353
|
+
}
|
|
354
|
+
else if (entity.operations.some((o) => o.kind === "create")) {
|
|
355
|
+
diagnostics.error("ABP002", `no handler method FOR NUMBERING for ${entity.alias}`, entity.src);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
// early numbering by association: FOR NUMBERING … FOR CREATE Travel\_Booking
|
|
359
|
+
for (const association of entity.associations.filter((a) => a.create)) {
|
|
360
|
+
const target = targetBehavior(behavior, entity, association.name, entities);
|
|
361
|
+
if (target === undefined || !target.earlyNumbering) {
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
364
|
+
const name = `${entity.alias}\\${association.name}`;
|
|
365
|
+
const handler = handlers.find((h) => h.what.kind === "numbering" && (same(h.what.alias, name) || same(h.what.alias, `${entity.entity}\\${association.name}`)));
|
|
366
|
+
if (handler === undefined) {
|
|
367
|
+
diagnostics.error("ABP002", `no handler method FOR NUMBERING for ${name}`, entity.src);
|
|
368
|
+
}
|
|
369
|
+
else {
|
|
370
|
+
handler.used = true;
|
|
371
|
+
association.earlyNumberingHandler = handler.ref;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
for (const handler of handlers) {
|
|
375
|
+
if (handler.what.kind === "precheck" && (same(handler.what.alias, entity.alias) || same(handler.what.alias, entity.entity))) {
|
|
376
|
+
// the BDEF must declare the precheck of the operation, else the handler is not called
|
|
377
|
+
const [operation = "", detail = ""] = handler.what.operation.toLowerCase().split(":");
|
|
378
|
+
const declared = operation === "action"
|
|
379
|
+
? entity.actions.some((a) => same(a.name, detail) && a.precheck)
|
|
380
|
+
: operation === "create" && detail !== ""
|
|
381
|
+
? entity.associations.some((a) => same(a.name, detail) && a.createPrecheck)
|
|
382
|
+
: entity.operations.some((o) => o.kind === operation && o.precheck);
|
|
383
|
+
if (declared) {
|
|
384
|
+
entity.precheckHandlers[handler.what.operation.toLowerCase()] = handler.ref;
|
|
385
|
+
handler.used = true;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
for (const handler of handlers.filter((h) => !h.used)) {
|
|
391
|
+
const description = handler.what.kind === "other" ? `FOR ${handler.what.text}` : handler.what.kind;
|
|
392
|
+
diagnostics.warning("ABP003", `handler method ${handler.ref.className}->${handler.ref.method} (${description}) does not match the BDEF and is not called`, {
|
|
393
|
+
file: handler.file,
|
|
394
|
+
line: handler.line,
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
//# sourceMappingURL=handlers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handlers.js","sourceRoot":"","sources":["../../src/ir/handlers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Intervals of the number ranges (decision D40): `rapt/number-ranges.json` next to the abapGit
|
|
3
|
+
* sources, versioned with them, as the number range objects and intervals of the system:
|
|
4
|
+
*
|
|
5
|
+
* ```json
|
|
6
|
+
* { "ZRT_TRAVEL": { "01": { "from": "1", "to": "99999999" } } }
|
|
7
|
+
* ```
|
|
8
|
+
*
|
|
9
|
+
* An interval may also give `subobject` and `toyear`. cl_numberrange_runtime=>number_get draws
|
|
10
|
+
* from the interval in the database of the application; an interval that is not configured
|
|
11
|
+
* starts at 1.
|
|
12
|
+
*/
|
|
13
|
+
import type { NumberRangeIntervalModel } from "@open-rap/model";
|
|
14
|
+
import type { Diagnostics } from "../diagnostics.js";
|
|
15
|
+
import type { Project } from "../input/project.js";
|
|
16
|
+
export declare const NUMBER_RANGES_FILE = "rapt/number-ranges.json";
|
|
17
|
+
export declare function loadNumberRanges(project: Project, diagnostics: Diagnostics): NumberRangeIntervalModel[] | undefined;
|
|
18
|
+
/** The services with tables of their own the ABAP of the project uses (D40, D41). */
|
|
19
|
+
export declare function usedServices(project: Project): {
|
|
20
|
+
numberRanges?: boolean;
|
|
21
|
+
applicationLog?: boolean;
|
|
22
|
+
background?: boolean;
|
|
23
|
+
mail?: boolean;
|
|
24
|
+
} | undefined;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Intervals of the number ranges (decision D40): `rapt/number-ranges.json` next to the abapGit
|
|
3
|
+
* sources, versioned with them, as the number range objects and intervals of the system:
|
|
4
|
+
*
|
|
5
|
+
* ```json
|
|
6
|
+
* { "ZRT_TRAVEL": { "01": { "from": "1", "to": "99999999" } } }
|
|
7
|
+
* ```
|
|
8
|
+
*
|
|
9
|
+
* An interval may also give `subobject` and `toyear`. cl_numberrange_runtime=>number_get draws
|
|
10
|
+
* from the interval in the database of the application; an interval that is not configured
|
|
11
|
+
* starts at 1.
|
|
12
|
+
*/
|
|
13
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
14
|
+
import path from "node:path";
|
|
15
|
+
export const NUMBER_RANGES_FILE = "rapt/number-ranges.json";
|
|
16
|
+
const DIGITS = /^\d{1,20}$/;
|
|
17
|
+
export function loadNumberRanges(project, diagnostics) {
|
|
18
|
+
const file = path.join(project.root, NUMBER_RANGES_FILE);
|
|
19
|
+
if (!existsSync(file)) {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
const at = { file: NUMBER_RANGES_FILE, line: 1 };
|
|
23
|
+
let json;
|
|
24
|
+
try {
|
|
25
|
+
json = JSON.parse(readFileSync(file, "utf8"));
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
diagnostics.error("NR001", `${NUMBER_RANGES_FILE} is not valid JSON: ${error.message}`, at);
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
if (typeof json !== "object" || json === null || Array.isArray(json)) {
|
|
32
|
+
diagnostics.error("NR001", `${NUMBER_RANGES_FILE} must be an object: number range object → interval → { from, to }`, at);
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
const intervals = [];
|
|
36
|
+
for (const [object, value] of Object.entries(json)) {
|
|
37
|
+
if (object.length > 10) {
|
|
38
|
+
diagnostics.error("NR001", `${object}: a number range object has at most 10 characters`, at);
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
for (const [nr, definition] of Object.entries((value ?? {}))) {
|
|
42
|
+
const d = (definition ?? {});
|
|
43
|
+
const from = String(d.from ?? "1");
|
|
44
|
+
const to = String(d.to ?? "");
|
|
45
|
+
if (nr.length > 2 || !DIGITS.test(from) || !DIGITS.test(to) || BigInt(from) > BigInt(to)) {
|
|
46
|
+
diagnostics.error("NR001", `${object}.${nr}: an interval has a name of 2 characters and "from" ≤ "to", decimal numbers of up to 20 digits`, at);
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
const interval = { object: object.toUpperCase(), interval: nr.toUpperCase(), from: BigInt(from).toString(), to: BigInt(to).toString() };
|
|
50
|
+
if (typeof d.subobject === "string" && d.subobject !== "")
|
|
51
|
+
interval.subobject = d.subobject.toUpperCase();
|
|
52
|
+
if (d.toyear !== undefined && String(d.toyear) !== "")
|
|
53
|
+
interval.toyear = String(d.toyear);
|
|
54
|
+
intervals.push(interval);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return intervals;
|
|
58
|
+
}
|
|
59
|
+
/** The services with tables of their own the ABAP of the project uses (D40, D41). */
|
|
60
|
+
export function usedServices(project) {
|
|
61
|
+
const code = project.files
|
|
62
|
+
.filter((f) => (f.type === "CLAS" || f.type === "INTF") && f.extension.endsWith("abap"))
|
|
63
|
+
.map((f) => f.content.toLowerCase())
|
|
64
|
+
.join("\n");
|
|
65
|
+
const services = {
|
|
66
|
+
numberRanges: code.includes("cl_numberrange_runtime"),
|
|
67
|
+
applicationLog: /\bcl_bali_/.test(code),
|
|
68
|
+
background: code.includes("cl_bgmc_process_factory"),
|
|
69
|
+
mail: code.includes("cl_bcs_mail_message"),
|
|
70
|
+
};
|
|
71
|
+
const used = Object.fromEntries(Object.entries(services).filter(([, value]) => value));
|
|
72
|
+
return Object.keys(used).length === 0 ? undefined : used;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=number-ranges.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"number-ranges.js","sourceRoot":"","sources":["../../src/ir/number-ranges.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Seed data of the application (decision D42): `rapt/seed.json` and `rapt/seed.sql` next to the
|
|
3
|
+
* abapGit sources. They are copied to `db/` in the application, which loads them at its first
|
|
4
|
+
* start (all its tables empty) when `SEED=auto` — the default of `rapt dev`.
|
|
5
|
+
*
|
|
6
|
+
* ```json
|
|
7
|
+
* { "zrt_travel": [ { "travel_id": "1", "description": "Paris", "begin_date": "2026-06-01" } ] }
|
|
8
|
+
* ```
|
|
9
|
+
*
|
|
10
|
+
* Tables and fields are those of the dictionary (lower case, without the client field); values are
|
|
11
|
+
* written in their database form (dates `YYYY-MM-DD`, UUIDs `xxxxxxxx-xxxx-…`). A UUID key left out
|
|
12
|
+
* is drawn at random.
|
|
13
|
+
*/
|
|
14
|
+
import type { Model } from "@open-rap/model";
|
|
15
|
+
import type { Diagnostics } from "../diagnostics.js";
|
|
16
|
+
import type { Project } from "../input/project.js";
|
|
17
|
+
export declare const SEED_JSON = "rapt/seed.json";
|
|
18
|
+
export declare const SEED_SQL = "rapt/seed.sql";
|
|
19
|
+
export interface Seed {
|
|
20
|
+
json?: Record<string, Record<string, unknown>[]>;
|
|
21
|
+
sql?: string;
|
|
22
|
+
}
|
|
23
|
+
export declare function loadSeed(project: Project, model: Model, diagnostics: Diagnostics): Seed;
|
package/dist/ir/seed.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Seed data of the application (decision D42): `rapt/seed.json` and `rapt/seed.sql` next to the
|
|
3
|
+
* abapGit sources. They are copied to `db/` in the application, which loads them at its first
|
|
4
|
+
* start (all its tables empty) when `SEED=auto` — the default of `rapt dev`.
|
|
5
|
+
*
|
|
6
|
+
* ```json
|
|
7
|
+
* { "zrt_travel": [ { "travel_id": "1", "description": "Paris", "begin_date": "2026-06-01" } ] }
|
|
8
|
+
* ```
|
|
9
|
+
*
|
|
10
|
+
* Tables and fields are those of the dictionary (lower case, without the client field); values are
|
|
11
|
+
* written in their database form (dates `YYYY-MM-DD`, UUIDs `xxxxxxxx-xxxx-…`). A UUID key left out
|
|
12
|
+
* is drawn at random.
|
|
13
|
+
*/
|
|
14
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
15
|
+
import path from "node:path";
|
|
16
|
+
export const SEED_JSON = "rapt/seed.json";
|
|
17
|
+
export const SEED_SQL = "rapt/seed.sql";
|
|
18
|
+
export function loadSeed(project, model, diagnostics) {
|
|
19
|
+
const seed = {};
|
|
20
|
+
const sqlFile = path.join(project.root, SEED_SQL);
|
|
21
|
+
if (existsSync(sqlFile)) {
|
|
22
|
+
seed.sql = readFileSync(sqlFile, "utf8");
|
|
23
|
+
}
|
|
24
|
+
const jsonFile = path.join(project.root, SEED_JSON);
|
|
25
|
+
if (!existsSync(jsonFile)) {
|
|
26
|
+
return seed;
|
|
27
|
+
}
|
|
28
|
+
const at = { file: SEED_JSON, line: 1 };
|
|
29
|
+
let json;
|
|
30
|
+
try {
|
|
31
|
+
json = JSON.parse(readFileSync(jsonFile, "utf8"));
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
diagnostics.error("SEED001", `${SEED_JSON} is not valid JSON: ${error.message}`, at);
|
|
35
|
+
return seed;
|
|
36
|
+
}
|
|
37
|
+
if (typeof json !== "object" || json === null || Array.isArray(json)) {
|
|
38
|
+
diagnostics.error("SEED001", `${SEED_JSON} must be an object: table → array of rows`, at);
|
|
39
|
+
return seed;
|
|
40
|
+
}
|
|
41
|
+
const result = {};
|
|
42
|
+
for (const [name, rows] of Object.entries(json)) {
|
|
43
|
+
const table = model.tables.find((t) => t.name === name.toLowerCase());
|
|
44
|
+
if (table === undefined) {
|
|
45
|
+
diagnostics.error("SEED002", `${SEED_JSON}: table ${name} is not a table of the application`, at);
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (!Array.isArray(rows)) {
|
|
49
|
+
diagnostics.error("SEED001", `${SEED_JSON}: ${name} must be an array of rows`, at);
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
const columns = new Map(table.columns.filter((c) => !c.client).map((c) => [c.name, c]));
|
|
53
|
+
const clean = [];
|
|
54
|
+
rows.forEach((row, index) => {
|
|
55
|
+
if (typeof row !== "object" || row === null || Array.isArray(row)) {
|
|
56
|
+
diagnostics.error("SEED001", `${SEED_JSON}: ${name}[${index}] must be an object`, at);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const values = {};
|
|
60
|
+
for (const [field, value] of Object.entries(row)) {
|
|
61
|
+
const lower = field.toLowerCase();
|
|
62
|
+
if (!columns.has(lower)) {
|
|
63
|
+
// the client field is not a column of the database (D9): ignored
|
|
64
|
+
if (table.columns.some((c) => c.client && c.name === lower))
|
|
65
|
+
continue;
|
|
66
|
+
diagnostics.error("SEED002", `${SEED_JSON}: ${name}[${index}].${field} is not a field of ${name}`, at);
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
values[lower] = value;
|
|
70
|
+
}
|
|
71
|
+
clean.push(values);
|
|
72
|
+
});
|
|
73
|
+
result[table.name] = clean;
|
|
74
|
+
}
|
|
75
|
+
seed.json = result;
|
|
76
|
+
return seed;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=seed.js.map
|