cds-plugin-ui5 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/README.md +55 -0
- package/cds-plugin.js +5 -4
- package/lib/applyUI5Middleware.js +25 -3
- package/lib/findUI5Modules.js +24 -3
- package/lib/log.js +1 -1
- 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.5.0](https://github.com/ui5-community/ui5-ecosystem-showcase/compare/cds-plugin-ui5@0.4.0...cds-plugin-ui5@0.5.0) (2023-09-02)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* **cds-plugin-ui5:** alternative ui5.yamls / ignore HTML fragments ([#824](https://github.com/ui5-community/ui5-ecosystem-showcase/issues/824)) ([20bfb51](https://github.com/ui5-community/ui5-ecosystem-showcase/commit/20bfb51fc46de05b000e617eaca6a30c2a7aae6a)), closes [#822](https://github.com/ui5-community/ui5-ecosystem-showcase/issues/822) [#823](https://github.com/ui5-community/ui5-ecosystem-showcase/issues/823)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# [0.4.0](https://github.com/ui5-community/ui5-ecosystem-showcase/compare/cds-plugin-ui5@0.3.0...cds-plugin-ui5@0.4.0) (2023-08-21)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Features
|
|
21
|
+
|
|
22
|
+
* **cds-plugin-ui5:** allow to attach custom app pages to cds server ([#800](https://github.com/ui5-community/ui5-ecosystem-showcase/issues/800)) ([0670b5e](https://github.com/ui5-community/ui5-ecosystem-showcase/commit/0670b5e9d01175ecf9d1f0db332963b8c9fec007)), closes [#785](https://github.com/ui5-community/ui5-ecosystem-showcase/issues/785)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
6
28
|
# [0.3.0](https://github.com/ui5-community/ui5-ecosystem-showcase/compare/cds-plugin-ui5@0.2.3...cds-plugin-ui5@0.3.0) (2023-08-17)
|
|
7
29
|
|
|
8
30
|
|
package/README.md
CHANGED
|
@@ -21,6 +21,61 @@ npm add cds-plugin-ui5 -D
|
|
|
21
21
|
|
|
22
22
|
That's it!
|
|
23
23
|
|
|
24
|
+
### Configuration
|
|
25
|
+
|
|
26
|
+
The plugin can be configured using the `cds-plugin-ui5` section in the `package.json`. To define a custom configFile for any module you can add a configuration object for each module in the `modules` section:
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"cds-plugin-ui5": {
|
|
31
|
+
"modules": {
|
|
32
|
+
"ui5-bookshop": {
|
|
33
|
+
"configFile": "ui5.yaml"
|
|
34
|
+
},
|
|
35
|
+
"cds-ui5-bookshopviewer": {
|
|
36
|
+
"configFile": "ui5-dist.yaml"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The key is the `moduleId` which is either the directory name for local apps in the `app` directory of the CAP server or for dependencies the `name` from the `package.json`. As value you can specify an alternative `configFile` name.
|
|
44
|
+
|
|
45
|
+
A second option to override this configuration is the usage of the environment variable `CDS_PLUGIN_UI5_MODULES`. It contains the JSON string from the configuration above, e.g.:
|
|
46
|
+
|
|
47
|
+
```sh
|
|
48
|
+
CDS_PLUGIN_UI5_MODULES="{ \"ui5-bookshop\": { \"configFile\": \"ui5-dist.yaml\" } }" cds-serve
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Info for UI5 Tooling Extension Developers
|
|
52
|
+
|
|
53
|
+
Custom middlewares may generate virtual app pages which should also be listed as web applications in the welcome page of the `@sap/cds` server. This is possible by assigning a static `getAppPages` function to the middleware function. The following snippet show-cases how this can be done:
|
|
54
|
+
|
|
55
|
+
```js
|
|
56
|
+
// the middleware factory function
|
|
57
|
+
module.exports = async ({ log, resources, options }) => {
|
|
58
|
+
// create the middleware function
|
|
59
|
+
const mwFn = (req, res, next) => {
|
|
60
|
+
[...]
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Returns an array of app pages to be added to the welcome
|
|
65
|
+
* page of the <code>@sap/cds</code> server.
|
|
66
|
+
* @returns {undefined|string[]} array of app pages
|
|
67
|
+
*/
|
|
68
|
+
mwFn.getAppPages = function() {
|
|
69
|
+
return ["/test.html"];
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
// finally return the middleware function
|
|
73
|
+
return mwFn;
|
|
74
|
+
};
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The returned app pages will be added to the welcome page within the respective mount path.
|
|
78
|
+
|
|
24
79
|
## Support
|
|
25
80
|
|
|
26
81
|
Please use the GitHub bug tracking system to post questions, bug reports or to create pull requests.
|
package/cds-plugin.js
CHANGED
|
@@ -32,16 +32,16 @@ cds.on("bootstrap", async function bootstrap(app) {
|
|
|
32
32
|
|
|
33
33
|
const cwd = process.cwd();
|
|
34
34
|
const ui5Modules = await findUI5Modules({ cwd });
|
|
35
|
-
const localApps = ui5Modules
|
|
35
|
+
const { localApps, configFiles } = ui5Modules;
|
|
36
36
|
|
|
37
37
|
const links = [];
|
|
38
38
|
|
|
39
39
|
// register the UI5 modules via their own router/middlewares
|
|
40
40
|
for await (const ui5Module of ui5Modules) {
|
|
41
|
-
const { mountPath, modulePath } = ui5Module;
|
|
41
|
+
const { moduleId, mountPath, modulePath } = ui5Module;
|
|
42
42
|
|
|
43
43
|
// mounting the Router for the UI5 application to the CAP server
|
|
44
|
-
log.info(`Mounting ${mountPath} to UI5 app ${modulePath}`);
|
|
44
|
+
log.info(`Mounting ${mountPath} to UI5 app ${modulePath} (id=${moduleId})${configFiles[moduleId] ? ` using configFile=${configFiles[moduleId]}` : ""}`);
|
|
45
45
|
|
|
46
46
|
// create a patched router
|
|
47
47
|
const router = await createPatchedRouter();
|
|
@@ -51,6 +51,7 @@ cds.on("bootstrap", async function bootstrap(app) {
|
|
|
51
51
|
const appInfo = await applyUI5Middleware(router, {
|
|
52
52
|
basePath: modulePath,
|
|
53
53
|
configPath: modulePath,
|
|
54
|
+
configFile: configFiles[moduleId],
|
|
54
55
|
});
|
|
55
56
|
|
|
56
57
|
// register the router to the specified mount path
|
|
@@ -59,7 +60,7 @@ cds.on("bootstrap", async function bootstrap(app) {
|
|
|
59
60
|
// append the HTML pages to the links
|
|
60
61
|
appInfo.pages.forEach((page) => {
|
|
61
62
|
const prefix = mountPath !== "/" ? mountPath : "";
|
|
62
|
-
links.push(`${prefix}${page
|
|
63
|
+
links.push(`${prefix}${page}`);
|
|
63
64
|
});
|
|
64
65
|
}
|
|
65
66
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
const path = require("path");
|
|
2
2
|
|
|
3
|
+
const log = require("./log");
|
|
4
|
+
|
|
3
5
|
/**
|
|
4
6
|
* @typedef UI5AppInfo
|
|
5
7
|
* @type {object}
|
|
@@ -14,16 +16,17 @@ const path = require("path");
|
|
|
14
16
|
* @param {object} options configuration options
|
|
15
17
|
* @param {string} options.basePath base path of the UI5 application
|
|
16
18
|
* @param {string} [options.configPath] path to the ui5.yaml (defaults to "${basePath}/ui5.yaml")
|
|
19
|
+
* @param {string} [options.configFile] name of the config file (defaults to "ui5.yaml")
|
|
17
20
|
* @returns {UI5AppInfo} UI5 application information object
|
|
18
21
|
*/
|
|
19
|
-
module.exports = async function applyUI5Middleware(router, { basePath, configPath }) {
|
|
22
|
+
module.exports = async function applyUI5Middleware(router, { basePath, configPath, configFile = "ui5.yaml" }) {
|
|
20
23
|
const { graphFromPackageDependencies } = await import("@ui5/project/graph");
|
|
21
24
|
const { createReaderCollection } = await import("@ui5/fs/resourceFactory");
|
|
22
25
|
|
|
23
26
|
const graph = await graphFromPackageDependencies({
|
|
24
27
|
workspaceName: process.env["ui5-workspace"],
|
|
25
28
|
cwd: basePath,
|
|
26
|
-
rootConfigPath: configPath ? path.resolve(configPath,
|
|
29
|
+
rootConfigPath: configPath ? path.resolve(configPath, configFile) : undefined,
|
|
27
30
|
});
|
|
28
31
|
|
|
29
32
|
const rootProject = graph.getRoot();
|
|
@@ -69,7 +72,26 @@ module.exports = async function applyUI5Middleware(router, { basePath, configPat
|
|
|
69
72
|
});
|
|
70
73
|
await middlewareManager.applyMiddleware(router);
|
|
71
74
|
|
|
75
|
+
// collect app pages from workspace (glob testing: https://globster.xyz/ and https://codepen.io/mrmlnc/pen/OXQjMe)
|
|
76
|
+
// -> but exclude the HTML fragments from the list of app pages!
|
|
77
|
+
const pages = (await rootReader.byGlob("**/!(*.fragment).{html,htm}")).map((resource) => resource.getPath());
|
|
78
|
+
|
|
79
|
+
// collect app pages from middlewares implementing the getAppPages
|
|
80
|
+
middlewareManager.middlewareExecutionOrder?.map((name) => {
|
|
81
|
+
const { middleware } = middlewareManager.middleware?.[name] || {};
|
|
82
|
+
if (typeof middleware?.getAppPages === "function") {
|
|
83
|
+
const customAppPages = middleware.getAppPages();
|
|
84
|
+
if (Array.isArray(customAppPages)) {
|
|
85
|
+
pages.push(...customAppPages);
|
|
86
|
+
} else {
|
|
87
|
+
if (customAppPages) {
|
|
88
|
+
log.warn(`The middleware ${name} returns an unexpected value for "getAppPages". The value must be either undefined or string[]! Ignoring app pages from middleware!`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
|
|
72
94
|
return {
|
|
73
|
-
pages
|
|
95
|
+
pages,
|
|
74
96
|
};
|
|
75
97
|
};
|
package/lib/findUI5Modules.js
CHANGED
|
@@ -59,8 +59,8 @@ module.exports = async function findUI5Modules({ cwd, skipLocalApps, skipDeps })
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
// lookup the UI5 modules in the project dependencies
|
|
62
|
+
const pkgJson = require(path.join(cwd, "package.json"));
|
|
62
63
|
if (!skipDeps) {
|
|
63
|
-
const pkgJson = require(path.join(cwd, "package.json"));
|
|
64
64
|
const deps = [];
|
|
65
65
|
deps.push(...Object.keys(pkgJson.dependencies || {}));
|
|
66
66
|
deps.push(...Object.keys(pkgJson.devDependencies || {}));
|
|
@@ -80,9 +80,23 @@ module.exports = async function findUI5Modules({ cwd, skipLocalApps, skipDeps })
|
|
|
80
80
|
);
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
+
// determine module configuration:
|
|
84
|
+
// => env variable: CDS_PLUGIN_UI5_MODULES (JSONObject<string, object>)
|
|
85
|
+
// => package.json: cds-plugin-ui5 > modules (JSONObject<string, object>)
|
|
86
|
+
// JSONObject<string, object>: key = moduleId (folder name, npm package name), object={ configFile: string }
|
|
87
|
+
let modulesConfig;
|
|
88
|
+
try {
|
|
89
|
+
modulesConfig = JSON.parse(process.env.CDS_PLUGIN_UI5_MODULES);
|
|
90
|
+
log.info(`Using modules configuration from env`);
|
|
91
|
+
} catch (err) {
|
|
92
|
+
modulesConfig = pkgJson.cds?.["cds-plugin-ui5"]?.modules;
|
|
93
|
+
}
|
|
94
|
+
log.debug(JSON.stringify(modulesConfig, undefined, 2));
|
|
95
|
+
|
|
83
96
|
// if apps are available, attach the middlewares of the UI5 apps
|
|
84
97
|
// to the express of the CAP server via a express router
|
|
85
98
|
const apps = [];
|
|
99
|
+
apps.configFiles = {};
|
|
86
100
|
if (appDirs) {
|
|
87
101
|
for await (const appDir of appDirs) {
|
|
88
102
|
// read the ui5.yaml file to extract the configuration
|
|
@@ -95,7 +109,7 @@ module.exports = async function findUI5Modules({ cwd, skipLocalApps, skipDeps })
|
|
|
95
109
|
ui5Configs = yaml.loadAll(content);
|
|
96
110
|
} catch (err) {
|
|
97
111
|
if (err.name === "YAMLException") {
|
|
98
|
-
log(
|
|
112
|
+
log.error(`Failed to read ${ui5YamlPath}!`);
|
|
99
113
|
}
|
|
100
114
|
throw err;
|
|
101
115
|
}
|
|
@@ -124,12 +138,19 @@ module.exports = async function findUI5Modules({ cwd, skipLocalApps, skipDeps })
|
|
|
124
138
|
const packageJsonContent = fs.readFileSync(packageJsonPath, "utf-8");
|
|
125
139
|
moduleName = JSON.parse(packageJsonContent).name;
|
|
126
140
|
}
|
|
127
|
-
const moduleId = moduleName || appDir;
|
|
141
|
+
const moduleId = moduleName || path.basename(appDir);
|
|
142
|
+
|
|
143
|
+
// store the custom config file
|
|
144
|
+
if (modulesConfig?.[moduleId]?.configFile) {
|
|
145
|
+
apps.configFiles[moduleId] = modulesConfig?.[moduleId]?.configFile;
|
|
146
|
+
}
|
|
128
147
|
|
|
129
148
|
apps.push({ moduleId, modulePath, mountPath });
|
|
130
149
|
}
|
|
131
150
|
}
|
|
132
151
|
}
|
|
133
152
|
apps.localApps = localApps; // necessary for CAP index.html rewrite
|
|
153
|
+
|
|
154
|
+
// return the apps
|
|
134
155
|
return apps;
|
|
135
156
|
};
|
package/lib/log.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cds-plugin-ui5",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "A CAP server cds-plugin to inject the middlewares of all related UI5 tooling based projects.",
|
|
5
5
|
"author": "Peter Muessig",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -24,5 +24,5 @@
|
|
|
24
24
|
"@sap/cds": ">=6.8.2",
|
|
25
25
|
"express": ">=4.18.2"
|
|
26
26
|
},
|
|
27
|
-
"gitHead": "
|
|
27
|
+
"gitHead": "9db24d0cd23d691749cd1419f24ec7f6cf7c1f5b"
|
|
28
28
|
}
|