@knapsack/renderer-react 4.70.0--canary.4513.12c8d13.0 → 4.70.0--canary.3797.b249674.0

Sign up to get free protection for your applications and to get access to all the features.
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