create-vista-app 0.3.0 → 0.3.3
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 +118 -10
- package/package.json +39 -39
- package/template/deploy/Dockerfile +2 -1
- package/template/deploy/netlify.toml +15 -0
- package/template/deploy/vercel.json +2 -11
- package/template/deploy/wrangler.toml +18 -2
package/bin/cli.js
CHANGED
|
@@ -70,17 +70,24 @@ const explicitFlashpack = rawArgs.includes('--flashpack');
|
|
|
70
70
|
const explicitDefaultEngine = rawArgs.includes('--default-engine');
|
|
71
71
|
const explicitEngine = getFlagValue('--engine');
|
|
72
72
|
const explicitPackageManager = getExplicitPackageManagerFromArgs(rawArgs);
|
|
73
|
+
const explicitSrcDir =
|
|
74
|
+
rawArgs.includes('--src-dir') || rawArgs.includes('--src')
|
|
75
|
+
? true
|
|
76
|
+
: rawArgs.includes('--no-src-dir')
|
|
77
|
+
? false
|
|
78
|
+
: undefined;
|
|
73
79
|
|
|
74
80
|
if (process.argv.includes('--help') || process.argv.includes('-h')) {
|
|
75
81
|
console.log(`
|
|
76
82
|
Usage:
|
|
77
|
-
${usageCommand} [--typed-api] [--skip-install] [--no-git] [--yes] [--no-deploy-templates] [--engine <default|flashpack>] [--flashpack] [--default-engine] [--package-manager <npm|pnpm|yarn|bun>] [--npm|--pnpm|--yarn|--bun]
|
|
83
|
+
${usageCommand} [--typed-api] [--skip-install] [--no-git] [--yes] [--no-deploy-templates] [--engine <default|flashpack>] [--flashpack] [--default-engine] [--src-dir|--no-src-dir] [--package-manager <npm|pnpm|yarn|bun>] [--npm|--pnpm|--yarn|--bun]
|
|
78
84
|
|
|
79
85
|
Example:
|
|
80
86
|
npx create-vista-app@latest my-vista-app
|
|
81
87
|
npx create-vista-app@latest
|
|
82
88
|
npx create-vista-app@latest my-vista-app --typed-api
|
|
83
89
|
npx create-vista-app@latest my-vista-app --flashpack
|
|
90
|
+
npx create-vista-app@latest my-vista-app --src-dir
|
|
84
91
|
npx create-vista-app@latest my-vista-app --package-manager pnpm
|
|
85
92
|
`);
|
|
86
93
|
process.exit(0);
|
|
@@ -91,6 +98,16 @@ if (explicitFlashpack && explicitDefaultEngine) {
|
|
|
91
98
|
process.exit(1);
|
|
92
99
|
}
|
|
93
100
|
|
|
101
|
+
if (rawArgs.includes('--src-dir') && rawArgs.includes('--no-src-dir')) {
|
|
102
|
+
console.error('Error: use only one of --src-dir or --no-src-dir.');
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (rawArgs.includes('--src') && rawArgs.includes('--no-src-dir')) {
|
|
107
|
+
console.error('Error: use only one of --src / --src-dir or --no-src-dir.');
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
|
|
94
111
|
if (explicitEngine && !['default', 'flashpack'].includes(explicitEngine)) {
|
|
95
112
|
console.error(`Error: unsupported engine "${explicitEngine}". Use "default" or "flashpack".`);
|
|
96
113
|
process.exit(1);
|
|
@@ -124,12 +141,13 @@ async function resolveProjectName() {
|
|
|
124
141
|
}
|
|
125
142
|
return value;
|
|
126
143
|
}
|
|
127
|
-
async function confirmProceed(projectName, projectDir, engine, packageManager) {
|
|
144
|
+
async function confirmProceed(projectName, projectDir, engine, packageManager, useSrcDir) {
|
|
128
145
|
if (assumeYes || !canPrompt) return true;
|
|
146
|
+
const layout = useSrcDir ? 'src/app' : 'app';
|
|
129
147
|
const response = await prompts({
|
|
130
148
|
type: 'confirm',
|
|
131
149
|
name: 'proceed',
|
|
132
|
-
message: `Create Vista app "${projectName}" in ${projectDir} (engine: ${engine}, package manager: ${packageManager})?`,
|
|
150
|
+
message: `Create Vista app "${projectName}" in ${projectDir} (engine: ${engine}, layout: ${layout}, package manager: ${packageManager})?`,
|
|
133
151
|
initial: true,
|
|
134
152
|
});
|
|
135
153
|
return response.proceed !== false;
|
|
@@ -168,6 +186,25 @@ async function resolveEngineChoice() {
|
|
|
168
186
|
return value;
|
|
169
187
|
}
|
|
170
188
|
|
|
189
|
+
async function resolveSrcDirChoice() {
|
|
190
|
+
if (typeof explicitSrcDir === 'boolean') return explicitSrcDir;
|
|
191
|
+
if (assumeYes || !canPrompt) return false;
|
|
192
|
+
|
|
193
|
+
const response = await prompts({
|
|
194
|
+
type: 'confirm',
|
|
195
|
+
name: 'useSrcDir',
|
|
196
|
+
message: 'Would you like to use a `src/` directory?',
|
|
197
|
+
initial: false,
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
if (typeof response.useSrcDir !== 'boolean') {
|
|
201
|
+
console.log('Aborted.');
|
|
202
|
+
process.exit(0);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return response.useSrcDir;
|
|
206
|
+
}
|
|
207
|
+
|
|
171
208
|
async function resolvePackageManagerChoice() {
|
|
172
209
|
if (explicitPackageManager) return explicitPackageManager;
|
|
173
210
|
if (assumeYes || !canPrompt) return detectedPackageManager;
|
|
@@ -277,15 +314,27 @@ function applyEngineToVistaConfig(projectDir, selectedEngine) {
|
|
|
277
314
|
fs.writeFileSync(configPath, patched);
|
|
278
315
|
}
|
|
279
316
|
|
|
280
|
-
function applyReadmeSelections(projectDir, selectedEngine, useTypedApi) {
|
|
317
|
+
function applyReadmeSelections(projectDir, selectedEngine, useTypedApi, useSrcDir = false) {
|
|
281
318
|
const readmePath = path.join(projectDir, 'README.md');
|
|
282
319
|
if (!fs.existsSync(readmePath)) return;
|
|
283
320
|
|
|
284
|
-
|
|
285
|
-
|
|
321
|
+
let source = fs.readFileSync(readmePath, 'utf8');
|
|
322
|
+
source = source
|
|
286
323
|
.replace(/__VISTA_ENGINE__/g, selectedEngine)
|
|
287
324
|
.replace(/__VISTA_TYPED_API__/g, useTypedApi ? 'enabled' : 'disabled');
|
|
288
|
-
|
|
325
|
+
|
|
326
|
+
if (useSrcDir) {
|
|
327
|
+
source = source
|
|
328
|
+
.replace(/Add pages under `app`\./g, 'Add pages under `src/app`.')
|
|
329
|
+
.replace(/`app\/api\/\*\*\/route\.ts`/g, '`src/app/api/**/route.ts`')
|
|
330
|
+
.replace(/`app\/agents\//g, '`src/app/agents/')
|
|
331
|
+
.replace(
|
|
332
|
+
/```\napp\/\n├── root\.tsx[\s\S]*?vista\.config\.ts\n```/,
|
|
333
|
+
'```\nsrc/\n├── app/\n│ ├── root.tsx # Root layout\n│ ├── index.tsx # Home → /\n│ ├── globals.css\n│ └── about/page.tsx # → /about\n└── components/\npublic/\nvista.config.ts\n```'
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
fs.writeFileSync(readmePath, source);
|
|
289
338
|
}
|
|
290
339
|
|
|
291
340
|
function applyFlashpackStarterTheme(projectDir) {
|
|
@@ -295,6 +344,56 @@ function applyFlashpackStarterTheme(projectDir) {
|
|
|
295
344
|
}
|
|
296
345
|
}
|
|
297
346
|
|
|
347
|
+
/**
|
|
348
|
+
* Move app/ + components/ under src/ (Next-style layout).
|
|
349
|
+
* Call after all template overlays so flashpack/typed files move too.
|
|
350
|
+
*/
|
|
351
|
+
function applySrcDirectoryLayout(projectDir) {
|
|
352
|
+
const srcDir = path.join(projectDir, 'src');
|
|
353
|
+
fs.mkdirSync(srcDir, { recursive: true });
|
|
354
|
+
|
|
355
|
+
const moves = [
|
|
356
|
+
['app', path.join('src', 'app')],
|
|
357
|
+
['components', path.join('src', 'components')],
|
|
358
|
+
];
|
|
359
|
+
|
|
360
|
+
for (const [fromRel, toRel] of moves) {
|
|
361
|
+
const from = path.join(projectDir, fromRel);
|
|
362
|
+
const to = path.join(projectDir, toRel);
|
|
363
|
+
if (!fs.existsSync(from)) continue;
|
|
364
|
+
if (fs.existsSync(to)) {
|
|
365
|
+
// Merge: move children into existing target
|
|
366
|
+
for (const entry of fs.readdirSync(from)) {
|
|
367
|
+
const srcPath = path.join(from, entry);
|
|
368
|
+
const destPath = path.join(to, entry);
|
|
369
|
+
if (fs.existsSync(destPath)) {
|
|
370
|
+
fs.rmSync(destPath, { recursive: true, force: true });
|
|
371
|
+
}
|
|
372
|
+
fs.renameSync(srcPath, destPath);
|
|
373
|
+
}
|
|
374
|
+
fs.rmSync(from, { recursive: true, force: true });
|
|
375
|
+
} else {
|
|
376
|
+
fs.renameSync(from, to);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// Point @/* at src/* for the common import alias.
|
|
381
|
+
const tsconfigPath = path.join(projectDir, 'tsconfig.json');
|
|
382
|
+
if (fs.existsSync(tsconfigPath)) {
|
|
383
|
+
try {
|
|
384
|
+
const tsconfig = JSON.parse(fs.readFileSync(tsconfigPath, 'utf8'));
|
|
385
|
+
tsconfig.compilerOptions = tsconfig.compilerOptions || {};
|
|
386
|
+
tsconfig.compilerOptions.paths = {
|
|
387
|
+
...(tsconfig.compilerOptions.paths || {}),
|
|
388
|
+
'@/*': ['./src/*'],
|
|
389
|
+
};
|
|
390
|
+
fs.writeFileSync(tsconfigPath, `${JSON.stringify(tsconfig, null, 2)}\n`);
|
|
391
|
+
} catch {
|
|
392
|
+
// Keep scaffold resilient if tsconfig is unexpected.
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
298
397
|
function applyDeployTemplates(projectDir, options = {}) {
|
|
299
398
|
const deployTemplateDir = path.join(__dirname, '../template/deploy');
|
|
300
399
|
if (!fs.existsSync(deployTemplateDir)) return;
|
|
@@ -318,6 +417,7 @@ async function main() {
|
|
|
318
417
|
const currentDir = process.cwd();
|
|
319
418
|
const projectName = await resolveProjectName();
|
|
320
419
|
const selectedEngine = await resolveEngineChoice();
|
|
420
|
+
const useSrcDir = await resolveSrcDirChoice();
|
|
321
421
|
const selectedPackageManager = await resolvePackageManagerChoice();
|
|
322
422
|
const projectDir = path.join(currentDir, projectName);
|
|
323
423
|
|
|
@@ -325,7 +425,8 @@ async function main() {
|
|
|
325
425
|
projectName,
|
|
326
426
|
projectDir,
|
|
327
427
|
selectedEngine,
|
|
328
|
-
selectedPackageManager
|
|
428
|
+
selectedPackageManager,
|
|
429
|
+
useSrcDir
|
|
329
430
|
);
|
|
330
431
|
if (!proceed) {
|
|
331
432
|
console.log('Aborted.');
|
|
@@ -352,7 +453,7 @@ async function main() {
|
|
|
352
453
|
}
|
|
353
454
|
|
|
354
455
|
applyEngineToVistaConfig(projectDir, selectedEngine);
|
|
355
|
-
applyReadmeSelections(projectDir, selectedEngine, useTypedApiStarter);
|
|
456
|
+
applyReadmeSelections(projectDir, selectedEngine, useTypedApiStarter, useSrcDir);
|
|
356
457
|
if (selectedEngine === 'flashpack') {
|
|
357
458
|
applyFlashpackStarterTheme(projectDir);
|
|
358
459
|
}
|
|
@@ -361,6 +462,11 @@ async function main() {
|
|
|
361
462
|
console.log('Added deployment templates (render.yaml, Dockerfile).');
|
|
362
463
|
}
|
|
363
464
|
|
|
465
|
+
if (useSrcDir) {
|
|
466
|
+
applySrcDirectoryLayout(projectDir);
|
|
467
|
+
console.log('Using src/ directory layout (src/app, src/components).');
|
|
468
|
+
}
|
|
469
|
+
|
|
364
470
|
console.log('Scaffolding complete.');
|
|
365
471
|
|
|
366
472
|
// 3. Setup Dependencies (production-ready)
|
|
@@ -378,7 +484,7 @@ async function main() {
|
|
|
378
484
|
react: '^19.0.0',
|
|
379
485
|
'react-dom': '^19.0.0',
|
|
380
486
|
'react-server-dom-webpack': '^19.0.0',
|
|
381
|
-
vista: useLocal ? 'file:../packages/vista' : 'npm:@vistagenic/vista@
|
|
487
|
+
vista: useLocal ? 'file:../packages/vista' : 'npm:@vistagenic/vista@0.3.3',
|
|
382
488
|
'lucide-react': '^0.468.0',
|
|
383
489
|
// CSS build (needed in production for vista build)
|
|
384
490
|
postcss: '^8.0.0',
|
|
@@ -500,6 +606,7 @@ coverage/
|
|
|
500
606
|
console.log(`
|
|
501
607
|
✨ Success! Created ${projectName} at ${projectDir}
|
|
502
608
|
Engine: ${selectedEngine}
|
|
609
|
+
Layout: ${useSrcDir ? 'src/app' : 'app'}
|
|
503
610
|
Package manager: ${selectedPackageManager}
|
|
504
611
|
|
|
505
612
|
Get started by running:
|
|
@@ -525,6 +632,7 @@ module.exports = {
|
|
|
525
632
|
applyEngineToVistaConfig,
|
|
526
633
|
applyReadmeSelections,
|
|
527
634
|
applyFlashpackStarterTheme,
|
|
635
|
+
applySrcDirectoryLayout,
|
|
528
636
|
};
|
|
529
637
|
|
|
530
638
|
if (require.main === module) {
|
package/package.json
CHANGED
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "create-vista-app",
|
|
3
|
-
"version": "0.3.
|
|
4
|
-
"description": "Create Vista applications with one command",
|
|
5
|
-
"bin": {
|
|
6
|
-
"create-vista-app": "./bin/cli.js"
|
|
7
|
-
},
|
|
8
|
-
"repository": {
|
|
9
|
-
"type": "git",
|
|
10
|
-
"url": "https://github.com/Mantitup-Org/vista.git",
|
|
11
|
-
"directory": "packages/create-vista-app"
|
|
12
|
-
},
|
|
13
|
-
"author": "Vista Team",
|
|
14
|
-
"license": "MIT",
|
|
15
|
-
"keywords": [
|
|
16
|
-
"create",
|
|
17
|
-
"vista",
|
|
18
|
-
"react",
|
|
19
|
-
"scaffold",
|
|
20
|
-
"cli"
|
|
21
|
-
],
|
|
22
|
-
"files": [
|
|
23
|
-
"bin",
|
|
24
|
-
"template",
|
|
25
|
-
"template-typed"
|
|
26
|
-
],
|
|
27
|
-
"dependencies": {
|
|
28
|
-
"fs-extra": "^11.1.1",
|
|
29
|
-
"picocolors": "^1.0.0",
|
|
30
|
-
"prompts": "^2.4.2"
|
|
31
|
-
},
|
|
32
|
-
"devDependencies": {
|
|
33
|
-
"@types/react": "^19.0.0",
|
|
34
|
-
"@types/react-dom": "^19.0.0",
|
|
35
|
-
"react": "^19.0.0",
|
|
36
|
-
"react-dom": "^19.0.0"
|
|
37
|
-
},
|
|
38
|
-
"gitHead": "d1b9f715d6365d8e1f553e96b752fbce8d98df7c"
|
|
39
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "create-vista-app",
|
|
3
|
+
"version": "0.3.3",
|
|
4
|
+
"description": "Create Vista applications with one command",
|
|
5
|
+
"bin": {
|
|
6
|
+
"create-vista-app": "./bin/cli.js"
|
|
7
|
+
},
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/Mantitup-Org/vista.git",
|
|
11
|
+
"directory": "packages/create-vista-app"
|
|
12
|
+
},
|
|
13
|
+
"author": "Vista Team",
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"keywords": [
|
|
16
|
+
"create",
|
|
17
|
+
"vista",
|
|
18
|
+
"react",
|
|
19
|
+
"scaffold",
|
|
20
|
+
"cli"
|
|
21
|
+
],
|
|
22
|
+
"files": [
|
|
23
|
+
"bin",
|
|
24
|
+
"template",
|
|
25
|
+
"template-typed"
|
|
26
|
+
],
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"fs-extra": "^11.1.1",
|
|
29
|
+
"picocolors": "^1.0.0",
|
|
30
|
+
"prompts": "^2.4.2"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/react": "^19.0.0",
|
|
34
|
+
"@types/react-dom": "^19.0.0",
|
|
35
|
+
"react": "^19.0.0",
|
|
36
|
+
"react-dom": "^19.0.0"
|
|
37
|
+
},
|
|
38
|
+
"gitHead": "d1b9f715d6365d8e1f553e96b752fbce8d98df7c"
|
|
39
|
+
}
|
|
@@ -11,7 +11,8 @@ FROM node:20-alpine AS runner
|
|
|
11
11
|
WORKDIR /app
|
|
12
12
|
ENV NODE_ENV=production
|
|
13
13
|
ENV PORT=3003
|
|
14
|
-
COPY --from=builder /app/.vista ./.vista
|
|
15
14
|
COPY --from=builder /app/package.json ./package.json
|
|
15
|
+
COPY --from=builder /app/node_modules ./node_modules
|
|
16
|
+
COPY --from=builder /app/.vista ./.vista
|
|
16
17
|
EXPOSE 3003
|
|
17
18
|
CMD ["node", ".vista/standalone/server.js"]
|
|
@@ -1,7 +1,22 @@
|
|
|
1
1
|
[build]
|
|
2
2
|
command = "npm run build"
|
|
3
3
|
publish = ".vista/deploy/netlify"
|
|
4
|
+
functions = "netlify/functions"
|
|
5
|
+
|
|
6
|
+
[functions]
|
|
7
|
+
node_bundler = "none"
|
|
8
|
+
included_files = ["netlify/functions/.vista/**", "netlify/functions/node_modules/**"]
|
|
4
9
|
|
|
5
10
|
[dev]
|
|
6
11
|
command = "npm run dev"
|
|
7
12
|
port = 3003
|
|
13
|
+
|
|
14
|
+
[[redirects]]
|
|
15
|
+
from = "/_vista/*"
|
|
16
|
+
to = "/_vista/:splat"
|
|
17
|
+
status = 200
|
|
18
|
+
|
|
19
|
+
[[redirects]]
|
|
20
|
+
from = "/*"
|
|
21
|
+
to = "/.netlify/functions/ssr"
|
|
22
|
+
status = 200
|
|
@@ -1,16 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 2,
|
|
3
3
|
"buildCommand": "npm run build",
|
|
4
|
-
"outputDirectory": ".vista",
|
|
5
|
-
"framework": null,
|
|
6
4
|
"installCommand": "npm install --legacy-peer-deps --no-audit --no-fund",
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
{ "handle": "filesystem" },
|
|
10
|
-
{ "src": "^/_vista/(.*)$", "dest": "/$1" },
|
|
11
|
-
{ "src": "^/(?:rsc|_rsc)/?$", "dest": "/static/pages/index.rsc" },
|
|
12
|
-
{ "src": "^/(?:rsc|_rsc)/(.+)$", "dest": "/static/pages/$1.rsc" },
|
|
13
|
-
{ "src": "^/$", "dest": "/static/pages/index.html" },
|
|
14
|
-
{ "src": "^/(.+)$", "dest": "/static/pages/$1.html" }
|
|
15
|
-
]
|
|
5
|
+
"framework": null,
|
|
6
|
+
"devCommand": "npm run dev"
|
|
16
7
|
}
|
|
@@ -1,3 +1,19 @@
|
|
|
1
1
|
name = "my-vista-app"
|
|
2
|
-
compatibility_date = "
|
|
3
|
-
|
|
2
|
+
compatibility_date = "2026-09-20"
|
|
3
|
+
main = ".vista/deploy/cloudflare/worker.js"
|
|
4
|
+
|
|
5
|
+
[vars]
|
|
6
|
+
VISTA_RUNTIME = "standalone"
|
|
7
|
+
|
|
8
|
+
[[containers]]
|
|
9
|
+
class_name = "VistaSSR"
|
|
10
|
+
image = "./Dockerfile"
|
|
11
|
+
max_instances = 4
|
|
12
|
+
|
|
13
|
+
[[durable_objects.bindings]]
|
|
14
|
+
name = "VISTA_SSR"
|
|
15
|
+
class_name = "VistaSSR"
|
|
16
|
+
|
|
17
|
+
[[migrations]]
|
|
18
|
+
tag = "v1"
|
|
19
|
+
new_sqlite_classes = ["VistaSSR"]
|