From 04271de6c435b49ec3eaf1fe082ec215c0273a77 Mon Sep 17 00:00:00 2001 From: Nayden Naydenov Date: Wed, 20 Sep 2023 16:32:06 +0300 Subject: [PATCH 01/74] docs: generate cem --- .../build-scripts-storybook/parse-manifest.js | 6 +- .../components-package/cem-plugin/event.mjs | 64 +++++ .../components-package/cem-plugin/utils.mjs | 90 +++++++ .../custom-elements-manifest.config.mjs | 252 ++++++++++++++++++ packages/tools/components-package/nps.js | 4 +- packages/tools/package.json | 2 + yarn.lock | 100 ++++++- 7 files changed, 512 insertions(+), 6 deletions(-) create mode 100644 packages/tools/components-package/cem-plugin/event.mjs create mode 100644 packages/tools/components-package/cem-plugin/utils.mjs create mode 100644 packages/tools/components-package/custom-elements-manifest.config.mjs diff --git a/packages/playground/build-scripts-storybook/parse-manifest.js b/packages/playground/build-scripts-storybook/parse-manifest.js index 6b114a134a5d..1fafd184a208 100644 --- a/packages/playground/build-scripts-storybook/parse-manifest.js +++ b/packages/playground/build-scripts-storybook/parse-manifest.js @@ -98,7 +98,7 @@ const flattenAPIsHierarchicalStructure = module => { const declarations = module.declarations; declarations.forEach(declaration => { - let superclassDeclaration = processedDeclarations.get(declaration.superclass.name); + let superclassDeclaration = processedDeclarations.get(declaration.superclass?.name); if (!superclassDeclaration) { superclassDeclaration = customElements.modules.find(_m => _m.declarations.find(_d => _d.name === declaration.superclass?.name )); @@ -109,7 +109,7 @@ const flattenAPIsHierarchicalStructure = module => { } if (superclassDeclaration) { - processedDeclarations.set(declaration.name, mergeClassMembers(declaration, processedDeclarations.get(declaration.superclass.name))); + processedDeclarations.set(declaration.name, mergeClassMembers(declaration, processedDeclarations.get(declaration.superclass?.name))); } else { processedDeclarations.set(declaration.name, declaration); } @@ -143,7 +143,7 @@ const { customElementsMain, customElementsFiori } = loadManifest(); const customElements = mergeManifests(customElementsMain, customElementsFiori ); const processedDeclarations = new Map(); -customElements.modules.forEach(flattenAPIsHierarchicalStructure) +customElements.modules.forEach(flattenAPIsHierarchicalStructure); fs.writeFileSync( path.join(__dirname, "../.storybook/custom-elements.json"), diff --git a/packages/tools/components-package/cem-plugin/event.mjs b/packages/tools/components-package/cem-plugin/event.mjs new file mode 100644 index 000000000000..dab24f2e50ba --- /dev/null +++ b/packages/tools/components-package/cem-plugin/event.mjs @@ -0,0 +1,64 @@ +import { parse } from "comment-parser"; +import { getPrivacyStatus, getDeprecatedStatus, getSinceStatus, getType } from "./utils.mjs"; + +const jsDocRegExp = /\/\*\*(.|\n)+?\s+\*\//; + +const getParams = (ts, decoratorParams, commentParams, classNode) => { + return commentParams?.map(commentParam => { + const decoratorParam = decoratorParams?.find(prop => prop?.name?.text === commentParam?.name); + + if (!decoratorParam) { + return; + } + + return { + type: getType(ts, commentParam?.type, classNode), + name: commentParam?.name, + privacy: getPrivacyStatus(ts, decoratorParam?.jsDoc?.[0]), + description: commentParam?.description, + _ui5since: getSinceStatus(ts, decoratorParam?.jsDoc?.[0]), + deprecated: getDeprecatedStatus(ts, decoratorParam?.jsDoc?.[0]), + }; + }).filter(pair => !!pair); +}; + +function processEvent(ts, event, classNode) { + const result = { + name: event?.expression?.arguments?.[0]?.text, + }; + + const comment = event.getFullText?.().match(jsDocRegExp)?.[0]; + + if (comment) { + const parsedComment = parse(comment)[0]; + const deprecatedTag = parsedComment?.tags?.find(tag => tag?.tag === "deprecated"); + const privacy = parsedComment?.tags?.find(tag => ["private", "public", "protected"].includes(tag?.tag))?.tag || "private"; + const sinceTag = parsedComment?.tags?.find(tag => tag?.tag === "since"); + const commentParams = parsedComment?.tags?.filter(tag => tag?.tag === "param") || []; + const allowPreventDefault = !!parsedComment?.tags?.find(tag => tag?.tag === "allowPreventDefault"); + const description = parsedComment?.description; + const native = !!parsedComment?.tags?.find(tag => tag?.tag === "native") ? "Event" : "CustomEvent"; + const decoratorParams = event?.expression?.arguments?.[1]?.properties?.find(prop => prop?.name?.text === "detail")?.initializer?.properties; + + result.privacy = privacy; + result.description = description; + result._ui5allowPreventDefault = allowPreventDefault; + result.type = { text: native }; + + if (deprecatedTag?.name) { + result.deprecated = deprecatedTag?.description ? `${deprecatedTag.name} ${deprecatedTag.description}` : deprecatedTag.name; + } + + if (sinceTag?.name) { + result._ui5since = sinceTag?.description ? `${sinceTag.name} ${sinceTag.description}` : sinceTag.name; + } + + if (commentParams && decoratorParams) { + result.params = getParams(ts, decoratorParams, commentParams, classNode); + } + } + + return result; +} + +export default processEvent; \ No newline at end of file diff --git a/packages/tools/components-package/cem-plugin/utils.mjs b/packages/tools/components-package/cem-plugin/utils.mjs new file mode 100644 index 000000000000..8161801c2c71 --- /dev/null +++ b/packages/tools/components-package/cem-plugin/utils.mjs @@ -0,0 +1,90 @@ +import fs from "fs"; + +const getDeprecatedStatus = (ts, jsdocComment) => { + const deprecatedTag = jsdocComment?.tags?.find(tag => tag?.kind === ts?.SyntaxKind?.JSDocDeprecatedTag); + + return deprecatedTag ? (deprecatedTag.comment || true) : false; +} + +const getSinceStatus = (ts, jsdocComment) => { + const sinceTag = jsdocComment?.tags?.find(tag => tag?.tagName?.text === "since"); + + return sinceTag?.comment; +} + +const getPrivacyStatus = (ts, jsdocComment) => { + const privacyTagKinds = [ts?.SyntaxKind?.JSDocPrivateTag, ts?.SyntaxKind?.JSDocPublicTag, ts?.SyntaxKind?.JSDocProtectedTag]; + const privacyTag = jsdocComment?.tags?.find(tag => privacyTagKinds.includes(tag?.kind)); + + return privacyTag ? privacyTag.tagName?.text : "private"; +} + +const findPackageName = (ts, sourceFile, typeName, packageJSON) => { + const localStatements = [ + ts.SyntaxKind.EnumDeclaration, + ts.SyntaxKind.InterfaceDeclaration, + ts.SyntaxKind.ClassDeclaration, + ts.SyntaxKind.TypeAliasDeclaration, + ]; + + const isLocalDeclared = sourceFile.statements.find(statement => localStatements.includes(statement.kind))?.name?.text === typeName; + + if (isLocalDeclared) { + return packageJSON?.name; + } else { + const importStatements = sourceFile.statements?.filter((statement) => statement.kind === ts.SyntaxKind.ImportDeclaration); + const currentModuleSpecifier = importStatements.find((statement) => { + if (statement.importClause?.name?.text === typeName) { + return true; + } + + return statement.importClause?.namedBindings?.elements?.some( + (element) => element.name?.text === typeName + ); + })?.moduleSpecifier; + + if (currentModuleSpecifier?.text?.startsWith(".")) { + return packageJSON?.name; + } else { + return Object.keys(packageJSON?.dependencies || {}).find( + (dependency) => currentModuleSpecifier?.text?.startsWith(dependency) + ); + } + } +}; + +const getReference = (ts, type, classNode) => { + const sourceFile = classNode.parent?.kind === ts.SyntaxKind.SourceFile && classNode.parent; + const packageJSON = JSON.parse(fs.readFileSync("./package.json")); + + const typeName = typeof type === "string" ? type : type.class?.expression?.text || type.typeExpression?.type?.getText() || type.typeExpression?.type?.elementType?.typeName?.text; + const packageName = findPackageName(ts, sourceFile, typeName, packageJSON); + + return packageName && { + name: typeName, + package: packageName, + }; +}; + +const getType = (ts, type, classNode) => { + const typeName = typeof type === "string" ? type : type.class?.expression?.text || type.typeExpression?.type?.getText() || type.typeExpression?.type?.elementType?.typeName?.text; + + const multiple = typeName.endsWith("[]"); + const name = multiple ? typeName.replace("[]", "") : typeName; + const reference = getReference(ts, name, classNode); + + return reference + ? { + text: multiple ? `${name}[]` : name, + references: [reference], + } + : { text: multiple ? `${name}[]` : name }; +}; + +export { + getPrivacyStatus, + getSinceStatus, + getDeprecatedStatus, + getType, + getReference +} diff --git a/packages/tools/components-package/custom-elements-manifest.config.mjs b/packages/tools/components-package/custom-elements-manifest.config.mjs new file mode 100644 index 000000000000..f55ef76dc26f --- /dev/null +++ b/packages/tools/components-package/custom-elements-manifest.config.mjs @@ -0,0 +1,252 @@ +import processEvent from "./cem-plugin/event.mjs"; +import { getDeprecatedStatus, getSinceStatus, getPrivacyStatus, getType, getReference } from "./cem-plugin/utils.mjs"; +import { parse } from "comment-parser"; + +function processClass(ts, classNode, moduleDoc) { + const className = classNode?.name?.text; + const currClass = moduleDoc?.declarations?.find(declaration => declaration?.name === className); + const currClassJSdoc = classNode?.jsDoc?.[0]; + + if (!currClassJSdoc) { + return; + } + + const customElementDecorator = classNode?.decorators?.find(decorator => decorator?.expression?.expression?.text === "customElement"); + + if (customElementDecorator) { + const decoratorArg = customElementDecorator.expression?.arguments[0]; + + if (decoratorArg) { + if (decoratorArg.kind === ts.SyntaxKind.StringLiteral || decoratorArg.kind === ts.SyntaxKind.ObjectLiteralExpression) { + debugger + currClass.tagName = decoratorArg.text || (decoratorArg.properties.find(property => property.name.text === "tag")?.initializer?.text); + } + } + } + + const hasSuperclass = currClassJSdoc?.tags?.some(tag => tag.kind === ts?.SyntaxKind?.JSDocAugmentsTag); + + if (hasSuperclass) { + const parsedJsDoc = parse(currClassJSdoc?.getText())[0]; + const superclassTag = parsedJsDoc?.tags?.find(tag => tag.tag === "extends"); + + currClass.superclass = getReference(ts, superclassTag.name, classNode) + } + + currClass.customElement = !!currClass.tagName; + currClass.kind = "class"; + currClass._ui5abstract = currClassJSdoc?.tags?.some(tag => tag.tagName?.text === "abstract"); + const slotTag = currClassJSdoc?.tags?.some(tag => tag.tagName?.text === "slot"); + currClass.deprecated = getDeprecatedStatus(ts, currClassJSdoc); + currClass._ui5since = getSinceStatus(ts, currClassJSdoc); + currClass.privacy = getPrivacyStatus(ts, currClassJSdoc); + currClass.description = currClassJSdoc?.tags?.find(tag => tag.kind === ts?.SyntaxKind?.JSDocClassTag)?.comment; + currClass._ui5implements = currClassJSdoc?.tags?.filter(tag => tag.tagName?.text === "implements") + .map(tag => getReference(ts, tag, classNode)); + + if (slotTag && currClass.slots) { + const parsedJsDoc = parse(currClassJSdoc?.getText())[0]; + const slotTag = parsedJsDoc?.tags?.find(tag => tag.tag === "slot"); + + currClass.slots[0].type = getType(ts, slotTag.type, classNode); + } + + for (let i = 0; i < (currClass.members?.length || 0); i++) { + const member = currClass.members[i]; + const classNodeMember = classNode.members?.find(nodeMember => nodeMember.name?.text === member?.name); + const classNodeMemberJSdoc = classNodeMember?.jsDoc?.[0]; + + if (!classNodeMember || !classNodeMemberJSdoc) { + continue; + } + + + const type = classNodeMemberJSdoc?.tags?.find(tag => tag.kind === ts?.SyntaxKind?.JSDocTypeTag) + member.since = getSinceStatus(ts, classNodeMemberJSdoc); + + if (!!type) { + member.type = getType(ts, type, classNode); + } + + if (member.kind === "field") { + + const slotDecorator = classNodeMember?.decorators?.find(decorator => decorator?.expression?.expression?.text === "slot"); + + if (slotDecorator) { + if (!currClass.slots) { + currClass.slots = []; + } + + const slot = currClass.members.splice(i, 1)[0]; + const defaultProperty = slotDecorator.expression?.arguments?.[0]?.properties?.find(property => property.name.text === "default"); + + if (defaultProperty && defaultProperty.initializer?.kind === ts.SyntaxKind.TrueKeyword) { + slot.name = "default"; + } + + currClass.slots.push(slot); + i--; + } + } else if (member.kind === "method") { + member.parameters?.forEach(param => { + param.privacy = classNodeMemberJSdoc.tags?.some(tag => tag.name?.text === param.name) ? "public" : "private"; + if (param.type?.text) { + param.type = getType(ts, param.type?.text, classNode); + } + }) + + if (member.return?.type?.text) { + member.return.type = getType(ts, member.return?.type?.text, classNode) + } + } + } + + currClass.events = classNode?.decorators + ?.filter(decorator => decorator?.expression?.expression?.text === "event") + .map(event => processEvent(ts, event, classNode)); +} + +function processInterface(ts, interfaceNode, moduleDoc) { + const interfaceJSdoc = interfaceNode?.jsDoc?.[0]; + const interfaceName = interfaceNode?.name?.text; + + if (!interfaceJSdoc) { + return; + } + + const result = { + kind: "interface", + name: interfaceName, + description: interfaceJSdoc?.comment, + privacy: getPrivacyStatus(ts, interfaceJSdoc), + _ui5since: getSinceStatus(ts, interfaceJSdoc), + deprecated: getDeprecatedStatus(ts, interfaceJSdoc), + }; + + moduleDoc.declarations.push(result); +} + +function processEnum(ts, enumNode, moduleDoc) { + const enumJSdoc = enumNode?.jsDoc?.[0]; + const enumName = enumNode?.name?.text; + + if (!enumJSdoc) { + return; + } + + const result = { + kind: "enum", + name: enumName, + description: enumJSdoc?.comment, + privacy: getPrivacyStatus(ts, enumJSdoc), + _ui5since: getSinceStatus(ts, enumJSdoc), + deprecated: getDeprecatedStatus(ts, enumJSdoc), + }; + + result.members = (enumNode?.members || []).map(member => { + const memberJSdoc = member?.jsDoc?.[0]; + + const memberResult = { + kind: "field", + static: true, + privacy: getPrivacyStatus(ts, memberJSdoc), + _ui5since: getSinceStatus(ts, memberJSdoc), + description: memberJSdoc?.comment, + deprecated: getDeprecatedStatus(ts, memberJSdoc), + name: member.name?.text, + }; + + return memberResult; + }); + + moduleDoc.declarations.push(result); +} + +const processPublicAPI = object => { + if (!object) { + return true; + } + + const keys = Object.keys(object); + + if (!keys.includes("privacy")) { + return true; + } + + for (const key of keys) { + if (key === "privacy" && object[key] !== "public") { + return true; + } else if (typeof object[key] === "object") { + if (key === "cssParts") { + continue; + } + + if (Array.isArray(object[key])) { + for (let i = 0; i < object[key].length; i++) { + const shouldRemove = processPublicAPI(object[key][i]); + + if (shouldRemove) { + object[key].splice(i, 1); + i--; + } + } + + if (object[key].length === 0) { + delete object[key]; + } else { + object[key].sort(function (a, b) { + if (a.name < b.name) { + return -1; + } + if (a.name > b.name) { + return 1; + } + return 0; + }); + } + } + } + } + + return false; +}; + +export default { + /** Globs to analyze */ + globs: ["src/!(*generated)/*.ts", "src/*.ts"], + // globs: ["src/Test1.ts", "src/Test2.ts", "src/Test3.ts", "src/Test4.ts", "src/Test5.ts"], + globs: ["src/Test1.ts", "src/ListItem.ts", "src/ListItemBase.ts"], + outdir: 'dist', + /** Run in dev mode, provides extra logging */ + // dev: true, + /** Run in watch mode, runs on file changes */ + watch: true, + plugins: [ + { + name: 'my-plugin', + analyzePhase({ ts, node, moduleDoc, context }) { + switch (node.kind) { + case ts.SyntaxKind.ClassDeclaration: + processClass(ts, node, moduleDoc); + break; + case ts.SyntaxKind.EnumDeclaration: + processEnum(ts, node, moduleDoc); + break; + case ts.SyntaxKind.InterfaceDeclaration: + processInterface(ts, node, moduleDoc); + break; + } + }, + moduleLinkPhase({ moduleDoc, context }) { + for (let i = 0; i < moduleDoc.declarations.length; i++) { + const shouldRemove = processPublicAPI(moduleDoc.declarations[i]) + + if (shouldRemove) { + moduleDoc.declarations.splice(i, 1); + i--; + } + } + }, + }, + ], +}; \ No newline at end of file diff --git a/packages/tools/components-package/nps.js b/packages/tools/components-package/nps.js index 5200860880a3..bb92a5249cae 100644 --- a/packages/tools/components-package/nps.js +++ b/packages/tools/components-package/nps.js @@ -54,6 +54,7 @@ const getScripts = (options) => { clean: 'rimraf jsdoc-dist && rimraf src/generated && rimraf dist && rimraf .port && nps "scope.testPages.clean"', lint: `eslint . ${eslintConfig}`, lintfix: `eslint . ${eslintConfig} --fix`, + testCEM: `cem analyze --config "${require.resolve("@ui5/webcomponents-tools/components-package/custom-elements-manifest.config.mjs")}"`, prepare: { default: `${tsCrossEnv} nps clean prepare.all typescript generateAPI`, all: 'concurrently "nps build.templates" "nps build.i18n" "nps prepare.styleRelated" "nps copy" "nps build.illustrations"', @@ -130,9 +131,8 @@ const getScripts = (options) => { bundle: `node ${LIB}/dev-server/dev-server.js ${viteConfig}`, }, generateAPI: { - default: "nps generateAPI.prepare generateAPI.preprocess generateAPI.jsdoc generateAPI.cleanup generateAPI.prepareManifest", + default: "nps generateAPI.prepare generateAPI.preprocess generateAPI.jsdoc generateAPI.cleanup testCEM", prepare: `node "${LIB}/copy-and-watch/index.js" --silent "dist/**/*.js" jsdoc-dist/`, - prepareManifest: `node "${LIB}/generate-custom-elements-manifest/index.js" dist dist`, preprocess: `node "${preprocessJSDocScript}" jsdoc-dist/ src`, jsdoc: `jsdoc -c "${LIB}/jsdoc/configTypescript.json"`, cleanup: "rimraf jsdoc-dist/" diff --git a/packages/tools/package.json b/packages/tools/package.json index 3eb23702cc73..ff53cdabb12b 100644 --- a/packages/tools/package.json +++ b/packages/tools/package.json @@ -21,6 +21,7 @@ "directory": "packages/tools" }, "dependencies": { + "@custom-elements-manifest/analyzer": "^0.8.4", "@typescript-eslint/eslint-plugin": "^5.42.1", "@typescript-eslint/parser": "^5.42.1", "@wdio/cli": "^7.19.7", @@ -34,6 +35,7 @@ "chokidar": "^3.5.1", "chokidar-cli": "^3.0.0", "command-line-args": "^5.1.1", + "comment-parser": "^1.4.0", "concurrently": "^6.0.0", "cross-env": "^7.0.3", "cssnano": "^6.0.1", diff --git a/yarn.lock b/yarn.lock index 02e4ec63c1fc..5e7a7aae6bf2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1494,6 +1494,29 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" +"@custom-elements-manifest/analyzer@^0.8.4": + version "0.8.4" + resolved "https://registry.yarnpkg.com/@custom-elements-manifest/analyzer/-/analyzer-0.8.4.tgz#34fce1158a44cb7a9d8c1c7415e8c9d03e25d95f" + integrity sha512-hibYFNoqPc/xSH9ySuotOllz3UtQnnbG912oC0RtRwHGilnOVT5zeL3Ip26swCjiuFAp8Y0uLN5DwnMpa/xXYQ== + dependencies: + "@custom-elements-manifest/find-dependencies" "^0.0.5" + "@github/catalyst" "^1.6.0" + "@web/config-loader" "0.1.3" + chokidar "3.5.2" + command-line-args "5.1.2" + comment-parser "1.2.4" + custom-elements-manifest "1.0.0" + debounce "1.2.1" + globby "11.0.4" + typescript "~4.3.2" + +"@custom-elements-manifest/find-dependencies@^0.0.5": + version "0.0.5" + resolved "https://registry.yarnpkg.com/@custom-elements-manifest/find-dependencies/-/find-dependencies-0.0.5.tgz#ebc11672019de3d52bb8f29f76efe510b8401fbd" + integrity sha512-fKIMMZCDFSoL2ySUoz8knWgpV4jpb0lUXgLOvdZQMQFHxgxz1PqOJpUIypwvEVyKk3nEHRY4f10gNol02HjeCg== + dependencies: + es-module-lexer "^0.9.3" + "@discoveryjs/json-ext@^0.5.3": version "0.5.7" resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" @@ -1761,6 +1784,11 @@ resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== +"@github/catalyst@^1.6.0": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@github/catalyst/-/catalyst-1.6.0.tgz#378734d1d2b6a85af169d7e66c1a2a604bf1e82c" + integrity sha512-u8A+DameixqpeyHzvnJWTGj+wfiskQOYHzSiJscCWVfMkIT3rxnbHMtGh3lMthaRY21nbUOK71WcsCnCrXhBJQ== + "@humanwhocodes/config-array@^0.5.0": version "0.5.0" resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" @@ -4078,6 +4106,13 @@ "@wdio/types" "7.30.2" p-iteration "^1.1.8" +"@web/config-loader@0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@web/config-loader/-/config-loader-0.1.3.tgz#8325ea54f75ef2ee7166783e64e66936db25bff7" + integrity sha512-XVKH79pk4d3EHRhofete8eAnqto1e8mCRAqPV00KLNFzCWSe8sWmLnqKCqkPNARC6nksMaGrATnA5sPDRllMpQ== + dependencies: + semver "^7.3.4" + "@whitespace/storybook-addon-html@^5.1.0": version "5.1.6" resolved "https://registry.yarnpkg.com/@whitespace/storybook-addon-html/-/storybook-addon-html-5.1.6.tgz#9813a40a3e71e4afcb49069788e1120423e083f6" @@ -4421,6 +4456,11 @@ array-back@^3.0.1, array-back@^3.1.0: resolved "https://registry.yarnpkg.com/array-back/-/array-back-3.1.0.tgz#b8859d7a508871c9a7b2cf42f99428f65e96bfb0" integrity sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q== +array-back@^6.1.2: + version "6.2.2" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-6.2.2.tgz#f567d99e9af88a6d3d2f9dfcc21db6f9ba9fd157" + integrity sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw== + array-buffer-byte-length@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz#fabe8bc193fea865f317fe7807085ee0dee5aead" @@ -5442,6 +5482,16 @@ comma-separated-tokens@^1.0.0: resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz#632b80b6117867a158f1080ad498b2fbe7e3f5ea" integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw== +command-line-args@5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.1.2.tgz#25908e573d2214bc23a8437e3df853b02dffa425" + integrity sha512-fytTsbndLbl+pPWtS0CxLV3BEWw9wJayB8NnU2cbQqVPsNdYezQeT+uIQv009m+GShnMNyuoBrRo8DTmuTfSCA== + dependencies: + array-back "^6.1.2" + find-replace "^3.0.0" + lodash.camelcase "^4.3.0" + typical "^4.0.0" + command-line-args@^5.1.1: version "5.2.1" resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.2.1.tgz#c44c32e437a57d7c51157696893c5909e9cec42e" @@ -5467,6 +5517,16 @@ commander@^8.0.0: resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== +comment-parser@1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/comment-parser/-/comment-parser-1.2.4.tgz#489f3ee55dfd184a6e4bffb31baba284453cb760" + integrity sha512-pm0b+qv+CkWNriSTMsfnjChF9kH0kxz55y44Wo5le9qLxMj5xDQAaEd9ZN1ovSuk9CsrncWaFwgpOMg7ClJwkw== + +comment-parser@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/comment-parser/-/comment-parser-1.4.0.tgz#0f8c560f59698193854f12884c20c0e39a26d32c" + integrity sha512-QLyTNiZ2KDOibvFPlZ6ZngVsZ/0gYnE6uTXi5aoDg8ed3AkJAz4sEje3Y8a29hQ1s6A99MZXe47fLAXQ1rTqaw== + common-ancestor-path@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz#4f7d2d1394d91b7abdf51871c62f71eadb0182a7" @@ -5993,6 +6053,11 @@ currently-unhandled@^0.4.1: dependencies: array-find-index "^1.0.1" +custom-elements-manifest@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/custom-elements-manifest/-/custom-elements-manifest-1.0.0.tgz#b35c2129076a1dc9f95d720c6f7b5b71a857274b" + integrity sha512-j59k0ExGCKA8T6Mzaq+7axc+KVHwpEphEERU7VZ99260npu/p/9kd+Db+I3cGKxHkM5y6q5gnlXn00mzRQkX2A== + dargs@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/dargs/-/dargs-7.0.0.tgz#04015c41de0bcb69ec84050f3d9be0caf8d6d5cc" @@ -6015,6 +6080,11 @@ dateformat@^3.0.0: resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== +debounce@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5" + integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug== + debug@2.6.9, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -7066,6 +7136,17 @@ fast-glob@3.2.7: merge2 "^1.3.0" micromatch "^4.0.4" +fast-glob@^3.1.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" + integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + fast-glob@^3.2.7, fast-glob@^3.2.9, fast-glob@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.0.tgz#7c40cb491e1e2ed5664749e87bfb516dbe8727c0" @@ -7778,6 +7859,18 @@ globalthis@^1.0.3: dependencies: define-properties "^1.1.3" +globby@11.0.4: + version "11.0.4" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" + integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.1.1" + ignore "^5.1.4" + merge2 "^1.3.0" + slash "^3.0.0" + globby@11.1.0, globby@^11.0.1, globby@^11.0.2, globby@^11.1.0: version "11.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" @@ -8161,7 +8254,7 @@ ignore@^4.0.6: resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== -ignore@^5.0.4, ignore@^5.1.9, ignore@^5.2.0, ignore@^5.2.4: +ignore@^5.0.4, ignore@^5.1.4, ignore@^5.1.9, ignore@^5.2.0, ignore@^5.2.4: version "5.2.4" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== @@ -14047,6 +14140,11 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== +typescript@~4.3.2: + version "4.3.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4" + integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA== + typical@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/typical/-/typical-4.0.0.tgz#cbeaff3b9d7ae1e2bbfaf5a4e6f11eccfde94fc4" From ce8470f420c36f95121a0b64a0fa35086b685394 Mon Sep 17 00:00:00 2001 From: Nayden Naydenov Date: Wed, 20 Sep 2023 16:46:49 +0300 Subject: [PATCH 02/74] chore: cleanup --- .../components-package/custom-elements-manifest.config.mjs | 7 ------- packages/tools/components-package/nps.js | 3 ++- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/packages/tools/components-package/custom-elements-manifest.config.mjs b/packages/tools/components-package/custom-elements-manifest.config.mjs index f55ef76dc26f..6cfe7cbf5d41 100644 --- a/packages/tools/components-package/custom-elements-manifest.config.mjs +++ b/packages/tools/components-package/custom-elements-manifest.config.mjs @@ -18,7 +18,6 @@ function processClass(ts, classNode, moduleDoc) { if (decoratorArg) { if (decoratorArg.kind === ts.SyntaxKind.StringLiteral || decoratorArg.kind === ts.SyntaxKind.ObjectLiteralExpression) { - debugger currClass.tagName = decoratorArg.text || (decoratorArg.properties.find(property => property.name.text === "tag")?.initializer?.text); } } @@ -214,13 +213,7 @@ const processPublicAPI = object => { export default { /** Globs to analyze */ globs: ["src/!(*generated)/*.ts", "src/*.ts"], - // globs: ["src/Test1.ts", "src/Test2.ts", "src/Test3.ts", "src/Test4.ts", "src/Test5.ts"], - globs: ["src/Test1.ts", "src/ListItem.ts", "src/ListItemBase.ts"], outdir: 'dist', - /** Run in dev mode, provides extra logging */ - // dev: true, - /** Run in watch mode, runs on file changes */ - watch: true, plugins: [ { name: 'my-plugin', diff --git a/packages/tools/components-package/nps.js b/packages/tools/components-package/nps.js index bb92a5249cae..124693a570b9 100644 --- a/packages/tools/components-package/nps.js +++ b/packages/tools/components-package/nps.js @@ -131,8 +131,9 @@ const getScripts = (options) => { bundle: `node ${LIB}/dev-server/dev-server.js ${viteConfig}`, }, generateAPI: { - default: "nps generateAPI.prepare generateAPI.preprocess generateAPI.jsdoc generateAPI.cleanup testCEM", + default: "nps generateAPI.prepare generateAPI.preprocess generateAPI.jsdoc generateAPI.cleanup generateAPI.prepareManifest", prepare: `node "${LIB}/copy-and-watch/index.js" --silent "dist/**/*.js" jsdoc-dist/`, + prepareManifest: `node "${LIB}/generate-custom-elements-manifest/index.js" dist dist`, preprocess: `node "${preprocessJSDocScript}" jsdoc-dist/ src`, jsdoc: `jsdoc -c "${LIB}/jsdoc/configTypescript.json"`, cleanup: "rimraf jsdoc-dist/" From 53558c03bb6116eb552c18bd339f1d9ce6950866 Mon Sep 17 00:00:00 2001 From: Nayden Naydenov Date: Tue, 26 Sep 2023 14:54:58 +0300 Subject: [PATCH 03/74] chore: migrate button --- packages/fiori/src/IllustratedMessage.ts | 5 +- packages/fiori/src/ShellBar.ts | 5 +- packages/main/src/Button.ts | 66 ++++++++++-------------- packages/main/src/Interfaces.ts | 10 ---- packages/main/src/ListItem.ts | 5 +- packages/main/src/TabContainer.ts | 5 +- packages/main/src/types/ButtonDesign.ts | 10 ---- packages/main/src/types/ButtonType.ts | 7 --- 8 files changed, 39 insertions(+), 74 deletions(-) diff --git a/packages/fiori/src/IllustratedMessage.ts b/packages/fiori/src/IllustratedMessage.ts index 203ea2fb90ec..4da1c66ea241 100644 --- a/packages/fiori/src/IllustratedMessage.ts +++ b/packages/fiori/src/IllustratedMessage.ts @@ -10,6 +10,7 @@ import { getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js"; import type I18nBundle from "@ui5/webcomponents-base/dist/i18nBundle.js"; import Title from "@ui5/webcomponents/dist/Title.js"; import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js"; +import type { IButton } from "@ui5/webcomponents/dist/Button.js"; import IllustrationMessageSize from "./types/IllustrationMessageSize.js"; import IllustrationMessageType from "./types/IllustrationMessageType.js"; import "./illustrations/BeforeSearch.js"; @@ -323,13 +324,13 @@ class IllustratedMessage extends UI5Element { /** * Defines the component actions. - * @type {sap.ui.webc.main.IButton[]} + * @type {IButton[]} * @slot actions * @name sap.ui.webc.fiori.IllustratedMessage.prototype.default * @public */ @slot({ type: HTMLElement, "default": true }) - actions!: Array; + actions!: Array; illustrationTitle?: string; illustrationSubtitle?: string; diff --git a/packages/fiori/src/ShellBar.ts b/packages/fiori/src/ShellBar.ts index 97bd0defd60a..a225dad76489 100644 --- a/packages/fiori/src/ShellBar.ts +++ b/packages/fiori/src/ShellBar.ts @@ -16,6 +16,7 @@ import type { ListSelectionChangeEventDetail } from "@ui5/webcomponents/dist/Lis import type { ResizeObserverCallback } from "@ui5/webcomponents-base/dist/delegate/ResizeHandler.js"; import Popover from "@ui5/webcomponents/dist/Popover.js"; import Button from "@ui5/webcomponents/dist/Button.js"; +import type { IButton } from "@ui5/webcomponents/dist/Button.js"; import type Input from "@ui5/webcomponents/dist/Input.js"; import HasPopup from "@ui5/webcomponents/dist/types/HasPopup.js"; import { getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js"; @@ -516,13 +517,13 @@ class ShellBar extends UI5Element { * We encourage this slot to be used for a back or home button. * It gets overstyled to match ShellBar's styling. * - * @type {sap.ui.webc.main.IButton} + * @type {IButton} * @name sap.ui.webc.fiori.ShellBar.prototype.startButton * @slot * @public */ @slot() - startButton!: Array