create-valaxy 0.15.2 → 0.15.3

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.mjs CHANGED
@@ -1,275 +1,6 @@
1
- import process from 'node:process';
2
- import fs from 'node:fs';
3
- import path from 'node:path';
4
- import { fileURLToPath } from 'node:url';
5
- import { execa } from 'execa';
6
- import { red, dim, gray, blue, yellow, bold, green, cyan, reset } from 'kolorist';
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.3";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}))});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.2",
4
+ "version": "0.15.3",
5
5
  "description": "Create Starter Template for Valaxy",
6
6
  "author": {
7
7
  "email": "me@yunyoujun.cn",
@@ -18,8 +18,13 @@
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": "^14.18.0 || >=16.0.0"
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.2",
15
- "valaxy-theme-yun": "0.15.2"
15
+ "valaxy": "0.15.3",
16
+ "valaxy-theme-yun": "0.15.3"
16
17
  },
17
18
  "devDependencies": {
18
19
  "typescript": "^5.2.2"
package/build.config.ts DELETED
@@ -1,3 +0,0 @@
1
- export default {
2
- entries: ['./src/index'],
3
- }
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
@@ -1,6 +0,0 @@
1
- /* eslint-disable no-console */
2
- import { init } from './valaxy'
3
-
4
- init().catch((e) => {
5
- console.error(e)
6
- })
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
- }