@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/dist/index.js CHANGED
@@ -1,1314 +1,53 @@
1
- var __create = Object.create;
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __getProtoOf = Object.getPrototypeOf;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
1
+ 'use strict';
29
2
 
30
- // src/index.ts
31
- var src_exports = {};
32
- __export(src_exports, {
33
- KnapsackReactRenderer: () => KnapsackReactRenderer
34
- });
35
- module.exports = __toCommonJS(src_exports);
3
+ var Ie = require('sleep-promise');
4
+ var rendererWebpackBase = require('@knapsack/renderer-webpack-base');
5
+ var utils = require('@knapsack/utils');
6
+ var app = require('@knapsack/app');
7
+ var renderers = require('@knapsack/app/renderers');
8
+ var types = require('@knapsack/types');
9
+ var fileUtils = require('@knapsack/file-utils');
10
+ var h = require('path');
11
+ var creatorUtils = require('@knapsack/creator-utils');
12
+ var ksFileUtils = require('@knapsack/ks-file-utils');
36
13
 
37
- // src/renderer-react.ts
38
- var import_sleep_promise = __toESM(require("sleep-promise"));
39
- var import_renderer_webpack_base = require("@knapsack/renderer-webpack-base");
40
- var import_utils3 = require("@knapsack/utils");
41
- var import_app2 = require("@knapsack/app");
42
- var import_renderers = require("@knapsack/app/renderers");
43
- var import_types2 = require("@knapsack/types");
44
- var import_file_utils3 = require("@knapsack/file-utils");
45
- var import_path2 = require("path");
14
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
46
15
 
47
- // src/utils.ts
48
- var import_app = require("@knapsack/app");
49
- var import_file_utils = require("@knapsack/file-utils");
50
- var import_utils = require("@knapsack/utils");
51
- var import_path = __toESM(require("path"));
52
- var import_types = require("@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}
16
+ var Ie__default = /*#__PURE__*/_interopDefault(Ie);
17
+ var h__default = /*#__PURE__*/_interopDefault(h);
18
+
19
+ 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 `
20
+ <${r}
21
+ ${e}
22
+ ${t?`>
23
+ ${t}
24
+ </${r}>`:"/>"}
25
+ `}c(ee,"renderUsageTemplate");var O="DemoApp";function te({imports:r="",children:e}){return `${r}
73
26
 
74
- function ${demoAppName}() {
27
+ function ${O}() {
75
28
  return (
76
- ${children}
29
+ ${e}
77
30
  )
78
31
  }
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 ? (0, import_file_utils.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 (0, import_file_utils.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 (0, import_file_utils.findUp)("tsconfig.json", {
150
- cwd: import_path.default.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 }) => (0, import_utils.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) => (0, import_utils.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 ((0, import_types.isNumberProp)(spec.props.properties[propName])) {
278
- spec.props.properties[propName].default = parseFloat(
279
- defaultValue.value
280
- );
281
- } else {
282
- spec.props.properties[propName].default = (0, import_utils.removeWrappingDoubleQuotes)(defaultValue.value);
283
- }
284
- }
285
- }
286
- });
287
- return spec;
288
- } catch (error) {
289
- import_app.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 (0, import_file_utils.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" ? (0, import_utils.removeWrappingDoubleQuotes)(defaultValue.value) : defaultValue.value;
365
- }
366
- }
367
- });
368
- return spec;
369
- } catch (error) {
370
- import_app.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 ((0, import_types.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 (0, import_file_utils.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 (0, import_file_utils.resolvePath)({
417
- path: unknownSrc,
418
- resolveFromDir
419
- });
420
- if (!jsInfo.exists) return { type: "unknown" };
421
- const { ext } = import_path.default.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
- import_app.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 } = (0, import_file_utils.getModulePkgJson)("react");
497
- const { version: reactDomVersion } = (0, import_file_utils.getModulePkgJson)("react-dom");
498
- const reactRoot = import_path.default.dirname(
499
- require.resolve("react", {
500
- paths: [process.cwd()]
501
- })
502
- );
503
- const reactDomRoot = import_path.default.dirname(
504
- require.resolve("react-dom", {
505
- paths: [process.cwd()]
506
- })
507
- );
508
- await Promise.all([
509
- (0, import_file_utils.copy)(
510
- import_path.default.join(reactRoot, "umd/react.development.js"),
511
- import_path.default.join(distDirAbsolute, `react.development.${reactVersion}.js`)
512
- ),
513
- (0, import_file_utils.copy)(
514
- import_path.default.join(reactRoot, "umd/react.production.min.js"),
515
- import_path.default.join(distDirAbsolute, `react.production.min.${reactVersion}.js`)
516
- ),
517
- (0, import_file_utils.copy)(
518
- import_path.default.join(reactDomRoot, "umd/react-dom.production.min.js"),
519
- import_path.default.join(
520
- distDirAbsolute,
521
- `react-dom.production.min.${reactDomVersion}.js`
522
- )
523
- ),
524
- (0, import_file_utils.copy)(
525
- import_path.default.join(reactDomRoot, "umd/react-dom.development.js"),
526
- import_path.default.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
- import_path.default.join(publicPath, `react.${reactFileSuffix}.${reactVersion}.js`),
535
- import_path.default.join(
536
- publicPath,
537
- `react-dom.${reactFileSuffix}.${reactDomVersion}.js`
538
- )
539
- ];
540
- } catch (error) {
541
- import_app.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
- var import_file_utils2 = require("@knapsack/file-utils");
553
- var import_creator_utils = require("@knapsack/creator-utils");
554
- var import_ks_file_utils = require("@knapsack/ks-file-utils");
555
- var import_utils2 = require("@knapsack/utils");
556
- function isCapitalLetter(char) {
557
- return char.toUpperCase() === char;
558
- }
559
- __name(isCapitalLetter, "isCapitalLetter");
560
- function startsWithCapitalLetter(str) {
561
- return isCapitalLetter(str[0]);
562
- }
563
- __name(startsWithCapitalLetter, "startsWithCapitalLetter");
564
- function createPatternData({
565
- importName,
566
- id,
567
- title = importName,
568
- pkgPath,
569
- initialDemoId
570
- }) {
571
- return {
572
- id,
573
- title,
574
- description: "",
575
- statuses: {
576
- main: "ready"
577
- },
578
- templates: [
579
- {
580
- id: "react",
581
- title: "react",
582
- path: pkgPath,
583
- alias: importName,
584
- templateLanguageId: "react",
585
- spec: {
586
- isInferred: true
587
- },
588
- demoIds: [initialDemoId],
589
- blockIds: []
590
- }
591
- ],
592
- tabs: [
593
- {
594
- type: "template",
595
- id: "react"
596
- }
597
- ],
598
- subPages: []
599
- };
600
- }
601
- __name(createPatternData, "createPatternData");
602
- var createReactPattern = (0, import_creator_utils.createCreator)({
603
- id: "react-patterns",
604
- title: "React Ks Patterns",
605
- description: "Adds React templates as Knapsack Patterns",
606
- getQuestions: /* @__PURE__ */ __name(async () => ({
607
- pkgPath: {
608
- type: "text",
609
- title: "Package path"
610
- },
611
- importPrefix: {
612
- type: "text",
613
- title: "Import Prefix to Remove"
614
- }
615
- }), "getQuestions"),
616
- getTasks: /* @__PURE__ */ __name(async ({ answers: { pkgPath, importPrefix = "" }, config }) => {
617
- const dataDir = config.dest;
618
- const currentPatterns = await (0, import_ks_file_utils.readKsPatternConfigs)({
619
- dataDir
620
- });
621
- const currentReactPatternsImportNames = currentPatterns.reduce(
622
- (cur, pattern) => {
623
- const reactTemplates = pattern.templates?.filter((t) => t.templateLanguageId === "react") ?? [];
624
- cur.push(...reactTemplates.map((t) => t.alias));
625
- return cur;
626
- },
627
- []
628
- );
629
- const { exports: allImports } = await (0, import_file_utils2.getJsExportNames)({
630
- path: pkgPath
631
- });
632
- return [
633
- {
634
- title: "Pick Imports to add",
635
- task: /* @__PURE__ */ __name((_, task) => import_creator_utils.tasks.runSubCreator({
636
- task,
637
- config,
638
- creator: (0, import_creator_utils.createCreator)({
639
- id: "react-pattern-import-names",
640
- getQuestions: /* @__PURE__ */ __name(async () => ({
641
- importNames: {
642
- type: "choices",
643
- choices: allImports.filter(
644
- (importName) => startsWithCapitalLetter(importName) && !currentReactPatternsImportNames.includes(importName)
645
- ).map((importName) => ({
646
- value: importName
647
- }))
648
- }
649
- }), "getQuestions"),
650
- getTasks: /* @__PURE__ */ __name(async ({ answers: { importNames } }) => {
651
- const patterns = importNames.map((importName) => ({
652
- importName,
653
- patternId: importName.startsWith(importPrefix) ? importName.slice(importPrefix.length).toLowerCase() : importName.toLowerCase()
654
- }));
655
- return [
656
- ...patterns.map(
657
- ({ importName, patternId }) => ({
658
- title: `Add ${importName} React Template`,
659
- task: /* @__PURE__ */ __name(async (__, subTask) => {
660
- const initialDemo = {
661
- type: "data",
662
- id: (0, import_utils2.makeShortId)(),
663
- title: "Main",
664
- patternId,
665
- templateId: "react",
666
- data: {
667
- props: {},
668
- slots: {}
669
- }
670
- };
671
- const pattern = createPatternData({
672
- id: patternId,
673
- importName,
674
- pkgPath,
675
- initialDemoId: initialDemo.id
676
- });
677
- await Promise.all([
678
- (0, import_ks_file_utils.writeDemo)({
679
- dataDir,
680
- demo: initialDemo
681
- }),
682
- (0, import_ks_file_utils.writeKsPatternConfig)({
683
- dataDir,
684
- patternId,
685
- data: pattern
686
- })
687
- ]);
688
- }, "task")
689
- })
690
- ),
691
- {
692
- title: `Updating Nav`,
693
- task: /* @__PURE__ */ __name(async (__, subTask) => {
694
- const { byId } = await (0, import_ks_file_utils.readKsNavConfig)({
695
- dataDir
696
- });
697
- const componentsGroup = Object.values(byId).find(
698
- ({ path: path2, name, id }) => {
699
- if (path2) return false;
700
- if (name.toLowerCase() === "patterns") return true;
701
- if (name.toLowerCase() === "components") return true;
702
- return false;
703
- }
704
- );
705
- await (0, import_ks_file_utils.addKsNavItems)({
706
- dataDir,
707
- navItems: patterns.map(({ patternId }) => ({
708
- navId: patternId,
709
- navPath: `/pattern/${patternId}`,
710
- navParent: componentsGroup?.id || "root"
711
- }))
712
- });
713
- }, "task")
714
- }
715
- ];
716
- }, "getTasks")
717
- })
718
- }), "task")
719
- }
720
- ];
721
- }, "getTasks")
722
- });
723
-
724
- // src/types.ts
725
- var rendererMetaScriptTagId = "ks-react-meta";
726
-
727
- // src/renderer-react.ts
728
- var { pkg } = (0, import_file_utils3.findUpPkgJson)(__dirname);
729
- import_app2.log.setupUpdateNotifier({ ...pkg, name: pkg.name, version: pkg.version });
730
- var KnapsackReactRenderer = class _KnapsackReactRenderer extends import_renderer_webpack_base.RendererWebpackBase {
731
- static {
732
- __name(this, "KnapsackReactRenderer");
733
- }
734
- /**
735
- * `react.js` & `react-dom.js` root relative paths
736
- */
737
- assets;
738
- babelConfig;
739
- demoWrapperPath;
740
- disableReactStrictMode;
741
- constructor({
742
- webpackConfig,
743
- demoWrapperPath = (0, import_path2.join)(__dirname, "./demo-wrapper.mjs"),
744
- id = import_types2.rendererIds.react,
745
- disableReactStrictMode
746
- } = {}) {
747
- super({
748
- id,
749
- extension: ".jsx",
750
- language: "jsx",
751
- webpackConfig,
752
- extraScripts: [
753
- // this is the code in `./client/init.mts`
754
- "@knapsack/renderer-react/client"
755
- ]
756
- });
757
- this.language = "jsx";
758
- this.assets = [];
759
- this.demoWrapperPath = demoWrapperPath;
760
- this.disableReactStrictMode = disableReactStrictMode;
761
- this.creators = [createReactPattern];
762
- }
763
- init = /* @__PURE__ */ __name(async (opt) => {
764
- await super.init(opt);
765
- this.assets = await copyReactAssets(this.outputDir, this.publicPath);
766
- if (!await (0, import_file_utils3.exists)(this.demoWrapperPath)) {
767
- throw new Error(
768
- `Could not find demo wrapper at: "${this.demoWrapperPath}"`
769
- );
770
- }
771
- }, "init");
772
- getMeta = /* @__PURE__ */ __name(() => ({
773
- id: this.id,
774
- title: "React",
775
- aliasUse: "optional",
776
- aliasTitle: "Named Export",
777
- aliasIsJsNamedExport: true,
778
- aliasDescription: "If `export X` was used instead of `export default`, then provide X.",
779
- enableDataDemos: true,
780
- enableTemplateDemos: true,
781
- hasSlotsSupport: true,
782
- hasSlotOptionsSupport: true,
783
- version: pkg.version,
784
- hasInferSpecSupport: true,
785
- syntaxHighlightingLanguage: "jsx",
786
- hasTemplateSuggestionsSupport: true,
787
- prototypingTemplate: {
788
- path: "@knapsack/renderer-react/prototype-template",
789
- spec: {
790
- isInferred: false,
791
- props: {
792
- type: "object",
793
- properties: {}
794
- },
795
- slots: {
796
- children: { title: "Children" }
797
- }
798
- }
799
- }
800
- }), "getMeta");
801
- changeCase = /* @__PURE__ */ __name((str) => (0, import_utils3.pascalCase)(str), "changeCase");
802
- createWebpackConfig = /* @__PURE__ */ __name(() => {
803
- const config = super.createWebpackConfig();
804
- config.externals = {
805
- react: "React",
806
- "react-dom": "ReactDOM"
807
- };
808
- return config;
809
- }, "createWebpackConfig");
810
- getJsImports = /* @__PURE__ */ __name(() => {
811
- const imports = super.getJsImports();
812
- imports.push(
813
- {
814
- type: "extra",
815
- importInfo: {
816
- type: "default",
817
- path: this.demoWrapperPath,
818
- name: "DemoWrapper"
819
- }
820
- },
821
- {
822
- type: "extra",
823
- importInfo: {
824
- type: "default",
825
- path: (0, import_path2.join)(__dirname, "./error-catcher.mjs"),
826
- name: "ErrorCatcher"
827
- }
828
- }
829
- );
830
- return imports;
831
- }, "getJsImports");
832
- async prepClientRenderResults({
833
- usage,
834
- demoApp,
835
- imports: xImports,
836
- renderOptions: { pattern, template, demo }
837
- }) {
838
- const extraImports = this.getJsImports().filter(
839
- (imp) => imp.type === "extra"
840
- );
841
- const { imports, isDeclaredVarsUnique, nameCollisions } = this.makeKsJsImportsUnique({ imports: [...xImports, ...extraImports] });
842
- if (!isDeclaredVarsUnique) {
843
- import_app2.log.error(`${nameCollisions.join(", ")} are declared multiple times`, {
844
- imports
845
- });
846
- }
847
- const meta = {
848
- demo,
849
- disableReactStrictMode: this.disableReactStrictMode,
850
- neededImports: imports,
851
- demoWrapperProps: {
852
- pattern,
853
- template,
854
- demo,
855
- patternsUsed: imports.flatMap((imp) => {
856
- if (imp.type === "pattern-template") {
857
- return [
858
- {
859
- patternId: imp.patternId,
860
- templateId: imp.templateId
861
- }
862
- ];
863
- }
864
- if (imp.type === "pattern-template-demo") {
865
- return [
866
- {
867
- patternId: imp.patternId,
868
- templateId: imp.templateId,
869
- demoId: imp.demoId
870
- }
871
- ];
872
- }
873
- return [];
874
- })
875
- }
876
- };
877
- let code = `
32
+ `}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(`
33
+ `)}</>`;i.push(`${n}={${u}}`);});let m=ee({templateName:t,attributes:[...o,...i].join(" "),children:s});return r.format?fileUtils.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?fileUtils.formatCode({contents:s,path:"x.tsx"}):s}c(v,"getDemoAppUsage");async function J({src:r}){let e=await fileUtils.findUp("tsconfig.json",{cwd:h__default.default.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})=>utils.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=>utils.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&&(types.isNumberProp(t.props.properties[i])?t.props.properties[i].default=parseFloat(p.value):t.props.properties[i].default=utils.removeWrappingDoubleQuotes(p.value)));}),t}catch(t){return app.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 fileUtils.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"?utils.removeWrappingDoubleQuotes(n.value):n.value));}),a}catch(t){return app.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])=>{types.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 fileUtils.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 fileUtils.resolvePath({path:r,resolveFromDir:e});if(!s.exists)return {type:"unknown"};let{ext:a}=h__default.default.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(()=>{app.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}=fileUtils.getModulePkgJson("react"),{version:s}=fileUtils.getModulePkgJson("react-dom"),a=h__default.default.dirname(K.resolve("react",{paths:[process.cwd()]})),o=h__default.default.dirname(K.resolve("react-dom",{paths:[process.cwd()]}));await Promise.all([fileUtils.copy(h__default.default.join(a,"umd/react.development.js"),h__default.default.join(r,`react.development.${t}.js`)),fileUtils.copy(h__default.default.join(a,"umd/react.production.min.js"),h__default.default.join(r,`react.production.min.${t}.js`)),fileUtils.copy(h__default.default.join(o,"umd/react-dom.production.min.js"),h__default.default.join(r,`react-dom.production.min.${s}.js`)),fileUtils.copy(h__default.default.join(o,"umd/react-dom.development.js"),h__default.default.join(r,`react-dom.development.${s}.js`))]);let i=process.env.NODE_ENV==="production"?"production.min":"development";return [h__default.default.join(e,`react.${i}.${t}.js`),h__default.default.join(e,`react-dom.${i}.${s}.js`)]}catch(t){app.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=creatorUtils.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 ksFileUtils.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 fileUtils.getJsExportNames({path:r});return [{title:"Pick Imports to add",task:c((l,m)=>creatorUtils.tasks.runSubCreator({task:m,config:t,creator:creatorUtils.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:utils.makeShortId(),title:"Main",patternId:f,templateId:"react",data:{props:{},slots:{}}},P=Pe({id:f,importName:u,pkgPath:r,initialDemoId:d.id});await Promise.all([ksFileUtils.writeDemo({dataDir:s,demo:d}),ksFileUtils.writeKsPatternConfig({dataDir:s,patternId:f,data:P})]);},"task")})),{title:"Updating Nav",task:c(async(u,f)=>{let{byId:y}=await ksFileUtils.readKsNavConfig({dataDir:s}),R=Object.values(y).find(({path:d,name:P,id:w})=>d?!1:P.toLowerCase()==="patterns"||P.toLowerCase()==="components");await ksFileUtils.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}=fileUtils.findUpPkgJson(__dirname);app.log.setupUpdateNotifier({...j,name:j.name,version:j.version});var Q=class r extends rendererWebpackBase.RendererWebpackBase{static{c(this,"KnapsackReactRenderer");}assets;babelConfig;demoWrapperPath;disableReactStrictMode;constructor({webpackConfig:e,demoWrapperPath:t=h.join(__dirname,"./demo-wrapper.mjs"),id:s=types.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 fileUtils.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=>utils.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:h.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||app.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=`
878
34
  window.knapsack = window.knapsack || {};
879
- window.knapsack.getDemoApp = ({ ${imports.map((i) => i.importInfo.name).join(", ")} }) => {
880
- ${demoApp}
881
- return ${demoAppName}
35
+ window.knapsack.getDemoApp = ({ ${m.map(d=>d.importInfo.name).join(", ")} }) => {
36
+ ${t}
37
+ return ${O}
882
38
  }
883
- `;
884
- let errorHtmlMsg = "";
885
- try {
886
- code = await (0, import_renderers.babelCodeForBrowser)({ code });
887
- } catch (e) {
888
- console.log(code);
889
- console.log("---original code before babel error ^---");
890
- console.trace(e.message);
891
- code = `console.error(${JSON.stringify(e.message)});`;
892
- errorHtmlMsg = `<pre><code>${e.message}</code></pre>`;
893
- }
894
- const html = `
895
- <script type="application/json" id="${rendererMetaScriptTagId}">${JSON.stringify(
896
- meta
897
- )}</script>
898
- <script type="application/javascript">${code}</script>
39
+ `,y="";try{f=await renderers.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=`
40
+ <script type="application/json" id="${H}">${JSON.stringify(u)}</script>
41
+ <script type="application/javascript">${f}</script>
899
42
  <div id="render-root" class="knapsack-pattern-direct-parent" data-dev-note="Knapsack React Template Wrapper"></div>
900
- ${this.assets.map((asset) => `<script src="${asset}"></script>`).join("\n")}
901
- ${this.createHtmlTagsForAssetPaths({
902
- assets: this.getWebpackAssetPaths(),
903
- // 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
904
- scriptTagsAreAsync: false
905
- })}
906
- ${errorHtmlMsg}
907
- `;
908
- return {
909
- ok: !errorHtmlMsg,
910
- html: await (0, import_file_utils3.formatCode)({
911
- contents: html,
912
- path: "x.html"
913
- // doing this to set format language
914
- }),
915
- usage,
916
- templateLanguage: this.language
917
- };
918
- }
919
- render = /* @__PURE__ */ __name(async (opt) => {
920
- if (opt.demo?.type === "template") {
921
- const waits = [5, 10, 20, 50, 100, 1e3, 1e3];
922
- let templateDemoPath;
923
- let attempt = 0;
924
- while (true) {
925
- try {
926
- const { absolutePath, exists } = await this.resolvePath(
927
- opt.demo.templateInfo.path
928
- );
929
- if (!exists) {
930
- throw new Error(
931
- `Template demo file does not exist: ${absolutePath}`
932
- );
933
- }
934
- templateDemoPath = absolutePath;
935
- break;
936
- } catch (e) {
937
- const waitTime = waits[attempt];
938
- if (!waitTime) {
939
- throw new Error(e);
940
- }
941
- attempt += 1;
942
- await (0, import_sleep_promise.default)(waitTime);
943
- }
944
- }
945
- const [templateFileContents, { usage, imports }] = await Promise.all([
946
- (0, import_file_utils3.readFile)(templateDemoPath),
947
- this.getUsageAndImports(opt)
948
- ]);
949
- const demoApp = await getDemoAppUsage({
950
- children: usage
951
- });
952
- const results = await this.prepClientRenderResults({
953
- usage: templateFileContents,
954
- demoApp,
955
- imports,
956
- renderOptions: opt
957
- });
958
- return results;
959
- }
960
- if (opt.demo?.type === "data") {
961
- const { usage, imports } = await this.getUsageAndImports(opt);
962
- const { code: importCode } = this.createJsImportCodeBlock({
963
- imports
964
- });
965
- const [demoAppUsage, demoApp] = await Promise.all([
966
- getDemoAppUsage({
967
- children: usage,
968
- imports: importCode,
969
- format: true
970
- }),
971
- getDemoAppUsage({
972
- children: usage
973
- })
974
- ]);
975
- return this.prepClientRenderResults({
976
- demoApp,
977
- usage: demoAppUsage,
978
- imports,
979
- renderOptions: opt
980
- });
981
- }
982
- }, "render");
983
- getUsageAndImports = /* @__PURE__ */ __name(async ({
984
- pattern,
985
- template,
986
- patternManifest,
987
- demo
988
- }) => {
989
- if (demo?.type && demo.type === "data") {
990
- const {
991
- data: { props, slots, slotsOptionsComputed }
992
- } = demo;
993
- const importInfo = this.getJsImport({
994
- patternId: pattern.id,
995
- templateId: template.id
996
- });
997
- if (!importInfo) {
998
- throw new Error(
999
- `Could not find import for pattern-template: ${pattern.id}-${template.id}`
1000
- );
1001
- }
1002
- const { type, name: templateName } = importInfo.importInfo;
1003
- const importInfos = [importInfo];
1004
- const children = [];
1005
- const extraProps = [];
1006
- if (slots) {
1007
- const slotNames = Object.keys(slots);
1008
- const slotUsages = await Promise.all(
1009
- slotNames.map(async (slotName) => {
1010
- const slotItems = slots[slotName];
1011
- const slotItemsUsages = await Promise.all(
1012
- slotItems.filter((slotItem) => {
1013
- if (slotItem.type !== "text") {
1014
- if (!slotItem.patternId) return false;
1015
- if (!slotItem.templateId) return false;
1016
- if (slotItem.type === "template-demo" && !slotItem.demoId) {
1017
- return false;
1018
- }
1019
- }
1020
- return true;
1021
- }).map(async (slotItem) => {
1022
- if (slotItem.type === "text") {
1023
- if (slotItems.length === 1 && slotName !== "children") {
1024
- return `\`${slotItem.text}\``;
1025
- }
1026
- return slotItem.text;
1027
- }
1028
- const slotPattern = patternManifest.getPattern(
1029
- slotItem.patternId
1030
- );
1031
- const slotTemplate = slotPattern.templates.find(
1032
- (t) => t.id === slotItem.templateId
1033
- );
1034
- if (slotItem.type === "template-reference") {
1035
- const { usage: usage2, imports } = await this.getUsageAndImports({
1036
- pattern: slotPattern,
1037
- template: slotTemplate,
1038
- patternManifest
1039
- });
1040
- importInfos.push(...imports);
1041
- return usage2;
1042
- }
1043
- if (slotItem.type === "template-demo") {
1044
- const { usage: usage2, imports } = await this.getUsageAndImports({
1045
- pattern: slotPattern,
1046
- template: slotTemplate,
1047
- demo: slotItem.demo || this.patterns.demosById[slotItem.demoId],
1048
- patternManifest
1049
- });
1050
- importInfos.push(...imports);
1051
- return usage2;
1052
- }
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 } = (0, import_renderers.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
- imports: importInfos
1112
- };
1113
- }
1114
- if (demo?.type && demo.type === "template") {
1115
- const importInfo = this.getJsImport({
1116
- patternId: pattern.id,
1117
- templateId: template.id,
1118
- demoId: demo.id
1119
- });
1120
- if (!importInfo) {
1121
- throw new Error(
1122
- `Could not find import for pattern-template-demo: ${pattern.id}-${template.id}-${demo.id}`
1123
- );
1124
- }
1125
- const { type, name: templateName } = importInfo.importInfo;
1126
- const usage = await getUsage({ templateName });
1127
- return {
1128
- usage,
1129
- imports: [importInfo]
1130
- };
1131
- }
1132
- if (!demo) {
1133
- const importInfo = this.getJsImport({
1134
- patternId: pattern.id,
1135
- templateId: template.id
1136
- });
1137
- if (!importInfo) {
1138
- throw new Error(
1139
- `Could not find import for pattern-template: ${pattern.id}-${template.id}`
1140
- );
1141
- }
1142
- const { type, name: templateName } = importInfo.importInfo;
1143
- return {
1144
- /**
1145
- * 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`
1146
- * @see {KsSlotInfo['isTemplateReference']}
1147
- * @see {SlottedTemplate}
1148
- */
1149
- usage: templateName,
1150
- imports: [importInfo]
1151
- };
1152
- }
1153
- throw new Error(
1154
- `Unhandled demo type for ${pattern.id}-${template.id}: ${JSON.stringify(
1155
- demo
1156
- )}`
1157
- );
1158
- }, "getUsageAndImports");
1159
- inferSpec = /* @__PURE__ */ __name(async ({
1160
- template,
1161
- templatePath
1162
- }) => {
1163
- const spec = await getReactDocs({
1164
- src: template.path,
1165
- exportName: template.alias || "default",
1166
- resolveFromDir: this.config.data
1167
- });
1168
- if (spec !== false) {
1169
- const totalProps = Object.keys(spec?.props?.properties || {}).length;
1170
- const totalSlots = Object.keys(spec?.slots || {}).length;
1171
- if (totalProps === 0 && totalSlots === 0) {
1172
- return false;
1173
- }
1174
- }
1175
- return spec;
1176
- }, "inferSpec");
1177
- watch = /* @__PURE__ */ __name(async (opt) => {
1178
- super.watch(opt);
1179
- import_app2.knapsackEvents.onPatternTemplateChanged(() => {
1180
- clearInferSpecCache();
1181
- });
1182
- }, "watch");
1183
- getTemplateMeta = /* @__PURE__ */ __name(async ({
1184
- pattern,
1185
- template
1186
- }) => {
1187
- const files = [];
1188
- if (template?.spec?.props) {
1189
- const schema = JSON.parse(JSON.stringify(template.spec.props));
1190
- if (template?.spec?.slots) {
1191
- Object.entries(template.spec.slots).forEach(([id, info]) => {
1192
- schema.properties[id] = {
1193
- typeof: "function",
1194
- tsType: "React.ReactNode",
1195
- description: info.allowedPatternIds ? `${info.description}. Only use: ${info.allowedPatternIds.join(
1196
- ", "
1197
- )}` : info.description
1198
- };
1199
- schema.required = schema.required ?? [];
1200
- if (info.isRequired) schema.required.push(id);
1201
- });
1202
- }
1203
- const typeDefs = await _KnapsackReactRenderer.convertSchemaToTypeScriptDefs({
1204
- schema,
1205
- title: `${this.changeCase(pattern.id)}Props`,
1206
- // @todo pull in base url
1207
- description: `[Knapsack Docs](http://localhost:3999/pattern/${pattern.id}/${template.id})`,
1208
- patternId: pattern.id,
1209
- templateId: template.id,
1210
- postBanner: `import * as React from 'react';`
1211
- });
1212
- files.push({
1213
- contents: typeDefs,
1214
- encoding: "utf8",
1215
- path: `${pattern.id}.${template.id}.spec.d.ts`
1216
- });
1217
- files.push({
1218
- contents: JSON.stringify(schema, null, " "),
1219
- encoding: "utf8",
1220
- path: `${pattern.id}.${template.id}.spec.json`
1221
- });
1222
- }
1223
- return files;
1224
- }, "getTemplateMeta");
1225
- alterTemplateMetaFiles = /* @__PURE__ */ __name(async ({
1226
- files,
1227
- metaDir
1228
- }) => {
1229
- const imports = [];
1230
- const ext = ".spec.d.ts";
1231
- files.forEach((file) => {
1232
- if (file.path.endsWith(ext)) {
1233
- const { base } = (0, import_path2.parse)(file.path);
1234
- const [patternId, templateId] = base.split(".");
1235
- const isFirst = templateId === this.id;
1236
- const exportName = this.changeCase(`${patternId}Props`);
1237
- const exportNameWithTemplateId = this.changeCase(
1238
- `${patternId}-${templateId}Props`
1239
- );
1240
- imports.push(
1241
- `export { ${isFirst ? exportName : `${exportName} as ${exportNameWithTemplateId}`} } from './${(0, import_path2.relative)(metaDir, file.path).replace(".d.ts", "")}';`
1242
- );
1243
- }
1244
- });
1245
- imports.push("");
1246
- return [
1247
- ...files,
1248
- {
1249
- contents: imports.join("\n"),
1250
- encoding: "utf8",
1251
- path: (0, import_path2.join)(metaDir, "react.d.ts")
1252
- }
1253
- ];
1254
- }, "alterTemplateMetaFiles");
1255
- getTemplateSuggestions = /* @__PURE__ */ __name(async ({
1256
- newPath
1257
- }) => {
1258
- const { data: dataDir } = this.patterns.userConfig;
1259
- const { allTemplateDemos, allTemplates } = this.getMyTemplates();
1260
- const usedSuggestions = [
1261
- ...allTemplateDemos,
1262
- ...allTemplates
1263
- ].map(({ path: path2, alias }) => {
1264
- return {
1265
- path: path2,
1266
- alias: alias || "default"
1267
- };
1268
- });
1269
- const allPaths = [
1270
- .../* @__PURE__ */ new Set([newPath, ...usedSuggestions.map(({ path: path2 }) => path2)])
1271
- ];
1272
- const allSuggestions = await Promise.all(
1273
- allPaths.map(async (path2) => {
1274
- if (!path2) return [];
1275
- try {
1276
- const { exports: exports2, errorMsg } = await (0, import_file_utils3.getJsExportNames)({
1277
- path: path2,
1278
- resolveFromDir: dataDir,
1279
- pkgPathAliases: this.pkgPathAliases
1280
- });
1281
- if (errorMsg) {
1282
- throw new Error(errorMsg);
1283
- }
1284
- return exports2.filter((e) => e === "default" || (0, import_utils3.isFirstLetterCapital)(e)).map((name) => ({
1285
- alias: name,
1286
- path: path2
1287
- }));
1288
- } catch (e) {
1289
- import_app2.log.verbose(
1290
- `Error getting import names for ${path2}: ${e.message}`,
1291
- null,
1292
- this.logPrefix
1293
- );
1294
- return [];
1295
- }
1296
- })
1297
- ).then((results) => {
1298
- return results.flat();
1299
- });
1300
- const suggestions = allSuggestions.filter((s) => {
1301
- return !usedSuggestions.find(
1302
- (us) => us.alias === s.alias && us.path === s.path
1303
- );
1304
- });
1305
- return {
1306
- suggestions
1307
- };
1308
- }, "getTemplateSuggestions");
1309
- };
1310
- // Annotate the CommonJS export names for ESM import in node:
1311
- 0 && (module.exports = {
1312
- KnapsackReactRenderer
1313
- });
43
+ ${this.assets.map(d=>`<script src="${d}"></script>`).join(`
44
+ `)}
45
+ ${this.createHtmlTagsForAssetPaths({assets:this.getWebpackAssetPaths(),scriptTagsAreAsync:!1})}
46
+ ${y}
47
+ `;return {ok:!y,html:await fileUtils.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__default.default(u);}let[o,{usage:i,imports:l}]=await Promise.all([fileUtils.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}=renderers.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(`
48
+ `),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),app.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}=h.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 './${h.relative(t,o.path).replace(".d.ts","")}';`);}}),s.push(""),[...e,{contents:s.join(`
49
+ `),encoding:"utf8",path:h.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 fileUtils.getJsExportNames({path:n,resolveFromDir:t,pkgPathAliases:this.pkgPathAliases});if(u)throw new Error(u);return p.filter(f=>f==="default"||utils.isFirstLetterCapital(f)).map(f=>({alias:f,path:n}))}catch(p){return app.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")};
50
+
51
+ exports.KnapsackReactRenderer = Q;
52
+ //# sourceMappingURL=index.js.map
1314
53
  //# sourceMappingURL=index.js.map