create-vitella-ssr 0.1.0
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/bin/index.js +8 -0
- package/package.json +17 -0
- package/src/index.js +79 -0
- package/templates/vanilla/package.json +17 -0
- package/templates/vanilla/src/app.html +14 -0
- package/templates/vanilla/src/pages/_error.js +7 -0
- package/templates/vanilla/src/pages/about.js +7 -0
- package/templates/vanilla/src/pages/index.js +11 -0
- package/templates/vanilla/vite.config.js +18 -0
- package/templates/vue/package.json +20 -0
- package/templates/vue/src/app.html +14 -0
- package/templates/vue/src/pages/_error.vue +11 -0
- package/templates/vue/src/pages/about.vue +7 -0
- package/templates/vue/src/pages/index.vue +19 -0
- package/templates/vue/vite.config.js +11 -0
package/bin/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-vitella-ssr",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Scaffold a new Vitella SSR project",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"create-vitella-ssr": "./bin/index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": ["bin", "src", "templates"],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"test": "vitest run"
|
|
12
|
+
},
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=20"
|
|
16
|
+
}
|
|
17
|
+
}
|
package/src/index.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { createInterface } from 'readline/promises'
|
|
2
|
+
import { existsSync, mkdirSync, cpSync, readdirSync, readFileSync, writeFileSync, statSync } from 'fs'
|
|
3
|
+
import { join, dirname, resolve } from 'path'
|
|
4
|
+
import { fileURLToPath } from 'url'
|
|
5
|
+
import { execSync } from 'child_process'
|
|
6
|
+
|
|
7
|
+
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
8
|
+
export const TEMPLATES_DIR = join(__dirname, '..', 'templates')
|
|
9
|
+
|
|
10
|
+
export async function prompt(rl, question, defaultValue) {
|
|
11
|
+
return (await rl.question(`${question} `)).trim() || defaultValue
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function copyAndSubstitute(srcDir, destDir, vars) {
|
|
15
|
+
cpSync(srcDir, destDir, { recursive: true })
|
|
16
|
+
|
|
17
|
+
function substitute(dir) {
|
|
18
|
+
const entries = readdirSync(dir, { withFileTypes: true })
|
|
19
|
+
for (const entry of entries) {
|
|
20
|
+
const fullPath = join(dir, entry.name)
|
|
21
|
+
if (entry.isDirectory()) {
|
|
22
|
+
substitute(fullPath)
|
|
23
|
+
} else {
|
|
24
|
+
let content = readFileSync(fullPath, 'utf-8')
|
|
25
|
+
for (const [key, value] of Object.entries(vars)) {
|
|
26
|
+
content = content.replaceAll(`{{${key}}}`, value)
|
|
27
|
+
}
|
|
28
|
+
writeFileSync(fullPath, content)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
substitute(destDir)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function validateProjectName(name) {
|
|
37
|
+
if (!/^[a-z0-9-._]+$/i.test(name)) {
|
|
38
|
+
throw new Error(`Invalid project name "${name}". Use letters, digits, hyphens, dots, or underscores.`)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export async function main(opts = {}) {
|
|
43
|
+
const { prompt: promptFn, argv = process.argv, runInstall = execSync } = opts
|
|
44
|
+
|
|
45
|
+
let rl
|
|
46
|
+
const ask = promptFn || (async (question, defaultValue) => {
|
|
47
|
+
rl = rl || createInterface({ input: process.stdin, output: process.stdout })
|
|
48
|
+
return prompt(rl, question, defaultValue)
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
try {
|
|
52
|
+
const projectName = await ask('Project name:', 'my-vitella-app')
|
|
53
|
+
validateProjectName(projectName)
|
|
54
|
+
|
|
55
|
+
const framework = await ask('Framework (vue/vanilla):', 'vue')
|
|
56
|
+
if (framework !== 'vue' && framework !== 'vanilla') {
|
|
57
|
+
throw new Error(`Unknown framework "${framework}". Choose "vue" or "vanilla".`)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const rawTarget = argv[2]
|
|
61
|
+
const destDir = rawTarget ? resolve(rawTarget) : join(process.cwd(), projectName)
|
|
62
|
+
|
|
63
|
+
if (existsSync(destDir)) {
|
|
64
|
+
throw new Error(`Directory "${destDir}" already exists.`)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const templateDir = join(TEMPLATES_DIR, framework)
|
|
68
|
+
if (!existsSync(templateDir) || !statSync(templateDir).isDirectory()) {
|
|
69
|
+
throw new Error(`Template "${framework}" not found at ${templateDir}.`)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
mkdirSync(destDir, { recursive: true })
|
|
73
|
+
copyAndSubstitute(templateDir, destDir, { name: projectName })
|
|
74
|
+
|
|
75
|
+
runInstall('npm install', { cwd: destDir, stdio: 'inherit' })
|
|
76
|
+
} finally {
|
|
77
|
+
if (rl) rl.close()
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{name}}",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vitella dev",
|
|
8
|
+
"build": "vitella build",
|
|
9
|
+
"start": "vitella start"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@vitella-ssr/core": "^0.1.0"
|
|
13
|
+
},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"vite": "^8.0.0"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
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">
|
|
6
|
+
<title><!--vitella-title--></title>
|
|
7
|
+
<!--vitella-head-->
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<!--vitella-html-->
|
|
11
|
+
<!--vitella-state-->
|
|
12
|
+
<!--vitella-scripts-->
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export default function Home({ message }) {
|
|
2
|
+
return `<main>
|
|
3
|
+
<h1>${message}</h1>
|
|
4
|
+
<p>Welcome to your new Vitella SSR site.</p>
|
|
5
|
+
<nav><a href="/about">About</a></nav>
|
|
6
|
+
</main>`
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const load = async () => {
|
|
10
|
+
return { message: 'Welcome to Vitella SSR!' }
|
|
11
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { defineConfig } from 'vite'
|
|
2
|
+
import { vitellaPlugin } from '@vitella-ssr/core'
|
|
3
|
+
|
|
4
|
+
export default defineConfig({
|
|
5
|
+
plugins: [vitellaPlugin({
|
|
6
|
+
appShell: 'src/app.html',
|
|
7
|
+
adapter: {
|
|
8
|
+
name: 'vanilla',
|
|
9
|
+
extensions: ['.js'],
|
|
10
|
+
render: async ({ component, loadData }) => {
|
|
11
|
+
const html = typeof component === 'function'
|
|
12
|
+
? component(loadData)
|
|
13
|
+
: String(component)
|
|
14
|
+
return { html }
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
})],
|
|
18
|
+
})
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{name}}",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vitella dev",
|
|
8
|
+
"build": "vitella build",
|
|
9
|
+
"start": "vitella start"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@vitella-ssr/core": "^0.1.0",
|
|
13
|
+
"@vitella-ssr/vue": "^0.1.0",
|
|
14
|
+
"vue": "^3.5.0"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@vitejs/plugin-vue": "^5.0.0",
|
|
18
|
+
"vite": "^8.0.0"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
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">
|
|
6
|
+
<title><!--vitella-title--></title>
|
|
7
|
+
<!--vitella-head-->
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<!--vitella-html-->
|
|
11
|
+
<!--vitella-state-->
|
|
12
|
+
<!--vitella-scripts-->
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
export const load = async () => {
|
|
3
|
+
return { message: 'Welcome to Vitella SSR!' }
|
|
4
|
+
}
|
|
5
|
+
</script>
|
|
6
|
+
|
|
7
|
+
<template>
|
|
8
|
+
<main>
|
|
9
|
+
<h1>Vitella SSR</h1>
|
|
10
|
+
<p>{{ message }}</p>
|
|
11
|
+
<nav>
|
|
12
|
+
<a href="/about">About</a>
|
|
13
|
+
</nav>
|
|
14
|
+
</main>
|
|
15
|
+
</template>
|
|
16
|
+
|
|
17
|
+
<script setup>
|
|
18
|
+
defineProps(['message'])
|
|
19
|
+
</script>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { defineConfig } from 'vite'
|
|
2
|
+
import vue from '@vitejs/plugin-vue'
|
|
3
|
+
import { vitellaPlugin } from '@vitella-ssr/core'
|
|
4
|
+
import { vueAdapter } from '@vitella-ssr/vue'
|
|
5
|
+
|
|
6
|
+
export default defineConfig({
|
|
7
|
+
plugins: [vue(), vitellaPlugin({
|
|
8
|
+
appShell: 'src/app.html',
|
|
9
|
+
adapter: vueAdapter,
|
|
10
|
+
})],
|
|
11
|
+
})
|