create-vista-app 0.2.9 → 0.2.12

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/cli.js CHANGED
@@ -1,10 +1,11 @@
1
- #!/usr/bin/env node
2
-
3
- const fs = require('fs');
4
- const path = require('path');
5
- const { execSync } = require('child_process');
6
-
7
- const usageCommand = 'npx create-vista-app@latest <project-name>';
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const { execSync } = require('child_process');
6
+ const prompts = require('prompts');
7
+
8
+ const usageCommand = 'npx create-vista-app@latest <project-name>';
8
9
 
9
10
  // Detect which package manager invoked us (npm, pnpm, yarn, bun)
10
11
  function detectPackageManager() {
@@ -20,209 +21,261 @@ const rawArgs = process.argv.slice(2);
20
21
  const useTypedApiStarter = rawArgs.includes('--typed-api') || rawArgs.includes('--typed');
21
22
  const skipInstall = rawArgs.includes('--skip-install');
22
23
  const skipGit = rawArgs.includes('--no-git');
24
+ const assumeYes = rawArgs.includes('--yes') || rawArgs.includes('-y');
25
+ const canPrompt = !!(process.stdin.isTTY && process.stdout.isTTY);
23
26
 
24
27
  if (process.argv.includes('--help') || process.argv.includes('-h')) {
25
28
  console.log(`
26
29
  Usage:
27
- ${usageCommand} [--typed-api] [--skip-install] [--no-git]
30
+ ${usageCommand} [--typed-api] [--skip-install] [--no-git] [--yes]
28
31
 
29
32
  Example:
30
33
  npx create-vista-app@latest my-vista-app
34
+ npx create-vista-app@latest
31
35
  npx create-vista-app@latest my-vista-app --typed-api
32
36
  `);
33
37
  process.exit(0);
34
38
  }
35
39
 
36
- // Simple args: npx create-vista-app@latest <project-name>
37
- const args = rawArgs.filter((arg) => !arg.startsWith('-'));
38
- const projectName = args[0] || 'my-vista-app';
39
- const useLocal = rawArgs.includes('--local');
40
- const currentDir = process.cwd();
41
- const projectDir = path.join(currentDir, projectName);
42
-
43
- console.log(`Creating a new Vista app in ${projectDir}...`);
44
-
45
- // 1. Create Directory
46
- if (fs.existsSync(projectDir)) {
47
- console.error(`Error: Directory ${projectName} already exists.`);
48
- process.exit(1);
49
- }
50
- fs.mkdirSync(projectDir);
51
-
52
- // 2. Copy Template
53
- const templateDir = path.join(__dirname, '../template');
54
-
55
- function copyRecursiveSync(src, dest) {
56
- const exists = fs.existsSync(src);
57
- const stats = exists && fs.statSync(src);
58
- const isDirectory = exists && stats.isDirectory();
59
- if (isDirectory) {
60
- fs.mkdirSync(dest, { recursive: true });
61
- fs.readdirSync(src).forEach((childItemName) => {
62
- copyRecursiveSync(path.join(src, childItemName), path.join(dest, childItemName));
63
- });
64
- } else {
65
- fs.copyFileSync(src, dest);
66
- }
67
- }
68
-
69
- copyRecursiveSync(templateDir, projectDir);
40
+ async function resolveProjectName() {
41
+ const args = rawArgs.filter((arg) => !arg.startsWith('-'));
42
+ if (args[0]) return args[0];
43
+
44
+ if (!canPrompt) {
45
+ return 'my-vista-app';
46
+ }
47
+
48
+ const response = await prompts({
49
+ type: 'text',
50
+ name: 'projectName',
51
+ message: 'Project name?',
52
+ initial: 'my-vista-app',
53
+ validate: (value) => {
54
+ const trimmed = String(value || '').trim();
55
+ if (!trimmed) return 'Project name is required.';
56
+ if (/[<>:"/\\|?*\x00-\x1F]/.test(trimmed)) return 'Use a valid folder name.';
57
+ return true;
58
+ },
59
+ });
70
60
 
71
- if (useTypedApiStarter) {
72
- const typedTemplateDir = path.join(__dirname, '../template-typed');
73
- copyRecursiveSync(typedTemplateDir, projectDir);
74
- console.log('Added typed API starter files.');
61
+ const value = String(response.projectName || '').trim();
62
+ if (!value) {
63
+ console.log('Aborted.');
64
+ process.exit(0);
65
+ }
66
+ return value;
67
+ }
68
+ async function confirmProceed(projectName, projectDir) {
69
+ if (assumeYes || !canPrompt) return true;
70
+ const response = await prompts({
71
+ type: 'confirm',
72
+ name: 'proceed',
73
+ message: `Create Vista app "${projectName}" in ${projectDir}?`,
74
+ initial: true,
75
+ });
76
+ return response.proceed !== false;
75
77
  }
76
78
 
77
- console.log('Scaffolding complete.');
78
-
79
- // 3. Setup Dependencies (production-ready)
80
- const packageJson = {
81
- name: projectName,
82
- version: '0.1.0',
83
- scripts: {
84
- dev: 'vista dev',
85
- build: 'vista build',
86
- start: 'vista start',
87
- },
88
- dependencies: {
89
- // Runtime dependencies
90
- react: '^19.0.0',
91
- 'react-dom': '^19.0.0',
92
- 'react-server-dom-webpack': '^19.0.0',
93
- vista: useLocal ? 'file:../packages/vista' : 'npm:@vistagenic/vista@latest',
94
- // CSS build (needed in production for vista build)
95
- postcss: '^8.0.0',
96
- 'postcss-cli': '^11.0.0',
97
- tailwindcss: '^4.0.0',
98
- '@tailwindcss/postcss': '^4.0.0',
99
- // Node 20+ SSR compatibility
100
- '@swc-node/register': '^1.9.0',
101
- '@swc/core': '^1.4.0',
102
- tsx: '^4.7.0',
103
- },
104
- devDependencies: {
105
- typescript: '^5.0.0',
106
- '@types/react': '^19.0.0',
107
- '@types/react-dom': '^19.0.0',
108
- },
109
- };
110
-
111
- fs.writeFileSync(path.join(projectDir, 'package.json'), JSON.stringify(packageJson, null, 2));
112
-
113
- // 4. Create .gitignore
114
- const gitignoreContent = `# Dependencies
115
- node_modules/
116
- .pnpm-store/
117
-
118
- # Build outputs
119
- dist/
120
- .vista/
121
- .next/
122
- out/
123
-
124
- # Rust artifacts
125
- target/
126
- *.node
127
-
128
- # IDE
129
- .idea/
130
- .vscode/
131
- *.swp
132
- *.swo
133
-
134
- # Environment
135
- .env
136
- .env.local
137
- .env.development.local
138
- .env.test.local
139
- .env.production.local
140
-
141
- # Logs
142
- npm-debug.log*
143
- yarn-debug.log*
144
- yarn-error.log*
145
- pnpm-debug.log*
146
-
147
- # OS files
148
- .DS_Store
149
- Thumbs.db
150
-
151
- # TypeScript
152
- *.tsbuildinfo
153
-
154
- # Testing
155
- coverage/
156
-
157
- # Misc
158
- *.log
159
- `;
160
-
161
- fs.writeFileSync(path.join(projectDir, '.gitignore'), gitignoreContent);
162
-
163
- console.log('Created .gitignore');
164
-
165
- // 5. Initialize Git Repository
166
- if (!skipGit) {
167
- try {
168
- execSync('git init', { cwd: projectDir, stdio: 'pipe' });
169
- execSync('git add .', { cwd: projectDir, stdio: 'pipe' });
170
- execSync('git commit -m "Initial commit from create-vista-app"', {
171
- cwd: projectDir,
172
- stdio: 'pipe',
173
- env: {
174
- ...process.env,
175
- GIT_AUTHOR_NAME: 'Vista',
176
- GIT_AUTHOR_EMAIL: 'vista@example.com',
177
- GIT_COMMITTER_NAME: 'Vista',
178
- GIT_COMMITTER_EMAIL: 'vista@example.com',
179
- },
79
+ function copyRecursiveSync(src, dest) {
80
+ const exists = fs.existsSync(src);
81
+ const stats = exists && fs.statSync(src);
82
+ const isDirectory = exists && stats.isDirectory();
83
+ if (isDirectory) {
84
+ fs.mkdirSync(dest, { recursive: true });
85
+ fs.readdirSync(src).forEach((childItemName) => {
86
+ copyRecursiveSync(path.join(src, childItemName), path.join(dest, childItemName));
180
87
  });
181
- console.log('Initialized git repository with initial commit');
182
- } catch (e) {
183
- // Git might not be installed, that's okay
184
- console.log('Note: Could not initialize git repository. You can do this manually with: git init');
88
+ } else {
89
+ fs.copyFileSync(src, dest);
185
90
  }
186
- } else {
187
- console.log('Skipped git initialization (--no-git).');
188
91
  }
189
92
 
190
- // 6. Install Dependencies
191
- const installCmd = pkgManager === 'yarn' ? 'yarn' : `${pkgManager} install`;
192
- if (!skipInstall) {
193
- console.log(`\nInstalling dependencies with ${pkgManager}... This may take a moment.\n`);
194
- try {
195
- execSync(installCmd, { cwd: projectDir, stdio: 'inherit' });
196
- console.log(`\n✓ Dependencies installed successfully!`);
197
- } catch (e) {
198
- console.log(
199
- `\nNote: Could not install dependencies automatically. Run "${installCmd}" manually.`
200
- );
93
+ async function main() {
94
+ const useLocal = rawArgs.includes('--local');
95
+ const currentDir = process.cwd();
96
+ const projectName = await resolveProjectName();
97
+ const projectDir = path.join(currentDir, projectName);
98
+
99
+ const proceed = await confirmProceed(projectName, projectDir);
100
+ if (!proceed) {
101
+ console.log('Aborted.');
102
+ process.exit(0);
103
+ }
104
+
105
+ console.log(`Creating a new Vista app in ${projectDir}...`);
106
+
107
+ // 1. Create Directory
108
+ if (fs.existsSync(projectDir)) {
109
+ console.error(`Error: Directory ${projectName} already exists.`);
110
+ process.exit(1);
111
+ }
112
+ fs.mkdirSync(projectDir);
113
+
114
+ // 2. Copy Template
115
+ const templateDir = path.join(__dirname, '../template');
116
+ copyRecursiveSync(templateDir, projectDir);
117
+
118
+ if (useTypedApiStarter) {
119
+ const typedTemplateDir = path.join(__dirname, '../template-typed');
120
+ copyRecursiveSync(typedTemplateDir, projectDir);
121
+ console.log('Added typed API starter files.');
122
+ }
123
+
124
+ console.log('Scaffolding complete.');
125
+
126
+ // 3. Setup Dependencies (production-ready)
127
+ const packageJson = {
128
+ name: projectName,
129
+ version: '0.1.0',
130
+ scripts: {
131
+ dev: 'vista dev',
132
+ build: 'vista build',
133
+ start: 'vista start',
134
+ },
135
+ dependencies: {
136
+ // Runtime dependencies
137
+ react: '^19.0.0',
138
+ 'react-dom': '^19.0.0',
139
+ 'react-server-dom-webpack': '^19.0.0',
140
+ vista: useLocal ? 'file:../packages/vista' : 'npm:@vistagenic/vista@latest',
141
+ // CSS build (needed in production for vista build)
142
+ postcss: '^8.0.0',
143
+ 'postcss-cli': '^11.0.0',
144
+ tailwindcss: '^4.0.0',
145
+ '@tailwindcss/postcss': '^4.0.0',
146
+ // Node 20+ SSR compatibility
147
+ '@swc-node/register': '^1.9.0',
148
+ '@swc/core': '^1.4.0',
149
+ tsx: '^4.7.0',
150
+ },
151
+ devDependencies: {
152
+ typescript: '^5.0.0',
153
+ '@types/react': '^19.0.0',
154
+ '@types/react-dom': '^19.0.0',
155
+ },
156
+ };
157
+
158
+ fs.writeFileSync(path.join(projectDir, 'package.json'), JSON.stringify(packageJson, null, 2));
159
+
160
+ // 4. Create .gitignore
161
+ const gitignoreContent = `# Dependencies
162
+ node_modules/
163
+ .pnpm-store/
164
+
165
+ # Build outputs
166
+ dist/
167
+ .vista/
168
+ .next/
169
+ out/
170
+
171
+ # Rust artifacts
172
+ target/
173
+ *.node
174
+
175
+ # IDE
176
+ .idea/
177
+ .vscode/
178
+ *.swp
179
+ *.swo
180
+
181
+ # Environment
182
+ .env
183
+ .env.local
184
+ .env.development.local
185
+ .env.test.local
186
+ .env.production.local
187
+
188
+ # Logs
189
+ npm-debug.log*
190
+ yarn-debug.log*
191
+ yarn-error.log*
192
+ pnpm-debug.log*
193
+
194
+ # OS files
195
+ .DS_Store
196
+ Thumbs.db
197
+
198
+ # TypeScript
199
+ *.tsbuildinfo
200
+
201
+ # Testing
202
+ coverage/
203
+
204
+ # Misc
205
+ *.log
206
+ `;
207
+
208
+ fs.writeFileSync(path.join(projectDir, '.gitignore'), gitignoreContent);
209
+
210
+ console.log('Created .gitignore');
211
+
212
+ // 5. Initialize Git Repository
213
+ if (!skipGit) {
214
+ try {
215
+ execSync('git init', { cwd: projectDir, stdio: 'pipe' });
216
+ execSync('git add .', { cwd: projectDir, stdio: 'pipe' });
217
+ execSync('git commit -m "Initial commit from create-vista-app"', {
218
+ cwd: projectDir,
219
+ stdio: 'pipe',
220
+ env: {
221
+ ...process.env,
222
+ GIT_AUTHOR_NAME: 'Vista',
223
+ GIT_AUTHOR_EMAIL: 'vista@example.com',
224
+ GIT_COMMITTER_NAME: 'Vista',
225
+ GIT_COMMITTER_EMAIL: 'vista@example.com',
226
+ },
227
+ });
228
+ console.log('Initialized git repository with initial commit');
229
+ } catch (e) {
230
+ // Git might not be installed, that's okay
231
+ console.log('Note: Could not initialize git repository. You can do this manually with: git init');
232
+ }
233
+ } else {
234
+ console.log('Skipped git initialization (--no-git).');
235
+ }
236
+
237
+ // 6. Install Dependencies
238
+ const installCmd = pkgManager === 'yarn' ? 'yarn' : `${pkgManager} install`;
239
+ if (!skipInstall) {
240
+ console.log(`\nInstalling dependencies with ${pkgManager}... This may take a moment.\n`);
241
+ try {
242
+ execSync(installCmd, { cwd: projectDir, stdio: 'inherit' });
243
+ console.log(`\n✓ Dependencies installed successfully!`);
244
+ } catch (e) {
245
+ console.log(
246
+ `\nNote: Could not install dependencies automatically. Run "${installCmd}" manually.`
247
+ );
248
+ }
249
+ } else {
250
+ console.log('\nSkipped dependency installation (--skip-install).');
201
251
  }
202
- } else {
203
- console.log('\nSkipped dependency installation (--skip-install).');
252
+
253
+ const runCmd = pkgManager === 'npm' ? 'npm run' : pkgManager;
254
+ const createCmd =
255
+ pkgManager === 'pnpm'
256
+ ? 'pnpm create vista-app'
257
+ : pkgManager === 'yarn'
258
+ ? 'yarn create vista-app'
259
+ : pkgManager === 'bun'
260
+ ? 'bun create vista-app'
261
+ : 'npx create-vista-app@latest';
262
+
263
+ console.log(`
264
+ ✨ Success! Created ${projectName} at ${projectDir}
265
+
266
+ Get started by running:
267
+
268
+ cd ${projectName}
269
+ ${runCmd} dev
270
+
271
+ Create another app anytime with:
272
+ ${createCmd} <project-name>
273
+
274
+ Happy Hacking! 🚀
275
+ `);
204
276
  }
205
-
206
- const runCmd = pkgManager === 'npm' ? 'npm run' : pkgManager;
207
- const createCmd =
208
- pkgManager === 'pnpm'
209
- ? 'pnpm create vista-app'
210
- : pkgManager === 'yarn'
211
- ? 'yarn create vista-app'
212
- : pkgManager === 'bun'
213
- ? 'bun create vista-app'
214
- : 'npx create-vista-app@latest';
215
-
216
- console.log(`
217
- ✨ Success! Created ${projectName} at ${projectDir}
218
-
219
- Get started by running:
220
-
221
- cd ${projectName}
222
- ${runCmd} dev
223
-
224
- Create another app anytime with:
225
- ${createCmd} <project-name>
226
-
227
- Happy Hacking! 🚀
228
- `);
277
+
278
+ main().catch((error) => {
279
+ console.error('create-vista-app failed:', error);
280
+ process.exit(1);
281
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-vista-app",
3
- "version": "0.2.9",
3
+ "version": "0.2.12",
4
4
  "description": "Create Vista applications with one command",
5
5
  "bin": {
6
6
  "create-vista-app": "./bin/cli.js"
@@ -1,26 +1,42 @@
1
- @import "tailwindcss";
2
-
3
- :root {
4
- --background: #ffffff;
5
- --foreground: #171717;
6
- }
7
-
8
- @theme inline {
9
- --color-background: var(--background);
10
- --color-foreground: var(--foreground);
11
- --font-sans: var(--font-geist-sans);
12
- --font-mono: var(--font-geist-mono);
13
- }
14
-
15
- @media (prefers-color-scheme: dark) {
16
- :root {
17
- --background: #0a0a0a;
18
- --foreground: #ededed;
19
- }
20
- }
21
-
22
- body {
23
- background: var(--background);
24
- color: var(--foreground);
25
- font-family: var(--font-geist-sans), Arial, Helvetica, sans-serif;
26
- }
1
+ @import "tailwindcss";
2
+
3
+ @custom-variant dark (&:where(.dark, .dark *));
4
+
5
+ @theme inline {
6
+ --color-background: var(--background);
7
+ --color-foreground: var(--foreground);
8
+ --color-primary: var(--primary);
9
+ --font-sans: var(--font-geist-sans);
10
+ --font-mono: var(--font-geist-mono);
11
+ }
12
+
13
+ html {
14
+ overflow-y: scroll;
15
+ }
16
+
17
+ :root {
18
+ --background: #0a0a0a;
19
+ --foreground: #ededed;
20
+ --primary: #ff4c30;
21
+ color-scheme: dark;
22
+ }
23
+
24
+ :root.light {
25
+ --background: #ffffff;
26
+ --foreground: #171717;
27
+ --primary: #ff4c30;
28
+ color-scheme: light;
29
+ }
30
+
31
+ :root.dark {
32
+ --background: #0a0a0a;
33
+ --foreground: #ededed;
34
+ --primary: #ff4c30;
35
+ color-scheme: dark;
36
+ }
37
+
38
+ body {
39
+ background: var(--background);
40
+ color: var(--foreground);
41
+ font-family: var(--font-geist-sans), Arial, Helvetica, sans-serif;
42
+ }
@@ -1,11 +1,13 @@
1
1
  const config = {
2
- images: {
3
- domains: ['example.com'],
4
- },
5
- // Optional: override server port
6
- // server: {
7
- // port: 3000
8
- // }
2
+ images: {
3
+ domains: ['example.com'],
4
+ // For static hosts where the /_vista/image endpoint is not available:
5
+ // unoptimized: true,
6
+ },
7
+ // Optional: override server port
8
+ // server: {
9
+ // port: 3003
10
+ // }
9
11
  };
10
12
 
11
13
  export default config;