| 
									
										
										
										
											2021-06-24 22:24:54 +00:00
										 |  |  | import fs from 'fs'; | 
					
						
							| 
									
										
										
										
											2022-11-16 17:47:34 +00:00
										 |  |  | import { generateCustomData } from 'cem-plugin-vs-code-custom-data-generator'; | 
					
						
							|  |  |  | import commandLineArgs from 'command-line-args'; | 
					
						
							| 
									
										
										
										
											2021-12-06 15:57:54 +00:00
										 |  |  | import { parse } from 'comment-parser'; | 
					
						
							| 
									
										
										
										
											2022-01-06 13:44:13 +00:00
										 |  |  | import { pascalCase } from 'pascal-case'; | 
					
						
							| 
									
										
										
										
											2021-06-24 22:24:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | const packageData = JSON.parse(fs.readFileSync('./package.json', 'utf8')); | 
					
						
							|  |  |  | const { name, description, version, author, homepage, license } = packageData; | 
					
						
							| 
									
										
										
										
											2022-11-10 20:28:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-16 17:47:34 +00:00
										 |  |  | const { outdir } = commandLineArgs([ | 
					
						
							|  |  |  |   { name: 'litelement', type: String }, | 
					
						
							|  |  |  |   { name: 'analyze', defaultOption: true }, | 
					
						
							|  |  |  |   { name: 'outdir', type: String } | 
					
						
							|  |  |  | ]); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-10 21:27:23 +00:00
										 |  |  | function noDash(string) { | 
					
						
							|  |  |  |   return string.replace(/^\s?-/, '').trim(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function replace(string, terms) { | 
					
						
							|  |  |  |   terms.forEach(({ from, to }) => { | 
					
						
							|  |  |  |     string = string?.replace(from, to); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return string; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-06-24 22:24:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | export default { | 
					
						
							|  |  |  |   globs: ['src/components/**/*.ts'], | 
					
						
							| 
									
										
										
										
											2022-01-31 19:41:18 +00:00
										 |  |  |   exclude: ['**/*.styles.ts', '**/*.test.ts'], | 
					
						
							| 
									
										
										
										
											2021-06-24 22:24:54 +00:00
										 |  |  |   plugins: [ | 
					
						
							|  |  |  |     // Append package data
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       name: 'shoelace-package-data', | 
					
						
							| 
									
										
										
										
											2022-01-16 05:47:14 +00:00
										 |  |  |       packageLinkPhase({ customElementsManifest }) { | 
					
						
							| 
									
										
										
										
											2021-06-24 22:24:54 +00:00
										 |  |  |         customElementsManifest.package = { name, description, version, author, homepage, license }; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }, | 
					
						
							| 
									
										
										
										
											2021-06-25 13:58:26 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-24 22:24:54 +00:00
										 |  |  |     // Parse custom jsDoc tags
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       name: 'shoelace-custom-tags', | 
					
						
							| 
									
										
										
										
											2022-01-16 05:47:14 +00:00
										 |  |  |       analyzePhase({ ts, node, moduleDoc }) { | 
					
						
							| 
									
										
										
										
											2021-06-24 22:24:54 +00:00
										 |  |  |         switch (node.kind) { | 
					
						
							| 
									
										
										
										
											2022-01-16 05:47:14 +00:00
										 |  |  |           case ts.SyntaxKind.ClassDeclaration: { | 
					
						
							| 
									
										
										
										
											2021-07-06 14:29:58 +00:00
										 |  |  |             const className = node.name.getText(); | 
					
						
							| 
									
										
										
										
											2021-06-24 22:24:54 +00:00
										 |  |  |             const classDoc = moduleDoc?.declarations?.find(declaration => declaration.name === className); | 
					
						
							| 
									
										
										
										
											2022-10-18 16:22:48 +00:00
										 |  |  |             const customTags = ['title', 'animation', 'dependency', 'since', 'status']; | 
					
						
							| 
									
										
										
										
											2021-06-24 22:24:54 +00:00
										 |  |  |             let customComments = '/**'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             node.jsDoc?.forEach(jsDoc => { | 
					
						
							|  |  |  |               jsDoc?.tags?.forEach(tag => { | 
					
						
							|  |  |  |                 const tagName = tag.tagName.getText(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (customTags.includes(tagName)) { | 
					
						
							|  |  |  |                   customComments += `\n * @${tagName} ${tag.comment}`; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |               }); | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-16 05:47:14 +00:00
										 |  |  |             const parsed = parse(`${customComments}\n */`); | 
					
						
							|  |  |  |             parsed[0].tags?.forEach(t => { | 
					
						
							| 
									
										
										
										
											2021-06-24 22:24:54 +00:00
										 |  |  |               switch (t.tag) { | 
					
						
							| 
									
										
										
										
											2021-06-25 13:58:26 +00:00
										 |  |  |                 // Animations
 | 
					
						
							|  |  |  |                 case 'animation': | 
					
						
							|  |  |  |                   if (!Array.isArray(classDoc['animations'])) { | 
					
						
							|  |  |  |                     classDoc['animations'] = []; | 
					
						
							|  |  |  |                   } | 
					
						
							|  |  |  |                   classDoc['animations'].push({ | 
					
						
							|  |  |  |                     name: t.name, | 
					
						
							| 
									
										
										
										
											2021-09-21 02:05:27 +00:00
										 |  |  |                     description: noDash(t.description) | 
					
						
							| 
									
										
										
										
											2021-06-25 13:58:26 +00:00
										 |  |  |                   }); | 
					
						
							| 
									
										
										
										
											2021-06-24 22:24:54 +00:00
										 |  |  |                   break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-25 13:58:26 +00:00
										 |  |  |                 // Dependencies
 | 
					
						
							| 
									
										
										
										
											2021-06-24 22:24:54 +00:00
										 |  |  |                 case 'dependency': | 
					
						
							|  |  |  |                   if (!Array.isArray(classDoc['dependencies'])) { | 
					
						
							|  |  |  |                     classDoc['dependencies'] = []; | 
					
						
							|  |  |  |                   } | 
					
						
							|  |  |  |                   classDoc['dependencies'].push(t.name); | 
					
						
							|  |  |  |                   break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-25 13:58:26 +00:00
										 |  |  |                 // Value-only metadata tags
 | 
					
						
							|  |  |  |                 case 'since': | 
					
						
							|  |  |  |                 case 'status': | 
					
						
							| 
									
										
										
										
											2022-10-18 16:22:48 +00:00
										 |  |  |                 case 'title': | 
					
						
							| 
									
										
										
										
											2021-06-25 13:58:26 +00:00
										 |  |  |                   classDoc[t.tag] = t.name; | 
					
						
							|  |  |  |                   break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-24 22:24:54 +00:00
										 |  |  |                 // All other tags
 | 
					
						
							|  |  |  |                 default: | 
					
						
							|  |  |  |                   if (!Array.isArray(classDoc[t.tag])) { | 
					
						
							|  |  |  |                     classDoc[t.tag] = []; | 
					
						
							|  |  |  |                   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                   classDoc[t.tag].push({ | 
					
						
							|  |  |  |                     name: t.name, | 
					
						
							|  |  |  |                     description: t.description, | 
					
						
							|  |  |  |                     type: t.type || undefined | 
					
						
							|  |  |  |                   }); | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |             }); | 
					
						
							| 
									
										
										
										
											2022-01-16 05:47:14 +00:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2021-06-24 22:24:54 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-11-05 13:23:30 +00:00
										 |  |  |     }, | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       name: 'shoelace-react-event-names', | 
					
						
							| 
									
										
										
										
											2022-01-16 05:47:14 +00:00
										 |  |  |       analyzePhase({ ts, node, moduleDoc }) { | 
					
						
							| 
									
										
										
										
											2021-11-05 13:23:30 +00:00
										 |  |  |         switch (node.kind) { | 
					
						
							| 
									
										
										
										
											2022-01-16 05:47:14 +00:00
										 |  |  |           case ts.SyntaxKind.ClassDeclaration: { | 
					
						
							| 
									
										
										
										
											2021-11-05 13:23:30 +00:00
										 |  |  |             const className = node.name.getText(); | 
					
						
							|  |  |  |             const classDoc = moduleDoc?.declarations?.find(declaration => declaration.name === className); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (classDoc?.events) { | 
					
						
							| 
									
										
										
										
											2022-01-16 05:47:14 +00:00
										 |  |  |               classDoc.events.forEach(event => { | 
					
						
							| 
									
										
										
										
											2021-11-05 13:23:30 +00:00
										 |  |  |                 event.reactName = `on${pascalCase(event.name)}`; | 
					
						
							|  |  |  |               }); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2022-01-16 05:47:14 +00:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2021-11-05 13:23:30 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-11-10 20:28:08 +00:00
										 |  |  |     }, | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       name: 'shoelace-translate-module-paths', | 
					
						
							| 
									
										
										
										
											2022-11-10 21:27:23 +00:00
										 |  |  |       packageLinkPhase({ customElementsManifest }) { | 
					
						
							|  |  |  |         customElementsManifest?.modules?.forEach(mod => { | 
					
						
							|  |  |  |           //
 | 
					
						
							|  |  |  |           // CEM paths look like this:
 | 
					
						
							|  |  |  |           //
 | 
					
						
							|  |  |  |           //  src/components/button/button.ts
 | 
					
						
							|  |  |  |           //
 | 
					
						
							|  |  |  |           // But we want them to look like this:
 | 
					
						
							|  |  |  |           //
 | 
					
						
							|  |  |  |           //  components/button/button.js
 | 
					
						
							|  |  |  |           //
 | 
					
						
							|  |  |  |           const terms = [ | 
					
						
							|  |  |  |             { from: /^src\//, to: '' }, // Strip the src/ prefix
 | 
					
						
							|  |  |  |             { from: /\.(t|j)sx?$/, to: '.js' } // Convert .ts to .js
 | 
					
						
							|  |  |  |           ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           mod.path = replace(mod.path, terms); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           for (const ex of mod.exports ?? []) { | 
					
						
							|  |  |  |             ex.declaration.module = replace(ex.declaration.module, terms); | 
					
						
							| 
									
										
										
										
											2022-11-10 20:28:08 +00:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2022-11-10 21:27:23 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |           for (const dec of mod.declarations ?? []) { | 
					
						
							|  |  |  |             if (dec.kind === 'class') { | 
					
						
							|  |  |  |               for (const member of dec.members ?? []) { | 
					
						
							|  |  |  |                 if (member.inheritedFrom) { | 
					
						
							|  |  |  |                   member.inheritedFrom.module = replace(member.inheritedFrom.module, terms); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2022-11-10 20:28:08 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-11-16 17:47:34 +00:00
										 |  |  |     }, | 
					
						
							|  |  |  |     // Generate custom VS Code data
 | 
					
						
							|  |  |  |     generateCustomData({ | 
					
						
							|  |  |  |       outdir, | 
					
						
							|  |  |  |       cssFileName: null | 
					
						
							|  |  |  |     }) | 
					
						
							| 
									
										
										
										
											2021-06-24 22:24:54 +00:00
										 |  |  |   ] | 
					
						
							|  |  |  | }; |