create-valaxy 0.15.2 → 0.15.4
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/index.mjs +6 -275
- package/package.json +8 -3
- package/template-blog/package.json +3 -2
- package/build.config.ts +0 -3
- package/src/config.ts +0 -45
- package/src/index.ts +0 -6
- package/src/theme.ts +0 -46
- package/src/utils.ts +0 -73
- package/src/valaxy.ts +0 -200
package/dist/index.mjs
CHANGED
@@ -1,275 +1,6 @@
|
|
1
|
-
import process from
|
2
|
-
import
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
import minimist from 'minimist';
|
8
|
-
import prompts from 'prompts';
|
9
|
-
|
10
|
-
const version = "0.15.2";
|
11
|
-
|
12
|
-
function formatTargetDir(targetDir) {
|
13
|
-
return targetDir?.trim().replace(/\/+$/g, "");
|
14
|
-
}
|
15
|
-
function isEmpty(path2) {
|
16
|
-
const files = fs.readdirSync(path2);
|
17
|
-
return files.length === 0 || files.length === 1 && files[0] === ".git";
|
18
|
-
}
|
19
|
-
function copy(src, dest) {
|
20
|
-
const stat = fs.statSync(src);
|
21
|
-
if (stat.isDirectory())
|
22
|
-
copyDir(src, dest);
|
23
|
-
else
|
24
|
-
fs.copyFileSync(src, dest);
|
25
|
-
}
|
26
|
-
function copyDir(srcDir, destDir) {
|
27
|
-
fs.mkdirSync(destDir, { recursive: true });
|
28
|
-
for (const file of fs.readdirSync(srcDir)) {
|
29
|
-
const srcFile = path.resolve(srcDir, file);
|
30
|
-
const destFile = path.resolve(destDir, file);
|
31
|
-
copy(srcFile, destFile);
|
32
|
-
}
|
33
|
-
}
|
34
|
-
function emptyDir(dir) {
|
35
|
-
console.log(`
|
36
|
-
${red(`Removing`)} ${dim(dir)}`);
|
37
|
-
if (!fs.existsSync(dir))
|
38
|
-
return;
|
39
|
-
for (const file of fs.readdirSync(dir)) {
|
40
|
-
if (file === ".git")
|
41
|
-
continue;
|
42
|
-
fs.rmSync(path.resolve(dir, file), { recursive: true, force: true });
|
43
|
-
}
|
44
|
-
}
|
45
|
-
function isValidPackageName(projectName) {
|
46
|
-
return /^(?:@[a-z\d\-*~][a-z\d\-*._~]*\/)?[a-z\d\-~][a-z\d\-._~]*$/.test(
|
47
|
-
projectName
|
48
|
-
);
|
49
|
-
}
|
50
|
-
function toValidPackageName(projectName) {
|
51
|
-
return projectName.trim().toLowerCase().replace(/\s+/g, "-").replace(/^[._]/, "").replace(/[^a-z\d\-~]+/g, "-");
|
52
|
-
}
|
53
|
-
function pkgFromUserAgent(userAgent) {
|
54
|
-
if (!userAgent)
|
55
|
-
return void 0;
|
56
|
-
const pkgSpec = userAgent.split(" ")[0];
|
57
|
-
const pkgSpecArr = pkgSpec.split("/");
|
58
|
-
return {
|
59
|
-
name: pkgSpecArr[0],
|
60
|
-
version: pkgSpecArr[1]
|
61
|
-
};
|
62
|
-
}
|
63
|
-
|
64
|
-
const starterTheme = {
|
65
|
-
name: "starter",
|
66
|
-
display: `Starter`,
|
67
|
-
repo: "https://github.com/valaxyjs/valaxy-theme-starter"
|
68
|
-
};
|
69
|
-
async function initTheme(options) {
|
70
|
-
const defaultThemeName = starterTheme.name;
|
71
|
-
let themeName = options.themeName || defaultThemeName;
|
72
|
-
if (!themeName) {
|
73
|
-
const { theme } = await prompts({
|
74
|
-
type: "text",
|
75
|
-
name: "theme",
|
76
|
-
message: "Theme name: valaxy-theme-",
|
77
|
-
initial: defaultThemeName
|
78
|
-
});
|
79
|
-
themeName = theme || defaultThemeName;
|
80
|
-
}
|
81
|
-
const targetDir = `valaxy-theme-${themeName.trim()}`;
|
82
|
-
console.log(` ${dim("npx")} ${gray("degit")} ${blue(starterTheme.repo)} ${yellow(targetDir)}`);
|
83
|
-
await execa("npx", ["degit", starterTheme.repo, targetDir], { stdio: "inherit" });
|
84
|
-
console.log();
|
85
|
-
console.log(` ${bold("Check it")}:`);
|
86
|
-
console.log();
|
87
|
-
console.log(`- Change ${bold("author")} name in ${yellow("LICENSE")} & ${green("package.json")} & ${blue(".github")}`);
|
88
|
-
console.log(`- Change ${blue("valaxy.config.ts")} theme: ${yellow("starter")} to ${cyan(`${themeName}`)}`);
|
89
|
-
console.log(`- Rename ${yellow(`valaxy-theme-${themeName}`)} to ${cyan(`valaxy-theme-${themeName}`)}`);
|
90
|
-
console.log();
|
91
|
-
console.log(` ${cyan("\u2728")}`);
|
92
|
-
console.log();
|
93
|
-
return `valaxy-theme-${themeName}`;
|
94
|
-
}
|
95
|
-
|
96
|
-
const renameFiles = {
|
97
|
-
_gitignore: ".gitignore",
|
98
|
-
_npmrc: ".npmrc"
|
99
|
-
};
|
100
|
-
const TEMPLATES = [
|
101
|
-
{
|
102
|
-
name: "blog",
|
103
|
-
display: `Blog`,
|
104
|
-
desc: "For Most Users",
|
105
|
-
message: "Project name:",
|
106
|
-
initial: "valaxy-blog",
|
107
|
-
color: cyan
|
108
|
-
},
|
109
|
-
{
|
110
|
-
name: "theme",
|
111
|
-
display: `Theme`,
|
112
|
-
desc: "For Theme Developers",
|
113
|
-
message: "Theme name: valaxy-theme-",
|
114
|
-
initial: "starter",
|
115
|
-
prefix: "valaxy-theme-",
|
116
|
-
color: green,
|
117
|
-
customInit: async (options) => {
|
118
|
-
return initTheme(options).catch((e) => {
|
119
|
-
console.error(e);
|
120
|
-
});
|
121
|
-
}
|
122
|
-
},
|
123
|
-
{
|
124
|
-
name: "addon",
|
125
|
-
display: `Addon`,
|
126
|
-
desc: "For Addon Developers",
|
127
|
-
message: "Addon name: valaxy-addon-",
|
128
|
-
initial: "template",
|
129
|
-
prefix: "valaxy-addon-",
|
130
|
-
color: yellow
|
131
|
-
}
|
132
|
-
];
|
133
|
-
const TEMPLATE_CHOICES = TEMPLATES.map((template) => template.name);
|
134
|
-
|
135
|
-
const argv = minimist(process.argv.slice(2));
|
136
|
-
const cwd = process.cwd();
|
137
|
-
const defaultTargetDir = "valaxy-blog";
|
138
|
-
async function init() {
|
139
|
-
console.log();
|
140
|
-
console.log(` ${bold("\u{1F30C} Valaxy")} ${blue(`v${version}`)}`);
|
141
|
-
console.log();
|
142
|
-
const argTargetDir = formatTargetDir(argv._[0]);
|
143
|
-
const argTemplate = argv.template || argv.t;
|
144
|
-
let targetDir = argTargetDir || defaultTargetDir;
|
145
|
-
const getProjectName = () => targetDir === "." ? path.basename(path.resolve()) : targetDir;
|
146
|
-
let result;
|
147
|
-
const { template } = await prompts({
|
148
|
-
type: argTemplate && TEMPLATE_CHOICES.includes(argTemplate) ? null : "select",
|
149
|
-
name: "template",
|
150
|
-
message: typeof argTemplate === "string" && !TEMPLATE_CHOICES.includes(argTemplate) ? reset(
|
151
|
-
`"${argTemplate}" isn't a valid template. Please choose from below: `
|
152
|
-
) : reset("Select a type:"),
|
153
|
-
initial: 0,
|
154
|
-
choices: TEMPLATES.map((template2) => {
|
155
|
-
const tColor = template2.color;
|
156
|
-
return {
|
157
|
-
title: tColor(template2.display || template2.name) + dim(` - ${template2.desc}`),
|
158
|
-
value: template2
|
159
|
-
};
|
160
|
-
})
|
161
|
-
});
|
162
|
-
try {
|
163
|
-
result = await prompts([
|
164
|
-
{
|
165
|
-
type: argTargetDir ? null : "text",
|
166
|
-
name: "projectName",
|
167
|
-
message: reset(template.message),
|
168
|
-
initial: template.initial,
|
169
|
-
onState: (state) => {
|
170
|
-
targetDir = formatTargetDir(template.prefix ? template.prefix + state.value : state.value) || template.initial;
|
171
|
-
}
|
172
|
-
},
|
173
|
-
{
|
174
|
-
type: () => !fs.existsSync(targetDir) || isEmpty(targetDir) ? null : "confirm",
|
175
|
-
name: "overwrite",
|
176
|
-
message: () => `${targetDir === "." ? "Current directory" : `Target directory "${targetDir}"`} is not empty. Remove existing files and continue?`
|
177
|
-
},
|
178
|
-
{
|
179
|
-
type: (_, { overwrite: overwrite2 }) => {
|
180
|
-
if (overwrite2 === false)
|
181
|
-
throw new Error(`${red("\u2716")} Operation cancelled`);
|
182
|
-
return null;
|
183
|
-
},
|
184
|
-
name: "overwriteChecker"
|
185
|
-
},
|
186
|
-
{
|
187
|
-
type: () => isValidPackageName(getProjectName()) ? null : "text",
|
188
|
-
name: "packageName",
|
189
|
-
message: reset("Package name:"),
|
190
|
-
initial: () => toValidPackageName(getProjectName()),
|
191
|
-
validate: (dir) => isValidPackageName(dir) || "Invalid package.json name"
|
192
|
-
}
|
193
|
-
], {
|
194
|
-
onCancel: () => {
|
195
|
-
throw new Error(`${red("\u2716")} Operation cancelled`);
|
196
|
-
}
|
197
|
-
});
|
198
|
-
} catch (cancelled) {
|
199
|
-
console.log(cancelled.message);
|
200
|
-
return;
|
201
|
-
}
|
202
|
-
const { projectName, overwrite } = result;
|
203
|
-
const dirName = template.prefix ? template.prefix + projectName : projectName;
|
204
|
-
const root = path.join(cwd, dirName);
|
205
|
-
console.log(root, overwrite);
|
206
|
-
if (overwrite)
|
207
|
-
emptyDir(root);
|
208
|
-
else if (!fs.existsSync(root))
|
209
|
-
fs.mkdirSync(root, { recursive: true });
|
210
|
-
if (template.customInit) {
|
211
|
-
await template.customInit({ themeName: projectName });
|
212
|
-
} else {
|
213
|
-
const templateDir = path.resolve(fileURLToPath(new URL(".", import.meta.url)), "..", `template-${template.name}`);
|
214
|
-
const write = (filename, content) => {
|
215
|
-
const targetPath = renameFiles[filename] ? path.join(root, renameFiles[filename]) : path.join(root, filename);
|
216
|
-
if (content)
|
217
|
-
fs.writeFileSync(targetPath, content);
|
218
|
-
else
|
219
|
-
copy(path.join(templateDir, filename), targetPath);
|
220
|
-
};
|
221
|
-
const files = fs.readdirSync(templateDir);
|
222
|
-
for (const file of files.filter((f) => f !== "package.json"))
|
223
|
-
write(file);
|
224
|
-
const pkg = await import(path.join(templateDir, "package.json"));
|
225
|
-
pkg.name = projectName || getProjectName();
|
226
|
-
write("package.json", JSON.stringify(pkg, null, 2));
|
227
|
-
}
|
228
|
-
console.log(` ${dim("\u{1F4C1}")} ${dim(root)}`);
|
229
|
-
console.log();
|
230
|
-
console.log(dim(" Scaffolding project in ") + targetDir + dim(" ..."));
|
231
|
-
const pkgInfo = pkgFromUserAgent(process.env.npm_config_user_agent);
|
232
|
-
const pkgManager = pkgInfo ? pkgInfo.name : "npm";
|
233
|
-
const related = path.relative(cwd, root);
|
234
|
-
console.log(green(" Done.\n"));
|
235
|
-
if (template.name === "addon")
|
236
|
-
return;
|
237
|
-
const { yes } = await prompts({
|
238
|
-
type: "confirm",
|
239
|
-
name: "yes",
|
240
|
-
initial: "Y",
|
241
|
-
message: "Install and start it now?"
|
242
|
-
});
|
243
|
-
if (yes) {
|
244
|
-
const { agent } = await prompts({
|
245
|
-
name: "agent",
|
246
|
-
type: "select",
|
247
|
-
message: "Choose the agent",
|
248
|
-
choices: ["npm", "yarn", "pnpm"].map((i) => ({ value: i, title: i }))
|
249
|
-
});
|
250
|
-
if (!agent)
|
251
|
-
return;
|
252
|
-
await execa(agent, ["install"], { stdio: "inherit", cwd: root });
|
253
|
-
await execa(agent, ["run", "dev"], { stdio: "inherit", cwd: root });
|
254
|
-
} else {
|
255
|
-
console.log(dim("\n start it later by:\n"));
|
256
|
-
if (root !== cwd)
|
257
|
-
console.log(` ${green("cd")} ${blue(related)}`);
|
258
|
-
switch (pkgManager) {
|
259
|
-
case "yarn":
|
260
|
-
console.log(` ${green("yarn")}`);
|
261
|
-
console.log(` ${green("yarn")} dev`);
|
262
|
-
break;
|
263
|
-
default:
|
264
|
-
console.log(` ${green(pkgManager)} install`);
|
265
|
-
console.log(` ${green(pkgManager)} run dev`);
|
266
|
-
break;
|
267
|
-
}
|
268
|
-
console.log();
|
269
|
-
console.log(` ${cyan("\u2728")}`);
|
270
|
-
}
|
271
|
-
}
|
272
|
-
|
273
|
-
init().catch((e) => {
|
274
|
-
console.error(e);
|
275
|
-
});
|
1
|
+
import S from"node:process";import a from"node:fs";import i from"node:path";import{fileURLToPath as U}from"node:url";import{execa as k}from"execa";import{red as j,dim as m,gray as J,blue as y,yellow as u,bold as C,green as g,cyan as f,reset as x}from"kolorist";import B from"minimist";import v from"prompts";const G="0.15.4";function D(e){return e?.trim().replace(/\/+$/g,"")}function H(e){const o=a.readdirSync(e);return o.length===0||o.length===1&&o[0]===".git"}function I(e,o){a.statSync(e).isDirectory()?K(e,o):a.copyFileSync(e,o)}function K(e,o){a.mkdirSync(o,{recursive:!0});for(const n of a.readdirSync(e)){const c=i.resolve(e,n),p=i.resolve(o,n);I(c,p)}}function Y(e){if(console.log(`
|
2
|
+
${j("Removing")} ${m(e)}`),!!a.existsSync(e))for(const o of a.readdirSync(e))o!==".git"&&a.rmSync(i.resolve(e,o),{recursive:!0,force:!0})}function P(e){return/^(?:@[a-z\d\-*~][a-z\d\-*._~]*\/)?[a-z\d\-~][a-z\d\-._~]*$/.test(e)}function q(e){return e.trim().toLowerCase().replace(/\s+/g,"-").replace(/^[._]/,"").replace(/[^a-z\d\-~]+/g,"-")}function Q(e){if(!e)return;const o=e.split(" ")[0].split("/");return{name:o[0],version:o[1]}}const b={name:"starter",display:"Starter",repo:"https://github.com/valaxyjs/valaxy-theme-starter"};async function W(e){const o=b.name;let n=e.themeName||o;if(!n){const{theme:p}=await v({type:"text",name:"theme",message:"Theme name: valaxy-theme-",initial:o});n=p||o}const c=`valaxy-theme-${n.trim()}`;return console.log(` ${m("npx")} ${J("degit")} ${y(b.repo)} ${u(c)}`),await k("npx",["degit",b.repo,c],{stdio:"inherit"}),console.log(),console.log(` ${C("Check it")}:`),console.log(),console.log(`- Change ${C("author")} name in ${u("LICENSE")} & ${g("package.json")} & ${y(".github")}`),console.log(`- Change ${y("valaxy.config.ts")} theme: ${u("starter")} to ${f(`${n}`)}`),console.log(`- Rename ${u(`valaxy-theme-${n}`)} to ${f(`valaxy-theme-${n}`)}`),console.log(),console.log(` ${f("\u2728")}`),console.log(),`valaxy-theme-${n}`}const X={_gitignore:".gitignore",_npmrc:".npmrc"},A=[{name:"blog",display:"Blog",desc:"For Most Users",message:"Project name:",initial:"valaxy-blog",color:f},{name:"theme",display:"Theme",desc:"For Theme Developers",message:"Theme name: valaxy-theme-",initial:"starter",prefix:"valaxy-theme-",color:g,customInit:async e=>W(e).catch(o=>{console.error(o)})},{name:"addon",display:"Addon",desc:"For Addon Developers",message:"Addon name: valaxy-addon-",initial:"template",prefix:"valaxy-addon-",color:u}],O=A.map(e=>e.name),T=B(S.argv.slice(2)),E=S.cwd(),Z="valaxy-blog",ee=U(import.meta.url);async function oe(){console.log(),console.log(` ${C("\u{1F30C} Valaxy")} ${y(`v${G}`)}`),console.log();const e=D(T._[0]),o=T.template||T.t;let n=e||Z;const c=()=>n==="."?i.basename(i.resolve()):n;let p;const{template:r}=await v({type:o&&O.includes(o)?null:"select",name:"template",message:typeof o=="string"&&!O.includes(o)?x(`"${o}" isn't a valid template. Please choose from below: `):x("Select a type:"),initial:0,choices:A.map(t=>{const s=t.color;return{title:s(t.display||t.name)+m(` - ${t.desc}`),value:t}})});try{p=await v([{type:e?null:"text",name:"projectName",message:x(r.message),initial:r.initial,onState:t=>{n=D(r.prefix?r.prefix+t.value:t.value)||r.initial}},{type:()=>!a.existsSync(n)||H(n)?null:"confirm",name:"overwrite",message:()=>`${n==="."?"Current directory":`Target directory "${n}"`} is not empty. Remove existing files and continue?`},{type:(t,{overwrite:s})=>{if(s===!1)throw new Error(`${j("\u2716")} Operation cancelled`);return null},name:"overwriteChecker"},{type:()=>P(c())?null:"text",name:"packageName",message:x("Package name:"),initial:()=>q(c()),validate:t=>P(t)||"Invalid package.json name"}],{onCancel:()=>{throw new Error(`${j("\u2716")} Operation cancelled`)}})}catch(t){console.log(t.message);return}const{projectName:$,overwrite:z}=p,L=r.prefix?r.prefix+$:$,l=i.join(E,L);if(z?Y(l):a.existsSync(l)||a.mkdirSync(l,{recursive:!0}),r.customInit)await r.customInit({themeName:$});else{const t=i.resolve(ee,"../..",`template-${r.name}`),s=(d,h)=>{const _=i.join(l,X[d]??d);h?a.writeFileSync(_,h):I(i.join(t,d),_)},M=a.readdirSync(t);for(const d of M.filter(h=>h!=="package.json"))s(d);const N=JSON.parse(a.readFileSync(i.join(t,"package.json"),"utf-8"));N.name=$||c(),s("package.json",`${JSON.stringify(N,null,2)}
|
3
|
+
`)}console.log(` ${m("\u{1F4C1}")} ${m(l)}`),console.log(),console.log(m(" Scaffolding project in ")+n+m(" ..."));const F=Q(S.env.npm_config_user_agent),w=F?F.name:"npm",R=i.relative(E,l);if(console.log(g(` Done.
|
4
|
+
`)),r.name==="addon")return;const{yes:V}=await v({type:"confirm",name:"yes",initial:"Y",message:"Install and start it now?"});if(V){const{agent:t}=await v({name:"agent",type:"select",message:"Choose the agent",choices:["npm","yarn","pnpm"].map(s=>({value:s,title:s})),initial:2});if(!t)return;await k(t,["install"],{stdio:"inherit",cwd:l}),await k(t,["run","dev"],{stdio:"inherit",cwd:l})}else{switch(console.log(m(`
|
5
|
+
start it later by:
|
6
|
+
`)),l!==E&&console.log(` ${g("cd")} ${y(R)}`),w){case"yarn":console.log(` ${g("yarn")}`),console.log(` ${g("yarn")} dev`);break;default:console.log(` ${g(w)} install`),console.log(` ${g(w)} run dev`);break}console.log(),console.log(` ${f("\u2728")}`)}}oe().catch(e=>{console.error(e)});
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "create-valaxy",
|
3
3
|
"type": "module",
|
4
|
-
"version": "0.15.
|
4
|
+
"version": "0.15.4",
|
5
5
|
"description": "Create Starter Template for Valaxy",
|
6
6
|
"author": {
|
7
7
|
"email": "me@yunyoujun.cn",
|
@@ -12,14 +12,19 @@
|
|
12
12
|
"homepage": "https://valaxy.site",
|
13
13
|
"repository": {
|
14
14
|
"type": "git",
|
15
|
-
"url": "https://github.com/YunYouJun/valaxy"
|
15
|
+
"url": "https://github.com/YunYouJun/valaxy/tree/main/packages/create-valaxy"
|
16
16
|
},
|
17
17
|
"main": "bin/index.mjs",
|
18
18
|
"bin": {
|
19
19
|
"create-valaxy": "bin/index.mjs"
|
20
20
|
},
|
21
|
+
"files": [
|
22
|
+
"bin",
|
23
|
+
"dist",
|
24
|
+
"template-*"
|
25
|
+
],
|
21
26
|
"engines": {
|
22
|
-
"node": "^
|
27
|
+
"node": "^18.0.0 || >=20.0.0"
|
23
28
|
},
|
24
29
|
"dependencies": {
|
25
30
|
"execa": "8.0.1",
|
@@ -1,5 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "valaxy-blog",
|
3
|
+
"type": "module",
|
3
4
|
"version": "0.0.0",
|
4
5
|
"private": true,
|
5
6
|
"scripts": {
|
@@ -11,8 +12,8 @@
|
|
11
12
|
"serve": "vite preview"
|
12
13
|
},
|
13
14
|
"dependencies": {
|
14
|
-
"valaxy": "0.15.
|
15
|
-
"valaxy-theme-yun": "0.15.
|
15
|
+
"valaxy": "0.15.4",
|
16
|
+
"valaxy-theme-yun": "0.15.4"
|
16
17
|
},
|
17
18
|
"devDependencies": {
|
18
19
|
"typescript": "^5.2.2"
|
package/build.config.ts
DELETED
package/src/config.ts
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
import { cyan, green, yellow } from 'kolorist'
|
2
|
-
import { initTheme } from './theme'
|
3
|
-
|
4
|
-
export const renameFiles: Record<string, string> = {
|
5
|
-
_gitignore: '.gitignore',
|
6
|
-
_npmrc: '.npmrc',
|
7
|
-
}
|
8
|
-
|
9
|
-
export const TEMPLATES = [
|
10
|
-
{
|
11
|
-
name: 'blog',
|
12
|
-
display: `Blog`,
|
13
|
-
desc: 'For Most Users',
|
14
|
-
message: 'Project name:',
|
15
|
-
initial: 'valaxy-blog',
|
16
|
-
color: cyan,
|
17
|
-
},
|
18
|
-
{
|
19
|
-
name: 'theme',
|
20
|
-
display: `Theme`,
|
21
|
-
desc: 'For Theme Developers',
|
22
|
-
message: 'Theme name: valaxy-theme-',
|
23
|
-
initial: 'starter',
|
24
|
-
prefix: 'valaxy-theme-',
|
25
|
-
color: green,
|
26
|
-
customInit: async (options: {
|
27
|
-
themeName?: string
|
28
|
-
}) => {
|
29
|
-
return initTheme(options).catch((e) => {
|
30
|
-
console.error(e)
|
31
|
-
})
|
32
|
-
},
|
33
|
-
},
|
34
|
-
{
|
35
|
-
name: 'addon',
|
36
|
-
display: `Addon`,
|
37
|
-
desc: 'For Addon Developers',
|
38
|
-
message: 'Addon name: valaxy-addon-',
|
39
|
-
initial: 'template',
|
40
|
-
prefix: 'valaxy-addon-',
|
41
|
-
color: yellow,
|
42
|
-
},
|
43
|
-
]
|
44
|
-
|
45
|
-
export const TEMPLATE_CHOICES = TEMPLATES.map(template => template.name)
|
package/src/index.ts
DELETED
package/src/theme.ts
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
/* eslint-disable no-console */
|
2
|
-
import prompts from 'prompts'
|
3
|
-
import { execa } from 'execa'
|
4
|
-
import { blue, bold, cyan, dim, gray, green, yellow } from 'kolorist'
|
5
|
-
|
6
|
-
const starterTheme = {
|
7
|
-
name: 'starter',
|
8
|
-
display: `Starter`,
|
9
|
-
repo: 'https://github.com/valaxyjs/valaxy-theme-starter',
|
10
|
-
}
|
11
|
-
|
12
|
-
export async function initTheme(options: {
|
13
|
-
themeName?: string
|
14
|
-
}) {
|
15
|
-
const defaultThemeName = starterTheme.name
|
16
|
-
let themeName = options.themeName || defaultThemeName
|
17
|
-
if (!themeName) {
|
18
|
-
/**
|
19
|
-
* @type {{ theme: string }}
|
20
|
-
*/
|
21
|
-
const { theme } = await prompts({
|
22
|
-
type: 'text',
|
23
|
-
name: 'theme',
|
24
|
-
message: 'Theme name: valaxy-theme-',
|
25
|
-
initial: defaultThemeName,
|
26
|
-
})
|
27
|
-
themeName = theme || defaultThemeName
|
28
|
-
}
|
29
|
-
|
30
|
-
const targetDir = `valaxy-theme-${themeName!.trim()}`
|
31
|
-
|
32
|
-
console.log(` ${dim('npx')} ${gray('degit')} ${blue(starterTheme.repo)} ${yellow(targetDir)}`)
|
33
|
-
await execa('npx', ['degit', starterTheme.repo, targetDir], { stdio: 'inherit' })
|
34
|
-
|
35
|
-
console.log()
|
36
|
-
console.log(` ${bold('Check it')}:`)
|
37
|
-
console.log()
|
38
|
-
console.log(`- Change ${bold('author')} name in ${yellow('LICENSE')} & ${green('package.json')} & ${blue('.github')}`)
|
39
|
-
console.log(`- Change ${blue('valaxy.config.ts')} theme: ${yellow('starter')} to ${cyan(`${themeName}`)}`)
|
40
|
-
console.log(`- Rename ${yellow(`valaxy-theme-${themeName}`)} to ${cyan(`valaxy-theme-${themeName}`)}`)
|
41
|
-
console.log()
|
42
|
-
console.log(` ${cyan('✨')}`)
|
43
|
-
console.log()
|
44
|
-
|
45
|
-
return `valaxy-theme-${themeName}`
|
46
|
-
}
|
package/src/utils.ts
DELETED
@@ -1,73 +0,0 @@
|
|
1
|
-
import fs from 'node:fs'
|
2
|
-
import path from 'node:path'
|
3
|
-
import { dim, red } from 'kolorist'
|
4
|
-
|
5
|
-
/**
|
6
|
-
* remove trailing slash
|
7
|
-
*/
|
8
|
-
export function formatTargetDir(targetDir: string | undefined) {
|
9
|
-
return targetDir?.trim().replace(/\/+$/g, '')
|
10
|
-
}
|
11
|
-
|
12
|
-
export function isEmpty(path: string) {
|
13
|
-
const files = fs.readdirSync(path)
|
14
|
-
return files.length === 0 || (files.length === 1 && files[0] === '.git')
|
15
|
-
}
|
16
|
-
|
17
|
-
export function copy(src: string, dest: string) {
|
18
|
-
const stat = fs.statSync(src)
|
19
|
-
if (stat.isDirectory())
|
20
|
-
copyDir(src, dest)
|
21
|
-
|
22
|
-
else
|
23
|
-
fs.copyFileSync(src, dest)
|
24
|
-
}
|
25
|
-
|
26
|
-
export function copyDir(srcDir: string, destDir: string) {
|
27
|
-
fs.mkdirSync(destDir, { recursive: true })
|
28
|
-
for (const file of fs.readdirSync(srcDir)) {
|
29
|
-
const srcFile = path.resolve(srcDir, file)
|
30
|
-
const destFile = path.resolve(destDir, file)
|
31
|
-
copy(srcFile, destFile)
|
32
|
-
}
|
33
|
-
}
|
34
|
-
|
35
|
-
export function emptyDir(dir: string) {
|
36
|
-
// eslint-disable-next-line no-console
|
37
|
-
console.log(`\n ${red(`Removing`)} ${dim(dir)}`)
|
38
|
-
if (!fs.existsSync(dir))
|
39
|
-
return
|
40
|
-
|
41
|
-
for (const file of fs.readdirSync(dir)) {
|
42
|
-
if (file === '.git')
|
43
|
-
continue
|
44
|
-
|
45
|
-
fs.rmSync(path.resolve(dir, file), { recursive: true, force: true })
|
46
|
-
}
|
47
|
-
}
|
48
|
-
|
49
|
-
export function isValidPackageName(projectName: string) {
|
50
|
-
return /^(?:@[a-z\d\-*~][a-z\d\-*._~]*\/)?[a-z\d\-~][a-z\d\-._~]*$/.test(
|
51
|
-
projectName,
|
52
|
-
)
|
53
|
-
}
|
54
|
-
|
55
|
-
export function toValidPackageName(projectName: string) {
|
56
|
-
return projectName
|
57
|
-
.trim()
|
58
|
-
.toLowerCase()
|
59
|
-
.replace(/\s+/g, '-')
|
60
|
-
.replace(/^[._]/, '')
|
61
|
-
.replace(/[^a-z\d\-~]+/g, '-')
|
62
|
-
}
|
63
|
-
|
64
|
-
export function pkgFromUserAgent(userAgent: string | undefined) {
|
65
|
-
if (!userAgent)
|
66
|
-
return undefined
|
67
|
-
const pkgSpec = userAgent.split(' ')[0]
|
68
|
-
const pkgSpecArr = pkgSpec.split('/')
|
69
|
-
return {
|
70
|
-
name: pkgSpecArr[0],
|
71
|
-
version: pkgSpecArr[1],
|
72
|
-
}
|
73
|
-
}
|
package/src/valaxy.ts
DELETED
@@ -1,200 +0,0 @@
|
|
1
|
-
/* eslint-disable no-console */
|
2
|
-
import process from 'node:process'
|
3
|
-
import fs from 'node:fs'
|
4
|
-
import path from 'node:path'
|
5
|
-
import { fileURLToPath } from 'node:url'
|
6
|
-
import { execa } from 'execa'
|
7
|
-
import { blue, bold, cyan, dim, green, red, reset } from 'kolorist'
|
8
|
-
import minimist from 'minimist'
|
9
|
-
import prompts from 'prompts'
|
10
|
-
import { version } from '../package.json'
|
11
|
-
import { copy, emptyDir, formatTargetDir, isEmpty, isValidPackageName, pkgFromUserAgent, toValidPackageName } from './utils'
|
12
|
-
import { TEMPLATES, TEMPLATE_CHOICES, renameFiles } from './config'
|
13
|
-
|
14
|
-
const argv = minimist(process.argv.slice(2))
|
15
|
-
|
16
|
-
const cwd = process.cwd()
|
17
|
-
const defaultTargetDir = 'valaxy-blog'
|
18
|
-
|
19
|
-
export async function init() {
|
20
|
-
console.log()
|
21
|
-
console.log(` ${bold('🌌 Valaxy')} ${blue(`v${version}`)}`)
|
22
|
-
console.log()
|
23
|
-
|
24
|
-
const argTargetDir = formatTargetDir(argv._[0])
|
25
|
-
const argTemplate = argv.template || argv.t
|
26
|
-
|
27
|
-
let targetDir = argTargetDir || defaultTargetDir
|
28
|
-
const getProjectName = () =>
|
29
|
-
targetDir === '.' ? path.basename(path.resolve()) : targetDir
|
30
|
-
|
31
|
-
let result: prompts.Answers<
|
32
|
-
'projectName' | 'overwrite' | 'packageName'
|
33
|
-
>
|
34
|
-
|
35
|
-
// get template
|
36
|
-
const { template } = await prompts({
|
37
|
-
type:
|
38
|
-
argTemplate && TEMPLATE_CHOICES.includes(argTemplate) ? null : 'select',
|
39
|
-
name: 'template',
|
40
|
-
message:
|
41
|
-
typeof argTemplate === 'string' && !TEMPLATE_CHOICES.includes(argTemplate)
|
42
|
-
? reset(
|
43
|
-
`"${argTemplate}" isn't a valid template. Please choose from below: `,
|
44
|
-
)
|
45
|
-
: reset('Select a type:'),
|
46
|
-
initial: 0,
|
47
|
-
choices: TEMPLATES.map((template) => {
|
48
|
-
const tColor = template.color
|
49
|
-
return {
|
50
|
-
title: tColor(template.display || template.name) + dim(` - ${template.desc}`),
|
51
|
-
value: template,
|
52
|
-
}
|
53
|
-
}),
|
54
|
-
})
|
55
|
-
|
56
|
-
try {
|
57
|
-
result = await prompts([
|
58
|
-
{
|
59
|
-
type: argTargetDir ? null : 'text',
|
60
|
-
name: 'projectName',
|
61
|
-
message: reset(template.message),
|
62
|
-
initial: template.initial,
|
63
|
-
onState: (state) => {
|
64
|
-
targetDir = formatTargetDir(template.prefix ? template.prefix + state.value : state.value) || (template.initial)
|
65
|
-
},
|
66
|
-
},
|
67
|
-
{
|
68
|
-
type: () =>
|
69
|
-
!fs.existsSync(targetDir) || isEmpty(targetDir) ? null : 'confirm',
|
70
|
-
name: 'overwrite',
|
71
|
-
message: () =>
|
72
|
-
`${targetDir === '.'
|
73
|
-
? 'Current directory'
|
74
|
-
: `Target directory "${targetDir}"`
|
75
|
-
} is not empty. Remove existing files and continue?`,
|
76
|
-
},
|
77
|
-
{
|
78
|
-
type: (_, { overwrite }: { overwrite?: boolean }) => {
|
79
|
-
if (overwrite === false)
|
80
|
-
throw new Error(`${red('✖')} Operation cancelled`)
|
81
|
-
|
82
|
-
return null
|
83
|
-
},
|
84
|
-
name: 'overwriteChecker',
|
85
|
-
},
|
86
|
-
{
|
87
|
-
type: () => (isValidPackageName(getProjectName()) ? null : 'text'),
|
88
|
-
name: 'packageName',
|
89
|
-
message: reset('Package name:'),
|
90
|
-
initial: () => toValidPackageName(getProjectName()),
|
91
|
-
validate: dir =>
|
92
|
-
isValidPackageName(dir) || 'Invalid package.json name',
|
93
|
-
},
|
94
|
-
], {
|
95
|
-
onCancel: () => {
|
96
|
-
throw new Error(`${red('✖')} Operation cancelled`)
|
97
|
-
},
|
98
|
-
})
|
99
|
-
}
|
100
|
-
catch (cancelled: any) {
|
101
|
-
console.log(cancelled.message)
|
102
|
-
return
|
103
|
-
}
|
104
|
-
|
105
|
-
const { projectName, overwrite } = result
|
106
|
-
const dirName = template.prefix ? template.prefix + projectName : projectName
|
107
|
-
const root = path.join(cwd, dirName)
|
108
|
-
|
109
|
-
console.log(root, overwrite)
|
110
|
-
|
111
|
-
if (overwrite)
|
112
|
-
emptyDir(root)
|
113
|
-
else if (!fs.existsSync(root))
|
114
|
-
fs.mkdirSync(root, { recursive: true })
|
115
|
-
|
116
|
-
// custom
|
117
|
-
if (template.customInit) {
|
118
|
-
await template.customInit({ themeName: projectName })
|
119
|
-
}
|
120
|
-
else {
|
121
|
-
const templateDir = path.resolve(fileURLToPath(new URL('.', import.meta.url)), '..', `template-${template.name}`)
|
122
|
-
const write = (filename: string, content?: string) => {
|
123
|
-
const targetPath = renameFiles[filename]
|
124
|
-
? path.join(root, renameFiles[filename])
|
125
|
-
: path.join(root, filename)
|
126
|
-
|
127
|
-
if (content)
|
128
|
-
fs.writeFileSync(targetPath, content)
|
129
|
-
else
|
130
|
-
copy(path.join(templateDir, filename), targetPath)
|
131
|
-
}
|
132
|
-
|
133
|
-
const files = fs.readdirSync(templateDir)
|
134
|
-
for (const file of files.filter(f => f !== 'package.json'))
|
135
|
-
write(file)
|
136
|
-
|
137
|
-
// write pkg name & version
|
138
|
-
const pkg = await import(path.join(templateDir, 'package.json'))
|
139
|
-
pkg.name = projectName || getProjectName()
|
140
|
-
|
141
|
-
write('package.json', JSON.stringify(pkg, null, 2))
|
142
|
-
}
|
143
|
-
|
144
|
-
console.log(` ${dim('📁')} ${dim(root)}`)
|
145
|
-
console.log()
|
146
|
-
console.log(dim(' Scaffolding project in ') + targetDir + dim(' ...'))
|
147
|
-
|
148
|
-
const pkgInfo = pkgFromUserAgent(process.env.npm_config_user_agent)
|
149
|
-
const pkgManager = pkgInfo ? pkgInfo.name : 'npm'
|
150
|
-
|
151
|
-
const related = path.relative(cwd, root)
|
152
|
-
console.log(green(' Done.\n'))
|
153
|
-
|
154
|
-
// addon not start
|
155
|
-
if (template.name === 'addon')
|
156
|
-
return
|
157
|
-
|
158
|
-
/**
|
159
|
-
* @type {{ yes: boolean }}
|
160
|
-
*/
|
161
|
-
const { yes } = await prompts({
|
162
|
-
type: 'confirm',
|
163
|
-
name: 'yes',
|
164
|
-
initial: 'Y',
|
165
|
-
message: 'Install and start it now?',
|
166
|
-
})
|
167
|
-
|
168
|
-
if (yes) {
|
169
|
-
const { agent } = await prompts({
|
170
|
-
name: 'agent',
|
171
|
-
type: 'select',
|
172
|
-
message: 'Choose the agent',
|
173
|
-
choices: ['npm', 'yarn', 'pnpm'].map(i => ({ value: i, title: i })),
|
174
|
-
})
|
175
|
-
|
176
|
-
if (!agent)
|
177
|
-
return
|
178
|
-
|
179
|
-
await execa(agent, ['install'], { stdio: 'inherit', cwd: root })
|
180
|
-
await execa(agent, ['run', 'dev'], { stdio: 'inherit', cwd: root })
|
181
|
-
}
|
182
|
-
else {
|
183
|
-
console.log(dim('\n start it later by:\n'))
|
184
|
-
if (root !== cwd)
|
185
|
-
console.log(` ${green('cd')} ${blue(related)}`)
|
186
|
-
|
187
|
-
switch (pkgManager) {
|
188
|
-
case 'yarn':
|
189
|
-
console.log(` ${green('yarn')}`)
|
190
|
-
console.log(` ${green('yarn')} dev`)
|
191
|
-
break
|
192
|
-
default:
|
193
|
-
console.log(` ${green(pkgManager)} install`)
|
194
|
-
console.log(` ${green(pkgManager)} run dev`)
|
195
|
-
break
|
196
|
-
}
|
197
|
-
console.log()
|
198
|
-
console.log(` ${cyan('✨')}`)
|
199
|
-
}
|
200
|
-
}
|