@ui5/webcomponents-tools 0.0.0-4e88b8243 → 0.0.0-50f1454ef
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 +222 -0
- package/assets-meta.js +1 -5
- package/components-package/eslint.js +4 -37
- package/components-package/nps.js +28 -7
- package/components-package/vite.config.js +7 -11
- package/components-package/wdio.js +1 -1
- package/lib/cem/custom-elements-manifest.config.mjs +42 -39
- package/lib/cem/schema-internal.json +9 -0
- package/lib/cem/utils.mjs +18 -8
- package/lib/cem/validate.js +37 -40
- package/lib/create-icons/index.js +5 -4
- package/lib/create-new-component/{tsFileContentTemplate.js → Component.js} +11 -8
- package/lib/create-new-component/ComponentTemplate.js +12 -0
- package/lib/create-new-component/index.js +11 -10
- package/lib/css-processors/css-processor-components.mjs +2 -1
- package/lib/dev-server/virtual-index-html-plugin.js +24 -20
- package/package.json +5 -9
- package/components-package/cypress/support/commands.js +0 -39
- package/components-package/cypress/support/component-index.html +0 -17
- package/components-package/cypress/support/component.d.ts +0 -23
- package/components-package/cypress/support/component.js +0 -34
- package/components-package/cypress.config.js +0 -19
- package/types/index.d.ts +0 -1
package/CHANGELOG.md
CHANGED
@@ -3,6 +3,228 @@
|
|
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
|
+
# [2.11.0-rc.1](https://github.com/SAP/ui5-webcomponents/compare/v2.11.0-rc.0...v2.11.0-rc.1) (2025-05-15)
|
7
|
+
|
8
|
+
**Note:** Version bump only for package @ui5/webcomponents-tools
|
9
|
+
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
# [2.11.0-rc.0](https://github.com/SAP/ui5-webcomponents/compare/v2.10.0...v2.11.0-rc.0) (2025-05-08)
|
15
|
+
|
16
|
+
**Note:** Version bump only for package @ui5/webcomponents-tools
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
# [2.10.0](https://github.com/SAP/ui5-webcomponents/compare/v2.10.0-rc.3...v2.10.0) (2025-05-07)
|
23
|
+
|
24
|
+
**Note:** Version bump only for package @ui5/webcomponents-tools
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
# [2.10.0-rc.3](https://github.com/SAP/ui5-webcomponents/compare/v2.10.0-rc.2...v2.10.0-rc.3) (2025-05-01)
|
31
|
+
|
32
|
+
|
33
|
+
### Bug Fixes
|
34
|
+
|
35
|
+
* escape backslash when processing component's css ([#11425](https://github.com/SAP/ui5-webcomponents/issues/11425)) ([2c4dc74](https://github.com/SAP/ui5-webcomponents/commit/2c4dc744fb06f79ec77df6cbe725723a75eecb87))
|
36
|
+
|
37
|
+
|
38
|
+
### Features
|
39
|
+
|
40
|
+
* **ui5-button:** make click button preventable ([#11318](https://github.com/SAP/ui5-webcomponents/issues/11318)) ([1f4aa92](https://github.com/SAP/ui5-webcomponents/commit/1f4aa927d2841e0c51f665ab2bdb851b1d030c35))
|
41
|
+
|
42
|
+
|
43
|
+
|
44
|
+
|
45
|
+
|
46
|
+
# [2.10.0-rc.2](https://github.com/SAP/ui5-webcomponents/compare/v2.10.0-rc.1...v2.10.0-rc.2) (2025-04-24)
|
47
|
+
|
48
|
+
**Note:** Version bump only for package @ui5/webcomponents-tools
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
|
53
|
+
|
54
|
+
# [2.10.0-rc.1](https://github.com/SAP/ui5-webcomponents/compare/v2.10.0-rc.0...v2.10.0-rc.1) (2025-04-17)
|
55
|
+
|
56
|
+
**Note:** Version bump only for package @ui5/webcomponents-tools
|
57
|
+
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
|
62
|
+
# [2.10.0-rc.0](https://github.com/SAP/ui5-webcomponents/compare/v2.9.1-rc.0...v2.10.0-rc.0) (2025-04-14)
|
63
|
+
|
64
|
+
**Note:** Version bump only for package @ui5/webcomponents-tools
|
65
|
+
|
66
|
+
|
67
|
+
|
68
|
+
|
69
|
+
|
70
|
+
## [2.9.1-rc.0](https://github.com/SAP/ui5-webcomponents/compare/v2.9.0...v2.9.1-rc.0) (2025-04-10)
|
71
|
+
|
72
|
+
**Note:** Version bump only for package @ui5/webcomponents-tools
|
73
|
+
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
|
78
|
+
# [2.9.0](https://github.com/SAP/ui5-webcomponents/compare/v2.9.0-rc.3...v2.9.0) (2025-04-04)
|
79
|
+
|
80
|
+
**Note:** Version bump only for package @ui5/webcomponents-tools
|
81
|
+
|
82
|
+
|
83
|
+
|
84
|
+
|
85
|
+
|
86
|
+
# [2.9.0-rc.3](https://github.com/SAP/ui5-webcomponents/compare/v2.9.0-rc.2...v2.9.0-rc.3) (2025-04-03)
|
87
|
+
|
88
|
+
|
89
|
+
### Bug Fixes
|
90
|
+
|
91
|
+
* **framework:** fix fetching "id" (indonesian) language ([#11251](https://github.com/SAP/ui5-webcomponents/issues/11251)) ([9a36df5](https://github.com/SAP/ui5-webcomponents/commit/9a36df5dc2191758abd665d6fb1014d645e322f7)), closes [#11233](https://github.com/SAP/ui5-webcomponents/issues/11233)
|
92
|
+
|
93
|
+
|
94
|
+
|
95
|
+
|
96
|
+
|
97
|
+
# [2.9.0-rc.2](https://github.com/SAP/ui5-webcomponents/compare/v2.9.0-rc.1...v2.9.0-rc.2) (2025-03-27)
|
98
|
+
|
99
|
+
**Note:** Version bump only for package @ui5/webcomponents-tools
|
100
|
+
|
101
|
+
|
102
|
+
|
103
|
+
|
104
|
+
|
105
|
+
# [2.9.0-rc.1](https://github.com/SAP/ui5-webcomponents/compare/v2.9.0-rc.0...v2.9.0-rc.1) (2025-03-20)
|
106
|
+
|
107
|
+
|
108
|
+
### Bug Fixes
|
109
|
+
|
110
|
+
* **tools:** fix icon imports to i18n texts ([#11091](https://github.com/SAP/ui5-webcomponents/issues/11091)) ([472ffdc](https://github.com/SAP/ui5-webcomponents/commit/472ffdcd602a4da53a839829e5a5bcf017ff618c))
|
111
|
+
|
112
|
+
|
113
|
+
|
114
|
+
|
115
|
+
|
116
|
+
# [2.9.0-rc.0](https://github.com/SAP/ui5-webcomponents/compare/v2.8.1-rc.0...v2.9.0-rc.0) (2025-03-13)
|
117
|
+
|
118
|
+
**Note:** Version bump only for package @ui5/webcomponents-tools
|
119
|
+
|
120
|
+
|
121
|
+
|
122
|
+
|
123
|
+
|
124
|
+
## [2.8.1-rc.0](https://github.com/SAP/ui5-webcomponents/compare/v2.8.0...v2.8.1-rc.0) (2025-03-06)
|
125
|
+
|
126
|
+
**Note:** Version bump only for package @ui5/webcomponents-tools
|
127
|
+
|
128
|
+
|
129
|
+
|
130
|
+
|
131
|
+
|
132
|
+
# [2.8.0](https://github.com/SAP/ui5-webcomponents/compare/v2.8.0-rc.3...v2.8.0) (2025-03-04)
|
133
|
+
|
134
|
+
**Note:** Version bump only for package @ui5/webcomponents-tools
|
135
|
+
|
136
|
+
|
137
|
+
|
138
|
+
|
139
|
+
|
140
|
+
# [2.8.0-rc.3](https://github.com/SAP/ui5-webcomponents/compare/v2.8.0-rc.2...v2.8.0-rc.3) (2025-02-27)
|
141
|
+
|
142
|
+
**Note:** Version bump only for package @ui5/webcomponents-tools
|
143
|
+
|
144
|
+
|
145
|
+
|
146
|
+
|
147
|
+
|
148
|
+
# [2.8.0-rc.2](https://github.com/SAP/ui5-webcomponents/compare/v2.8.0-rc.1...v2.8.0-rc.2) (2025-02-20)
|
149
|
+
|
150
|
+
**Note:** Version bump only for package @ui5/webcomponents-tools
|
151
|
+
|
152
|
+
|
153
|
+
|
154
|
+
|
155
|
+
|
156
|
+
# [2.8.0-rc.1](https://github.com/SAP/ui5-webcomponents/compare/v2.8.0-rc.0...v2.8.0-rc.1) (2025-02-13)
|
157
|
+
|
158
|
+
**Note:** Version bump only for package @ui5/webcomponents-tools
|
159
|
+
|
160
|
+
|
161
|
+
|
162
|
+
|
163
|
+
|
164
|
+
# [2.8.0-rc.0](https://github.com/SAP/ui5-webcomponents/compare/v2.7.0...v2.8.0-rc.0) (2025-02-06)
|
165
|
+
|
166
|
+
**Note:** Version bump only for package @ui5/webcomponents-tools
|
167
|
+
|
168
|
+
|
169
|
+
|
170
|
+
|
171
|
+
|
172
|
+
# [2.7.0](https://github.com/SAP/ui5-webcomponents/compare/v2.7.0-rc.2...v2.7.0) (2025-02-03)
|
173
|
+
|
174
|
+
**Note:** Version bump only for package @ui5/webcomponents-tools
|
175
|
+
|
176
|
+
|
177
|
+
|
178
|
+
|
179
|
+
|
180
|
+
# [2.7.0-rc.2](https://github.com/SAP/ui5-webcomponents/compare/v2.7.0-rc.1...v2.7.0-rc.2) (2025-01-30)
|
181
|
+
|
182
|
+
**Note:** Version bump only for package @ui5/webcomponents-tools
|
183
|
+
|
184
|
+
|
185
|
+
|
186
|
+
|
187
|
+
|
188
|
+
# [2.7.0-rc.1](https://github.com/SAP/ui5-webcomponents/compare/v2.7.0-rc.0...v2.7.0-rc.1) (2025-01-23)
|
189
|
+
|
190
|
+
**Note:** Version bump only for package @ui5/webcomponents-tools
|
191
|
+
|
192
|
+
|
193
|
+
|
194
|
+
|
195
|
+
|
196
|
+
# [2.7.0-rc.0](https://github.com/SAP/ui5-webcomponents/compare/v2.6.2...v2.7.0-rc.0) (2025-01-16)
|
197
|
+
|
198
|
+
**Note:** Version bump only for package @ui5/webcomponents-tools
|
199
|
+
|
200
|
+
|
201
|
+
|
202
|
+
|
203
|
+
|
204
|
+
## [2.6.2](https://github.com/SAP/ui5-webcomponents/compare/v2.6.2-rc.0...v2.6.2) (2025-01-09)
|
205
|
+
|
206
|
+
**Note:** Version bump only for package @ui5/webcomponents-tools
|
207
|
+
|
208
|
+
|
209
|
+
|
210
|
+
|
211
|
+
|
212
|
+
## [2.6.2-rc.0](https://github.com/SAP/ui5-webcomponents/compare/v2.6.1...v2.6.2-rc.0) (2025-01-09)
|
213
|
+
|
214
|
+
**Note:** Version bump only for package @ui5/webcomponents-tools
|
215
|
+
|
216
|
+
|
217
|
+
|
218
|
+
|
219
|
+
|
220
|
+
## [2.6.1](https://github.com/SAP/ui5-webcomponents/compare/v2.6.0...v2.6.1) (2025-01-08)
|
221
|
+
|
222
|
+
**Note:** Version bump only for package @ui5/webcomponents-tools
|
223
|
+
|
224
|
+
|
225
|
+
|
226
|
+
|
227
|
+
|
6
228
|
# [2.6.0](https://github.com/SAP/ui5-webcomponents/compare/v2.6.0-rc.5...v2.6.0) (2025-01-07)
|
7
229
|
|
8
230
|
**Note:** Version bump only for package @ui5/webcomponents-tools
|
package/assets-meta.js
CHANGED
@@ -10,10 +10,6 @@ const assetsMeta = {
|
|
10
10
|
"sap_horizon_dark",
|
11
11
|
"sap_horizon_hcb",
|
12
12
|
"sap_horizon_hcw",
|
13
|
-
"sap_horizon_exp",
|
14
|
-
"sap_horizon_dark_exp",
|
15
|
-
"sap_horizon_hcb_exp",
|
16
|
-
"sap_horizon_hcw_exp",
|
17
13
|
],
|
18
14
|
},
|
19
15
|
"languages": {
|
@@ -42,7 +38,7 @@ const assetsMeta = {
|
|
42
38
|
"hi",
|
43
39
|
"hr",
|
44
40
|
"hu",
|
45
|
-
"
|
41
|
+
"id",
|
46
42
|
"it",
|
47
43
|
"iw",
|
48
44
|
"ja",
|
@@ -17,8 +17,7 @@ const getTsModeOverrides = () => {
|
|
17
17
|
],
|
18
18
|
parserOptions: {
|
19
19
|
"project": [
|
20
|
-
"./tsconfig.json"
|
21
|
-
"./cypress/tsconfig.json",
|
20
|
+
"./tsconfig.json"
|
22
21
|
],
|
23
22
|
EXPERIMENTAL_useSourceOfProjectReferenceRedirect: true,
|
24
23
|
},
|
@@ -42,8 +41,10 @@ const getTsModeOverrides = () => {
|
|
42
41
|
|
43
42
|
const tsxConfiguration = JSON.parse(JSON.stringify(tsConfiguration));
|
44
43
|
tsxConfiguration.files = ["*.tsx"];
|
44
|
+
tsxConfiguration.plugins.push("jsx-no-leaked-values");
|
45
45
|
tsxConfiguration.rules = {
|
46
46
|
...tsxConfiguration.rules,
|
47
|
+
"jsx-no-leaked-values/jsx-no-leaked-values": "error",
|
47
48
|
"@typescript-eslint/unbound-method": "off", // to be able to attach on* listeners
|
48
49
|
"@typescript-eslint/no-misused-promises": "off", // to be able to have async event listeners
|
49
50
|
"operator-linebreak": "off",
|
@@ -53,43 +54,9 @@ const getTsModeOverrides = () => {
|
|
53
54
|
"comma-dangle": "off"
|
54
55
|
};
|
55
56
|
|
56
|
-
const cypressConfiguration = {
|
57
|
-
"files": ["**/cypress/**/*.ts"],
|
58
|
-
|
59
|
-
"plugins": [
|
60
|
-
"cypress"
|
61
|
-
],
|
62
|
-
extends: [
|
63
|
-
"plugin:cypress/recommended"
|
64
|
-
],
|
65
|
-
"env": {
|
66
|
-
"cypress/globals": true
|
67
|
-
},
|
68
|
-
"rules": {
|
69
|
-
"max-nested-callbacks": 0,
|
70
|
-
"@typescript-eslint/no-namespace": "off",
|
71
|
-
"cypress/no-assigning-return-values": "error",
|
72
|
-
"cypress/no-unnecessary-waiting": "error",
|
73
|
-
"cypress/assertion-before-screenshot": "warn",
|
74
|
-
"cypress/no-force": "warn",
|
75
|
-
"cypress/no-async-tests": "error",
|
76
|
-
"cypress/no-async-before": "error",
|
77
|
-
"cypress/no-pause": "error",
|
78
|
-
"import/no-extraneous-dependencies": [
|
79
|
-
"error",
|
80
|
-
{
|
81
|
-
"devDependencies": [
|
82
|
-
"**/cypress/**/*.ts"
|
83
|
-
]
|
84
|
-
}
|
85
|
-
]
|
86
|
-
}
|
87
|
-
}
|
88
|
-
|
89
57
|
return [
|
90
58
|
tsConfiguration,
|
91
|
-
tsxConfiguration
|
92
|
-
cypressConfiguration,
|
59
|
+
tsxConfiguration
|
93
60
|
];
|
94
61
|
}
|
95
62
|
|
@@ -9,6 +9,25 @@ if (process.env.DEPLOY) {
|
|
9
9
|
websiteBaseUrl = "/ui5-webcomponents/nightly/";
|
10
10
|
}
|
11
11
|
|
12
|
+
const cypressEnvVariables = (options, predefinedVars) => {
|
13
|
+
let variables = [];
|
14
|
+
const { cypress_code_coverage, cypress_acc_tests } = options.internal ?? {};
|
15
|
+
|
16
|
+
// Handle environment variables like TEST_SUITE
|
17
|
+
if (predefinedVars) {
|
18
|
+
variables = [...predefinedVars];
|
19
|
+
}
|
20
|
+
|
21
|
+
// The coverage task is always registered and requires an explicit variable whether to generate a report or not
|
22
|
+
variables.push(`CYPRESS_COVERAGE=${!!cypress_code_coverage}`);
|
23
|
+
|
24
|
+
if (cypress_acc_tests) {
|
25
|
+
variables.push("CYPRESS_UI5_ACC=true");
|
26
|
+
}
|
27
|
+
|
28
|
+
return variables.length ? `cross-env ${variables.join(" ")}` : "";
|
29
|
+
}
|
30
|
+
|
12
31
|
const getScripts = (options) => {
|
13
32
|
|
14
33
|
// The script creates all JS modules (dist/illustrations/{illustrationName}.js) out of the existing SVGs
|
@@ -17,9 +36,9 @@ const getScripts = (options) => {
|
|
17
36
|
const createIllustrationsJSImportsScript = illustrations.join(" && ");
|
18
37
|
|
19
38
|
// The script creates the "src/generated/js-imports/Illustration.js" file that registers loaders (dynamic JS imports) for each illustration
|
20
|
-
|
39
|
+
const createIllustrationsLoadersScript = illustrationsData.map(illustrations => `node ${LIB}/generate-js-imports/illustrations.js ${illustrations.destinationPath} ${illustrations.dynamicImports.outputFile} ${illustrations.set} ${illustrations.collection} ${illustrations.dynamicImports.location} ${illustrations.dynamicImports.filterOut.join(" ")}`).join(" && ");
|
21
40
|
|
22
|
-
const tsOption = !options.legacy;
|
41
|
+
const tsOption = !options.legacy || options.jsx;
|
23
42
|
const tsCommandOld = tsOption ? "tsc" : "";
|
24
43
|
let tsWatchCommandStandalone = tsOption ? "tsc --watch" : "";
|
25
44
|
// this command is only used for standalone projects. monorepo projects get their watch from vite, so opt-out here
|
@@ -31,7 +50,7 @@ const getScripts = (options) => {
|
|
31
50
|
if (tsOption) {
|
32
51
|
try {
|
33
52
|
require("typescript");
|
34
|
-
} catch(e) {
|
53
|
+
} catch (e) {
|
35
54
|
console.error(`TypeScript is not found. Try to install it by running \`npm install --save-dev typescript\` if you are using npm or by running \`yarn add --dev typescript\` if you are using yarn.`);
|
36
55
|
process.exit(e.code);
|
37
56
|
}
|
@@ -122,8 +141,10 @@ const getScripts = (options) => {
|
|
122
141
|
},
|
123
142
|
start: "nps prepare watch.devServer",
|
124
143
|
test: `node "${LIB}/test-runner/test-runner.js"`,
|
125
|
-
"test-cy-ci":
|
126
|
-
"test-cy-
|
144
|
+
"test-cy-ci": `${cypressEnvVariables(options)} yarn cypress run --component --browser chrome`,
|
145
|
+
"test-cy-ci-suite-1": `${cypressEnvVariables(options, ["TEST_SUITE=SUITE1"])} yarn cypress run --component --browser chrome`,
|
146
|
+
"test-cy-ci-suite-2": `${cypressEnvVariables(options, ["TEST_SUITE=SUITE2"])} yarn cypress run --component --browser chrome`,
|
147
|
+
"test-cy-open": `${cypressEnvVariables(options)} yarn cypress open --component --browser chrome`,
|
127
148
|
"test-suite-1": `node "${LIB}/test-runner/test-runner.js" --suite suite1`,
|
128
149
|
"test-suite-2": `node "${LIB}/test-runner/test-runner.js" --suite suite2`,
|
129
150
|
startWithScope: "nps scope.prepare scope.watchWithBundle",
|
@@ -142,8 +163,8 @@ const getScripts = (options) => {
|
|
142
163
|
},
|
143
164
|
generateAPI: {
|
144
165
|
default: tsOption ? "nps generateAPI.generateCEM generateAPI.validateCEM" : "",
|
145
|
-
generateCEM:
|
146
|
-
validateCEM:
|
166
|
+
generateCEM: `${options.dev ? "cross-env UI5_CEM_MODE='dev'" : ""} cem analyze --config "${LIB}/cem/custom-elements-manifest.config.mjs"`,
|
167
|
+
validateCEM: `${options.dev ? "cross-env UI5_CEM_MODE='dev'" : ""} node "${LIB}/cem/validate.js"`,
|
147
168
|
},
|
148
169
|
};
|
149
170
|
|
@@ -1,13 +1,9 @@
|
|
1
1
|
// vite.config.js
|
2
|
-
|
3
|
-
import virtualIndex from '../lib/dev-server/virtual-index-html-plugin.js';
|
2
|
+
const virtualIndex = require('../lib/dev-server/virtual-index-html-plugin.js');
|
4
3
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
plugins: [data],
|
12
|
-
}
|
13
|
-
})
|
4
|
+
module.exports = {
|
5
|
+
build: {
|
6
|
+
emptyOutDir: false,
|
7
|
+
},
|
8
|
+
plugins: [virtualIndex()],
|
9
|
+
};
|
@@ -60,7 +60,7 @@ exports.config = {
|
|
60
60
|
// to run chrome headless the following flags are required
|
61
61
|
// (see https://developers.google.com/web/updates/2017/04/headless-chrome)
|
62
62
|
args: [
|
63
|
-
'--headless
|
63
|
+
'--headless',
|
64
64
|
'--disable-search-engine-choice-screen',
|
65
65
|
'--start-maximized',
|
66
66
|
'--no-sandbox',
|
@@ -27,6 +27,7 @@ import { generateCustomData } from "cem-plugin-vs-code-custom-data-generator";
|
|
27
27
|
import { customElementJetBrainsPlugin } from "custom-element-jet-brains-integration";
|
28
28
|
|
29
29
|
const packageJSON = JSON.parse(fs.readFileSync("./package.json"));
|
30
|
+
const devMode = process.env.UI5_CEM_MODE === "dev";
|
30
31
|
|
31
32
|
const extractClassNodeJSDoc = node => {
|
32
33
|
const fileContent = node.getFullText();
|
@@ -127,7 +128,7 @@ function processClass(ts, classNode, moduleDoc) {
|
|
127
128
|
}
|
128
129
|
|
129
130
|
// Events
|
130
|
-
currClass.events = findAllDecorators(classNode, "event")
|
131
|
+
currClass.events = findAllDecorators(classNode, ["event", "eventStrict"])
|
131
132
|
?.map(event => processEvent(ts, event, classNode, moduleDoc));
|
132
133
|
|
133
134
|
const filename = classNode.getSourceFile().fileName;
|
@@ -451,14 +452,6 @@ export default {
|
|
451
452
|
}
|
452
453
|
},
|
453
454
|
moduleLinkPhase({ moduleDoc }) {
|
454
|
-
for (let i = 0; i < moduleDoc.declarations.length; i++) {
|
455
|
-
const shouldRemove = processPublicAPI(moduleDoc.declarations[i]) || ["function", "variable"].includes(moduleDoc.declarations[i].kind)
|
456
|
-
if (shouldRemove) {
|
457
|
-
moduleDoc.declarations.splice(i, 1);
|
458
|
-
i--;
|
459
|
-
}
|
460
|
-
}
|
461
|
-
|
462
455
|
moduleDoc.path = moduleDoc.path?.replace(/^src/, "dist").replace(/\.ts$/, ".js");
|
463
456
|
|
464
457
|
moduleDoc.exports = moduleDoc.exports.
|
@@ -482,41 +475,51 @@ export default {
|
|
482
475
|
})
|
483
476
|
}
|
484
477
|
})
|
478
|
+
},
|
479
|
+
packageLinkPhase({ customElementsManifest }) {
|
480
|
+
customElementsManifest.modules.forEach(moduleDoc => {
|
481
|
+
for (let i = 0; i < moduleDoc.declarations.length; i++) {
|
482
|
+
const shouldRemove = processPublicAPI(moduleDoc.declarations[i]) || ["function", "variable"].includes(moduleDoc.declarations[i].kind)
|
483
|
+
if (shouldRemove) {
|
484
|
+
moduleDoc.declarations.splice(i, 1);
|
485
|
+
i--;
|
486
|
+
}
|
487
|
+
}
|
485
488
|
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
489
|
+
const typeReferences = new Set();
|
490
|
+
const registerTypeReference = reference => typeReferences.add(JSON.stringify(reference))
|
491
|
+
|
492
|
+
moduleDoc.declarations.forEach(declaration => {
|
493
|
+
["events", "slots", "members"].forEach(memberType => {
|
494
|
+
declaration[memberType]?.forEach(member => {
|
495
|
+
if (member.type?.references) {
|
496
|
+
member.type.references.forEach(registerTypeReference)
|
497
|
+
} else if (member._ui5type?.references) {
|
498
|
+
member._ui5type.references.forEach(registerTypeReference)
|
499
|
+
} else if (member.kind === "method") {
|
500
|
+
member.return?.type?.references?.forEach(registerTypeReference)
|
501
|
+
|
502
|
+
member.parameters?.forEach(parameter => {
|
503
|
+
parameter.type?.references?.forEach(registerTypeReference)
|
504
|
+
})
|
505
|
+
}
|
506
|
+
})
|
503
507
|
})
|
504
|
-
})
|
505
|
-
});
|
508
|
+
});
|
506
509
|
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
510
|
+
typeReferences.forEach(reference => {
|
511
|
+
reference = JSON.parse(reference);
|
512
|
+
if (reference.package === packageJSON?.name && reference.module === moduleDoc.path) {
|
513
|
+
const hasExport = moduleDoc.exports.some(e => e.declaration?.name === reference.name && e.declaration?.module === reference.module)
|
511
514
|
|
512
|
-
|
513
|
-
|
515
|
+
if (!hasExport) {
|
516
|
+
logDocumentationError(moduleDoc.path?.replace(/^dist/, "src").replace(/\.js$/, ".ts"), `Type '${reference.name}' is used to describe a public API but is not exported.`,)
|
517
|
+
}
|
514
518
|
}
|
515
|
-
}
|
516
|
-
})
|
517
|
-
|
518
|
-
|
519
|
-
if (context.dev) {
|
519
|
+
})
|
520
|
+
});
|
521
|
+
|
522
|
+
if (devMode) {
|
520
523
|
displayDocumentationErrors();
|
521
524
|
}
|
522
525
|
}
|
@@ -407,6 +407,9 @@
|
|
407
407
|
"CssCustomProperty": {
|
408
408
|
"additionalProperties": false,
|
409
409
|
"properties": {
|
410
|
+
"inheritedFrom": {
|
411
|
+
"$ref": "#/definitions/Reference"
|
412
|
+
},
|
410
413
|
"default": {
|
411
414
|
"type": "string"
|
412
415
|
},
|
@@ -443,6 +446,9 @@
|
|
443
446
|
"additionalProperties": false,
|
444
447
|
"description": "The description of a CSS Part",
|
445
448
|
"properties": {
|
449
|
+
"inheritedFrom": {
|
450
|
+
"$ref": "#/definitions/Reference"
|
451
|
+
},
|
446
452
|
"deprecated": {
|
447
453
|
"description": "Whether the CSS shadow part is deprecated.\nIf the value is a string, it's the reason for the deprecation.",
|
448
454
|
"type": [
|
@@ -1222,6 +1228,9 @@
|
|
1222
1228
|
"Slot": {
|
1223
1229
|
"additionalProperties": false,
|
1224
1230
|
"properties": {
|
1231
|
+
"inheritedFrom": {
|
1232
|
+
"$ref": "#/definitions/Reference"
|
1233
|
+
},
|
1225
1234
|
"_ui5propertyName": {
|
1226
1235
|
"type": "string"
|
1227
1236
|
},
|
package/lib/cem/utils.mjs
CHANGED
@@ -241,7 +241,7 @@ const allowedTags = {
|
|
241
241
|
eventParam: [...commonTags],
|
242
242
|
method: [...commonTags, "param", "returns", "override"],
|
243
243
|
class: [...commonTags, "constructor", "class", "abstract", "experimental", "implements", "extends", "slot", "csspart"],
|
244
|
-
enum: [...commonTags],
|
244
|
+
enum: [...commonTags, "experimental",],
|
245
245
|
enumMember: [...commonTags, "experimental",],
|
246
246
|
interface: [...commonTags, "experimental",],
|
247
247
|
};
|
@@ -256,19 +256,29 @@ const tagMatchCallback = (tag, tagName) => {
|
|
256
256
|
};
|
257
257
|
|
258
258
|
const findDecorator = (node, decoratorName) => {
|
259
|
-
return node?.decorators?.find(
|
259
|
+
return (node?.modifiers || node?.decorators)?.find(
|
260
260
|
(decorator) =>
|
261
261
|
decorator?.expression?.expression?.text === decoratorName
|
262
262
|
);
|
263
263
|
};
|
264
264
|
|
265
265
|
const findAllDecorators = (node, decoratorName) => {
|
266
|
-
|
267
|
-
node?.decorators?.filter(
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
266
|
+
if (typeof decoratorName === "string") {
|
267
|
+
return (node?.modifiers || node?.decorators)?.filter(decorator => decorator?.expression?.expression?.text === decoratorName) || [];
|
268
|
+
}
|
269
|
+
|
270
|
+
if (Array.isArray(decoratorName)) {
|
271
|
+
return (node?.modifiers || node?.decorators)?.filter(decorator => {
|
272
|
+
if (decorator?.expression?.expression?.text) {
|
273
|
+
return decoratorName.includes(decorator.expression.expression.text);
|
274
|
+
}
|
275
|
+
|
276
|
+
return false;
|
277
|
+
}
|
278
|
+
) || [];
|
279
|
+
}
|
280
|
+
|
281
|
+
return [];
|
272
282
|
};
|
273
283
|
|
274
284
|
const hasTag = (jsDoc, tagName) => {
|
package/lib/cem/validate.js
CHANGED
@@ -1,11 +1,6 @@
|
|
1
1
|
const fs = require('fs');
|
2
2
|
const Ajv = require('ajv');
|
3
3
|
const path = require('path');
|
4
|
-
const yargs = require('yargs/yargs')
|
5
|
-
const { hideBin } = require('yargs/helpers')
|
6
|
-
const argv = yargs(hideBin(process.argv))
|
7
|
-
.argv;
|
8
|
-
|
9
4
|
// Load your JSON schema
|
10
5
|
const extenalSchema = require('./schema.json');
|
11
6
|
const internalSchema = require('./schema-internal.json');
|
@@ -14,47 +9,49 @@ const internalSchema = require('./schema-internal.json');
|
|
14
9
|
const inputFilePath = path.join(process.cwd(), "dist/custom-elements.json"); // Update with your file path
|
15
10
|
const customManifest = fs.readFileSync(inputFilePath, 'utf8');
|
16
11
|
const inputDataInternal = JSON.parse(customManifest);
|
12
|
+
const devMode = process.env.UI5_CEM_MODE === "dev";
|
17
13
|
|
18
14
|
inputDataInternal.modules.forEach(moduleDoc => {
|
19
|
-
|
20
|
-
|
15
|
+
moduleDoc.exports = moduleDoc.exports.
|
16
|
+
filter(e => moduleDoc.declarations.find(d => d.name === e.declaration.name && ["class", "function", "variable", "enum"].includes(d.kind)) || e.name === "default");
|
21
17
|
})
|
22
18
|
|
23
19
|
const clearProps = (data) => {
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
20
|
+
if (Array.isArray(data)) {
|
21
|
+
for (let i = 0; i < data.length; i++) {
|
22
|
+
if (typeof data[i] === "object") {
|
23
|
+
if (["enum", "interface"].includes(data[i].kind)) {
|
24
|
+
data.splice(i, 1);
|
25
|
+
i--;
|
26
|
+
} else {
|
27
|
+
clearProps(data[i]);
|
28
|
+
}
|
29
|
+
}
|
30
|
+
}
|
31
|
+
} else if (typeof data === "object") {
|
32
|
+
Object.keys(data).forEach(prop => {
|
33
|
+
if (prop.startsWith("_ui5")) {
|
34
|
+
delete data[prop];
|
35
|
+
} else if (typeof data[prop] === "object") {
|
36
|
+
clearProps(data[prop]);
|
37
|
+
}
|
38
|
+
});
|
39
|
+
}
|
44
40
|
|
45
|
-
|
41
|
+
return data;
|
46
42
|
}
|
47
43
|
|
48
44
|
const ajv = new Ajv({ allowUnionTypes: true, allError: true })
|
49
45
|
let validate = ajv.compile(internalSchema)
|
50
46
|
|
51
47
|
// Validate the JSON data against the schema
|
52
|
-
if (
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
48
|
+
if (devMode) {
|
49
|
+
if (validate(inputDataInternal)) {
|
50
|
+
console.log('Internal custom element manifest is validated successfully');
|
51
|
+
} else {
|
52
|
+
console.log(validate.errors)
|
53
|
+
throw new Error(`Validation of internal custom elements manifest failed: ${validate.errors}`);
|
54
|
+
}
|
58
55
|
}
|
59
56
|
|
60
57
|
const inputDataExternal = clearProps(JSON.parse(JSON.stringify(inputDataInternal)));
|
@@ -62,9 +59,9 @@ validate = ajv.compile(extenalSchema)
|
|
62
59
|
|
63
60
|
// Validate the JSON data against the schema
|
64
61
|
if (validate(inputDataExternal)) {
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
} else if (
|
69
|
-
|
70
|
-
|
62
|
+
console.log('Custom element manifest is validated successfully');
|
63
|
+
fs.writeFileSync(inputFilePath, JSON.stringify(inputDataExternal, null, 2), 'utf8');
|
64
|
+
fs.writeFileSync(inputFilePath.replace("custom-elements", "custom-elements-internal"), JSON.stringify(inputDataInternal, null, 2), 'utf8');
|
65
|
+
} else if (devMode) {
|
66
|
+
throw new Error(`Validation of public custom elements manifest failed: ${validate.errors}`);
|
67
|
+
}
|
@@ -21,8 +21,8 @@ export default "${collection}/${name}";
|
|
21
21
|
export { pathData, ltr, accData };`;
|
22
22
|
|
23
23
|
|
24
|
-
const iconAccTemplate = (name, pathData, ltr, accData, collection, packageName) => `import { registerIcon } from "@ui5/webcomponents-base/dist/asset-registries/Icons.js";
|
25
|
-
import { ${accData.key} } from "../generated/i18n/i18n-defaults.js";
|
24
|
+
const iconAccTemplate = (name, pathData, ltr, accData, collection, packageName, versioned) => `import { registerIcon } from "@ui5/webcomponents-base/dist/asset-registries/Icons.js";
|
25
|
+
import { ${accData.key} } from "${versioned ? "../" : "./"}generated/i18n/i18n-defaults.js";
|
26
26
|
|
27
27
|
const name = "${name}";
|
28
28
|
const pathData = "${pathData}";
|
@@ -84,8 +84,9 @@ const createIcons = async (file) => {
|
|
84
84
|
const acc = iconData.acc;
|
85
85
|
const packageName = json.packageName;
|
86
86
|
const collection = json.collection;
|
87
|
+
const versioned = json.version;
|
87
88
|
|
88
|
-
const content = acc ? iconAccTemplate(name, pathData, ltr, acc, collection, packageName) : iconTemplate(name, pathData, ltr, collection, packageName);
|
89
|
+
const content = acc ? iconAccTemplate(name, pathData, ltr, acc, collection, packageName, versioned) : iconTemplate(name, pathData, ltr, collection, packageName);
|
89
90
|
|
90
91
|
promises.push(fs.writeFile(path.join(destDir, `${name}.js`), content));
|
91
92
|
promises.push(fs.writeFile(path.join(destDir, `${name}.svg`), svgTemplate(pathData)));
|
@@ -96,7 +97,7 @@ const createIcons = async (file) => {
|
|
96
97
|
// - "@ui5/ui5-webcomponents-icons/dist/v5/accept.js"
|
97
98
|
// - "@ui5/ui5-webcomponents-icons/dist/v4/accept.js"
|
98
99
|
|
99
|
-
if (
|
100
|
+
if (versioned) {
|
100
101
|
// The exported value from the top level (unversioned) icon module depends on whether the collection is the default,
|
101
102
|
// to add or not the collection name to the exported value:
|
102
103
|
// For the default collection (SAPIcons) we export just the icon name - "export default { 'accept' }"
|
@@ -1,12 +1,12 @@
|
|
1
|
-
const
|
1
|
+
const Component = (componentName, tagName, library, packageName) => {
|
2
2
|
return `import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js";
|
3
3
|
import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js";
|
4
4
|
import property from "@ui5/webcomponents-base/dist/decorators/property.js";
|
5
5
|
import slot from "@ui5/webcomponents-base/dist/decorators/slot.js";
|
6
|
-
import event from "@ui5/webcomponents-base/dist/decorators/event.js";
|
7
|
-
import
|
6
|
+
import event from "@ui5/webcomponents-base/dist/decorators/event-strict.js";
|
7
|
+
import jsxRenderer from "@ui5/webcomponents-base/dist/renderer/JsxRenderer.js";
|
8
8
|
|
9
|
-
import ${componentName}Template from "
|
9
|
+
import ${componentName}Template from "./${componentName}Template.js";
|
10
10
|
|
11
11
|
// Styles
|
12
12
|
import ${componentName}Css from "./generated/themes/${componentName}.css.js";
|
@@ -30,10 +30,9 @@ import ${componentName}Css from "./generated/themes/${componentName}.css.js";
|
|
30
30
|
*/
|
31
31
|
@customElement({
|
32
32
|
tag: "${tagName}",
|
33
|
-
renderer:
|
33
|
+
renderer: jsxRenderer,
|
34
34
|
styles: ${componentName}Css,
|
35
35
|
template: ${componentName}Template,
|
36
|
-
dependencies: [],
|
37
36
|
})
|
38
37
|
|
39
38
|
/**
|
@@ -42,8 +41,12 @@ import ${componentName}Css from "./generated/themes/${componentName}.css.js";
|
|
42
41
|
*
|
43
42
|
* @public
|
44
43
|
*/
|
45
|
-
@event("interact"
|
44
|
+
@event("interact")
|
46
45
|
class ${componentName} extends UI5Element {
|
46
|
+
eventDetails!: {
|
47
|
+
"interact": void,
|
48
|
+
};
|
49
|
+
|
47
50
|
/**
|
48
51
|
* Defines the value of the component.
|
49
52
|
*
|
@@ -68,4 +71,4 @@ export default ${componentName};
|
|
68
71
|
`;
|
69
72
|
};
|
70
73
|
|
71
|
-
module.exports =
|
74
|
+
module.exports = Component;
|
@@ -0,0 +1,12 @@
|
|
1
|
+
const ComponentTemplate = (componentName) => {
|
2
|
+
return `import type ${componentName} from "./${componentName}.js";
|
3
|
+
|
4
|
+
export default function ${componentName}Template(this: ${componentName}) {
|
5
|
+
return (
|
6
|
+
<div>Hello World!</div>
|
7
|
+
);
|
8
|
+
}
|
9
|
+
`;
|
10
|
+
};
|
11
|
+
|
12
|
+
module.exports = ComponentTemplate;
|
@@ -1,16 +1,17 @@
|
|
1
1
|
const fs = require("fs");
|
2
2
|
const prompts = require("prompts");
|
3
|
-
const
|
3
|
+
const Component = require("./Component.js");
|
4
|
+
const ComponentTemplate= require("./ComponentTemplate.js");
|
4
5
|
|
5
6
|
/**
|
6
|
-
* Hyphanates the given PascalCase string, f.e.:
|
7
|
-
* Foo -> "my-foo"
|
8
|
-
* FooBar -> "foo-bar"
|
7
|
+
* Hyphanates the given PascalCase string and adds prefix, f.e.:
|
8
|
+
* Foo -> "my-foo"
|
9
|
+
* FooBar -> "my-foo-bar"
|
9
10
|
*/
|
10
11
|
const hyphaneteComponentName = (componentName) => {
|
11
12
|
const result = componentName.replace(/([a-z])([A-Z])/g, '$1-$2' ).toLowerCase();
|
12
13
|
|
13
|
-
return
|
14
|
+
return `my-${result}`;
|
14
15
|
};
|
15
16
|
|
16
17
|
/**
|
@@ -61,12 +62,12 @@ const generateFiles = (componentName, tagName, library, packageName) => {
|
|
61
62
|
const filePaths = {
|
62
63
|
"main": `./src/${componentName}.ts`,
|
63
64
|
"css": `./src/themes/${componentName}.css`,
|
64
|
-
"template": `./src/${componentName}.
|
65
|
+
"template": `./src/${componentName}Template.tsx`,
|
65
66
|
};
|
66
67
|
|
67
|
-
fs.writeFileSync(filePaths.main,
|
68
|
+
fs.writeFileSync(filePaths.main, Component(componentName, tagName, library, packageName), { flag: "wx+" });
|
68
69
|
fs.writeFileSync(filePaths.css, "", { flag: "wx+" });
|
69
|
-
fs.writeFileSync(filePaths.template,
|
70
|
+
fs.writeFileSync(filePaths.template, ComponentTemplate(componentName), { flag: "wx+" });
|
70
71
|
|
71
72
|
console.log(`Successfully generated ${filePaths.main}`);
|
72
73
|
console.log(`Successfully generated ${filePaths.css}`);
|
@@ -74,8 +75,8 @@ const generateFiles = (componentName, tagName, library, packageName) => {
|
|
74
75
|
|
75
76
|
// Change the color of the output
|
76
77
|
console.warn('\x1b[33m%s\x1b[0m', `
|
77
|
-
|
78
|
-
|
78
|
+
Now, import the component in src/bundle.esm.ts via: "import ${componentName} from ./${componentName}.js";
|
79
|
+
And, add it to your HTML: <${tagName}></${tagName}>.`);
|
79
80
|
}
|
80
81
|
|
81
82
|
// Main function
|
@@ -22,7 +22,8 @@ let customPlugin = {
|
|
22
22
|
build.onEnd(result => {
|
23
23
|
result.outputFiles.forEach(async f => {
|
24
24
|
// scoping
|
25
|
-
|
25
|
+
let newText = scopeVariables(f.text, packageJSON);
|
26
|
+
newText = newText.replaceAll(/\\/g, "\\\\"); // Escape backslashes as they might appear in css rules
|
26
27
|
await mkdir(path.dirname(f.path), {recursive: true});
|
27
28
|
writeFile(f.path, newText);
|
28
29
|
|
@@ -1,23 +1,17 @@
|
|
1
|
-
const virtualIndexPlugin =
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
let folder = pagesPerFolder[path.dirname(file)] = pagesPerFolder[path.dirname(file)] || [];
|
9
|
-
folder.push(path.basename(file));
|
10
|
-
});
|
1
|
+
const virtualIndexPlugin = () => {
|
2
|
+
return {
|
3
|
+
name: 'virtual-index-html',
|
4
|
+
async config() {
|
5
|
+
const path = (await import("path")).default;
|
6
|
+
const globby = (await import("globby")).globby;
|
7
|
+
const files = await globby(["test/pages/**/*.html", "packages/*/test/pages/**/*.html"]);
|
11
8
|
|
12
|
-
|
9
|
+
const rollupInput = {};
|
13
10
|
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
files.forEach(file => {
|
12
|
+
rollupInput[file] = path.resolve(process.cwd(), file);
|
13
|
+
});
|
17
14
|
|
18
|
-
return {
|
19
|
-
name: 'virtual-index-html',
|
20
|
-
config() {
|
21
15
|
return {
|
22
16
|
build: {
|
23
17
|
rollupOptions: {
|
@@ -26,7 +20,17 @@ const virtualIndexPlugin = async () => {
|
|
26
20
|
}
|
27
21
|
}
|
28
22
|
},
|
29
|
-
configureServer(server) {
|
23
|
+
async configureServer(server) {
|
24
|
+
const path = (await import("path")).default;
|
25
|
+
const globby = (await import("globby")).globby;
|
26
|
+
const files = await globby(["test/pages/**/*.html", "packages/*/test/pages/**/*.html"]);
|
27
|
+
|
28
|
+
const pagesPerFolder = {};
|
29
|
+
files.forEach(file => {
|
30
|
+
let folder = pagesPerFolder[path.dirname(file)] = pagesPerFolder[path.dirname(file)] || [];
|
31
|
+
folder.push(path.basename(file));
|
32
|
+
});
|
33
|
+
|
30
34
|
server.middlewares.use((req, res, next) => {
|
31
35
|
if (req.url === "/") {
|
32
36
|
const folders = Object.keys(pagesPerFolder);
|
@@ -37,8 +41,8 @@ const virtualIndexPlugin = async () => {
|
|
37
41
|
const pages = pagesPerFolder[folder];
|
38
42
|
return `<h1>${folder}</h1>
|
39
43
|
${pages.map(page => {
|
40
|
-
|
41
|
-
|
44
|
+
return `<li><a href='${folder}/${page}'>${page}</a></li>`
|
45
|
+
}).join("")}
|
42
46
|
`
|
43
47
|
}).join("")}`);
|
44
48
|
} else {
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@ui5/webcomponents-tools",
|
3
|
-
"version": "0.0.0-
|
3
|
+
"version": "0.0.0-50f1454ef",
|
4
4
|
"description": "UI5 Web Components: webcomponents.tools",
|
5
5
|
"author": "SAP SE (https://www.sap.com)",
|
6
6
|
"license": "Apache-2.0",
|
@@ -10,7 +10,6 @@
|
|
10
10
|
"sapui5",
|
11
11
|
"ui5"
|
12
12
|
],
|
13
|
-
"types": "./types/index.d.ts",
|
14
13
|
"scripts": {},
|
15
14
|
"bin": {
|
16
15
|
"wc-dev": "bin/dev.js",
|
@@ -22,7 +21,7 @@
|
|
22
21
|
"directory": "packages/tools"
|
23
22
|
},
|
24
23
|
"dependencies": {
|
25
|
-
"@custom-elements-manifest/analyzer": "^0.
|
24
|
+
"@custom-elements-manifest/analyzer": "^0.10.4",
|
26
25
|
"@typescript-eslint/eslint-plugin": "^6.9.0",
|
27
26
|
"@typescript-eslint/parser": "^6.9.0",
|
28
27
|
"@wdio/cli": "^7.19.7",
|
@@ -42,13 +41,11 @@
|
|
42
41
|
"concurrently": "^6.0.0",
|
43
42
|
"cross-env": "^7.0.3",
|
44
43
|
"custom-element-jet-brains-integration": "^1.4.4",
|
45
|
-
"cypress": "^13.11.0",
|
46
|
-
"cypress-real-events": "^1.12.0",
|
47
44
|
"escodegen": "^2.0.0",
|
48
45
|
"eslint": "^7.22.0",
|
49
46
|
"eslint-config-airbnb-base": "^14.2.1",
|
50
|
-
"eslint-plugin-cypress": "^3.4.0",
|
51
47
|
"eslint-plugin-import": "^2.31.0",
|
48
|
+
"eslint-plugin-jsx-no-leaked-values": "^0.1.24",
|
52
49
|
"esprima": "^4.0.1",
|
53
50
|
"getopts": "^2.3.0",
|
54
51
|
"glob": "^7.1.6",
|
@@ -69,6 +66,7 @@
|
|
69
66
|
"rimraf": "^3.0.2",
|
70
67
|
"slash": "3.0.0",
|
71
68
|
"vite": "^5.4.8",
|
69
|
+
"vite-plugin-istanbul": "^6.0.2",
|
72
70
|
"wdio-chromedriver-service": "^7.3.2"
|
73
71
|
},
|
74
72
|
"peerDependencies": {
|
@@ -81,9 +79,7 @@
|
|
81
79
|
}
|
82
80
|
},
|
83
81
|
"devDependencies": {
|
84
|
-
"
|
85
|
-
"cypress-real-events": "^1.12.0",
|
86
|
-
"esbuild": "^0.19.9",
|
82
|
+
"esbuild": "^0.25.0",
|
87
83
|
"yargs": "^17.5.1"
|
88
84
|
}
|
89
85
|
}
|
@@ -1,39 +0,0 @@
|
|
1
|
-
/// <reference types="cypress" />
|
2
|
-
// ***********************************************
|
3
|
-
// This example commands.ts shows you how to
|
4
|
-
// create various custom commands and overwrite
|
5
|
-
// existing commands.
|
6
|
-
//
|
7
|
-
// For more comprehensive examples of custom
|
8
|
-
// commands please read more here:
|
9
|
-
// https://on.cypress.io/custom-commands
|
10
|
-
// ***********************************************
|
11
|
-
//
|
12
|
-
//
|
13
|
-
// -- This is a parent command --
|
14
|
-
// Cypress.Commands.add('login', (email, password) => { ... })
|
15
|
-
//
|
16
|
-
//
|
17
|
-
// -- This is a child command --
|
18
|
-
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
|
19
|
-
//
|
20
|
-
//
|
21
|
-
// -- This is a dual command --
|
22
|
-
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
|
23
|
-
//
|
24
|
-
//
|
25
|
-
// -- This will overwrite an existing command --
|
26
|
-
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
|
27
|
-
//
|
28
|
-
// declare global {
|
29
|
-
// namespace Cypress {
|
30
|
-
// interface Chainable {
|
31
|
-
// login(email: string, password: string): Chainable<void>
|
32
|
-
// drag(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
|
33
|
-
// dismiss(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
|
34
|
-
// visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
|
35
|
-
// }
|
36
|
-
// }
|
37
|
-
// }
|
38
|
-
|
39
|
-
import "cypress-real-events";
|
@@ -1,17 +0,0 @@
|
|
1
|
-
<!DOCTYPE html>
|
2
|
-
<html>
|
3
|
-
|
4
|
-
<head>
|
5
|
-
<meta charset="utf-8">
|
6
|
-
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
7
|
-
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
8
|
-
<meta name="sap-allowedThemeOrigins" content="https://example.com">
|
9
|
-
<title>Components App</title>
|
10
|
-
<script data-ui5-config type="application/json">{}</script>
|
11
|
-
</head>
|
12
|
-
|
13
|
-
<body>
|
14
|
-
<div data-cy-root></div>
|
15
|
-
</body>
|
16
|
-
|
17
|
-
</html>
|
@@ -1,23 +0,0 @@
|
|
1
|
-
/// <reference types="cypress" />
|
2
|
-
import { RenderOptions, HTMLTemplateResult } from 'lit';
|
3
|
-
import "cypress-real-events";
|
4
|
-
|
5
|
-
export type Renderable = HTMLTemplateResult;
|
6
|
-
export interface MountUI5Options extends MountLitTemplateOptions {
|
7
|
-
ui5Configuration: object;
|
8
|
-
}
|
9
|
-
export type MountOptions = Partial<MountUI5Options>;
|
10
|
-
export declare function mount<T extends keyof HTMLElementTagNameMap = any>(component: string | Renderable, options?: MountOptions): Cypress.Chainable<JQuery<HTMLElementTagNameMap[T]>>;
|
11
|
-
declare global {
|
12
|
-
namespace Cypress {
|
13
|
-
interface Chainable {
|
14
|
-
/**
|
15
|
-
* Mount your component into Cypress sandbox
|
16
|
-
* @param component content to render by lit-html render function
|
17
|
-
* @param options render options for custom rendering
|
18
|
-
*/
|
19
|
-
mount: typeof mount;
|
20
|
-
}
|
21
|
-
}
|
22
|
-
}
|
23
|
-
|
@@ -1,34 +0,0 @@
|
|
1
|
-
import { setupHooks } from '@cypress/mount-utils';
|
2
|
-
import { unsafeHTML } from 'lit-html/directives/unsafe-html.js';
|
3
|
-
import { mount } from 'cypress-ct-lit'
|
4
|
-
import "./commands.js";
|
5
|
-
|
6
|
-
let dispose;
|
7
|
-
|
8
|
-
function cleanup() {
|
9
|
-
dispose?.();
|
10
|
-
}
|
11
|
-
|
12
|
-
function ui5Mount(component, options = {}) {
|
13
|
-
const configurationScript = document.head.querySelector("script[data-ui5-config]")
|
14
|
-
cleanup();
|
15
|
-
|
16
|
-
if (options.ui5Configuration) {
|
17
|
-
configurationScript.innerHTML = JSON.stringify(options.ui5Configuration);
|
18
|
-
|
19
|
-
}
|
20
|
-
|
21
|
-
dispose = () => {
|
22
|
-
configurationScript.innerHTML = "{}";
|
23
|
-
}
|
24
|
-
|
25
|
-
if (typeof component === "string") {
|
26
|
-
return mount(unsafeHTML(component), options)
|
27
|
-
}
|
28
|
-
|
29
|
-
return mount(component, options)
|
30
|
-
}
|
31
|
-
|
32
|
-
setupHooks(cleanup);
|
33
|
-
|
34
|
-
Cypress.Commands.add('mount', ui5Mount)
|
@@ -1,19 +0,0 @@
|
|
1
|
-
const { defineConfig } = require('cypress')
|
2
|
-
const path = require("path");
|
3
|
-
|
4
|
-
module.exports = defineConfig({
|
5
|
-
component: {
|
6
|
-
supportFile: path.join(__dirname, "cypress/support/component.js"),
|
7
|
-
indexHtmlFile: path.join(__dirname, "cypress/support/component-index.html"),
|
8
|
-
specPattern: ["**/specs/*.cy.{js,ts}", "**/specs/**/*.cy.{js,ts}"],
|
9
|
-
devServer: {
|
10
|
-
framework: 'cypress-ct-lit',
|
11
|
-
bundler: 'vite',
|
12
|
-
}
|
13
|
-
},
|
14
|
-
video: false,
|
15
|
-
screenshotOnRunFailure: false,
|
16
|
-
scrollBehavior: false,
|
17
|
-
viewportHeight: 1080,
|
18
|
-
viewportWidth: 1440,
|
19
|
-
})
|
package/types/index.d.ts
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
import "../components-package/cypress/support/component"
|