@ui5/webcomponents-tools 2.20.0-rc.2 → 2.20.0-rc.3

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,14 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [2.20.0-rc.3](https://github.com/UI5/webcomponents/compare/v2.20.0-rc.2...v2.20.0-rc.3) (2026-03-05)
7
+
8
+ **Note:** Version bump only for package @ui5/webcomponents-tools
9
+
10
+
11
+
12
+
13
+
6
14
  # [2.20.0-rc.2](https://github.com/UI5/webcomponents/compare/v2.20.0-rc.1...v2.20.0-rc.2) (2026-02-26)
7
15
 
8
16
 
@@ -68,7 +68,7 @@ const getScripts = (options) => {
68
68
 
69
69
  const scripts = {
70
70
  __ui5envs: {
71
- UI5_CEM_MODE: options.dev,
71
+ UI5_CEM_MODE: typeof options.dev === "boolean" ? (options.dev ? "dev" : undefined) : options.dev,
72
72
  UI5_TS: `${tsOption}`,
73
73
  CSS_VARIABLES_TARGET: options.cssVariablesTarget ?? "root",
74
74
  CYPRESS_COVERAGE: !!(options.internal?.cypress_code_coverage),
@@ -86,7 +86,7 @@ const getScripts = (options) => {
86
86
  styleRelated: "ui5nps build.styles build.jsonImports build.jsImports",
87
87
  },
88
88
  prepare: {
89
- default: `ui5nps clean prepare.all copy copyProps prepare.typescript generateAPI`,
89
+ default: `ui5nps clean prepare.all copy copyProps prepare.typescript`,
90
90
  all: `ui5nps-p build.templates build.i18n prepare.styleRelated build.illustrations`, // concurently
91
91
  styleRelated: "ui5nps build.styles build.jsonImports build.jsImports",
92
92
  typescript: tsCommandOld,
@@ -165,9 +165,9 @@ const getScripts = (options) => {
165
165
  bundle: `ui5nps-script ${LIB}dev-server/dev-server.mjs ${viteConfig}`,
166
166
  },
167
167
  generateAPI: {
168
- default: tsOption ? "ui5nps generateAPI.generateCEM generateAPI.validateCEM" : "",
169
168
  generateCEM: `ui5nps-script "${LIB}cem/cem.js" analyze --config "${LIB}cem/custom-elements-manifest.config.mjs"`,
170
169
  validateCEM: `ui5nps-script "${LIB}cem/validate.js"`,
170
+ mergeCEM: `ui5nps-script "${LIB}cem/merge.mjs"`,
171
171
  },
172
172
  };
173
173
 
@@ -48,7 +48,7 @@ const wrapPluginForQuietMode = (plugin) => {
48
48
  ...plugin,
49
49
  packageLinkPhase(context) {
50
50
  const originalLog = console.log;
51
- console.log = () => {};
51
+ console.log = () => { };
52
52
  try {
53
53
  return originalPackageLinkPhase.call(plugin, context);
54
54
  } finally {
@@ -135,6 +135,13 @@ function processClass(ts, classNode, moduleDoc) {
135
135
  if (currClass.superclass?.name === "UI5Element") {
136
136
  currClass.customElement = true;
137
137
  }
138
+ } else if (currClass.customElement && classNode?.heritageClauses) {
139
+ // Find the extends clause (not implements)
140
+ const extendsClause = classNode.heritageClauses.find(clause => clause.token === ts.SyntaxKind.ExtendsKeyword);
141
+ if (extendsClause?.types?.[0]?.expression?.text) {
142
+ const extendedClass = extendsClause.types[0].expression.text;
143
+ logDocumentationError(moduleDoc.path, `Class extends ${extendedClass} but @extends tag is missing in JSDoc`);
144
+ }
138
145
  }
139
146
 
140
147
  if (!currClass._ui5implements.length) delete currClass._ui5implements;
@@ -417,10 +424,10 @@ const processPublicAPI = object => {
417
424
  return true;
418
425
  }
419
426
  for (const key of keys) {
420
- if ((key === "privacy" && object[key] !== "public") || (key === "_ui5privacy" && object[key] !== "public")) {
427
+ if (((key === "privacy" && object[key] !== "public") || (key === "_ui5privacy" && object[key] !== "public")) && !object.customElement) {
421
428
  return true;
422
429
  } else if (typeof object[key] === "object") {
423
- if (key === "cssParts" || key === "attributes" || key === "_ui5implements") {
430
+ if (key === "cssParts" || key === "cssStates" || key === "attributes" || key === "_ui5implements") {
424
431
  continue;
425
432
  }
426
433
 
@@ -569,6 +576,38 @@ export default {
569
576
  }
570
577
  }
571
578
  },
579
+ {
580
+ name: 'alphabetical-sort-plugin',
581
+ packageLinkPhase({ customElementsManifest }) {
582
+ const sortByName = (arr) => {
583
+ if (Array.isArray(arr)) {
584
+ arr.sort((a, b) => {
585
+ if (a?.name && b?.name) {
586
+ return a.name.localeCompare(b.name);
587
+ }
588
+ return 0;
589
+ });
590
+ }
591
+ };
592
+
593
+ const sortArraysInObject = (obj) => {
594
+ if (!obj || typeof obj !== 'object') return;
595
+
596
+ for (const key in obj) {
597
+ if (Array.isArray(obj[key])) {
598
+ sortByName(obj[key]);
599
+ obj[key].forEach(item => sortArraysInObject(item));
600
+ } else if (typeof obj[key] === 'object') {
601
+ sortArraysInObject(obj[key]);
602
+ }
603
+ }
604
+ };
605
+
606
+ customElementsManifest.modules?.forEach(moduleDoc => {
607
+ sortArraysInObject(moduleDoc);
608
+ });
609
+ }
610
+ },
572
611
  wrapPluginForQuietMode(generateCustomData({ outdir: "dist", cssFileName: null, cssPropertiesDocs: false })),
573
612
  wrapPluginForQuietMode(customElementJetBrainsPlugin({ outdir: "dist", cssFileName: null, cssPropertiesDocs: false }))
574
613
  ],
@@ -0,0 +1,220 @@
1
+ import { pathToFileURL } from "url";
2
+ import path from "path";
3
+ import { createRequire } from 'module';
4
+ import { readFile, writeFile } from "fs/promises";
5
+
6
+ const require = createRequire(import.meta.url);
7
+
8
+ const UI5_BASE_CLASS = "UI5Element";
9
+
10
+ const main = async (argv) => {
11
+ let customElementsPath = null;
12
+ const CACHED_CEMS = new Map();
13
+ const DECLARATION_PACKAGE = new WeakMap();
14
+ const DECLARATION_MODULE = new WeakMap();
15
+
16
+ function removeInheritedFrom(obj) {
17
+ if (obj === null || typeof obj !== 'object') {
18
+ return obj;
19
+ }
20
+
21
+ if (Array.isArray(obj)) {
22
+ return obj.map(item => removeInheritedFrom(item));
23
+ }
24
+
25
+ const result = {};
26
+ for (const [key, value] of Object.entries(obj)) {
27
+ if (key === 'inheritedFrom') {
28
+ continue;
29
+ }
30
+ result[key] = removeInheritedFrom(value);
31
+ }
32
+ return result;
33
+ }
34
+
35
+ async function readPackageJson(filePath) {
36
+ try {
37
+ return JSON.parse(await readFile(filePath, "utf-8"));
38
+ } catch (error) {
39
+ throw new Error(`Failed to read package.json at ${filePath}: ${error.message}`);
40
+ }
41
+ }
42
+
43
+ async function loadPackageJson(depName) {
44
+ try {
45
+ // First try the standard require method (works when exports includes package.json)
46
+ const pkg = require(`${depName}/package.json`);
47
+ const pkgPath = require.resolve(`${depName}/package.json`);
48
+ return { path: path.dirname(pkgPath), pkg };
49
+ } catch (e) {
50
+ // If that fails, resolve the package path and read package.json directly
51
+ try {
52
+ const packagePath = require.resolve(depName);
53
+ let currentDir = path.dirname(packagePath);
54
+
55
+ // Navigate up to find package.json (the resolved path might be deep in dist/ or similar)
56
+ while (currentDir !== path.parse(currentDir).root) {
57
+ try {
58
+ const pkgPath = path.join(currentDir, 'package.json');
59
+ const content = await readFile(pkgPath, 'utf-8');
60
+ const pkg = JSON.parse(content);
61
+
62
+ // Verify this is the correct package.json by checking the name
63
+ if (pkg.name === depName) {
64
+ return { path: currentDir, pkg };
65
+ }
66
+ } catch {
67
+ // Continue searching up the directory tree
68
+ }
69
+ currentDir = path.dirname(currentDir);
70
+ }
71
+ } catch (resolveError) {
72
+ // console.warn(`Could not resolve ${depName}:`, resolveError.message);
73
+ }
74
+ return null;
75
+ }
76
+ }
77
+
78
+ async function collectThirdPartyCem() {
79
+ const packageJSONPath = path.resolve(process.cwd(), "package.json");
80
+ const packageJSON = await readPackageJson(packageJSONPath);
81
+
82
+ const dependencyKeys = Object.keys(packageJSON).filter(key => key.toLowerCase().includes("dependencies"));
83
+ const dependencies = dependencyKeys.flatMap(key => Object.keys(packageJSON[key]));
84
+
85
+ const thirdPartCEM = (await Promise.all(dependencies.map(async dep => {
86
+ const result = await loadPackageJson(dep);
87
+ if (!result?.pkg?.customElements) return null;
88
+
89
+ return {
90
+ path: result.path,
91
+ name: dep,
92
+ cem: result.pkg.customElements
93
+ };
94
+ }))).filter(Boolean);
95
+
96
+ await Promise.all(thirdPartCEM.map(async dep => {
97
+ const cemPath = path.resolve(dep.path, dep.cem);
98
+ try {
99
+ const cemContent = JSON.parse(await readFile(cemPath, "utf-8"));
100
+ CACHED_CEMS.set(dep.name, cemContent);
101
+ } catch (error) {
102
+ console.warn(`Failed to read CEM for ${dep.name} from ${cemPath}: ${error.message}`);
103
+ }
104
+ }));
105
+ }
106
+
107
+ async function readCurrentCEM() {
108
+ const packageJSONPath = path.resolve(process.cwd(), "package.json");
109
+ const packageJSON = await readPackageJson(packageJSONPath);
110
+
111
+ if (!packageJSON?.customElements) {
112
+ return null;
113
+ }
114
+
115
+ customElementsPath = packageJSON.customElements;
116
+ const cemPath = path.resolve(process.cwd(), customElementsPath);
117
+
118
+ try {
119
+ const cemContent = JSON.parse(await readFile(cemPath, "utf-8"));
120
+ CACHED_CEMS.set(packageJSON.name, cemContent);
121
+ return cemContent;
122
+ } catch (error) {
123
+ throw new Error(`Failed to read CEM from ${cemPath}: ${error.message}`);
124
+ }
125
+ }
126
+
127
+ async function resolveReference(ref) {
128
+ const pkg = CACHED_CEMS.get(ref.package);
129
+
130
+ if (!pkg) {
131
+ return null;
132
+ }
133
+
134
+ const mod = (pkg.modules || []).find(m => m.path === ref.module);
135
+
136
+ if (!mod) {
137
+ return null;
138
+ }
139
+
140
+ const declaration = (mod.declarations || []).find(d => d.name === ref.name);
141
+
142
+ if (!declaration) {
143
+ return null;
144
+ }
145
+
146
+ DECLARATION_PACKAGE.set(declaration, ref.package);
147
+ DECLARATION_MODULE.set(declaration, ref.module);
148
+
149
+ return resolveDeclaration(declaration);
150
+ }
151
+
152
+ async function resolveDeclaration(declaration) {
153
+ if (!declaration.superclass || declaration.superclass.name === UI5_BASE_CLASS) {
154
+ return [declaration];
155
+ }
156
+
157
+ const superclassDeclarations = await resolveReference(declaration.superclass);
158
+ return [declaration, superclassDeclarations].flat().filter(Boolean);
159
+ }
160
+
161
+ const merge = async () => {
162
+ const currentCEM = await readCurrentCEM();
163
+ if (!currentCEM) {
164
+ throw new Error("No custom elements manifest found in current project");
165
+ }
166
+
167
+ await collectThirdPartyCem();
168
+
169
+ const modules = currentCEM.modules || [];
170
+
171
+ for (const mod of modules) {
172
+ const declarations = (mod.declarations || []).filter(d => d.kind === "class");
173
+
174
+ for (const declaration of declarations) {
175
+ const declarationHierarchy = await resolveDeclaration(declaration);
176
+ const allKeys = declarationHierarchy.flatMap(dec => Object.keys(dec));
177
+ const uniqueKeys = [...new Set(allKeys)];
178
+ const arrayKeys = uniqueKeys
179
+ .filter(key => !key.startsWith("_ui5"))
180
+ .filter(key => declarationHierarchy.some(dec => Array.isArray(dec[key])));
181
+
182
+ for (const key of arrayKeys) {
183
+ const allItems = declarationHierarchy.flatMap(dec => dec[key] || []);
184
+
185
+ // Remove duplicates based on name property
186
+ const seen = new Set();
187
+ declaration[key] = allItems.filter(item => {
188
+ if (!item.name) return true;
189
+ if (seen.has(item.name)) return false;
190
+ seen.add(item.name);
191
+ return true;
192
+ });
193
+ }
194
+ }
195
+ }
196
+
197
+ const cleanedCEM = removeInheritedFrom(currentCEM);
198
+ const outputPath = path.resolve(process.cwd(), customElementsPath);
199
+
200
+ try {
201
+ await writeFile(outputPath, JSON.stringify(cleanedCEM, null, 2), "utf-8");
202
+ console.log(`Successfully merged CEM to ${outputPath}`);
203
+ } catch (error) {
204
+ throw new Error(`Failed to write merged CEM to ${outputPath}: ${error.message}`);
205
+ }
206
+ };
207
+
208
+ await merge();
209
+ }
210
+
211
+ const filePath = process.argv[1];
212
+ const fileUrl = pathToFileURL(filePath).href;
213
+
214
+ if (import.meta.url === fileUrl) {
215
+ main(process.argv)
216
+ }
217
+
218
+ export default {
219
+ _ui5mainFn: main
220
+ }
@@ -1,6 +1,34 @@
1
1
  {
2
2
  "$schema": "http://json-schema.org/draft-07/schema#",
3
3
  "definitions": {
4
+ "CssCustomState": {
5
+ "description": "The description of a CSS Custom State\nhttps://developer.mozilla.org/en-US/docs/Web/API/CustomStateSet",
6
+ "properties": {
7
+ "deprecated": {
8
+ "description": "Whether the CSS custom state is deprecated.\nIf the value is a string, it's the reason for the deprecation.",
9
+ "type": [
10
+ "string",
11
+ "boolean"
12
+ ]
13
+ },
14
+ "description": {
15
+ "description": "A markdown description.",
16
+ "type": "string"
17
+ },
18
+ "name": {
19
+ "description": "The name of the state. Note: Unlike CSS custom properties, custom states\ndo not have a leading `--`.",
20
+ "type": "string"
21
+ },
22
+ "summary": {
23
+ "description": "A markdown summary suitable for display in a listing.",
24
+ "type": "string"
25
+ }
26
+ },
27
+ "required": [
28
+ "name"
29
+ ],
30
+ "type": "object"
31
+ },
4
32
  "Attribute": {
5
33
  "additionalProperties": false,
6
34
  "properties": {
@@ -521,6 +549,12 @@
521
549
  },
522
550
  "type": "array"
523
551
  },
552
+ "cssStates": {
553
+ "items": {
554
+ "$ref": "#/definitions/CssCustomState"
555
+ },
556
+ "type": "array"
557
+ },
524
558
  "customElement": {
525
559
  "description": "Distinguishes a regular JavaScript class from a\ncustom element class",
526
560
  "enum": [
@@ -676,6 +710,12 @@
676
710
  },
677
711
  "type": "array"
678
712
  },
713
+ "cssStates": {
714
+ "items": {
715
+ "$ref": "#/definitions/CssCustomState"
716
+ },
717
+ "type": "array"
718
+ },
679
719
  "customElement": {
680
720
  "description": "Distinguishes a regular JavaScript class from a\ncustom element class",
681
721
  "enum": [
@@ -1039,7 +1079,7 @@
1039
1079
  "type": "string"
1040
1080
  },
1041
1081
  "path": {
1042
- "description": "Path to the javascript file needed to be imported. \n(not the path for example to a typescript file.)",
1082
+ "description": "Path to the javascript file needed to be imported.\n(not the path for example to a typescript file.)",
1043
1083
  "type": "string"
1044
1084
  },
1045
1085
  "summary": {
@@ -258,6 +258,34 @@
258
258
  ],
259
259
  "type": "object"
260
260
  },
261
+ "CssCustomState": {
262
+ "description": "The description of a CSS Custom State\nhttps://developer.mozilla.org/en-US/docs/Web/API/CustomStateSet",
263
+ "properties": {
264
+ "deprecated": {
265
+ "description": "Whether the CSS custom state is deprecated.\nIf the value is a string, it's the reason for the deprecation.",
266
+ "type": [
267
+ "string",
268
+ "boolean"
269
+ ]
270
+ },
271
+ "description": {
272
+ "description": "A markdown description.",
273
+ "type": "string"
274
+ },
275
+ "name": {
276
+ "description": "The name of the state. Note: Unlike CSS custom properties, custom states\ndo not have a leading `--`.",
277
+ "type": "string"
278
+ },
279
+ "summary": {
280
+ "description": "A markdown summary suitable for display in a listing.",
281
+ "type": "string"
282
+ }
283
+ },
284
+ "required": [
285
+ "name"
286
+ ],
287
+ "type": "object"
288
+ },
261
289
  "CssPart": {
262
290
  "description": "The description of a CSS Part",
263
291
  "properties": {
@@ -307,6 +335,12 @@
307
335
  },
308
336
  "type": "array"
309
337
  },
338
+ "cssStates": {
339
+ "items": {
340
+ "$ref": "#/definitions/CssCustomState"
341
+ },
342
+ "type": "array"
343
+ },
310
344
  "customElement": {
311
345
  "description": "Distinguishes a regular JavaScript class from a\ncustom element class",
312
346
  "enum": [
@@ -451,6 +485,12 @@
451
485
  },
452
486
  "type": "array"
453
487
  },
488
+ "cssStates": {
489
+ "items": {
490
+ "$ref": "#/definitions/CssCustomState"
491
+ },
492
+ "type": "array"
493
+ },
454
494
  "customElement": {
455
495
  "description": "Distinguishes a regular JavaScript class from a\ncustom element class",
456
496
  "enum": [
@@ -765,7 +805,7 @@
765
805
  "type": "string"
766
806
  },
767
807
  "path": {
768
- "description": "Path to the javascript file needed to be imported. \n(not the path for example to a typescript file.)",
808
+ "description": "Path to the javascript file needed to be imported.\n(not the path for example to a typescript file.)",
769
809
  "type": "string"
770
810
  },
771
811
  "summary": {
@@ -56,7 +56,7 @@ export interface JavaScriptModule {
56
56
  kind: 'javascript-module';
57
57
 
58
58
  /**
59
- * Path to the javascript file needed to be imported.
59
+ * Path to the javascript file needed to be imported.
60
60
  * (not the path for example to a typescript file.)
61
61
  */
62
62
  path: string;
@@ -258,6 +258,8 @@ export interface CustomElement extends ClassLike {
258
258
 
259
259
  cssProperties?: CssCustomProperty[];
260
260
 
261
+ cssStates?: CssCustomState[];
262
+
261
263
  demos?: Demo[];
262
264
 
263
265
  /**
@@ -416,6 +418,34 @@ export interface CssPart {
416
418
  deprecated?: boolean | string;
417
419
  }
418
420
 
421
+ /**
422
+ * The description of a CSS Custom State
423
+ * https://developer.mozilla.org/en-US/docs/Web/API/CustomStateSet
424
+ */
425
+ export interface CssCustomState {
426
+ /**
427
+ * The name of the state. Note: Unlike CSS custom properties, custom states
428
+ * do not have a leading `--`.
429
+ */
430
+ name: string;
431
+
432
+ /**
433
+ * A markdown summary suitable for display in a listing.
434
+ */
435
+ summary?: string;
436
+
437
+ /**
438
+ * A markdown description.
439
+ */
440
+ description?: string;
441
+
442
+ /**
443
+ * Whether the CSS custom state is deprecated.
444
+ * If the value is a string, it's the reason for the deprecation.
445
+ */
446
+ deprecated?: boolean | string;
447
+ }
448
+
419
449
  export interface CssCustomProperty {
420
450
  /**
421
451
  * The name of the property, including leading `--`.
@@ -632,7 +662,7 @@ export interface ClassField extends PropertyLike {
632
662
  export interface CustomElementField extends ClassField {
633
663
  /**
634
664
  * The corresponding attribute name if there is one.
635
- *
665
+ *
636
666
  * If this property is defined, the attribute must be listed in the classes'
637
667
  * `attributes` array.
638
668
  */
@@ -56,7 +56,7 @@ export interface JavaScriptModule {
56
56
  kind: 'javascript-module';
57
57
 
58
58
  /**
59
- * Path to the javascript file needed to be imported.
59
+ * Path to the javascript file needed to be imported.
60
60
  * (not the path for example to a typescript file.)
61
61
  */
62
62
  path: string;
@@ -250,6 +250,8 @@ export interface CustomElement extends ClassLike {
250
250
 
251
251
  cssProperties?: CssCustomProperty[];
252
252
 
253
+ cssStates?: CssCustomState[];
254
+
253
255
  demos?: Demo[];
254
256
 
255
257
  /**
@@ -372,6 +374,34 @@ export interface CssPart {
372
374
  deprecated?: boolean | string;
373
375
  }
374
376
 
377
+ /**
378
+ * The description of a CSS Custom State
379
+ * https://developer.mozilla.org/en-US/docs/Web/API/CustomStateSet
380
+ */
381
+ export interface CssCustomState {
382
+ /**
383
+ * The name of the state. Note: Unlike CSS custom properties, custom states
384
+ * do not have a leading `--`.
385
+ */
386
+ name: string;
387
+
388
+ /**
389
+ * A markdown summary suitable for display in a listing.
390
+ */
391
+ summary?: string;
392
+
393
+ /**
394
+ * A markdown description.
395
+ */
396
+ description?: string;
397
+
398
+ /**
399
+ * Whether the CSS custom state is deprecated.
400
+ * If the value is a string, it's the reason for the deprecation.
401
+ */
402
+ deprecated?: boolean | string;
403
+ }
404
+
375
405
  export interface CssCustomProperty {
376
406
  /**
377
407
  * The name of the property, including leading `--`.
@@ -573,7 +603,7 @@ export interface ClassField extends PropertyLike {
573
603
  export interface CustomElementField extends ClassField {
574
604
  /**
575
605
  * The corresponding attribute name if there is one.
576
- *
606
+ *
577
607
  * If this property is defined, the attribute must be listed in the classes'
578
608
  * `attributes` array.
579
609
  */
package/lib/cem/utils.mjs CHANGED
@@ -240,7 +240,7 @@ const allowedTags = {
240
240
  event: [...commonTags, "param", "native", "allowPreventDefault"],
241
241
  eventParam: [...commonTags],
242
242
  method: [...commonTags, "param", "returns", "override"],
243
- class: [...commonTags, "constructor", "class", "abstract", "experimental", "implements", "extends", "slot", "csspart"],
243
+ class: [...commonTags, "constructor", "class", "abstract", "experimental", "implements", "extends", "slot", "csspart", "cssstate", "cssState"],
244
244
  enum: [...commonTags, "experimental",],
245
245
  enumMember: [...commonTags, "experimental",],
246
246
  interface: [...commonTags, "experimental",],
@@ -330,6 +330,9 @@ const validateJSDocTag = (tag) => {
330
330
  return tag.type && tag.name && tag.description;
331
331
  case "csspart":
332
332
  return !tag.type && tag.name && tag.description;
333
+ case "cssState":
334
+ case "cssstate":
335
+ return !tag.type && tag.name && tag.description;
333
336
  case "since":
334
337
  return !tag.type && tag.name;
335
338
  case "returns":
@@ -360,7 +363,8 @@ const validateJSDocComment = (fieldType, jsdocComment, node, moduleDoc) => {
360
363
  }
361
364
 
362
365
  if (!isValid) {
363
- logDocumentationError(moduleDoc.path, `Incorrect use of @${tag.tag}. Ensure it is part of ${fieldType} JSDoc tags.`)
366
+ const nodeName = node ? ` in '${node}'` : '';
367
+ logDocumentationError(moduleDoc.path, `Incorrect use of @${tag.tag}${nodeName}. Ensure it is part of ${fieldType} JSDoc tags.`)
364
368
  }
365
369
 
366
370
  return !!isValid;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ui5/webcomponents-tools",
3
- "version": "2.20.0-rc.2",
3
+ "version": "2.20.0-rc.3",
4
4
  "description": "UI5 Web Components: webcomponents.tools",
5
5
  "author": "SAP SE (https://www.sap.com)",
6
6
  "license": "Apache-2.0",
@@ -82,5 +82,5 @@
82
82
  "esbuild": "^0.25.0",
83
83
  "yargs": "^17.5.1"
84
84
  },
85
- "gitHead": "98b851b62424d1b81b69d58768924dc4a7a17096"
85
+ "gitHead": "d1767f2375f2b81e1187f9c58bb3b0eaf28b139e"
86
86
  }