@reliverse/dler 1.7.14 → 1.7.16
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/README.md +45 -0
- package/bin/app/merge/cmd.d.ts +20 -6
- package/bin/app/merge/cmd.js +294 -117
- package/bin/libs/sdk/sdk-impl/cfg/info.js +1 -1
- package/bin/libs/sdk/sdk-impl/pub/pub-library.js +9 -4
- package/bin/libs/sdk/sdk-impl/pub/pub-regular.js +4 -8
- package/bin/libs/sdk/sdk-impl/utils/utils-error-cwd.js +2 -2
- package/package.json +2 -2
- package/bin/templates/App.css +0 -31
- package/bin/templates/App.tsx +0 -21
- package/bin/templates/DOCS.md +0 -31
- package/bin/templates/globals.css +0 -27
- package/bin/templates/hello/world.ts +0 -1
- package/bin/templates/index.html +0 -12
- package/bin/templates/main.tsx +0 -11
package/README.md
CHANGED
|
@@ -356,6 +356,10 @@ merges multiple files into a single file. The command is built for both CI and i
|
|
|
356
356
|
- includes backup functionality
|
|
357
357
|
- validates file permissions and sizes
|
|
358
358
|
- enforces output path conflict detection
|
|
359
|
+
- supports template generation with TypeScript type definitions
|
|
360
|
+
- handles both single file and directory output modes
|
|
361
|
+
- implements interactive prompts via `@reliverse/rempts`
|
|
362
|
+
- provides reporting with logging via `@reliverse/relinka`
|
|
359
363
|
|
|
360
364
|
**usage examples:**
|
|
361
365
|
|
|
@@ -371,8 +375,49 @@ bun dler merge --s "src/templates" --d "templates/my-template.ts" --as-template
|
|
|
371
375
|
|
|
372
376
|
# update mock template:
|
|
373
377
|
bun dler merge --s "src/templates" --d "templates/my-template.ts" --as-template --update-template REACT_DLER_TEMPLATE
|
|
378
|
+
|
|
379
|
+
# generate multiple templates based on directory structure:
|
|
380
|
+
bun dler merge --s "src/templates" --d "templates" --as-template --template-multi --depth 2
|
|
381
|
+
|
|
382
|
+
# create separate files for each template with an aggregator:
|
|
383
|
+
bun dler merge --s "src/templates" --d "templates/index.ts" --as-template --template-per-file
|
|
374
384
|
```
|
|
375
385
|
|
|
386
|
+
**arguments:**
|
|
387
|
+
|
|
388
|
+
- `--s`: Input glob patterns (array)
|
|
389
|
+
- `--d`: Output file path or directory
|
|
390
|
+
- `--ignore`: Extra ignore patterns (array)
|
|
391
|
+
- `--format`: Fallback extension when output path is omitted (default: "txt")
|
|
392
|
+
- `--stdout`: Print to stdout
|
|
393
|
+
- `--noPath`: Don't inject relative path below each file
|
|
394
|
+
- `--pathAbove`: Print file path above each file's content (default: true)
|
|
395
|
+
- `--separator`: Custom separator (default: "\n\n")
|
|
396
|
+
- `--comment`: Custom comment prefix (e.g. '# ')
|
|
397
|
+
- `--forceComment`: Force custom comment prefix for all file types
|
|
398
|
+
- `--batch`: Disable interactive prompts (CI/non-interactive mode)
|
|
399
|
+
- `--recursive`: Recursively process all files in subdirectories (default: true)
|
|
400
|
+
- `--preserveStructure`: Preserve source directory structure in output (default: true)
|
|
401
|
+
- `--increment`: Attach an incrementing index to each output filename
|
|
402
|
+
- `--concurrency`: Number of concurrent file operations (default: 8)
|
|
403
|
+
- `--sort`: Sort files by: name, path, mtime, none (default: path)
|
|
404
|
+
- `--dryRun`: Show what would be done, but don't write files
|
|
405
|
+
- `--backup`: Backup output files before overwriting
|
|
406
|
+
- `--dedupe`: Remove duplicate file contents in merge
|
|
407
|
+
- `--header`: Header text to add at the start of merged output
|
|
408
|
+
- `--footer`: Footer text to add at the end of merged output
|
|
409
|
+
- `--select-files`: Prompt for file selection before merging
|
|
410
|
+
- `--interactive`: Enable interactive mode with prompts
|
|
411
|
+
- `--as-template`: Generate a TypeScript file with template structure
|
|
412
|
+
- `--custom-template-name`: Custom template name when using --as-template
|
|
413
|
+
- `--template-multi`: Create multiple templates based on directory structure (default: true)
|
|
414
|
+
- `--depth`: Depth level to start processing from (default: 0)
|
|
415
|
+
- `--template-per-file`: Create separate files for each template with an aggregator (default: false)
|
|
416
|
+
- `--whitelabel`: Custom prefix to use instead of 'DLER' in template generation (default: "DLER")
|
|
417
|
+
- `--sourcemap`: Generate source map for the merged output
|
|
418
|
+
- `--update-template`: Update specific template in existing mock template file
|
|
419
|
+
- `--dev`: Generate template for development
|
|
420
|
+
|
|
376
421
|
**implementation details:**
|
|
377
422
|
|
|
378
423
|
- uses `magic-string` for efficient string manipulation and source map generation
|
package/bin/app/merge/cmd.d.ts
CHANGED
|
@@ -101,26 +101,40 @@ declare const _default: import("@reliverse/rempts").Command<{
|
|
|
101
101
|
type: "boolean";
|
|
102
102
|
description: string;
|
|
103
103
|
};
|
|
104
|
+
depth: {
|
|
105
|
+
type: "number";
|
|
106
|
+
description: string;
|
|
107
|
+
default: number;
|
|
108
|
+
};
|
|
109
|
+
sourcemap: {
|
|
110
|
+
type: "boolean";
|
|
111
|
+
description: string;
|
|
112
|
+
};
|
|
104
113
|
"as-template": {
|
|
105
114
|
type: "boolean";
|
|
106
115
|
description: string;
|
|
107
116
|
};
|
|
108
|
-
"
|
|
117
|
+
"template-whitelabel": {
|
|
109
118
|
type: "string";
|
|
110
119
|
description: string;
|
|
120
|
+
default: string;
|
|
121
|
+
dependencies: string[];
|
|
111
122
|
};
|
|
112
|
-
|
|
123
|
+
"template-update": {
|
|
113
124
|
type: "string";
|
|
114
125
|
description: string;
|
|
115
|
-
|
|
126
|
+
dependencies: string[];
|
|
116
127
|
};
|
|
117
|
-
|
|
128
|
+
"template-multi": {
|
|
118
129
|
type: "boolean";
|
|
119
130
|
description: string;
|
|
131
|
+
default: true;
|
|
132
|
+
dependencies: string[];
|
|
120
133
|
};
|
|
121
|
-
"
|
|
122
|
-
type: "
|
|
134
|
+
"template-per-file": {
|
|
135
|
+
type: "boolean";
|
|
123
136
|
description: string;
|
|
137
|
+
default: false;
|
|
124
138
|
dependencies: string[];
|
|
125
139
|
};
|
|
126
140
|
}>;
|
package/bin/app/merge/cmd.js
CHANGED
|
@@ -73,7 +73,7 @@ const maybePrompt = async (interactive, value, promptFn) => {
|
|
|
73
73
|
if (!interactive || value !== void 0) return value;
|
|
74
74
|
return promptFn();
|
|
75
75
|
};
|
|
76
|
-
const collectFiles = async (include, extraIgnore, recursive, sortBy) => {
|
|
76
|
+
const collectFiles = async (include, extraIgnore, recursive, sortBy, depth) => {
|
|
77
77
|
try {
|
|
78
78
|
const normalizedInclude = include.map(normalizeGlobPattern);
|
|
79
79
|
const files = await glob(normalizedInclude, {
|
|
@@ -88,6 +88,19 @@ const collectFiles = async (include, extraIgnore, recursive, sortBy) => {
|
|
|
88
88
|
await checkPermissions(file, "read");
|
|
89
89
|
}
|
|
90
90
|
let filtered = [...new Set(files)];
|
|
91
|
+
if (depth > 0) {
|
|
92
|
+
const fileGroups = /* @__PURE__ */ new Map();
|
|
93
|
+
for (const file of filtered) {
|
|
94
|
+
const relPath = path.relative(process.cwd(), file);
|
|
95
|
+
const parts = relPath.split(path.sep);
|
|
96
|
+
const groupKey = parts.slice(0, depth).join(path.sep);
|
|
97
|
+
if (!fileGroups.has(groupKey)) {
|
|
98
|
+
fileGroups.set(groupKey, []);
|
|
99
|
+
}
|
|
100
|
+
fileGroups.get(groupKey)?.push(file);
|
|
101
|
+
}
|
|
102
|
+
filtered = Array.from(fileGroups.values()).flat();
|
|
103
|
+
}
|
|
91
104
|
if (sortBy === "name") {
|
|
92
105
|
filtered.sort((a, b) => path.basename(a).localeCompare(path.basename(b)));
|
|
93
106
|
} else if (sortBy === "path") {
|
|
@@ -263,6 +276,49 @@ const updateTemplateInFile = async (templateName, templateContent, targetFile, d
|
|
|
263
276
|
handleError(error, "updateTemplateInFile");
|
|
264
277
|
}
|
|
265
278
|
};
|
|
279
|
+
const generateTemplateContent = (template, templateConstName, templateKey, whitelabel, isDev) => {
|
|
280
|
+
return `import type { Template } from "${isDev ? "~/libs/sdk/sdk-types" : "@reliverse/dler-sdk"}";
|
|
281
|
+
${(() => {
|
|
282
|
+
const files = template.config.files;
|
|
283
|
+
if (!files) return "";
|
|
284
|
+
const hasPackageJson = Object.values(files).some(
|
|
285
|
+
(f) => f.type === "json" && f.content
|
|
286
|
+
);
|
|
287
|
+
const hasTSConfig = Object.values(files).some(
|
|
288
|
+
(f) => f.type === "json" && f.content
|
|
289
|
+
);
|
|
290
|
+
if (!hasPackageJson && !hasTSConfig) return "";
|
|
291
|
+
const imports = [];
|
|
292
|
+
if (hasPackageJson) imports.push("PackageJson");
|
|
293
|
+
if (hasTSConfig) imports.push("TSConfig");
|
|
294
|
+
return `import type { ${imports.join(", ")} } from "pkg-types";
|
|
295
|
+
`;
|
|
296
|
+
})()}
|
|
297
|
+
export const ${templateConstName}: Template = ${JSON.stringify(template, null, 2).replace(
|
|
298
|
+
/"([^"]+)":/g,
|
|
299
|
+
(_, key) => {
|
|
300
|
+
return /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(key) ? `${key}:` : `"${key}":`;
|
|
301
|
+
}
|
|
302
|
+
)};
|
|
303
|
+
export const ${whitelabel}_TEMPLATES = {
|
|
304
|
+
${templateKey}: ${templateConstName},
|
|
305
|
+
} as const;
|
|
306
|
+
export type ${whitelabel}_TEMPLATE_NAMES = keyof typeof ${whitelabel}_TEMPLATES;
|
|
307
|
+
export const ${whitelabel.toLowerCase()}TemplatesMap: Record<string, ${whitelabel}_TEMPLATE_NAMES> = {
|
|
308
|
+
${templateConstName}: "${templateKey}",
|
|
309
|
+
};`;
|
|
310
|
+
};
|
|
311
|
+
const generateAggregatorContent = (templateNames, whitelabel, isDev) => {
|
|
312
|
+
return `import type { Template } from "${isDev ? "~/libs/sdk/sdk-types" : "@reliverse/dler-sdk"}";
|
|
313
|
+
${templateNames.map((name) => `import { ${name}, ${whitelabel}_TEMPLATES as ${name}_TEMPLATES, ${whitelabel}_TEMPLATE_NAMES as ${name}_TEMPLATE_NAMES, ${whitelabel.toLowerCase()}TemplatesMap as ${name.toLowerCase()}TemplatesMap } from "./${name}";`).join("\n")}
|
|
314
|
+
export const ${whitelabel}_TEMPLATES = {
|
|
315
|
+
${templateNames.map((name) => ` ...${name}_TEMPLATES,`).join("\n")}
|
|
316
|
+
} as const;
|
|
317
|
+
export type ${whitelabel}_TEMPLATE_NAMES = ${templateNames.map((name) => `${name}_TEMPLATE_NAMES`).join(" | ")};
|
|
318
|
+
export const ${whitelabel.toLowerCase()}TemplatesMap: Record<string, ${whitelabel}_TEMPLATE_NAMES> = {
|
|
319
|
+
${templateNames.map((name) => ` ...${name.toLowerCase()}TemplatesMap,`).join("\n")}
|
|
320
|
+
};`;
|
|
321
|
+
};
|
|
266
322
|
export default defineCommand({
|
|
267
323
|
meta: {
|
|
268
324
|
name: "merge",
|
|
@@ -270,6 +326,7 @@ export default defineCommand({
|
|
|
270
326
|
description: "Merge text files with optional commented path header/footer, skips binaries/media, built for CI & interactive use. Supports copy-like patterns and advanced options."
|
|
271
327
|
},
|
|
272
328
|
args: defineArgs({
|
|
329
|
+
/* ===== GENERAL ARGS ===== */
|
|
273
330
|
dev: { type: "boolean", description: "Generate template for development" },
|
|
274
331
|
s: { type: "array", description: "Input glob patterns" },
|
|
275
332
|
d: { type: "string", description: "Output file path or directory" },
|
|
@@ -357,36 +414,51 @@ export default defineCommand({
|
|
|
357
414
|
type: "boolean",
|
|
358
415
|
description: "Enable interactive mode with prompts (default: false)"
|
|
359
416
|
},
|
|
417
|
+
depth: {
|
|
418
|
+
type: "number",
|
|
419
|
+
description: "Depth level to start processing from (default: 0)",
|
|
420
|
+
default: 0
|
|
421
|
+
},
|
|
422
|
+
sourcemap: {
|
|
423
|
+
type: "boolean",
|
|
424
|
+
description: "Generate source map for the merged output"
|
|
425
|
+
},
|
|
426
|
+
/* ===== TEMPLATE GENERATION ARGS ===== */
|
|
360
427
|
"as-template": {
|
|
361
428
|
type: "boolean",
|
|
362
429
|
description: "Generate a TypeScript file with MOCK_TEMPLATES structure"
|
|
363
430
|
},
|
|
364
|
-
"
|
|
365
|
-
type: "string",
|
|
366
|
-
description: "Custom template name when using --as-template"
|
|
367
|
-
},
|
|
368
|
-
whitelabel: {
|
|
431
|
+
"template-whitelabel": {
|
|
369
432
|
type: "string",
|
|
370
433
|
description: "Custom prefix to use instead of 'DLER' in template generation",
|
|
371
|
-
default: "DLER"
|
|
372
|
-
|
|
373
|
-
sourcemap: {
|
|
374
|
-
type: "boolean",
|
|
375
|
-
description: "Generate source map for the merged output"
|
|
434
|
+
default: "DLER",
|
|
435
|
+
dependencies: ["as-template"]
|
|
376
436
|
},
|
|
377
|
-
"update
|
|
437
|
+
"template-update": {
|
|
378
438
|
type: "string",
|
|
379
439
|
description: "Update specific template in existing mock template file",
|
|
380
440
|
dependencies: ["as-template"]
|
|
441
|
+
},
|
|
442
|
+
"template-multi": {
|
|
443
|
+
type: "boolean",
|
|
444
|
+
description: "Create multiple templates based on directory structure (default: true)",
|
|
445
|
+
default: true,
|
|
446
|
+
dependencies: ["as-template"]
|
|
447
|
+
},
|
|
448
|
+
"template-per-file": {
|
|
449
|
+
type: "boolean",
|
|
450
|
+
description: "Create separate files for each template with an aggregator (default: false)",
|
|
451
|
+
default: false,
|
|
452
|
+
dependencies: ["as-template", "template-multi"]
|
|
381
453
|
}
|
|
382
454
|
}),
|
|
383
455
|
async run({ args }) {
|
|
384
|
-
const customTemplateName = args["custom-template-name"];
|
|
385
456
|
try {
|
|
386
457
|
const timer = createPerfTimer();
|
|
387
458
|
const interactive = args.interactive ?? false;
|
|
388
459
|
const isDev = args.dev ?? false;
|
|
389
|
-
const whitelabel = args
|
|
460
|
+
const whitelabel = args["template-whitelabel"] ?? "DLER";
|
|
461
|
+
const depth = args.depth ?? 0;
|
|
390
462
|
let include = args.s ?? [];
|
|
391
463
|
if (include.length === 0) {
|
|
392
464
|
const raw = await maybePrompt(
|
|
@@ -476,7 +548,7 @@ export default defineCommand({
|
|
|
476
548
|
const footer = args.footer;
|
|
477
549
|
const selectFiles = args["select-files"] ?? false;
|
|
478
550
|
const asTemplate = args["as-template"] ?? false;
|
|
479
|
-
let files = await collectFiles(include, ignore, recursive, sortBy);
|
|
551
|
+
let files = await collectFiles(include, ignore, recursive, sortBy, depth);
|
|
480
552
|
if (files.length === 0) {
|
|
481
553
|
throw new Error("No text files matched given patterns (binary/media files are skipped)");
|
|
482
554
|
}
|
|
@@ -493,11 +565,11 @@ export default defineCommand({
|
|
|
493
565
|
throw new Error("No files selected for merging");
|
|
494
566
|
}
|
|
495
567
|
}
|
|
496
|
-
if (args["update
|
|
568
|
+
if (args["template-update"]) {
|
|
497
569
|
if (!outFile) {
|
|
498
570
|
throw new Error("Output file path required for template update");
|
|
499
571
|
}
|
|
500
|
-
const templateName = args["update
|
|
572
|
+
const templateName = args["template-update"];
|
|
501
573
|
const templateData = {
|
|
502
574
|
name: templateName.replace(/_DLER_TEMPLATE$/, "").replace(/_/g, " ").toLowerCase(),
|
|
503
575
|
// Convert REACT_DLER_TEMPLATE to "react"
|
|
@@ -519,31 +591,35 @@ export default defineCommand({
|
|
|
519
591
|
if (ext === "json") {
|
|
520
592
|
const jsonContent = JSON.parse(fileContent);
|
|
521
593
|
if (fileName === "package.json") {
|
|
522
|
-
content =
|
|
523
|
-
|
|
524
|
-
|
|
594
|
+
content = jsonContent;
|
|
595
|
+
type = "json";
|
|
596
|
+
const magic = new MagicString(JSON.stringify(jsonContent, null, 2));
|
|
597
|
+
magic.append(" satisfies PackageJson");
|
|
598
|
+
content = magic.toString();
|
|
525
599
|
} else if (fileName === "tsconfig.json") {
|
|
526
|
-
content =
|
|
527
|
-
|
|
528
|
-
|
|
600
|
+
content = jsonContent;
|
|
601
|
+
type = "json";
|
|
602
|
+
const magic = new MagicString(JSON.stringify(jsonContent, null, 2));
|
|
603
|
+
magic.append(" satisfies TSConfig");
|
|
604
|
+
content = magic.toString();
|
|
529
605
|
} else {
|
|
530
606
|
content = jsonContent;
|
|
607
|
+
type = "json";
|
|
531
608
|
}
|
|
532
|
-
type = "json";
|
|
533
609
|
} else {
|
|
534
610
|
content = fileContent;
|
|
535
611
|
type = "text";
|
|
536
612
|
}
|
|
537
613
|
} catch (error) {
|
|
538
614
|
type = "binary";
|
|
539
|
-
if (asTemplate || args["update
|
|
615
|
+
if (asTemplate || args["template-update"]) {
|
|
540
616
|
relinka(
|
|
541
617
|
"warn",
|
|
542
618
|
`Skipped file "${relPath}" due to error: ${error instanceof Error ? error.message : "unknown error"}`
|
|
543
619
|
);
|
|
544
620
|
}
|
|
545
621
|
}
|
|
546
|
-
} else if (asTemplate || args["update
|
|
622
|
+
} else if (asTemplate || args["template-update"]) {
|
|
547
623
|
relinka("warn", `Skipped binary file "${relPath}"`);
|
|
548
624
|
}
|
|
549
625
|
templateData.config.files[relPath] = {
|
|
@@ -579,114 +655,215 @@ export default defineCommand({
|
|
|
579
655
|
pausedAt: null,
|
|
580
656
|
pausedDuration: 0
|
|
581
657
|
};
|
|
658
|
+
const templateMulti = args["template-multi"] ?? true;
|
|
659
|
+
const templatePerFile = args["template-per-file"] ?? false;
|
|
582
660
|
if (!outFile) {
|
|
583
|
-
outFile = "
|
|
661
|
+
outFile = templatePerFile ? "templates/index.ts" : "templates.ts";
|
|
584
662
|
} else if (!outFile.endsWith(".ts")) {
|
|
585
663
|
outFile = `${outFile}.ts`;
|
|
586
664
|
}
|
|
587
|
-
const
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
665
|
+
const baseDir = path.dirname(outFile);
|
|
666
|
+
if (templateMulti) {
|
|
667
|
+
const fileGroups = /* @__PURE__ */ new Map();
|
|
668
|
+
const templateDepth = depth;
|
|
669
|
+
for (const file of files) {
|
|
670
|
+
const relPath = path.relative(process.cwd(), file);
|
|
671
|
+
const parts = relPath.split(path.sep);
|
|
672
|
+
const groupKey = parts.slice(0, templateDepth + 1).join(path.sep);
|
|
673
|
+
if (!fileGroups.has(groupKey)) {
|
|
674
|
+
fileGroups.set(groupKey, []);
|
|
675
|
+
}
|
|
676
|
+
fileGroups.get(groupKey)?.push(file);
|
|
596
677
|
}
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
678
|
+
const templateNames = [];
|
|
679
|
+
for (const [groupKey, groupFiles] of fileGroups) {
|
|
680
|
+
const templateName = groupKey.split(path.sep).pop() || groupKey;
|
|
681
|
+
const templateConstName = templateName.replace(/[^a-zA-Z0-9]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "").replace(/[A-Z]/g, (letter) => `_${letter}`).replace(/^_/, "").toUpperCase() + `_${whitelabel}_TEMPLATE`;
|
|
682
|
+
const templateKey = templateName.replace(/[^a-zA-Z0-9]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "").toLowerCase();
|
|
683
|
+
const template = {
|
|
684
|
+
name: templateName.toLowerCase(),
|
|
685
|
+
description: `Template generated from ${groupFiles.length} files in ${groupKey}`,
|
|
686
|
+
config: {
|
|
687
|
+
files: {}
|
|
688
|
+
}
|
|
689
|
+
};
|
|
690
|
+
for (const file of groupFiles) {
|
|
691
|
+
const relPath = path.relative(process.cwd(), file);
|
|
692
|
+
const ext = path.extname(file).slice(1).toLowerCase();
|
|
693
|
+
const isBinary = await isBinaryExt(file);
|
|
694
|
+
const fileName = path.basename(file).toLowerCase();
|
|
695
|
+
let content = "";
|
|
696
|
+
let type = "binary";
|
|
697
|
+
if (!isBinary) {
|
|
698
|
+
try {
|
|
699
|
+
const fileContent = await fs.readFile(file, "utf8");
|
|
700
|
+
if (ext === "json") {
|
|
701
|
+
const jsonContent = JSON.parse(fileContent);
|
|
702
|
+
if (fileName === "package.json") {
|
|
703
|
+
content = jsonContent;
|
|
704
|
+
type = "json";
|
|
705
|
+
const magic = new MagicString(JSON.stringify(jsonContent, null, 2));
|
|
706
|
+
magic.append(" satisfies PackageJson");
|
|
707
|
+
content = magic.toString();
|
|
708
|
+
} else if (fileName === "tsconfig.json") {
|
|
709
|
+
content = jsonContent;
|
|
710
|
+
type = "json";
|
|
711
|
+
const magic = new MagicString(JSON.stringify(jsonContent, null, 2));
|
|
712
|
+
magic.append(" satisfies TSConfig");
|
|
713
|
+
content = magic.toString();
|
|
714
|
+
} else {
|
|
715
|
+
content = jsonContent;
|
|
716
|
+
type = "json";
|
|
717
|
+
}
|
|
718
|
+
} else {
|
|
719
|
+
content = fileContent;
|
|
720
|
+
type = "text";
|
|
721
|
+
}
|
|
722
|
+
} catch (error) {
|
|
723
|
+
type = "binary";
|
|
724
|
+
if (asTemplate || args["template-update"]) {
|
|
725
|
+
relinka(
|
|
726
|
+
"warn",
|
|
727
|
+
`Skipped file "${relPath}" due to error: ${error instanceof Error ? error.message : "unknown error"}`
|
|
728
|
+
);
|
|
729
|
+
}
|
|
620
730
|
}
|
|
621
|
-
|
|
731
|
+
} else if (asTemplate || args["template-update"]) {
|
|
732
|
+
relinka("warn", `Skipped binary file "${relPath}"`);
|
|
733
|
+
}
|
|
734
|
+
template.config.files[relPath] = {
|
|
735
|
+
content,
|
|
736
|
+
type
|
|
737
|
+
};
|
|
738
|
+
}
|
|
739
|
+
const templateContent = generateTemplateContent(
|
|
740
|
+
template,
|
|
741
|
+
templateConstName,
|
|
742
|
+
templateKey,
|
|
743
|
+
whitelabel,
|
|
744
|
+
isDev
|
|
745
|
+
);
|
|
746
|
+
if (templatePerFile) {
|
|
747
|
+
const templateFileName = `${templateKey}.ts`;
|
|
748
|
+
const templateFilePath = path.join(baseDir, templateFileName);
|
|
749
|
+
if (dryRun) {
|
|
750
|
+
relinka("verbose", `[DRY RUN] Would write template file: ${templateFilePath}`);
|
|
622
751
|
} else {
|
|
623
|
-
|
|
624
|
-
|
|
752
|
+
await fs.ensureDir(path.dirname(templateFilePath));
|
|
753
|
+
if (backup && await fs.pathExists(templateFilePath)) {
|
|
754
|
+
const backupPath = `${templateFilePath}.${Date.now()}.bak`;
|
|
755
|
+
await fs.copyFile(templateFilePath, backupPath);
|
|
756
|
+
}
|
|
757
|
+
await fs.writeFile(templateFilePath, templateContent, "utf8");
|
|
625
758
|
}
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
if (
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
759
|
+
templateNames.push(templateKey);
|
|
760
|
+
} else {
|
|
761
|
+
if (!dryRun) {
|
|
762
|
+
await fs.ensureDir(path.dirname(outFile));
|
|
763
|
+
if (backup && await fs.pathExists(outFile)) {
|
|
764
|
+
const backupPath = `${outFile}.${Date.now()}.bak`;
|
|
765
|
+
await fs.copyFile(outFile, backupPath);
|
|
766
|
+
}
|
|
767
|
+
await fs.appendFile(outFile, templateContent + "\n\n", "utf8");
|
|
633
768
|
}
|
|
769
|
+
templateNames.push(templateKey);
|
|
634
770
|
}
|
|
635
|
-
} else if (asTemplate || args["update-template"]) {
|
|
636
|
-
relinka("warn", `Skipped binary file "${relPath}"`);
|
|
637
771
|
}
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
772
|
+
if (templatePerFile) {
|
|
773
|
+
const aggregatorContent = generateAggregatorContent(templateNames, whitelabel, isDev);
|
|
774
|
+
if (dryRun) {
|
|
775
|
+
relinka("verbose", `[DRY RUN] Would write aggregator file: ${outFile}`);
|
|
776
|
+
} else {
|
|
777
|
+
await fs.ensureDir(path.dirname(outFile));
|
|
778
|
+
if (backup && await fs.pathExists(outFile)) {
|
|
779
|
+
const backupPath = `${outFile}.${Date.now()}.bak`;
|
|
780
|
+
await fs.copyFile(outFile, backupPath);
|
|
781
|
+
}
|
|
782
|
+
await fs.writeFile(outFile, aggregatorContent, "utf8");
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
} else {
|
|
786
|
+
const templateName = path.basename(outFile, ".ts");
|
|
787
|
+
const templateConstName = templateName.replace(/[^a-zA-Z0-9]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "").replace(/[A-Z]/g, (letter) => `_${letter}`).replace(/^_/, "").toUpperCase() + `_${whitelabel}_TEMPLATE`;
|
|
788
|
+
const templateKey = templateName.replace(/[^a-zA-Z0-9]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "").toLowerCase();
|
|
789
|
+
const template = {
|
|
790
|
+
name: templateName.toLowerCase(),
|
|
791
|
+
description: `Template generated from ${files.length} files`,
|
|
792
|
+
config: {
|
|
793
|
+
files: {}
|
|
794
|
+
}
|
|
641
795
|
};
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
796
|
+
for (const file of files) {
|
|
797
|
+
const relPath = path.relative(process.cwd(), file);
|
|
798
|
+
const ext = path.extname(file).slice(1).toLowerCase();
|
|
799
|
+
const isBinary = await isBinaryExt(file);
|
|
800
|
+
const fileName = path.basename(file).toLowerCase();
|
|
801
|
+
let content = "";
|
|
802
|
+
let type = "binary";
|
|
803
|
+
if (!isBinary) {
|
|
804
|
+
try {
|
|
805
|
+
const fileContent = await fs.readFile(file, "utf8");
|
|
806
|
+
if (ext === "json") {
|
|
807
|
+
const jsonContent = JSON.parse(fileContent);
|
|
808
|
+
if (fileName === "package.json") {
|
|
809
|
+
content = jsonContent;
|
|
810
|
+
type = "json";
|
|
811
|
+
const magic = new MagicString(JSON.stringify(jsonContent, null, 2));
|
|
812
|
+
magic.append(" satisfies PackageJson");
|
|
813
|
+
content = magic.toString();
|
|
814
|
+
} else if (fileName === "tsconfig.json") {
|
|
815
|
+
content = jsonContent;
|
|
816
|
+
type = "json";
|
|
817
|
+
const magic = new MagicString(JSON.stringify(jsonContent, null, 2));
|
|
818
|
+
magic.append(" satisfies TSConfig");
|
|
819
|
+
content = magic.toString();
|
|
820
|
+
} else {
|
|
821
|
+
content = jsonContent;
|
|
822
|
+
type = "json";
|
|
823
|
+
}
|
|
824
|
+
} else {
|
|
825
|
+
content = fileContent;
|
|
826
|
+
type = "text";
|
|
827
|
+
}
|
|
828
|
+
} catch (error) {
|
|
829
|
+
type = "binary";
|
|
830
|
+
if (asTemplate || args["template-update"]) {
|
|
831
|
+
relinka(
|
|
832
|
+
"warn",
|
|
833
|
+
`Skipped file "${relPath}" due to error: ${error instanceof Error ? error.message : "unknown error"}`
|
|
834
|
+
);
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
} else if (asTemplate || args["template-update"]) {
|
|
838
|
+
relinka("warn", `Skipped binary file "${relPath}"`);
|
|
839
|
+
}
|
|
840
|
+
template.config.files[relPath] = {
|
|
841
|
+
content,
|
|
842
|
+
type
|
|
843
|
+
};
|
|
844
|
+
}
|
|
845
|
+
const templateContent = generateTemplateContent(
|
|
846
|
+
template,
|
|
847
|
+
templateConstName,
|
|
848
|
+
templateKey,
|
|
849
|
+
whitelabel,
|
|
850
|
+
isDev
|
|
652
851
|
);
|
|
653
|
-
if (
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
`;
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
return /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(key) ? `${key}:` : `"${key}":`;
|
|
664
|
-
}).replace(/"([^"]+)":/g, (_, key) => {
|
|
665
|
-
return /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(key) ? `${key}:` : `"${key}":`;
|
|
666
|
-
})};
|
|
667
|
-
export const ${whitelabel}_TEMPLATES = {
|
|
668
|
-
${templateKey}: ${templateConstName},
|
|
669
|
-
} as const;
|
|
670
|
-
export type ${whitelabel}_TEMPLATE_NAMES = keyof typeof ${whitelabel}_TEMPLATES;
|
|
671
|
-
export const ${whitelabel.toLowerCase()}TemplatesMap: Record<string, ${whitelabel}_TEMPLATE_NAMES> = {
|
|
672
|
-
${templateConstName}: "${templateKey}",
|
|
673
|
-
};
|
|
674
|
-
`;
|
|
675
|
-
if (dryRun) {
|
|
676
|
-
relinka("verbose", `[DRY RUN] Would write template file: ${outFile}`);
|
|
677
|
-
return;
|
|
678
|
-
}
|
|
679
|
-
const dir = path.dirname(outFile);
|
|
680
|
-
if (dir && dir !== ".") await fs.ensureDir(dir);
|
|
681
|
-
if (backup && await fs.pathExists(outFile)) {
|
|
682
|
-
const backupPath = `${outFile}.${Date.now()}.bak`;
|
|
683
|
-
await fs.copyFile(outFile, backupPath);
|
|
852
|
+
if (dryRun) {
|
|
853
|
+
relinka("verbose", `[DRY RUN] Would write template file: ${outFile}`);
|
|
854
|
+
} else {
|
|
855
|
+
await fs.ensureDir(path.dirname(outFile));
|
|
856
|
+
if (backup && await fs.pathExists(outFile)) {
|
|
857
|
+
const backupPath = `${outFile}.${Date.now()}.bak`;
|
|
858
|
+
await fs.copyFile(outFile, backupPath);
|
|
859
|
+
}
|
|
860
|
+
await fs.writeFile(outFile, templateContent, "utf8");
|
|
861
|
+
}
|
|
684
862
|
}
|
|
685
|
-
await fs.writeFile(outFile, tsContent, "utf8");
|
|
686
863
|
const elapsed2 = getElapsedPerfTime(timer2);
|
|
687
864
|
relinka(
|
|
688
865
|
"success",
|
|
689
|
-
`Successfully ${dryRun ? "would generate" : "generated"} template file
|
|
866
|
+
`Successfully ${dryRun ? "would generate" : "generated"} template file(s) (in ${prettyMilliseconds(elapsed2)})`
|
|
690
867
|
);
|
|
691
868
|
return;
|
|
692
869
|
}
|
|
@@ -8,6 +8,7 @@ export async function library_publishLibrary(effectivePubRegistry, libName, npmO
|
|
|
8
8
|
switch (effectivePubRegistry) {
|
|
9
9
|
case "jsr":
|
|
10
10
|
relinka("log", `Publishing lib ${libName} to JSR only...`);
|
|
11
|
+
relinka("null", "");
|
|
11
12
|
await library_pubToJsr(
|
|
12
13
|
jsrOutDir,
|
|
13
14
|
distJsrDryRun,
|
|
@@ -21,10 +22,12 @@ export async function library_publishLibrary(effectivePubRegistry, libName, npmO
|
|
|
21
22
|
break;
|
|
22
23
|
case "npm":
|
|
23
24
|
relinka("log", `Publishing lib ${libName} to NPM only...`);
|
|
25
|
+
relinka("null", "");
|
|
24
26
|
await library_pubToNpm(npmOutDir, distJsrDryRun, distJsrFailOnWarn, libName, isDev, timer);
|
|
25
27
|
break;
|
|
26
28
|
case "npm-jsr": {
|
|
27
29
|
relinka("log", `Publishing lib ${libName} to both NPM and JSR...`);
|
|
30
|
+
relinka("null", "");
|
|
28
31
|
const publishTasks = [
|
|
29
32
|
() => library_pubToNpm(npmOutDir, distJsrDryRun, distJsrFailOnWarn, libName, isDev, timer),
|
|
30
33
|
() => library_pubToJsr(
|
|
@@ -54,6 +57,7 @@ async function library_pubToJsr(libOutDir, distJsrDryRun, distJsrFailOnWarn, dis
|
|
|
54
57
|
if (timer) pausePerfTimer(timer);
|
|
55
58
|
await withWorkingDirectory(libOutDir, async () => {
|
|
56
59
|
relinka("log", `Publishing lib ${libName} to JSR from ${libOutDir}`);
|
|
60
|
+
relinka("null", "");
|
|
57
61
|
const command = [
|
|
58
62
|
"bun x jsr publish",
|
|
59
63
|
distJsrDryRun ? "--dry-run" : "",
|
|
@@ -62,8 +66,9 @@ async function library_pubToJsr(libOutDir, distJsrDryRun, distJsrFailOnWarn, dis
|
|
|
62
66
|
distJsrSlowTypes ? "--allow-slow-types" : ""
|
|
63
67
|
].filter(Boolean).join(" ");
|
|
64
68
|
await execaCommand(command, { stdio: "inherit" });
|
|
69
|
+
relinka("null", "");
|
|
65
70
|
relinka(
|
|
66
|
-
"
|
|
71
|
+
"log",
|
|
67
72
|
`Successfully ${distJsrDryRun ? "validated" : "published"} lib ${libName} to JSR registry`
|
|
68
73
|
);
|
|
69
74
|
});
|
|
@@ -79,10 +84,12 @@ async function library_pubToNpm(libOutDir, distJsrDryRun, _distJsrFailOnWarn, li
|
|
|
79
84
|
if (timer) pausePerfTimer(timer);
|
|
80
85
|
await withWorkingDirectory(libOutDir, async () => {
|
|
81
86
|
relinka("log", `Publishing lib ${libName} to NPM from ${libOutDir}`);
|
|
87
|
+
relinka("null", "");
|
|
82
88
|
const command = ["bun publish", distJsrDryRun ? "--dry-run" : ""].filter(Boolean).join(" ");
|
|
83
89
|
await execaCommand(command, { stdio: "inherit" });
|
|
90
|
+
relinka("null", "");
|
|
84
91
|
relinka(
|
|
85
|
-
"
|
|
92
|
+
"log",
|
|
86
93
|
`Successfully ${distJsrDryRun ? "validated" : "published"} lib ${libName} to NPM registry`
|
|
87
94
|
);
|
|
88
95
|
});
|
|
@@ -90,7 +97,5 @@ async function library_pubToNpm(libOutDir, distJsrDryRun, _distJsrFailOnWarn, li
|
|
|
90
97
|
} catch (error) {
|
|
91
98
|
if (timer) resumePerfTimer(timer);
|
|
92
99
|
throw error;
|
|
93
|
-
} finally {
|
|
94
|
-
relinka("verbose", `Exiting library_pubToNpm for lib: ${libName}`);
|
|
95
100
|
}
|
|
96
101
|
}
|
|
@@ -20,10 +20,8 @@ export async function regular_pubToJsr(distJsrDryRun, distJsrFailOnWarn, _isDev,
|
|
|
20
20
|
].filter(Boolean).join(" ");
|
|
21
21
|
relinka("verbose", `Running publish command: ${command}`);
|
|
22
22
|
await execaCommand(command, { stdio: "inherit" });
|
|
23
|
-
relinka(
|
|
24
|
-
|
|
25
|
-
`Successfully ${distJsrDryRun ? "validated" : "published"} to JSR registry`
|
|
26
|
-
);
|
|
23
|
+
relinka("null", "");
|
|
24
|
+
relinka("log", `Successfully ${distJsrDryRun ? "validated" : "published"} to JSR registry`);
|
|
27
25
|
});
|
|
28
26
|
if (timer) resumePerfTimer(timer);
|
|
29
27
|
}
|
|
@@ -42,10 +40,8 @@ export async function regular_pubToNpm(distJsrDryRun, _isDev, commonPubPause, di
|
|
|
42
40
|
const command = ["bun publish", distJsrDryRun ? "--dry-run" : ""].filter(Boolean).join(" ");
|
|
43
41
|
relinka("verbose", `Running publish command: ${command}`);
|
|
44
42
|
await execaCommand(command, { stdio: "inherit" });
|
|
45
|
-
relinka(
|
|
46
|
-
|
|
47
|
-
`Successfully ${distJsrDryRun ? "validated" : "published"} to NPM registry`
|
|
48
|
-
);
|
|
43
|
+
relinka("null", "");
|
|
44
|
+
relinka("log", `Successfully ${distJsrDryRun ? "validated" : "published"} to NPM registry`);
|
|
49
45
|
});
|
|
50
46
|
if (timer) resumePerfTimer(timer);
|
|
51
47
|
}
|
|
@@ -20,7 +20,7 @@ export async function withWorkingDirectory(transpileTargetDir, fn) {
|
|
|
20
20
|
const originalDir = process.cwd();
|
|
21
21
|
try {
|
|
22
22
|
process.chdir(transpileTargetDir);
|
|
23
|
-
relinka("
|
|
23
|
+
relinka("log", `CWD (current working directory): ${originalDir} -> ${transpileTargetDir}`);
|
|
24
24
|
const result = await fn();
|
|
25
25
|
return result;
|
|
26
26
|
} catch (error) {
|
|
@@ -29,7 +29,7 @@ export async function withWorkingDirectory(transpileTargetDir, fn) {
|
|
|
29
29
|
throw error;
|
|
30
30
|
} finally {
|
|
31
31
|
process.chdir(originalDir);
|
|
32
|
-
relinka("
|
|
32
|
+
relinka("log", `CWD (current working directory): ${transpileTargetDir} -> ${originalDir}`);
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
export async function validateDevCwd(isDev, paths, cliName, cliOrg = "") {
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"@reliverse/relico": "^1.1.2",
|
|
7
7
|
"@reliverse/relifso": "^1.4.5",
|
|
8
8
|
"@reliverse/relinka": "^1.4.7",
|
|
9
|
-
"@reliverse/rempts": "^1.7.
|
|
9
|
+
"@reliverse/rempts": "^1.7.19",
|
|
10
10
|
"@rollup/plugin-alias": "^5.1.1",
|
|
11
11
|
"@rollup/plugin-commonjs": "^28.0.3",
|
|
12
12
|
"@rollup/plugin-json": "^6.1.0",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"license": "MIT",
|
|
45
45
|
"name": "@reliverse/dler",
|
|
46
46
|
"type": "module",
|
|
47
|
-
"version": "1.7.
|
|
47
|
+
"version": "1.7.16",
|
|
48
48
|
"keywords": [
|
|
49
49
|
"reliverse",
|
|
50
50
|
"cli",
|
package/bin/templates/App.css
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
#root {
|
|
2
|
-
max-width: 1280px;
|
|
3
|
-
margin: 0 auto;
|
|
4
|
-
padding: 2rem;
|
|
5
|
-
text-align: center;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
.card {
|
|
9
|
-
padding: 2em;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
button {
|
|
13
|
-
border-radius: 8px;
|
|
14
|
-
border: 1px solid transparent;
|
|
15
|
-
padding: 0.6em 1.2em;
|
|
16
|
-
font-size: 1em;
|
|
17
|
-
font-weight: 500;
|
|
18
|
-
font-family: inherit;
|
|
19
|
-
background-color: #1a1a1a;
|
|
20
|
-
cursor: pointer;
|
|
21
|
-
transition: border-color 0.25s;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
button:hover {
|
|
25
|
-
border-color: #646cff;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
button:focus,
|
|
29
|
-
button:focus-visible {
|
|
30
|
-
outline: 4px auto -webkit-focus-ring-color;
|
|
31
|
-
}
|
package/bin/templates/App.tsx
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { useState } from "react";
|
|
2
|
-
import "./App.css";
|
|
3
|
-
|
|
4
|
-
function App() {
|
|
5
|
-
const [count, setCount] = useState(0);
|
|
6
|
-
|
|
7
|
-
return (
|
|
8
|
-
// @ts-expect-error mock
|
|
9
|
-
<div className="App">
|
|
10
|
-
{/* @ts-expect-error mock */}
|
|
11
|
-
<h1>React TSX App</h1>
|
|
12
|
-
{/* @ts-expect-error mock */}
|
|
13
|
-
<div className="card">
|
|
14
|
-
{/* @ts-expect-error mock */}
|
|
15
|
-
<button onClick={() => setCount((count: number) => count + 1)}>count is {count}</button>
|
|
16
|
-
</div>
|
|
17
|
-
</div>
|
|
18
|
-
);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export default App;
|
package/bin/templates/DOCS.md
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
# React TSX Project
|
|
2
|
-
|
|
3
|
-
A modern React project with TypeScript and Vite.
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- React 19 with TypeScript
|
|
8
|
-
- Vite for fast development and building
|
|
9
|
-
- Modern CSS with CSS modules support
|
|
10
|
-
- Hot Module Replacement (HMR)
|
|
11
|
-
- ESLint and Prettier configuration
|
|
12
|
-
|
|
13
|
-
## Getting Started
|
|
14
|
-
|
|
15
|
-
1. Install dependencies:
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
npm install
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
2. Start development server:
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
npm run dev
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
3. Build for production:
|
|
28
|
-
|
|
29
|
-
```bash
|
|
30
|
-
npm run build
|
|
31
|
-
```
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
:root {
|
|
2
|
-
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
|
3
|
-
line-height: 1.5;
|
|
4
|
-
font-weight: 400;
|
|
5
|
-
|
|
6
|
-
color-scheme: light dark;
|
|
7
|
-
color: rgba(255, 255, 255, 0.87);
|
|
8
|
-
background-color: #242424;
|
|
9
|
-
|
|
10
|
-
font-synthesis: none;
|
|
11
|
-
text-rendering: optimizeLegibility;
|
|
12
|
-
-webkit-font-smoothing: antialiased;
|
|
13
|
-
-moz-osx-font-smoothing: grayscale;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
body {
|
|
17
|
-
margin: 0;
|
|
18
|
-
display: flex;
|
|
19
|
-
place-items: center;
|
|
20
|
-
min-width: 320px;
|
|
21
|
-
min-height: 100vh;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
h1 {
|
|
25
|
-
font-size: 3.2em;
|
|
26
|
-
line-height: 1.1;
|
|
27
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
console.log("Hello, world!");
|
package/bin/templates/index.html
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<title>React TSX App</title>
|
|
7
|
-
</head>
|
|
8
|
-
<body>
|
|
9
|
-
<div id="root"></div>
|
|
10
|
-
<script type="module" src="/src/main.tsx"></script>
|
|
11
|
-
</body>
|
|
12
|
-
</html>
|
package/bin/templates/main.tsx
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
// @ts-expect-error mock
|
|
3
|
-
import ReactDOM from "react-dom/client";
|
|
4
|
-
import App from "./App";
|
|
5
|
-
import "./index.css";
|
|
6
|
-
|
|
7
|
-
ReactDOM.createRoot(document.getElementById("root")!).render(
|
|
8
|
-
<React.StrictMode>
|
|
9
|
-
<App />
|
|
10
|
-
</React.StrictMode>,
|
|
11
|
-
);
|