@webority/canvas-kit 0.91.0 → 0.92.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/dist/build.js +3 -3
- package/dist/drawn.js +1 -1
- package/dist/kitModule.js +1 -1
- package/dist/manifest.d.ts +4 -0
- package/dist/manifest.js +1 -1
- package/dist/meta.d.ts +4 -0
- package/dist/metaCheck.d.ts +6 -2
- package/dist/metaCheck.js +1 -1
- package/dist/metas.js +2 -2
- package/dist/spec.d.ts +2 -0
- package/package.json +1 -1
package/dist/build.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{findPackageDir as e,readJson as t,toPosix as n}from"./files.js";import{KIT_MODULE_EXTERNALS as r}from"./kitModule.js";import{libraryFiles as i,readManifest as a}from"./manifest.js";import{digest as o,writeReleaseFolder as s}from"./release.js";import{existsSync as c}from"node:fs";import{dirname as l,join as u,resolve as d}from"node:path";import{fileURLToPath as f}from"node:url";import{build as p}from"vite";var m=19,h=[`react-redux`,`react-router-dom`,`axios`],g=[`kit`,`platform`,`libraryPackage`,`components`,`tokens`,`rolesFile`,`styles`,`rendererProtocolVersion`],_=[`kit`,`platform`,`libraryPackage`,`components`,`tokens`,`rendererProtocolVersion`],v=`canvas-kit:entry`,y=`\0${v}`,b=u(l(f(import.meta.url)),`kitModule.js`),x={"process.env.NODE_ENV":JSON.stringify(`production`),"process.env":`{}`,__DEV__:`false`},S=/(?<![\w$."'`])(process\.env|__DEV__)(?![\w$])/;function C(e){let n=t(e);if(typeof n!=`object`||!n||Array.isArray(n))throw Error(`${e} must be a JSON object.`);if(n.entry!==void 0)throw Error(`${e}: A kit lists its components with components, a glob of .meta.js files; entry is retired.`);for(let t of Object.keys(n))if(!g.includes(t))throw Error(`${e} has the unknown key ${t}. The keys are ${g.join(`, `)}.`);for(let t of _)if(n[t]===void 0)throw Error(`${e} needs the key ${t}.`);for(let t of[`kit`,`platform`,`libraryPackage`,`components`,`tokens`])if(typeof n[t]!=`string`)throw Error(`${e}: ${t} must be a string.`);for(let t of[`rolesFile`])if(n[t]!==void 0&&typeof n[t]!=`string`)throw Error(`${e}: ${t} must be a string path.`);if(n.styles!==void 0){if(!Array.isArray(n.styles)||n.styles.some(e=>typeof e!=`string`||e===``))throw Error(`${e}: styles must be a list of style file paths.`);for(let t of n.styles){if(!/\.(css|scss)$/.test(t))throw Error(`${e}: styles names ${t}, which is not a .css or .scss file.`);if(!c(d(l(e),t)))throw Error(`${e}: styles names ${t}, which does not exist.`)}}return n}function w(n){let r=e(n,`react`);if(!r)throw Error(`react is not installed for ${n}. Run pnpm install there.`);let{version:i}=t(u(r,`package.json`));if(Number(String(i).split(`.`)[0])!==m)throw Error(`The product uses React ${i}; the Canvas renderer runs React ${m}. Pin react to ${m}.x and rebuild.`)}function T(e){let{version:n}=t(u(e,`package.json`));if(!n)throw Error(`${u(e,`package.json`)} needs a version; the release is stamped with it.`);return n}function E({styleFiles:e,libraryFile:t,chromeFile:r,manifest:i,libraryNames:a,chromeNames:o,productModules:s}){let c=e.map(e=>`import ${JSON.stringify(n(e))};`);
|
|
2
|
-
`)}function D(e){return{name:`canvas-kit-entry`,resolveId(e){return e===v?y:null},load(t){return t===y?e:null}}}function O(e){let t=`${n(u(e,`src`,`services`))}/`;return{name:`canvas-kit-banned-imports`,transform(e,r){let i=n(r.split(`?`)[0]),a=h.find(e=>i.includes(`/node_modules/${e}/`));if(a)throw Error(`The kit imports ${a} (${i}). A kit draws from its props only; the container that renders it holds the state and the calls.`);if(i.startsWith(t))throw Error(`The kit imports ${i}, which is in src/services. A kit draws from its props only; move the call into the container.`);return null}}}async function k({root:e,kit:t,platform:n,styleFiles:i,libraryFile:a,chromeFile:o,libraryNames:s,chromeNames:c,productModules:l,manifest:u}){let d=r[n],f=await p({configFile:!1,root:e,logLevel:`warn`,publicDir:!1,envDir:!1,define:x,plugins:[D(E({styleFiles:i,libraryFile:a,chromeFile:o,manifest:u,libraryNames:s,chromeNames:c,productModules:l})),O(e)],esbuild:{jsx:`automatic`,jsxImportSource:`react`,include:/\.[cm]?[jt]sx?$/},build:{write:!1,minify:!0,target:`es2022`,cssCodeSplit:!1,lib:{entry:v,formats:[`es`],fileName:()=>`kit.js`},rollupOptions:{input:v,external:e=>d.some(t=>e===t||e.startsWith(`${t}/`)),output:{
|
|
3
|
-
`);return{script:h.code,styles:y}}async function A({configFile:e,outDir:t,styleKeysFile:n,phoneRendererSupportFile:r}){let u=d(e),f=d(t);if(c(f))throw Error(`${f} already exists. A release folder is never overwritten; choose a new folder.`);let p=C(u),m=l(u);if(p.platform!==`Phone`&&r!==void 0)throw Error(`Only a Phone kit reads --phone-renderer-support; a Web kit takes no phone support file.`);w(m);let h=p.rolesFile===void 0?void 0:d(m,p.rolesFile),{manifest:g,warnings:_,phoneChromeNames:v,productModules:y}=await a({projectRoot:m,kit:p.kit,platform:p.platform,components:p.components,tokens:p.tokens,libraryPackage:p.libraryPackage,rolesFile:h,rendererProtocolVersion:p.rendererProtocolVersion,phoneRendererSupportFile:r===void 0?void 0:d(r),styleKeysFile:n===void 0?void 0:d(n)}),b=i(m,p.libraryPackage),x=T(m),S=g.components.filter(({source:e,name:t})=>e===p.libraryPackage&&!v.includes(t)).map(({name:e})=>e),{script:E,styles:D}=await k({root:m,kit:p.kit,platform:p.platform,styleFiles:(p.styles??[]).map(e=>d(m,e)),libraryFile:b.entryFile,chromeFile:b.canvasKitFile,libraryNames:S,chromeNames:v,productModules:y,manifest:g}),O={"manifest.json":`${JSON.stringify(g,null,2)}\n`,"kit.js":E,"kit.css":D},A={name:p.kit,version:x,platform:p.platform,kitModuleVersion:2,rendererProtocolVersion:p.rendererProtocolVersion,library:g.library,files:Object.fromEntries(Object.entries(O).map(([e,t])=>[e,o(t)]))};return s(f,O,A),{outDir:f,release:A,manifest:g,warnings:_}}export{A as buildKitRelease,C as readConfig};
|
|
1
|
+
import{findPackageDir as e,readJson as t,toPosix as n}from"./files.js";import{KIT_MODULE_EXTERNALS as r}from"./kitModule.js";import{libraryFiles as i,readManifest as a}from"./manifest.js";import{digest as o,writeReleaseFolder as s}from"./release.js";import{existsSync as c}from"node:fs";import{dirname as l,join as u,resolve as d}from"node:path";import{fileURLToPath as f}from"node:url";import{build as p}from"vite";var m=19,h=[`react-redux`,`react-router-dom`,`axios`],g=[`kit`,`platform`,`libraryPackage`,`components`,`tokens`,`rolesFile`,`styles`,`rendererProtocolVersion`],_=[`kit`,`platform`,`libraryPackage`,`components`,`tokens`,`rendererProtocolVersion`],v=`canvas-kit:entry`,y=`\0${v}`,b=u(l(f(import.meta.url)),`kitModule.js`),x={"process.env.NODE_ENV":JSON.stringify(`production`),"process.env":`{}`,__DEV__:`false`},S=/(?<![\w$."'`])(process\.env|__DEV__)(?![\w$])/;function C(e){let n=t(e);if(typeof n!=`object`||!n||Array.isArray(n))throw Error(`${e} must be a JSON object.`);if(n.entry!==void 0)throw Error(`${e}: A kit lists its components with components, a glob of .meta.js files; entry is retired.`);for(let t of Object.keys(n))if(!g.includes(t))throw Error(`${e} has the unknown key ${t}. The keys are ${g.join(`, `)}.`);for(let t of _)if(n[t]===void 0)throw Error(`${e} needs the key ${t}.`);for(let t of[`kit`,`platform`,`libraryPackage`,`components`,`tokens`])if(typeof n[t]!=`string`)throw Error(`${e}: ${t} must be a string.`);for(let t of[`rolesFile`])if(n[t]!==void 0&&typeof n[t]!=`string`)throw Error(`${e}: ${t} must be a string path.`);if(n.styles!==void 0){if(!Array.isArray(n.styles)||n.styles.some(e=>typeof e!=`string`||e===``))throw Error(`${e}: styles must be a list of style file paths.`);for(let t of n.styles){if(!/\.(css|scss)$/.test(t))throw Error(`${e}: styles names ${t}, which is not a .css or .scss file.`);if(!c(d(l(e),t)))throw Error(`${e}: styles names ${t}, which does not exist.`)}}return n}function w(n){let r=e(n,`react`);if(!r)throw Error(`react is not installed for ${n}. Run pnpm install there.`);let{version:i}=t(u(r,`package.json`));if(Number(String(i).split(`.`)[0])!==m)throw Error(`The product uses React ${i}; the Canvas renderer runs React ${m}. Pin react to ${m}.x and rebuild.`)}function T(e){let{version:n}=t(u(e,`package.json`));if(!n)throw Error(`${u(e,`package.json`)} needs a version; the release is stamped with it.`);return n}function E({styleFiles:e,libraryFile:t,chromeFile:r,manifest:i,libraryNames:a,chromeNames:o,productModules:s}){let c=[...s],l=[...a.map(({fixedProps:e})=>e),...c.map(([,{fixedProps:e}])=>e)].some(e=>e!==void 0),u=e.map(e=>`import ${JSON.stringify(n(e))};`);l&&u.push(`import { createElement } from "react";`),u.push(`import { ${l?`defineKit, withFixedProps`:`defineKit`} } from ${JSON.stringify(n(b))};`),c.forEach(([,{module:e,exportName:t}],r)=>{u.push(`import { ${t} as product${r} } from ${JSON.stringify(n(e))};`)});let d=[...new Set(a.map(({exportName:e})=>e))];d.length>0&&u.push(`import { ${d.join(`, `)} } from ${JSON.stringify(n(t))};`),o.length>0&&u.push(`import { ${o.join(`, `)} } from ${JSON.stringify(n(r))};`);let f=(e,t,n)=>n===void 0?e===t?e:`${e}: ${t}`:`${e}: withFixedProps(createElement, ${t}, ${JSON.stringify(n)}, ${JSON.stringify(e)})`,p=[...a.map(({name:e,exportName:t,fixedProps:n})=>f(e,t,n)),...o,...c.map(([e,{fixedProps:t}],n)=>f(e,`product${n}`,t))],m=Object.fromEntries(i.components.filter(({marker:e})=>e!==null).map(({name:e,marker:t})=>[e,t]));return u.push(`export default defineKit({ components: { ${p.join(`, `)} }, markers: ${JSON.stringify(m)}, tokenValues: ${JSON.stringify(i.tokenValues)}, manifest: ${JSON.stringify(i)} });`,``),u.join(`
|
|
2
|
+
`)}function D(e){return{name:`canvas-kit-entry`,resolveId(e){return e===v?y:null},load(t){return t===y?e:null}}}function O(e){let t=`${n(u(e,`src`,`services`))}/`;return{name:`canvas-kit-banned-imports`,transform(e,r){let i=n(r.split(`?`)[0]),a=h.find(e=>i.includes(`/node_modules/${e}/`));if(a)throw Error(`The kit imports ${a} (${i}). A kit draws from its props only; the container that renders it holds the state and the calls.`);if(i.startsWith(t))throw Error(`The kit imports ${i}, which is in src/services. A kit draws from its props only; move the call into the container.`);return null}}}async function k({root:e,kit:t,platform:n,styleFiles:i,libraryFile:a,chromeFile:o,libraryNames:s,chromeNames:c,productModules:l,manifest:u}){let d=r[n],f=await p({configFile:!1,root:e,logLevel:`warn`,publicDir:!1,envDir:!1,define:x,plugins:[D(E({styleFiles:i,libraryFile:a,chromeFile:o,manifest:u,libraryNames:s,chromeNames:c,productModules:l})),O(e)],esbuild:{jsx:`automatic`,jsxImportSource:`react`,include:/\.[cm]?[jt]sx?$/},build:{write:!1,minify:!0,target:`es2022`,cssCodeSplit:!1,lib:{entry:v,formats:[`es`],fileName:()=>`kit.js`},rollupOptions:{input:v,external:e=>d.some(t=>e===t||e.startsWith(`${t}/`)),output:{codeSplitting:!1}}}}),m=(Array.isArray(f)?f:[f]).flatMap(e=>e.output),h=m.find(e=>e.type===`chunk`&&e.isEntry);if(!h)throw Error(`The bundle of ${t} has no entry module.`);let g=S.exec(h.code);if(g)throw Error(`The bundle of ${t} still reads ${g[1]}, which the renderer does not define.`);let _=m.filter(e=>e.type===`chunk`&&!e.isEntry);if(_.length>0)throw Error(`The bundle of ${t} split ${_.map(e=>e.fileName).join(`, `)} out of kit.js; a kit must be one file.`);let y=m.filter(e=>e.type===`asset`&&e.fileName.endsWith(`.css`)).map(e=>typeof e.source==`string`?e.source:Buffer.from(e.source).toString(`utf8`)).join(`
|
|
3
|
+
`);return{script:h.code,styles:y}}async function A({configFile:e,outDir:t,styleKeysFile:n,phoneRendererSupportFile:r}){let u=d(e),f=d(t);if(c(f))throw Error(`${f} already exists. A release folder is never overwritten; choose a new folder.`);let p=C(u),m=l(u);if(p.platform!==`Phone`&&r!==void 0)throw Error(`Only a Phone kit reads --phone-renderer-support; a Web kit takes no phone support file.`);w(m);let h=p.rolesFile===void 0?void 0:d(m,p.rolesFile),{manifest:g,warnings:_,phoneChromeNames:v,productModules:y}=await a({projectRoot:m,kit:p.kit,platform:p.platform,components:p.components,tokens:p.tokens,libraryPackage:p.libraryPackage,rolesFile:h,rendererProtocolVersion:p.rendererProtocolVersion,phoneRendererSupportFile:r===void 0?void 0:d(r),styleKeysFile:n===void 0?void 0:d(n)}),b=i(m,p.libraryPackage),x=T(m),S=g.components.filter(({source:e,name:t})=>e===p.libraryPackage&&!v.includes(t)).map(({name:e,component:t,fixedProps:n})=>({name:e,exportName:t??e,...n===void 0?{}:{fixedProps:n}})),{script:E,styles:D}=await k({root:m,kit:p.kit,platform:p.platform,styleFiles:(p.styles??[]).map(e=>d(m,e)),libraryFile:b.entryFile,chromeFile:b.canvasKitFile,libraryNames:S,chromeNames:v,productModules:y,manifest:g}),O={"manifest.json":`${JSON.stringify(g,null,2)}\n`,"kit.js":E,"kit.css":D},A={name:p.kit,version:x,platform:p.platform,kitModuleVersion:2,rendererProtocolVersion:p.rendererProtocolVersion,library:g.library,files:Object.fromEntries(Object.entries(O).map(([e,t])=>[e,o(t)]))};return s(f,O,A),{outDir:f,release:A,manifest:g,warnings:_}}export{A as buildKitRelease,C as readConfig};
|
package/dist/drawn.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import{readJson as e,toPosix as t}from"./files.js";import{TSC as n,specifierOf as r}from"./metaCheck.js";import{existsSync as i,mkdirSync as a,rmSync as o,writeFileSync as s}from"node:fs";import{join as c}from"node:path";import{execFileSync as l}from"node:child_process";var u=`src/components/not-drawn.json`;function d({root:e,typesFile:i}){let u=c(e,`node_modules`,`.canvas-kit-exports-${process.pid}`);try{a(u,{recursive:!0});let e=[`import type * as L from "${r(i)}";`,`type IsComponent<T> = 0 extends 1 & T ? true : T extends (...args: never[]) => unknown ? true : T extends abstract new (...args: never[]) => unknown ? true : T extends { $$typeof: symbol } ? true : false;`,`type Named<K> = K extends string ? (K extends Capitalize<K> ? (K extends Uncapitalize<K> ? never : K) : never) : never;`,`type Components = { [K in keyof typeof L]: Named<K> extends never ? never : IsComponent<(typeof L)[K]> extends true ? K : never }[keyof typeof L];`,`export const components: never = null as unknown as { [K in Components]: K };`];s(c(u,`check.ts`),`${e.join(`
|
|
2
2
|
`)}\n`),s(c(u,`tsconfig.json`),JSON.stringify({compilerOptions:{strict:!0,noEmit:!0,allowJs:!0,checkJs:!1,jsx:`react-jsx`,module:`esnext`,moduleResolution:`bundler`,target:`es2022`,skipLibCheck:!0,noErrorTruncation:!0,types:[]},files:[`check.ts`]}));let o=``;try{l(process.execPath,[n,`-p`,c(u,`tsconfig.json`),`--pretty`,`false`],{cwd:u,encoding:`utf8`,stdio:`pipe`})}catch(e){o=String(e.stdout??``)+String(e.stderr??``)}let d=o.split(/\r?\n/).find(e=>/^check\.ts\(5,\d+\): error TS2322: /.test(e)),f=d&&/Type '(\{[^']*\})' is not assignable to type 'never'/.exec(d);if(!f)throw Error(`tsc could not list the components ${t(i)} exports: ${o.split(/\r?\n/).slice(0,20).join(`
|
|
3
|
-
`)}`);return[...new Set([...f[1].matchAll(/(\w+): "\w+"/g)].map(e=>e[1]))].sort()}finally{o(u,{recursive:!0,force:!0})}}function f(t){if(!i(t))return{};let n=e(t);if(typeof n!=`object`||!n||Array.isArray(n))throw Error(`${t} must be an object from component name to the reason the kit does not draw it.`);let r=Object.entries(n).filter(([,e])=>typeof e!=`string`||e.trim()===``).map(([e])=>e);if(r.length>0)throw Error(`${t}: ${r.join(`, `)} need a reason the kit does not draw them.`);return n}function p({libraryPackage:e,exported:t,
|
|
3
|
+
`)}`);return[...new Set([...f[1].matchAll(/(\w+): "\w+"/g)].map(e=>e[1]))].sort()}finally{o(u,{recursive:!0,force:!0})}}function f(t){if(!i(t))return{};let n=e(t);if(typeof n!=`object`||!n||Array.isArray(n))throw Error(`${t} must be an object from component name to the reason the kit does not draw it.`);let r=Object.entries(n).filter(([,e])=>typeof e!=`string`||e.trim()===``).map(([e])=>e);if(r.length>0)throw Error(`${t}: ${r.join(`, `)} need a reason the kit does not draw them.`);return n}function p({libraryPackage:e,exported:t,drawnNames:n,notDrawn:r}){let i=new Set(t),a=[...new Map(n.map(e=>[`${e.name} ${e.component}`,e])).values()],o=new Set(a.map(({component:e})=>e)),s=Object.keys(r),c=[],l=t.filter(e=>!o.has(e)&&!(e in r));l.length>0&&c.push(`${e} exports ${l.join(`, `)} with no meta. Write a meta for each, or list it in ${u} with the reason the kit does not draw it.`);let d=s.filter(e=>o.has(e));d.length>0&&c.push(`${u} lists ${d.join(`, `)}, which have a meta. A component is drawn or not drawn; remove one.`);let f=s.filter(e=>!i.has(e));f.length>0&&c.push(`${u} lists ${f.join(`, `)}, which ${e} does not export as components. Remove them.`);let p=a.filter(({component:e})=>!i.has(e));if(p.length>0){let t=p.map(({name:e,component:t})=>e===t?e:`${e} (draws ${t})`);c.push(`${t.join(`, `)} have a meta, but ${e} does not export them as components.`)}if(c.length>0)throw Error(c.join(`
|
|
4
4
|
`))}export{u as NOT_DRAWN_FILE,p as checkDrawn,d as componentExports,f as readNotDrawn};
|
package/dist/kitModule.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=2,t=Object.freeze({Web:[`react`,`react-dom`,`react/jsx-runtime`],Phone:[`react`,`react-dom`,`react/jsx-runtime`,`react-native`,`react-native-svg`,`@webority/mobile-core`,`expo-image`,`expo-haptics`,`expo-file-system`,`react-hook-form`,`react-native-gesture-handler`,`react-native-keyboard-controller`,`react-native-reanimated`,`react-native-safe-area-context`,`react-native-worklets`]});function n({components:e,markers:n,tokenValues:r,manifest:i}){if(typeof i!=`object`||!i)throw Error(`defineKit needs the manifest, the kit's manifest object.`);if(!Object.hasOwn(t,i.platform))throw Error(`defineKit: platform ${JSON.stringify(i.platform)} is not Web or Phone.`);if(typeof e!=`object`||!e)throw Error(`defineKit: components must be an object of React components.`);let a={};for(let[t,n]of Object.entries(e)){if(n===null||typeof n!=`function`&&typeof n!=`object`)throw Error(`defineKit: component ${t} is not a React component.`);a[t]=n}if(typeof n!=`object`||!n)throw Error(`defineKit: markers must be an object of marker names by component name.`);for(let[e,t]of Object.entries(n))if(!Object.hasOwn(a,e)||typeof t!=`string`||t===``)throw Error(`defineKit: the marker of ${e} must name a component with a non-empty marker.`);if(r===void 0||r!==null&&typeof r!=`object`)throw Error(`defineKit: tokenValues must be an object, or null on a release built before it existed.`);return{components:Object.freeze(a),markers:Object.freeze({...n}),tokenValues:r,manifest:i}}export{t as KIT_MODULE_EXTERNALS,
|
|
1
|
+
var e=2,t=Object.freeze({Web:[`react`,`react-dom`,`react/jsx-runtime`],Phone:[`react`,`react-dom`,`react/jsx-runtime`,`react-native`,`react-native-svg`,`@webority/mobile-core`,`expo-image`,`expo-haptics`,`expo-file-system`,`react-hook-form`,`react-native-gesture-handler`,`react-native-keyboard-controller`,`react-native-reanimated`,`react-native-safe-area-context`,`react-native-worklets`]});function n(e,t,n,r){let i=r=>e(t,{...r,...n});return i.displayName=r,i}function r({components:e,markers:n,tokenValues:r,manifest:i}){if(typeof i!=`object`||!i)throw Error(`defineKit needs the manifest, the kit's manifest object.`);if(!Object.hasOwn(t,i.platform))throw Error(`defineKit: platform ${JSON.stringify(i.platform)} is not Web or Phone.`);if(typeof e!=`object`||!e)throw Error(`defineKit: components must be an object of React components.`);let a={};for(let[t,n]of Object.entries(e)){if(n===null||typeof n!=`function`&&typeof n!=`object`)throw Error(`defineKit: component ${t} is not a React component.`);a[t]=n}if(typeof n!=`object`||!n)throw Error(`defineKit: markers must be an object of marker names by component name.`);for(let[e,t]of Object.entries(n))if(!Object.hasOwn(a,e)||typeof t!=`string`||t===``)throw Error(`defineKit: the marker of ${e} must name a component with a non-empty marker.`);if(r===void 0||r!==null&&typeof r!=`object`)throw Error(`defineKit: tokenValues must be an object, or null on a release built before it existed.`);return{components:Object.freeze(a),markers:Object.freeze({...n}),tokenValues:r,manifest:i}}export{t as KIT_MODULE_EXTERNALS,r as defineKit,e as kitModuleVersion,n as withFixedProps};
|
package/dist/manifest.d.ts
CHANGED
|
@@ -54,6 +54,10 @@ export interface CanvasManifestComponent {
|
|
|
54
54
|
takesAction: string[];
|
|
55
55
|
// The package the component comes from. A product's own component names its source file.
|
|
56
56
|
source: string;
|
|
57
|
+
// The export the component draws, when it is not its name.
|
|
58
|
+
component?: string;
|
|
59
|
+
// Props the kit sets on every placement; code export writes them on the export.
|
|
60
|
+
fixedProps?: Record<string, unknown>;
|
|
57
61
|
role?: "title" | "navigation";
|
|
58
62
|
// Present on every Web component; absent on Phone until its metas carry usage.
|
|
59
63
|
usage?: ComponentUsage;
|
package/dist/manifest.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{findPackageDir as e,readJson as t,toPosix as n}from"./files.js";import"./kitModule.js";import{checkMetaTypes as r}from"./metaCheck.js";import{NOT_DRAWN_FILE as i,checkDrawn as a,componentExports as o,readNotDrawn as s}from"./drawn.js";import{componentModuleOf as c,manifestComponent as l,readMetas as u}from"./metas.js";import{applyPhoneActions as d,phoneChromeEntries as f,phoneIcons as p}from"./phone.js";import{tokensFromV2 as m,webIcons as h}from"./tokens.js";import{existsSync as g}from"node:fs";import{join as _,relative as v,resolve as y}from"node:path";var b=/^[a-z][a-z0-9-]{1,39}$/,ee=[`Web`,`Phone`],x=[`title`,`navigation`],S={Web:`WeborityWeb`,Phone:`WeborityPhone`},C={Web:`web`,Phone:`phone`};function w(n,r){let i=_(n,`package.json`),a=g(i)&&t(i).name===r,o=a?n:e(n,r);if(!o)throw Error(`${r} is not installed for ${n}. Run pnpm install there.`);let s=t(_(o,`package.json`)),c=(e,t)=>{if(typeof e==`string`)return t==="default"?e:void 0;if(!(!e||typeof e!=`object`))return typeof e[t]==`string`?e[t]:c(e.import,t)??c(e.default,t)},l=s.exports?.[`.`],u=s.types??c(l,`types`),d=c(l,`default`)??s.main;if(!u)throw Error(`${r} declares no types, and the manifest reads its declaration files.`);if(!d)throw Error(`${r} declares no entry file for its runtime.`);let f=c(s.exports?.[`./canvasKit`],`default`);return{dir:o,pkg:s,isSelf:a,typesFile:_(o,u),entryFile:_(o,d),canvasKitFile:f?_(o,f):null}}function T(e,n,r){let i=t(_(e,`package.json`)),a=i.dependencies?.[n]??i.devDependencies?.[n];if(/^\d+\.\d+\.\d+$/.test(a??``)&&a!==r)throw Error(`${n} is pinned to ${a} in package.json but ${r} is installed. Run pnpm install first.`)}function E(e,n,r){let i=e.pkg.exports?.[`./canvas-kit/*`];if(typeof i!=`string`)throw Error(`${n} exports no ./canvas-kit/*; a product kit takes the library's components from its kit release.`);let a=_(e.dir,i.replace(`*`,`manifest.json`)),o=t(a);if(!(o?.kind===S[r]&&o.platform===r&&Array.isArray(o.components)&&Array.isArray(o.icons)))throw Error(`${a} is not a ${r} library kit release.`);return o}function D(e,t){let n=C[t];for(let{meta:r,file:i}of e)if(!r.platforms?.includes(n))throw Error(`${i}: platforms: a ${t} kit lists only components that list ${n}`)}function O(e,n){if(!n)return;let r=t(n);if(typeof r!=`object`||!r||Array.isArray(r))throw Error(`${n} must be an object from component name to role.`);for(let[t,i]of Object.entries(r)){let r=e.find(e=>e.name===t);if(!r)throw Error(`${n} names ${t}, which the kit does not have.`);if(!x.includes(i))throw Error(`${n}: ${t} has role ${JSON.stringify(i)}; a role is title or navigation.`);r.role=i}}function k(e){let n=t(e);if(!Array.isArray(n)||n.some(e=>typeof e?.name!=`string`))throw Error(`${e} must be the style key table: a list of style keys, each with a name.`);return n}function A(e){let n=t(e);if(n?.schema!==1)throw Error(`${e} has schema ${n?.schema}; this reader reads schema 1.`);if(!n.itemActions)throw Error(`${e} has no itemActions; the phone kit's action lists come from it.`);return{flags:n.styleKeys??{},itemActions:n.itemActions}}function j(e,t,n){let r=e.map(({name:e})=>e),i=r.filter(e=>typeof t[e]!=`boolean`),a=Object.keys(t).filter(e=>!r.includes(e));if(i.length>0||a.length>0)throw Error(`${n} must list exactly the style keys of the style key table, each true or false. Missing or not a boolean: ${i.join(`, `)||`none`}. Not in the table: ${a.join(`, `)||`none`}.`)}function te(e,t){return e.map(({name:e,type:n,values:r,appliesTo:i,description:a})=>({name:e,type:n,values:r,appliesTo:i,...t?{phoneSupported:t[e]}:{},description:a}))}var ne=(e,t)=>e.name<t.name?-1:+(e.name>t.name);async function M({projectRoot:t,kit:g,platform:x,entry:C,components:M,tokens:N,libraryPackage:P,rolesFile:F,rendererProtocolVersion:I,phoneRendererSupportFile:L,styleKeysFile:R}){if(!b.test(g??``))throw Error(`kit ${JSON.stringify(g)} must be 2 to 40 characters: lowercase letters, digits and hyphens, starting with a letter.`);if(!ee.includes(x))throw Error(`platform must be Web or Phone, not ${JSON.stringify(x)}.`);if(!Number.isInteger(I)||I<1)throw Error(`rendererProtocolVersion must be a positive integer, not ${JSON.stringify(I)}.`);if(C!==void 0)throw Error(`A kit lists its components with components, a glob of .meta.js files; entry is retired.`);if(typeof M!=`string`||M===``||typeof N!=`string`||N===``)throw Error(`A kit needs components, a glob of .meta.js files, and tokens, the path of its webority-theme-tokens/2 file.`);let z=y(t),B=w(z,P),V=B.isSelf;if(x===`Phone`&&!L&&!V)throw Error(`A Phone product kit needs phoneRendererSupportFile, the phone renderer's support file; only a phone library's own kit release builds without it.`);V||T(z,P,B.pkg.version);let H=L?A(L):null,U=x===`Phone`?H:null,W=R?k(R):null;W&&H&&j(W,H.flags,L);let G=V?null:E(B,P,x),K;K=V?x===`Web`?h(_(B.dir,`dist`)):p(_(B.dir,`lib`,`typescript`,`module`,`components`,`AppIcon`,`catalog.g.d.ts`)):G.icons;let q=[];V&&(q=await u({root:z,components:M,icons:K}),D(q,x),a({libraryPackage:P,exported:o({root:z,typesFile:B.typesFile}),
|
|
1
|
+
import{findPackageDir as e,readJson as t,toPosix as n}from"./files.js";import"./kitModule.js";import{checkMetaTypes as r}from"./metaCheck.js";import{NOT_DRAWN_FILE as i,checkDrawn as a,componentExports as o,readNotDrawn as s}from"./drawn.js";import{componentModuleOf as c,manifestComponent as l,readMetas as u}from"./metas.js";import{applyPhoneActions as d,phoneChromeEntries as f,phoneIcons as p}from"./phone.js";import{tokensFromV2 as m,webIcons as h}from"./tokens.js";import{existsSync as g}from"node:fs";import{join as _,relative as v,resolve as y}from"node:path";var b=/^[a-z][a-z0-9-]{1,39}$/,ee=[`Web`,`Phone`],x=[`title`,`navigation`],S={Web:`WeborityWeb`,Phone:`WeborityPhone`},C={Web:`web`,Phone:`phone`};function w(n,r){let i=_(n,`package.json`),a=g(i)&&t(i).name===r,o=a?n:e(n,r);if(!o)throw Error(`${r} is not installed for ${n}. Run pnpm install there.`);let s=t(_(o,`package.json`)),c=(e,t)=>{if(typeof e==`string`)return t==="default"?e:void 0;if(!(!e||typeof e!=`object`))return typeof e[t]==`string`?e[t]:c(e.import,t)??c(e.default,t)},l=s.exports?.[`.`],u=s.types??c(l,`types`),d=c(l,`default`)??s.main;if(!u)throw Error(`${r} declares no types, and the manifest reads its declaration files.`);if(!d)throw Error(`${r} declares no entry file for its runtime.`);let f=c(s.exports?.[`./canvasKit`],`default`);return{dir:o,pkg:s,isSelf:a,typesFile:_(o,u),entryFile:_(o,d),canvasKitFile:f?_(o,f):null}}function T(e,n,r){let i=t(_(e,`package.json`)),a=i.dependencies?.[n]??i.devDependencies?.[n];if(/^\d+\.\d+\.\d+$/.test(a??``)&&a!==r)throw Error(`${n} is pinned to ${a} in package.json but ${r} is installed. Run pnpm install first.`)}function E(e,n,r){let i=e.pkg.exports?.[`./canvas-kit/*`];if(typeof i!=`string`)throw Error(`${n} exports no ./canvas-kit/*; a product kit takes the library's components from its kit release.`);let a=_(e.dir,i.replace(`*`,`manifest.json`)),o=t(a);if(!(o?.kind===S[r]&&o.platform===r&&Array.isArray(o.components)&&Array.isArray(o.icons)))throw Error(`${a} is not a ${r} library kit release.`);return o}function D(e,t){let n=C[t];for(let{meta:r,file:i}of e)if(!r.platforms?.includes(n))throw Error(`${i}: platforms: a ${t} kit lists only components that list ${n}`)}function O(e,n){if(!n)return;let r=t(n);if(typeof r!=`object`||!r||Array.isArray(r))throw Error(`${n} must be an object from component name to role.`);for(let[t,i]of Object.entries(r)){let r=e.find(e=>e.name===t);if(!r)throw Error(`${n} names ${t}, which the kit does not have.`);if(!x.includes(i))throw Error(`${n}: ${t} has role ${JSON.stringify(i)}; a role is title or navigation.`);r.role=i}}function k(e){let n=t(e);if(!Array.isArray(n)||n.some(e=>typeof e?.name!=`string`))throw Error(`${e} must be the style key table: a list of style keys, each with a name.`);return n}function A(e){let n=t(e);if(n?.schema!==1)throw Error(`${e} has schema ${n?.schema}; this reader reads schema 1.`);if(!n.itemActions)throw Error(`${e} has no itemActions; the phone kit's action lists come from it.`);return{flags:n.styleKeys??{},itemActions:n.itemActions}}function j(e,t,n){let r=e.map(({name:e})=>e),i=r.filter(e=>typeof t[e]!=`boolean`),a=Object.keys(t).filter(e=>!r.includes(e));if(i.length>0||a.length>0)throw Error(`${n} must list exactly the style keys of the style key table, each true or false. Missing or not a boolean: ${i.join(`, `)||`none`}. Not in the table: ${a.join(`, `)||`none`}.`)}function te(e,t){return e.map(({name:e,type:n,values:r,appliesTo:i,description:a})=>({name:e,type:n,values:r,appliesTo:i,...t?{phoneSupported:t[e]}:{},description:a}))}var ne=(e,t)=>e.name<t.name?-1:+(e.name>t.name);async function M({projectRoot:t,kit:g,platform:x,entry:C,components:M,tokens:N,libraryPackage:P,rolesFile:F,rendererProtocolVersion:I,phoneRendererSupportFile:L,styleKeysFile:R}){if(!b.test(g??``))throw Error(`kit ${JSON.stringify(g)} must be 2 to 40 characters: lowercase letters, digits and hyphens, starting with a letter.`);if(!ee.includes(x))throw Error(`platform must be Web or Phone, not ${JSON.stringify(x)}.`);if(!Number.isInteger(I)||I<1)throw Error(`rendererProtocolVersion must be a positive integer, not ${JSON.stringify(I)}.`);if(C!==void 0)throw Error(`A kit lists its components with components, a glob of .meta.js files; entry is retired.`);if(typeof M!=`string`||M===``||typeof N!=`string`||N===``)throw Error(`A kit needs components, a glob of .meta.js files, and tokens, the path of its webority-theme-tokens/2 file.`);let z=y(t),B=w(z,P),V=B.isSelf;if(x===`Phone`&&!L&&!V)throw Error(`A Phone product kit needs phoneRendererSupportFile, the phone renderer's support file; only a phone library's own kit release builds without it.`);V||T(z,P,B.pkg.version);let H=L?A(L):null,U=x===`Phone`?H:null,W=R?k(R):null;W&&H&&j(W,H.flags,L);let G=V?null:E(B,P,x),K;K=V?x===`Web`?h(_(B.dir,`dist`)):p(_(B.dir,`lib`,`typescript`,`module`,`components`,`AppIcon`,`catalog.g.d.ts`)):G.icons;let q=[];V&&(q=await u({root:z,components:M,icons:K}),D(q,x),a({libraryPackage:P,exported:o({root:z,typesFile:B.typesFile}),drawnNames:q.map(({meta:e})=>({name:e.name,component:e.component??e.name})),notDrawn:s(_(B.dir,i))}),x===`Web`&&r({root:z,metas:q,componentOf:()=>B.typesFile}));let J=[],Y=new Map;if(!V){let e=G.components.map(({name:e})=>e);J=await u({root:z,components:M,knownNames:e,icons:K}),D(J,x);let t=J.map(({meta:e})=>e.name).filter(t=>e.includes(t));if(t.length>0)throw Error(`The kit names ${t.join(`, `)} as ${P} already has them; rename the product components.`);x===`Web`&&r({root:z,metas:J,componentOf:(e,t)=>c(e,t)});for(let{meta:e,file:t}of J)Y.set(e.name,{module:c(t,e.component??e.name),exportName:e.component??e.name,fixedProps:e.fixedProps})}let X=[];if(x===`Phone`){if(!B.canvasKitFile)throw Error(`${P} exports no ./canvasKit subpath; a Phone kit takes the device frame parts from it.`);X=f(B.canvasKitFile,P)}if(V&&x===`Phone`){let e=new Set(q.map(({meta:e})=>e.name)),t=X.filter(({name:t})=>e.has(t)).map(({name:e})=>e);if(t.length>0)throw Error(`${P} exports ${t.join(`, `)} from both its main entry and ./canvasKit.`)}let re=V?q.map(({meta:e})=>l(e,{platform:x,source:P})):G.components,ie=J.map(({meta:e})=>l(e,{platform:x,source:n(v(z,Y.get(e.name).module))})),Z=[...re,...V?X:[],...ie].sort(ne);U&&d(Z,U.itemActions),O(Z,F);let Q=e(z,`@webority/tokens`);if(!Q)throw Error(`@webority/tokens is not installed for ${z}. Run pnpm install there.`);let $=m(y(z,N),_(Q,`dist`,`meanings.json`),x);return{manifest:{kind:V?S[x]:`Product`,library:{name:B.pkg.name,version:B.pkg.version},rendererProtocolVersion:I,platform:x,kitModuleVersion:2,productKit:null,components:Z,tokens:$.tokens,tokenValues:$.tokenValues,icons:K,...W?{styleKeys:te(W,U?U.flags:null)}:{}},warnings:[],phoneChromeNames:X.map(({name:e})=>e),productModules:Y,metas:V?q:J}}export{w as libraryFiles,M as readManifest,A as readPhoneSupport};
|
package/dist/meta.d.ts
CHANGED
|
@@ -71,6 +71,10 @@ export interface ComponentUsage {
|
|
|
71
71
|
export interface ComponentMeta {
|
|
72
72
|
/** The catalogue name, such as AppButton. */
|
|
73
73
|
name: string;
|
|
74
|
+
/** The export this description draws, when it is not `name`: one export described once per fixed setup, such as a picker per mode. */
|
|
75
|
+
component?: string;
|
|
76
|
+
/** Props the kit sets on every placement, over any stored value; never shown in the panel. Only with `component`. */
|
|
77
|
+
fixedProps?: Readonly<Record<string, unknown>>;
|
|
74
78
|
/** The data-wui value the component renders, or null when it renders none. */
|
|
75
79
|
marker: string | null;
|
|
76
80
|
platforms: readonly ("web" | "phone")[];
|
package/dist/metaCheck.d.ts
CHANGED
|
@@ -110,8 +110,12 @@ export type PropsMismatch<P, F extends Shape, N> = {
|
|
|
110
110
|
|
|
111
111
|
// A meta with no omit list would make NonNullable<M["omit"]>[number] collapse ExtraProps to never.
|
|
112
112
|
type OmitOf<M extends ComponentMeta> = M extends { readonly omit: infer O extends readonly string[] } ? O[number] : never;
|
|
113
|
-
|
|
114
|
-
|
|
113
|
+
// The props a meta fixes are set by the kit, not the panel, so they are not extra props.
|
|
114
|
+
type FixedOf<M extends ComponentMeta> = M extends { readonly fixedProps: infer F extends Readonly<Record<string, unknown>> }
|
|
115
|
+
? keyof F & string
|
|
116
|
+
: never;
|
|
117
|
+
/** Props the component takes that the meta neither lists, omits nor fixes. */
|
|
118
|
+
export type ExtraProps<P, M extends ComponentMeta> = Exclude<DesignKeys<P>, keyof M["props"] | OmitOf<M> | FixedOf<M>>;
|
|
115
119
|
/** Props the meta lists that the component does not take. */
|
|
116
120
|
export type MissingProps<P, M extends ComponentMeta> = Exclude<keyof M["props"] & string, DesignKeys<P>>;
|
|
117
121
|
export type MismatchedProps<P, M extends ComponentMeta, N> = PropsMismatch<P, M["props"], N>;
|
package/dist/metaCheck.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{toPosix as e}from"./files.js";import{createRequire as t}from"node:module";import{mkdirSync as n,rmSync as r,writeFileSync as i}from"node:fs";import{dirname as a,join as o}from"node:path";import{fileURLToPath as s}from"node:url";import{execFileSync as c}from"node:child_process";var l=o(a(t(import.meta.url).resolve(`typescript/package.json`)),`bin`,`tsc`),u=o(a(s(import.meta.url)),`metaCheck.js`),d=/^check\.ts\((\d+),\d+\): error TS\d+: (.*)$/,f=/^(.+?)\(\d+,\d+\): error TS\d+: (.*)$/,p=[`propsNotInMeta`,`metaPropsNotOnComponent`,`propsThatDiffer`,`children`],m={propsNotInMeta:`props the component takes that the meta does not list`,metaPropsNotOnComponent:`props the meta lists that the component does not take`,propsThatDiffer:`props whose type, required or nullable flag, or nested fields differ from the component`};function h(t){let n=e(t);return/\.d\.ts$/.test(n)?n.replace(/\.d\.ts$/,``):n.replace(/\.(jsx|tsx|js|ts|mjs)$/,``)}function g(e){let t=[];for(let n of e.split(/\r?\n/)){let e=d.exec(n);if(e){t.push({line:Number(e[1]),file:null,message:e[2]});continue}let r=f.exec(n);r&&t.push({line:null,file:r[1],message:r[2]})}return t}function _(e){let t=/Type '(\{[^']*\})'/.exec(e);return t?[...t[1].matchAll(/: "([^"]+)"/g)].map(e=>e[1]):[]}function v(e){let t=new Map,n=(e,n,r,i)=>{let a=`${e} ${n}`;t.has(a)||t.set(a,{component:e,handler:n,path:r,owner:i})},r=(e,t,i)=>{if(!(typeof e!=`object`||!e)){for(let r of e.handlers??[])n(e.component,r,t,i);Array.isArray(e.children)&&e.children.forEach((e,n)=>r(e,`${t}.children[${n}]`,i))}};return e.forEach(({meta:e},t)=>{(e.examples??[]).forEach((i,a)=>{let o=`examples[${a}]`;for(let r of i.handlers??[])n(e.name,r,o,t);r({children:i.children},o,t),r(i.wrap,`${o}.wrap`,t)});for(let n of[`do`,`dont`])(e.usage?.[n]??[]).forEach((e,i)=>{(e.example??[]).forEach((e,a)=>r(e,`usage.${n}[${i}].example[${a}]`,t))})}),t}function y({root:t,metas:a,componentOf:s}){let d=o(t,`node_modules`,`.canvas-kit-check-${process.pid}`);try{n(d,{recursive:!0});let t=a.map(({meta:e,file:t})=>({component:h(s(t,e.name)),meta:h(t)})),r=[],f=new Map,y=new Map,b=(e,t=-1,n=null)=>{r.push(e);let i=r.length;t>=0&&f.set(i,t),n&&y.set(i,n)};b(`import type { ExtraProps, MissingProps, MismatchedProps, ChildrenOk, HandlerKeys } from "${e(u)}";`),b(`type N = import("react").ReactNode;`),b(`type Empty = { [key: string]: never };`),a.forEach((e,n)=>{b(`import type * as C${n} from "${t[n].component}";`,n),b(`import type { meta as M${n} } from "${t[n].meta}";`,n)});let x=e=>`{ [K in ${e}]: K }`;a.forEach(({meta:e},t)=>{let n=e.name;b(`type P${t} = import("react").ComponentProps<typeof C${t}.${
|
|
1
|
+
import{toPosix as e}from"./files.js";import{createRequire as t}from"node:module";import{mkdirSync as n,rmSync as r,writeFileSync as i}from"node:fs";import{dirname as a,join as o}from"node:path";import{fileURLToPath as s}from"node:url";import{execFileSync as c}from"node:child_process";var l=o(a(t(import.meta.url).resolve(`typescript/package.json`)),`bin`,`tsc`),u=o(a(s(import.meta.url)),`metaCheck.js`),d=/^check\.ts\((\d+),\d+\): error TS\d+: (.*)$/,f=/^(.+?)\(\d+,\d+\): error TS\d+: (.*)$/,p=[`propsNotInMeta`,`metaPropsNotOnComponent`,`propsThatDiffer`,`children`,`fixedProps`],m={propsNotInMeta:`props the component takes that the meta does not list`,metaPropsNotOnComponent:`props the meta lists that the component does not take`,propsThatDiffer:`props whose type, required or nullable flag, or nested fields differ from the component`,fixedProps:`fixed props whose value does not fit the component's prop`};function h(t){let n=e(t);return/\.d\.ts$/.test(n)?n.replace(/\.d\.ts$/,``):n.replace(/\.(jsx|tsx|js|ts|mjs)$/,``)}function g(e){let t=[];for(let n of e.split(/\r?\n/)){let e=d.exec(n);if(e){t.push({line:Number(e[1]),file:null,message:e[2]});continue}let r=f.exec(n);r&&t.push({line:null,file:r[1],message:r[2]})}return t}function _(e){let t=/Type '(\{[^']*\})'/.exec(e);return t?[...t[1].matchAll(/: "([^"]+)"/g)].map(e=>e[1]):[]}function v(e){let t=new Map,n=(e,n,r,i)=>{let a=`${e} ${n}`;t.has(a)||t.set(a,{component:e,handler:n,path:r,owner:i})},r=(e,t,i)=>{if(!(typeof e!=`object`||!e)){for(let r of e.handlers??[])n(e.component,r,t,i);Array.isArray(e.children)&&e.children.forEach((e,n)=>r(e,`${t}.children[${n}]`,i))}};return e.forEach(({meta:e},t)=>{(e.examples??[]).forEach((i,a)=>{let o=`examples[${a}]`;for(let r of i.handlers??[])n(e.name,r,o,t);r({children:i.children},o,t),r(i.wrap,`${o}.wrap`,t)});for(let n of[`do`,`dont`])(e.usage?.[n]??[]).forEach((e,i)=>{(e.example??[]).forEach((e,a)=>r(e,`usage.${n}[${i}].example[${a}]`,t))})}),t}function y({root:t,metas:a,componentOf:s}){let d=o(t,`node_modules`,`.canvas-kit-check-${process.pid}`);try{n(d,{recursive:!0});let t=a.map(({meta:e,file:t})=>({component:h(s(t,e.component??e.name)),meta:h(t)})),r=[],f=new Map,y=new Map,b=(e,t=-1,n=null)=>{r.push(e);let i=r.length;t>=0&&f.set(i,t),n&&y.set(i,n)};b(`import type { ExtraProps, MissingProps, MismatchedProps, ChildrenOk, HandlerKeys } from "${e(u)}";`),b(`type N = import("react").ReactNode;`),b(`type Empty = { [key: string]: never };`),a.forEach((e,n)=>{b(`import type * as C${n} from "${t[n].component}";`,n),b(`import type { meta as M${n} } from "${t[n].meta}";`,n)});let x=e=>`{ [K in ${e}]: K }`;a.forEach(({meta:e},t)=>{let n=e.name,r=e.component??e.name;b(`type P${t} = import("react").ComponentProps<typeof C${t}.${r}>;`,t),b(`export const ${n}__propsNotInMeta: Empty = null as unknown as ${x(`ExtraProps<P${t}, typeof M${t}>`)};`,t,`propsNotInMeta`),b(`export const ${n}__metaPropsNotOnComponent: Empty = null as unknown as ${x(`MissingProps<P${t}, typeof M${t}>`)};`,t,`metaPropsNotOnComponent`),b(`export const ${n}__propsThatDiffer: Empty = null as unknown as ${x(`MismatchedProps<P${t}, typeof M${t}, N>`)};`,t,`propsThatDiffer`),b(`export const ${n}__children: true = null as unknown as ChildrenOk<P${t}, typeof M${t}>;`,t,`children`),e.fixedProps!==void 0&&b(`export const ${n}__fixedProps: Partial<P${t}> = null as unknown as NonNullable<(typeof M${t})["fixedProps"]>;`,t,`fixedProps`)});let S=new Map(a.map(({meta:e},t)=>[e.name,t])),C=new Map,w=0;for(let{component:t,handler:n,path:i,owner:o}of v(a).values()){let s=S.get(t);s!==void 0&&(w+=1,b(`export const ${t.replace(/[^A-Za-z0-9_]/g,`_`)}__handler_${n}_${w}: Empty = null as unknown as { [K in Exclude<"${n}", HandlerKeys<P${s}>>]: K };`),C.set(r.length,{owner:o,where:`${e(a[o].file)}: ${i}`,component:t,handler:n}))}i(o(d,`check.ts`),`${r.join(`
|
|
2
2
|
`)}\n`),i(o(d,`tsconfig.json`),JSON.stringify({compilerOptions:{strict:!0,noEmit:!0,allowJs:!0,checkJs:!1,jsx:`react-jsx`,module:`esnext`,moduleResolution:`bundler`,target:`es2022`,skipLibCheck:!0,noErrorTruncation:!0,types:[]},files:[`check.ts`]},null,2));let T;try{c(process.execPath,[l,`-p`,o(d,`tsconfig.json`),`--pretty`,`false`],{cwd:d,encoding:`utf8`,stdio:`pipe`});return}catch(e){T=String(e.stdout??``)+String(e.stderr??``)}let E=new Map,D=[];for(let n of g(T)){let r=n.line===null?void 0:C.get(n.line);if(r){D.push({owner:r.owner,rank:p.length,text:`${r.where}: "${r.handler}" is not a function prop of ${r.component}`});continue}let i=n.line!==null&&f.has(n.line)?f.get(n.line):void 0,o=n.line===null?void 0:y.get(n.line);if(o&&i!==void 0){let e=`${i}:${o}`;if(E.has(e)||E.set(e,{owner:i,kind:o,names:new Set}),o!==`children`)for(let t of _(n.message))E.get(e).names.add(t);continue}let s=i??t.findIndex(e=>[n.file,n.message].some(t=>t&&(t.includes(e.component)||t.includes(e.meta)))),c=n.line===null?`${e(n.file)}: `:``;D.push({owner:s,rank:-1,text:`${s>=0?a[s].meta.name:`metaCheck`}: tsc could not read the check file: ${c}${n.message}`})}for(let{owner:e,kind:t,names:n}of E.values()){let{meta:r}=a[e],i=t===`children`?`${r.name}: acceptsChildren is ${r.acceptsChildren} but the component ${r.acceptsChildren?`does not take`:`takes`} children`:n.size>0?`${r.name}: ${m[t]}: ${[...n].sort().join(`, `)}`:`${r.name}: ${m[t]}: see the meta against the component's props`;D.push({owner:e,rank:p.indexOf(t),text:i})}throw D.length===0?Error(`metaCheck: tsc failed: ${T.split(/\r?\n/).slice(0,20).join(`
|
|
3
3
|
`)}`):(D.sort((e,t)=>e.owner-t.owner||e.rank-t.rank),Error(D.map(e=>e.text).join(`
|
|
4
4
|
`)))}finally{r(d,{recursive:!0,force:!0})}}export{l as TSC,y as checkMetaTypes,h as specifierOf};
|
package/dist/metas.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{toPosix as e}from"./files.js";import{existsSync as t,globSync as n}from"node:fs";import{resolve as
|
|
2
|
-
`))}function h(e,{platform:t,source:n}){let r=Object.keys(e.props).sort(L);return{name:e.name,marker:e.marker,acceptsChildren:e.acceptsChildren,props:r.map(t=>j(t,e.props[t])),itemsTakeAction:t===`Web`?r.filter(t=>P(e.props[t])):[],takesAction:[],source:n,usage:e.usage}}function g(n,r){let i=n.replace(/\.meta\.[jt]s$/,``);for(let n of f)if(t(i+n))return e(i+n);throw Error(`no component module for ${r} beside ${n}`)}function _(e,t,n,r,i,a){if(!R(e)){a.push([`meta`,`must be an object`]);return}let{name:s}=e;typeof s!=`string`||!o.test(s)?a.push([`name`,`"${s}" is not a catalogue name; start with a capital letter and use letters and digits`]):n.has(s)?a.push([`name`,`"${s}" is also the name in ${n.get(s)}`]):n.set(s,t);let{platforms:c}=e;Array.isArray(c)&&c.length>0&&c.every(e=>e===`web`||e===`phone`)||a.push([`platforms`,`must list web, phone or both`]),e.marker!==null&&typeof e.marker!=`string`&&a.push([`marker`,`must be a string or null`]),typeof e.acceptsChildren!=`boolean`&&a.push([`acceptsChildren`,`must be true or false`]),e.omit!==void 0&&(!Array.isArray(e.omit)||!e.omit.every(e=>typeof e==`string`))&&a.push([`omit`,`must be a list of prop names`]);let l=R(e.props)?e.props:{};if(!R(e.props))a.push([`props`,`must be an object`]);else for(let[t,n]of Object.entries(e.props))v(n,`props.${t}`,i,a);Array.isArray(e.examples)?e.examples.forEach((n,o)=>{E(n,`examples[${o}]`,e,l,t,r,i,a)}):a.push([`examples`,`must be a list`]),D(e.usage,i,a),A(e,``,a)}function v(e,t,n,r){if(!R(e)){r.push([t,`is not a prop`]);return}if(!d.includes(e.type)){r.push([`${t}.type`,`${I(e.type)} is not a prop type`]);return}if(e.type===`enum`||e.type===`enumOrNumber`?y(e,t,r):e.values!==void 0&&r.push([`${t}.values`,`only an enum or an enumOrNumber has values`]),e.fields!==void 0)if(e.type!==`object`)r.push([`${t}.fields`,`only an object has fields`]);else for(let[i,a]of Object.entries(e.fields))v(a,`${t}.fields.${i}`,n,r);if(e.itemFields!==void 0)if(e.type!==`array`)r.push([`${t}.itemFields`,`only an array has itemFields`]);else for(let[i,a]of Object.entries(e.itemFields))v(a,`${t}.itemFields.${i}`,n,r);if(B(e.description)||r.push([`${t}.description`,`is empty`]),e.required!==void 0&&typeof e.required!=`boolean`&&r.push([`${t}.required`,`must be true or false`]),e.nullable!==void 0&&typeof e.nullable!=`boolean`&&r.push([`${t}.nullable`,`must be true or false`]),e.default!==void 0)if(e.required===!0)r.push([`${t}.default`,`a required prop has no default`]);else{let i=[];b(e.default,e,t,n,i),i.length>0&&r.push([`${t}.default`,`${I(e.default)} does not fit ${e.type}`])}}function y(e,t,n){let{type:r,values:i}=e;if(!Array.isArray(i)||i.length===0){n.push([`${t}.values`,`an ${r} lists its values`]);return}let a=new Set;for(let e of i)(r===`enum`?typeof e==`string`||z(e):typeof e==`string`)?a.has(e)&&n.push([`${t}.values`,`"${e}" is listed twice`]):n.push([`${t}.values`,`${I(e)} is not allowed here`]),a.add(e)}function b(e,t,n,r,i){if(!R(t)||e===null&&(t.nullable===!0||t.type===`node`||t.type===`icon`))return;let a=Array.isArray(t.values)?t.values:[];switch(t.type){case`string`:case`url`:typeof e!=`string`&&F(e,t.type,n,i);return;case`number`:z(e)||F(e,t.type,n,i);return;case`boolean`:typeof e!=`boolean`&&F(e,t.type,n,i);return;case`stringOrNumber`:typeof e!=`string`&&!z(e)&&F(e,t.type,n,i);return;case`enum`:a.includes(e)||i.push([n,`${I(e)} is not one of ${I(a)}`]);return;case`enumOrNumber`:!z(e)&&!a.includes(e)&&i.push([n,`${I(e)} is not one of ${I(a)}`]);return;case`icon`:V(e)?C(e,n,r,i):typeof e==`string`?Array.isArray(r.icons)&&!r.icons.includes(e)&&i.push([n,`"${e}" is not an icon of the kit`]):F(e,t.type,n,i);return;case`node`:Array.isArray(e)?e.forEach((e,t)=>x(e,`${n}[${t}]`,r,i)):x(e,n,r,i);return;case`array`:Array.isArray(e)?t.itemFields!==void 0&&e.forEach((e,a)=>{R(e)?S(e,t.itemFields,`${n}[${a}]`,r,i):i.push([`${n}[${a}]`,`${I(e)} is not an object`])}):F(e,t.type,n,i);return;case`object`:R(e)?t.fields!==void 0&&S(e,t.fields,n,r,i):F(e,t.type,n,i);return;default:return}}function x(e,t,n,r){V(e)?C(e,t,n,r):typeof e!=`string`&&!z(e)&&r.push([t,`${I(e)} is not a node`])}function S(e,t,n,r,i){for(let a of Object.keys(e))Object.hasOwn(t,a)?b(e[a],t[a],`${n}.${a}`,r,i):i.push([`${n}.${a}`,`not a field`]);for(let[r,a]of Object.entries(t))R(a)&&a.required===!0&&!Object.hasOwn(e,r)&&i.push([`${n}.${r}`,`missing, the field is required`])}function C(e,t,n,r){let{component:i}=e,o=n.byName.get(i);if(!o&&!n.knownNames.has(i)&&!a.includes(i)&&r.push([`${t}.component`,`"${i}" is neither a component of the kit nor one of the HTML tags`]),o&&e.props!==void 0)if(!R(e.props))r.push([`${t}.props`,`must be an object`]);else{let a=R(o.props)?o.props:{};for(let[o,s]of Object.entries(e.props))Object.hasOwn(a,o)?b(s,a[o],`${t}.props.${o}`,n,r):r.push([`${t}.props.${o}`,`not a prop of ${i}`])}e.children!==void 0&&(o&&o.acceptsChildren===!1&&r.push([`${t}.children`,`${i} takes no children`]),T(e.children,`${t}.children`,n,r)),e.handlers!==void 0&&w(e.handlers,`${t}.handlers`,i,o,r)}function w(e,t,n,r,i){if(!Array.isArray(e)||!e.every(e=>typeof e==`string`)){i.push([t,`must be a list of handler names`]);return}if(a.includes(n)){i.push([t,`handlers need a kit component`]);return}if(e.length===0){i.push([t,`omit handlers when empty`]);return}let o=new Set;for(let a of e)l.test(a)?o.has(a)?i.push([t,`"${a}" is listed twice`]):r&&R(r.props)&&Object.hasOwn(r.props,a)&&i.push([t,`"${a}" is a data prop of ${n}, set it in props`]):i.push([t,`"${a}" is not a handler name (on<Event>)`]),o.add(a)}function T(e,t,n,r){if(typeof e!=`string`){if(!Array.isArray(e)){r.push([t,`is text or a list of text and placed elements`]);return}e.forEach((e,i)=>{typeof e!=`string`&&(V(e)?C(e,`${t}[${i}]`,n,r):r.push([`${t}[${i}]`,`is neither text nor a placed element`]))})}}function E(e,t,n,r,i,a,o,c){if(!R(e)){c.push([t,`is not an example`]);return}let{name:l}=n,{id:u}=e;if(typeof u==`string`&&(u===l||u.startsWith(`${l}.`)&&s.test(u.slice(l.length+1)))?a.has(u)?c.push([`${t}.id`,`"${u}" is also used in ${a.get(u)}`]):a.set(u,i):c.push([`${t}.id`,`"${u}" must be ${l} or ${l}.<case>`]),B(e.title)||c.push([`${t}.title`,`is empty`]),!R(e.props))c.push([`${t}.props`,`must be an object`]);else{for(let[n,i]of Object.entries(e.props))Object.hasOwn(r,n)?b(i,r[n],`${t}.props.${n}`,o,c):c.push([`${t}.props.${n}`,`not a prop of ${l}`]);for(let[n,i]of Object.entries(r))R(i)&&i.required===!0&&!Object.hasOwn(e.props,n)&&c.push([`${t}.props.${n}`,`missing, the prop is required`])}e.children!==void 0&&(n.acceptsChildren===!1&&c.push([`${t}.children`,`${l} takes no children`]),T(e.children,`${t}.children`,o,c)),e.wrap!==void 0&&(V(e.wrap)?C(e.wrap,`${t}.wrap`,o,c):c.push([`${t}.wrap`,`is not a placed element`])),e.handlers!==void 0&&w(e.handlers,`${t}.handlers`,l,n,c)}function D(e,t,n){if(!R(e)){n.push([`usage`,`must be an object`]);return}(!Array.isArray(e.when)||e.when.length===0||!e.when.every(B))&&n.push([`usage.when`,`lists nothing; write at least one line`]),Array.isArray(e.whenNot)?e.whenNot.forEach((e,r)=>O(e,`usage.whenNot[${r}]`,t,n)):n.push([`usage.whenNot`,`must be a list`]),Array.isArray(e.do)||n.push([`usage.do`,`must be a list`]),Array.isArray(e.dont)||n.push([`usage.dont`,`must be a list`]),Array.isArray(e.do)&&Array.isArray(e.dont)&&(e.do.length!==e.dont.length&&n.push([`usage`,`${e.do.length} do against ${e.dont.length} dont; they pair up one to one`]),e.do.forEach((e,r)=>k(e,`usage.do[${r}]`,t,n)),e.dont.forEach((e,r)=>k(e,`usage.dont[${r}]`,t,n))),Array.isArray(e.a11y)?e.a11y.forEach((e,t)=>{B(e)||n.push([`usage.a11y[${t}]`,`is empty`])}):n.push([`usage.a11y`,`must be a list`])}function O(e,t,n,r){if(!R(e)){r.push([t,`is not an object`]);return}B(e.text)||r.push([`${t}.text`,`is empty`]),e.instead!==void 0&&(typeof e.instead==`string`?c.test(e.instead)&&!n.byName.has(e.instead)&&!n.knownNames.has(e.instead)&&r.push([`${t}.instead`,`"${e.instead}" is not a component of the kit`]):r.push([`${t}.instead`,`must be text`]))}function k(e,t,n,r){if(!R(e)){r.push([t,`is not a practice`]);return}if(B(e.note)||r.push([`${t}.note`,`is empty`]),!Array.isArray(e.example)||e.example.length===0){r.push([`${t}.example`,`needs at least one placed element`]);return}e.example.forEach((e,i)=>{let a=`${t}.example[${i}]`;V(e)?C(e,a,n,r):r.push([a,`is not a placed element`])})}function A(e,t,n){if(typeof e==`string`)u.test(e)&&n.push([t,`contains an em or en dash; use a comma, colon or period`]);else if(Array.isArray(e))e.forEach((e,r)=>A(e,`${t}[${r}]`,n));else if(R(e))for(let[r,i]of Object.entries(e))A(i,t?`${t}.${r}`:r,n)}function j(e,t){let n={name:e,type:t.type};return(t.type===`enum`||t.type===`enumOrNumber`)&&(n.enum=N(t.values)),t.fields!==void 0&&(n.fields=M(t.fields)),t.itemFields!==void 0&&(n.itemFields=M(t.itemFields)),n.required=t.required===!0,t.nullable===!0&&(n.nullable=!0),t.description!==void 0&&(n.description=t.description),t.default!==void 0&&(n.default=t.default),n}function M(e){return Object.keys(e).sort(L).map(t=>j(t,e[t]))}function N(e){return[...e].sort((e,t)=>{let n=typeof e==`number`,r=typeof t==`number`;return n&&r?e-t:n===r?L(e,t):n?-1:1})}function P(e){return e.type===`array`&&Object.keys(e.itemFields??{}).some(e=>e===`href`||e===`to`)}function F(e,t,n,r){r.push([n,`${I(e)} is not a ${t}`])}function I(e){return JSON.stringify(e)}function L(e,t){return e<t?-1:+(e>t)}function R(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function z(e){return typeof e==`number`&&Number.isFinite(e)}function B(e){return typeof e==`string`&&e.trim()!==``}function V(e){return R(e)&&typeof e.component==`string`}export{a as HTML_TAGS,m as checkMetas,g as componentModuleOf,h as manifestComponent,p as readMetas};
|
|
1
|
+
import{toPosix as e}from"./files.js";import{existsSync as t,globSync as n}from"node:fs";import{basename as r,dirname as i,join as a,resolve as o}from"node:path";import{pathToFileURL as s}from"node:url";var c=Object.freeze([`a`,`b`,`button`,`div`,`img`,`kbd`,`li`,`p`,`span`,`strong`,`table`,`tbody`,`td`,`th`,`thead`,`tr`,`ul`]),l=/^[A-Z][A-Za-z0-9]*$/,u=/^[A-Za-z0-9][A-Za-z0-9_-]*$/,d=/^App[A-Za-z0-9]*$/,f=/^on[A-Z][A-Za-z0-9]*$/,p=/[\u2013\u2014]/,m=[`string`,`number`,`stringOrNumber`,`boolean`,`enum`,`enumOrNumber`,`url`,`icon`,`node`,`array`,`object`,`any`],h=[`.jsx`,`.tsx`,`.js`,`.ts`];async function g({root:e,components:t,knownNames:r,icons:i}){let a=n(t,{cwd:e});if(a.length===0)throw Error(`${e}: no component metadata matches ${t}`);let c=a.map(t=>o(e,t)).sort(B),l=[];for(let e of c){let t=await import(s(e).href);if(!(`meta`in t))throw Error(`${e}: exports no meta; write export const meta = defineMeta({...})`);l.push({meta:t.meta,file:e})}return _(l,{knownNames:r,icons:i}),l.sort((e,t)=>B(e.meta.name,t.meta.name))}function _(e,{knownNames:t=[],icons:n}={}){let r=new Map;for(let{meta:t}of e)V(t)&&typeof t.name==`string`&&!r.has(t.name)&&r.set(t.name,t);let i={byName:r,knownNames:new Set(t),icons:n},a=new Map,o=new Map,s=[];for(let{meta:t,file:n}of e){let e=[];b(t,n,a,o,i,e);for(let[t,r]of e)s.push(`${n}: ${t}: ${r}`)}if(s.length>0)throw Error(s.join(`
|
|
2
|
+
`))}function v(e,{platform:t,source:n}){let r=Object.keys(e.props).sort(B);return{name:e.name,marker:e.marker,acceptsChildren:e.acceptsChildren,props:r.map(t=>P(t,e.props[t])),itemsTakeAction:t===`Web`?r.filter(t=>L(e.props[t])):[],takesAction:[],source:n,...e.component===void 0?{}:{component:e.component},...e.fixedProps===void 0?{}:{fixedProps:e.fixedProps},usage:e.usage}}function y(n,o){let s=n.replace(/\.meta\.[jt]s$/,``),c=r(s)===o?s:a(i(s),o);for(let n of h)if(t(c+n))return e(c+n);throw Error(`no component module for ${o} beside ${n}`)}function b(e,t,n,r,i,a){if(!V(e)){a.push([`meta`,`must be an object`]);return}let{name:o}=e;typeof o!=`string`||!l.test(o)?a.push([`name`,`"${o}" is not a catalogue name; start with a capital letter and use letters and digits`]):n.has(o)?a.push([`name`,`"${o}" is also the name in ${n.get(o)}`]):n.set(o,t),e.component!==void 0&&(U(e.component)?e.component===o&&a.push([`component`,`"${e.component}" is the name; leave component out when the meta draws its own export`]):a.push([`component`,`must name an export as text`]));let{platforms:s}=e;Array.isArray(s)&&s.length>0&&s.every(e=>e===`web`||e===`phone`)||a.push([`platforms`,`must list web, phone or both`]),e.marker!==null&&typeof e.marker!=`string`&&a.push([`marker`,`must be a string or null`]),typeof e.acceptsChildren!=`boolean`&&a.push([`acceptsChildren`,`must be true or false`]),e.omit!==void 0&&(!Array.isArray(e.omit)||!e.omit.every(e=>typeof e==`string`))&&a.push([`omit`,`must be a list of prop names`]);let c=V(e.props)?e.props:{};if(!V(e.props))a.push([`props`,`must be an object`]);else for(let[t,n]of Object.entries(e.props))x(n,`props.${t}`,i,a);let u=new Set;if(e.fixedProps!==void 0)if(e.component===void 0&&a.push([`fixedProps`,`needs component, the export the fixed props go to`]),!V(e.fixedProps)||Object.keys(e.fixedProps).length===0)a.push([`fixedProps`,`must be an object of the props the kit sets`]);else{let t=Array.isArray(e.omit)?e.omit:[];for(let n of Object.keys(e.fixedProps))u.add(n),Object.hasOwn(c,n)?a.push([`fixedProps.${n}`,`is also a prop; a fixed prop is set by the kit, not the panel`]):t.includes(n)&&a.push([`fixedProps.${n}`,`is listed in omit; a prop is fixed or omitted, not both`])}i.fixed={name:o,keys:u},Array.isArray(e.examples)?e.examples.forEach((n,o)=>{k(n,`examples[${o}]`,e,c,t,r,i,a)}):a.push([`examples`,`must be a list`]),A(e.usage,i,a),i.fixed=null,N(e,``,a)}function x(e,t,n,r){if(!V(e)){r.push([t,`is not a prop`]);return}if(!m.includes(e.type)){r.push([`${t}.type`,`${z(e.type)} is not a prop type`]);return}if(e.type===`enum`||e.type===`enumOrNumber`?S(e,t,r):e.values!==void 0&&r.push([`${t}.values`,`only an enum or an enumOrNumber has values`]),e.fields!==void 0)if(e.type!==`object`)r.push([`${t}.fields`,`only an object has fields`]);else for(let[i,a]of Object.entries(e.fields))x(a,`${t}.fields.${i}`,n,r);if(e.itemFields!==void 0)if(e.type!==`array`)r.push([`${t}.itemFields`,`only an array has itemFields`]);else for(let[i,a]of Object.entries(e.itemFields))x(a,`${t}.itemFields.${i}`,n,r);if(U(e.description)||r.push([`${t}.description`,`is empty`]),e.required!==void 0&&typeof e.required!=`boolean`&&r.push([`${t}.required`,`must be true or false`]),e.nullable!==void 0&&typeof e.nullable!=`boolean`&&r.push([`${t}.nullable`,`must be true or false`]),e.default!==void 0)if(e.required===!0)r.push([`${t}.default`,`a required prop has no default`]);else{let i=[];C(e.default,e,t,n,i),i.length>0&&r.push([`${t}.default`,`${z(e.default)} does not fit ${e.type}`])}}function S(e,t,n){let{type:r,values:i}=e;if(!Array.isArray(i)||i.length===0){n.push([`${t}.values`,`an ${r} lists its values`]);return}let a=new Set;for(let e of i)(r===`enum`?typeof e==`string`||H(e):typeof e==`string`)?a.has(e)&&n.push([`${t}.values`,`"${e}" is listed twice`]):n.push([`${t}.values`,`${z(e)} is not allowed here`]),a.add(e)}function C(e,t,n,r,i){if(!V(t)||e===null&&(t.nullable===!0||t.type===`node`||t.type===`icon`))return;let a=Array.isArray(t.values)?t.values:[];switch(t.type){case`string`:case`url`:typeof e!=`string`&&R(e,t.type,n,i);return;case`number`:H(e)||R(e,t.type,n,i);return;case`boolean`:typeof e!=`boolean`&&R(e,t.type,n,i);return;case`stringOrNumber`:typeof e!=`string`&&!H(e)&&R(e,t.type,n,i);return;case`enum`:a.includes(e)||i.push([n,`${z(e)} is not one of ${z(a)}`]);return;case`enumOrNumber`:!H(e)&&!a.includes(e)&&i.push([n,`${z(e)} is not one of ${z(a)}`]);return;case`icon`:W(e)?E(e,n,r,i):typeof e==`string`?Array.isArray(r.icons)&&!r.icons.includes(e)&&i.push([n,`"${e}" is not an icon of the kit`]):R(e,t.type,n,i);return;case`node`:Array.isArray(e)?e.forEach((e,t)=>w(e,`${n}[${t}]`,r,i)):w(e,n,r,i);return;case`array`:Array.isArray(e)?t.itemFields!==void 0&&e.forEach((e,a)=>{V(e)?T(e,t.itemFields,`${n}[${a}]`,r,i):i.push([`${n}[${a}]`,`${z(e)} is not an object`])}):R(e,t.type,n,i);return;case`object`:V(e)?t.fields!==void 0&&T(e,t.fields,n,r,i):R(e,t.type,n,i);return;default:return}}function w(e,t,n,r){W(e)?E(e,t,n,r):typeof e!=`string`&&!H(e)&&r.push([t,`${z(e)} is not a node`])}function T(e,t,n,r,i){for(let a of Object.keys(e))Object.hasOwn(t,a)?C(e[a],t[a],`${n}.${a}`,r,i):i.push([`${n}.${a}`,`not a field`]);for(let[r,a]of Object.entries(t))V(a)&&a.required===!0&&!Object.hasOwn(e,r)&&i.push([`${n}.${r}`,`missing, the field is required`])}function E(e,t,n,r){let{component:i}=e,a=n.byName.get(i);if(!a&&!n.knownNames.has(i)&&!c.includes(i)&&r.push([`${t}.component`,`"${i}" is neither a component of the kit nor one of the HTML tags`]),a&&e.props!==void 0)if(!V(e.props))r.push([`${t}.props`,`must be an object`]);else{let o=V(a.props)?a.props:{};for(let[a,s]of Object.entries(e.props))n.fixed&&n.fixed.name===i&&n.fixed.keys.has(a)?r.push([`${t}.props.${a}`,`is a fixed prop; the kit sets it`]):Object.hasOwn(o,a)?C(s,o[a],`${t}.props.${a}`,n,r):r.push([`${t}.props.${a}`,`not a prop of ${i}`])}e.children!==void 0&&(a&&a.acceptsChildren===!1&&r.push([`${t}.children`,`${i} takes no children`]),O(e.children,`${t}.children`,n,r)),e.handlers!==void 0&&D(e.handlers,`${t}.handlers`,i,a,r)}function D(e,t,n,r,i){if(!Array.isArray(e)||!e.every(e=>typeof e==`string`)){i.push([t,`must be a list of handler names`]);return}if(c.includes(n)){i.push([t,`handlers need a kit component`]);return}if(e.length===0){i.push([t,`omit handlers when empty`]);return}let a=new Set;for(let o of e)f.test(o)?a.has(o)?i.push([t,`"${o}" is listed twice`]):r&&V(r.props)&&Object.hasOwn(r.props,o)&&i.push([t,`"${o}" is a data prop of ${n}, set it in props`]):i.push([t,`"${o}" is not a handler name (on<Event>)`]),a.add(o)}function O(e,t,n,r){if(typeof e!=`string`){if(!Array.isArray(e)){r.push([t,`is text or a list of text and placed elements`]);return}e.forEach((e,i)=>{typeof e!=`string`&&(W(e)?E(e,`${t}[${i}]`,n,r):r.push([`${t}[${i}]`,`is neither text nor a placed element`]))})}}function k(e,t,n,r,i,a,o,s){if(!V(e)){s.push([t,`is not an example`]);return}let{name:c}=n,{id:l}=e;if(typeof l==`string`&&(l===c||l.startsWith(`${c}.`)&&u.test(l.slice(c.length+1)))?a.has(l)?s.push([`${t}.id`,`"${l}" is also used in ${a.get(l)}`]):a.set(l,i):s.push([`${t}.id`,`"${l}" must be ${c} or ${c}.<case>`]),U(e.title)||s.push([`${t}.title`,`is empty`]),!V(e.props))s.push([`${t}.props`,`must be an object`]);else{for(let[n,i]of Object.entries(e.props))o.fixed&&o.fixed.keys.has(n)?s.push([`${t}.props.${n}`,`is a fixed prop; the kit sets it`]):Object.hasOwn(r,n)?C(i,r[n],`${t}.props.${n}`,o,s):s.push([`${t}.props.${n}`,`not a prop of ${c}`]);for(let[n,i]of Object.entries(r))V(i)&&i.required===!0&&!Object.hasOwn(e.props,n)&&s.push([`${t}.props.${n}`,`missing, the prop is required`])}e.children!==void 0&&(n.acceptsChildren===!1&&s.push([`${t}.children`,`${c} takes no children`]),O(e.children,`${t}.children`,o,s)),e.wrap!==void 0&&(W(e.wrap)?E(e.wrap,`${t}.wrap`,o,s):s.push([`${t}.wrap`,`is not a placed element`])),e.handlers!==void 0&&D(e.handlers,`${t}.handlers`,c,n,s)}function A(e,t,n){if(!V(e)){n.push([`usage`,`must be an object`]);return}(!Array.isArray(e.when)||e.when.length===0||!e.when.every(U))&&n.push([`usage.when`,`lists nothing; write at least one line`]),Array.isArray(e.whenNot)?e.whenNot.forEach((e,r)=>j(e,`usage.whenNot[${r}]`,t,n)):n.push([`usage.whenNot`,`must be a list`]),Array.isArray(e.do)||n.push([`usage.do`,`must be a list`]),Array.isArray(e.dont)||n.push([`usage.dont`,`must be a list`]),Array.isArray(e.do)&&Array.isArray(e.dont)&&(e.do.length!==e.dont.length&&n.push([`usage`,`${e.do.length} do against ${e.dont.length} dont; they pair up one to one`]),e.do.forEach((e,r)=>M(e,`usage.do[${r}]`,t,n)),e.dont.forEach((e,r)=>M(e,`usage.dont[${r}]`,t,n))),Array.isArray(e.a11y)?e.a11y.forEach((e,t)=>{U(e)||n.push([`usage.a11y[${t}]`,`is empty`])}):n.push([`usage.a11y`,`must be a list`])}function j(e,t,n,r){if(!V(e)){r.push([t,`is not an object`]);return}U(e.text)||r.push([`${t}.text`,`is empty`]),e.instead!==void 0&&(typeof e.instead==`string`?d.test(e.instead)&&!n.byName.has(e.instead)&&!n.knownNames.has(e.instead)&&r.push([`${t}.instead`,`"${e.instead}" is not a component of the kit`]):r.push([`${t}.instead`,`must be text`]))}function M(e,t,n,r){if(!V(e)){r.push([t,`is not a practice`]);return}if(U(e.note)||r.push([`${t}.note`,`is empty`]),!Array.isArray(e.example)||e.example.length===0){r.push([`${t}.example`,`needs at least one placed element`]);return}e.example.forEach((e,i)=>{let a=`${t}.example[${i}]`;W(e)?E(e,a,n,r):r.push([a,`is not a placed element`])})}function N(e,t,n){if(typeof e==`string`)p.test(e)&&n.push([t,`contains an em or en dash; use a comma, colon or period`]);else if(Array.isArray(e))e.forEach((e,r)=>N(e,`${t}[${r}]`,n));else if(V(e))for(let[r,i]of Object.entries(e))N(i,t?`${t}.${r}`:r,n)}function P(e,t){let n={name:e,type:t.type};return(t.type===`enum`||t.type===`enumOrNumber`)&&(n.enum=I(t.values)),t.fields!==void 0&&(n.fields=F(t.fields)),t.itemFields!==void 0&&(n.itemFields=F(t.itemFields)),n.required=t.required===!0,t.nullable===!0&&(n.nullable=!0),t.description!==void 0&&(n.description=t.description),t.default!==void 0&&(n.default=t.default),n}function F(e){return Object.keys(e).sort(B).map(t=>P(t,e[t]))}function I(e){return[...e].sort((e,t)=>{let n=typeof e==`number`,r=typeof t==`number`;return n&&r?e-t:n===r?B(e,t):n?-1:1})}function L(e){return e.type===`array`&&Object.keys(e.itemFields??{}).some(e=>e===`href`||e===`to`)}function R(e,t,n,r){r.push([n,`${z(e)} is not a ${t}`])}function z(e){return JSON.stringify(e)}function B(e,t){return e<t?-1:+(e>t)}function V(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function H(e){return typeof e==`number`&&Number.isFinite(e)}function U(e){return typeof e==`string`&&e.trim()!==``}function W(e){return V(e)&&typeof e.component==`string`}export{c as HTML_TAGS,_ as checkMetas,y as componentModuleOf,v as manifestComponent,g as readMetas};
|
package/dist/spec.d.ts
CHANGED
|
@@ -12,6 +12,8 @@ export interface CanvasSpecBox {
|
|
|
12
12
|
export interface CanvasSpecTokenValues {
|
|
13
13
|
light: string;
|
|
14
14
|
dark: string;
|
|
15
|
+
// The token reference the style key names, with its sigil: "$leading.heading", or "-$space.2" for a negative.
|
|
16
|
+
path?: string;
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
export interface CanvasSpecCode {
|
package/package.json
CHANGED