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