33import { exec as execSync } from "child_process"
44import { promisify } from "util"
55import { promises as fs } from "fs"
6- import { join } from "path"
6+ import { join } from "path"
7+ import { tmpdir } from 'os'
78
89const selfPkg = {
910 name : "@webwriter/build" ,
10- version : "1.6.0 "
11+ version : "1.9.1 "
1112}
1213
1314const exec = promisify ( execSync )
1415
1516function tableEscape ( str ) {
16- return str ?. replaceAll ( "|" , "\\|" )
17+ return str ?. replaceAll ( "|" , "\\|" ) ?. replaceAll ( "\n" , "<br>" )
1718}
1819
1920export async function document ( ) {
@@ -26,17 +27,38 @@ async function generateManifest() {
2627 const pkg = JSON . parse ( await fs . readFile ( "package.json" , "utf8" ) )
2728 const pkgExports = pkg ?. exports ?? { }
2829 const widgetPaths = Object . keys ( pkgExports ) . filter ( k => k . startsWith ( "./widgets/" ) ) . map ( k => pkgExports [ k ] ?. source ) . filter ( p => p )
29- const globsPart = widgetPaths . length ? `--globs ${ widgetPaths . map ( p => `"${ p } "` ) . join ( " " ) } ` : ""
30- const { stdout, stderr} = await exec ( `npx @custom-elements-manifest/analyzer analyze --litelement ${ globsPart } ` )
30+ const widgetPathsBare = widgetPaths . map ( p => p . startsWith ( "./" ) ? p . slice ( 2 ) : p )
31+ // const globsPart = widgetPaths.length? `--globs ${widgetPaths.map(p => `"${p}"`).join(" ")}`: ""
32+ const tempPath = await fs . mkdtemp ( join ( tmpdir ( ) , "wwbuild-" ) )
33+ let jsdoctagsScript = ( await ( await fetch ( "https://cdn.jsdelivr.net/npm/@wc-toolkit/jsdoc-tags@1.1.0" ) ) . text ( ) ) ;
34+ await fs . writeFile ( join ( tempPath , "jsdoctags.js" ) , jsdoctagsScript )
35+ let inheritanceScript = ( await ( await fetch ( "https://cdn.jsdelivr.net/npm/@wc-toolkit/cem-inheritance@1.2.2" ) ) . text ( ) ) ;
36+ inheritanceScript = inheritanceScript . replace ( `@wc-toolkit/jsdoc-tags` , `./jsdoctags.js` )
37+ await fs . writeFile ( join ( tempPath , "inheritance.js" ) , inheritanceScript )
38+ const configScript = `
39+ import {cemInheritancePlugin} from "./inheritance.js"
40+ export default {plugins: [cemInheritancePlugin()]}
41+ `
42+ const configPath = join ( tempPath , "custom-elements-manifest.config.mjs" )
43+ await fs . writeFile ( configPath , configScript )
44+ const { stdout, stderr} = await exec ( `npx @custom-elements-manifest/analyzer analyze --litelement --config "${ configPath } "` )
3145 stderr ? console . error ( stderr ) : console . log ( stdout )
46+ try {
47+ const cem = JSON . parse ( await fs . readFile ( "custom-elements.json" , "utf8" ) )
48+ cem . modules = cem . modules . filter ( mod => widgetPathsBare . includes ( mod . path ) )
49+ await fs . writeFile ( "custom-elements.json" , JSON . stringify ( cem , undefined , 2 ) )
50+ }
51+ catch ( err ) {
52+ console . error ( err )
53+ }
3254 console . log ( "Updating package.json" )
3355 pkg . customElements = "custom-elements.json"
3456 pkg . exports = { ...pkg . exports , "./custom-elements.json" : "./custom-elements.json" }
3557 await fs . writeFile ( "./package.json" , JSON . stringify ( pkg , undefined , 2 ) , "utf8" )
3658}
3759
3860function widgetMarkdown ( pkg , manifest , id ) {
39- const pkgExports = pkg . exports
61+ const pkgExports = pkg ? .exports ?? { }
4062
4163const tag = id . replace ( "./widgets/" , "" ) . slice ( 0 , - 2 )
4264const scriptId = id . slice ( 0 , - 1 ) + "js"
@@ -48,16 +70,16 @@ const stylePath = pkgExports[styleId]?.default ?? pkgExports[styleId]
4870const styleLocal = [ pkg . name , styleId . slice ( 2 ) ] . join ( "/" )
4971const styleCDN = new URL ( styleLocal , "https://cdn.jsdelivr.net/npm/" ) . href
5072
51- const editingConfig = pkg ?. editingConfig [ `./widgets/${ tag } ` ]
73+ const editingConfig = pkg ?. editingConfig ?. [ `./widgets/${ tag } ` ] ?? { }
5274const widgetModule = manifest . modules ?. find ( mod => mod . exports . some ( exp => exp . kind === "custom-element-definition" && exp . name === tag ) )
5375const className = widgetModule . exports . find ( exp => exp . kind === "custom-element-definition" && exp . name === tag ) . declaration . name
5476const widgetClass = widgetModule . declarations . find ( decl => decl . kind === "class" && decl . name === className )
55- const publicFields = widgetClass . members . filter ( decl => decl . kind === "field" && ( ! decl . privacy || decl . privacy === "public" ) )
77+ const publicFields = widgetClass ? .members ? .filter ( decl => decl . kind === "field" && ( ! decl . privacy || decl . privacy === "public" ) ) ?? [ ]
5678const excludedMethodNames = [
5779 "connectedCallback" , "disconnectedCallback" , "attributeChangedCallback" , "adoptedCallback" , // standard lifecycle
5880 "shouldUpdate" , "willUpdate" , "update" , "render" , "firstUpdated" , "updated" // lit lifecycle
5981]
60- const publicMethods = widgetClass . members . filter ( decl => decl . kind === "method" && ( ! decl . privacy || decl . privacy === "public" ) && ! excludedMethodNames . includes ( decl . name ) )
82+ const publicMethods = widgetClass ? .members ? .filter ( decl => decl . kind === "method" && ( ! decl . privacy || decl . privacy === "public" ) && ! excludedMethodNames . includes ( decl . name ) ) ?? [ ]
6183
6284const fieldsTemplate = ! publicFields . length ? undefined :
6385`| Name (Attribute Name) | Type | Description | Default | Reflects |
@@ -73,31 +95,31 @@ ${publicMethods.map(field => `| \`${tableEscape(field.name)}\` | ${tableEscape(f
7395
7496*[Methods](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions) allow programmatic access to the widget.*`
7597
76- const slotsTemplate = ! widgetClass . slots ?. length ? undefined :
98+ const slotsTemplate = ! widgetClass ? .slots ?. length ? undefined :
7799`| Name | Description | Content Type |
78100| :--: | :---------: | :----------: |
79- ${ widgetClass . slots . map ( field => `| ${ field . name ? `\`${ tableEscape ( field . name ) } \`` : "*(default)*" } | ${ tableEscape ( field . description ?? "-" ) } | ${ editingConfig ?. content ? tableEscape ( editingConfig . content ) : "-" } |` ) . join ( "\n" ) }
101+ ${ widgetClass ? .slots . map ( field => `| ${ field . name ? `\`${ tableEscape ( field . name ) } \`` : "*(default)*" } | ${ tableEscape ( field . description ?? "-" ) } | ${ editingConfig ?. content ? tableEscape ( editingConfig . content ) : "-" } |` ) . join ( "\n" ) }
80102
81103*[Slots](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_templates_and_slots) define how the content of the widget is rendered.*`
82104
83- const eventsTemplate = ! widgetClass . events ?. length ? undefined :
105+ const eventsTemplate = ! widgetClass ? .events ?. length ? undefined :
84106`| Name | Description |
85107| :--: | :---------: |
86- ${ widgetClass . events . map ( field => `| ${ tableEscape ( field . name ) } | ${ tableEscape ( field . description ?? "-" ) } |` ) . join ( "\n" ) }
108+ ${ widgetClass ? .events . map ( field => `| ${ tableEscape ( field . name ) } | ${ tableEscape ( field . description ?? "-" ) } |` ) . join ( "\n" ) }
87109
88110*[Events](https://developer.mozilla.org/en-US/docs/Web/Events) are dispatched by the widget after certain triggers.*`
89111
90- const cssPropertiesTemplate = ! widgetClass . cssProperties ?. length ? undefined :
112+ const cssPropertiesTemplate = ! widgetClass ? .cssProperties ?. length ? undefined :
91113`| Name | Description |
92114| :--: | :---------: |
93- ${ widgetClass . cssProperties . map ( field => `| ${ tableEscape ( field . name ) } | ${ tableEscape ( field . description ?? "-" ) } |` ) . join ( "\n" ) }
115+ ${ widgetClass ? .cssProperties . map ( field => `| ${ tableEscape ( field . name ) } | ${ tableEscape ( field . description ?? "-" ) } |` ) . join ( "\n" ) }
94116
95117*[Custom CSS properties](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_cascading_variables/Using_CSS_custom_properties) offer defined customization of the widget's style.*`
96118
97- const cssPartsTemplate = ! widgetClass . cssParts ?. length ? undefined :
119+ const cssPartsTemplate = ! widgetClass ? .cssParts ?. length ? undefined :
98120`| Name | Description |
99121| :--: | :---------: |
100- ${ widgetClass . cssParts . map ( field => `| ${ tableEscape ( field . name ) } | ${ tableEscape ( field . description ?? "-" ) } |` ) . join ( "\n" ) }
122+ ${ widgetClass ? .cssParts . map ( field => `| ${ tableEscape ( field . name ) } | ${ tableEscape ( field . description ?? "-" ) } |` ) . join ( "\n" ) }
101123
102124*[CSS parts](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_shadow_parts) allow freely styling internals of the widget with CSS.*`
103125
@@ -118,8 +140,8 @@ const templates = {
118140 "editing config" : editingConfigTemplate
119141}
120142
121- const nonemptyNames = Object . keys ( templates ) . filter ( k => templates [ k ] )
122- const emptyNames = Object . keys ( templates ) . filter ( k => ! templates [ k ] )
143+ const nonemptyNames = Object . keys ( templates ) ? .filter ( k => templates [ k ] ) ?? [ ]
144+ const emptyNames = Object . keys ( templates ) ? .filter ( k => ! templates [ k ] ) ?? [ ]
123145
124146let emptyTemplate = ""
125147if ( emptyNames . length >= 2 ) {
@@ -130,7 +152,7 @@ else if(emptyNames.length === 1) {
130152}
131153
132154return `## \`${ className } \` (\`<${ tag } >\`)
133- ${ widgetClass . description }
155+ ${ widgetClass ? .description }
134156
135157### Usage
136158
@@ -208,7 +230,7 @@ const snippetsTemplate = !snippetIDs.length? "":
208230
209231| Name | Import Path |
210232| :--: | :---------: |
211- ${ snippetIDs . map ( id => `| ${ id . replace ( "./snippets/" , "" ) . replace ( ".html" , "" ) . split ( "-" ) . map ( part => part [ 0 ] . toUpperCase ( ) + part . slice ( 1 ) ) . join ( " " ) } | ${ pkg . name + id . slice ( 1 ) } |` ) . join ( "\n" ) } `
233+ ${ snippetIDs . map ( id => `| ${ id . replace ( "./snippets/" , "" ) . replace ( ".html" , "" ) . split ( "-" ) . map ( part => part [ 0 ] . toUpperCase ( ) + part . slice ( 1 ) ) . join ( " " ) } | \` ${ pkg . name + id . slice ( 1 ) } \` |` ) . join ( "\n" ) } `
212234
213235const themesTemplate = ! themeIDs . length ? "" :
214236`## Themes
@@ -219,9 +241,9 @@ const themesTemplate = !themeIDs.length? "":
219241${ themeIDs . map ( id => `| ${ id . replace ( "./themes/" , "" ) } | ${ pkg . name + id . slice ( 1 ) } |` ) . join ( "\n" ) } `
220242
221243const prettyName =
222- pkg ?. editingConfig [ "." ] ?. label ?. _ ?? pkg . name . slice ( 1 ) . split ( "/" ) [ 1 ] . split ( "-" ) . map ( part => part [ 0 ] . toUpperCase ( ) + part . slice ( 1 ) )
244+ pkg ?. editingConfig ?. [ "." ] ?. label ?. _ ?? pkg . name . slice ( 1 ) . split ( "/" ) [ 1 ] . split ( "-" ) . map ( part => part [ 0 ] . toUpperCase ( ) + part . slice ( 1 ) ) . join ( " " )
223245
224- const description = pkg ?. editingConfig [ "." ] ?. description ?. _ ?? pkg ?. description
246+ const description = pkg ?. editingConfig ?. [ "." ] ?. description ?. _ ?? pkg ?. description
225247
226248const template =
227249`# ${ prettyName } (\`${ pkg . name } @${ pkg . version } \`)
0 commit comments