@ui5/builder 3.0.0-beta.5 → 3.0.0-rc.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
@@ -2,7 +2,13 @@
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...HEAD).
5
+ A list of unreleased changes can be found [here](https://github.com/SAP/ui5-builder/compare/v3.0.0-rc.0...HEAD).
6
+
7
+ <a name="v3.0.0-rc.0"></a>
8
+ ## [v3.0.0-rc.0] - 2022-12-23
9
+
10
+ <a name="v3.0.0-beta.6"></a>
11
+ ## [v3.0.0-beta.6] - 2022-12-13
6
12
 
7
13
  <a name="v3.0.0-beta.5"></a>
8
14
  ## [v3.0.0-beta.5] - 2022-12-12
@@ -825,6 +831,8 @@ to load the custom bundle file instead.
825
831
  - Add ability to configure component preloads and custom bundles [`2241e5f`](https://github.com/SAP/ui5-builder/commit/2241e5ff98fd95f1f80cc74959655ae7a9c660e7)
826
832
 
827
833
 
834
+ [v3.0.0-rc.0]: https://github.com/SAP/ui5-builder/compare/v3.0.0-beta.6...v3.0.0-rc.0
835
+ [v3.0.0-beta.6]: https://github.com/SAP/ui5-builder/compare/v3.0.0-beta.5...v3.0.0-beta.6
828
836
  [v3.0.0-beta.5]: https://github.com/SAP/ui5-builder/compare/v3.0.0-beta.4...v3.0.0-beta.5
829
837
  [v3.0.0-beta.4]: https://github.com/SAP/ui5-builder/compare/v3.0.0-beta.3...v3.0.0-beta.4
830
838
  [v3.0.0-beta.3]: https://github.com/SAP/ui5-builder/compare/v3.0.0-beta.2...v3.0.0-beta.3
package/jsdoc.json CHANGED
@@ -28,7 +28,7 @@
28
28
  "openGraph": {
29
29
  "title": "UI5 Tooling - API Reference",
30
30
  "type": "website",
31
- "image": "https://sap.github.io/ui5-tooling/docs/images/UI5_logo_wide.png",
31
+ "image": "https://sap.github.io/ui5-tooling/v3/images/UI5_logo_wide.png",
32
32
  "site_name": "UI5 Tooling - API Reference",
33
33
  "url": "https://sap.github.io/ui5-tooling/"
34
34
  },
@@ -57,10 +57,11 @@ class ComponentAnalyzer {
57
57
  const fileContent = await manifestResource.buffer();
58
58
  this._analyzeManifest( JSON.parse(fileContent.toString()), info );
59
59
  } else {
60
- log.verbose("No manifest found for '%s', skipping analysis", resource.name);
60
+ log.verbose(`No manifest found for '${resource.name}', skipping analysis`);
61
61
  }
62
62
  } catch (err) {
63
- log.error("an error occurred while analyzing component %s (ignored)", resource.name, err.stack);
63
+ log.error(`An error occurred while analyzing component ${resource.name} (ignored): ${err.message}`);
64
+ log.verbose(err.stack);
64
65
  }
65
66
 
66
67
  return info;
@@ -137,20 +138,20 @@ class ComponentAnalyzer {
137
138
  if ( ui5.rootView ) {
138
139
  const module = this._getRootViewModule(ui5.rootView);
139
140
  if (module) {
140
- log.verbose("adding root view dependency ", module);
141
+ log.verbose(`Adding root view dependency ${module}`);
141
142
  info.addDependency( module );
142
143
  }
143
144
  }
144
145
 
145
146
  each( ui5.dependencies && ui5.dependencies.libs, (options, lib) => {
146
147
  const module = fromUI5LegacyName(lib, "/library.js");
147
- log.verbose("adding library dependency ", module, options.lazy || false);
148
+ log.verbose(`Adding library dependency ${module} - lazy: ${options.lazy || false}`);
148
149
  info.addDependency( module, options.lazy ); // lazy -> conditional dependency
149
150
  });
150
151
 
151
152
  each( ui5.dependencies && ui5.dependencies.components, (options, component) => {
152
153
  const module = fromUI5LegacyName(component, "/Component.js");
153
- log.verbose("adding component dependency ", module, options.lazy || false);
154
+ log.verbose(`Adding component dependency ${module} - lazy: ${options.lazy || false}`);
154
155
  info.addDependency( module, options.lazy ); // lazy -> conditional dependency
155
156
  });
156
157
 
@@ -202,7 +203,7 @@ class ComponentAnalyzer {
202
203
  return;
203
204
  }
204
205
  const module = fromUI5LegacyName( modelType );
205
- log.verbose("derived model implementation dependency ", module);
206
+ log.verbose(`Derived model implementation dependency ${module}`);
206
207
  info.addDependency(module);
207
208
  });
208
209
 
@@ -214,15 +215,15 @@ class ComponentAnalyzer {
214
215
  if (routing.routes) {
215
216
  const routerClassName = routingConfig.routerClass || "sap.ui.core.routing.Router";
216
217
  const routerClassModule = fromUI5LegacyName(routerClassName);
217
- log.verbose(`adding router dependency '${routerClassModule}'`);
218
+ log.verbose(`Adding router dependency '${routerClassModule}'`);
218
219
  info.addDependency(routerClassModule);
219
220
  } else if (routing.targets) {
220
221
  const targetsModule = routingConfig.targetsClass || "sap/ui/core/routing/Targets.js";
221
- log.verbose(`adding routing targets dependency '${targetsModule}'`);
222
+ log.verbose(`Adding routing targets dependency '${targetsModule}'`);
222
223
  info.addDependency(targetsModule);
223
224
 
224
225
  const viewsModule = "sap/ui/core/routing/Views.js";
225
- log.verbose(`adding routing views dependency '${viewsModule}'`);
226
+ log.verbose(`Adding routing views dependency '${viewsModule}'`);
226
227
  info.addDependency(viewsModule);
227
228
  }
228
229
 
@@ -235,7 +236,7 @@ class ComponentAnalyzer {
235
236
  const module = fromUI5LegacyName(
236
237
  (config.viewPath ? config.viewPath + "." : "") +
237
238
  config.viewName, ".view." + config.viewType.toLowerCase() );
238
- log.verbose("converting routing target '%s' to view dependency '%s'", targetName, module);
239
+ log.verbose(`Converting routing target '${targetName}' to view dependency '${module}'`);
239
240
  // TODO make this a conditional dependency, depending on the route pattern?
240
241
  info.addDependency(module);
241
242
  }
@@ -100,10 +100,11 @@ class FioriElementsAnalyzer {
100
100
  const fileContent = await manifestResource.buffer();
101
101
  await this._analyzeManifest( JSON.parse(fileContent.toString()), info );
102
102
  } else {
103
- log.verbose("No manifest found for '%s', skipping analysis", resource.name);
103
+ log.verbose(`No manifest found for '${resource.name}', skipping analysis`);
104
104
  }
105
105
  } catch (err) {
106
- log.error("an error occurred while analyzing template app %s (ignored)", resource.name, err);
106
+ log.error(`An error occurred while analyzing template app ${resource.name} (ignored): ${err.message}`);
107
+ log.verbose(err.stack);
107
108
  }
108
109
 
109
110
  return info;
@@ -131,7 +132,7 @@ class FioriElementsAnalyzer {
131
132
  if ( actionCfg.template ) {
132
133
  const module = fromUI5LegacyName( "sap.fe.templates." +
133
134
  actionCfg.template + ".Component" );
134
- log.verbose("template app: add dependency to template component %s", module);
135
+ log.verbose(`Template app: Add dependency to template component ${module}`);
135
136
  info.addDependency(module);
136
137
  promises.push( this._analyzeTemplateComponent(module, actionCfg, info) );
137
138
  }
@@ -152,7 +153,7 @@ class FioriElementsAnalyzer {
152
153
  pageConfig.component.settings.templateName) || defaultTemplateName;
153
154
  if ( templateName ) {
154
155
  const templateModuleName = fromUI5LegacyName( templateName, ".view.xml" );
155
- log.verbose("template app: add dependency to template view %s", templateModuleName);
156
+ log.verbose(`Template app: Add dependency to template view ${templateModuleName}`);
156
157
  appInfo.addDependency(templateModuleName);
157
158
  }
158
159
  }
@@ -178,7 +178,7 @@ export const EnrichedVisitorKeys = (function() {
178
178
  // check for unknown keys in our configuration
179
179
  for ( const type in TempKeys ) {
180
180
  if ( VisitorKeys[type] === undefined ) {
181
- throw new Error("configuration contains unknown node type '" + type + "'");
181
+ throw new Error(`Configuration contains unknown node type '${type}'`);
182
182
  }
183
183
  }
184
184
 
@@ -190,7 +190,7 @@ export const EnrichedVisitorKeys = (function() {
190
190
  // check configured keys against visitor keys
191
191
  condKeys.forEach( (key) => {
192
192
  if ( !visitorKeys.includes(key) ) {
193
- throw new Error(`configuration for type '${type}' contains unknown key '${key}'`);
193
+ throw new Error(`Configuration for type '${type}' contains unknown key '${key}'`);
194
194
  }
195
195
  });
196
196
  TempKeys[type] = visitorKeys.map( (key) => ({
@@ -301,7 +301,7 @@ class JSModuleAnalyzer {
301
301
  if ( comment.value.startsWith("@ui5-bundle-raw-include ") ) {
302
302
  const subModule = comment.value.slice("@ui5-bundle-raw-include ".length);
303
303
  info.addSubModule(subModule);
304
- log.verbose(`bundle include directive ${subModule}`);
304
+ log.verbose(`Bundle include directive ${subModule}`);
305
305
  } else if ( comment.value.startsWith("@ui5-bundle ") ) {
306
306
  const bundleName = comment.value.slice("@ui5-bundle ".length);
307
307
  if (comment.start === 0) {
@@ -310,9 +310,9 @@ class JSModuleAnalyzer {
310
310
  } else {
311
311
  setMainModuleInfo(bundleName, null);
312
312
  }
313
- log.verbose(`bundle name directive ${bundleName}`);
313
+ log.verbose(`Bundle name directive ${bundleName}`);
314
314
  } else {
315
- log.warn(`unrecognized bundle directive ${comment.value}`);
315
+ log.warn(`Unrecognized bundle directive ${comment.value}`);
316
316
  }
317
317
  }
318
318
  });
@@ -363,7 +363,7 @@ class JSModuleAnalyzer {
363
363
  // hoisted functions
364
364
  function setMainModuleInfo(name, description) {
365
365
  if ( mainModuleFound ) {
366
- throw new Error("conflicting main modules found (unnamed + named)");
366
+ throw new Error("Conflicting main modules found (unnamed + named)");
367
367
  }
368
368
  mainModuleFound = true;
369
369
  info.name = name;
@@ -524,7 +524,7 @@ class JSModuleAnalyzer {
524
524
 
525
525
  default:
526
526
  if ( condKeys == null ) {
527
- log.error("Unhandled AST node type " + node.type, node);
527
+ log.error(`Unhandled AST node type ${node.type}`, node);
528
528
  throw new Error(`Unhandled AST node type ${node.type}`);
529
529
  }
530
530
  // default visit
@@ -547,17 +547,18 @@ class JSModuleAnalyzer {
547
547
  setMainModuleInfo(name, getDocumentation(node));
548
548
  } else if ( nModuleDeclarations > 1 && name === info.name ) {
549
549
  // ignore duplicate declarations (e.g. in behavior file of design time controls)
550
- log.warn(`duplicate declaration of module name at ${getLocation(args)} in ${name}`);
550
+ log.warn(`Duplicate declaration of module name at ${getLocation(args)} in ${name}`);
551
551
  } else {
552
552
  // otherwise it is just a submodule declaration
553
553
  info.addSubModule(name);
554
554
  }
555
555
  return;
556
556
  } else {
557
- log.error("jQuery.sap.declare: module name could not be determined from first argument:", args[0]);
557
+ log.error(
558
+ `jQuery.sap.declare: Module name could not be determined from first argument: ${args[0]}`);
558
559
  }
559
560
  } else {
560
- log.error("jQuery.sap.declare: module name could not be determined, no arguments are given");
561
+ log.error("jQuery.sap.declare: Module name could not be determined, no arguments are given");
561
562
  }
562
563
  }
563
564
 
@@ -594,11 +595,11 @@ class JSModuleAnalyzer {
594
595
  nUnnamedDefines++;
595
596
  if ( nUnnamedDefines > 1 ) {
596
597
  throw new Error(
597
- "if multiple modules are contained in a file, only one of them may omit the module ID " +
598
+ "If multiple modules are contained in a file, only one of them may omit the module ID " +
598
599
  name + " " + nUnnamedDefines);
599
600
  }
600
601
  if ( defaultName == null ) {
601
- throw new Error("unnamed module found, but no default name given");
602
+ throw new Error("Unnamed module found, but no default name given");
602
603
  }
603
604
  name = defaultName;
604
605
  // the first unnamed module definition qualifies as main module
@@ -617,7 +618,7 @@ class JSModuleAnalyzer {
617
618
  const nArgs = args.length;
618
619
 
619
620
  if ( nArgs > 0 && args[0].type == Syntax.OBJECT ) {
620
- log.verbose("jQuery.sap.require: cannot evaluate complex require (view/controller)");
621
+ log.verbose("jQuery.sap.require: Cannot evaluate complex require (view/controller)");
621
622
  } else {
622
623
  // UI5 signature with one or many required modules
623
624
  for (let i = 0; i < nArgs; i++) {
@@ -638,11 +639,11 @@ class JSModuleAnalyzer {
638
639
  info.addDependency(requiredModuleName2, true);
639
640
  }
640
641
  if ( consequentValue === undefined || alternateValue === undefined ) {
641
- log.verbose("jQuery.sap.require: cannot evaluate dynamic arguments: ", arg && arg.type);
642
+ log.verbose(`jQuery.sap.require: Cannot evaluate dynamic arguments: ${arg && arg.type}`);
642
643
  info.dynamicDependencies = true;
643
644
  }
644
645
  } else {
645
- log.verbose("jQuery.sap.require: cannot evaluate dynamic arguments: ", arg && arg.type);
646
+ log.verbose(`jQuery.sap.require: Cannot evaluate dynamic arguments: ${arg && arg.type}`);
646
647
  info.dynamicDependencies = true;
647
648
  }
648
649
  }
@@ -661,7 +662,7 @@ class JSModuleAnalyzer {
661
662
  const moduleName = fromRequireJSName( value );
662
663
  info.addDependency(moduleName, conditional);
663
664
  } else {
664
- log.verbose("sap.ui.requireSync: cannot evaluate dynamic arguments: ", args[i] && args[i].type);
665
+ log.verbose(`sap.ui.requireSync: Cannot evaluate dynamic arguments: ${args[i] && args[i].type}`);
665
666
  info.dynamicDependencies = true;
666
667
  }
667
668
  }
@@ -726,7 +727,7 @@ class JSModuleAnalyzer {
726
727
  info.addSubModule(moduleName);
727
728
  });
728
729
  } else {
729
- log.verbose("Cannot evaluate registerPreloadedModules: '%s'", modules && modules.type);
730
+ log.verbose(`Cannot evaluate registerPreloadedModules: ${modules && modules.type}`);
730
731
  }
731
732
  }
732
733
 
@@ -747,7 +748,7 @@ class JSModuleAnalyzer {
747
748
  }
748
749
  info.addDependency( requiredModule, conditional );
749
750
  } else {
750
- log.verbose("sap.ui.require/sap.ui.define: cannot evaluate dynamic argument: ", item && item.type);
751
+ log.verbose(`sap.ui.require/sap.ui.define: Cannot evaluate dynamic argument: ${item && item.type}`);
751
752
  info.dynamicDependencies = true;
752
753
  }
753
754
  });
@@ -59,11 +59,11 @@ class TemplateComponentAnalyzer {
59
59
  const fileContent = await manifestResource.buffer();
60
60
  await this._analyzeManifest( JSON.parse(fileContent.toString()), info );
61
61
  } else {
62
- log.verbose("No manifest found for '%s', skipping analysis", resource.name);
62
+ log.verbose(`No manifest found for '${resource.name}', skipping analysis`);
63
63
  }
64
64
  } catch (err) {
65
- log.error("an error occurred while analyzing template app %s (ignored):", resource.name);
66
- log.error(err.stack);
65
+ log.error(`An error occurred while analyzing template app ${resource.name} (ignored): ${err.message}`);
66
+ log.verbose(err.stack);
67
67
  }
68
68
 
69
69
  return info;
@@ -85,7 +85,7 @@ class TemplateComponentAnalyzer {
85
85
  function recursePage(page) {
86
86
  if ( page.component && page.component.name ) {
87
87
  const module = fromUI5LegacyName( page.component.name + ".Component" );
88
- log.verbose("template app: add dependency to template component %s", module);
88
+ log.verbose(`Template app: Add dependency to template component ${module}`);
89
89
  info.addDependency(module);
90
90
  promises.push( that._analyzeTemplateComponent(module, page, info) );
91
91
  }
@@ -114,12 +114,12 @@ class TemplateComponentAnalyzer {
114
114
  pageConfig.component.settings.templateName) || defaultTemplateName;
115
115
  if ( templateName ) {
116
116
  const templateModuleName = fromUI5LegacyName( templateName, ".view.xml" );
117
- log.verbose("template app: add dependency to template view %s", templateModuleName);
117
+ log.verbose(`Template app: Add dependency to template view ${templateModuleName}`);
118
118
  appInfo.addDependency(templateModuleName);
119
119
  }
120
120
  } catch (err) {
121
121
  if (this._pool.getIgnoreMissingModules() && err.message.startsWith("resource not found in pool")) {
122
- log.verbose("Ignoring missing module as per ResourcePool configuration: " + err.message);
122
+ log.verbose(`Ignoring missing module as per ResourcePool configuration: ${err.message}`);
123
123
  } else {
124
124
  throw err;
125
125
  }
@@ -43,7 +43,7 @@ class XMLCompositeAnalyzer {
43
43
  }
44
44
  if (fragmentName) {
45
45
  const fragmentModule = fromUI5LegacyName(fragmentName, ".control.xml");
46
- log.verbose("fragment control: add dependency to template fragment %s", fragmentModule);
46
+ log.verbose(`Fragment control: Add dependency to template fragment ${fragmentModule}`);
47
47
  info.addDependency(fragmentModule);
48
48
  }
49
49
  }
@@ -206,7 +206,7 @@ class XMLTemplateAnalyzer {
206
206
  const resourceBundleName = getAttribute(node, XMLVIEW_RESBUNDLENAME_ATTRIBUTE);
207
207
  if ( resourceBundleName ) {
208
208
  const resourceBundleModuleName = fromUI5LegacyName(resourceBundleName, ".properties");
209
- log.verbose("found dependency to resource bundle %s", resourceBundleModuleName);
209
+ log.verbose(`Found dependency to resource bundle ${resourceBundleModuleName}`);
210
210
  // TODO locale dependent dependencies: this._addDependency(resourceBundleModuleName);
211
211
  this._addDependency( resourceBundleModuleName, this.conditional );
212
212
  }
@@ -269,9 +269,8 @@ class XMLTemplateAnalyzer {
269
269
  // e.g. "{= '{Handler: \'' + ${myActions > handlerModule} + '\'}'}"
270
270
  if ((coreRequire.startsWith("{=") || coreRequire.startsWith("{:=")) && this.templateTag) {
271
271
  log.verbose(
272
- `Ignoring core:require: '%s' on Node %s:%s contains ` +
273
- `an expression binding and is within a 'template' Node`,
274
- coreRequire, node.$ns.uri, node.$ns.local
272
+ `Ignoring core:require: '${coreRequire}' on Node ${node.$ns.uri}:${node.$ns.local} contains ` +
273
+ `an expression binding and is within a 'template' Node`
275
274
  );
276
275
  return;
277
276
  }
@@ -280,9 +279,10 @@ class XMLTemplateAnalyzer {
280
279
  requireContext = JSTokenizer.parseJS(coreRequire);
281
280
  } catch (e) {
282
281
  log.error(
283
- "Ignoring core:require: '%s' can't be parsed on Node %s:%s",
284
- coreRequire, node.$ns.uri, node.$ns.local
282
+ `Ignoring core:require: '${coreRequire}' can't be parsed on Node ` +
283
+ `${node.$ns.uri}:${node.$ns.local}: ${e.message}`
285
284
  );
285
+ log.verbose(e.stack);
286
286
  }
287
287
  if ( requireContext ) {
288
288
  Object.keys(requireContext).forEach((key) => {
@@ -82,8 +82,9 @@ class AutoSplitter {
82
82
  await Promise.all(promises);
83
83
 
84
84
  const partSize = Math.floor(totalSize / numberOfParts);
85
- log.verbose("total size of modules %d (chars), target size for each of the %d parts: %d (chars)",
86
- totalSize, numberOfParts, partSize);
85
+ log.verbose(
86
+ `Total size of modules ${totalSize} (chars), target size for each ` +
87
+ `of the ${numberOfParts} parts: ${partSize} (chars)`);
87
88
 
88
89
  // ---- create a separate module definition for each part
89
90
  const splittedModules = [];
@@ -184,7 +185,7 @@ class AutoSplitter {
184
185
  }
185
186
  });
186
187
 
187
- log.verbose("splitted modules: %s", splittedModules);
188
+ log.verbose(`Splitted modules: ${splittedModules}`);
188
189
  return splittedModules;
189
190
  }
190
191
 
@@ -98,10 +98,10 @@ class BundleBuilder {
98
98
  async _createBundle(module, options) {
99
99
  const resolvedModule = await this.resolver.resolve(module);
100
100
  if ( options.skipIfEmpty && isEmptyBundle(resolvedModule) ) {
101
- log.verbose(" skipping empty bundle " + module.name);
101
+ log.verbose(" Skipping empty bundle " + module.name);
102
102
  return undefined;
103
103
  }
104
- log.verbose(" create '%s'", resolvedModule.name);
104
+ log.verbose(` Create '${resolvedModule.name}'`);
105
105
 
106
106
  this.options = options || {};
107
107
  this.optimize = !!this.options.optimize;
@@ -131,8 +131,7 @@ class BundleBuilder {
131
131
  let bundleInfos = [];
132
132
  // create all sections in sequence
133
133
  for ( const section of resolvedModule.sections ) {
134
- log.verbose(" adding section%s of type %s",
135
- section.name ? " '" + section.name + "'" : "", section.mode);
134
+ log.verbose(` Adding section${section.name ? " '" + section.name + "'" : ""} of type ${section.mode}`);
136
135
  if ( section.mode === SectionType.BundleInfo ) {
137
136
  bundleInfos.push(section);
138
137
  } else {
@@ -253,8 +252,7 @@ class BundleBuilder {
253
252
  this.outW.writeln("//@ui5-bundle-raw-include " + moduleName);
254
253
  await this.writeRawModule(moduleName, resource);
255
254
  const compressedSize = this.outW.endSegment();
256
- log.verbose(" %s (%d,%d)", moduleName,
257
- resource.info != null ? resource.info.size : -1, compressedSize);
255
+ log.verbose(` ${moduleName} (${resource.info != null ? resource.info.size : -1},${compressedSize})`);
258
256
  if ( section.declareRawModules ) {
259
257
  this.missingRawDeclarations.push(moduleName);
260
258
  }
@@ -262,7 +260,7 @@ class BundleBuilder {
262
260
  this.jqglobalAvailable = true;
263
261
  }
264
262
  } else {
265
- log.error(" couldn't find %s", moduleName);
263
+ log.error(` Could not find module ${moduleName}`);
266
264
  }
267
265
  }
268
266
  }
@@ -308,11 +306,10 @@ class BundleBuilder {
308
306
  outW.startSegment(module);
309
307
  await this.writePreloadModule(module, resource.info, resource);
310
308
  const compressedSize = outW.endSegment();
311
- log.verbose(" %s (%d,%d)", module,
312
- resource.info != null ? resource.info.size : -1, compressedSize);
309
+ log.verbose(` ${module} (${resource.info != null ? resource.info.size : -1},${compressedSize})`);
313
310
  i++;
314
311
  } else {
315
- log.error(" couldn't find %s", module);
312
+ log.error(` Could not find module ${module}`);
316
313
  }
317
314
  }
318
315
 
@@ -387,8 +384,8 @@ class BundleBuilder {
387
384
  outW.write(moduleContent);
388
385
  outW.ensureNewLine();
389
386
  const compressedSize = outW.endSegment();
390
- log.verbose(" %s (%d,%d)", moduleName,
391
- resource.info != null ? resource.info.size : -1, compressedSize);
387
+ log.verbose(
388
+ ` ${moduleName} (${resource.info != null ? resource.info.size : -1},${compressedSize})`);
392
389
  } else {
393
390
  // keep unprocessed modules
394
391
  remaining.push(moduleName);
@@ -440,8 +437,8 @@ class BundleBuilder {
440
437
  outW.ensureNewLine();
441
438
  outW.write(`}`);
442
439
  } else if ( /\.js$/.test(moduleName) /* implicitly: && info != null && info.requiresTopLevelScope */ ) {
443
- log.warn("**** warning: module %s requires top level scope" +
444
- " and can only be embedded as a string (requires 'eval')", moduleName);
440
+ log.warn(
441
+ `Module ${moduleName} requires top level scope and can only be embedded as a string (requires 'eval')`);
445
442
  outW.write( makeStringLiteral( (await resource.buffer()).toString() ) );
446
443
  } else if ( /\.html$/.test(moduleName) ) {
447
444
  const fileContent = (await resource.buffer()).toString();
@@ -452,7 +449,7 @@ class BundleBuilder {
452
449
  try {
453
450
  fileContent = JSON.stringify( JSON.parse( fileContent) );
454
451
  } catch (e) {
455
- log.verbose("Failed to parse JSON file %s. Ignoring error, skipping compression.", moduleName);
452
+ log.verbose(`Failed to parse JSON file ${moduleName}. Ignoring error, skipping compression.`);
456
453
  log.verbose(e);
457
454
  }
458
455
  }
@@ -475,7 +472,7 @@ class BundleBuilder {
475
472
 
476
473
  outW.write( makeStringLiteral( fileContent ) );
477
474
  } else {
478
- log.error("don't know how to embed module " + moduleName); // TODO throw?
475
+ log.error("Don't know how to embed module " + moduleName); // TODO throw?
479
476
  }
480
477
 
481
478
  return true;
@@ -512,7 +509,7 @@ class BundleBuilder {
512
509
  throw new Error(`A 'bundleInfo' section is missing the mandatory 'name' property.` );
513
510
  }
514
511
  if (!path.extname(section.name)) {
515
- log.warn(`bundleInfo section name '${section.name}' is missing a file extension. ` +
512
+ log.warn(`BundleInfo section name '${section.name}' is missing a file extension. ` +
516
513
  `The info might not work as expected. ` +
517
514
  `The name must match the bundle filename (incl. extension such as '.js')`);
518
515
  }
@@ -636,7 +633,8 @@ async function rewriteDefine({moduleName, moduleContent, moduleSourceMap}) {
636
633
  try {
637
634
  ast = parseJS(moduleContent, {range: true});
638
635
  } catch (e) {
639
- log.error("error while parsing %s: %s", moduleName, e.message);
636
+ log.error(`Error while parsing ${moduleName}: ${e.message}`);
637
+ log.verbose(e.stack);
640
638
  return {};
641
639
  }
642
640
 
@@ -272,7 +272,7 @@ class BundleResolver {
272
272
 
273
273
  // NODE-TODO placeholderValues = vars;
274
274
 
275
- log.verbose(" resolving bundle definition %s", bundle.name);
275
+ log.verbose(` Resolving bundle definition ${bundle.name}`);
276
276
 
277
277
  const resolved = new ResolvedBundleDefinition(bundle /* , vars*/);
278
278
 
@@ -280,8 +280,8 @@ class BundleResolver {
280
280
 
281
281
  bundle.sections.forEach(function(section, index) {
282
282
  previous = previous.then( function() {
283
- log.verbose(" resolving section%s of type %s",
284
- section.name ? " '" + section.name + "'" : "", section.mode);
283
+ log.verbose(
284
+ ` Resolving section${section.name ? " '" + section.name + "'" : ""} of type ${section.mode}`);
285
285
 
286
286
  // NODE-TODO long t0=System.nanoTime();
287
287
  const resolvedSection = resolved.sections[index];
@@ -291,12 +291,12 @@ class BundleResolver {
291
291
  if ( section.mode == SectionType.Raw && section.sort !== false ) {
292
292
  // sort the modules in topological order
293
293
  return topologicalSort(pool, modules).then( (modules) => {
294
- log.silly(" resolved modules (sorted): %s", modules);
294
+ log.silly(` Resolved modules (sorted): ${modules}`);
295
295
  return modules;
296
296
  });
297
297
  }
298
298
 
299
- log.silly(" resolved modules: %s", modules);
299
+ log.silly(` Resolved modules: ${modules}`);
300
300
  return modules;
301
301
  }).then( function(modules) {
302
302
  resolvedSection.modules = modules;
@@ -315,7 +315,7 @@ class BundleResolver {
315
315
  // NODE-TODO if ( PerfMeasurement.ACTIVE ) PerfMeasurement.stop(PerfKeys.RESOLVE_MODULE);
316
316
 
317
317
  return previous.then( function() {
318
- log.verbose(" resolving bundle done");
318
+ log.verbose(" Resolving bundle done");
319
319
 
320
320
  return resolved;
321
321
  });
@@ -43,7 +43,7 @@ async function createDependencyGraph(pool, roots, options) {
43
43
  });
44
44
  return Promise.all(p);
45
45
  }, (err) => {
46
- log.error("module %s not found in pool:", name, err);
46
+ log.error(`Module ${name} not found in pool: ${err.message}`);
47
47
  }).then( () => node );
48
48
  }
49
49
 
@@ -28,7 +28,7 @@ function calculateDominatorTree({n0, nodes}) {
28
28
  }
29
29
  }
30
30
 
31
- log.verbose("%d modules found, starting dominator tree calculation", nodes.size - 1);
31
+ log.verbose(`${nodes.size - 1} modules found, starting dominator tree calculation`);
32
32
 
33
33
  function countEdges(nodes) {
34
34
  let count = 0;
@@ -43,7 +43,9 @@ function calculateDominatorTree({n0, nodes}) {
43
43
  do {
44
44
  // while changes in any Dom(n)
45
45
 
46
- log.verbose("%d remaining edges", countEdges(nodes));
46
+ if (log.isLevelEnabled("verbose")) {
47
+ log.verbose(`${countEdges(nodes)} remaining edges`);
48
+ }
47
49
 
48
50
  modified = false;
49
51
  for ( const n of nodes.values() ) {
@@ -81,7 +83,7 @@ function calculateDominatorTree({n0, nodes}) {
81
83
  n.visited = false;
82
84
  }
83
85
 
84
- log.verbose("reduce dominator graph to immediate dominator tree");
86
+ log.verbose("Reduce dominator graph to immediate dominator tree");
85
87
 
86
88
  // use DFS to reduce the dominator graph to the (immediate) dominator tree
87
89
  //
@@ -108,7 +110,7 @@ function calculateDominatorTree({n0, nodes}) {
108
110
  }
109
111
  dfs(n0);
110
112
 
111
- log.verbose("calculation of dominator tree done");
113
+ log.verbose("Calculation of dominator tree done");
112
114
 
113
115
  return n0;
114
116
  }
@@ -70,7 +70,7 @@ function createDependencyGraph(pool, moduleNames, indegreeOnly) {
70
70
  });
71
71
  return Promise.all(p);
72
72
  }, (err) => {
73
- log.error("module %s not found in pool", moduleName);
73
+ log.error(`Module ${moduleName} not found in pool`);
74
74
  });
75
75
  });
76
76
 
@@ -119,7 +119,7 @@ function topologicalSort(pool, moduleNames) {
119
119
  dependent.outgoing.splice(index, 1);
120
120
  // console.log("removing outgoing %s in %s", node.name, dependent.name);
121
121
  } else {
122
- log.error("**** could not find node %s in %s", node.name, dependent.name);
122
+ log.error(`**** Could not find node ${node.name} in ${dependent.name}`);
123
123
  }
124
124
  });
125
125
  }
@@ -177,7 +177,7 @@ function topologicalSort(pool, moduleNames) {
177
177
  Object.keys(graph)
178
178
  .filter((name) => moduleNames.indexOf(name) < l)
179
179
  .map((name) => graph[name].toString()));
180
- throw new Error("failed to resolve cyclic dependencies: " + moduleNames.slice(0, l) );
180
+ throw new Error("Failed to resolve cyclic dependencies: " + moduleNames.slice(0, l).join(", ") );
181
181
  // NODE-TODO use new CycleFinder(graph).toString() for easier to understand output
182
182
  }
183
183
 
@@ -64,7 +64,7 @@ export function getDependencyInfos( name, content ) {
64
64
  moduleInfos["raw-module"] && moduleInfos["raw-module"].forEach( (rawModule) => {
65
65
  const rawInfo = createRawInfo(rawModule);
66
66
  if ( rawInfo ) {
67
- log.verbose(name + " rawInfo:", JSON.stringify(rawInfo));
67
+ log.verbose(name + " rawInfo: " + JSON.stringify(rawInfo));
68
68
  infos[rawInfo.name] = rawInfo;
69
69
  }
70
70
  });
@@ -80,7 +80,7 @@ class ResourceCollector {
80
80
  async visitResource(resource) {
81
81
  const virPath = resource.getPath();
82
82
  if ( !virPath.startsWith("/resources/") ) {
83
- log.warn(`non-runtime resource ${virPath} ignored`);
83
+ log.warn(`Non-runtime resource ${virPath} ignored`);
84
84
  return;
85
85
  }
86
86
  const name = virPath.slice("/resources/".length);
@@ -102,7 +102,7 @@ class ResourceCollector {
102
102
  // .theming files are not always present therefore this check is relevant for the library.source.less
103
103
  if ( name.match("(?:[^/]+/)*themes/[^/]+/(?:\\.theming|library\\.source\\.less)") &&
104
104
  !this._themePackages.has(prefix) ) {
105
- // log.info("found new theme package %s", prefix);
105
+ // log.info("Found new theme package %s", prefix);
106
106
  this._themePackages.set(prefix, new ResourceInfoList(prefix));
107
107
  }
108
108
  }
@@ -141,7 +141,7 @@ class ResourceCollector {
141
141
  try {
142
142
  subModuleInfo = await this._pool.getModuleInfo(subModule);
143
143
  } catch (err) {
144
- log.verbose(` missing submodule ${subModule} included by ${moduleInfo.name}`);
144
+ log.verbose(` Missing submodule ${subModule} included by ${moduleInfo.name}`);
145
145
  }
146
146
  if (subModuleInfo) {
147
147
  // Inherit subModule dependencies
@@ -207,14 +207,14 @@ class ResourceCollector {
207
207
  for (const [name, info] of this._resources.entries()) {
208
208
  if ( debugFilter.matches(name) ) {
209
209
  info.isDebug = true;
210
- log.verbose(` found potential debug resource '${name}'`);
210
+ log.verbose(` Found potential debug resource '${name}'`);
211
211
  }
212
212
 
213
213
  // log.verbose(` checking ${name}`);
214
214
  let m;
215
215
  if ( m = LOCALE.exec(name) ) {
216
216
  const baseName = m[1] + m[3];
217
- log.verbose(` found potential i18n resource '${name}', base name is '${baseName}', locale is ${m[2]}`);
217
+ log.verbose(` Found potential i18n resource '${name}', base name is '${baseName}', locale is ${m[2]}`);
218
218
  info.i18nName = baseName; // e.g. "i18n.properties"
219
219
  info.i18nLocale = m[2]; // e.g. "de"
220
220
  baseNames.add(baseName);
@@ -225,7 +225,7 @@ class ResourceCollector {
225
225
  if ( this._themePackages.has(m[0]) ) {
226
226
  const theme = m[2];
227
227
  info.theme = theme;
228
- log.verbose(` found potential theme resource '${name}', theme ${theme}`);
228
+ log.verbose(` Found potential theme resource '${name}', theme ${theme}`);
229
229
  }
230
230
  }
231
231
 
@@ -255,17 +255,17 @@ class ResourceCollector {
255
255
 
256
256
  if ( mergeFilter.matches(name) ) {
257
257
  info.merged = true;
258
- log.verbose(` found potential merged resource '${name}'`);
258
+ log.verbose(` Found potential merged resource '${name}'`);
259
259
  }
260
260
 
261
261
  if ( designtimeFilter.matches(name) ) {
262
262
  info.designtime = true;
263
- log.verbose(` found potential designtime resource '${name}'`);
263
+ log.verbose(` Found potential designtime resource '${name}'`);
264
264
  }
265
265
 
266
266
  if ( supportFilter.matches(name) ) {
267
267
  info.support = true;
268
- log.verbose(` found potential support resource '${name}'`);
268
+ log.verbose(` Found potential support resource '${name}'`);
269
269
  }
270
270
  }
271
271
 
@@ -320,7 +320,7 @@ class ResourceCollector {
320
320
 
321
321
  createOrphanFilters() {
322
322
  log.verbose(
323
- ` configured external resources filters (resources outside the namespace): ` +
323
+ ` Configured external resources filters (resources outside the namespace): ` +
324
324
  `${this._externalResources == null ? "(none)" : this._externalResources}`);
325
325
 
326
326
  const filtersByComponent = new Map();
@@ -333,7 +333,7 @@ class ResourceCollector {
333
333
  } else if ( !component.endsWith("/") ) {
334
334
  component += "/";
335
335
  }
336
- log.verbose(` resulting filter list for '${component}': '${packageFilters}'`);
336
+ log.verbose(` Resulting filter list for '${component}': '${packageFilters}'`);
337
337
  filtersByComponent.set(component, packageFilters);
338
338
  }
339
339
  }
@@ -100,7 +100,7 @@ export default class ResourceFilterList {
100
100
  this.matchers = [];
101
101
  this.matchByDefault = true;
102
102
  this.fileTypes = makeFileTypePattern(fileTypes);
103
- log.verbose(`filetypes: ${fileTypes}`);
103
+ log.verbose(`Filetypes: ${fileTypes}`);
104
104
  this.addFilters(filters);
105
105
  }
106
106
 
@@ -63,14 +63,16 @@ async function determineDependencyInfo(resource, rawInfo, pool) {
63
63
  try {
64
64
  ast = parseJS(code, {comment: true});
65
65
  } catch (err) {
66
- log.error("failed to parse %s: %s", resource.name, err.message);
66
+ log.error(`Failed to parse ${resource.name}: ${err.message}`);
67
+ log.verbose(err.stack);
67
68
  }
68
69
  if (ast) {
69
70
  try {
70
71
  jsAnalyzer.analyze(ast, resource.name, info);
71
72
  new XMLCompositeAnalyzer(pool).analyze(ast, resource.name, info);
72
73
  } catch (error) {
73
- log.error("failed to analyze %s: %s", resource.name, error.stack);
74
+ log.error(`Failed to analyze ${resource.name}: ${error.message}`);
75
+ log.verbose(error.stack);
74
76
  }
75
77
  }
76
78
  if ( rawInfo ) {
@@ -149,7 +151,7 @@ class ResourcePool {
149
151
  */
150
152
  addResource( resource ) {
151
153
  if ( this._resourcesByName.has(resource.name) ) {
152
- log.warn("duplicate resource " + resource.name);
154
+ log.warn("Duplicate resource " + resource.name);
153
155
  // TODO return and let the first one always win?
154
156
  }
155
157
 
@@ -1855,7 +1855,7 @@ class TypeStringBuilder {
1855
1855
  }
1856
1856
 
1857
1857
  function TypeParser(defaultBuilder = new ASTBuilder()) {
1858
- const rLexer = /\s*(Array\.?<|Object\.?<|Set\.?<|Promise\.?<|function\(|\{|:|\(|\||\}|\.?<|>|\)|,|\[\]|\*|\?|!|=|\.\.\.)|\s*(false|true|(?:\+|-)?(?:\d+(?:\.\d+)?|NaN|Infinity)|'[^']*'|"[^"]*"|null|undefined)|\s*((?:module:)?\w+(?:[/.#~]\w+)*)|./g;
1858
+ const rLexer = /\s*(Array\.?<|Object\.?<|Set\.?<|Promise\.?<|function\(|\{|:|\(|\||\}|\.?<|>|\)|,|\[\]|\*|\?|!|=|\.\.\.)|\s*(false|true|(?:\+|-)?(?:\d+(?:\.\d+)?|NaN|Infinity)|'[^']*'|"[^"]*"|null|undefined)|\s*((?:module:)?\w+(?:[/.#~][$\w_]+)*)|./g;
1859
1859
 
1860
1860
  let input;
1861
1861
  let builder;
@@ -2392,6 +2392,24 @@ function createAPIJSON4Symbol(symbol, omitDefaults) {
2392
2392
 
2393
2393
  }
2394
2394
 
2395
+ function writeModuleInfo(member, symbol) {
2396
+ // write out resource, module and export only when the module is different from the module of the parent entity
2397
+ // and when the member was not cloned (e.g. because it is borrowed)
2398
+ var isBorrowed = member.__ui5.initialLongname !== member.longname;
2399
+
2400
+ if ( member.__ui5.resource
2401
+ && member.__ui5.resource !== symbol.__ui5.resource
2402
+ && !isBorrowed ) {
2403
+ attrib("resource", member.__ui5.resource);
2404
+ }
2405
+ if ( member.__ui5.module
2406
+ && member.__ui5.module !== symbol.__ui5.module
2407
+ && !isBorrowed ) {
2408
+ attrib("module", member.__ui5.module);
2409
+ attrib("export", member.__ui5.globalOnly ? GLOBAL_ONLY : member.__ui5.export, '', true);
2410
+ }
2411
+ }
2412
+
2395
2413
  function examples(symbol) {
2396
2414
  if ( symbol.examples && symbol.examples.length ) {
2397
2415
  collection("examples");
@@ -2877,14 +2895,7 @@ function createAPIJSON4Symbol(symbol, omitDefaults) {
2877
2895
  }
2878
2896
  tag("method");
2879
2897
  attrib("name", name || member.name);
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 ) {
2885
- attrib("module", member.__ui5.module);
2886
- attrib("export", member.__ui5.globalOnly ? GLOBAL_ONLY : member.__ui5.export, '', true);
2887
- }
2898
+ writeModuleInfo(member, symbol);
2888
2899
  attrib("visibility", visibility(member), 'public');
2889
2900
  if ( stakeholders(member) ) {
2890
2901
  stakeholderList("allowedFor", stakeholders(member));
@@ -2911,9 +2922,6 @@ function createAPIJSON4Symbol(symbol, omitDefaults) {
2911
2922
  attrib("tsSkip", true, false, /* raw = */true);
2912
2923
  }
2913
2924
  //secTags(member);
2914
- if ( member.__ui5.resource && member.__ui5.resource !== symbol.__ui5.resource ) {
2915
- attrib("resource", member.__ui5.resource);
2916
- }
2917
2925
  closeTag("method");
2918
2926
 
2919
2927
  }
@@ -3067,6 +3075,12 @@ function createAPIJSON4Symbol(symbol, omitDefaults) {
3067
3075
  if ( symbol.params || symbol.returns || symbol.exceptions ) {
3068
3076
  methodSignature(symbol);
3069
3077
  } else if ( symbol.properties && symbol.properties.length > 0 ) {
3078
+ if ( symbol.type ) { // "type" of a typedef defines its inheritance base
3079
+ const type = listTypes(symbol.type);
3080
+ if ( type.toLowerCase() !== "object" ) {
3081
+ attrib("extends", type);
3082
+ }
3083
+ }
3070
3084
  collection("properties");
3071
3085
  symbol.properties.forEach((prop) => {
3072
3086
  if ( prop.name.indexOf('.') >= 0 ) {
@@ -3108,10 +3122,7 @@ function createAPIJSON4Symbol(symbol, omitDefaults) {
3108
3122
  const member = ownProperties[i];
3109
3123
  tag("property");
3110
3124
  attrib("name", member.name);
3111
- if ( member.__ui5.module && member.__ui5.module !== symbol.__ui5.module ) {
3112
- attrib("module", member.__ui5.module);
3113
- attrib("export", member.__ui5.globalOnly ? GLOBAL_ONLY : member.__ui5.export, '', true);
3114
- }
3125
+ writeModuleInfo(member, symbol);
3115
3126
  if ( kind === 'enum' && !standardEnum && member.__ui5.value !== undefined ) {
3116
3127
  attrib("value", member.__ui5.value, undefined, /* raw = */true);
3117
3128
  }
@@ -3132,9 +3143,6 @@ function createAPIJSON4Symbol(symbol, omitDefaults) {
3132
3143
  if ( member.__ui5.tsSkip ) {
3133
3144
  attrib("tsSkip", true, false, /* raw = */true);
3134
3145
  }
3135
- if ( member.__ui5.resource && member.__ui5.resource !== symbol.__ui5.resource ) {
3136
- attrib("resource", member.__ui5.resource);
3137
- }
3138
3146
  closeTag("property");
3139
3147
  }
3140
3148
  endCollection("properties");
@@ -3147,10 +3155,7 @@ function createAPIJSON4Symbol(symbol, omitDefaults) {
3147
3155
  const member = ownEvents[i];
3148
3156
  tag("event");
3149
3157
  attrib("name", member.name);
3150
- if ( member.__ui5.module && member.__ui5.module !== symbol.__ui5.module ) {
3151
- attrib("module", member.__ui5.module);
3152
- attrib("export", member.__ui5.globalOnly ? GLOBAL_ONLY : member.__ui5.export, '', true);
3153
- }
3158
+ writeModuleInfo(member, symbol);
3154
3159
  attrib("visibility", visibility(member), 'public');
3155
3160
  if ( stakeholders(member) ) {
3156
3161
  stakeholderList("allowedFor", stakeholders(member));
@@ -3188,9 +3193,6 @@ function createAPIJSON4Symbol(symbol, omitDefaults) {
3188
3193
  examples(member);
3189
3194
  referencesList(member);
3190
3195
  //secTags(member);
3191
- if ( member.__ui5.resource && member.__ui5.resource !== symbol.__ui5.resource ) {
3192
- attrib("resource", member.__ui5.resource);
3193
- }
3194
3196
  closeTag("event");
3195
3197
  }
3196
3198
  endCollection("events");
@@ -3341,6 +3343,11 @@ function postProcessAPIJSON(api) {
3341
3343
  debug(`could not identify export name of ${symbol.symbol.kind} '${symbol.name}', contained in module '${moduleName}'`);
3342
3344
  }
3343
3345
  }
3346
+ if ( symbol.symbol.kind === "namespace" && symbol.symbol.export === undefined ) {
3347
+ // if no export could be identified for a namespace, don't annotate the namespace with a module
3348
+ symbol.symbol.resource =
3349
+ symbol.symbol.module = undefined;
3350
+ }
3344
3351
  });
3345
3352
 
3346
3353
  }
@@ -193,7 +193,7 @@ async function createManifest(
193
193
 
194
194
  const manifestResource = libBundle.findResource(manifestPath.substring(libraryPathPrefix.length));
195
195
  if ( manifestResource == null ) {
196
- log.verbose(" component has no accompanying manifest.json, don't list it as 'embedded'");
196
+ log.verbose(" Component has no accompanying manifest.json, don't list it as 'embedded'");
197
197
  return false;
198
198
  }
199
199
  return true;
@@ -204,19 +204,19 @@ async function createManifest(
204
204
  const components = libBundle.getResources(/^\/(?:[^/]+\/)*Component\.js$/);
205
205
  for (const comp of components) {
206
206
  const componentPath = posixPath.dirname(comp.getPath());
207
- log.verbose("checking component at %s", componentPath);
207
+ log.verbose(`Checking component at ${componentPath}`);
208
208
  if ( componentPath.startsWith(libraryPathPrefix) && hasManifest(componentPath) ) {
209
209
  result.push( componentPath.substring(libraryPathPrefix.length) );
210
210
  } else if ( libraryPathPrefix === "/resources/sap/apf/" ) {
211
- log.verbose("Package %s contains both '*.library' and 'Component.js'. " +
212
- "This is a known issue but can't be solved due to backward compatibility.", componentPath);
211
+ log.verbose(`Package ${componentPath} contains both '*.library' and 'Component.js'. ` +
212
+ `This is a known issue but can't be solved due to backward compatibility.`);
213
213
  } else if (
214
214
  libraryPathPrefix === (componentPath + "/") &&
215
215
  libraryPathPrefix !== "/resources/sap/ui/core/"
216
216
  ) {
217
- log.error("Package %s contains both '*.library' and 'Component.js'. " +
218
- "This is not supported by manifests, therefore the component won't be " +
219
- "listed in the library's manifest.", componentPath);
217
+ log.error(`Package ${componentPath} contains both '*.library' and 'Component.js'. ` +
218
+ `This is not supported by manifests, therefore the component won't be ` +
219
+ `listed in the library's manifest.`);
220
220
  }
221
221
  }
222
222
  return result.sort();
@@ -308,7 +308,7 @@ async function createManifest(
308
308
  let i18n;
309
309
  if (typeof i18nText === "string") {
310
310
  i18n = createI18nSection(i18nText, i18nToSupportedLocales);
311
- log.verbose(`sap.app/i18n taken from .library appData: '%s'`, i18nText);
311
+ log.verbose(`sap.app/i18n taken from .library appData: '${i18nText}'`);
312
312
  }
313
313
  const sapApp = {
314
314
  _version: sectionVersion(APP_DESCRIPTOR_V3_SECTION_SAP_APP),
@@ -328,10 +328,10 @@ async function createManifest(
328
328
  openSourceComponents: openSourceComponents()
329
329
  };
330
330
 
331
- log.verbose(" sap.app/id taken from .library: '%s'", sapApp.id);
332
- log.verbose(" sap.app/embeds determined from resources: '%s'", sapApp.embeds);
333
- log.verbose(" sap.app/i18n taken from .library appData: '%s'", sapApp.i18n);
334
- log.verbose(" sap.app/ach taken from .library appData/ownership: '%s'", sapApp.ach);
331
+ log.verbose(` sap.app/id taken from .library: '${sapApp.id}'`);
332
+ log.verbose(` sap.app/embeds determined from resources:`, sapApp.embeds);
333
+ log.verbose(` sap.app/i18n taken from .library appData:`, sapApp.i18n);
334
+ log.verbose(` sap.app/ach taken from .library appData/ownership: '${sapApp.ach}'`);
335
335
 
336
336
  return sapApp;
337
337
  }
@@ -382,7 +382,7 @@ async function createManifest(
382
382
  supportedThemes: collectThemes()
383
383
  };
384
384
 
385
- log.verbose(" sap.ui/supportedThemes determined from resources: '%s'", sapUi.supportedThemes);
385
+ log.verbose(` sap.ui/supportedThemes determined from resources: '${sapUi.supportedThemes.join(", ")}'`);
386
386
 
387
387
  return sapUi;
388
388
  }
@@ -406,7 +406,7 @@ async function createManifest(
406
406
  };
407
407
  }
408
408
  }
409
- log.verbose(" sap.ui5/dependencies/libs determined from .library dependencies: '%s'", dependencies.libs);
409
+ log.verbose(` sap.ui5/dependencies/libs determined from .library dependencies:`, dependencies.libs);
410
410
  return dependencies;
411
411
  }
412
412
 
@@ -417,18 +417,17 @@ async function createManifest(
417
417
  cozy: getBooleanAttribute(contentDensitiesElement, "cozy"),
418
418
  compact: getBooleanAttribute(contentDensitiesElement, "compact")
419
419
  };
420
- log.verbose(" sap.ui5/contentDensities property taken from .library appData: '%s'", contentDensities);
420
+ log.verbose(` sap.ui5/contentDensities property taken from .library appData:`, contentDensities);
421
421
  return contentDensities;
422
422
  }
423
423
  }
424
424
 
425
425
  function createLibraryMetadata() {
426
426
  if ( descriptorVersion.compare(APP_DESCRIPTOR_V10) < 0 ) {
427
- log.verbose(" target descriptor version %s: skipping sap.ui5/library information",
428
- descriptorVersion);
427
+ log.verbose(` Target descriptor version ${descriptorVersion}: skipping sap.ui5/library information`);
429
428
  }
430
429
 
431
- log.verbose(" target descriptor version %s: include sap.ui5/library information", descriptorVersion);
430
+ log.verbose(` Target descriptor version ${descriptorVersion}: include sap.ui5/library information`);
432
431
 
433
432
  const sapUi5AppData = findChild(manifestAppData, "sap.ui5");
434
433
  const libraryAppData = findChild(sapUi5AppData, "library");
@@ -465,11 +464,11 @@ async function createManifest(
465
464
  if ( cssElement != null ) {
466
465
  const css = cssElement._;
467
466
  if ( css === "false" ) {
468
- log.verbose(" sap.ui5/library/css property taken from .library appData: '%s'", false);
467
+ log.verbose(` sap.ui5/library/css property taken from .library appData: 'false'`);
469
468
  return false;
470
469
  }
471
470
  } else if ( libraryJSInfo.noLibraryCSS ) {
472
- log.verbose(" sap.ui5/library/css property extracted from library.js: '%s'", false);
471
+ log.verbose(` sap.ui5/library/css property extracted from library.js: 'false'`);
473
472
  return false;
474
473
  }
475
474
  }
@@ -624,7 +623,7 @@ async function createManifest(
624
623
  export default function({libraryResource, resources, getProjectVersion, options}) {
625
624
  // merge options with defaults
626
625
  options = Object.assign({
627
- descriptorVersion: APP_DESCRIPTOR_V22, // TODO 3.0: change this to type string instead of a semver object
626
+ descriptorVersion: APP_DESCRIPTOR_V22.toString(),
628
627
  include3rdParty: true,
629
628
  prettyPrint: true,
630
629
  omitMinVersions: false
@@ -636,11 +635,11 @@ export default function({libraryResource, resources, getProjectVersion, options}
636
635
  // check whether a manifest exists already
637
636
  const manifestResource = libBundle.findResource("manifest.json");
638
637
  if ( manifestResource != null ) {
639
- log.verbose("Library manifest already exists at '%s', skipping generation", manifestResource.getPath());
638
+ log.verbose(`Library manifest already exists at '${manifestResource.getPath()}', skipping generation`);
640
639
  return Promise.resolve(null); // a fulfillment of null indicates that no manifest has been created
641
640
  }
642
641
 
643
- return createManifest(libraryResource, libBundle, options.descriptorVersion, options.include3rdParty,
642
+ return createManifest(libraryResource, libBundle, new Version(options.descriptorVersion), options.include3rdParty,
644
643
  options.omitMinVersions, getProjectVersion)
645
644
  .then((manifest) => {
646
645
  return new Resource({
@@ -138,7 +138,7 @@ export default async function({resources, dependencyResources = [], options}) {
138
138
  const visitPromises = resources.map((resource) => collector.visitResource(resource));
139
139
 
140
140
  await Promise.all(visitPromises);
141
- log.verbose(` found ${collector.resources.size} resources`);
141
+ log.verbose(` Found ${collector.resources.size} resources`);
142
142
 
143
143
  // determine additional information for the found resources
144
144
  if ( options && options.externalResources ) {
@@ -159,7 +159,7 @@ export default async function({resources, dependencyResources = [], options}) {
159
159
 
160
160
  // write out resources.json files
161
161
  for (const [prefix, list] of collector.components.entries()) {
162
- log.verbose(` writing '${prefix}resources.json'`);
162
+ log.verbose(` Writing '${prefix}resources.json'`);
163
163
 
164
164
  const contentString = makeResourcesJSON(list, prefix);
165
165
 
@@ -169,7 +169,7 @@ export default async function({resources, dependencyResources = [], options}) {
169
169
  }));
170
170
  }
171
171
  for (const [prefix, list] of collector.themePackages.entries()) {
172
- log.verbose(` writing '${prefix}resources.json'`);
172
+ log.verbose(` Writing '${prefix}resources.json'`);
173
173
 
174
174
  const contentString = makeResourcesJSON(list, prefix);
175
175
 
@@ -45,7 +45,7 @@ export class ThemeBuilder {
45
45
  const files = [];
46
46
 
47
47
  const compile = (resource) => {
48
- log.verbose("Compiling %s", resource.getPath());
48
+ log.verbose(`Compiling ${resource.getPath()}`);
49
49
 
50
50
  let libraryName;
51
51
  const libraryMatch = libraryMatchPattern.exec(resource.getPath());
@@ -101,20 +101,19 @@ const processManifest = async (manifestResource) => {
101
101
  */
102
102
  const isBundledWithLibrary = (embeddedBy, componentPath, libraryPathPrefix) => {
103
103
  if (typeof embeddedBy === "undefined") {
104
- log.verbose(" component doesn't declare 'sap.app/embeddedBy', don't list it as 'embedded'");
104
+ log.verbose(" Component doesn't declare 'sap.app/embeddedBy', don't list it as 'embedded'");
105
105
  return false;
106
106
  }
107
107
  if (typeof embeddedBy !== "string") {
108
108
  log.error(
109
- " component '%s': property 'sap.app/embeddedBy' is of type '%s' (expected 'string'), " +
110
- "it won't be listed as 'embedded'", componentPath, typeof embeddedBy
111
- );
109
+ ` Component '${componentPath}': property 'sap.app/embeddedBy' is of type '${typeof embeddedBy}' ` +
110
+ `(expected 'string'), it won't be listed as 'embedded'`);
112
111
  return false;
113
112
  }
114
113
  if ( !embeddedBy.length ) {
115
114
  log.error(
116
- " component '%s': property 'sap.app/embeddedBy' has an empty string value (which is invalid), " +
117
- "it won't be listed as 'embedded'", componentPath
115
+ ` Component '${componentPath}': property 'sap.app/embeddedBy' has an empty string value ` +
116
+ `(which is invalid), it won't be listed as 'embedded'`
118
117
  );
119
118
  return false;
120
119
  }
@@ -123,12 +122,11 @@ const isBundledWithLibrary = (embeddedBy, componentPath, libraryPathPrefix) => {
123
122
  resolvedEmbeddedBy = resolvedEmbeddedBy + "/";
124
123
  }
125
124
  if ( libraryPathPrefix === resolvedEmbeddedBy ) {
126
- log.verbose(" component's 'sap.app/embeddedBy' property points to library, list it as 'embedded'");
125
+ log.verbose(" Component's 'sap.app/embeddedBy' property points to library, list it as 'embedded'");
127
126
  return true;
128
127
  } else {
129
128
  log.verbose(
130
- " component's 'sap.app/embeddedBy' points to '%s', don't list it as 'embedded'", resolvedEmbeddedBy
131
- );
129
+ ` Component's 'sap.app/embeddedBy' points to '${resolvedEmbeddedBy}', don't list it as 'embedded'`);
132
130
  return false;
133
131
  }
134
132
  };
@@ -1,3 +1,18 @@
1
+ import {createRequire} from "node:module";
2
+
3
+ /**
4
+ * Repository providing access to all UI5 Builder tasks and various metadata required by the build process.
5
+ * This module is designed to be imported by @ui5/project or to be passed as a private parameter
6
+ * to the <code>build</code> function of a [@ui5/project/graph/ProjectGraph]{@link @ui5/project/graph/ProjectGraph}.
7
+ *
8
+ * For other use cases, it is recommended to import the required tasks directly.
9
+ *
10
+ * Therefore, all API of this module is private.
11
+ *
12
+ * @private
13
+ * @module @ui5/builder/tasks/taskRepository
14
+ */
15
+
1
16
  const taskInfos = {
2
17
  replaceCopyright: {path: "./replaceCopyright.js"},
3
18
  replaceVersion: {path: "./replaceVersion.js"},
@@ -21,11 +36,29 @@ const taskInfos = {
21
36
  generateCachebusterInfo: {path: "./generateCachebusterInfo.js"}
22
37
  };
23
38
 
39
+
40
+ /**
41
+ * TaskInfo object returned by the getTask function
42
+ *
43
+ * @private
44
+ * @typedef {object} @ui5/builder/tasks/taskRepository~TaskInfo
45
+ * @property {Function} task Task function
46
+ */
47
+
48
+ /**
49
+ * Returns the module for a given task name
50
+ *
51
+ * @private
52
+ * @static
53
+ * @param {string} taskName Name of the task to retrieve
54
+ * @throws {Error} In case the specified task does not exist
55
+ * @returns {Promise<@ui5/builder/tasks/taskRepository~TaskInfo>} Object containing the task module
56
+ */
24
57
  export async function getTask(taskName) {
25
58
  const taskInfo = taskInfos[taskName];
26
59
 
27
60
  if (!taskInfo) {
28
- if (["createDebugFiles", "uglify", "generateManifestBundle"].includes(taskName)) {
61
+ if (getRemovedTaskNames().includes(taskName)) {
29
62
  throw new Error(
30
63
  `Standard task ${taskName} has been removed in UI5 Tooling 3.0. ` +
31
64
  `Please see the migration guide at https://sap.github.io/ui5-tooling/updates/migrate-v3/`);
@@ -42,6 +75,54 @@ export async function getTask(taskName) {
42
75
  }
43
76
  }
44
77
 
78
+ /**
79
+ * Returns a list of the names of all available tasks
80
+ *
81
+ * @private
82
+ * @static
83
+ * @returns {string[]} Array containing the names of all available tasks
84
+ */
45
85
  export function getAllTaskNames() {
46
86
  return Object.keys(taskInfos);
47
87
  }
88
+
89
+ /**
90
+ * Returns a list of the names of all tasks that have been removed
91
+ * in this or previous versions of ui5-builder.
92
+ *
93
+ * @private
94
+ * @static
95
+ * @returns {string[]} Array containing the names of all removed tasks
96
+ */
97
+ export function getRemovedTaskNames() {
98
+ return ["createDebugFiles", "uglify", "generateManifestBundle"];
99
+ }
100
+
101
+ // Using CommonsJS require as importing json files causes an ExperimentalWarning
102
+ const require = createRequire(import.meta.url);
103
+ function getVersion(pkg) {
104
+ return require(`${pkg}/package.json`).version;
105
+ }
106
+
107
+ /**
108
+ * Object containing the versions of the ui5-builder module and relevant dependencies
109
+ *
110
+ * @private
111
+ * @typedef {object} @ui5/builder/tasks/taskRepository~Versions
112
+ * @property {string} builderVersion Version of the ui5-builder module
113
+ * @property {string} fsVersion Version of the ui5-fs module in use
114
+ */
115
+
116
+ /**
117
+ * Provides version information on all relevant modules, used by ui5-builder
118
+ *
119
+ * @private
120
+ * @static
121
+ * @returns {@ui5/builder/tasks/taskRepository~Versions} Object containing version information
122
+ */
123
+ export async function getVersions() {
124
+ return {
125
+ builderVersion: getVersion("@ui5/builder"),
126
+ fsVersion: getVersion("@ui5/fs"),
127
+ };
128
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ui5/builder",
3
- "version": "3.0.0-beta.5",
3
+ "version": "3.0.0-rc.0",
4
4
  "description": "UI5 Tooling - Builder",
5
5
  "author": {
6
6
  "name": "SAP SE",
@@ -119,8 +119,8 @@
119
119
  },
120
120
  "dependencies": {
121
121
  "@jridgewell/sourcemap-codec": "^1.4.14",
122
- "@ui5/fs": "^3.0.0-beta.4",
123
- "@ui5/logger": "^3.0.1-beta.1",
122
+ "@ui5/fs": "^3.0.0-rc.0",
123
+ "@ui5/logger": "^3.0.1-rc.0",
124
124
  "cheerio": "1.0.0-rc.12",
125
125
  "escape-unicode": "^0.2.0",
126
126
  "escope": "^4.0.0",
@@ -137,7 +137,7 @@
137
137
  },
138
138
  "devDependencies": {
139
139
  "@istanbuljs/esm-loader-hook": "^0.2.0",
140
- "@ui5/project": "^3.0.0-beta.4",
140
+ "@ui5/project": "^3.0.0-beta.5",
141
141
  "ava": "^5.1.0",
142
142
  "chai": "^4.3.7",
143
143
  "chai-fs": "^2.0.0",
@@ -145,7 +145,7 @@
145
145
  "cross-env": "^7.0.3",
146
146
  "depcheck": "^1.4.3",
147
147
  "docdash": "^2.0.0",
148
- "eslint": "^8.29.0",
148
+ "eslint": "^8.30.0",
149
149
  "eslint-config-google": "^0.14.0",
150
150
  "eslint-plugin-ava": "^13.2.0",
151
151
  "eslint-plugin-jsdoc": "^39.6.4",
@@ -153,7 +153,7 @@
153
153
  "nyc": "^15.1.0",
154
154
  "open-cli": "^7.1.0",
155
155
  "recursive-readdir": "^2.2.3",
156
- "sinon": "^15.0.0",
156
+ "sinon": "^15.0.1",
157
157
  "tap-nyan": "^1.1.0",
158
158
  "tap-xunit": "^2.4.1"
159
159
  }