babel-plugin-transform-modules-ui5 7.4.1 → 7.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
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
|
+
# [7.5.0](https://github.com/ui5-community/babel-plugin-transform-modules-ui5/compare/v7.4.2...v7.5.0) (2024-07-12)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* support ControllerExtensions extended with .override(...) ([#128](https://github.com/ui5-community/babel-plugin-transform-modules-ui5/issues/128)) ([f744d9d](https://github.com/ui5-community/babel-plugin-transform-modules-ui5/commit/f744d9db3dd82020712b47a18ce55ed51a13fe89))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
## [7.4.2](https://github.com/ui5-community/babel-plugin-transform-modules-ui5/compare/v7.4.1...v7.4.2) (2024-06-25)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Bug Fixes
|
|
21
|
+
|
|
22
|
+
* remove mandatory ESM file extensions from sap.ui.define imports ([#129](https://github.com/ui5-community/babel-plugin-transform-modules-ui5/issues/129)) ([571dfa1](https://github.com/ui5-community/babel-plugin-transform-modules-ui5/commit/571dfa192984c9838c573909546b42a85b71e5b6))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
6
28
|
## [7.4.1](https://github.com/ui5-community/babel-plugin-transform-modules-ui5/compare/v7.4.0...v7.4.1) (2024-06-02)
|
|
7
29
|
|
|
8
30
|
|
|
@@ -121,6 +121,7 @@ function convertClassToUI5Extend(path, node, classInfo, extraStaticProps, import
|
|
|
121
121
|
const typeAnnotation = (_member$typeAnnotatio = member.typeAnnotation) === null || _member$typeAnnotatio === void 0 ? void 0 : _member$typeAnnotatio.typeAnnotation;
|
|
122
122
|
// double-check that it is a valid node for a controller extension
|
|
123
123
|
if (_core.types.isTSTypeReference(typeAnnotation) || _core.types.isTSQualifiedName(typeAnnotation)) {
|
|
124
|
+
var _memberPath$hub;
|
|
124
125
|
const typeName = getTypeName(typeAnnotation);
|
|
125
126
|
|
|
126
127
|
// 1. transform the property from being typed as instance and un-initialized to a property where the controller extension *class* is assigned as value
|
|
@@ -137,7 +138,7 @@ function convertClassToUI5Extend(path, node, classInfo, extraStaticProps, import
|
|
|
137
138
|
}
|
|
138
139
|
|
|
139
140
|
// 3. restore the import in case it was run already and removed the import
|
|
140
|
-
const neededImportDeclaration = (0, _imports.getImportDeclaration)(memberPath.hub.file.opts.filename, typeName);
|
|
141
|
+
const neededImportDeclaration = (0, _imports.getImportDeclaration)(memberPath === null || memberPath === void 0 || (_memberPath$hub = memberPath.hub) === null || _memberPath$hub === void 0 || (_memberPath$hub = _memberPath$hub.file) === null || _memberPath$hub === void 0 || (_memberPath$hub = _memberPath$hub.opts) === null || _memberPath$hub === void 0 ? void 0 : _memberPath$hub.filename, typeName);
|
|
141
142
|
if (!importDeclarationPaths.some(path => path.node === neededImportDeclaration)) {
|
|
142
143
|
// TODO: import might be there but with the specifier removed; we can clone, but then other specifiers are duplicate
|
|
143
144
|
// if import is no longer there, re-add it
|
|
@@ -150,6 +151,36 @@ function convertClassToUI5Extend(path, node, classInfo, extraStaticProps, import
|
|
|
150
151
|
}
|
|
151
152
|
if (!member.value) continue; // remove all other un-initialized static class props (typescript)
|
|
152
153
|
|
|
154
|
+
// Now handle the case where an extended controller extension - not just e.g. "Routing", but
|
|
155
|
+
// "Routing.override({...})" - is assigned to the class property. To make this work in TypeScript code
|
|
156
|
+
// (Routing.override({...}) returns a class, but the "routing" member property needs to be typed as an instance),
|
|
157
|
+
// we require the following notation, using a dummy function ControllerExtension.use() that does actually
|
|
158
|
+
// not exist at runtime, but does the required class-to-instance conversion from TypeScript perspective:
|
|
159
|
+
// routing: ControllerExtension.use(Routing.override({...}))
|
|
160
|
+
// In this case, the code in the "if" clause above was not executed, regardless of the presence of the
|
|
161
|
+
// @transformControllerExtension marker, because it is not a type assignment. In the resulting code, the
|
|
162
|
+
// "ControllerExtension.use(...)" part should be removed and the content of the brackets should be assigned
|
|
163
|
+
// directly to the member property.
|
|
164
|
+
if (_core.types.isCallExpression(member.value)) {
|
|
165
|
+
const callee = member.value.callee;
|
|
166
|
+
if (_core.types.isMemberExpression(callee) && _core.types.isIdentifier(callee.object) && _core.types.isIdentifier(callee.property) && callee.property.name === "use" // we are looking for "ControllerExtension.use(...)"
|
|
167
|
+
) {
|
|
168
|
+
var _memberPath$hub2, _callee$object, _importDeclaration$so;
|
|
169
|
+
const importDeclaration = (0, _imports.getImportDeclaration)(memberPath === null || memberPath === void 0 || (_memberPath$hub2 = memberPath.hub) === null || _memberPath$hub2 === void 0 || (_memberPath$hub2 = _memberPath$hub2.file) === null || _memberPath$hub2 === void 0 || (_memberPath$hub2 = _memberPath$hub2.opts) === null || _memberPath$hub2 === void 0 ? void 0 : _memberPath$hub2.filename, callee === null || callee === void 0 || (_callee$object = callee.object) === null || _callee$object === void 0 ? void 0 : _callee$object.name // usually, but not necessarily always: "ControllerExtension"...
|
|
170
|
+
);
|
|
171
|
+
// ...hence we rather look at the imported module name to be sure
|
|
172
|
+
if ((importDeclaration === null || importDeclaration === void 0 || (_importDeclaration$so = importDeclaration.source) === null || _importDeclaration$so === void 0 ? void 0 : _importDeclaration$so.value) === "sap/ui/core/mvc/ControllerExtension") {
|
|
173
|
+
if (!member.value.arguments || member.value.arguments.length !== 1) {
|
|
174
|
+
// exactly one argument must be there
|
|
175
|
+
throw memberPath.buildCodeFrameError(`ControllerExtension.use() must be called with exactly one argument but has ${member.value.arguments ? member.value.arguments.length : 0}`);
|
|
176
|
+
}
|
|
177
|
+
member.value = member.value.arguments[0];
|
|
178
|
+
extendProps.unshift(buildObjectProperty(member)); // add it to the properties of the extend() config object
|
|
179
|
+
continue; // prevent the member from also being added to the constructor
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
153
184
|
// Special handling for TypeScript limitation where metadata, renderer and overrides must be properties.
|
|
154
185
|
if (["metadata", "renderer", "overrides"].includes(memberName)) {
|
|
155
186
|
if (opts.overridesToOverride && member.key.name === "overrides") {
|
|
@@ -15,6 +15,9 @@ const saveImports = file => {
|
|
|
15
15
|
// can be called from visitor to access previously present declarations
|
|
16
16
|
exports.saveImports = saveImports;
|
|
17
17
|
function getImportDeclaration(filename, typeName) {
|
|
18
|
+
if (!filename || !typeName) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
18
21
|
const typeNameParts = typeName.split(".");
|
|
19
22
|
|
|
20
23
|
// find the declaration importing the typeName among the collected import declarations in this file
|
package/dist/modules/visitor.js
CHANGED
|
@@ -43,7 +43,23 @@ const addImport = (imports, imp, filename, first) => {
|
|
|
43
43
|
// (the require/define of UI5 always adds the file extension ".js" to the module name)
|
|
44
44
|
if (/^(?:(@[^/]+)\/)?([^/]+)\/(.*)\.js$/.test(imp.src)) {
|
|
45
45
|
try {
|
|
46
|
-
|
|
46
|
+
let modulePath;
|
|
47
|
+
let absModuleSrc = imp.src;
|
|
48
|
+
// if the module has a relative path, resolve it to an absolute path
|
|
49
|
+
// and verify if the file exists, if not, try to resolve it as a module
|
|
50
|
+
if (/^\.\.?\//.test(absModuleSrc)) {
|
|
51
|
+
absModuleSrc = (0, _path.resolve)((0, _path.dirname)(filename), absModuleSrc);
|
|
52
|
+
// handle the fallback of module names introduced with Node 20.0.0
|
|
53
|
+
[".js", ".jsx", ".ts", ".tsx"].some(ext => {
|
|
54
|
+
if ((0, _fs.existsSync)(absModuleSrc.replace(/\.js$/, ext))) {
|
|
55
|
+
modulePath = imp.src;
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
} else {
|
|
60
|
+
modulePath = require.resolve(absModuleSrc);
|
|
61
|
+
}
|
|
62
|
+
// detect removal of file extension and log a hint
|
|
47
63
|
if (modulePath.endsWith(imp.src.split("/").pop())) {
|
|
48
64
|
console.log(`\x1b[33mHint:\x1b[0m Removed file extension for dependency "\x1b[34m${imp.src}\x1b[0m" found in \x1b[90m${filename}\x1b[0m`);
|
|
49
65
|
imp.src = imp.src.slice(0, -3);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "babel-plugin-transform-modules-ui5",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.5.0",
|
|
4
4
|
"description": "An unofficial babel plugin for SAP UI5.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"repository": {
|
|
@@ -18,9 +18,9 @@
|
|
|
18
18
|
"lint": "eslint src",
|
|
19
19
|
"lint:fix": "npm run lint -- --fix",
|
|
20
20
|
"lint:staged": "lint-staged",
|
|
21
|
-
"test": "jest __test__ --coverage=no",
|
|
21
|
+
"test": "FORCE_COLOR=0 jest __test__ --coverage=no",
|
|
22
22
|
"test:watch": "npm test -- --watch",
|
|
23
|
-
"test:update-snapshot": "jest --updateSnapshot",
|
|
23
|
+
"test:update-snapshot": "FORCE_COLOR=0 jest --updateSnapshot",
|
|
24
24
|
"prepare": "npm test && npm run build",
|
|
25
25
|
"format": "prettier --write 'src/**/*.js'"
|
|
26
26
|
},
|
|
@@ -94,5 +94,5 @@
|
|
|
94
94
|
"prettier": "^3.1.0",
|
|
95
95
|
"rimraf": "^5.0.5"
|
|
96
96
|
},
|
|
97
|
-
"gitHead": "
|
|
97
|
+
"gitHead": "afd2f7c5644541c95ea3218a306fce1c71391050"
|
|
98
98
|
}
|