@ui5/builder 3.0.0-beta.1 → 3.0.0-beta.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 +18 -1
- package/lib/lbt/analyzer/JSModuleAnalyzer.js +12 -12
- package/lib/lbt/resources/LibraryFileAnalyzer.js +1 -1
- package/lib/lbt/resources/ModuleInfo.js +1 -1
- package/lib/lbt/resources/ResourceCollector.js +1 -1
- package/lib/lbt/utils/ASTUtils.js +2 -0
- package/lib/lbt/utils/escapePropertiesFile.js +1 -1
- package/lib/lbt/utils/parseUtils.js +1 -1
- package/lib/processors/jsdoc/jsdocGenerator.js +6 -8
- package/lib/processors/jsdoc/lib/transformApiJson.cjs +5 -4
- package/lib/processors/jsdoc/lib/ui5/plugin.cjs +9 -5
- package/lib/processors/jsdoc/lib/ui5/template/publish.cjs +5 -1
- package/lib/processors/libraryLessGenerator.js +1 -1
- package/lib/processors/manifestCreator.js +1 -1
- package/lib/processors/nonAsciiEscaper.js +1 -1
- package/lib/processors/versionInfoGenerator.js +7 -7
- package/lib/tasks/bundlers/generateComponentPreload.js +6 -3
- package/lib/tasks/bundlers/generateLibraryPreload.js +13 -7
- package/lib/tasks/bundlers/utils/createModuleNameMapping.js +1 -1
- package/lib/tasks/generateCachebusterInfo.js +1 -1
- package/lib/tasks/taskRepository.js +1 -2
- package/package.json +19 -21
- package/lib/processors/bundlers/manifestBundler.js +0 -181
- package/lib/tasks/bundlers/generateManifestBundle.js +0 -58
package/CHANGELOG.md
CHANGED
|
@@ -2,7 +2,23 @@
|
|
|
2
2
|
All notable changes to this project will be documented in this file.
|
|
3
3
|
This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
|
4
4
|
|
|
5
|
-
A list of unreleased changes can be found [here](https://github.com/SAP/ui5-builder/compare/v3.0.0-beta.
|
|
5
|
+
A list of unreleased changes can be found [here](https://github.com/SAP/ui5-builder/compare/v3.0.0-beta.2...HEAD).
|
|
6
|
+
|
|
7
|
+
<a name="v3.0.0-beta.2"></a>
|
|
8
|
+
## [v3.0.0-beta.2] - 2022-11-17
|
|
9
|
+
### Breaking Changes
|
|
10
|
+
- Removal of manifestBundler and generateManifestBundle ([#838](https://github.com/SAP/ui5-builder/issues/838)) [`07a5be2`](https://github.com/SAP/ui5-builder/commit/07a5be2b6d9aa23cf78ddd17951c832d6dec7bef)
|
|
11
|
+
- **JSDoc:** Fail build when jsdoc command failed ([#845](https://github.com/SAP/ui5-builder/issues/845)) [`c2916b4`](https://github.com/SAP/ui5-builder/commit/c2916b4f1d49b5500e4b51143d4e6065ac200eef)
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
- Support ES2022 language features ([#848](https://github.com/SAP/ui5-builder/issues/848)) [`f9b8457`](https://github.com/SAP/ui5-builder/commit/f9b845726731a0e02ec4a499e2a1a82a639174a8)
|
|
15
|
+
|
|
16
|
+
### BREAKING CHANGE
|
|
17
|
+
|
|
18
|
+
The `jsdocGenerator` processor and the corresponding `generateJsdoc` task will now throw an error when JSDoc reports an error (exit code != 0). This will also fail the build when running `ui5 build jsdoc`.
|
|
19
|
+
|
|
20
|
+
The manifestBundler processor and generateManifestBundle task has been removed because it is no longer required for the HTML5 repository in Cloud Foundry.
|
|
21
|
+
|
|
6
22
|
|
|
7
23
|
<a name="v3.0.0-beta.1"></a>
|
|
8
24
|
## [v3.0.0-beta.1] - 2022-11-07
|
|
@@ -787,6 +803,7 @@ to load the custom bundle file instead.
|
|
|
787
803
|
- Add ability to configure component preloads and custom bundles [`2241e5f`](https://github.com/SAP/ui5-builder/commit/2241e5ff98fd95f1f80cc74959655ae7a9c660e7)
|
|
788
804
|
|
|
789
805
|
|
|
806
|
+
[v3.0.0-beta.2]: https://github.com/SAP/ui5-builder/compare/v3.0.0-beta.1...v3.0.0-beta.2
|
|
790
807
|
[v3.0.0-beta.1]: https://github.com/SAP/ui5-builder/compare/v3.0.0-alpha.12...v3.0.0-beta.1
|
|
791
808
|
[v3.0.0-alpha.12]: https://github.com/SAP/ui5-builder/compare/v3.0.0-alpha.11...v3.0.0-alpha.12
|
|
792
809
|
[v3.0.0-alpha.11]: https://github.com/SAP/ui5-builder/compare/v3.0.0-alpha.10...v3.0.0-alpha.11
|
|
@@ -135,10 +135,10 @@ const EnrichedVisitorKeys = (function() {
|
|
|
135
135
|
* All properties in an object pattern are executed.
|
|
136
136
|
*/
|
|
137
137
|
ObjectPattern: [], // properties
|
|
138
|
-
|
|
138
|
+
PrivateIdentifier: [],
|
|
139
139
|
Program: [],
|
|
140
140
|
Property: [],
|
|
141
|
-
|
|
141
|
+
PropertyDefinition: [],
|
|
142
142
|
/*
|
|
143
143
|
* argument of the rest element is always executed under the same condition as the rest element itself
|
|
144
144
|
*/
|
|
@@ -146,7 +146,7 @@ const EnrichedVisitorKeys = (function() {
|
|
|
146
146
|
ReturnStatement: [],
|
|
147
147
|
SequenceExpression: [],
|
|
148
148
|
SpreadElement: [], // the argument of the spread operator always needs to be evaluated - argument
|
|
149
|
-
|
|
149
|
+
StaticBlock: [],
|
|
150
150
|
Super: [],
|
|
151
151
|
SwitchStatement: [],
|
|
152
152
|
SwitchCase: ["test", "consequent"], // test and consequent are executed only conditionally
|
|
@@ -196,15 +196,6 @@ const EnrichedVisitorKeys = (function() {
|
|
|
196
196
|
return;
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
-
// Ignore new ES2022 syntax as we currently use ES2021 (see parseUtils.js)
|
|
200
|
-
if (
|
|
201
|
-
type === "PrivateIdentifier" ||
|
|
202
|
-
type === "PropertyDefinition" ||
|
|
203
|
-
type === "StaticBlock"
|
|
204
|
-
) {
|
|
205
|
-
return;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
199
|
const visitorKeys = VisitorKeys[type];
|
|
209
200
|
const condKeys = TempKeys[type];
|
|
210
201
|
if ( condKeys === undefined ) {
|
|
@@ -535,6 +526,15 @@ class JSModuleAnalyzer {
|
|
|
535
526
|
}
|
|
536
527
|
break;
|
|
537
528
|
|
|
529
|
+
case Syntax.PropertyDefinition:
|
|
530
|
+
|
|
531
|
+
// Instance properties (static=false) are only initialized when an instance is created (conditional)
|
|
532
|
+
// but a computed key is always evaluated on class initialization (eager)
|
|
533
|
+
visit(node.key, conditional);
|
|
534
|
+
visit(node.value, !node.static || conditional);
|
|
535
|
+
|
|
536
|
+
break;
|
|
537
|
+
|
|
538
538
|
default:
|
|
539
539
|
if ( condKeys == null ) {
|
|
540
540
|
log.error("Unhandled AST node type " + node.type, node);
|
|
@@ -66,7 +66,7 @@ class ResourceCollector {
|
|
|
66
66
|
*
|
|
67
67
|
* If no component is given, orphans will only be reported but not added to any component (default).
|
|
68
68
|
*
|
|
69
|
-
* @param {
|
|
69
|
+
* @param {Object<string, string[]>} list component to list of components
|
|
70
70
|
*/
|
|
71
71
|
setExternalResources(list) {
|
|
72
72
|
this._externalResources = list;
|
|
@@ -56,6 +56,8 @@ export function isMethodCall(node, methodPath) {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
export function isNamedObject(node, objectPath, length) {
|
|
59
|
+
// TODO: Support PrivateIdentifier (foo.#bar)
|
|
60
|
+
|
|
59
61
|
// console.log("checking for named object ", node, objectPath, length);
|
|
60
62
|
while ( length > 1 &&
|
|
61
63
|
node.type === Syntax.MemberExpression &&
|
|
@@ -15,7 +15,7 @@ export default async function(resource) {
|
|
|
15
15
|
let propertiesFileSourceEncoding = project && project.getPropertiesFileSourceEncoding();
|
|
16
16
|
|
|
17
17
|
if (!propertiesFileSourceEncoding) {
|
|
18
|
-
if (project &&
|
|
18
|
+
if (project && project.getSpecVersion().lte("1.1")) {
|
|
19
19
|
// default encoding to "ISO-8859-1" for old specVersions
|
|
20
20
|
propertiesFileSourceEncoding = "ISO-8859-1";
|
|
21
21
|
} else {
|
|
@@ -7,7 +7,7 @@ export function parseJS(code, userOptions = {}) {
|
|
|
7
7
|
// allowed options and their defaults
|
|
8
8
|
const options = {
|
|
9
9
|
comment: false,
|
|
10
|
-
ecmaVersion:
|
|
10
|
+
ecmaVersion: 2022, // NOTE: Adopt JSModuleAnalyzer.js to allow new Syntax when upgrading to newer ECMA versions
|
|
11
11
|
range: false,
|
|
12
12
|
sourceType: "script",
|
|
13
13
|
};
|
|
@@ -170,18 +170,16 @@ async function buildJsdoc({sourcePath, configPath}) {
|
|
|
170
170
|
"--verbose",
|
|
171
171
|
sourcePath
|
|
172
172
|
];
|
|
173
|
-
|
|
173
|
+
const exitCode = await new Promise((resolve /* , reject */) => {
|
|
174
174
|
const child = spawn("node", args, {
|
|
175
175
|
stdio: ["ignore", "ignore", "inherit"]
|
|
176
176
|
});
|
|
177
|
-
child.on("close",
|
|
178
|
-
if (code === 0 || code === 1) {
|
|
179
|
-
resolve();
|
|
180
|
-
} else {
|
|
181
|
-
reject(new Error(`JSDoc child process closed with code ${code}`));
|
|
182
|
-
}
|
|
183
|
-
});
|
|
177
|
+
child.on("close", resolve);
|
|
184
178
|
});
|
|
179
|
+
|
|
180
|
+
if (exitCode !== 0) {
|
|
181
|
+
throw new Error(`JSDoc reported an error, check the log for issues (exit code: ${exitCode})`);
|
|
182
|
+
}
|
|
185
183
|
}
|
|
186
184
|
|
|
187
185
|
jsdocGenerator._generateJsdocConfig = generateJsdocConfig;
|
|
@@ -989,11 +989,12 @@ function transformer(sInputFile, sOutputFile, sLibraryFile, vDependencyAPIFiles,
|
|
|
989
989
|
const {sources} = options;
|
|
990
990
|
let {librarySrcDir, libraryTestDir} = options;
|
|
991
991
|
|
|
992
|
-
// Using path.join to normalize POSIX paths to Windows paths on Windows
|
|
993
|
-
librarySrcDir = path.join(librarySrcDir);
|
|
994
|
-
libraryTestDir = path.join(libraryTestDir);
|
|
995
|
-
|
|
996
992
|
if (Array.isArray(sources) && typeof librarySrcDir === "string" && typeof libraryTestDir === "string") {
|
|
993
|
+
|
|
994
|
+
// Using path.join to normalize POSIX paths to Windows paths on Windows
|
|
995
|
+
librarySrcDir = path.join(librarySrcDir);
|
|
996
|
+
libraryTestDir = path.join(libraryTestDir);
|
|
997
|
+
|
|
997
998
|
/**
|
|
998
999
|
* Calculate prefix to check
|
|
999
1000
|
*
|
|
@@ -507,9 +507,10 @@ function stripChainWrappers(rootNode, path) {
|
|
|
507
507
|
|
|
508
508
|
function isTemplateLiteralWithoutExpression(node) {
|
|
509
509
|
return (
|
|
510
|
-
node
|
|
511
|
-
node
|
|
512
|
-
node
|
|
510
|
+
node &&
|
|
511
|
+
node.type === Syntax.TemplateLiteral &&
|
|
512
|
+
node.expressions && node.expressions.length === 0 &&
|
|
513
|
+
node.quasis && node.quasis.length === 1
|
|
513
514
|
);
|
|
514
515
|
}
|
|
515
516
|
|
|
@@ -801,9 +802,11 @@ function convertValueWithRaw(node, type, propertyName) {
|
|
|
801
802
|
}
|
|
802
803
|
|
|
803
804
|
} else if ( isTemplateLiteralWithoutExpression(node) ) {
|
|
805
|
+
let value = node.quasis[0].value || {};
|
|
806
|
+
|
|
804
807
|
return {
|
|
805
|
-
value:
|
|
806
|
-
raw:
|
|
808
|
+
value: value.cooked,
|
|
809
|
+
raw: value.raw,
|
|
807
810
|
};
|
|
808
811
|
}
|
|
809
812
|
|
|
@@ -2495,6 +2498,7 @@ exports.handlers = {
|
|
|
2495
2498
|
e.doclet.meta.__shortpath = getRelativePath(filepath);
|
|
2496
2499
|
_ui5data.resource = currentModule.resource;
|
|
2497
2500
|
_ui5data.module = currentModule.name || currentModule.module;
|
|
2501
|
+
_ui5data.initialLongname = e.doclet.longname;
|
|
2498
2502
|
|
|
2499
2503
|
const localDecl = findLocalDeclaration(e.doclet.meta.lineno, e.doclet.meta.columnno);
|
|
2500
2504
|
if ( localDecl ) {
|
|
@@ -2877,7 +2877,11 @@ function createAPIJSON4Symbol(symbol, omitDefaults) {
|
|
|
2877
2877
|
}
|
|
2878
2878
|
tag("method");
|
|
2879
2879
|
attrib("name", name || member.name);
|
|
2880
|
-
|
|
2880
|
+
// write out module and export only when the module is different from the module of the parent entity
|
|
2881
|
+
// and when the member was not cloned (e.g. because it is borrowed)
|
|
2882
|
+
if ( member.__ui5.module
|
|
2883
|
+
&& member.__ui5.module !== symbol.__ui5.module
|
|
2884
|
+
&& member.__ui5.initialLongname === member.longname ) {
|
|
2881
2885
|
attrib("module", member.__ui5.module);
|
|
2882
2886
|
attrib("export", member.__ui5.globalOnly ? GLOBAL_ONLY : member.__ui5.export, '', true);
|
|
2883
2887
|
}
|
|
@@ -178,7 +178,7 @@ class LibraryLessGenerator {
|
|
|
178
178
|
* @param {@ui5/fs/Resource[]} parameters.resources List of <code>library.source.less</code>
|
|
179
179
|
* resources
|
|
180
180
|
* @param {fs|module:@ui5/fs/fsInterface} parameters.fs Node fs or custom
|
|
181
|
-
* [fs interface]{@link module
|
|
181
|
+
* [fs interface]{@link module:@ui5/fs/fsInterface}
|
|
182
182
|
* @returns {Promise<@ui5/fs/Resource[]>} Promise resolving with library.less resources
|
|
183
183
|
*/
|
|
184
184
|
async function createLibraryLess({resources, fs}) {
|
|
@@ -349,7 +349,7 @@ async function createManifest(
|
|
|
349
349
|
}
|
|
350
350
|
|
|
351
351
|
function collectThemes() {
|
|
352
|
-
const themes =
|
|
352
|
+
const themes = Object.create(null);
|
|
353
353
|
|
|
354
354
|
// find theme resources and determine theme names from their paths
|
|
355
355
|
libBundle.getResources(/(?:[^/]+\/)*themes\//).forEach((res) => {
|
|
@@ -14,7 +14,7 @@ import escapeUnicode from "escape-unicode";
|
|
|
14
14
|
const CHAR_CODE_OF_LAST_ASCII_CHARACTER = 127;
|
|
15
15
|
|
|
16
16
|
// use memoization for escapeUnicode function for performance
|
|
17
|
-
const memoizeEscapeUnicodeMap =
|
|
17
|
+
const memoizeEscapeUnicodeMap = Object.create(null);
|
|
18
18
|
const memoizeEscapeUnicode = function(sChar) {
|
|
19
19
|
if (memoizeEscapeUnicodeMap[sChar]) {
|
|
20
20
|
return memoizeEscapeUnicodeMap[sChar];
|
|
@@ -25,7 +25,7 @@ function getTimestamp() {
|
|
|
25
25
|
/**
|
|
26
26
|
* Manifest libraries as defined in the manifest.json file
|
|
27
27
|
*
|
|
28
|
-
* @typedef {
|
|
28
|
+
* @typedef {Object<string, {lazy: boolean}>} ManifestLibraries
|
|
29
29
|
*
|
|
30
30
|
* sample:
|
|
31
31
|
* <pre>
|
|
@@ -60,15 +60,15 @@ function getTimestamp() {
|
|
|
60
60
|
const processManifest = async (manifestResource) => {
|
|
61
61
|
const manifestContent = await manifestResource.getString();
|
|
62
62
|
const manifestObject = JSON.parse(manifestContent);
|
|
63
|
-
const manifestInfo =
|
|
63
|
+
const manifestInfo = Object.create(null);
|
|
64
64
|
|
|
65
65
|
// sap.ui5/dependencies is used for the "manifestHints/libs"
|
|
66
66
|
if (manifestObject["sap.ui5"]) {
|
|
67
67
|
const manifestDependencies = manifestObject["sap.ui5"]["dependencies"];
|
|
68
68
|
if (manifestDependencies && manifestDependencies.libs) {
|
|
69
|
-
const libs =
|
|
69
|
+
const libs = Object.create(null);
|
|
70
70
|
for (const [libKey, libValue] of Object.entries(manifestDependencies.libs)) {
|
|
71
|
-
libs[libKey] =
|
|
71
|
+
libs[libKey] = Object.create(null);
|
|
72
72
|
if (libValue.lazy) {
|
|
73
73
|
libs[libKey].lazy = true;
|
|
74
74
|
}
|
|
@@ -230,7 +230,7 @@ class DependencyInfo {
|
|
|
230
230
|
* @returns {object} the object with sorted keys
|
|
231
231
|
*/
|
|
232
232
|
const sortObjectKeys = (obj) => {
|
|
233
|
-
const sortedObject =
|
|
233
|
+
const sortedObject = Object.create(null);
|
|
234
234
|
const keys = Object.keys(obj);
|
|
235
235
|
keys.sort();
|
|
236
236
|
keys.forEach((key) => {
|
|
@@ -433,7 +433,7 @@ export default async function({options}) {
|
|
|
433
433
|
let components;
|
|
434
434
|
artifactInfos.forEach((artifactInfo) => {
|
|
435
435
|
artifactInfo.embeds.forEach((embeddedArtifactInfo) => {
|
|
436
|
-
const componentObject =
|
|
436
|
+
const componentObject = Object.create(null);
|
|
437
437
|
const bundledComponents = artifactInfo.bundledComponents;
|
|
438
438
|
const componentName = embeddedArtifactInfo.componentName;
|
|
439
439
|
if (!bundledComponents.has(componentName)) {
|
|
@@ -446,7 +446,7 @@ export default async function({options}) {
|
|
|
446
446
|
componentObject.manifestHints = manifestHints;
|
|
447
447
|
}
|
|
448
448
|
|
|
449
|
-
components = components ||
|
|
449
|
+
components = components || Object.create(null);
|
|
450
450
|
components[componentName] = componentObject;
|
|
451
451
|
});
|
|
452
452
|
});
|
|
@@ -37,9 +37,12 @@ export default async function({
|
|
|
37
37
|
}) {
|
|
38
38
|
let nonDbgWorkspace = workspace;
|
|
39
39
|
if (taskUtil) {
|
|
40
|
-
nonDbgWorkspace =
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
nonDbgWorkspace = taskUtil.resourceFactory.createFilterReader({
|
|
41
|
+
reader: workspace,
|
|
42
|
+
callback: function(resource) {
|
|
43
|
+
// Remove any debug variants
|
|
44
|
+
return !taskUtil.getTag(resource, taskUtil.STANDARD_TAGS.IsDebugVariant);
|
|
45
|
+
}
|
|
43
46
|
});
|
|
44
47
|
}
|
|
45
48
|
|
|
@@ -246,9 +246,12 @@ function getSapUiCoreBunDef(name, filters, preload) {
|
|
|
246
246
|
export default async function({workspace, taskUtil, options: {skipBundles = [], excludes = [], projectName}}) {
|
|
247
247
|
let nonDbgWorkspace = workspace;
|
|
248
248
|
if (taskUtil) {
|
|
249
|
-
nonDbgWorkspace =
|
|
250
|
-
|
|
251
|
-
|
|
249
|
+
nonDbgWorkspace = taskUtil.resourceFactory.createFilterReader({
|
|
250
|
+
reader: workspace,
|
|
251
|
+
callback: function(resource) {
|
|
252
|
+
// Remove any debug variants
|
|
253
|
+
return !taskUtil.getTag(resource, taskUtil.STANDARD_TAGS.IsDebugVariant);
|
|
254
|
+
}
|
|
252
255
|
});
|
|
253
256
|
}
|
|
254
257
|
|
|
@@ -273,7 +276,7 @@ export default async function({workspace, taskUtil, options: {skipBundles = [],
|
|
|
273
276
|
// This is mainly to have an easier check without version parsing or using semver.
|
|
274
277
|
// If no project/specVersion is available, the bundles should also be created to not break potential
|
|
275
278
|
// existing use cases without a properly formed/formatted project tree.
|
|
276
|
-
if (!taskUtil ||
|
|
279
|
+
if (!taskUtil || taskUtil.getProject().getSpecVersion().lte("2.0")) {
|
|
277
280
|
const isEvo = resources.find((resource) => {
|
|
278
281
|
return resource.getPath() === "/resources/ui5loader.js";
|
|
279
282
|
});
|
|
@@ -281,9 +284,12 @@ export default async function({workspace, taskUtil, options: {skipBundles = [],
|
|
|
281
284
|
let unoptimizedModuleNameMapping;
|
|
282
285
|
let unoptimizedResources = resources;
|
|
283
286
|
if (taskUtil) {
|
|
284
|
-
const unoptimizedWorkspace =
|
|
285
|
-
|
|
286
|
-
|
|
287
|
+
const unoptimizedWorkspace = taskUtil.resourceFactory.createFilterReader({
|
|
288
|
+
reader: workspace,
|
|
289
|
+
callback: function(resource) {
|
|
290
|
+
// Remove any non-debug variants
|
|
291
|
+
return !taskUtil.getTag(resource, taskUtil.STANDARD_TAGS.HasDebugVariant);
|
|
292
|
+
}
|
|
287
293
|
});
|
|
288
294
|
unoptimizedResources =
|
|
289
295
|
await unoptimizedWorkspace.byGlob("/**/*.{js,json,xml,html,properties,library,js.map}");
|
|
@@ -15,7 +15,7 @@ import {getNonDebugName} from "../../../lbt/utils/ModuleName.js";
|
|
|
15
15
|
* @returns {object} Module name mapping
|
|
16
16
|
*/
|
|
17
17
|
export default function({resources, taskUtil}) {
|
|
18
|
-
const moduleNameMapping =
|
|
18
|
+
const moduleNameMapping = Object.create(null);
|
|
19
19
|
for (let i = resources.length - 1; i >= 0; i--) {
|
|
20
20
|
const resource = resources[i];
|
|
21
21
|
if (taskUtil.getTag(resource, taskUtil.STANDARD_TAGS.IsDebugVariant)) {
|
|
@@ -57,7 +57,7 @@ export default function({workspace, options}) {
|
|
|
57
57
|
const basePath = `/resources/${namespace}/`;
|
|
58
58
|
return workspace.byGlob(`/resources/${namespace}/**/*`)
|
|
59
59
|
.then(async (resources) => {
|
|
60
|
-
const cachebusterInfo =
|
|
60
|
+
const cachebusterInfo = Object.create(null);
|
|
61
61
|
const signer = getSigner(signatureType);
|
|
62
62
|
|
|
63
63
|
await Promise.all(resources.map(async (resource) => {
|
|
@@ -11,7 +11,6 @@ const taskInfos = {
|
|
|
11
11
|
transformBootstrapHtml: {path: "./transformBootstrapHtml.js"},
|
|
12
12
|
generateLibraryManifest: {path: "./generateLibraryManifest.js"},
|
|
13
13
|
generateVersionInfo: {path: "./generateVersionInfo.js"},
|
|
14
|
-
generateManifestBundle: {path: "./bundlers/generateManifestBundle.js"},
|
|
15
14
|
generateFlexChangesBundle: {path: "./bundlers/generateFlexChangesBundle.js"},
|
|
16
15
|
generateComponentPreload: {path: "./bundlers/generateComponentPreload.js"},
|
|
17
16
|
generateResourcesJson: {path: "./generateResourcesJson.js"},
|
|
@@ -26,7 +25,7 @@ export async function getTask(taskName) {
|
|
|
26
25
|
const taskInfo = taskInfos[taskName];
|
|
27
26
|
|
|
28
27
|
if (!taskInfo) {
|
|
29
|
-
if (["createDebugFiles", "uglify"].includes(taskName)) {
|
|
28
|
+
if (["createDebugFiles", "uglify", "generateManifestBundle"].includes(taskName)) {
|
|
30
29
|
throw new Error(
|
|
31
30
|
`Standard task ${taskName} has been removed in UI5 Tooling 3.0. ` +
|
|
32
31
|
`Please see the migration guide at https://sap.github.io/ui5-tooling/updates/migrate-v3/`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ui5/builder",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.2",
|
|
4
4
|
"description": "UI5 Tooling - Builder",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "SAP SE",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"./internal/jsdoc/template/publish": "./lib/processors/jsdoc/lib/ui5/template/publish.cjs"
|
|
29
29
|
},
|
|
30
30
|
"engines": {
|
|
31
|
-
"node": "
|
|
31
|
+
"node": "^16.18.0 || >=18.0.0",
|
|
32
32
|
"npm": ">= 8"
|
|
33
33
|
},
|
|
34
34
|
"scripts": {
|
|
@@ -119,44 +119,42 @@
|
|
|
119
119
|
},
|
|
120
120
|
"dependencies": {
|
|
121
121
|
"@jridgewell/sourcemap-codec": "^1.4.14",
|
|
122
|
-
"@ui5/fs": "^3.0.0-beta.
|
|
123
|
-
"@ui5/logger": "^3.0.1-beta.
|
|
124
|
-
"cheerio": "1.0.0-rc.
|
|
122
|
+
"@ui5/fs": "^3.0.0-beta.3",
|
|
123
|
+
"@ui5/logger": "^3.0.1-beta.1",
|
|
124
|
+
"cheerio": "1.0.0-rc.12",
|
|
125
125
|
"escape-unicode": "^0.2.0",
|
|
126
126
|
"escope": "^4.0.0",
|
|
127
|
-
"espree": "^9.
|
|
128
|
-
"graceful-fs": "^4.2.
|
|
129
|
-
"jsdoc": "^3.6.
|
|
127
|
+
"espree": "^9.4.1",
|
|
128
|
+
"graceful-fs": "^4.2.10",
|
|
129
|
+
"jsdoc": "^3.6.11",
|
|
130
130
|
"less-openui5": "^0.11.2",
|
|
131
131
|
"make-dir": "^3.1.0",
|
|
132
132
|
"pretty-data": "^0.40.0",
|
|
133
133
|
"replacestream": "^4.0.3",
|
|
134
134
|
"rimraf": "^3.0.2",
|
|
135
|
-
"semver": "^7.3.
|
|
136
|
-
"terser": "^5.
|
|
137
|
-
"xml2js": "^0.4.23"
|
|
138
|
-
"yazl": "^2.5.1"
|
|
135
|
+
"semver": "^7.3.8",
|
|
136
|
+
"terser": "^5.16.0",
|
|
137
|
+
"xml2js": "^0.4.23"
|
|
139
138
|
},
|
|
140
139
|
"devDependencies": {
|
|
141
140
|
"@istanbuljs/esm-loader-hook": "^0.2.0",
|
|
142
|
-
"@ui5/project": "^3.0.0-
|
|
143
|
-
"ava": "^
|
|
144
|
-
"chai": "^4.3.
|
|
141
|
+
"@ui5/project": "^3.0.0-beta.3",
|
|
142
|
+
"ava": "^5.1.0",
|
|
143
|
+
"chai": "^4.3.7",
|
|
145
144
|
"chai-fs": "^2.0.0",
|
|
146
145
|
"chokidar-cli": "^3.0.0",
|
|
147
146
|
"cross-env": "^7.0.3",
|
|
148
147
|
"depcheck": "^1.4.3",
|
|
149
|
-
"docdash": "^
|
|
150
|
-
"eslint": "^8.
|
|
148
|
+
"docdash": "^2.0.0",
|
|
149
|
+
"eslint": "^8.28.0",
|
|
151
150
|
"eslint-config-google": "^0.14.0",
|
|
152
151
|
"eslint-plugin-ava": "^13.2.0",
|
|
153
|
-
"eslint-plugin-jsdoc": "^
|
|
154
|
-
"esmock": "^2.0.
|
|
155
|
-
"extract-zip": "^2.0.1",
|
|
152
|
+
"eslint-plugin-jsdoc": "^39.6.4",
|
|
153
|
+
"esmock": "^2.0.9",
|
|
156
154
|
"nyc": "^15.1.0",
|
|
157
155
|
"open-cli": "^7.1.0",
|
|
158
156
|
"recursive-readdir": "^2.2.3",
|
|
159
|
-
"sinon": "^14.0.
|
|
157
|
+
"sinon": "^14.0.2",
|
|
160
158
|
"tap-nyan": "^1.1.0",
|
|
161
159
|
"tap-xunit": "^2.4.1"
|
|
162
160
|
}
|
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
import posixPath from "node:path/posix";
|
|
2
|
-
import yazl from "yazl";
|
|
3
|
-
import {createResource} from "@ui5/fs/resourceFactory";
|
|
4
|
-
import logger from "@ui5/logger";
|
|
5
|
-
const log = logger.getLogger("builder:processors:bundlers:manifestBundler");
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Repository to handle i18n resource files
|
|
9
|
-
*
|
|
10
|
-
* @private
|
|
11
|
-
*/
|
|
12
|
-
class I18nResourceList {
|
|
13
|
-
/**
|
|
14
|
-
* Constructor
|
|
15
|
-
*/
|
|
16
|
-
constructor() {
|
|
17
|
-
this.propertyFiles = new Map();
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Adds a i18n resource to the repository
|
|
22
|
-
*
|
|
23
|
-
* @param {string} directory Path to the i18n resource
|
|
24
|
-
* @param {@ui5/fs/Resource} resource i18n resource
|
|
25
|
-
*/
|
|
26
|
-
add(directory, resource) {
|
|
27
|
-
const normalizedDirectory = posixPath.normalize(directory);
|
|
28
|
-
if (!this.propertyFiles.has(normalizedDirectory)) {
|
|
29
|
-
this.propertyFiles.set(normalizedDirectory, [resource]);
|
|
30
|
-
} else {
|
|
31
|
-
this.propertyFiles.get(normalizedDirectory).push(resource);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Gets all registered i18n files within the provided path
|
|
37
|
-
*
|
|
38
|
-
* @param {string} directory Path to search for
|
|
39
|
-
* @returns {Array} Array of resources files
|
|
40
|
-
*/
|
|
41
|
-
get(directory) {
|
|
42
|
-
return this.propertyFiles.get(posixPath.normalize(directory)) || [];
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* @public
|
|
49
|
-
* @module @ui5/builder/processors/bundlers/manifestBundler
|
|
50
|
-
*/
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Creates a manifest bundle from the provided resources.
|
|
54
|
-
*
|
|
55
|
-
* @public
|
|
56
|
-
* @function default
|
|
57
|
-
* @static
|
|
58
|
-
*
|
|
59
|
-
* @param {object} parameters Parameters
|
|
60
|
-
* @param {@ui5/fs/Resource[]} parameters.resources List of resources to be processed
|
|
61
|
-
* @param {object} parameters.options Options
|
|
62
|
-
* @param {string} parameters.options.namespace Namespace of the project
|
|
63
|
-
* @param {string} parameters.options.bundleName Name of the bundled zip file
|
|
64
|
-
* @param {string} parameters.options.propertiesExtension Extension name of the properties files, e.g. ".properties"
|
|
65
|
-
* @param {string} parameters.options.descriptor Descriptor name
|
|
66
|
-
* @returns {Promise<@ui5/fs/Resource[]>} Promise resolving with manifest bundle resources
|
|
67
|
-
*/
|
|
68
|
-
export default ({resources, options: {namespace, bundleName, propertiesExtension, descriptor}}) => {
|
|
69
|
-
function bundleNameToUrl(bundleName, appId) {
|
|
70
|
-
if (!bundleName.startsWith(appId)) {
|
|
71
|
-
return null;
|
|
72
|
-
}
|
|
73
|
-
const relativeBundleName = bundleName.substring(appId.length + 1);
|
|
74
|
-
return relativeBundleName.replace(/\./g, "/") + propertiesExtension;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function addDescriptorI18nInfos(descriptorI18nInfos, manifest) {
|
|
78
|
-
function addI18nInfo(i18nPath) {
|
|
79
|
-
if (i18nPath.startsWith("ui5:")) {
|
|
80
|
-
log.warn(`Using the ui5:// protocol for i18n bundles is currently not supported ('${i18nPath}' in ${manifest.path})`);
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
descriptorI18nInfos.set(
|
|
84
|
-
posixPath.join(posixPath.dirname(manifest.path), posixPath.dirname(i18nPath)),
|
|
85
|
-
posixPath.basename(i18nPath, propertiesExtension)
|
|
86
|
-
);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const content = JSON.parse(manifest.content);
|
|
90
|
-
const appI18n = content["sap.app"]["i18n"];
|
|
91
|
-
let bundleUrl;
|
|
92
|
-
// i18n section in sap.app can be either a string or an object with bundleUrl
|
|
93
|
-
if (typeof appI18n === "object") {
|
|
94
|
-
if (appI18n.bundleUrl) {
|
|
95
|
-
bundleUrl = appI18n.bundleUrl;
|
|
96
|
-
} else if (appI18n.bundleName) {
|
|
97
|
-
bundleUrl = bundleNameToUrl(appI18n.bundleName, content["sap.app"]["id"]);
|
|
98
|
-
}
|
|
99
|
-
} else if (typeof appI18n === "string") {
|
|
100
|
-
bundleUrl = appI18n;
|
|
101
|
-
} else {
|
|
102
|
-
bundleUrl = "i18n/i18n.properties";
|
|
103
|
-
}
|
|
104
|
-
if (bundleUrl) {
|
|
105
|
-
addI18nInfo(bundleUrl);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
if (typeof appI18n === "object" && Array.isArray(appI18n.enhanceWith)) {
|
|
109
|
-
appI18n.enhanceWith.forEach((enhanceWithEntry) => {
|
|
110
|
-
let bundleUrl;
|
|
111
|
-
if (enhanceWithEntry.bundleUrl) {
|
|
112
|
-
bundleUrl = enhanceWithEntry.bundleUrl;
|
|
113
|
-
} else if (enhanceWithEntry.bundleName) {
|
|
114
|
-
bundleUrl = bundleNameToUrl(enhanceWithEntry.bundleName, content["sap.app"]["id"]);
|
|
115
|
-
}
|
|
116
|
-
if (bundleUrl) {
|
|
117
|
-
addI18nInfo(bundleUrl);
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
return Promise.all(resources.map((resource) =>
|
|
124
|
-
resource.getBuffer().then((content) => {
|
|
125
|
-
const basename = posixPath.basename(resource.getPath());
|
|
126
|
-
return {
|
|
127
|
-
name: basename,
|
|
128
|
-
isManifest: basename === descriptor,
|
|
129
|
-
path: resource.getPath(),
|
|
130
|
-
content: content
|
|
131
|
-
};
|
|
132
|
-
})
|
|
133
|
-
)).then((resources) => {
|
|
134
|
-
const archiveContent = new Map();
|
|
135
|
-
const descriptorI18nInfos = new Map();
|
|
136
|
-
const i18nResourceList = new I18nResourceList();
|
|
137
|
-
|
|
138
|
-
resources.forEach((resource) => {
|
|
139
|
-
if (resource.isManifest) {
|
|
140
|
-
addDescriptorI18nInfos(descriptorI18nInfos, resource);
|
|
141
|
-
archiveContent.set(resource.path, resource.content);
|
|
142
|
-
} else {
|
|
143
|
-
const directory = posixPath.dirname(resource.path);
|
|
144
|
-
i18nResourceList.add(directory, resource);
|
|
145
|
-
}
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
descriptorI18nInfos.forEach((rootName, directory) => {
|
|
149
|
-
const i18nResources = i18nResourceList.get(directory)
|
|
150
|
-
.filter((resource) => resource.name.startsWith(rootName));
|
|
151
|
-
|
|
152
|
-
if (i18nResources.length) {
|
|
153
|
-
i18nResources.forEach((resource) => archiveContent.set(resource.path, resource.content));
|
|
154
|
-
} else {
|
|
155
|
-
log.warn(`Could not find any resources for i18n bundle '${directory}'`);
|
|
156
|
-
}
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
return archiveContent;
|
|
160
|
-
}).then((archiveContent) => new Promise((resolve) => {
|
|
161
|
-
const zip = new yazl.ZipFile();
|
|
162
|
-
const basePath = `/resources/${namespace}/`;
|
|
163
|
-
archiveContent.forEach((content, path) => {
|
|
164
|
-
if (!path.startsWith(basePath)) {
|
|
165
|
-
log.verbose(`Not bundling resource with path ${path} since it is not based on path ${basePath}`);
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
// Remove base path. Absolute paths are not allowed in ZIP files
|
|
169
|
-
const normalizedPath = path.replace(basePath, "");
|
|
170
|
-
zip.addBuffer(content, normalizedPath);
|
|
171
|
-
});
|
|
172
|
-
zip.end();
|
|
173
|
-
|
|
174
|
-
const pathPrefix = "/resources/" + namespace + "/";
|
|
175
|
-
const res = createResource({
|
|
176
|
-
path: pathPrefix + bundleName,
|
|
177
|
-
stream: zip.outputStream
|
|
178
|
-
});
|
|
179
|
-
resolve([res]);
|
|
180
|
-
}));
|
|
181
|
-
};
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import logger from "@ui5/logger";
|
|
2
|
-
const log = logger.getLogger("builder:tasks:bundlers:generateManifestBundle");
|
|
3
|
-
import manifestBundler from "../../processors/bundlers/manifestBundler.js";
|
|
4
|
-
|
|
5
|
-
const DESCRIPTOR = "manifest.json";
|
|
6
|
-
const PROPERTIES_EXT = ".properties";
|
|
7
|
-
const BUNDLE_NAME = "manifest-bundle.zip";
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* @public
|
|
11
|
-
* @module @ui5/builder/tasks/bundlers/generateManifestBundle
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
/* eslint "jsdoc/check-param-names": ["error", {"disableExtraPropertyReporting":true}] */
|
|
15
|
-
/**
|
|
16
|
-
* Task for manifestBundler.
|
|
17
|
-
*
|
|
18
|
-
* @public
|
|
19
|
-
* @function default
|
|
20
|
-
* @static
|
|
21
|
-
*
|
|
22
|
-
* @param {object} parameters Parameters
|
|
23
|
-
* @param {@ui5/fs/DuplexCollection} parameters.workspace DuplexCollection to read and write files
|
|
24
|
-
* @param {object} parameters.options Options
|
|
25
|
-
* @param {string} parameters.options.projectName Project name
|
|
26
|
-
* @param {string} parameters.options.projectNamespace Project namespace
|
|
27
|
-
* @returns {Promise<undefined>} Promise resolving with <code>undefined</code> once data has been written
|
|
28
|
-
*/
|
|
29
|
-
export default async function({workspace, options = {}}) {
|
|
30
|
-
const {projectName} = options;
|
|
31
|
-
// Backward compatibility: "namespace" option got renamed to "projectNamespace"
|
|
32
|
-
const namespace = options.projectNamespace || options.namespace;
|
|
33
|
-
|
|
34
|
-
if (!projectName || !namespace) {
|
|
35
|
-
throw new Error("[generateManifestBundle]: One or more mandatory options not provided");
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const allResources = await workspace.byGlob(`/resources/${namespace}/**/{${DESCRIPTOR},*${PROPERTIES_EXT}}`);
|
|
39
|
-
if (allResources.length === 0) {
|
|
40
|
-
log.verbose(`Could not find a "${DESCRIPTOR}" file for project ${projectName}, ` +
|
|
41
|
-
`creation of "${BUNDLE_NAME}" is skipped!`);
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const processedResources = await manifestBundler({
|
|
46
|
-
resources: allResources,
|
|
47
|
-
options: {
|
|
48
|
-
descriptor: DESCRIPTOR,
|
|
49
|
-
propertiesExtension: PROPERTIES_EXT,
|
|
50
|
-
bundleName: BUNDLE_NAME,
|
|
51
|
-
namespace
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
await Promise.all(processedResources.map((resource) => {
|
|
56
|
-
return workspace.write(resource);
|
|
57
|
-
}));
|
|
58
|
-
}
|