@remyyy/create-velox 0.0.1

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/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@remyyy/create-velox",
3
+ "version": "0.0.1",
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
7
+ "description": "Scaffolding tool for Velox Framework",
8
+ "bin": {
9
+ "create-velox": "index.js",
10
+ "cv": "index.js"
11
+ },
12
+ "main": "index.js",
13
+ "scripts": {
14
+ "build": "tsup src/index.ts --format esm --clean --minify",
15
+ "dev": "tsup src/index.ts --format esm --watch",
16
+ "test": "echo \"Error: no test specified\" && exit 1"
17
+ },
18
+ "dependencies": {
19
+ "kolorist": "^1.8.0",
20
+ "minimist": "^1.2.8",
21
+ "prompts": "^2.4.2"
22
+ },
23
+ "devDependencies": {
24
+ "@types/minimist": "^1.2.5",
25
+ "@types/node": "^20.0.0",
26
+ "@types/prompts": "^2.4.9",
27
+ "tsup": "^8.0.0",
28
+ "typescript": "^5.0.0"
29
+ },
30
+ "engines": {
31
+ "node": ">=18.0.0"
32
+ }
33
+ }
package/src/index.ts ADDED
@@ -0,0 +1,174 @@
1
+ import fs from 'node:fs'
2
+ import path from 'node:path'
3
+ import { fileURLToPath } from 'node:url'
4
+ import minimist from 'minimist'
5
+ import prompts from 'prompts'
6
+ import { red, green, bold } from 'kolorist'
7
+
8
+ const argv = minimist(process.argv.slice(2), { string: ['_'] })
9
+ const cwd = process.cwd()
10
+
11
+ const TEMPLATES = [
12
+ {
13
+ name: 'vanilla-ts',
14
+ display: 'Vanilla TypeScript',
15
+ color: green
16
+ },
17
+ {
18
+ name: 'vanilla-js',
19
+ display: 'Vanilla JavaScript',
20
+ color: red // Just for distinction
21
+ }
22
+ ]
23
+
24
+ const renameFiles: Record<string, string | undefined> = {
25
+ _gitignore: '.gitignore'
26
+ }
27
+
28
+ async function init() {
29
+ const defaultTargetDir = '@remyyy/velox-project'
30
+ let targetDir = argv._[0] || defaultTargetDir
31
+
32
+ let result: prompts.Answers<'projectName' | 'overwrite' | 'packageName' | 'framework'>
33
+
34
+ try {
35
+ result = await prompts(
36
+ [
37
+ {
38
+ type: targetDir ? null : 'text',
39
+ name: 'projectName',
40
+ message: 'Project name:',
41
+ initial: defaultTargetDir,
42
+ onState: (state) => {
43
+ targetDir = state.value.trim() || defaultTargetDir
44
+ }
45
+ },
46
+ {
47
+ type: () =>
48
+ !fs.existsSync(targetDir) || isEmpty(targetDir) ? null : 'confirm',
49
+ name: 'overwrite',
50
+ message: () =>
51
+ (targetDir === '.'
52
+ ? 'Current directory'
53
+ : `Target directory "${targetDir}"`) +
54
+ ` is not empty. Remove existing files and continue?`
55
+ },
56
+ {
57
+ type: (_, { overwrite }: { overwrite?: boolean }) => {
58
+ if (overwrite === false) {
59
+ throw new Error(red('✖') + ' Operation cancelled')
60
+ }
61
+ return null
62
+ },
63
+ name: 'overwriteChecker'
64
+ },
65
+ {
66
+ type: 'select',
67
+ name: 'framework',
68
+ message: 'Select a variant:',
69
+ initial: 0,
70
+ choices: TEMPLATES.map((framework) => {
71
+ const frameworkColor = framework.color
72
+ return {
73
+ title: frameworkColor(framework.display || framework.name),
74
+ value: framework
75
+ }
76
+ })
77
+ }
78
+ ],
79
+ {
80
+ onCancel: () => {
81
+ throw new Error(red('✖') + ' Operation cancelled')
82
+ }
83
+ }
84
+ )
85
+ } catch (cancelled: any) {
86
+ console.log(cancelled.message)
87
+ return
88
+ }
89
+
90
+ const { framework, overwrite, packageName } = result
91
+ const root = path.join(cwd, targetDir)
92
+
93
+ if (overwrite) {
94
+ emptyDir(root)
95
+ } else if (!fs.existsSync(root)) {
96
+ fs.mkdirSync(root, { recursive: true })
97
+ }
98
+
99
+ // Determine template
100
+ const templateDir = path.resolve(
101
+ fileURLToPath(import.meta.url),
102
+ '../..',
103
+ `templates/${framework.name}`
104
+ )
105
+
106
+ const write = (file: string, content?: string) => {
107
+ const targetPath = path.join(root, renameFiles[file] ?? file)
108
+ if (content) {
109
+ fs.writeFileSync(targetPath, content)
110
+ } else {
111
+ copy(path.join(templateDir, file), targetPath)
112
+ }
113
+ }
114
+
115
+ const files = fs.readdirSync(templateDir)
116
+ for (const file of files) {
117
+ write(file)
118
+ }
119
+
120
+ const pkg = JSON.parse(
121
+ fs.readFileSync(path.join(templateDir, 'package.json'), 'utf-8')
122
+ )
123
+
124
+ pkg.name = packageName || targetDir
125
+
126
+ write('package.json', JSON.stringify(pkg, null, 2))
127
+
128
+ console.log(`\n${bold(green('Done!'))} Now run:\n`)
129
+ if (root !== cwd) {
130
+ console.log(` cd ${path.relative(cwd, root)}`)
131
+ }
132
+ console.log(` npm install`)
133
+ console.log(` npm run dev`)
134
+ console.log()
135
+ }
136
+
137
+ function copy(src: string, dest: string) {
138
+ const stat = fs.statSync(src)
139
+ if (stat.isDirectory()) {
140
+ copyDir(src, dest)
141
+ } else {
142
+ fs.copyFileSync(src, dest)
143
+ }
144
+ }
145
+
146
+ function copyDir(srcDir: string, destDir: string) {
147
+ fs.mkdirSync(destDir, { recursive: true })
148
+ for (const file of fs.readdirSync(srcDir)) {
149
+ const srcFile = path.resolve(srcDir, file)
150
+ const destFile = path.resolve(destDir, file)
151
+ copy(srcFile, destFile)
152
+ }
153
+ }
154
+
155
+ function isEmpty(path: string) {
156
+ const files = fs.readdirSync(path)
157
+ return files.length === 0 || (files.length === 1 && files[0] === '.git')
158
+ }
159
+
160
+ function emptyDir(dir: string) {
161
+ if (!fs.existsSync(dir)) {
162
+ return
163
+ }
164
+ for (const file of fs.readdirSync(dir)) {
165
+ if (file === '.git') {
166
+ continue
167
+ }
168
+ fs.rmSync(path.resolve(dir, file), { recursive: true, force: true })
169
+ }
170
+ }
171
+
172
+ init().catch((e) => {
173
+ console.error(e)
174
+ })
@@ -0,0 +1,3 @@
1
+ node_modules
2
+ dist
3
+ .DS_Store
@@ -0,0 +1,16 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8" />
6
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
7
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
8
+ <title>Velox App</title>
9
+ </head>
10
+
11
+ <body>
12
+ <div id="app"></div>
13
+ <script type="module" src="/src/main.js"></script>
14
+ </body>
15
+
16
+ </html>
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "velox-app",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "vite build",
9
+ "preview": "vite preview",
10
+ "check": "tsc"
11
+ },
12
+ "dependencies": {
13
+ "velox": "^0.0.1"
14
+ },
15
+ "devDependencies": {
16
+ "vite": "^5.2.0",
17
+ "vite-plugin-velox": "^0.0.1"
18
+ }
19
+ }
@@ -0,0 +1,22 @@
1
+ import { createSignal } from 'velox'
2
+
3
+ export default function App() {
4
+ const [count, setCount] = createSignal(0)
5
+
6
+ return (
7
+ <div>
8
+ <h1>Hello Velox! </h1>
9
+ < div class="card" >
10
+ <button onclick={ () => setCount(c => c + 1) }>
11
+ count is { count }
12
+ </button>
13
+ <p>
14
+ Edit < code > src / App.ts </code> and save to test HMR
15
+ </p>
16
+ </div>
17
+ < p class="read-the-docs" >
18
+ Click on the Velox logo to learn more
19
+ </p>
20
+ </div>
21
+ )
22
+ }
@@ -0,0 +1,6 @@
1
+ import { mount } from 'velox'
2
+ import './style.css'
3
+ import App from './App'
4
+
5
+ const root = document.getElementById('app')!
6
+ mount(App, root)
@@ -0,0 +1,56 @@
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
+ }
28
+
29
+ button {
30
+ border-radius: 8px;
31
+ border: 1px solid transparent;
32
+ padding: 0.6em 1.2em;
33
+ font-size: 1em;
34
+ font-weight: 500;
35
+ font-family: inherit;
36
+ background-color: #1a1a1a;
37
+ cursor: pointer;
38
+ transition: border-color 0.25s;
39
+ }
40
+ button:hover {
41
+ border-color: #646cff;
42
+ }
43
+ button:focus,
44
+ button:focus-visible {
45
+ outline: 4px auto -webkit-focus-ring-color;
46
+ }
47
+
48
+ @media (prefers-color-scheme: light) {
49
+ :root {
50
+ color: #213547;
51
+ background-color: #ffffff;
52
+ }
53
+ button {
54
+ background-color: #f9f9f9;
55
+ }
56
+ }
@@ -0,0 +1,6 @@
1
+ import { defineConfig } from 'vite'
2
+ import velox from 'vite-plugin-velox'
3
+
4
+ export default defineConfig({
5
+ plugins: [velox()]
6
+ })
@@ -0,0 +1,3 @@
1
+ node_modules
2
+ dist
3
+ .DS_Store
@@ -0,0 +1,13 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Velox App</title>
8
+ </head>
9
+ <body>
10
+ <div id="app"></div>
11
+ <script type="module" src="/src/main.ts"></script>
12
+ </body>
13
+ </html>
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "velox-app",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "vite build",
9
+ "preview": "vite preview",
10
+ "check": "tsc"
11
+ },
12
+ "dependencies": {
13
+ "@remyyy/velox": "^0.0.1"
14
+ },
15
+ "devDependencies": {
16
+ "typescript": "^5.2.2",
17
+ "vite": "^5.2.0",
18
+ "@remyyy/vite-plugin-velox": "^0.0.1"
19
+ }
20
+ }
@@ -0,0 +1,46 @@
1
+ import { createSignal, Router, Route, Link } from 'velox';
2
+ import './style.css';
3
+
4
+ function Home() {
5
+ const [count, setCount] = createSignal(0);
6
+
7
+ return (
8
+ <div className="card">
9
+ <h1>Velox Framework</h1>
10
+ <div className="card-body">
11
+ <button onClick={() => setCount(c => c + 1)}>
12
+ Count is {count}
13
+ </button>
14
+ <p>
15
+ Edit <code>src/App.tsx</code> and save to test HMR
16
+ </p>
17
+ </div>
18
+ <p className="read-the-docs">
19
+ Click on the Velox logo to learn more
20
+ </p>
21
+ </div>
22
+ );
23
+ }
24
+
25
+ function About() {
26
+ return (
27
+ <div className="card">
28
+ <h1>About Page</h1>
29
+ <p>This is a demonstration of Velox Routing.</p>
30
+ </div>
31
+ );
32
+ }
33
+
34
+ export default function App() {
35
+ return (
36
+ <div className="app-container">
37
+ <Router>
38
+ <nav style="margin-bottom: 2rem;">
39
+ <Link to="/">Home</Link> | <Link to="/about">About</Link>
40
+ </nav>
41
+ <Route path="/" component={Home} />
42
+ <Route path="/about" component={About} />
43
+ </Router>
44
+ </div>
45
+ );
46
+ }
@@ -0,0 +1,6 @@
1
+ import { mount } from 'velox'
2
+ import './style.css'
3
+ import App from './App'
4
+
5
+ const root = document.getElementById('app')!
6
+ mount(App, root)
@@ -0,0 +1,82 @@
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
+ justify-content: center;
20
+ align-items: center;
21
+ min-width: 320px;
22
+ min-height: 100vh;
23
+ text-align: center;
24
+ }
25
+
26
+ #app {
27
+ width: 100%;
28
+ max-width: 1280px;
29
+ padding: 2rem;
30
+ margin: 0 auto;
31
+ display: flex;
32
+ flex-direction: column;
33
+ align-items: center;
34
+ }
35
+
36
+ .app-container {
37
+ display: flex;
38
+ flex-direction: column;
39
+ align-items: center;
40
+ justify-content: center;
41
+ width: 100%;
42
+ }
43
+
44
+ .card {
45
+ padding: 2em;
46
+ }
47
+
48
+ .read-the-docs {
49
+ color: #888;
50
+ }
51
+
52
+ button {
53
+ border-radius: 8px;
54
+ border: 1px solid transparent;
55
+ padding: 0.6em 1.2em;
56
+ font-size: 1em;
57
+ font-weight: 500;
58
+ font-family: inherit;
59
+ background-color: #1a1a1a;
60
+ cursor: pointer;
61
+ transition: border-color 0.25s;
62
+ }
63
+
64
+ button:hover {
65
+ border-color: #646cff;
66
+ }
67
+
68
+ button:focus,
69
+ button:focus-visible {
70
+ outline: 4px auto -webkit-focus-ring-color;
71
+ }
72
+
73
+ @media (prefers-color-scheme: light) {
74
+ :root {
75
+ color: #213547;
76
+ background-color: #ffffff;
77
+ }
78
+
79
+ button {
80
+ background-color: #f9f9f9;
81
+ }
82
+ }
@@ -0,0 +1,30 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "useDefineForClassFields": true,
5
+ "module": "ESNext",
6
+ "lib": [
7
+ "ES2020",
8
+ "DOM",
9
+ "DOM.Iterable"
10
+ ],
11
+ "skipLibCheck": true,
12
+ /* Bundler mode */
13
+ "moduleResolution": "bundler",
14
+ "allowImportingTsExtensions": true,
15
+ "resolveJsonModule": true,
16
+ "isolatedModules": true,
17
+ "noEmit": true,
18
+ /* Velox JSX - Brutally Strict */
19
+ "jsx": "react-jsx",
20
+ "jsxImportSource": "velox",
21
+ /* Linting - Safety First */
22
+ "strict": true,
23
+ "noUnusedLocals": true,
24
+ "noUnusedParameters": true,
25
+ "noFallthroughCasesInSwitch": true
26
+ },
27
+ "include": [
28
+ "src"
29
+ ]
30
+ }
@@ -0,0 +1,6 @@
1
+ import { defineConfig } from 'vite'
2
+ import velox from 'vite-plugin-velox'
3
+
4
+ export default defineConfig({
5
+ plugins: [velox()]
6
+ })
package/tsconfig.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "outDir": "./dist",
5
+ "target": "es2020",
6
+ "module": "esnext",
7
+ "moduleResolution": "bundler",
8
+ "esModuleInterop": true,
9
+ "lib": [
10
+ "esnext",
11
+ "dom"
12
+ ],
13
+ "skipLibCheck": true
14
+ },
15
+ "include": [
16
+ "src"
17
+ ]
18
+ }