create-web-kit 25.728.953 → 25.728.1414
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 +1 -1
- package/dist/config/frameworks.js +2 -7
- package/dist/generators/electron-vue.js +8 -1
- package/dist/generators/nextjs-csr.js +20 -16
- package/dist/generators/nextjs-ssr.js +9 -1
- package/dist/generators/template.js +44 -1
- package/dist/generators/vue3.js +8 -1
- package/dist/index.js +174 -1
- package/dist/types/index.js +1 -1
- package/dist/utils/file.js +62 -1
- package/dist/utils/package-manager.js +94 -1
- package/dist/utils/template.js +41 -1
- package/package.json +4 -10
- package/dist/assets/html/ie.html +0 -256
- package/dist/templates/electron-react/eslint.config.js +0 -1
- package/dist/templates/electron-vue/eslint.config.js +0 -1
- package/dist/templates/nextjs-csr/build-info.tsx +0 -20
- package/dist/templates/nextjs-csr/devcontainer.json +0 -32
- package/dist/templates/nextjs-csr/eslint.config.js +0 -1
- package/dist/templates/nextjs-csr/layout.tsx +0 -46
- package/dist/templates/nextjs-csr/next.config.js +0 -1
- package/dist/templates/nextjs-csr/not-found.tsx +0 -16
- package/dist/templates/nextjs-csr/prettier.config.json +0 -21
- package/dist/templates/nextjs-csr/query-provider.tsx +0 -45
- package/dist/templates/nextjs-csr/request.ts +0 -204
- package/dist/templates/nextjs-csr/show.tsx +0 -12
- package/dist/templates/nextjs-csr/theme-provider.tsx +0 -17
- package/dist/templates/vue3/vite.config.ts +0 -12
package/README.md
CHANGED
|
@@ -32,15 +32,10 @@ export const FRAMEWORKS = [
|
|
|
32
32
|
workingDir: "target",
|
|
33
33
|
},
|
|
34
34
|
{
|
|
35
|
-
command: "pnpm add date-fns",
|
|
35
|
+
command: "pnpm add date-fns next-themes motion",
|
|
36
36
|
description: "Installing date-fns for date utilities",
|
|
37
37
|
workingDir: "target",
|
|
38
38
|
},
|
|
39
|
-
{
|
|
40
|
-
command: "pnpm add next-themes",
|
|
41
|
-
description: "Installing next-themes for theme support",
|
|
42
|
-
workingDir: "target",
|
|
43
|
-
},
|
|
44
39
|
{
|
|
45
40
|
command: "pnpm dlx shadcn@latest add --all",
|
|
46
41
|
description: "Installing all shadcnui components",
|
|
@@ -64,7 +59,7 @@ export const FRAMEWORKS = [
|
|
|
64
59
|
workingDir: "target",
|
|
65
60
|
},
|
|
66
61
|
{
|
|
67
|
-
command: "pnpm add @tanstack/react-query next-auth prisma",
|
|
62
|
+
command: "pnpm add @tanstack/react-query next-auth prisma motion",
|
|
68
63
|
description: "Installing SSR dependencies",
|
|
69
64
|
workingDir: "target",
|
|
70
65
|
},
|
|
@@ -1 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
import { copyTemplateFiles } from "../utils/template.js";
|
|
2
|
+
const TEMPLATE_NAME = "electron-vue";
|
|
3
|
+
const TEMPLATE_FILES = [
|
|
4
|
+
{ source: "eslint.config.js", destination: ".eslintrc.js" },
|
|
5
|
+
];
|
|
6
|
+
export function createElectronVueFiles(root) {
|
|
7
|
+
copyTemplateFiles(TEMPLATE_NAME, TEMPLATE_FILES, root);
|
|
8
|
+
}
|
|
@@ -5,34 +5,38 @@ const TEMPLATE_NAME = "nextjs-csr";
|
|
|
5
5
|
const TEMPLATE_FILES = [
|
|
6
6
|
// Config files
|
|
7
7
|
{ source: "prettier.config.json", destination: ".prettierrc", isJson: true },
|
|
8
|
-
{ source: "eslint.config.
|
|
9
|
-
{ source: "next.config.
|
|
10
|
-
// Environment files
|
|
11
|
-
{ source: ".env", destination: ".env.development" },
|
|
12
|
-
{ source: ".env", destination: ".env.production" },
|
|
13
|
-
{ source: ".env", destination: ".env.test" },
|
|
8
|
+
{ source: "eslint.config.mjs", destination: "eslint.config.mjs" },
|
|
9
|
+
{ source: "next.config.ts", destination: "next.config.ts" },
|
|
14
10
|
// DevContainer
|
|
15
11
|
{
|
|
16
|
-
source: "devcontainer.json",
|
|
12
|
+
source: ".devcontainer/devcontainer.json",
|
|
17
13
|
destination: ".devcontainer/devcontainer.json",
|
|
18
14
|
isJson: true,
|
|
19
15
|
},
|
|
20
16
|
// App files
|
|
21
|
-
{ source: "layout.tsx", destination: "src/app/layout.tsx" },
|
|
22
|
-
{ source: "not-found.tsx", destination: "src/app/not-found.tsx" },
|
|
17
|
+
{ source: "src/app/layout.tsx", destination: "src/app/layout.tsx" },
|
|
18
|
+
{ source: "src/app/not-found.tsx", destination: "src/app/not-found.tsx" },
|
|
19
|
+
{ source: "src/app/error.tsx", destination: "src/app/error.tsx" },
|
|
23
20
|
// Components
|
|
24
|
-
{ source: "show.tsx", destination: "src/components/show.tsx" },
|
|
25
|
-
{ source: "build-info.tsx", destination: "src/components/build-info.tsx" },
|
|
21
|
+
{ source: "src/components/show.tsx", destination: "src/components/show.tsx" },
|
|
26
22
|
{
|
|
27
|
-
source: "
|
|
28
|
-
destination: "src/components/
|
|
23
|
+
source: "src/components/build-info.tsx",
|
|
24
|
+
destination: "src/components/build-info.tsx",
|
|
29
25
|
},
|
|
30
26
|
{
|
|
31
|
-
source: "
|
|
32
|
-
destination: "src/components/providers/
|
|
27
|
+
source: "src/components/providers/theme.tsx",
|
|
28
|
+
destination: "src/components/providers/theme.tsx",
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
source: "src/components/providers/query.tsx",
|
|
32
|
+
destination: "src/components/providers/query.tsx",
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
source: "src/components/providers/index.tsx",
|
|
36
|
+
destination: "src/components/providers/index.tsx",
|
|
33
37
|
},
|
|
34
38
|
// Utils
|
|
35
|
-
{ source: "request.ts", destination: "src/
|
|
39
|
+
{ source: "src/lib/request.ts", destination: "src/lib/request.ts" },
|
|
36
40
|
];
|
|
37
41
|
export function createNextjsCSRFiles(root) {
|
|
38
42
|
// Copy all template files
|
|
@@ -1 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import { copyTemplateFiles } from "../utils/template.js";
|
|
2
|
+
const TEMPLATE_NAME = "nextjs-ssr";
|
|
3
|
+
const TEMPLATE_FILES = [
|
|
4
|
+
{ source: ".env.local", destination: ".env.local" },
|
|
5
|
+
{ source: ".env.local", destination: ".env.example" },
|
|
6
|
+
];
|
|
7
|
+
export function createNextjsSSRFiles(root) {
|
|
8
|
+
copyTemplateFiles(TEMPLATE_NAME, TEMPLATE_FILES, root);
|
|
9
|
+
}
|
|
@@ -1 +1,44 @@
|
|
|
1
|
-
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import * as prompts from "@clack/prompts";
|
|
5
|
+
import { copy } from "../utils/file.js";
|
|
6
|
+
import { renameFiles } from "../config/frameworks.js";
|
|
7
|
+
export function generateTemplateProject(template, root, packageName, pkgManager, cwd) {
|
|
8
|
+
fs.mkdirSync(root, { recursive: true });
|
|
9
|
+
prompts.log.step(`Scaffolding project in ${root}...`);
|
|
10
|
+
const templateDir = path.resolve(fileURLToPath(import.meta.url), "../../..", `template-${template}`);
|
|
11
|
+
const write = (file, content) => {
|
|
12
|
+
const targetPath = path.join(root, renameFiles[file] ?? file);
|
|
13
|
+
if (content) {
|
|
14
|
+
fs.writeFileSync(targetPath, content);
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
copy(path.join(templateDir, file), targetPath);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
const files = fs.readdirSync(templateDir);
|
|
21
|
+
for (const file of files.filter((f) => f !== "package.json")) {
|
|
22
|
+
write(file);
|
|
23
|
+
}
|
|
24
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(templateDir, `package.json`), "utf-8"));
|
|
25
|
+
pkg.name = packageName;
|
|
26
|
+
write("package.json", JSON.stringify(pkg, null, 2) + "\n");
|
|
27
|
+
let doneMessage = "";
|
|
28
|
+
const cdProjectName = path.relative(cwd, root);
|
|
29
|
+
doneMessage += `Done. Now run:\n`;
|
|
30
|
+
if (root !== cwd) {
|
|
31
|
+
doneMessage += `\n cd ${cdProjectName.includes(" ") ? `"${cdProjectName}"` : cdProjectName}`;
|
|
32
|
+
}
|
|
33
|
+
switch (pkgManager) {
|
|
34
|
+
case "yarn":
|
|
35
|
+
doneMessage += "\n yarn";
|
|
36
|
+
doneMessage += "\n yarn dev";
|
|
37
|
+
break;
|
|
38
|
+
default:
|
|
39
|
+
doneMessage += `\n ${pkgManager} install`;
|
|
40
|
+
doneMessage += `\n ${pkgManager} run dev`;
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
prompts.outro(doneMessage);
|
|
44
|
+
}
|
package/dist/generators/vue3.js
CHANGED
|
@@ -1 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
import { copyTemplateFiles } from "../utils/template.js";
|
|
2
|
+
const TEMPLATE_NAME = "vue3";
|
|
3
|
+
const TEMPLATE_FILES = [
|
|
4
|
+
{ source: "vite.config.ts", destination: "vite.config.ts" },
|
|
5
|
+
];
|
|
6
|
+
export function createVue3Files(root) {
|
|
7
|
+
copyTemplateFiles(TEMPLATE_NAME, TEMPLATE_FILES, root);
|
|
8
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,175 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import spawn from "cross-spawn";
|
|
5
|
+
import mri from "mri";
|
|
6
|
+
import * as prompts from "@clack/prompts";
|
|
7
|
+
import colors from "picocolors";
|
|
8
|
+
// Import configurations
|
|
9
|
+
import { helpMessage } from "./config/help.js";
|
|
10
|
+
import { FRAMEWORKS, TEMPLATES, defaultTargetDir, } from "./config/frameworks.js";
|
|
11
|
+
// Import utilities
|
|
12
|
+
import { formatTargetDir, isValidPackageName, toValidPackageName, isEmpty, emptyDir, pkgFromUserAgent, } from "./utils/file.js";
|
|
13
|
+
import { getFullCustomCommand } from "./utils/package-manager.js";
|
|
14
|
+
// Import generators
|
|
15
|
+
import { executeMultiStepCommands, createProjectFiles, generateSuccessMessage, } from "./generators/project.js";
|
|
16
|
+
import { generateTemplateProject } from "./generators/template.js";
|
|
17
|
+
const argv = mri(process.argv.slice(2), {
|
|
18
|
+
alias: { h: "help", t: "template" },
|
|
19
|
+
boolean: ["help", "overwrite"],
|
|
20
|
+
string: ["template"],
|
|
21
|
+
});
|
|
22
|
+
const cwd = process.cwd();
|
|
23
|
+
async function init() {
|
|
24
|
+
const argTargetDir = argv._[0]
|
|
25
|
+
? formatTargetDir(String(argv._[0]))
|
|
26
|
+
: undefined;
|
|
27
|
+
const argTemplate = argv.template;
|
|
28
|
+
const argOverwrite = argv.overwrite;
|
|
29
|
+
const help = argv.help;
|
|
30
|
+
if (help) {
|
|
31
|
+
console.log(helpMessage);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const pkgInfo = pkgFromUserAgent(process.env.npm_config_user_agent);
|
|
35
|
+
const cancel = () => prompts.cancel("Operation cancelled");
|
|
36
|
+
prompts.intro(colors.bgCyan(colors.black(" create-web ")));
|
|
37
|
+
// 1. Get project name and target dir
|
|
38
|
+
let targetDir = argTargetDir;
|
|
39
|
+
if (!targetDir) {
|
|
40
|
+
const projectName = await prompts.text({
|
|
41
|
+
message: "Project name:",
|
|
42
|
+
defaultValue: defaultTargetDir,
|
|
43
|
+
placeholder: defaultTargetDir,
|
|
44
|
+
validate: (value) => {
|
|
45
|
+
return value.length === 0 || formatTargetDir(value).length > 0
|
|
46
|
+
? undefined
|
|
47
|
+
: "Invalid project name";
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
if (prompts.isCancel(projectName))
|
|
51
|
+
return cancel();
|
|
52
|
+
targetDir = formatTargetDir(projectName);
|
|
53
|
+
}
|
|
54
|
+
// 2. Handle directory if exist and not empty
|
|
55
|
+
if (fs.existsSync(targetDir) && !isEmpty(targetDir)) {
|
|
56
|
+
const overwrite = argOverwrite
|
|
57
|
+
? "yes"
|
|
58
|
+
: await prompts.select({
|
|
59
|
+
message: (targetDir === "."
|
|
60
|
+
? "Current directory"
|
|
61
|
+
: `Target directory "${targetDir}"`) +
|
|
62
|
+
` is not empty. Please choose how to proceed:`,
|
|
63
|
+
options: [
|
|
64
|
+
{
|
|
65
|
+
label: "Cancel operation",
|
|
66
|
+
value: "no",
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
label: "Remove existing files and continue",
|
|
70
|
+
value: "yes",
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
label: "Ignore files and continue",
|
|
74
|
+
value: "ignore",
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
});
|
|
78
|
+
if (prompts.isCancel(overwrite))
|
|
79
|
+
return cancel();
|
|
80
|
+
switch (overwrite) {
|
|
81
|
+
case "yes":
|
|
82
|
+
emptyDir(targetDir);
|
|
83
|
+
break;
|
|
84
|
+
case "no":
|
|
85
|
+
cancel();
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// 3. Get package name
|
|
90
|
+
let packageName = path.basename(path.resolve(targetDir));
|
|
91
|
+
if (!isValidPackageName(packageName)) {
|
|
92
|
+
const packageNameResult = await prompts.text({
|
|
93
|
+
message: "Package name:",
|
|
94
|
+
defaultValue: toValidPackageName(packageName),
|
|
95
|
+
placeholder: toValidPackageName(packageName),
|
|
96
|
+
validate(dir) {
|
|
97
|
+
if (!isValidPackageName(dir)) {
|
|
98
|
+
return "Invalid package.json name";
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
if (prompts.isCancel(packageNameResult))
|
|
103
|
+
return cancel();
|
|
104
|
+
packageName = packageNameResult;
|
|
105
|
+
}
|
|
106
|
+
// 4. Choose a framework and variant
|
|
107
|
+
let template = argTemplate;
|
|
108
|
+
let hasInvalidArgTemplate = false;
|
|
109
|
+
if (argTemplate && !TEMPLATES.includes(argTemplate)) {
|
|
110
|
+
template = undefined;
|
|
111
|
+
hasInvalidArgTemplate = true;
|
|
112
|
+
}
|
|
113
|
+
if (!template) {
|
|
114
|
+
const framework = (await prompts.select({
|
|
115
|
+
message: hasInvalidArgTemplate
|
|
116
|
+
? `"${argTemplate}" isn't a valid template. Please choose from below: `
|
|
117
|
+
: "Select a framework:",
|
|
118
|
+
options: FRAMEWORKS.map((framework) => {
|
|
119
|
+
const frameworkColor = framework.color;
|
|
120
|
+
return {
|
|
121
|
+
label: frameworkColor(framework.display || framework.name),
|
|
122
|
+
value: framework,
|
|
123
|
+
};
|
|
124
|
+
}),
|
|
125
|
+
}));
|
|
126
|
+
if (prompts.isCancel(framework))
|
|
127
|
+
return cancel();
|
|
128
|
+
const variant = (await prompts.select({
|
|
129
|
+
message: "Select a variant:",
|
|
130
|
+
options: framework.variants.map((variant) => {
|
|
131
|
+
const variantColor = variant.color;
|
|
132
|
+
const command = variant.customCommand
|
|
133
|
+
? getFullCustomCommand(variant.customCommand, pkgInfo).replace(/ TARGET_DIR$/, "")
|
|
134
|
+
: variant.multiStepCommands
|
|
135
|
+
? `Multi-step setup: ${variant.multiStepCommands.length} commands`
|
|
136
|
+
: undefined;
|
|
137
|
+
return {
|
|
138
|
+
label: variantColor(variant.display || variant.name),
|
|
139
|
+
value: variant.name,
|
|
140
|
+
hint: command,
|
|
141
|
+
};
|
|
142
|
+
}),
|
|
143
|
+
}));
|
|
144
|
+
if (prompts.isCancel(variant))
|
|
145
|
+
return cancel();
|
|
146
|
+
template = variant;
|
|
147
|
+
}
|
|
148
|
+
const root = path.join(cwd, targetDir);
|
|
149
|
+
const pkgManager = pkgInfo ? pkgInfo.name : "npm";
|
|
150
|
+
const selectedVariant = FRAMEWORKS.flatMap((f) => f.variants).find((v) => v.name === template);
|
|
151
|
+
// Handle multi-step commands
|
|
152
|
+
if (selectedVariant?.multiStepCommands) {
|
|
153
|
+
await executeMultiStepCommands(selectedVariant, targetDir, root, cwd, pkgInfo);
|
|
154
|
+
createProjectFiles(template, root);
|
|
155
|
+
const successMessage = generateSuccessMessage(targetDir, pkgManager);
|
|
156
|
+
prompts.outro(successMessage);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
// Handle custom commands
|
|
160
|
+
const { customCommand } = selectedVariant ?? {};
|
|
161
|
+
if (customCommand) {
|
|
162
|
+
const fullCustomCommand = getFullCustomCommand(customCommand, pkgInfo);
|
|
163
|
+
const [command, ...args] = fullCustomCommand.split(" ");
|
|
164
|
+
const replacedArgs = args.map((arg) => arg.replace("TARGET_DIR", () => targetDir));
|
|
165
|
+
const { status } = spawn.sync(command, replacedArgs, {
|
|
166
|
+
stdio: "inherit",
|
|
167
|
+
});
|
|
168
|
+
process.exit(status ?? 0);
|
|
169
|
+
}
|
|
170
|
+
// Handle template-based projects
|
|
171
|
+
generateTemplateProject(template, root, packageName, pkgManager, cwd);
|
|
172
|
+
}
|
|
173
|
+
init().catch((e) => {
|
|
174
|
+
console.error(e);
|
|
175
|
+
});
|
package/dist/types/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{};
|
|
1
|
+
export {};
|
package/dist/utils/file.js
CHANGED
|
@@ -1 +1,62 @@
|
|
|
1
|
-
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
export function formatTargetDir(targetDir) {
|
|
4
|
+
return targetDir.trim().replace(/\/+$/g, "");
|
|
5
|
+
}
|
|
6
|
+
export function isValidPackageName(projectName) {
|
|
7
|
+
return /^(?:@[a-z\d\-*~][a-z\d\-*._~]*\/)?[a-z\d\-~][a-z\d\-._~]*$/.test(projectName);
|
|
8
|
+
}
|
|
9
|
+
export function toValidPackageName(projectName) {
|
|
10
|
+
return projectName
|
|
11
|
+
.trim()
|
|
12
|
+
.toLowerCase()
|
|
13
|
+
.replace(/\s+/g, "-")
|
|
14
|
+
.replace(/^[._]/, "")
|
|
15
|
+
.replace(/[^a-z\d\-~]+/g, "-");
|
|
16
|
+
}
|
|
17
|
+
export function isEmpty(dirPath) {
|
|
18
|
+
const files = fs.readdirSync(dirPath);
|
|
19
|
+
return files.length === 0 || (files.length === 1 && files[0] === ".git");
|
|
20
|
+
}
|
|
21
|
+
export function emptyDir(dir) {
|
|
22
|
+
if (!fs.existsSync(dir)) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
for (const file of fs.readdirSync(dir)) {
|
|
26
|
+
if (file === ".git") {
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
fs.rmSync(path.resolve(dir, file), { recursive: true, force: true });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export function pkgFromUserAgent(userAgent) {
|
|
33
|
+
if (!userAgent)
|
|
34
|
+
return undefined;
|
|
35
|
+
const pkgSpec = userAgent.split(" ")[0];
|
|
36
|
+
const pkgSpecArr = pkgSpec.split("/");
|
|
37
|
+
return {
|
|
38
|
+
name: pkgSpecArr[0],
|
|
39
|
+
version: pkgSpecArr[1],
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export function editFile(file, callback) {
|
|
43
|
+
const content = fs.readFileSync(file, "utf-8");
|
|
44
|
+
fs.writeFileSync(file, callback(content), "utf-8");
|
|
45
|
+
}
|
|
46
|
+
export function copy(src, dest) {
|
|
47
|
+
const stat = fs.statSync(src);
|
|
48
|
+
if (stat.isDirectory()) {
|
|
49
|
+
copyDir(src, dest);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
fs.copyFileSync(src, dest);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export function copyDir(srcDir, destDir) {
|
|
56
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
57
|
+
for (const file of fs.readdirSync(srcDir)) {
|
|
58
|
+
const srcFile = path.resolve(srcDir, file);
|
|
59
|
+
const destFile = path.resolve(destDir, file);
|
|
60
|
+
copy(srcFile, destFile);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -1 +1,94 @@
|
|
|
1
|
-
|
|
1
|
+
export function getFullCustomCommand(customCommand, pkgInfo) {
|
|
2
|
+
const pkgManager = pkgInfo ? pkgInfo.name : "npm";
|
|
3
|
+
const isYarn1 = pkgManager === "yarn" && pkgInfo?.version.startsWith("1.");
|
|
4
|
+
return (customCommand
|
|
5
|
+
.replace(/^npm create (?:-- )?/, () => {
|
|
6
|
+
// `bun create` uses it's own set of templates,
|
|
7
|
+
// the closest alternative is using `bun x` directly on the package
|
|
8
|
+
if (pkgManager === "bun") {
|
|
9
|
+
return "bun x create-";
|
|
10
|
+
}
|
|
11
|
+
// pnpm doesn't support the -- syntax
|
|
12
|
+
if (pkgManager === "pnpm") {
|
|
13
|
+
return "pnpm create ";
|
|
14
|
+
}
|
|
15
|
+
// For other package managers, preserve the original format
|
|
16
|
+
return customCommand.startsWith("npm create -- ")
|
|
17
|
+
? `${pkgManager} create -- `
|
|
18
|
+
: `${pkgManager} create `;
|
|
19
|
+
})
|
|
20
|
+
// Only Yarn 1.x doesn't support `@version` in the `create` command
|
|
21
|
+
.replace("@latest", () => (isYarn1 ? "" : "@latest"))
|
|
22
|
+
.replace(/^npm exec/, () => {
|
|
23
|
+
// Prefer `pnpm dlx`, `yarn dlx`, or `bun x`
|
|
24
|
+
if (pkgManager === "pnpm") {
|
|
25
|
+
return "pnpm dlx";
|
|
26
|
+
}
|
|
27
|
+
if (pkgManager === "yarn" && !isYarn1) {
|
|
28
|
+
return "yarn dlx";
|
|
29
|
+
}
|
|
30
|
+
if (pkgManager === "bun") {
|
|
31
|
+
return "bun x";
|
|
32
|
+
}
|
|
33
|
+
// Use `npm exec` in all other cases,
|
|
34
|
+
// including Yarn 1.x and other custom npm clients.
|
|
35
|
+
return "npm exec";
|
|
36
|
+
}));
|
|
37
|
+
}
|
|
38
|
+
export function replacePackageManagerInCommand(command, pkgInfo) {
|
|
39
|
+
const pkgManager = pkgInfo ? pkgInfo.name : "npm";
|
|
40
|
+
const isYarn1 = pkgManager === "yarn" && pkgInfo?.version.startsWith("1.");
|
|
41
|
+
return (command
|
|
42
|
+
// Replace pnpx/npx with appropriate package manager
|
|
43
|
+
.replace(/^pnpx\s/, () => {
|
|
44
|
+
if (pkgManager === "yarn") {
|
|
45
|
+
return isYarn1 ? "npx " : "yarn dlx ";
|
|
46
|
+
}
|
|
47
|
+
if (pkgManager === "bun") {
|
|
48
|
+
return "bunx ";
|
|
49
|
+
}
|
|
50
|
+
if (pkgManager === "npm") {
|
|
51
|
+
return "npx ";
|
|
52
|
+
}
|
|
53
|
+
return "pnpx ";
|
|
54
|
+
})
|
|
55
|
+
// Replace pnpm dlx with appropriate package manager
|
|
56
|
+
.replace(/^pnpm dlx\s/, () => {
|
|
57
|
+
if (pkgManager === "yarn") {
|
|
58
|
+
return isYarn1 ? "npx " : "yarn dlx ";
|
|
59
|
+
}
|
|
60
|
+
if (pkgManager === "bun") {
|
|
61
|
+
return "bunx ";
|
|
62
|
+
}
|
|
63
|
+
if (pkgManager === "npm") {
|
|
64
|
+
return "npx ";
|
|
65
|
+
}
|
|
66
|
+
return "pnpm dlx ";
|
|
67
|
+
})
|
|
68
|
+
// Replace pnpm add with appropriate package manager
|
|
69
|
+
.replace(/^pnpm add\s/, () => {
|
|
70
|
+
if (pkgManager === "yarn") {
|
|
71
|
+
return "yarn add ";
|
|
72
|
+
}
|
|
73
|
+
if (pkgManager === "bun") {
|
|
74
|
+
return "bun add ";
|
|
75
|
+
}
|
|
76
|
+
if (pkgManager === "npm") {
|
|
77
|
+
return "npm install ";
|
|
78
|
+
}
|
|
79
|
+
return "pnpm add ";
|
|
80
|
+
})
|
|
81
|
+
// Replace pnpm create with appropriate package manager
|
|
82
|
+
.replace(/^pnpm create\s/, () => {
|
|
83
|
+
if (pkgManager === "yarn") {
|
|
84
|
+
return "yarn create ";
|
|
85
|
+
}
|
|
86
|
+
if (pkgManager === "bun") {
|
|
87
|
+
return "bun create ";
|
|
88
|
+
}
|
|
89
|
+
if (pkgManager === "npm") {
|
|
90
|
+
return "npm create ";
|
|
91
|
+
}
|
|
92
|
+
return "pnpm create ";
|
|
93
|
+
}));
|
|
94
|
+
}
|
package/dist/utils/template.js
CHANGED
|
@@ -1 +1,41 @@
|
|
|
1
|
-
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
5
|
+
const __dirname = path.dirname(__filename);
|
|
6
|
+
export function getTemplatePath(template) {
|
|
7
|
+
return path.join(__dirname, "../templates", template);
|
|
8
|
+
}
|
|
9
|
+
export function readTemplateFile(templatePath, fileName) {
|
|
10
|
+
const filePath = path.join(templatePath, fileName);
|
|
11
|
+
if (!fs.existsSync(filePath)) {
|
|
12
|
+
throw new Error(`Template file not found: ${filePath}`);
|
|
13
|
+
}
|
|
14
|
+
return fs.readFileSync(filePath, "utf-8");
|
|
15
|
+
}
|
|
16
|
+
export function copyTemplateFiles(templateName, files, targetRoot) {
|
|
17
|
+
const templatePath = getTemplatePath(templateName);
|
|
18
|
+
for (const file of files) {
|
|
19
|
+
try {
|
|
20
|
+
const content = readTemplateFile(templatePath, file.source);
|
|
21
|
+
const targetPath = path.join(targetRoot, file.destination);
|
|
22
|
+
// Ensure target directory exists
|
|
23
|
+
const targetDir = path.dirname(targetPath);
|
|
24
|
+
if (!fs.existsSync(targetDir)) {
|
|
25
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
26
|
+
}
|
|
27
|
+
if (file.isJson) {
|
|
28
|
+
// Pretty print JSON files
|
|
29
|
+
const jsonContent = JSON.parse(content);
|
|
30
|
+
fs.writeFileSync(targetPath, JSON.stringify(jsonContent, null, 2));
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
fs.writeFileSync(targetPath, content);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
console.error(`Error copying template file ${file.source}:`, error);
|
|
38
|
+
throw error;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-web-kit",
|
|
3
|
-
"version": "25.0728.
|
|
3
|
+
"version": "25.0728.1414",
|
|
4
4
|
"description": "A powerful scaffolding tool for creating modern frontend projects with Vue, Next.js, and Electron templates",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -13,13 +13,9 @@
|
|
|
13
13
|
"node": "^18.0.0 || >=20.0.0"
|
|
14
14
|
},
|
|
15
15
|
"scripts": {
|
|
16
|
-
"build": "tsc -d --outDir
|
|
17
|
-
"dev": "
|
|
18
|
-
"start": "node dist/index.js"
|
|
19
|
-
"test": "node dist/index.js --help",
|
|
20
|
-
"prepublishOnly": "npm run build",
|
|
21
|
-
"prepack": "node scripts/pre-publish.mjs",
|
|
22
|
-
"clean": "rm -rf dist temp-dist"
|
|
16
|
+
"build": "tsc -d --outDir dist",
|
|
17
|
+
"dev": "pnpx tsx src/index.ts",
|
|
18
|
+
"start": "node dist/index.js"
|
|
23
19
|
},
|
|
24
20
|
"keywords": [
|
|
25
21
|
"scaffolding",
|
|
@@ -51,10 +47,8 @@
|
|
|
51
47
|
},
|
|
52
48
|
"devDependencies": {
|
|
53
49
|
"@types/cross-spawn": "^6.0.6",
|
|
54
|
-
"@types/javascript-obfuscator": "^0.17.0",
|
|
55
50
|
"@types/mri": "^1.1.5",
|
|
56
51
|
"@types/node": "^20.0.0",
|
|
57
|
-
"javascript-obfuscator": "^4.1.1",
|
|
58
52
|
"typescript": "^5.0.0"
|
|
59
53
|
}
|
|
60
54
|
}
|