cds-plugin-ui5 0.10.0 → 0.11.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/.lintstagedrc.json +3 -0
- package/CHANGELOG.md +22 -0
- package/cds-plugin.js +335 -322
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,28 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [0.11.1](https://github.com/ui5-community/ui5-ecosystem-showcase/compare/cds-plugin-ui5@0.11.0...cds-plugin-ui5@0.11.1) (2024-10-10)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* **cds-plugin-ui5:** move logging into real execution ([#1091](https://github.com/ui5-community/ui5-ecosystem-showcase/issues/1091)) ([f60fc51](https://github.com/ui5-community/ui5-ecosystem-showcase/commit/f60fc51683727a29da03e8cd3f9c80d2077f89eb))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# [0.11.0](https://github.com/ui5-community/ui5-ecosystem-showcase/compare/cds-plugin-ui5@0.10.0...cds-plugin-ui5@0.11.0) (2024-09-06)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Features
|
|
21
|
+
|
|
22
|
+
* enhanced v4 compat + update dependencies ([#1070](https://github.com/ui5-community/ui5-ecosystem-showcase/issues/1070)) ([2d7ed16](https://github.com/ui5-community/ui5-ecosystem-showcase/commit/2d7ed1623249febd32ecabdd2b47698f1cd968d5))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
6
28
|
# [0.10.0](https://github.com/ui5-community/ui5-ecosystem-showcase/compare/cds-plugin-ui5@0.9.8...cds-plugin-ui5@0.10.0) (2024-08-29)
|
|
7
29
|
|
|
8
30
|
|
package/cds-plugin.js
CHANGED
|
@@ -13,370 +13,383 @@
|
|
|
13
13
|
// - https://github.com/ui5-community/ui5-ecosystem-showcase/issues/901
|
|
14
14
|
//
|
|
15
15
|
// To disable JEST we rely on env variables (see https://jestjs.io/docs/environment-variables)
|
|
16
|
+
let skip = false;
|
|
16
17
|
if (process.env.NODE_ENV === "test" && process.env.JEST_WORKER_ID && process.env.CDS_PLUGIN_UI5_ACTIVE !== "true") {
|
|
17
18
|
console.log(
|
|
18
19
|
process.env.NO_COLOR ? "[%s] %s" : "\x1b[36m[%s]\x1b[0m \x1b[31m%s\x1b[0m",
|
|
19
20
|
"cds-plugin-ui5",
|
|
20
|
-
"Skip execution because JEST is running tests! To force the execution of the plugin set env var CDS_PLUGIN_UI5_ACTIVE=true..."
|
|
21
|
+
"Skip execution because JEST is running tests! To force the execution of the plugin set env var CDS_PLUGIN_UI5_ACTIVE=true...",
|
|
21
22
|
);
|
|
22
|
-
|
|
23
|
+
skip = true;
|
|
23
24
|
}
|
|
24
25
|
if (process.env.CDS_PLUGIN_UI5_ACTIVE === "false") {
|
|
25
26
|
console.log(process.env.NO_COLOR ? "[%s] %s" : "\x1b[36m[%s]\x1b[0m \x1b[31m%s\x1b[0m", "cds-plugin-ui5", "Skip execution because it has been disabled by env var CDS_PLUGIN_UI5_ACTIVE!");
|
|
26
|
-
|
|
27
|
+
skip = true;
|
|
27
28
|
}
|
|
28
29
|
|
|
29
|
-
//
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if (!(process.env.NO_COLOR || process.env.CDS_PLUGIN_UI5_NO_CUSTOM_LOGGER)) {
|
|
34
|
-
const LOG_COLORS = {
|
|
35
|
-
TRACE: "\x1b[0m", // default
|
|
36
|
-
DEBUG: "\x1b[34m", // blue
|
|
37
|
-
INFO: "\x1b[32m", // green
|
|
38
|
-
WARN: "\x1b[33m", // yellow
|
|
39
|
-
ERROR: "\x1b[31m", // red
|
|
40
|
-
};
|
|
41
|
-
const LOG_LEVEL_TO_COLOR = Object.fromEntries(Object.keys(LOG_COLORS).map((level) => [cds.log.levels[level], LOG_COLORS[level]]));
|
|
42
|
-
const LOG_LEVEL_TO_TEXT = Object.fromEntries(Object.keys(LOG_COLORS).map((level) => [cds.log.levels[level], level]));
|
|
43
|
-
cds.log.format = (label, level, ...args) => {
|
|
44
|
-
return ["\x1b[36m[%s]\x1b[0m %s[%s]\x1b[0m %s", label, LOG_LEVEL_TO_COLOR[level], LOG_LEVEL_TO_TEXT[level], ...args];
|
|
45
|
-
};
|
|
46
|
-
}
|
|
30
|
+
// only execute the plugin if it should not be skipped
|
|
31
|
+
if (!skip) {
|
|
32
|
+
// @sap/cds/lib/index.js#138: global.cds = cds // REVISIT: using global.cds seems wrong
|
|
33
|
+
const cds = global.cds || require("@sap/cds"); // reuse already loaded cds!
|
|
47
34
|
|
|
48
|
-
//
|
|
49
|
-
|
|
35
|
+
// add color support to the logger
|
|
36
|
+
if (!(process.env.NO_COLOR || process.env.CDS_PLUGIN_UI5_NO_CUSTOM_LOGGER)) {
|
|
37
|
+
const LOG_COLORS = {
|
|
38
|
+
TRACE: "\x1b[0m", // default
|
|
39
|
+
DEBUG: "\x1b[34m", // blue
|
|
40
|
+
INFO: "\x1b[32m", // green
|
|
41
|
+
WARN: "\x1b[33m", // yellow
|
|
42
|
+
ERROR: "\x1b[31m", // red
|
|
43
|
+
};
|
|
44
|
+
const LOG_LEVEL_TO_COLOR = Object.fromEntries(Object.keys(LOG_COLORS).map((level) => [cds.log.levels[level], LOG_COLORS[level]]));
|
|
45
|
+
const LOG_LEVEL_TO_TEXT = Object.fromEntries(Object.keys(LOG_COLORS).map((level) => [cds.log.levels[level], level]));
|
|
46
|
+
cds.log.format = (label, level, ...args) => {
|
|
47
|
+
return ["\x1b[36m[%s]\x1b[0m %s[%s]\x1b[0m %s", label, LOG_LEVEL_TO_COLOR[level], LOG_LEVEL_TO_TEXT[level], ...args];
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
const
|
|
53
|
-
const applyUI5Middleware = require("./lib/applyUI5Middleware");
|
|
54
|
-
const rewriteHTML = require("./lib/rewriteHTML");
|
|
51
|
+
// create a logger for the cds-plugin-ui5
|
|
52
|
+
const LOG = cds.log("cds-plugin-ui5");
|
|
55
53
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
skip = true;
|
|
61
|
-
} else if (process.env["dev-approuter"]) {
|
|
62
|
-
LOG.info("Skip execution of plugin because is has been started via dev-approuter!");
|
|
63
|
-
skip = true;
|
|
64
|
-
}
|
|
54
|
+
const findUI5Modules = require("./lib/findUI5Modules");
|
|
55
|
+
const createPatchedRouter = require("./lib/createPatchedRouter");
|
|
56
|
+
const applyUI5Middleware = require("./lib/applyUI5Middleware");
|
|
57
|
+
const rewriteHTML = require("./lib/rewriteHTML");
|
|
65
58
|
|
|
66
|
-
//
|
|
67
|
-
if (
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
process.env["
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
return
|
|
59
|
+
// identify whether the execution should be skipped
|
|
60
|
+
if (process.env["ui5-middleware-cap"]) {
|
|
61
|
+
LOG.info("Skip execution of plugin because is has been started via ui5-middleware-cap!");
|
|
62
|
+
skip = true;
|
|
63
|
+
} else if (process.env["dev-approuter"]) {
|
|
64
|
+
LOG.info("Skip execution of plugin because is has been started via dev-approuter!");
|
|
65
|
+
skip = true;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// only hook into lifecycle if the plugin should not be skipped
|
|
69
|
+
if (!skip) {
|
|
70
|
+
// marker that the cds-plugin-ui5 plugin is running
|
|
71
|
+
// to disable the ui5-middleware-cap if used in apps
|
|
72
|
+
process.env["cds-plugin-ui5"] = true;
|
|
73
|
+
|
|
74
|
+
const { dirname, join, resolve } = require("path");
|
|
75
|
+
const { readFileSync, existsSync, realpathSync } = require("fs");
|
|
76
|
+
const { execSync } = require("child_process");
|
|
77
|
+
|
|
78
|
+
const { version: cdsPluginUI5Version } = require(`${__dirname}/package.json`);
|
|
79
|
+
|
|
80
|
+
// function to resolve a module with the given paths without throwing an error
|
|
81
|
+
const resolveModule = function resolveModule(moduleName, paths) {
|
|
82
|
+
try {
|
|
83
|
+
return require.resolve(moduleName, { paths });
|
|
84
|
+
// eslint-disable-next-line no-unused-vars
|
|
85
|
+
} catch (err) {
|
|
86
|
+
return null;
|
|
94
87
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
// ignore
|
|
107
|
-
}
|
|
108
|
-
const cdsDkDir = dirname(cdsDkPath);
|
|
109
|
-
const packageJsonPath = findPackageJson(cdsDkDir);
|
|
110
|
-
if (packageJsonPath) {
|
|
111
|
-
const packageJson = JSON.parse(readFileSync(packageJsonPath, { encoding: "utf-8" }));
|
|
112
|
-
return packageJson.version;
|
|
113
|
-
} else {
|
|
114
|
-
const moduleName = "@sap/cds-dk";
|
|
115
|
-
let resolvedPath = resolveModule(`${moduleName}/package.json`);
|
|
116
|
-
if (!resolvedPath) {
|
|
117
|
-
const globalModulesPath = execSync("npm root -g").toString().trim();
|
|
118
|
-
resolvedPath = resolveModule(`${moduleName}/package.json`, [globalModulesPath]);
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
// helper to find the package.json in the current dir or upwards
|
|
91
|
+
const findPackageJson = function findPackageJson(dir) {
|
|
92
|
+
let currentDir = dir;
|
|
93
|
+
while (currentDir !== resolve(currentDir, "..")) {
|
|
94
|
+
const packageJsonPath = join(currentDir, "package.json");
|
|
95
|
+
if (existsSync(packageJsonPath)) {
|
|
96
|
+
return packageJsonPath;
|
|
97
|
+
}
|
|
98
|
+
currentDir = resolve(currentDir, "..");
|
|
119
99
|
}
|
|
120
|
-
|
|
121
|
-
|
|
100
|
+
return undefined;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
// find out the CDS-DK version to control the behavior of the plugin
|
|
104
|
+
const getCDSDKVersion = function getCDSDKVersion() {
|
|
105
|
+
let cdsDkPath = process.argv[1];
|
|
106
|
+
try {
|
|
107
|
+
cdsDkPath = realpathSync(cdsDkPath);
|
|
108
|
+
// eslint-disable-next-line no-unused-vars
|
|
109
|
+
} catch (err) {
|
|
110
|
+
// ignore
|
|
111
|
+
}
|
|
112
|
+
const cdsDkDir = dirname(cdsDkPath);
|
|
113
|
+
const packageJsonPath = findPackageJson(cdsDkDir);
|
|
114
|
+
if (packageJsonPath) {
|
|
115
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, { encoding: "utf-8" }));
|
|
122
116
|
return packageJson.version;
|
|
117
|
+
} else {
|
|
118
|
+
const moduleName = "@sap/cds-dk";
|
|
119
|
+
let resolvedPath = resolveModule(`${moduleName}/package.json`);
|
|
120
|
+
if (!resolvedPath) {
|
|
121
|
+
const globalModulesPath = execSync("npm root -g").toString().trim();
|
|
122
|
+
resolvedPath = resolveModule(`${moduleName}/package.json`, [globalModulesPath]);
|
|
123
|
+
}
|
|
124
|
+
if (resolvedPath) {
|
|
125
|
+
const packageJson = JSON.parse(readFileSync(resolvedPath, { encoding: "utf-8" }));
|
|
126
|
+
return packageJson.version;
|
|
127
|
+
}
|
|
123
128
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
// get the CDS-DK version to control the behavior of the plugin
|
|
129
|
-
const cdsdkVersion = getCDSDKVersion();
|
|
130
|
-
|
|
131
|
-
// logging the version of the cds-plugin-ui5
|
|
132
|
-
LOG.info(`Running cds-plugin-ui5@${cdsPluginUI5Version} (@sap/cds-dk@${cdsdkVersion}, @sap/cds@${cds.version})`);
|
|
133
|
-
if (global.__cds_loaded_from?.size > 1) {
|
|
134
|
-
LOG.warn(" !! Multiple versions of @sap/cds loaded !!");
|
|
135
|
-
global.__cds_loaded_from.forEach((cdsPath) => {
|
|
136
|
-
LOG.warn(` => ${cdsPath}`);
|
|
137
|
-
});
|
|
138
|
-
}
|
|
129
|
+
return undefined;
|
|
130
|
+
};
|
|
139
131
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
// middlewares for the UI5 applications are properly available
|
|
150
|
-
cds.on("served", async function served(/* cdsServices */) {
|
|
151
|
-
LOG.debug("served");
|
|
152
|
-
await bootstrapCompleted;
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
// hook into the "bootstrap" event to startup the UI5 middlewares
|
|
156
|
-
// for the available UI5 applications in the CDS server and its deps
|
|
157
|
-
cds.on("bootstrap", async function bootstrap(app) {
|
|
158
|
-
LOG.debug("bootstrap");
|
|
159
|
-
|
|
160
|
-
// only for cds serve or serving all services the cds-plugin-ui5 is active
|
|
161
|
-
if (cds.cli?.command === "serve" || cds.options?.service === "all") {
|
|
162
|
-
const cwd = cds.env?._home || process.cwd();
|
|
163
|
-
const ui5Modules = await findUI5Modules({ cwd, cds, LOG });
|
|
164
|
-
const { localApps, config } = ui5Modules;
|
|
165
|
-
|
|
166
|
-
const links = [];
|
|
167
|
-
|
|
168
|
-
// register the UI5 modules via their own router/middlewares
|
|
169
|
-
for await (const ui5Module of ui5Modules) {
|
|
170
|
-
const { moduleId, mountPath, modulePath } = ui5Module;
|
|
171
|
-
|
|
172
|
-
// mounting the Router for the UI5 application to the CDS server
|
|
173
|
-
LOG.info(`Mounting ${mountPath} to UI5 app ${modulePath} (id=${moduleId})${config[moduleId] ? ` using config=${JSON.stringify(config[moduleId])}` : ""}`);
|
|
174
|
-
|
|
175
|
-
// create a patched router
|
|
176
|
-
const router = await createPatchedRouter();
|
|
177
|
-
|
|
178
|
-
// apply the UI5 middlewares to the router and
|
|
179
|
-
// retrieve the available HTML pages
|
|
180
|
-
const appInfo = await applyUI5Middleware(router, {
|
|
181
|
-
cwd,
|
|
182
|
-
basePath: modulePath,
|
|
183
|
-
...(config[moduleId] || {}),
|
|
184
|
-
LOG,
|
|
132
|
+
// get the CDS-DK version to control the behavior of the plugin
|
|
133
|
+
const cdsdkVersion = getCDSDKVersion();
|
|
134
|
+
const logVersion = function () {
|
|
135
|
+
// logging the version of the cds-plugin-ui5
|
|
136
|
+
LOG.info(`Running cds-plugin-ui5@${cdsPluginUI5Version} (@sap/cds-dk@${cdsdkVersion}, @sap/cds@${cds.version})`);
|
|
137
|
+
if (global.__cds_loaded_from?.size > 1) {
|
|
138
|
+
LOG.warn(" !! Multiple versions of @sap/cds loaded !!");
|
|
139
|
+
global.__cds_loaded_from.forEach((cdsPath) => {
|
|
140
|
+
LOG.warn(` => ${cdsPath}`);
|
|
185
141
|
});
|
|
142
|
+
}
|
|
143
|
+
};
|
|
186
144
|
|
|
187
|
-
|
|
188
|
-
|
|
145
|
+
// promise to await the bootstrap and lock the
|
|
146
|
+
// served event to delay the startup a bit
|
|
147
|
+
let bootstrapped;
|
|
148
|
+
const bootstrapCompleted = new Promise((r) => {
|
|
149
|
+
bootstrapped = r;
|
|
150
|
+
});
|
|
189
151
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
152
|
+
// hook into the "served" event to delay the startup of the
|
|
153
|
+
// CDS server until the bootstrap is completed and the UI5
|
|
154
|
+
// middlewares for the UI5 applications are properly available
|
|
155
|
+
cds.on("served", async function served(/* cdsServices */) {
|
|
156
|
+
LOG.debug("served");
|
|
157
|
+
await bootstrapCompleted;
|
|
158
|
+
});
|
|
196
159
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
160
|
+
// hook into the "bootstrap" event to startup the UI5 middlewares
|
|
161
|
+
// for the available UI5 applications in the CDS server and its deps
|
|
162
|
+
cds.on("bootstrap", async function bootstrap(app) {
|
|
163
|
+
LOG.debug("bootstrap");
|
|
164
|
+
|
|
165
|
+
// only for cds serve or serving all services the cds-plugin-ui5 is active
|
|
166
|
+
if (cds.cli?.command === "serve" || cds.options?.service === "all") {
|
|
167
|
+
const cwd = cds.env?._home || process.cwd();
|
|
168
|
+
const ui5Modules = await findUI5Modules({ cwd, cds, LOG });
|
|
169
|
+
const { localApps, config } = ui5Modules;
|
|
170
|
+
|
|
171
|
+
const links = [];
|
|
172
|
+
|
|
173
|
+
// log the version of the cds-plugin-ui5
|
|
174
|
+
logVersion();
|
|
175
|
+
|
|
176
|
+
// register the UI5 modules via their own router/middlewares
|
|
177
|
+
for await (const ui5Module of ui5Modules) {
|
|
178
|
+
const { moduleId, mountPath, modulePath } = ui5Module;
|
|
179
|
+
|
|
180
|
+
// mounting the Router for the UI5 application to the CDS server
|
|
181
|
+
LOG.info(`Mounting ${mountPath} to UI5 app ${modulePath} (id=${moduleId})${config[moduleId] ? ` using config=${JSON.stringify(config[moduleId])}` : ""}`);
|
|
182
|
+
|
|
183
|
+
// create a patched router
|
|
184
|
+
const router = await createPatchedRouter();
|
|
185
|
+
|
|
186
|
+
// apply the UI5 middlewares to the router and
|
|
187
|
+
// retrieve the available HTML pages
|
|
188
|
+
const appInfo = await applyUI5Middleware(router, {
|
|
189
|
+
cwd,
|
|
190
|
+
basePath: modulePath,
|
|
191
|
+
...(config[moduleId] || {}),
|
|
192
|
+
LOG,
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
// register the router to the specified mount path
|
|
196
|
+
app.use(mountPath, router);
|
|
197
|
+
|
|
198
|
+
// append the HTML pages to the links
|
|
199
|
+
appInfo.pages.forEach((page) => {
|
|
200
|
+
const prefix = mountPath !== "/" ? mountPath : "";
|
|
201
|
+
links.push(`${prefix}${page}`);
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// identify whether the welcome page should be rewritten
|
|
206
|
+
let rewrite = links.length > 0;
|
|
207
|
+
|
|
208
|
+
// rewrite the welcome page
|
|
209
|
+
if (rewrite) {
|
|
210
|
+
// register the custom middleware (similar like in @sap/cds/server.js)
|
|
211
|
+
app.get("/", function appendLinksToIndex(req, res, next) {
|
|
212
|
+
req._cds_plugin_ui5 = true; // marker for patched router to ignore
|
|
213
|
+
rewriteHTML(
|
|
214
|
+
req,
|
|
215
|
+
res,
|
|
216
|
+
() => true,
|
|
217
|
+
(doc) => {
|
|
218
|
+
// the first <ul> element contains the links to the
|
|
219
|
+
// application pages which is fully under control of
|
|
220
|
+
// our plugin now and we keep all links to static
|
|
221
|
+
// pages to ensure coop with classic apps
|
|
222
|
+
const head = doc.getElementsByTagName("head")?.[0];
|
|
223
|
+
head?.insertAdjacentHTML(
|
|
224
|
+
"beforeend",
|
|
225
|
+
`<style>
|
|
227
226
|
a.ui5:after {
|
|
228
|
-
|
|
227
|
+
content: "UI5";
|
|
228
|
+
font-weight: bold;
|
|
229
|
+
font-size: 0.5rem;
|
|
230
|
+
vertical-align: super;
|
|
231
|
+
margin: 0.25rem;
|
|
232
|
+
color: #1873B4;
|
|
229
233
|
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
const ul = doc.getElementsByTagName("ul")?.[0];
|
|
234
|
-
if (ul) {
|
|
235
|
-
const newLis = [];
|
|
236
|
-
const lis = ul.getElementsByTagName("li");
|
|
237
|
-
lis?.forEach((li) => {
|
|
238
|
-
const appDir = li.firstChild?.text?.split("/")?.[1];
|
|
239
|
-
if (localApps.has(appDir)) {
|
|
240
|
-
newLis.push(li.toString());
|
|
234
|
+
@media (prefers-color-scheme: dark) {
|
|
235
|
+
a.ui5:after {
|
|
236
|
+
color: #FF5A37;
|
|
241
237
|
}
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
...links.sort().map((link) => {
|
|
245
|
-
// we remove the query parameters from the link text
|
|
246
|
-
const linkText = link.indexOf("?") === -1 ? link : link.substr(0, link.indexOf("?"));
|
|
247
|
-
// renders a UI5 link ;-)
|
|
248
|
-
return `<li><a class="ui5" href="${link}">${linkText}</a></li>`;
|
|
249
|
-
})
|
|
238
|
+
}
|
|
239
|
+
</style>`,
|
|
250
240
|
);
|
|
251
|
-
ul
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
241
|
+
const ul = doc.getElementsByTagName("ul")?.[0];
|
|
242
|
+
if (ul) {
|
|
243
|
+
const newLis = [];
|
|
244
|
+
const lis = ul.getElementsByTagName("li");
|
|
245
|
+
lis?.forEach((li) => {
|
|
246
|
+
const appDir = li.firstChild?.text?.split("/")?.[1];
|
|
247
|
+
if (localApps.has(appDir)) {
|
|
248
|
+
newLis.push(li.toString());
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
newLis.push(
|
|
252
|
+
...links.sort().map((link) => {
|
|
253
|
+
// we remove the query parameters from the link text
|
|
254
|
+
const linkText = link.indexOf("?") === -1 ? link : link.substr(0, link.indexOf("?"));
|
|
255
|
+
// renders a UI5 link ;-)
|
|
256
|
+
return `<li><a class="ui5" href="${link}">${linkText}</a></li>`;
|
|
257
|
+
}),
|
|
258
|
+
);
|
|
259
|
+
ul.innerHTML = newLis.join("\n");
|
|
260
|
+
} else {
|
|
261
|
+
LOG.warn(`Failed to inject application links into CDS index page!`);
|
|
262
|
+
}
|
|
263
|
+
},
|
|
264
|
+
);
|
|
265
|
+
next();
|
|
266
|
+
});
|
|
259
267
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
268
|
+
// move our middleware before the CDS index serve middleware to
|
|
269
|
+
// allow that we can intercept the response and modify it to
|
|
270
|
+
// inject our application pages an remove the exitsing ones
|
|
271
|
+
const middlewareStack = app?._router?.stack;
|
|
272
|
+
if (Array.isArray(middlewareStack)) {
|
|
273
|
+
const cmw = middlewareStack.pop();
|
|
274
|
+
const idxOfServeStatic = middlewareStack.findIndex((layer) => layer.name === "serveStatic");
|
|
275
|
+
if (idxOfServeStatic !== -1) {
|
|
276
|
+
middlewareStack.splice(idxOfServeStatic, 0, cmw);
|
|
277
|
+
} else {
|
|
278
|
+
LOG.error(`Failed to determine welcome page middleware! The links of the application pages may not work properly!`);
|
|
279
|
+
}
|
|
269
280
|
} else {
|
|
270
|
-
LOG.error(`Failed to
|
|
281
|
+
LOG.error(`Failed to inject application pages to welcome page! The links of the application pages may not work properly!`);
|
|
271
282
|
}
|
|
272
|
-
} else {
|
|
273
|
-
LOG.error(`Failed to inject application pages to welcome page! The links of the application pages may not work properly!`);
|
|
274
283
|
}
|
|
284
|
+
} else {
|
|
285
|
+
LOG.info("Skip execution of plugin! The plugin is only active for 'cds serve'!");
|
|
275
286
|
}
|
|
276
|
-
} else {
|
|
277
|
-
LOG.info("Skip execution of plugin! The plugin is only active for 'cds serve'!");
|
|
278
|
-
}
|
|
279
287
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
// check if the register function for build tasks is available at the cds object
|
|
285
|
-
// and if the Plugin class is available to register the cds build task to cover
|
|
286
|
-
// the tracks of the cds-plugin-ui5 workspace configuration and dependencies
|
|
287
|
-
const { minVersion, satisfies } = require("semver");
|
|
288
|
-
if (typeof cds.build?.register === "function" && typeof cds.build?.Plugin?.constructor === "function") {
|
|
289
|
-
const { readFile, writeFile } = require("fs").promises;
|
|
290
|
-
const { existsSync } = require("fs");
|
|
291
|
-
const { join } = require("path");
|
|
292
|
-
const util = require("util");
|
|
293
|
-
const exec = util.promisify(require("child_process").exec);
|
|
294
|
-
|
|
295
|
-
// helper to check whether a semantic version is valid
|
|
296
|
-
const valid = (version) => {
|
|
297
|
-
try {
|
|
298
|
-
return minVersion(version) !== null;
|
|
299
|
-
} catch (e) {
|
|
300
|
-
return false;
|
|
301
|
-
}
|
|
302
|
-
};
|
|
288
|
+
// bootstrap completed, unlock the "served" event
|
|
289
|
+
bootstrapped();
|
|
290
|
+
});
|
|
303
291
|
|
|
304
|
-
//
|
|
305
|
-
cds
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
292
|
+
// check if the register function for build tasks is available at the cds object
|
|
293
|
+
// and if the Plugin class is available to register the cds build task to cover
|
|
294
|
+
// the tracks of the cds-plugin-ui5 workspace configuration and dependencies
|
|
295
|
+
const { minVersion, satisfies } = require("semver");
|
|
296
|
+
if (typeof cds.build?.register === "function" && typeof cds.build?.Plugin?.constructor === "function") {
|
|
297
|
+
const { readFile, writeFile } = require("fs").promises;
|
|
298
|
+
const { existsSync } = require("fs");
|
|
299
|
+
const { join } = require("path");
|
|
300
|
+
const util = require("util");
|
|
301
|
+
const exec = util.promisify(require("child_process").exec);
|
|
302
|
+
|
|
303
|
+
// log the version of the cds-plugin-ui5
|
|
304
|
+
logVersion();
|
|
305
|
+
|
|
306
|
+
// helper to check whether a semantic version is valid
|
|
307
|
+
const valid = (version) => {
|
|
308
|
+
try {
|
|
309
|
+
return minVersion(version) !== null;
|
|
310
|
+
// eslint-disable-next-line no-unused-vars
|
|
311
|
+
} catch (err) {
|
|
312
|
+
return false;
|
|
322
313
|
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
// register the cds build task to sanitize the package.json and update the package-lock.json
|
|
317
|
+
cds.build.register(
|
|
318
|
+
"ui5",
|
|
319
|
+
/**
|
|
320
|
+
* CDS Build Plugin to ensure that the workspace configuration and the workspace dev
|
|
321
|
+
* dependencies are removed and finally runs the npm install --package-lock-only to
|
|
322
|
+
* update the package-lock.json
|
|
323
|
+
*/
|
|
324
|
+
class UI5Plugin extends cds.build.Plugin {
|
|
325
|
+
static taskDefaults = { src: cds.env.folders.srv };
|
|
326
|
+
static hasTask() {
|
|
327
|
+
return true; // plugin is a cds build task
|
|
328
328
|
}
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
if (!model) return;
|
|
334
|
-
const namespace = model.namespace || "<unknown>";
|
|
335
|
-
// sanitize the package.json if it exists
|
|
336
|
-
const packageJsonPath = join(this.task.dest, "package.json");
|
|
337
|
-
if (existsSync(packageJsonPath)) {
|
|
338
|
-
LOG.info(`Sanitizing the package.json for "${namespace}"...`);
|
|
339
|
-
const packageJson = JSON.parse(await readFile(packageJsonPath), "utf-8");
|
|
340
|
-
let modified = false;
|
|
341
|
-
// remove the workspace configuration
|
|
342
|
-
if (packageJson.workspaces) {
|
|
343
|
-
delete packageJson.workspaces;
|
|
344
|
-
modified = true;
|
|
329
|
+
init() {}
|
|
330
|
+
clean() {
|
|
331
|
+
if (!satisfies(cdsdkVersion, ">=8")) {
|
|
332
|
+
this._priority = -1; // hack to ensure that the task is executed last!
|
|
345
333
|
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
return acc;
|
|
353
|
-
}, {});
|
|
354
|
-
modified = true;
|
|
355
|
-
}
|
|
356
|
-
// overwrite the package.json if it was modified only
|
|
357
|
-
if (modified) {
|
|
358
|
-
await writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2), "utf-8");
|
|
334
|
+
}
|
|
335
|
+
get priority() {
|
|
336
|
+
if (!satisfies(cdsdkVersion, ">=8")) {
|
|
337
|
+
return this._priority || 1;
|
|
338
|
+
} else {
|
|
339
|
+
return -1;
|
|
359
340
|
}
|
|
360
341
|
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
LOG.
|
|
342
|
+
async build() {
|
|
343
|
+
// determine the namespace from the model
|
|
344
|
+
const model = await this.model();
|
|
345
|
+
if (!model) return;
|
|
346
|
+
const namespace = model.namespace || "<unknown>";
|
|
347
|
+
// sanitize the package.json if it exists
|
|
348
|
+
const packageJsonPath = join(this.task.dest, "package.json");
|
|
349
|
+
if (existsSync(packageJsonPath)) {
|
|
350
|
+
LOG.info(`Sanitizing the package.json for "${namespace}"...`);
|
|
351
|
+
const packageJson = JSON.parse(await readFile(packageJsonPath), "utf-8");
|
|
352
|
+
let modified = false;
|
|
353
|
+
// remove the workspace configuration
|
|
354
|
+
if (packageJson.workspaces) {
|
|
355
|
+
delete packageJson.workspaces;
|
|
356
|
+
modified = true;
|
|
357
|
+
}
|
|
358
|
+
// remove the workspace dev dependencies and the cds-plugin-ui5
|
|
359
|
+
if (packageJson.devDependencies) {
|
|
360
|
+
packageJson.devDependencies = Object.entries(packageJson.devDependencies).reduce((acc, [dep, version]) => {
|
|
361
|
+
if (valid(version) && dep !== "cds-plugin-ui5") {
|
|
362
|
+
acc[dep] = version;
|
|
363
|
+
}
|
|
364
|
+
return acc;
|
|
365
|
+
}, {});
|
|
366
|
+
modified = true;
|
|
367
|
+
}
|
|
368
|
+
// overwrite the package.json if it was modified only
|
|
369
|
+
if (modified) {
|
|
370
|
+
await writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2), "utf-8");
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
// update the package-lock.json if it exists
|
|
374
|
+
if (existsSync(join(this.task.dest, "package-lock.json"))) {
|
|
375
|
+
LOG.info(`Updating the package-lock.json for "${namespace}"...`);
|
|
376
|
+
// run the npm install --package-lock-only to only update the package-lock.json
|
|
377
|
+
// without installing the dependencies to node_modules
|
|
378
|
+
try {
|
|
379
|
+
/* const { stdout, stderr } = */ await exec("npm install --package-lock-only", { cwd: this.task.dest });
|
|
380
|
+
} catch (e) {
|
|
381
|
+
LOG.error(`Failed to update the package-lock.json for "${namespace}"! Error: ${e.code} - ${e.message}`);
|
|
382
|
+
}
|
|
370
383
|
}
|
|
371
384
|
}
|
|
372
|
-
}
|
|
385
|
+
},
|
|
386
|
+
);
|
|
387
|
+
} else {
|
|
388
|
+
if (!satisfies(cdsdkVersion, ">=7.5.0")) {
|
|
389
|
+
// TODO: add error message to inform the user that the cds build task is not available
|
|
390
|
+
// and that the @sap/cds-dk version is too old to support the cds build task
|
|
391
|
+
LOG.warn("The cds build task requires @sap/cds-dk version >= 7.5.0! Skipping execution as your @sap/cds-dk version is too old...");
|
|
373
392
|
}
|
|
374
|
-
);
|
|
375
|
-
} else {
|
|
376
|
-
if (!satisfies(cdsdkVersion, ">=7.5.0")) {
|
|
377
|
-
// TODO: add error message to inform the user that the cds build task is not available
|
|
378
|
-
// and that the @sap/cds-dk version is too old to support the cds build task
|
|
379
|
-
LOG.warn("The cds build task requires @sap/cds-dk version >= 7.5.0! Skipping execution as your @sap/cds-dk version is too old...");
|
|
380
393
|
}
|
|
381
394
|
}
|
|
382
395
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cds-plugin-ui5",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.1",
|
|
4
4
|
"description": "A CDS server plugin to inject the middlewares of all related UI5 tooling based projects.",
|
|
5
5
|
"author": "Peter Muessig",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
"directory": "packages/cds-plugin-ui5"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@ui5/fs": "^4
|
|
15
|
-
"@ui5/project": "^4
|
|
16
|
-
"@ui5/server": "^4
|
|
14
|
+
"@ui5/fs": "^4",
|
|
15
|
+
"@ui5/project": "^4",
|
|
16
|
+
"@ui5/server": "^4",
|
|
17
17
|
"js-yaml": "^4.1.0",
|
|
18
18
|
"node-html-parser": "^6.1.13",
|
|
19
19
|
"semver": "^7.6.3"
|
|
@@ -26,5 +26,5 @@
|
|
|
26
26
|
"@sap/cds": ">=6.8.2",
|
|
27
27
|
"express": ">=4.18.2"
|
|
28
28
|
},
|
|
29
|
-
"gitHead": "
|
|
29
|
+
"gitHead": "49c0415f143ba94b88f522362f027e84021933d2"
|
|
30
30
|
}
|