@knapsack/renderer-react 4.70.0--canary.3797.b249674.0 → 4.70.0--canary.4821.56b0218.0
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/client/init.js +66 -15
- package/dist/client/init.js.map +1 -1
- package/dist/client/init.mjs +71 -10
- package/dist/client/init.mjs.map +1 -1
- package/dist/demo-wrapper.d.mts +1 -2
- package/dist/demo-wrapper.d.ts +1 -2
- package/dist/demo-wrapper.js +27 -7
- package/dist/demo-wrapper.js.map +1 -1
- package/dist/demo-wrapper.mjs +9 -5
- package/dist/demo-wrapper.mjs.map +1 -1
- package/dist/error-catcher.js +94 -28
- package/dist/error-catcher.js.map +1 -1
- package/dist/error-catcher.mjs +66 -6
- package/dist/error-catcher.mjs.map +1 -1
- package/dist/index.d.mts +5 -7
- package/dist/index.d.ts +5 -7
- package/dist/index.js +1283 -42
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1292 -37
- package/dist/index.mjs.map +1 -1
- package/dist/prototype-template.js +26 -5
- package/dist/prototype-template.js.map +1 -1
- package/dist/prototype-template.mjs +8 -3
- package/dist/prototype-template.mjs.map +1 -1
- package/dist/types-CivTHEEo.d.mts +10 -0
- package/dist/types-CivTHEEo.d.ts +10 -0
- package/package.json +13 -13
- package/dist/types-D2eCZXsg.d.mts +0 -13
- package/dist/types-D2eCZXsg.d.ts +0 -13
package/dist/index.mjs
CHANGED
@@ -1,46 +1,1301 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
import { createCreator, tasks } from '@knapsack/creator-utils';
|
10
|
-
import { readKsPatternConfigs, writeDemo, writeKsPatternConfig, readKsNavConfig, addKsNavItems } from '@knapsack/ks-file-utils';
|
1
|
+
var __defProp = Object.defineProperty;
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
3
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
4
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
5
|
+
}) : x)(function(x) {
|
6
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
7
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
8
|
+
});
|
11
9
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
`}c(ee,"renderUsageTemplate");var O="DemoApp";function te({imports:r="",children:e}){return `${r}
|
10
|
+
// ../../../../node_modules/.pnpm/tsup@8.2.4_@microsoft+api-extractor@7.43.8_@types+node@20.16.6__@swc+core@1.3.57_@swc+helpers_iqa4vqpgdlzwuubzthdmdz7nfe/node_modules/tsup/assets/esm_shims.js
|
11
|
+
import { fileURLToPath } from "url";
|
12
|
+
import path from "path";
|
13
|
+
var getFilename = /* @__PURE__ */ __name(() => fileURLToPath(import.meta.url), "getFilename");
|
14
|
+
var getDirname = /* @__PURE__ */ __name(() => path.dirname(getFilename()), "getDirname");
|
15
|
+
var __dirname = /* @__PURE__ */ getDirname();
|
19
16
|
|
20
|
-
|
17
|
+
// src/renderer-react.ts
|
18
|
+
import sleep from "sleep-promise";
|
19
|
+
import {
|
20
|
+
RendererWebpackBase,
|
21
|
+
convertImportMapToNeededImportsByPath
|
22
|
+
} from "@knapsack/renderer-webpack-base";
|
23
|
+
import { pascalCase, isFirstLetterCapital } from "@knapsack/utils";
|
24
|
+
import { knapsackEvents, log as log2 } from "@knapsack/app";
|
25
|
+
import {
|
26
|
+
babelCodeForBrowser,
|
27
|
+
createSlotOptionsHtmlTags
|
28
|
+
} from "@knapsack/app/renderers";
|
29
|
+
import {
|
30
|
+
rendererIds
|
31
|
+
} from "@knapsack/types";
|
32
|
+
import {
|
33
|
+
exists as fileExists,
|
34
|
+
findUpPkgJson,
|
35
|
+
getJsExportNames as getJsExportNames2,
|
36
|
+
readFile as readFile2,
|
37
|
+
formatCode as formatCode2,
|
38
|
+
assertFileExists
|
39
|
+
} from "@knapsack/file-utils";
|
40
|
+
import { join, relative, parse, isAbsolute } from "path";
|
41
|
+
|
42
|
+
// src/utils.ts
|
43
|
+
import { log } from "@knapsack/app";
|
44
|
+
import {
|
45
|
+
getModulePkgJson,
|
46
|
+
readFile,
|
47
|
+
copy,
|
48
|
+
formatCode,
|
49
|
+
resolvePath,
|
50
|
+
findUp
|
51
|
+
} from "@knapsack/file-utils";
|
52
|
+
import { removeWrappingDoubleQuotes } from "@knapsack/utils";
|
53
|
+
import path2 from "path";
|
54
|
+
import { isNumberProp, isOptionsProp } from "@knapsack/types";
|
55
|
+
function renderUsageTemplate({
|
56
|
+
templateName,
|
57
|
+
attributes,
|
58
|
+
children
|
59
|
+
}) {
|
60
|
+
return `
|
61
|
+
<${templateName}
|
62
|
+
${attributes}
|
63
|
+
${children ? `>
|
64
|
+
${children}
|
65
|
+
</${templateName}>` : "/>"}
|
66
|
+
`;
|
67
|
+
}
|
68
|
+
__name(renderUsageTemplate, "renderUsageTemplate");
|
69
|
+
var demoAppName = "DemoApp";
|
70
|
+
function renderDemoAppTemplate({
|
71
|
+
imports = "",
|
72
|
+
children
|
73
|
+
}) {
|
74
|
+
return `${imports}
|
75
|
+
|
76
|
+
function ${demoAppName}() {
|
21
77
|
return (
|
22
|
-
${
|
78
|
+
${children}
|
23
79
|
)
|
24
80
|
}
|
25
|
-
|
26
|
-
`)}</>`;i.push(`${n}={${u}}`);});let m=ee({templateName:t,attributes:[...o,...i].join(" "),children:s});return r.format?formatCode({contents:m,path:"x.tsx"}).then(n=>n.trim()).catch(()=>m.trim()):m.trim()}c(M,"getUsage");async function v({children:r,imports:e,format:t}){let s=te({children:r,imports:e});return t?formatCode({contents:s,path:"x.tsx"}):s}c(v,"getDemoAppUsage");async function J({src:r}){let e=await findUp("tsconfig.json",{cwd:h.dirname(r)}),t=await import('react-docgen-typescript'),s={shouldExtractLiteralValuesFromEnum:!0,savePropValueAsString:!0,skipChildrenPropWithoutDoc:!1,customComponentTypes:["VoidFunctionComponent","VFC"]};return {info:(e?t.withCustomConfig(e,s).parse:t.withDefaultConfig(s).parse)(r)}}c(J,"getTypeScriptInfoFromFile");function re({info:r,exportName:e}){try{if(!r)return !1;let t={props:{$schema:"http://json-schema.org/draft-07/schema",type:"object",required:[],properties:{}},slots:{}},a=!e||e==="default"?r.pop():r.find(i=>i.displayName===e);if(!a)return !1;return Object.entries(a?.props||{}).forEach(([i,l])=>{let{name:m,description:n,defaultValue:p,required:u,type:f,parent:y}=l;switch(f?.name?.replace("| undefined","").replace(/<.*/g,"").trim()){case"string":t.props.properties[i]={type:"string"};break;case"number":t.props.properties[i]={type:"number"};break;case"boolean":case"bool":p&&"value"in p&&(p.value=p.value==="true"),t.props.properties[i]={type:"boolean"};break;case"enum":t.props.properties[i]={type:"string",enum:[...new Set(f.value.map(({value:d})=>removeWrappingDoubleQuotes(d?.trim())).filter(Boolean))]};break;case"ReactNode":case"React.ReactNode":case"React.ReactElement":case"ReactElement":t.slots[i]={title:i},n&&(t.slots[i]={...t.slots[i],description:n});break;case"VFC":case"FC":t.slots[i]={title:i,description:n||"A reference to a component",isTemplateReference:!0,allowOnlyOne:!0,disallowText:!0};break;default:if(f?.name?.startsWith("("))t.props.properties[i]={typeof:"function",tsType:l?.type?.name};else if(f?.name?.includes("|")){let d=f.name.split("|").map(P=>removeWrappingDoubleQuotes(P.trim())).filter(Boolean);d?.length&&(t.props.properties[i]={type:"string",enum:[...new Set(d)]});}else t.props.properties[i]={tsType:l?.type?.name};}t.props.properties[i]&&(u&&t.props.required.push(i),n&&!t.props.properties[i].description&&(t.props.properties[i].description=n),p&&"value"in p&&(isNumberProp(t.props.properties[i])?t.props.properties[i].default=parseFloat(p.value):t.props.properties[i].default=removeWrappingDoubleQuotes(p.value)));}),t}catch(t){return log.verbose("Could not infer spec from React TypeScript file",{exportName:e,error:t},"react renderer"),!1}}c(re,"extractSpecFromTypeScriptInfo");async function se({src:r}){let e=await import('react-docgen'),{builtinResolvers:t}=e,s=await readFile(r),{FindExportedDefinitionsResolver:a}=t;return {info:e.parse(s,{resolver:new a,handlers:null,filename:r})}}c(se,"getPropTypesInfoFromFile");function ae({info:r,exportName:e}){try{let s=!e||e==="default"?r.pop():r.find(o=>o.displayName===e),a={isInferred:!0,props:{$schema:"http://json-schema.org/draft-07/schema",type:"object",required:[],properties:{}},slots:{}};return Object.entries(s?.props||{}).forEach(([o,i])=>{let{required:l,description:m,defaultValue:n}=i;switch(i?.type?.name){case"string":a.props.properties[o]={type:"string"};break;case"func":a.props.properties[o]={type:"string"};break;case"bool":a.props.properties[o]={type:"boolean"};break;case"node":a.slots[o]={title:o,description:m};}a.props.properties[o]&&(l&&a.props.required.push(o),m&&!a.props.properties[o].description&&(a.props.properties[o].description=m),n&&"value"in n&&(a.props.properties[o].default=typeof n.value=="string"?removeWrappingDoubleQuotes(n.value):n.value));}),a}catch(t){return log.verbose("Could not infer spec from React PropTypes",{exportName:e,error:t},"react renderer"),!1}}c(ae,"extractSpecFromPropTypesInfo");function ne({spec:r}){return r===!1||Object.entries(r?.props?.properties||{}).forEach(([e,t])=>{isOptionsProp(t)&&(t.enum.includes(t.default)||(t.default=void 0));}),r}c(ne,"cleanUpSpec");async function oe({src:r,resolveFromDir:e}){let t=await resolvePath({path:r,resolveFromDir:e,resolveType:"types"});if(t.exists){let o=await J({src:t.absolutePath});if(o)return {type:"typescript",info:o.info}}let s=await resolvePath({path:r,resolveFromDir:e});if(!s.exists)return {type:"unknown"};let{ext:a}=h.parse(s.absolutePath);switch(a){case".jsx":return {type:"propTypes",info:(await se({src:s.absolutePath})).info};case".ts":case".tsx":return {type:"typescript",info:(await J({src:s.absolutePath})).info};default:return {type:"unknown"}}}c(oe,"getReactModuleInfoUncached");var $=new Map,V=c(()=>{log.info("Clearing React TypeScript inferSpec cache..."),$.clear();},"clearInferSpecCache");async function ie(r){let e=JSON.stringify(r);return $.has(e)||$.set(e,oe(r)),$.get(e)}c(ie,"getReactModuleInfo");async function pe({src:r,exportName:e,resolveFromDir:t}){let s=await ie({src:r,resolveFromDir:t});switch(s.type){case"typescript":return re({info:s.info,exportName:e});case"propTypes":return ae({info:s.info,exportName:e});case"unknown":default:return !1}}c(pe,"getReactSpec");async function B(r){return ne({spec:await pe(r)})}c(B,"getReactDocs");async function L(r,e){try{let{version:t}=getModulePkgJson("react"),{version:s}=getModulePkgJson("react-dom"),a=h.dirname(K.resolve("react",{paths:[process.cwd()]})),o=h.dirname(K.resolve("react-dom",{paths:[process.cwd()]}));await Promise.all([copy(h.join(a,"umd/react.development.js"),h.join(r,`react.development.${t}.js`)),copy(h.join(a,"umd/react.production.min.js"),h.join(r,`react.production.min.${t}.js`)),copy(h.join(o,"umd/react-dom.production.min.js"),h.join(r,`react-dom.production.min.${s}.js`)),copy(h.join(o,"umd/react-dom.development.js"),h.join(r,`react-dom.development.${s}.js`))]);let i=process.env.NODE_ENV==="production"?"production.min":"development";return [h.join(e,`react.${i}.${t}.js`),h.join(e,`react-dom.${i}.${s}.js`)]}catch(t){log.warn('Error trying to copy "react" and "react-dom" JS files, are they installed? We want to use your exact versions.',t,"templateRenderer:react"),process.exit(1);}}c(L,"copyReactAssets");function ye(r){return r.toUpperCase()===r}c(ye,"isCapitalLetter");function we(r){return ye(r[0])}c(we,"startsWithCapitalLetter");function Pe({importName:r,id:e,title:t=r,pkgPath:s,initialDemoId:a}){return {id:e,title:t,description:"",statuses:{main:"ready"},templates:[{id:"react",title:"react",path:s,alias:r,templateLanguageId:"react",spec:{isInferred:!0},demoIds:[a],blockIds:[]}],tabs:[{type:"template",id:"react"}],subPages:[]}}c(Pe,"createPatternData");var G=createCreator({id:"react-patterns",title:"React Ks Patterns",description:"Adds React templates as Knapsack Patterns",getQuestions:c(async()=>({pkgPath:{type:"text",title:"Package path"},importPrefix:{type:"text",title:"Import Prefix to Remove"}}),"getQuestions"),getTasks:c(async({answers:{pkgPath:r,importPrefix:e=""},config:t})=>{let s=t.dest,o=(await readKsPatternConfigs({dataDir:s})).reduce((l,m)=>{let n=m.templates?.filter(p=>p.templateLanguageId==="react")??[];return l.push(...n.map(p=>p.alias)),l},[]),{exports:i}=await getJsExportNames({path:r});return [{title:"Pick Imports to add",task:c((l,m)=>tasks.runSubCreator({task:m,config:t,creator:createCreator({id:"react-pattern-import-names",getQuestions:c(async()=>({importNames:{type:"choices",choices:i.filter(n=>we(n)&&!o.includes(n)).map(n=>({value:n}))}}),"getQuestions"),getTasks:c(async({answers:{importNames:n}})=>{let p=n.map(u=>({importName:u,patternId:u.startsWith(e)?u.slice(e.length).toLowerCase():u.toLowerCase()}));return [...p.map(({importName:u,patternId:f})=>({title:`Add ${u} React Template`,task:c(async(y,R)=>{let d={type:"data",id:makeShortId(),title:"Main",patternId:f,templateId:"react",data:{props:{},slots:{}}},P=Pe({id:f,importName:u,pkgPath:r,initialDemoId:d.id});await Promise.all([writeDemo({dataDir:s,demo:d}),writeKsPatternConfig({dataDir:s,patternId:f,data:P})]);},"task")})),{title:"Updating Nav",task:c(async(u,f)=>{let{byId:y}=await readKsNavConfig({dataDir:s}),R=Object.values(y).find(({path:d,name:P,id:w})=>d?!1:P.toLowerCase()==="patterns"||P.toLowerCase()==="components");await addKsNavItems({dataDir:s,navItems:p.map(({patternId:d})=>({navId:d,navPath:`/pattern/${d}`,navParent:R?.id||"root"}))});},"task")}]},"getTasks")})}),"task")}]},"getTasks")});var H="ks-react-meta";var{pkg:j}=findUpPkgJson(__dirname);log.setupUpdateNotifier({...j,name:j.name,version:j.version});var Q=class r extends RendererWebpackBase{static{c(this,"KnapsackReactRenderer");}assets;babelConfig;demoWrapperPath;disableReactStrictMode;constructor({webpackConfig:e,demoWrapperPath:t=join(__dirname,"./demo-wrapper.mjs"),id:s=rendererIds.react,disableReactStrictMode:a}={}){super({id:s,extension:".jsx",language:"jsx",webpackConfig:e,extraScripts:["@knapsack/renderer-react/client"]}),this.language="jsx",this.assets=[],this.demoWrapperPath=t,this.disableReactStrictMode=a,this.creators=[G];}init=c(async e=>{if(await super.init(e),this.assets=await L(this.outputDir,this.publicPath),!await exists(this.demoWrapperPath))throw new Error(`Could not find demo wrapper at: "${this.demoWrapperPath}"`)},"init");getMeta=c(()=>({id:this.id,title:"React",aliasUse:"optional",aliasTitle:"Named Export",aliasIsJsNamedExport:!0,aliasDescription:"If `export X` was used instead of `export default`, then provide X.",enableDataDemos:!0,enableTemplateDemos:!0,hasSlotsSupport:!0,hasSlotOptionsSupport:!0,version:j.version,hasInferSpecSupport:!0,syntaxHighlightingLanguage:"jsx",hasTemplateSuggestionsSupport:!0,prototypingTemplate:{path:"@knapsack/renderer-react/prototype-template",spec:{isInferred:!1,props:{type:"object",properties:{}},slots:{children:{title:"Children"}}}}}),"getMeta");changeCase=c(e=>pascalCase(e),"changeCase");createWebpackConfig=c(()=>{let e=super.createWebpackConfig();return e.externals={react:"React","react-dom":"ReactDOM"},e},"createWebpackConfig");getJsImports=c(()=>{let e=super.getJsImports();return e.push({type:"extra",importInfo:{type:"default",path:this.demoWrapperPath,name:"DemoWrapper"}},{type:"extra",importInfo:{type:"default",path:join(__dirname,"./error-catcher.mjs"),name:"ErrorCatcher"}}),e},"getJsImports");async prepClientRenderResults({usage:e,demoApp:t,imports:s,renderOptions:{pattern:a,template:o,demo:i}}){let l=this.getJsImports().filter(d=>d.type==="extra"),{imports:m,isDeclaredVarsUnique:n,nameCollisions:p}=this.makeKsJsImportsUnique({imports:[...s,...l]});n||log.error(`${p.join(", ")} are declared multiple times`,{imports:m});let u={demo:i,disableReactStrictMode:this.disableReactStrictMode,neededImports:m,demoWrapperProps:{pattern:a,template:o,demo:i,patternsUsed:m.flatMap(d=>d.type==="pattern-template"?[{patternId:d.patternId,templateId:d.templateId}]:d.type==="pattern-template-demo"?[{patternId:d.patternId,templateId:d.templateId,demoId:d.demoId}]:[])}},f=`
|
81
|
+
`;
|
82
|
+
}
|
83
|
+
__name(renderDemoAppTemplate, "renderDemoAppTemplate");
|
84
|
+
async function getUsage(data) {
|
85
|
+
const props = Object.keys(data.props || {}).map((key) => {
|
86
|
+
const value = data.props[key];
|
87
|
+
return {
|
88
|
+
key,
|
89
|
+
value
|
90
|
+
};
|
91
|
+
});
|
92
|
+
const { templateName, children, extraProps = [] } = data;
|
93
|
+
if (!templateName) {
|
94
|
+
throw new Error(
|
95
|
+
`Cannot getUsage of a React Component when no "templateName" is provided.`
|
96
|
+
);
|
97
|
+
}
|
98
|
+
const attributes = props.map(({ key, value }) => {
|
99
|
+
switch (typeof value) {
|
100
|
+
case "string":
|
101
|
+
if (value.startsWith("(") && value.includes("=>")) {
|
102
|
+
return `${key}={${value}}`;
|
103
|
+
}
|
104
|
+
return `${key}="${value}"`;
|
105
|
+
case "boolean":
|
106
|
+
return value ? `${key}` : `${key}={${value}}`;
|
107
|
+
default:
|
108
|
+
return `${key}={${JSON.stringify(value)}}`;
|
109
|
+
}
|
110
|
+
});
|
111
|
+
const extraAttributes = [];
|
112
|
+
const slotProps = {};
|
113
|
+
extraProps.forEach(({ key, value }) => {
|
114
|
+
slotProps[key] = slotProps[key] ?? [];
|
115
|
+
slotProps[key].push(value);
|
116
|
+
});
|
117
|
+
Object.entries(slotProps).forEach(([key, values]) => {
|
118
|
+
const value = values.length === 1 ? values[0] : `<>${values.join("\n")}</>`;
|
119
|
+
extraAttributes.push(`${key}={${value}}`);
|
120
|
+
});
|
121
|
+
const result = renderUsageTemplate({
|
122
|
+
templateName,
|
123
|
+
attributes: [...attributes, ...extraAttributes].join(" "),
|
124
|
+
children
|
125
|
+
});
|
126
|
+
return data.format ? formatCode({
|
127
|
+
contents: result,
|
128
|
+
path: "x.tsx"
|
129
|
+
// doing this to set format language
|
130
|
+
}).then((code) => code.trim()).catch(() => result.trim()) : result.trim();
|
131
|
+
}
|
132
|
+
__name(getUsage, "getUsage");
|
133
|
+
async function getDemoAppUsage({
|
134
|
+
children,
|
135
|
+
imports,
|
136
|
+
format
|
137
|
+
}) {
|
138
|
+
const code = renderDemoAppTemplate({
|
139
|
+
children,
|
140
|
+
imports
|
141
|
+
});
|
142
|
+
if (!format) return code;
|
143
|
+
return formatCode({
|
144
|
+
contents: code,
|
145
|
+
path: "x.tsx"
|
146
|
+
// doing this to set format language
|
147
|
+
});
|
148
|
+
}
|
149
|
+
__name(getDemoAppUsage, "getDemoAppUsage");
|
150
|
+
async function getTypeScriptInfoFromFile({ src }) {
|
151
|
+
const tsConfigPath = await findUp("tsconfig.json", {
|
152
|
+
cwd: path2.dirname(src)
|
153
|
+
});
|
154
|
+
const rdTs = await import("react-docgen-typescript");
|
155
|
+
const config = {
|
156
|
+
shouldExtractLiteralValuesFromEnum: true,
|
157
|
+
savePropValueAsString: true,
|
158
|
+
skipChildrenPropWithoutDoc: false,
|
159
|
+
// In addition to the ones listed here, which had not strangely included these below ~ https://github.com/styleguidist/react-docgen-typescript/blob/287e7012843cb26fed8f4bd8ee24e462c25a1414/src/parser.ts#L308
|
160
|
+
customComponentTypes: ["VoidFunctionComponent", "VFC"]
|
161
|
+
};
|
162
|
+
const parse2 = tsConfigPath ? rdTs.withCustomConfig(tsConfigPath, config).parse : rdTs.withDefaultConfig(config).parse;
|
163
|
+
return {
|
164
|
+
info: parse2(src)
|
165
|
+
};
|
166
|
+
}
|
167
|
+
__name(getTypeScriptInfoFromFile, "getTypeScriptInfoFromFile");
|
168
|
+
function extractSpecFromTypeScriptInfo({
|
169
|
+
info: results,
|
170
|
+
exportName
|
171
|
+
}) {
|
172
|
+
try {
|
173
|
+
if (!results) return false;
|
174
|
+
const spec = {
|
175
|
+
props: {
|
176
|
+
$schema: "http://json-schema.org/draft-07/schema",
|
177
|
+
type: "object",
|
178
|
+
required: [],
|
179
|
+
properties: {}
|
180
|
+
},
|
181
|
+
slots: {
|
182
|
+
// children: {
|
183
|
+
// title: 'children',
|
184
|
+
// },
|
185
|
+
}
|
186
|
+
};
|
187
|
+
const isDefaultExport = !exportName || exportName === "default";
|
188
|
+
const result = isDefaultExport ? results.pop() : results.find((r) => r.displayName === exportName);
|
189
|
+
if (!result) return false;
|
190
|
+
const { displayName } = result;
|
191
|
+
Object.entries(result?.props || {}).forEach(([propName, propDef]) => {
|
192
|
+
const { name, description, defaultValue, required, type, parent } = propDef;
|
193
|
+
const propType = type?.name?.replace("| undefined", "").replace(/<.*/g, "").trim();
|
194
|
+
switch (propType) {
|
195
|
+
case "string":
|
196
|
+
spec.props.properties[propName] = {
|
197
|
+
type: "string"
|
198
|
+
};
|
199
|
+
break;
|
200
|
+
case "number":
|
201
|
+
spec.props.properties[propName] = {
|
202
|
+
type: "number"
|
203
|
+
};
|
204
|
+
break;
|
205
|
+
case "boolean":
|
206
|
+
case "bool":
|
207
|
+
if (defaultValue && "value" in defaultValue) {
|
208
|
+
defaultValue.value = defaultValue.value === "true";
|
209
|
+
}
|
210
|
+
spec.props.properties[propName] = {
|
211
|
+
type: "boolean"
|
212
|
+
};
|
213
|
+
break;
|
214
|
+
case "enum":
|
215
|
+
spec.props.properties[propName] = {
|
216
|
+
type: "string",
|
217
|
+
// yes there is a double "value" & yes it is confusing
|
218
|
+
enum: [
|
219
|
+
// ensure list is unique
|
220
|
+
...new Set(
|
221
|
+
type.value.map(({ value }) => removeWrappingDoubleQuotes(value?.trim())).filter(Boolean)
|
222
|
+
)
|
223
|
+
]
|
224
|
+
};
|
225
|
+
break;
|
226
|
+
case "ReactNode":
|
227
|
+
case "React.ReactNode":
|
228
|
+
case "React.ReactElement":
|
229
|
+
case "ReactElement":
|
230
|
+
spec.slots[propName] = {
|
231
|
+
title: propName
|
232
|
+
};
|
233
|
+
if (description) {
|
234
|
+
spec.slots[propName] = {
|
235
|
+
...spec.slots[propName],
|
236
|
+
description
|
237
|
+
};
|
238
|
+
}
|
239
|
+
break;
|
240
|
+
case "VFC":
|
241
|
+
case "FC":
|
242
|
+
spec.slots[propName] = {
|
243
|
+
title: propName,
|
244
|
+
description: description || "A reference to a component",
|
245
|
+
isTemplateReference: true,
|
246
|
+
allowOnlyOne: true,
|
247
|
+
disallowText: true
|
248
|
+
};
|
249
|
+
break;
|
250
|
+
default: {
|
251
|
+
if (type?.name?.startsWith("(")) {
|
252
|
+
spec.props.properties[propName] = {
|
253
|
+
// description: `\`${type.name}\` ${description}`,
|
254
|
+
typeof: "function",
|
255
|
+
tsType: propDef?.type?.name
|
256
|
+
};
|
257
|
+
} else if (type?.name?.includes("|")) {
|
258
|
+
const options = type.name.split("|").map((enumItem) => removeWrappingDoubleQuotes(enumItem.trim())).filter(Boolean);
|
259
|
+
if (options?.length) {
|
260
|
+
spec.props.properties[propName] = {
|
261
|
+
type: "string",
|
262
|
+
// ensuring list is unique
|
263
|
+
enum: [...new Set(options)]
|
264
|
+
};
|
265
|
+
}
|
266
|
+
} else {
|
267
|
+
spec.props.properties[propName] = {
|
268
|
+
tsType: propDef?.type?.name
|
269
|
+
};
|
270
|
+
}
|
271
|
+
}
|
272
|
+
}
|
273
|
+
if (spec.props.properties[propName]) {
|
274
|
+
if (required) spec.props.required.push(propName);
|
275
|
+
if (description && !spec.props.properties[propName].description) {
|
276
|
+
spec.props.properties[propName].description = description;
|
277
|
+
}
|
278
|
+
if (defaultValue && "value" in defaultValue) {
|
279
|
+
if (isNumberProp(spec.props.properties[propName])) {
|
280
|
+
spec.props.properties[propName].default = parseFloat(
|
281
|
+
defaultValue.value
|
282
|
+
);
|
283
|
+
} else {
|
284
|
+
spec.props.properties[propName].default = removeWrappingDoubleQuotes(defaultValue.value);
|
285
|
+
}
|
286
|
+
}
|
287
|
+
}
|
288
|
+
});
|
289
|
+
return spec;
|
290
|
+
} catch (error) {
|
291
|
+
log.verbose(
|
292
|
+
"Could not infer spec from React TypeScript file",
|
293
|
+
{
|
294
|
+
exportName,
|
295
|
+
error
|
296
|
+
},
|
297
|
+
"react renderer"
|
298
|
+
);
|
299
|
+
return false;
|
300
|
+
}
|
301
|
+
}
|
302
|
+
__name(extractSpecFromTypeScriptInfo, "extractSpecFromTypeScriptInfo");
|
303
|
+
async function getPropTypesInfoFromFile({ src }) {
|
304
|
+
const reactDocs = await import("react-docgen");
|
305
|
+
const { builtinResolvers } = reactDocs;
|
306
|
+
const fileSrc = await readFile(src);
|
307
|
+
const { FindExportedDefinitionsResolver } = builtinResolvers;
|
308
|
+
const results = reactDocs.parse(fileSrc, {
|
309
|
+
resolver: new FindExportedDefinitionsResolver(),
|
310
|
+
handlers: null,
|
311
|
+
filename: src
|
312
|
+
// babelrc: false,
|
313
|
+
});
|
314
|
+
return {
|
315
|
+
info: results
|
316
|
+
};
|
317
|
+
}
|
318
|
+
__name(getPropTypesInfoFromFile, "getPropTypesInfoFromFile");
|
319
|
+
function extractSpecFromPropTypesInfo({
|
320
|
+
info: results,
|
321
|
+
exportName
|
322
|
+
}) {
|
323
|
+
try {
|
324
|
+
const isDefaultExport = !exportName || exportName === "default";
|
325
|
+
const result = isDefaultExport ? results.pop() : results.find((r) => r.displayName === exportName);
|
326
|
+
const spec = {
|
327
|
+
isInferred: true,
|
328
|
+
props: {
|
329
|
+
$schema: "http://json-schema.org/draft-07/schema",
|
330
|
+
type: "object",
|
331
|
+
required: [],
|
332
|
+
properties: {}
|
333
|
+
},
|
334
|
+
slots: {}
|
335
|
+
};
|
336
|
+
Object.entries(result?.props || {}).forEach(([propName, propDef]) => {
|
337
|
+
const { required, description, defaultValue } = propDef;
|
338
|
+
switch (propDef?.type?.name) {
|
339
|
+
case "string":
|
340
|
+
spec.props.properties[propName] = {
|
341
|
+
type: "string"
|
342
|
+
};
|
343
|
+
break;
|
344
|
+
case "func":
|
345
|
+
spec.props.properties[propName] = {
|
346
|
+
type: "string"
|
347
|
+
};
|
348
|
+
break;
|
349
|
+
case "bool":
|
350
|
+
spec.props.properties[propName] = {
|
351
|
+
type: "boolean"
|
352
|
+
};
|
353
|
+
break;
|
354
|
+
case "node":
|
355
|
+
spec.slots[propName] = {
|
356
|
+
title: propName,
|
357
|
+
description
|
358
|
+
};
|
359
|
+
}
|
360
|
+
if (spec.props.properties[propName]) {
|
361
|
+
if (required) spec.props.required.push(propName);
|
362
|
+
if (description && !spec.props.properties[propName].description) {
|
363
|
+
spec.props.properties[propName].description = description;
|
364
|
+
}
|
365
|
+
if (defaultValue && "value" in defaultValue) {
|
366
|
+
spec.props.properties[propName].default = typeof defaultValue.value === "string" ? removeWrappingDoubleQuotes(defaultValue.value) : defaultValue.value;
|
367
|
+
}
|
368
|
+
}
|
369
|
+
});
|
370
|
+
return spec;
|
371
|
+
} catch (error) {
|
372
|
+
log.verbose(
|
373
|
+
"Could not infer spec from React PropTypes",
|
374
|
+
{
|
375
|
+
exportName,
|
376
|
+
error
|
377
|
+
},
|
378
|
+
"react renderer"
|
379
|
+
);
|
380
|
+
return false;
|
381
|
+
}
|
382
|
+
}
|
383
|
+
__name(extractSpecFromPropTypesInfo, "extractSpecFromPropTypesInfo");
|
384
|
+
function cleanUpSpec({
|
385
|
+
spec
|
386
|
+
}) {
|
387
|
+
if (spec === false) return spec;
|
388
|
+
Object.entries(spec?.props?.properties || {}).forEach(([propName, prop]) => {
|
389
|
+
if (isOptionsProp(prop)) {
|
390
|
+
if (!prop.enum.includes(prop.default)) {
|
391
|
+
prop.default = void 0;
|
392
|
+
}
|
393
|
+
}
|
394
|
+
});
|
395
|
+
return spec;
|
396
|
+
}
|
397
|
+
__name(cleanUpSpec, "cleanUpSpec");
|
398
|
+
async function getReactModuleInfoUncached({
|
399
|
+
src: unknownSrc,
|
400
|
+
resolveFromDir
|
401
|
+
}) {
|
402
|
+
const typesInfo = await resolvePath({
|
403
|
+
path: unknownSrc,
|
404
|
+
resolveFromDir,
|
405
|
+
resolveType: "types"
|
406
|
+
});
|
407
|
+
if (typesInfo.exists) {
|
408
|
+
const typeScriptInfo = await getTypeScriptInfoFromFile({
|
409
|
+
src: typesInfo.absolutePath
|
410
|
+
});
|
411
|
+
if (typeScriptInfo) {
|
412
|
+
return {
|
413
|
+
type: "typescript",
|
414
|
+
info: typeScriptInfo.info
|
415
|
+
};
|
416
|
+
}
|
417
|
+
}
|
418
|
+
const jsInfo = await resolvePath({
|
419
|
+
path: unknownSrc,
|
420
|
+
resolveFromDir
|
421
|
+
});
|
422
|
+
if (!jsInfo.exists) return { type: "unknown" };
|
423
|
+
const { ext } = path2.parse(jsInfo.absolutePath);
|
424
|
+
switch (ext) {
|
425
|
+
case ".jsx": {
|
426
|
+
const propTypesInfo = await getPropTypesInfoFromFile({
|
427
|
+
src: jsInfo.absolutePath
|
428
|
+
});
|
429
|
+
return {
|
430
|
+
type: "propTypes",
|
431
|
+
info: propTypesInfo.info
|
432
|
+
};
|
433
|
+
}
|
434
|
+
case ".ts":
|
435
|
+
case ".tsx": {
|
436
|
+
const typeScriptInfo = await getTypeScriptInfoFromFile({
|
437
|
+
src: jsInfo.absolutePath
|
438
|
+
});
|
439
|
+
return {
|
440
|
+
type: "typescript",
|
441
|
+
info: typeScriptInfo.info
|
442
|
+
};
|
443
|
+
}
|
444
|
+
default:
|
445
|
+
return {
|
446
|
+
type: "unknown"
|
447
|
+
};
|
448
|
+
}
|
449
|
+
}
|
450
|
+
__name(getReactModuleInfoUncached, "getReactModuleInfoUncached");
|
451
|
+
var getReactModuleInfoCache = /* @__PURE__ */ new Map();
|
452
|
+
var clearInferSpecCache = /* @__PURE__ */ __name(() => {
|
453
|
+
log.info(`Clearing React TypeScript inferSpec cache...`);
|
454
|
+
getReactModuleInfoCache.clear();
|
455
|
+
}, "clearInferSpecCache");
|
456
|
+
async function getReactModuleInfo(args) {
|
457
|
+
const cacheKey = JSON.stringify(args);
|
458
|
+
if (!getReactModuleInfoCache.has(cacheKey)) {
|
459
|
+
getReactModuleInfoCache.set(cacheKey, getReactModuleInfoUncached(args));
|
460
|
+
}
|
461
|
+
return getReactModuleInfoCache.get(cacheKey);
|
462
|
+
}
|
463
|
+
__name(getReactModuleInfo, "getReactModuleInfo");
|
464
|
+
async function getReactSpec({
|
465
|
+
src,
|
466
|
+
exportName,
|
467
|
+
resolveFromDir
|
468
|
+
}) {
|
469
|
+
const reactModuleInfo = await getReactModuleInfo({
|
470
|
+
src,
|
471
|
+
resolveFromDir
|
472
|
+
});
|
473
|
+
switch (reactModuleInfo.type) {
|
474
|
+
case "typescript":
|
475
|
+
return extractSpecFromTypeScriptInfo({
|
476
|
+
info: reactModuleInfo.info,
|
477
|
+
exportName
|
478
|
+
});
|
479
|
+
case "propTypes":
|
480
|
+
return extractSpecFromPropTypesInfo({
|
481
|
+
info: reactModuleInfo.info,
|
482
|
+
exportName
|
483
|
+
});
|
484
|
+
case "unknown":
|
485
|
+
default:
|
486
|
+
return false;
|
487
|
+
}
|
488
|
+
}
|
489
|
+
__name(getReactSpec, "getReactSpec");
|
490
|
+
async function getReactDocs(opt) {
|
491
|
+
return cleanUpSpec({
|
492
|
+
spec: await getReactSpec(opt)
|
493
|
+
});
|
494
|
+
}
|
495
|
+
__name(getReactDocs, "getReactDocs");
|
496
|
+
async function copyReactAssets(distDirAbsolute, publicPath) {
|
497
|
+
try {
|
498
|
+
const { version: reactVersion } = getModulePkgJson("react");
|
499
|
+
const { version: reactDomVersion } = getModulePkgJson("react-dom");
|
500
|
+
const reactRoot = path2.dirname(
|
501
|
+
__require.resolve("react", {
|
502
|
+
paths: [process.cwd()]
|
503
|
+
})
|
504
|
+
);
|
505
|
+
const reactDomRoot = path2.dirname(
|
506
|
+
__require.resolve("react-dom", {
|
507
|
+
paths: [process.cwd()]
|
508
|
+
})
|
509
|
+
);
|
510
|
+
await Promise.all([
|
511
|
+
copy(
|
512
|
+
path2.join(reactRoot, "umd/react.development.js"),
|
513
|
+
path2.join(distDirAbsolute, `react.development.${reactVersion}.js`)
|
514
|
+
),
|
515
|
+
copy(
|
516
|
+
path2.join(reactRoot, "umd/react.production.min.js"),
|
517
|
+
path2.join(distDirAbsolute, `react.production.min.${reactVersion}.js`)
|
518
|
+
),
|
519
|
+
copy(
|
520
|
+
path2.join(reactDomRoot, "umd/react-dom.production.min.js"),
|
521
|
+
path2.join(
|
522
|
+
distDirAbsolute,
|
523
|
+
`react-dom.production.min.${reactDomVersion}.js`
|
524
|
+
)
|
525
|
+
),
|
526
|
+
copy(
|
527
|
+
path2.join(reactDomRoot, "umd/react-dom.development.js"),
|
528
|
+
path2.join(
|
529
|
+
distDirAbsolute,
|
530
|
+
`react-dom.development.${reactDomVersion}.js`
|
531
|
+
)
|
532
|
+
)
|
533
|
+
]);
|
534
|
+
const reactFileSuffix = process.env.NODE_ENV === "production" ? "production.min" : "development";
|
535
|
+
return [
|
536
|
+
path2.join(publicPath, `react.${reactFileSuffix}.${reactVersion}.js`),
|
537
|
+
path2.join(
|
538
|
+
publicPath,
|
539
|
+
`react-dom.${reactFileSuffix}.${reactDomVersion}.js`
|
540
|
+
)
|
541
|
+
];
|
542
|
+
} catch (error) {
|
543
|
+
log.warn(
|
544
|
+
'Error trying to copy "react" and "react-dom" JS files, are they installed? We want to use your exact versions.',
|
545
|
+
error,
|
546
|
+
"templateRenderer:react"
|
547
|
+
);
|
548
|
+
process.exit(1);
|
549
|
+
}
|
550
|
+
}
|
551
|
+
__name(copyReactAssets, "copyReactAssets");
|
552
|
+
|
553
|
+
// src/react-creators.ts
|
554
|
+
import { getJsExportNames } from "@knapsack/file-utils";
|
555
|
+
import { createCreator, tasks } from "@knapsack/creator-utils";
|
556
|
+
import {
|
557
|
+
readKsPatternConfigs,
|
558
|
+
writeKsPatternConfig,
|
559
|
+
readKsNavConfig,
|
560
|
+
addKsNavItems,
|
561
|
+
writeDemo
|
562
|
+
} from "@knapsack/ks-file-utils";
|
563
|
+
import { makeShortId } from "@knapsack/utils";
|
564
|
+
function isCapitalLetter(char) {
|
565
|
+
return char.toUpperCase() === char;
|
566
|
+
}
|
567
|
+
__name(isCapitalLetter, "isCapitalLetter");
|
568
|
+
function startsWithCapitalLetter(str) {
|
569
|
+
return isCapitalLetter(str[0]);
|
570
|
+
}
|
571
|
+
__name(startsWithCapitalLetter, "startsWithCapitalLetter");
|
572
|
+
function createPatternData({
|
573
|
+
importName,
|
574
|
+
id,
|
575
|
+
title = importName,
|
576
|
+
pkgPath,
|
577
|
+
initialDemoId
|
578
|
+
}) {
|
579
|
+
return {
|
580
|
+
id,
|
581
|
+
title,
|
582
|
+
description: "",
|
583
|
+
statuses: {
|
584
|
+
main: "ready"
|
585
|
+
},
|
586
|
+
templates: [
|
587
|
+
{
|
588
|
+
id: "react",
|
589
|
+
title: "react",
|
590
|
+
path: pkgPath,
|
591
|
+
alias: importName,
|
592
|
+
templateLanguageId: "react",
|
593
|
+
spec: {
|
594
|
+
isInferred: true
|
595
|
+
},
|
596
|
+
demoIds: [initialDemoId],
|
597
|
+
blockIds: []
|
598
|
+
}
|
599
|
+
],
|
600
|
+
tabs: [
|
601
|
+
{
|
602
|
+
type: "template",
|
603
|
+
id: "react"
|
604
|
+
}
|
605
|
+
],
|
606
|
+
subPages: []
|
607
|
+
};
|
608
|
+
}
|
609
|
+
__name(createPatternData, "createPatternData");
|
610
|
+
var createReactPattern = createCreator({
|
611
|
+
id: "react-patterns",
|
612
|
+
title: "React Ks Patterns",
|
613
|
+
description: "Adds React templates as Knapsack Patterns",
|
614
|
+
getQuestions: /* @__PURE__ */ __name(async () => ({
|
615
|
+
pkgPath: {
|
616
|
+
type: "text",
|
617
|
+
title: "Package path"
|
618
|
+
},
|
619
|
+
importPrefix: {
|
620
|
+
type: "text",
|
621
|
+
title: "Import Prefix to Remove"
|
622
|
+
}
|
623
|
+
}), "getQuestions"),
|
624
|
+
getTasks: /* @__PURE__ */ __name(async ({ answers: { pkgPath, importPrefix = "" }, config }) => {
|
625
|
+
const dataDir = config.dest;
|
626
|
+
const currentPatterns = await readKsPatternConfigs({
|
627
|
+
dataDir
|
628
|
+
});
|
629
|
+
const currentReactPatternsImportNames = currentPatterns.reduce(
|
630
|
+
(cur, pattern) => {
|
631
|
+
const reactTemplates = pattern.templates?.filter((t) => t.templateLanguageId === "react") ?? [];
|
632
|
+
cur.push(...reactTemplates.map((t) => t.alias));
|
633
|
+
return cur;
|
634
|
+
},
|
635
|
+
[]
|
636
|
+
);
|
637
|
+
const { exports: allImports } = await getJsExportNames({
|
638
|
+
path: pkgPath
|
639
|
+
});
|
640
|
+
return [
|
641
|
+
{
|
642
|
+
title: "Pick Imports to add",
|
643
|
+
task: /* @__PURE__ */ __name((_, task) => tasks.runSubCreator({
|
644
|
+
task,
|
645
|
+
config,
|
646
|
+
creator: createCreator({
|
647
|
+
id: "react-pattern-import-names",
|
648
|
+
getQuestions: /* @__PURE__ */ __name(async () => ({
|
649
|
+
importNames: {
|
650
|
+
type: "choices",
|
651
|
+
choices: allImports.filter(
|
652
|
+
(importName) => startsWithCapitalLetter(importName) && !currentReactPatternsImportNames.includes(importName)
|
653
|
+
).map((importName) => ({
|
654
|
+
value: importName
|
655
|
+
}))
|
656
|
+
}
|
657
|
+
}), "getQuestions"),
|
658
|
+
getTasks: /* @__PURE__ */ __name(async ({ answers: { importNames } }) => {
|
659
|
+
const patterns = importNames.map((importName) => ({
|
660
|
+
importName,
|
661
|
+
patternId: importName.startsWith(importPrefix) ? importName.slice(importPrefix.length).toLowerCase() : importName.toLowerCase()
|
662
|
+
}));
|
663
|
+
return [
|
664
|
+
...patterns.map(
|
665
|
+
({ importName, patternId }) => ({
|
666
|
+
title: `Add ${importName} React Template`,
|
667
|
+
task: /* @__PURE__ */ __name(async (__, subTask) => {
|
668
|
+
const initialDemo = {
|
669
|
+
type: "data",
|
670
|
+
id: makeShortId(),
|
671
|
+
title: "Main",
|
672
|
+
patternId,
|
673
|
+
templateId: "react",
|
674
|
+
data: {
|
675
|
+
props: {},
|
676
|
+
slots: {}
|
677
|
+
}
|
678
|
+
};
|
679
|
+
const pattern = createPatternData({
|
680
|
+
id: patternId,
|
681
|
+
importName,
|
682
|
+
pkgPath,
|
683
|
+
initialDemoId: initialDemo.id
|
684
|
+
});
|
685
|
+
await Promise.all([
|
686
|
+
writeDemo({
|
687
|
+
dataDir,
|
688
|
+
demo: initialDemo
|
689
|
+
}),
|
690
|
+
writeKsPatternConfig({
|
691
|
+
dataDir,
|
692
|
+
patternId,
|
693
|
+
data: pattern
|
694
|
+
})
|
695
|
+
]);
|
696
|
+
}, "task")
|
697
|
+
})
|
698
|
+
),
|
699
|
+
{
|
700
|
+
title: `Updating Nav`,
|
701
|
+
task: /* @__PURE__ */ __name(async (__, subTask) => {
|
702
|
+
const { byId } = await readKsNavConfig({
|
703
|
+
dataDir
|
704
|
+
});
|
705
|
+
const componentsGroup = Object.values(byId).find(
|
706
|
+
({ path: path3, name, id }) => {
|
707
|
+
if (path3) return false;
|
708
|
+
if (name.toLowerCase() === "patterns") return true;
|
709
|
+
if (name.toLowerCase() === "components") return true;
|
710
|
+
return false;
|
711
|
+
}
|
712
|
+
);
|
713
|
+
await addKsNavItems({
|
714
|
+
dataDir,
|
715
|
+
navItems: patterns.map(({ patternId }) => ({
|
716
|
+
navId: patternId,
|
717
|
+
navPath: `/pattern/${patternId}`,
|
718
|
+
navParent: componentsGroup?.id || "root"
|
719
|
+
}))
|
720
|
+
});
|
721
|
+
}, "task")
|
722
|
+
}
|
723
|
+
];
|
724
|
+
}, "getTasks")
|
725
|
+
})
|
726
|
+
}), "task")
|
727
|
+
}
|
728
|
+
];
|
729
|
+
}, "getTasks")
|
730
|
+
});
|
731
|
+
|
732
|
+
// src/types.ts
|
733
|
+
var rendererMetaScriptTagId = "ks-react-meta";
|
734
|
+
|
735
|
+
// src/renderer-react.ts
|
736
|
+
var { pkg } = findUpPkgJson(__dirname);
|
737
|
+
log2.setupUpdateNotifier({ ...pkg, name: pkg.name, version: pkg.version });
|
738
|
+
var errorCatcherPath = join(__dirname, "./error-catcher.mjs");
|
739
|
+
var KnapsackReactRenderer = class _KnapsackReactRenderer extends RendererWebpackBase {
|
740
|
+
static {
|
741
|
+
__name(this, "KnapsackReactRenderer");
|
742
|
+
}
|
743
|
+
/**
|
744
|
+
* `react.js` & `react-dom.js` root relative paths
|
745
|
+
*/
|
746
|
+
assets;
|
747
|
+
babelConfig;
|
748
|
+
demoWrapperPath;
|
749
|
+
disableReactStrictMode;
|
750
|
+
constructor({
|
751
|
+
webpackConfig,
|
752
|
+
demoWrapperPath = join(__dirname, "./demo-wrapper.mjs"),
|
753
|
+
id = rendererIds.react,
|
754
|
+
disableReactStrictMode
|
755
|
+
} = {}) {
|
756
|
+
super({
|
757
|
+
id,
|
758
|
+
language: "jsx",
|
759
|
+
webpackConfig,
|
760
|
+
extraScripts: [
|
761
|
+
// this is the code in `./client/init.mts`
|
762
|
+
"@knapsack/renderer-react/client"
|
763
|
+
],
|
764
|
+
codeSrcs: [demoWrapperPath, errorCatcherPath]
|
765
|
+
});
|
766
|
+
this.language = "jsx";
|
767
|
+
this.assets = [];
|
768
|
+
this.demoWrapperPath = isAbsolute(demoWrapperPath) ? demoWrapperPath : this.resolvePathSync({
|
769
|
+
path: demoWrapperPath,
|
770
|
+
resolveFromDir: this.userConfigDir
|
771
|
+
}).absolutePath;
|
772
|
+
assertFileExists(
|
773
|
+
this.demoWrapperPath,
|
774
|
+
`Could not find demo wrapper at: "${this.demoWrapperPath}"
|
775
|
+
Please adjust setting in "knapsack.config.js" or pass a different path when creating the React Renderer.`
|
776
|
+
);
|
777
|
+
this.disableReactStrictMode = disableReactStrictMode;
|
778
|
+
this.creators = [createReactPattern];
|
779
|
+
}
|
780
|
+
init = /* @__PURE__ */ __name(async () => {
|
781
|
+
this.assets = await copyReactAssets(this.outputDir, this.publicPath);
|
782
|
+
if (!await fileExists(this.demoWrapperPath)) {
|
783
|
+
throw new Error(
|
784
|
+
`Could not find demo wrapper at: "${this.demoWrapperPath}"`
|
785
|
+
);
|
786
|
+
}
|
787
|
+
}, "init");
|
788
|
+
getMeta = /* @__PURE__ */ __name(() => ({
|
789
|
+
id: this.id,
|
790
|
+
title: "React",
|
791
|
+
aliasUse: "optional",
|
792
|
+
aliasTitle: "Named Export",
|
793
|
+
aliasIsJsNamedExport: true,
|
794
|
+
aliasDescription: "If `export X` was used instead of `export default`, then provide X.",
|
795
|
+
enableDataDemos: true,
|
796
|
+
enableTemplateDemos: true,
|
797
|
+
hasSlotsSupport: true,
|
798
|
+
hasSlotOptionsSupport: true,
|
799
|
+
version: pkg.version,
|
800
|
+
hasInferSpecSupport: true,
|
801
|
+
syntaxHighlightingLanguage: "jsx",
|
802
|
+
hasTemplateSuggestionsSupport: true,
|
803
|
+
prototypingTemplate: {
|
804
|
+
path: "@knapsack/renderer-react/prototype-template",
|
805
|
+
spec: {
|
806
|
+
isInferred: false,
|
807
|
+
props: {
|
808
|
+
type: "object",
|
809
|
+
properties: {}
|
810
|
+
},
|
811
|
+
slots: {
|
812
|
+
children: { title: "Children" }
|
813
|
+
}
|
814
|
+
}
|
815
|
+
}
|
816
|
+
}), "getMeta");
|
817
|
+
changeCase = /* @__PURE__ */ __name((str) => pascalCase(str), "changeCase");
|
818
|
+
createWebpackConfig = /* @__PURE__ */ __name(() => {
|
819
|
+
const config = super.createWebpackConfig();
|
820
|
+
config.externals = {
|
821
|
+
react: "React",
|
822
|
+
"react-dom": "ReactDOM"
|
823
|
+
};
|
824
|
+
return config;
|
825
|
+
}, "createWebpackConfig");
|
826
|
+
async prepClientRenderResults({
|
827
|
+
usage,
|
828
|
+
demoApp,
|
829
|
+
importMap,
|
830
|
+
renderOptions: { demo, state, patternId, templateId }
|
831
|
+
}) {
|
832
|
+
const meta = {
|
833
|
+
demo,
|
834
|
+
disableReactStrictMode: this.disableReactStrictMode,
|
835
|
+
neededImportsByPath: convertImportMapToNeededImportsByPath(importMap),
|
836
|
+
extraImports: {
|
837
|
+
DemoWrapper: {
|
838
|
+
type: "default",
|
839
|
+
path: this.demoWrapperPath,
|
840
|
+
name: "DemoWrapper"
|
841
|
+
},
|
842
|
+
ErrorCatcher: {
|
843
|
+
type: "default",
|
844
|
+
path: errorCatcherPath,
|
845
|
+
name: "ErrorCatcher"
|
846
|
+
}
|
847
|
+
},
|
848
|
+
demoWrapperProps: {
|
849
|
+
patternId,
|
850
|
+
templateId,
|
851
|
+
demo
|
852
|
+
}
|
853
|
+
};
|
854
|
+
let code = `
|
27
855
|
window.knapsack = window.knapsack || {};
|
28
|
-
window.knapsack.getDemoApp = ({ ${
|
29
|
-
${
|
30
|
-
return ${
|
856
|
+
window.knapsack.getDemoApp = ({ ${[...importMap.keys()].join(", ")} }) => {
|
857
|
+
${demoApp}
|
858
|
+
return ${demoAppName}
|
31
859
|
}
|
32
|
-
|
33
|
-
|
34
|
-
|
860
|
+
`;
|
861
|
+
let errorHtmlMsg = "";
|
862
|
+
try {
|
863
|
+
code = await babelCodeForBrowser({ code });
|
864
|
+
} catch (e) {
|
865
|
+
console.log(code);
|
866
|
+
console.log("---original code before babel error ^---");
|
867
|
+
console.trace(e.message);
|
868
|
+
code = `console.error(${JSON.stringify(e.message)});`;
|
869
|
+
errorHtmlMsg = `<pre><code>${e.message}</code></pre>`;
|
870
|
+
}
|
871
|
+
const html = `
|
872
|
+
<script type="application/json" id="${rendererMetaScriptTagId}">${JSON.stringify(
|
873
|
+
meta
|
874
|
+
)}</script>
|
875
|
+
<script type="application/javascript">${code}</script>
|
35
876
|
<div id="render-root" class="knapsack-pattern-direct-parent" data-dev-note="Knapsack React Template Wrapper"></div>
|
36
|
-
${this.assets.map(
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
877
|
+
${this.assets.map((asset) => `<script src="${asset}"></script>`).join("\n")}
|
878
|
+
${RendererWebpackBase.createHtmlTagsForAssetPaths({
|
879
|
+
assets: this.getWebpackAssetPaths(),
|
880
|
+
// we need the scripts to finish adding methods to the global knapsack object synchronously before the client-side code runs that is in the <script> tag below
|
881
|
+
scriptTagsAreAsync: false
|
882
|
+
})}
|
883
|
+
${errorHtmlMsg}
|
884
|
+
`;
|
885
|
+
return {
|
886
|
+
ok: !errorHtmlMsg,
|
887
|
+
html: await formatCode2({
|
888
|
+
contents: html,
|
889
|
+
path: "x.html"
|
890
|
+
// doing this to set format language
|
891
|
+
}),
|
892
|
+
usage,
|
893
|
+
templateLanguage: this.language
|
894
|
+
};
|
895
|
+
}
|
896
|
+
render = /* @__PURE__ */ __name(async (opt) => {
|
897
|
+
if (opt.demo?.type === "template") {
|
898
|
+
const waits = [5, 10, 20, 50, 100, 1e3, 1e3];
|
899
|
+
let templateDemoPath;
|
900
|
+
let attempt = 0;
|
901
|
+
while (true) {
|
902
|
+
try {
|
903
|
+
const { absolutePath, exists } = await this.resolvePath(
|
904
|
+
opt.demo.templateInfo.path
|
905
|
+
);
|
906
|
+
if (!exists) {
|
907
|
+
throw new Error(
|
908
|
+
`Template demo file does not exist: ${absolutePath}`
|
909
|
+
);
|
910
|
+
}
|
911
|
+
templateDemoPath = absolutePath;
|
912
|
+
break;
|
913
|
+
} catch (e) {
|
914
|
+
const waitTime = waits[attempt];
|
915
|
+
if (!waitTime) {
|
916
|
+
throw new Error(e);
|
917
|
+
}
|
918
|
+
attempt += 1;
|
919
|
+
await sleep(waitTime);
|
920
|
+
}
|
921
|
+
}
|
922
|
+
const [templateFileContents, { usage, importMap }] = await Promise.all([
|
923
|
+
readFile2(templateDemoPath),
|
924
|
+
this.getUsageAndImports({
|
925
|
+
...opt,
|
926
|
+
importMap: /* @__PURE__ */ new Map()
|
927
|
+
})
|
928
|
+
]);
|
929
|
+
const demoApp = await getDemoAppUsage({
|
930
|
+
children: usage
|
931
|
+
});
|
932
|
+
const results = await this.prepClientRenderResults({
|
933
|
+
usage: templateFileContents,
|
934
|
+
demoApp,
|
935
|
+
renderOptions: opt,
|
936
|
+
importMap
|
937
|
+
});
|
938
|
+
return results;
|
939
|
+
}
|
940
|
+
if (opt.demo?.type === "data") {
|
941
|
+
const { usage, importMap } = await this.getUsageAndImports({
|
942
|
+
...opt,
|
943
|
+
importMap: /* @__PURE__ */ new Map()
|
944
|
+
});
|
945
|
+
const importCode = RendererWebpackBase.createJsImportCodeBlock({
|
946
|
+
importMap
|
947
|
+
});
|
948
|
+
const [demoAppUsage, demoApp] = await Promise.all([
|
949
|
+
getDemoAppUsage({
|
950
|
+
children: usage,
|
951
|
+
imports: importCode,
|
952
|
+
format: true
|
953
|
+
}),
|
954
|
+
getDemoAppUsage({
|
955
|
+
children: usage
|
956
|
+
})
|
957
|
+
]);
|
958
|
+
return this.prepClientRenderResults({
|
959
|
+
demoApp,
|
960
|
+
usage: demoAppUsage,
|
961
|
+
renderOptions: opt,
|
962
|
+
importMap
|
963
|
+
});
|
964
|
+
}
|
965
|
+
}, "render");
|
966
|
+
getUsageAndImports = /* @__PURE__ */ __name(async ({
|
967
|
+
patternId,
|
968
|
+
templateId,
|
969
|
+
demo,
|
970
|
+
state,
|
971
|
+
importMap
|
972
|
+
}) => {
|
973
|
+
if (!demo) {
|
974
|
+
throw new Error(
|
975
|
+
`No demo provided while rendering ${patternId} ${templateId}`
|
976
|
+
);
|
977
|
+
}
|
978
|
+
const pattern = state.patterns[patternId];
|
979
|
+
if (!pattern) {
|
980
|
+
throw new Error(`Could not find pattern: ${patternId}`);
|
981
|
+
}
|
982
|
+
if (demo.type === "data") {
|
983
|
+
const template = pattern.templates.find((t) => t.id === templateId);
|
984
|
+
if (!template) {
|
985
|
+
throw new Error(`Could not find template: ${templateId}`);
|
986
|
+
}
|
987
|
+
const {
|
988
|
+
data: { props, slots, slotsOptionsComputed }
|
989
|
+
} = demo;
|
990
|
+
const { name: templateName } = await this.addUniqueValueToImportMap({
|
991
|
+
importMap,
|
992
|
+
path: template.path,
|
993
|
+
alias: template.alias || "default"
|
994
|
+
});
|
995
|
+
const children = [];
|
996
|
+
const extraProps = [];
|
997
|
+
if (slots) {
|
998
|
+
const slotNames = Object.keys(slots);
|
999
|
+
const slotUsages = await Promise.all(
|
1000
|
+
slotNames.map(async (slotName) => {
|
1001
|
+
const slotItems = slots[slotName];
|
1002
|
+
const slotItemsUsages = await Promise.all(
|
1003
|
+
slotItems.filter((slotItem) => {
|
1004
|
+
if (!slotItem) return false;
|
1005
|
+
if (slotItem.type !== "text") {
|
1006
|
+
if (!slotItem.patternId) return false;
|
1007
|
+
if (!slotItem.templateId) return false;
|
1008
|
+
if (slotItem.type === "template-demo" && !slotItem.demoId) {
|
1009
|
+
return false;
|
1010
|
+
}
|
1011
|
+
}
|
1012
|
+
return true;
|
1013
|
+
}).map(async (slotItem) => {
|
1014
|
+
if (slotItem.type === "text") {
|
1015
|
+
if (slotItems.length === 1 && slotName !== "children") {
|
1016
|
+
return `\`${slotItem.text}\``;
|
1017
|
+
}
|
1018
|
+
return slotItem.text;
|
1019
|
+
}
|
1020
|
+
if (slotItem.type === "template-reference") {
|
1021
|
+
const slottedTemplate = state.patterns[slotItem.patternId]?.templates.find((t) => t.id === slotItem.templateId);
|
1022
|
+
if (!slottedTemplate) {
|
1023
|
+
throw new Error(
|
1024
|
+
`Could not find slotted template: ${slotItem.patternId} ${slotItem.templateId}`
|
1025
|
+
);
|
1026
|
+
}
|
1027
|
+
const templateRefImport = await this.addUniqueValueToImportMap({
|
1028
|
+
importMap,
|
1029
|
+
path: slottedTemplate.path,
|
1030
|
+
alias: slottedTemplate.alias || "default"
|
1031
|
+
});
|
1032
|
+
return templateRefImport.name;
|
1033
|
+
}
|
1034
|
+
if (slotItem.type === "template-demo") {
|
1035
|
+
const thisDemo = slotItem.demo;
|
1036
|
+
if (!thisDemo) {
|
1037
|
+
throw new Error(
|
1038
|
+
`Could not find slotted template demo ${JSON.stringify(
|
1039
|
+
slotItem
|
1040
|
+
)}`
|
1041
|
+
);
|
1042
|
+
}
|
1043
|
+
const { usage: usage2 } = await this.getUsageAndImports({
|
1044
|
+
patternId: thisDemo.patternId,
|
1045
|
+
templateId: thisDemo.templateId,
|
1046
|
+
demo: thisDemo,
|
1047
|
+
state,
|
1048
|
+
importMap
|
1049
|
+
});
|
1050
|
+
return usage2;
|
1051
|
+
}
|
1052
|
+
const _exhaustiveCheck2 = slotItem;
|
1053
|
+
throw new Error(
|
1054
|
+
`Unknown slot item: ${JSON.stringify(slotItem)}`
|
1055
|
+
);
|
1056
|
+
})
|
1057
|
+
);
|
1058
|
+
return {
|
1059
|
+
slotName,
|
1060
|
+
slotItemsUsages
|
1061
|
+
};
|
1062
|
+
})
|
1063
|
+
);
|
1064
|
+
slotUsages.forEach(({ slotName, slotItemsUsages }) => {
|
1065
|
+
const slotOptionsComputed = slotsOptionsComputed?.[slotName];
|
1066
|
+
const { openTag, closeTag } = createSlotOptionsHtmlTags({
|
1067
|
+
slotOptionsComputed,
|
1068
|
+
classAttributeName: "className",
|
1069
|
+
stylesValueType: "object"
|
1070
|
+
});
|
1071
|
+
if (openTag) {
|
1072
|
+
if (slotName === "children") {
|
1073
|
+
children.push(openTag);
|
1074
|
+
} else {
|
1075
|
+
extraProps.push({
|
1076
|
+
key: slotName,
|
1077
|
+
value: openTag
|
1078
|
+
});
|
1079
|
+
}
|
1080
|
+
}
|
1081
|
+
slotItemsUsages.forEach((usage2) => {
|
1082
|
+
if (slotName === "children") {
|
1083
|
+
children.push(usage2);
|
1084
|
+
} else {
|
1085
|
+
extraProps.push({
|
1086
|
+
key: slotName,
|
1087
|
+
value: usage2
|
1088
|
+
});
|
1089
|
+
}
|
1090
|
+
});
|
1091
|
+
if (closeTag) {
|
1092
|
+
if (slotName === "children") {
|
1093
|
+
children.push(closeTag);
|
1094
|
+
} else {
|
1095
|
+
extraProps.push({
|
1096
|
+
key: slotName,
|
1097
|
+
value: closeTag
|
1098
|
+
});
|
1099
|
+
}
|
1100
|
+
}
|
1101
|
+
});
|
1102
|
+
}
|
1103
|
+
const usage = await getUsage({
|
1104
|
+
templateName,
|
1105
|
+
props,
|
1106
|
+
children: children.join("\n"),
|
1107
|
+
extraProps
|
1108
|
+
});
|
1109
|
+
return {
|
1110
|
+
usage,
|
1111
|
+
importMap
|
1112
|
+
};
|
1113
|
+
}
|
1114
|
+
if (demo.type === "template") {
|
1115
|
+
const { templateInfo } = demo;
|
1116
|
+
const { name: templateName } = await this.addUniqueValueToImportMap({
|
1117
|
+
importMap,
|
1118
|
+
path: templateInfo.path,
|
1119
|
+
alias: templateInfo.alias || "default"
|
1120
|
+
});
|
1121
|
+
const usage = await getUsage({ templateName });
|
1122
|
+
return {
|
1123
|
+
usage,
|
1124
|
+
importMap
|
1125
|
+
};
|
1126
|
+
}
|
1127
|
+
const _exhaustiveCheck = demo;
|
1128
|
+
throw new Error(
|
1129
|
+
`Unhandled demo type for ${patternId}-${templateId}: ${JSON.stringify(
|
1130
|
+
demo
|
1131
|
+
)}`
|
1132
|
+
);
|
1133
|
+
}, "getUsageAndImports");
|
1134
|
+
inferSpec = /* @__PURE__ */ __name(async ({
|
1135
|
+
template,
|
1136
|
+
templatePath
|
1137
|
+
}) => {
|
1138
|
+
const spec = await getReactDocs({
|
1139
|
+
src: template.path,
|
1140
|
+
exportName: template.alias || "default",
|
1141
|
+
resolveFromDir: this.config.data
|
1142
|
+
});
|
1143
|
+
if (spec !== false) {
|
1144
|
+
const totalProps = Object.keys(spec?.props?.properties || {}).length;
|
1145
|
+
const totalSlots = Object.keys(spec?.slots || {}).length;
|
1146
|
+
if (totalProps === 0 && totalSlots === 0) {
|
1147
|
+
return false;
|
1148
|
+
}
|
1149
|
+
}
|
1150
|
+
return spec;
|
1151
|
+
}, "inferSpec");
|
1152
|
+
watch = /* @__PURE__ */ __name(async () => {
|
1153
|
+
super.watch();
|
1154
|
+
knapsackEvents.onPatternTemplateChanged(() => {
|
1155
|
+
clearInferSpecCache();
|
1156
|
+
});
|
1157
|
+
}, "watch");
|
1158
|
+
getTemplateMeta = /* @__PURE__ */ __name(async ({
|
1159
|
+
pattern,
|
1160
|
+
template
|
1161
|
+
}) => {
|
1162
|
+
const files = [];
|
1163
|
+
if (template?.spec?.props) {
|
1164
|
+
const schema = JSON.parse(JSON.stringify(template.spec.props));
|
1165
|
+
if (template?.spec?.slots) {
|
1166
|
+
Object.entries(template.spec.slots).forEach(([id, info]) => {
|
1167
|
+
schema.properties[id] = {
|
1168
|
+
typeof: "function",
|
1169
|
+
tsType: "React.ReactNode",
|
1170
|
+
description: info.allowedPatternIds ? `${info.description}. Only use: ${info.allowedPatternIds.join(
|
1171
|
+
", "
|
1172
|
+
)}` : info.description
|
1173
|
+
};
|
1174
|
+
schema.required = schema.required ?? [];
|
1175
|
+
if (info.isRequired) schema.required.push(id);
|
1176
|
+
});
|
1177
|
+
}
|
1178
|
+
const typeDefs = await _KnapsackReactRenderer.convertSchemaToTypeScriptDefs({
|
1179
|
+
schema,
|
1180
|
+
title: `${this.changeCase(pattern.id)}Props`,
|
1181
|
+
// @todo pull in base url
|
1182
|
+
description: `[Knapsack Docs](http://localhost:3999/pattern/${pattern.id}/${template.id})`,
|
1183
|
+
patternId: pattern.id,
|
1184
|
+
templateId: template.id,
|
1185
|
+
postBanner: `import * as React from 'react';`
|
1186
|
+
});
|
1187
|
+
files.push({
|
1188
|
+
contents: typeDefs,
|
1189
|
+
encoding: "utf8",
|
1190
|
+
path: `${pattern.id}.${template.id}.spec.d.ts`
|
1191
|
+
});
|
1192
|
+
files.push({
|
1193
|
+
contents: JSON.stringify(schema, null, " "),
|
1194
|
+
encoding: "utf8",
|
1195
|
+
path: `${pattern.id}.${template.id}.spec.json`
|
1196
|
+
});
|
1197
|
+
}
|
1198
|
+
return files;
|
1199
|
+
}, "getTemplateMeta");
|
1200
|
+
alterTemplateMetaFiles = /* @__PURE__ */ __name(async ({
|
1201
|
+
files,
|
1202
|
+
metaDir
|
1203
|
+
}) => {
|
1204
|
+
const imports = [];
|
1205
|
+
const ext = ".spec.d.ts";
|
1206
|
+
files.forEach((file) => {
|
1207
|
+
if (file.path.endsWith(ext)) {
|
1208
|
+
const { base } = parse(file.path);
|
1209
|
+
const [patternId, templateId] = base.split(".");
|
1210
|
+
const isFirst = templateId === this.id;
|
1211
|
+
const exportName = this.changeCase(`${patternId}Props`);
|
1212
|
+
const exportNameWithTemplateId = this.changeCase(
|
1213
|
+
`${patternId}-${templateId}Props`
|
1214
|
+
);
|
1215
|
+
imports.push(
|
1216
|
+
`export { ${isFirst ? exportName : `${exportName} as ${exportNameWithTemplateId}`} } from './${relative(metaDir, file.path).replace(".d.ts", "")}';`
|
1217
|
+
);
|
1218
|
+
}
|
1219
|
+
});
|
1220
|
+
imports.push("");
|
1221
|
+
return [
|
1222
|
+
...files,
|
1223
|
+
{
|
1224
|
+
contents: imports.join("\n"),
|
1225
|
+
encoding: "utf8",
|
1226
|
+
path: join(metaDir, "react.d.ts")
|
1227
|
+
}
|
1228
|
+
];
|
1229
|
+
}, "alterTemplateMetaFiles");
|
1230
|
+
getTemplateSuggestions = /* @__PURE__ */ __name(async ({
|
1231
|
+
newPath,
|
1232
|
+
state
|
1233
|
+
}) => {
|
1234
|
+
const usedSuggestions = Object.values(state.patterns).reduce(
|
1235
|
+
(acc, { templateDemos, templates }) => {
|
1236
|
+
templates.forEach(({ path: path3, alias, templateLanguageId }) => {
|
1237
|
+
if (templateLanguageId !== this.id) return;
|
1238
|
+
acc.push({ path: path3, alias });
|
1239
|
+
});
|
1240
|
+
templateDemos.forEach(
|
1241
|
+
({ templateInfo: { path: path3, alias }, templateLanguageId }) => {
|
1242
|
+
if (templateLanguageId !== this.id) return;
|
1243
|
+
acc.push({ path: path3, alias });
|
1244
|
+
}
|
1245
|
+
);
|
1246
|
+
return acc;
|
1247
|
+
},
|
1248
|
+
[]
|
1249
|
+
);
|
1250
|
+
const codeSrcs = new Set(this.getCodeSrcs());
|
1251
|
+
codeSrcs.delete(this.demoWrapperPath);
|
1252
|
+
codeSrcs.delete(errorCatcherPath);
|
1253
|
+
const allPaths = [
|
1254
|
+
.../* @__PURE__ */ new Set([
|
1255
|
+
newPath,
|
1256
|
+
...Object.keys(this.pkgPathAliases || {}),
|
1257
|
+
...codeSrcs
|
1258
|
+
])
|
1259
|
+
];
|
1260
|
+
const allSuggestions = await Promise.all(
|
1261
|
+
allPaths.map(async (path3) => {
|
1262
|
+
if (!path3) return [];
|
1263
|
+
try {
|
1264
|
+
const { exports, errorMsg } = await getJsExportNames2({
|
1265
|
+
path: path3,
|
1266
|
+
resolveFromDir: this.dataDir,
|
1267
|
+
pkgPathAliases: this.pkgPathAliases
|
1268
|
+
});
|
1269
|
+
if (errorMsg) {
|
1270
|
+
throw new Error(errorMsg);
|
1271
|
+
}
|
1272
|
+
return exports.filter((e) => e === "default" || isFirstLetterCapital(e)).map((name) => ({
|
1273
|
+
alias: name,
|
1274
|
+
path: path3
|
1275
|
+
}));
|
1276
|
+
} catch (e) {
|
1277
|
+
log2.verbose(
|
1278
|
+
`Error getting import names for ${path3}: ${e.message}`,
|
1279
|
+
null,
|
1280
|
+
this.logPrefix
|
1281
|
+
);
|
1282
|
+
return [];
|
1283
|
+
}
|
1284
|
+
})
|
1285
|
+
).then((results) => {
|
1286
|
+
return results.flat();
|
1287
|
+
});
|
1288
|
+
const suggestions = allSuggestions.filter((s) => {
|
1289
|
+
return !usedSuggestions.find(
|
1290
|
+
(us) => us.alias === s.alias && us.path === s.path
|
1291
|
+
);
|
1292
|
+
});
|
1293
|
+
return {
|
1294
|
+
suggestions
|
1295
|
+
};
|
1296
|
+
}, "getTemplateSuggestions");
|
1297
|
+
};
|
1298
|
+
export {
|
1299
|
+
KnapsackReactRenderer
|
1300
|
+
};
|
46
1301
|
//# sourceMappingURL=index.mjs.map
|