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