create-vista-app 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/bin/vista.js +731 -0
- package/index.d.ts +4 -0
- package/index.js +3 -0
- package/package.json +40 -0
- package/src/exports/font/google.d.ts +6 -0
- package/src/exports/font/google.js +45 -0
- package/src/exports/image.d.ts +1 -0
- package/src/exports/image.js +1 -0
- package/src/exports/link.d.ts +3 -0
- package/src/exports/link.js +2 -0
- package/templates/default/.vscode/settings.json +5 -0
- package/templates/default/_gitignore +103 -0
- package/templates/default/app/globals.css +26 -0
- package/templates/default/app/index.tsx +24 -0
- package/templates/default/app/layout.tsx +34 -0
- package/templates/default/package.json +27 -0
- package/templates/default/public/favicon.ico +0 -0
- package/templates/default/public/vista.svg +1 -0
- package/templates/default/tsconfig.json +25 -0
- package/templates/default/tsconfig.node.json +10 -0
- package/templates/default/vista.config.ts +41 -0
- package/tsconfig.json +21 -0
package/bin/vista.js
ADDED
|
@@ -0,0 +1,731 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { createServer, createLogger } from 'vite';
|
|
4
|
+
import pc from 'picocolors';
|
|
5
|
+
import prompts from 'prompts';
|
|
6
|
+
|
|
7
|
+
import fs from 'fs';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
import { fileURLToPath } from 'url';
|
|
10
|
+
import { spawnSync } from 'child_process';
|
|
11
|
+
import http from 'http';
|
|
12
|
+
import { Transform } from 'stream';
|
|
13
|
+
|
|
14
|
+
import react from '@vitejs/plugin-react';
|
|
15
|
+
import tailwindnorm from '@tailwindcss/vite';
|
|
16
|
+
import { vistaPlugin } from '@vista/core/plugin';
|
|
17
|
+
|
|
18
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
19
|
+
|
|
20
|
+
const args = process.argv.slice(2);
|
|
21
|
+
const command = args[0] || 'dev';
|
|
22
|
+
const targetDirArg = args[1]; // Removed default '.' to rely on prompt if creating
|
|
23
|
+
|
|
24
|
+
// Helper: Find all CSS files in app directory
|
|
25
|
+
function findCssFiles(dir, fileList = []) {
|
|
26
|
+
if (!fs.existsSync(dir)) return fileList;
|
|
27
|
+
|
|
28
|
+
const files = fs.readdirSync(dir);
|
|
29
|
+
files.forEach(file => {
|
|
30
|
+
const filePath = path.join(dir, file);
|
|
31
|
+
const stat = fs.statSync(filePath);
|
|
32
|
+
if (stat.isDirectory()) {
|
|
33
|
+
findCssFiles(filePath, fileList);
|
|
34
|
+
} else {
|
|
35
|
+
if (file.endsWith('.css')) {
|
|
36
|
+
const root = process.cwd();
|
|
37
|
+
let relativePath = path.relative(root, filePath).replace(/\\/g, '/');
|
|
38
|
+
if (!relativePath.startsWith('/')) relativePath = '/' + relativePath;
|
|
39
|
+
fileList.push(relativePath);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
return fileList;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Helper: Generate Manifest and Types
|
|
47
|
+
function generateManifest(root) {
|
|
48
|
+
const appDir = path.join(root, 'app');
|
|
49
|
+
const manifestPath = path.join(root, '.vista', 'manifest.json');
|
|
50
|
+
const typesDir = path.join(root, '.vista', 'types');
|
|
51
|
+
const routesTypePath = path.join(typesDir, 'routes.d.ts');
|
|
52
|
+
|
|
53
|
+
if (!fs.existsSync(appDir)) return;
|
|
54
|
+
if (!fs.existsSync(path.dirname(manifestPath))) fs.mkdirSync(path.dirname(manifestPath), { recursive: true });
|
|
55
|
+
if (!fs.existsSync(typesDir)) fs.mkdirSync(typesDir, { recursive: true });
|
|
56
|
+
|
|
57
|
+
const routes = [];
|
|
58
|
+
|
|
59
|
+
function scan(dir, baseRoute = '') {
|
|
60
|
+
const files = fs.readdirSync(dir);
|
|
61
|
+
files.forEach(file => {
|
|
62
|
+
const filePath = path.join(dir, file);
|
|
63
|
+
const stat = fs.statSync(filePath);
|
|
64
|
+
|
|
65
|
+
if (stat.isDirectory()) {
|
|
66
|
+
scan(filePath, `${baseRoute}/${file}`);
|
|
67
|
+
} else if (file === 'index.tsx') {
|
|
68
|
+
let route = baseRoute || '/';
|
|
69
|
+
if (route === '') route = '/';
|
|
70
|
+
routes.push(route);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
scan(appDir);
|
|
76
|
+
|
|
77
|
+
const manifest = {
|
|
78
|
+
version: 1,
|
|
79
|
+
routes: routes.reduce((acc, route) => {
|
|
80
|
+
acc[route] = {
|
|
81
|
+
file: `/app${route === '/' ? '' : route}/index.tsx`
|
|
82
|
+
};
|
|
83
|
+
return acc;
|
|
84
|
+
}, {})
|
|
85
|
+
};
|
|
86
|
+
fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
|
|
87
|
+
|
|
88
|
+
const routeUnion = routes.map(r => `'${r}'`).join(' | ') || 'string';
|
|
89
|
+
const typeContent = `
|
|
90
|
+
declare module 'vista' {
|
|
91
|
+
export type AppRoute = ${routeUnion};
|
|
92
|
+
}
|
|
93
|
+
`;
|
|
94
|
+
fs.writeFileSync(routesTypePath, typeContent);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Helper: Find available port
|
|
98
|
+
const findAvailablePort = async (startPort) => {
|
|
99
|
+
const net = await import('net');
|
|
100
|
+
return new Promise((resolve, reject) => {
|
|
101
|
+
const server = net.default.createServer();
|
|
102
|
+
server.unref();
|
|
103
|
+
server.on('error', (err) => {
|
|
104
|
+
if (err.code === 'EADDRINUSE') {
|
|
105
|
+
resolve(findAvailablePort(startPort + 1));
|
|
106
|
+
} else {
|
|
107
|
+
reject(err);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
server.listen(startPort, () => {
|
|
111
|
+
server.close(() => {
|
|
112
|
+
resolve(startPort);
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
async function startDev() {
|
|
120
|
+
const logger = createLogger('info', { prefix: '[vista]' });
|
|
121
|
+
|
|
122
|
+
const originalInfo = logger.info;
|
|
123
|
+
const originalWarn = logger.warn;
|
|
124
|
+
const originalError = logger.error;
|
|
125
|
+
|
|
126
|
+
const sanitizeString = (str) => {
|
|
127
|
+
return str
|
|
128
|
+
.replace(/vite:/g, 'vista:')
|
|
129
|
+
.replace(/Vite/g, 'Vista')
|
|
130
|
+
.replace(/vite\s/g, 'vista ');
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
const sanitize = (msg) => {
|
|
134
|
+
if (typeof msg === 'string') {
|
|
135
|
+
if (msg.includes('Failed to parse JSON file')) return '';
|
|
136
|
+
return sanitizeString(msg);
|
|
137
|
+
}
|
|
138
|
+
if (msg instanceof Error || (typeof msg === 'object' && msg !== null)) {
|
|
139
|
+
if (msg.message && msg.message.includes('Failed to parse JSON file')) return '';
|
|
140
|
+
if (msg.message) msg.message = sanitizeString(msg.message);
|
|
141
|
+
if (msg.stack) msg.stack = sanitizeString(msg.stack);
|
|
142
|
+
if (msg.plugin) msg.plugin = sanitizeString(msg.plugin);
|
|
143
|
+
if (msg.id) msg.id = sanitizeString(msg.id);
|
|
144
|
+
return msg;
|
|
145
|
+
}
|
|
146
|
+
return msg;
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
logger.info = (msg, options) => {
|
|
150
|
+
const sanitized = sanitize(msg);
|
|
151
|
+
if (sanitized) originalInfo(sanitized, options);
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
logger.warn = (msg, options) => {
|
|
155
|
+
const sanitized = sanitize(msg);
|
|
156
|
+
if (sanitized) originalWarn(sanitized, options);
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
logger.warnOnce = (msg, options) => {
|
|
160
|
+
const sanitized = sanitize(msg);
|
|
161
|
+
if (sanitized) originalWarn(sanitized, options);
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
logger.error = (msg, options) => {
|
|
165
|
+
const sanitized = sanitize(msg);
|
|
166
|
+
if (sanitized) originalError(sanitized, options);
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
const logRequest = (url) => {
|
|
170
|
+
console.log(` ${pc.white('•')} ${pc.cyan('compiling')} ${pc.dim(url)} ...`);
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
const logSuccess = (url, duration, status = 200) => {
|
|
174
|
+
if (status === 404) {
|
|
175
|
+
console.log(` ${pc.red('⨯')} ${pc.red('404')} ${pc.dim(url)} ${pc.red('no page found')} in ${pc.bold(duration + 'ms')}`);
|
|
176
|
+
} else {
|
|
177
|
+
console.log(` ${pc.green('✓')} ${pc.green('compiled')} ${pc.dim(url)} in ${pc.bold(duration + 'ms')} ${pc.dim('(200)')}`);
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
try {
|
|
182
|
+
const root = process.cwd();
|
|
183
|
+
|
|
184
|
+
// Ensure .vista folder exists & Generate Manifest
|
|
185
|
+
const dotVista = path.resolve(root, '.vista');
|
|
186
|
+
if (!fs.existsSync(dotVista)) {
|
|
187
|
+
fs.mkdirSync(dotVista);
|
|
188
|
+
}
|
|
189
|
+
generateManifest(root);
|
|
190
|
+
|
|
191
|
+
// Find a free port
|
|
192
|
+
const port = await findAvailablePort(5173);
|
|
193
|
+
|
|
194
|
+
const express = (await import('express')).default;
|
|
195
|
+
const app = express();
|
|
196
|
+
const httpServer = http.createServer(app);
|
|
197
|
+
|
|
198
|
+
const server = await createServer({
|
|
199
|
+
configFile: 'vista.config.ts',
|
|
200
|
+
root,
|
|
201
|
+
server: {
|
|
202
|
+
middlewareMode: true,
|
|
203
|
+
ws: true,
|
|
204
|
+
hmr: { server: httpServer }
|
|
205
|
+
},
|
|
206
|
+
appType: 'custom',
|
|
207
|
+
plugins: [react(), tailwindnorm(), vistaPlugin()],
|
|
208
|
+
customLogger: logger,
|
|
209
|
+
cacheDir: '.vista/cache',
|
|
210
|
+
resolve: {
|
|
211
|
+
dedupe: ['react', 'react-dom'],
|
|
212
|
+
alias: {
|
|
213
|
+
// Dev Fix: Point @vista/core to source to enable HMR/Fast Refresh for framework internals
|
|
214
|
+
'@vista/core': path.resolve(__dirname, '../../core/src')
|
|
215
|
+
}
|
|
216
|
+
},
|
|
217
|
+
optimizeDeps: {
|
|
218
|
+
include: ['react', 'react-dom', 'lucide-react', 'react-shaders']
|
|
219
|
+
},
|
|
220
|
+
ssr: {
|
|
221
|
+
noExternal: ['lucide-react', 'react-shaders']
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
app.use(server.middlewares);
|
|
226
|
+
|
|
227
|
+
app.use(async (req, res, next) => {
|
|
228
|
+
const url = req.originalUrl;
|
|
229
|
+
const start = Date.now();
|
|
230
|
+
|
|
231
|
+
if (req.method === 'GET' && !url.includes('/@') && !url.includes('favicon')) {
|
|
232
|
+
logRequest(url);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Check route existence for 404 logic
|
|
236
|
+
const cleanPath = url === '/' ? '/' : url.replace(/\/$/, '');
|
|
237
|
+
const pagePath = path.join(root, 'app', cleanPath === '/' ? '' : cleanPath, 'index.tsx');
|
|
238
|
+
const exists = fs.existsSync(pagePath);
|
|
239
|
+
const status = exists ? 200 : 404;
|
|
240
|
+
|
|
241
|
+
try {
|
|
242
|
+
const clientEntryPath = path.resolve(__dirname, '../../core/src/entry-client.tsx').replace(/\\/g, '/');
|
|
243
|
+
|
|
244
|
+
// Prepare Bootstrap Modules (Vite Client + Entry Client + Globals CSS)
|
|
245
|
+
const bootstrapModules = [
|
|
246
|
+
'/@vite/client',
|
|
247
|
+
`/@fs/${clientEntryPath}`
|
|
248
|
+
];
|
|
249
|
+
|
|
250
|
+
// Zero-Config CSS: Auto-inject globals.css if it exists
|
|
251
|
+
const globalsCssPath = path.join(root, 'app', 'globals.css');
|
|
252
|
+
const stylesheets = [];
|
|
253
|
+
if (fs.existsSync(globalsCssPath)) {
|
|
254
|
+
// In Dev, we inject the source file directly. Vite Middleware handles the transformation.
|
|
255
|
+
// bootstrapModules.push('/app/globals.css'); // DISABLE: Script-based injection conflicts with React Hydration
|
|
256
|
+
|
|
257
|
+
// ENABLE: React 19 will hoist this link tag correctly.
|
|
258
|
+
// MUST use ?direct to ensure Vite serves raw CSS (not JS module), preventing FOUC.
|
|
259
|
+
stylesheets.push('/app/globals.css?direct');
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Construct React Refresh Preamble Content
|
|
263
|
+
const preamble = `
|
|
264
|
+
import RefreshRuntime from "/@react-refresh";
|
|
265
|
+
RefreshRuntime.injectIntoGlobalHook(window);
|
|
266
|
+
window.$RefreshReg$ = () => {};
|
|
267
|
+
window.$RefreshSig$ = () => (type) => type;
|
|
268
|
+
window.__vite_plugin_react_preamble_installed__ = true;
|
|
269
|
+
`;
|
|
270
|
+
|
|
271
|
+
const { render } = await server.ssrLoadModule('@vista/core/entry-server');
|
|
272
|
+
|
|
273
|
+
// FOUC Fix: Send Link Header to preload CSS immediately
|
|
274
|
+
if (stylesheets.length > 0) {
|
|
275
|
+
const linkHeader = stylesheets.map(href => `<${href}>; rel=preload; as=style`).join(', ');
|
|
276
|
+
res.setHeader('Link', linkHeader);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
let didError = false;
|
|
280
|
+
const stream = await render(url, {
|
|
281
|
+
bootstrapModules,
|
|
282
|
+
stylesheets,
|
|
283
|
+
preamble, // Pass preamble content to App
|
|
284
|
+
onShellReady() {
|
|
285
|
+
res.status(didError ? 500 : status);
|
|
286
|
+
res.set({ 'Content-Type': 'text/html' });
|
|
287
|
+
// res.write('<!DOCTYPE html>'); // REMOVED: Caused double doctype and hydration mismatch
|
|
288
|
+
|
|
289
|
+
// Fix: Use setTimeout to break synchronous shell initialization (TDZ issue)
|
|
290
|
+
// "stream" variable is assigned via await render(...) which might resolve AFTER onShellReady fires synchronously
|
|
291
|
+
setTimeout(() => {
|
|
292
|
+
if (stream) {
|
|
293
|
+
// Disable CLI Injection to prevent Hydration Mismatch (duplicate links)
|
|
294
|
+
// stream.pipe(injectStyles).pipe(res);
|
|
295
|
+
stream.pipe(res);
|
|
296
|
+
} else {
|
|
297
|
+
console.error('Stream was not available even after timeout');
|
|
298
|
+
res.status(500).end();
|
|
299
|
+
}
|
|
300
|
+
}, 0);
|
|
301
|
+
},
|
|
302
|
+
onShellError(err) {
|
|
303
|
+
didError = true;
|
|
304
|
+
logger.error(err);
|
|
305
|
+
res.status(500).send('<!doctype html><p>Server Error</p>');
|
|
306
|
+
},
|
|
307
|
+
onError(err) {
|
|
308
|
+
didError = true;
|
|
309
|
+
logger.error(err);
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
if (req.method === 'GET' && !url.includes('/@') && !url.includes('favicon')) {
|
|
314
|
+
logSuccess(url, Date.now() - start, status);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
} catch (e) {
|
|
318
|
+
server.ssrFixStacktrace(e);
|
|
319
|
+
console.error(e);
|
|
320
|
+
res.status(500).end(e.message);
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
// Helper to get network address
|
|
325
|
+
const getNetworkAddress = async () => {
|
|
326
|
+
const { networkInterfaces } = await import('os');
|
|
327
|
+
const nets = networkInterfaces();
|
|
328
|
+
for (const name of Object.keys(nets)) {
|
|
329
|
+
for (const net of nets[name]) {
|
|
330
|
+
if (net.family === 'IPv4' && !net.internal) {
|
|
331
|
+
return net.address;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
return null;
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
httpServer.listen(port, async () => {
|
|
339
|
+
console.log(` ${pc.green('➜')} ${pc.bold('Vista Server')} running at http://localhost:${port}`);
|
|
340
|
+
|
|
341
|
+
const networkAddress = await getNetworkAddress();
|
|
342
|
+
if (networkAddress) {
|
|
343
|
+
console.log(` ${pc.green('➜')} ${pc.bold('Network')}: http://${networkAddress}:${port}`);
|
|
344
|
+
}
|
|
345
|
+
if (port !== 5173) {
|
|
346
|
+
console.log(` ${pc.yellow('➜')} ${pc.yellow('Port 5173 was in use, using ' + port + ' instead')}`);
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
} catch (e) {
|
|
351
|
+
console.error(pc.red('failed to start server'), e);
|
|
352
|
+
process.exit(1);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
async function build() {
|
|
357
|
+
console.log(pc.cyan('Building for production...'));
|
|
358
|
+
const { build: viteBuild } = await import('vite');
|
|
359
|
+
const root = process.cwd();
|
|
360
|
+
const dist = path.resolve(root, '.vista');
|
|
361
|
+
|
|
362
|
+
generateManifest(root);
|
|
363
|
+
|
|
364
|
+
// Create a dummy HTML for Vite to crawl dependencies, but we won't use it for serving.
|
|
365
|
+
const htmlContent = `
|
|
366
|
+
<!DOCTYPE html>
|
|
367
|
+
<html lang="en">
|
|
368
|
+
<head>
|
|
369
|
+
<meta charset="UTF-8" />
|
|
370
|
+
</head>
|
|
371
|
+
<body>
|
|
372
|
+
<script type="module" src="@vista/core/entry-client"></script>
|
|
373
|
+
</body>
|
|
374
|
+
</html>`;
|
|
375
|
+
|
|
376
|
+
fs.writeFileSync(path.resolve(root, 'index.html'), htmlContent);
|
|
377
|
+
|
|
378
|
+
try {
|
|
379
|
+
console.log(pc.green('✓ Building Client...'));
|
|
380
|
+
await viteBuild({
|
|
381
|
+
root,
|
|
382
|
+
configFile: 'vista.config.ts',
|
|
383
|
+
build: {
|
|
384
|
+
outDir: path.resolve(dist, 'client'),
|
|
385
|
+
emptyOutDir: true,
|
|
386
|
+
manifest: true, // Generate manifest for asset mapping
|
|
387
|
+
rollupOptions: {}
|
|
388
|
+
},
|
|
389
|
+
plugins: [react(), tailwindnorm(), vistaPlugin()]
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
console.log(pc.green('✓ Building Server...'));
|
|
393
|
+
await viteBuild({
|
|
394
|
+
root,
|
|
395
|
+
configFile: 'vista.config.ts',
|
|
396
|
+
build: {
|
|
397
|
+
ssr: true,
|
|
398
|
+
outDir: path.resolve(dist, 'server'),
|
|
399
|
+
emptyOutDir: true,
|
|
400
|
+
rollupOptions: {
|
|
401
|
+
input: '@vista/core/entry-server'
|
|
402
|
+
}
|
|
403
|
+
},
|
|
404
|
+
plugins: [react(), tailwindnorm(), vistaPlugin()]
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
} catch (e) {
|
|
408
|
+
console.error(pc.red('Build failed:'), e);
|
|
409
|
+
process.exit(1);
|
|
410
|
+
} finally {
|
|
411
|
+
if (fs.existsSync(path.resolve(root, 'index.html'))) {
|
|
412
|
+
fs.unlinkSync(path.resolve(root, 'index.html'));
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
async function start() {
|
|
418
|
+
console.log(pc.cyan('Starting production server...'));
|
|
419
|
+
const express = (await import('express')).default;
|
|
420
|
+
const compression = (await import('compression')).default;
|
|
421
|
+
|
|
422
|
+
const app = express();
|
|
423
|
+
app.use(compression());
|
|
424
|
+
|
|
425
|
+
const root = process.cwd();
|
|
426
|
+
const dist = path.resolve(root, '.vista');
|
|
427
|
+
|
|
428
|
+
if (!fs.existsSync(dist)) {
|
|
429
|
+
console.error(pc.red('Build directory (.vista) not found. Run `vista build` first.'));
|
|
430
|
+
process.exit(1);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
app.use(express.static(path.resolve(dist, 'client'), { index: false }));
|
|
434
|
+
|
|
435
|
+
app.use(async (req, res) => {
|
|
436
|
+
try {
|
|
437
|
+
console.log('Handling request:', req.url);
|
|
438
|
+
// Fix connection refused failure by importing correct path format
|
|
439
|
+
const serverEntryPath = path.resolve(dist, 'server/entry-server.js');
|
|
440
|
+
const importPath = process.platform === 'win32' ? 'file://' + serverEntryPath.replace(/\\/g, '/') : serverEntryPath;
|
|
441
|
+
|
|
442
|
+
console.log('Importing server entry:', importPath);
|
|
443
|
+
const serverEntry = await import(importPath);
|
|
444
|
+
const { render } = serverEntry;
|
|
445
|
+
console.log('Render function loaded');
|
|
446
|
+
|
|
447
|
+
let didError = false;
|
|
448
|
+
|
|
449
|
+
// In prod, we need to map the entry-client to the hashed file
|
|
450
|
+
// For now, simpler approach: we rely on manifest or known entry?
|
|
451
|
+
// The template index.html used @vista/core/entry-client.
|
|
452
|
+
// Vite build produces a manifest.json.
|
|
453
|
+
// Let's assume standard behavior for now:
|
|
454
|
+
// bootstrapModules: ['/entry-client-hash.js']
|
|
455
|
+
// But we don't have the hash easily here without parsing manifest.
|
|
456
|
+
|
|
457
|
+
// Simplified Prod: Just pipe. The user's layout likely doesn't have the script tags for prod...
|
|
458
|
+
// Wait, in Prod, the layout is just HTML. The CLIENT SCRIPT needs to be injected.
|
|
459
|
+
// We need to read manifest.json to find the entry chunk.
|
|
460
|
+
|
|
461
|
+
let manifest;
|
|
462
|
+
try {
|
|
463
|
+
const manifestPath = path.resolve(dist, 'client/.vite/manifest.json');
|
|
464
|
+
manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8'));
|
|
465
|
+
} catch (e) {
|
|
466
|
+
fs.writeFileSync('debug.txt', `Manifest Error: ${e.message}\nPath: ${path.resolve(dist, 'client/.vite/manifest.json')}`);
|
|
467
|
+
throw e;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
// The manifest path key might be relative to project root or source root.
|
|
471
|
+
// Vite defaults: "node_modules/@vista/core/src/entry-client.tsx" if externalized?
|
|
472
|
+
// Or just "src/entry-client.tsx" if local.
|
|
473
|
+
// Let's print keys if fails.
|
|
474
|
+
|
|
475
|
+
let entryKey = Object.keys(manifest).find(key => manifest[key].isEntry);
|
|
476
|
+
if (!entryKey) {
|
|
477
|
+
// Fallback: search for something ending in entry-client
|
|
478
|
+
entryKey = Object.keys(manifest).find(key => key.includes('entry-client'));
|
|
479
|
+
}
|
|
480
|
+
const entryScript = entryKey ? `/${manifest[entryKey].file}` : null;
|
|
481
|
+
|
|
482
|
+
// Production CSS Injection
|
|
483
|
+
// In dev we scan; in prod we trust Vite's manifest OR we scan dist/client/assets.
|
|
484
|
+
// Vite normally injects CSS for the entry chunk automatically if we use the manifest correctly.
|
|
485
|
+
// However, our "Clean Layout" + Stream approach means we might need to force it.
|
|
486
|
+
// Let's replicate the Dev logic but using the built assets.
|
|
487
|
+
|
|
488
|
+
const stylesheets = [];
|
|
489
|
+
|
|
490
|
+
// 1. Try to find the built CSS for the app
|
|
491
|
+
const clientDir = path.resolve(dist, 'client');
|
|
492
|
+
const assetsDir = path.join(clientDir, 'assets');
|
|
493
|
+
if (fs.existsSync(assetsDir)) {
|
|
494
|
+
const files = fs.readdirSync(assetsDir);
|
|
495
|
+
files.forEach(file => {
|
|
496
|
+
if (file.endsWith('.css')) {
|
|
497
|
+
stylesheets.push(`/assets/${file}`);
|
|
498
|
+
}
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// 2. Add Link Header for Preload
|
|
503
|
+
if (stylesheets.length > 0) {
|
|
504
|
+
const linkHeader = stylesheets.map(href => `<${href}>; rel=preload; as=style`).join(', ');
|
|
505
|
+
res.setHeader('Link', linkHeader);
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
const stream = await render(req.originalUrl, {
|
|
509
|
+
bootstrapModules,
|
|
510
|
+
onShellReady() {
|
|
511
|
+
res.statusCode = didError ? 500 : 200;
|
|
512
|
+
res.setHeader('Content-type', 'text/html');
|
|
513
|
+
// res.write('<!DOCTYPE html>'); // REMOVED: Caused double doctype
|
|
514
|
+
|
|
515
|
+
const injectStyles = new Transform({
|
|
516
|
+
transform(chunk, encoding, callback) {
|
|
517
|
+
const chunkString = chunk.toString();
|
|
518
|
+
const bodyMatch = chunkString.match(/<body/i);
|
|
519
|
+
if (bodyMatch && stylesheets.length > 0) {
|
|
520
|
+
const links = stylesheets.map(href => `<link rel="stylesheet" href="${href}">`).join('');
|
|
521
|
+
const injected = chunkString.replace(/<body/i, `<head>${links}</head><body`);
|
|
522
|
+
this.push(injected);
|
|
523
|
+
} else {
|
|
524
|
+
this.push(chunk);
|
|
525
|
+
}
|
|
526
|
+
callback();
|
|
527
|
+
}
|
|
528
|
+
});
|
|
529
|
+
|
|
530
|
+
stream.pipe(injectStyles).pipe(res);
|
|
531
|
+
},
|
|
532
|
+
onError(err) {
|
|
533
|
+
didError = true;
|
|
534
|
+
console.error(err);
|
|
535
|
+
}
|
|
536
|
+
});
|
|
537
|
+
} catch (e) {
|
|
538
|
+
fs.writeFileSync('debug.txt', `SSR Crash: ${e.message}\nStack: ${e.stack}\n`, { flag: 'a' });
|
|
539
|
+
console.error('SSR Error:', e);
|
|
540
|
+
res.status(500).end('Internal Server Error');
|
|
541
|
+
}
|
|
542
|
+
});
|
|
543
|
+
|
|
544
|
+
const port = process.env.PORT || 3000;
|
|
545
|
+
app.listen(port, () => {
|
|
546
|
+
console.log(` ${pc.green('➜')} ${pc.bold('Vista Server')} running at http://localhost:${port}`);
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
async function create() {
|
|
551
|
+
const templateDir = path.resolve(__dirname, '../templates/default');
|
|
552
|
+
|
|
553
|
+
// Interactive Prompts
|
|
554
|
+
let projectName = targetDirArg;
|
|
555
|
+
if (!projectName || projectName === '.') {
|
|
556
|
+
const response = await prompts({
|
|
557
|
+
type: 'text',
|
|
558
|
+
name: 'projectName',
|
|
559
|
+
message: 'What is your project name?',
|
|
560
|
+
initial: 'my-vista-app'
|
|
561
|
+
});
|
|
562
|
+
projectName = response.projectName;
|
|
563
|
+
if (!projectName) {
|
|
564
|
+
console.log(pc.red('Operation cancelled'));
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
const { useTypeScript, useTailwind } = await prompts([
|
|
570
|
+
{
|
|
571
|
+
type: 'confirm',
|
|
572
|
+
name: 'useTypeScript',
|
|
573
|
+
message: 'Use TypeScript?',
|
|
574
|
+
initial: true
|
|
575
|
+
},
|
|
576
|
+
{
|
|
577
|
+
type: 'confirm',
|
|
578
|
+
name: 'useTailwind',
|
|
579
|
+
message: 'Use Tailwind CSS?',
|
|
580
|
+
initial: true
|
|
581
|
+
}
|
|
582
|
+
]);
|
|
583
|
+
|
|
584
|
+
if (useTypeScript === undefined || useTailwind === undefined) {
|
|
585
|
+
console.log(pc.red('Operation cancelled'));
|
|
586
|
+
return;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
const projectDir = path.resolve(process.cwd(), projectName);
|
|
590
|
+
|
|
591
|
+
console.log(pc.cyan(`\nCreating Vista app in ${projectDir}...`));
|
|
592
|
+
|
|
593
|
+
if (!fs.existsSync(projectDir)) {
|
|
594
|
+
fs.mkdirSync(projectDir, { recursive: true });
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
fs.cpSync(templateDir, projectDir, { recursive: true });
|
|
598
|
+
|
|
599
|
+
const gitignorePath = path.join(projectDir, '_gitignore');
|
|
600
|
+
if (fs.existsSync(gitignorePath)) {
|
|
601
|
+
fs.renameSync(gitignorePath, path.join(projectDir, '.gitignore'));
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
// Handle Tailwind Selection
|
|
605
|
+
if (!useTailwind) {
|
|
606
|
+
// 1. Remove @tailwindcss/vite from package.json
|
|
607
|
+
const pkgPath = path.join(projectDir, 'package.json');
|
|
608
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
609
|
+
if (pkg.dependencies && pkg.dependencies.tailwindcss) delete pkg.dependencies.tailwindcss;
|
|
610
|
+
if (pkg.dependencies && pkg.dependencies['@tailwindcss/vite']) delete pkg.dependencies['@tailwindcss/vite'];
|
|
611
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));
|
|
612
|
+
|
|
613
|
+
// 2. Remove plugin from vista.config.ts
|
|
614
|
+
const configPath = path.join(projectDir, 'vista.config.ts');
|
|
615
|
+
let config = fs.readFileSync(configPath, 'utf-8');
|
|
616
|
+
config = config.replace(/import tailwindcss from '@tailwindcss\/vite';\n/, '');
|
|
617
|
+
config = config.replace(/plugins: \[react\(\), tailwindcss\(\)\],/, 'plugins: [react()],');
|
|
618
|
+
fs.writeFileSync(configPath, config);
|
|
619
|
+
|
|
620
|
+
// 3. Clear globals.css
|
|
621
|
+
const cssPath = path.join(projectDir, 'app/globals.css');
|
|
622
|
+
if (fs.existsSync(cssPath)) {
|
|
623
|
+
fs.writeFileSync(cssPath, `
|
|
624
|
+
:root {
|
|
625
|
+
--foreground-rgb: 0, 0, 0;
|
|
626
|
+
--background-start-rgb: 214, 219, 220;
|
|
627
|
+
--background-end-rgb: 255, 255, 255;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
@media (prefers-color-scheme: dark) {
|
|
631
|
+
:root {
|
|
632
|
+
--foreground-rgb: 255, 255, 255;
|
|
633
|
+
--background-start-rgb: 0, 0, 0;
|
|
634
|
+
--background-end-rgb: 0, 0, 0;
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
body {
|
|
639
|
+
color: rgb(var(--foreground-rgb));
|
|
640
|
+
background: linear-gradient(
|
|
641
|
+
to bottom,
|
|
642
|
+
transparent,
|
|
643
|
+
rgb(var(--background-end-rgb))
|
|
644
|
+
)
|
|
645
|
+
rgb(var(--background-start-rgb));
|
|
646
|
+
font-family: var(--font-geist-sans), Arial, Helvetica, sans-serif;
|
|
647
|
+
}
|
|
648
|
+
`);
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
// Handle TypeScript Selection (Basic support)
|
|
653
|
+
if (!useTypeScript) {
|
|
654
|
+
console.log(pc.yellow('Note: TypeScript is recommended for Vista. Converting to JavaScript... (Experimental)'));
|
|
655
|
+
|
|
656
|
+
// Rename tsconfig.json -> jsconfig.json
|
|
657
|
+
const tsConfigPath = path.join(projectDir, 'tsconfig.json');
|
|
658
|
+
if (fs.existsSync(tsConfigPath)) {
|
|
659
|
+
fs.renameSync(tsConfigPath, path.join(projectDir, 'jsconfig.json'));
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
// Rename files (simple renaming, logic conversion not fully supported but unnecessary for basic template)
|
|
663
|
+
const renameExt = (dir) => {
|
|
664
|
+
const items = fs.readdirSync(dir);
|
|
665
|
+
items.forEach(item => {
|
|
666
|
+
const fullPath = path.join(dir, item);
|
|
667
|
+
const stat = fs.statSync(fullPath);
|
|
668
|
+
if (stat.isDirectory()) {
|
|
669
|
+
renameExt(fullPath);
|
|
670
|
+
} else if (item.endsWith('.tsx')) {
|
|
671
|
+
fs.renameSync(fullPath, fullPath.replace('.tsx', '.jsx'));
|
|
672
|
+
} else if (item.endsWith('.ts')) {
|
|
673
|
+
fs.renameSync(fullPath, fullPath.replace('.ts', '.js'));
|
|
674
|
+
}
|
|
675
|
+
});
|
|
676
|
+
};
|
|
677
|
+
renameExt(projectDir);
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
const readmePath = path.join(projectDir, 'README.md');
|
|
681
|
+
const readmeContent = `# ${projectName}
|
|
682
|
+
|
|
683
|
+
Created with [Vista](https://github.com/vista-js/vista).
|
|
684
|
+
|
|
685
|
+
## Getting Started
|
|
686
|
+
|
|
687
|
+
Run the development server:
|
|
688
|
+
|
|
689
|
+
\`\`\`bash
|
|
690
|
+
npm run dev
|
|
691
|
+
\`\`\`
|
|
692
|
+
|
|
693
|
+
Open [http://localhost:5173](http://localhost:5173) with your browser to see the result.
|
|
694
|
+
`;
|
|
695
|
+
fs.writeFileSync(readmePath, readmeContent);
|
|
696
|
+
|
|
697
|
+
console.log(pc.green('\nInitializing git repository...'));
|
|
698
|
+
try {
|
|
699
|
+
spawnSync('git', ['init'], { cwd: projectDir, stdio: 'ignore' });
|
|
700
|
+
} catch (e) {
|
|
701
|
+
console.warn(pc.yellow('Failed to initialize git repository. Do you have git installed?'));
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
console.log(pc.green('\nInstalling dependencies...'));
|
|
705
|
+
|
|
706
|
+
const installResult = spawnSync('npm', ['install'], {
|
|
707
|
+
cwd: projectDir,
|
|
708
|
+
stdio: 'inherit',
|
|
709
|
+
shell: true,
|
|
710
|
+
});
|
|
711
|
+
|
|
712
|
+
if (installResult.error || installResult.status !== 0) {
|
|
713
|
+
console.error(pc.red('Failed to install dependencies. Please run npm install manually.'));
|
|
714
|
+
} else {
|
|
715
|
+
console.log(pc.green('\nDone! Now run:\n'));
|
|
716
|
+
console.log(` cd ${projectName}`);
|
|
717
|
+
console.log(' npm run dev\n');
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
if (command === 'dev') {
|
|
722
|
+
startDev();
|
|
723
|
+
} else if (command === 'create') {
|
|
724
|
+
create();
|
|
725
|
+
} else if (command === 'build') {
|
|
726
|
+
build();
|
|
727
|
+
} else if (command === 'start') {
|
|
728
|
+
start();
|
|
729
|
+
} else {
|
|
730
|
+
console.log(`Command ${command} not implemented yet.`);
|
|
731
|
+
}
|
package/index.d.ts
ADDED
package/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-vista-app",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"bin": {
|
|
6
|
+
"vista": "./bin/vista.js"
|
|
7
|
+
},
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./index.js",
|
|
10
|
+
"./image": "./src/exports/image.js",
|
|
11
|
+
"./font/google": {
|
|
12
|
+
"types": "./src/exports/font/google.d.ts",
|
|
13
|
+
"default": "./src/exports/font/google.js"
|
|
14
|
+
},
|
|
15
|
+
"./link": {
|
|
16
|
+
"types": "./src/exports/link.d.ts",
|
|
17
|
+
"default": "./src/exports/link.js"
|
|
18
|
+
},
|
|
19
|
+
"./package.json": "./package.json"
|
|
20
|
+
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"dev": "tsc --watch",
|
|
23
|
+
"build": "tsc"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@tailwindcss/vite": "^4.0.0-beta.9",
|
|
27
|
+
"@vista/core": "^0.0.2",
|
|
28
|
+
"@vitejs/plugin-react": "^5.1.2",
|
|
29
|
+
"compression": "^1.8.1",
|
|
30
|
+
"express": "^5.2.1",
|
|
31
|
+
"picocolors": "^1.0.0",
|
|
32
|
+
"prompts": "^2.4.2",
|
|
33
|
+
"tailwindcss": "^4.1.18",
|
|
34
|
+
"vite": "^5.0.0"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/node": "^20.0.0",
|
|
38
|
+
"typescript": "^5.0.0"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
|
|
2
|
+
export declare function Inter(options?: any): { className: string; style: { fontFamily: string }; variable: string };
|
|
3
|
+
export declare function Poppins(options?: any): { className: string; style: { fontFamily: string }; variable: string };
|
|
4
|
+
export declare function Roboto(options?: any): { className: string; style: { fontFamily: string }; variable: string };
|
|
5
|
+
export declare function Geist(options?: any): { className: string; style: { fontFamily: string }; variable: string };
|
|
6
|
+
export declare function Geist_Mono(options?: any): { className: string; style: { fontFamily: string }; variable: string };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* Vista Google Fonts Loader
|
|
4
|
+
* Mimics next/font/google
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export function Inter(options) {
|
|
8
|
+
return {
|
|
9
|
+
className: 'font-inter',
|
|
10
|
+
style: { fontFamily: "'Inter', sans-serif" },
|
|
11
|
+
variable: '--font-inter'
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function Poppins(options) {
|
|
16
|
+
return {
|
|
17
|
+
className: 'font-poppins',
|
|
18
|
+
style: { fontFamily: "'Poppins', sans-serif" },
|
|
19
|
+
variable: '--font-poppins'
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function Roboto(options) {
|
|
24
|
+
return {
|
|
25
|
+
className: 'font-roboto',
|
|
26
|
+
style: { fontFamily: "'Roboto', sans-serif" },
|
|
27
|
+
variable: '--font-roboto'
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function Geist(options) {
|
|
32
|
+
return {
|
|
33
|
+
className: 'font-geist-sans',
|
|
34
|
+
style: { fontFamily: "'Geist Sans', sans-serif" },
|
|
35
|
+
variable: '--font-geist-sans'
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function Geist_Mono(options) {
|
|
40
|
+
return {
|
|
41
|
+
className: 'font-geist-mono',
|
|
42
|
+
style: { fontFamily: "'Geist Mono', monospace" },
|
|
43
|
+
variable: '--font-geist-mono'
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Image as default } from '@vista/core';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Image as default } from '@vista/core';
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# Logs
|
|
2
|
+
logs
|
|
3
|
+
*.log
|
|
4
|
+
npm-debug.log*
|
|
5
|
+
yarn-debug.log*
|
|
6
|
+
yarn-error.log*
|
|
7
|
+
pnpm-debug.log*
|
|
8
|
+
lerna-debug.log*
|
|
9
|
+
|
|
10
|
+
# Diagnostic reports (https://nodejs.org/api/report.html)
|
|
11
|
+
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
|
12
|
+
|
|
13
|
+
# Runtime data
|
|
14
|
+
pids
|
|
15
|
+
*.pid
|
|
16
|
+
*.seed
|
|
17
|
+
*.pid.lock
|
|
18
|
+
|
|
19
|
+
# Directory for instrumented libs generated by jscoverage/JSCover
|
|
20
|
+
lib-cov
|
|
21
|
+
|
|
22
|
+
# Coverage directory used by tools like istanbul
|
|
23
|
+
coverage
|
|
24
|
+
*.lcov
|
|
25
|
+
|
|
26
|
+
# nyc test coverage
|
|
27
|
+
.nyc_output
|
|
28
|
+
|
|
29
|
+
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
|
30
|
+
.grunt
|
|
31
|
+
|
|
32
|
+
# Bower dependency directory (https://bower.io/)
|
|
33
|
+
bower_components
|
|
34
|
+
|
|
35
|
+
# node-waf configuration
|
|
36
|
+
.lock-wscript
|
|
37
|
+
|
|
38
|
+
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
|
39
|
+
build/Release
|
|
40
|
+
|
|
41
|
+
# Dependency directories
|
|
42
|
+
node_modules/
|
|
43
|
+
jspm_packages/
|
|
44
|
+
|
|
45
|
+
# TypeScript v1 declaration files
|
|
46
|
+
typings/
|
|
47
|
+
|
|
48
|
+
# TypeScript cache
|
|
49
|
+
*.tsbuildinfo
|
|
50
|
+
|
|
51
|
+
# Optional npm cache directory
|
|
52
|
+
.npm
|
|
53
|
+
|
|
54
|
+
# Optional eslint cache
|
|
55
|
+
.eslintcache
|
|
56
|
+
|
|
57
|
+
# Microbundle cache
|
|
58
|
+
.rpt2_cache/
|
|
59
|
+
.rts2_cache_cjs/
|
|
60
|
+
.rts2_cache_es/
|
|
61
|
+
.rts2_cache_umd/
|
|
62
|
+
|
|
63
|
+
# Optional REPL history
|
|
64
|
+
.node_repl_history
|
|
65
|
+
|
|
66
|
+
# Output of 'npm pack'
|
|
67
|
+
*.tgz
|
|
68
|
+
|
|
69
|
+
# Yarn Integrity file
|
|
70
|
+
.yarn-integrity
|
|
71
|
+
|
|
72
|
+
# dotenv environment variables file
|
|
73
|
+
.env
|
|
74
|
+
.env.test
|
|
75
|
+
|
|
76
|
+
# parcel-bundler cache (https://parceljs.org/)
|
|
77
|
+
.cache
|
|
78
|
+
.parcel-cache
|
|
79
|
+
|
|
80
|
+
# Next.js build output
|
|
81
|
+
.next
|
|
82
|
+
out
|
|
83
|
+
|
|
84
|
+
# Vuepress build output
|
|
85
|
+
.vuepress/dist
|
|
86
|
+
|
|
87
|
+
# Serverless directories
|
|
88
|
+
.serverless/
|
|
89
|
+
|
|
90
|
+
# FuseBox cache
|
|
91
|
+
.fusebox/
|
|
92
|
+
|
|
93
|
+
# DynamoDB Local files
|
|
94
|
+
.dynamodb/
|
|
95
|
+
|
|
96
|
+
# TernJS port file
|
|
97
|
+
.tern-port
|
|
98
|
+
|
|
99
|
+
# Stores VSCode versions used for testing VSCode extensions
|
|
100
|
+
.vscode-test
|
|
101
|
+
|
|
102
|
+
# Vista
|
|
103
|
+
.vista
|
|
@@ -0,0 +1,26 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import Image from 'vista/image';
|
|
2
|
+
|
|
3
|
+
export default function Index() {
|
|
4
|
+
return (
|
|
5
|
+
<main className="flex min-h-screen flex-col items-center justify-center bg-white dark:bg-black transition-colors duration-200">
|
|
6
|
+
<div className="-mt-20 mb-10 relative border border-dashed border-gray-300 dark:border-neutral-700 p-10">
|
|
7
|
+
<div className="absolute -top-0 -left-0 -translate-x-1/2 -translate-y-1/2 w-24 h-24 border border-dashed border-gray-300 dark:border-neutral-700 rounded-full" />
|
|
8
|
+
<div className="absolute -bottom-0 -right-0 translate-x-1/2 translate-y-1/2 w-24 h-24 border border-dashed border-gray-300 dark:border-neutral-700 rounded-full" />
|
|
9
|
+
<Image
|
|
10
|
+
src="/vista.svg"
|
|
11
|
+
alt="Vista Logo"
|
|
12
|
+
width={600}
|
|
13
|
+
height={600}
|
|
14
|
+
className="dark:invert"
|
|
15
|
+
priority
|
|
16
|
+
/>
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
<h1 className="max-w-xs sm:max-w-none text-3xl font-semibold leading-10 tracking-tight text-black dark:text-zinc-50 text-center">
|
|
20
|
+
To get started, edit the index.tsx file.
|
|
21
|
+
</h1>
|
|
22
|
+
</main>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import './globals.css';
|
|
4
|
+
import { Geist, Geist_Mono } from 'vista/font/google';
|
|
5
|
+
|
|
6
|
+
const geistSans = Geist({
|
|
7
|
+
variable: '--font-geist-sans',
|
|
8
|
+
subsets: ['latin'],
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
const geistMono = Geist_Mono({
|
|
12
|
+
variable: '--font-geist-mono',
|
|
13
|
+
subsets: ['latin'],
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
export const metadata = {
|
|
17
|
+
title: 'Vista App',
|
|
18
|
+
description: 'Generated by create-vista-app',
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default function RootLayout({
|
|
22
|
+
children,
|
|
23
|
+
}: Readonly<{
|
|
24
|
+
children: React.ReactNode;
|
|
25
|
+
}>) {
|
|
26
|
+
return (
|
|
27
|
+
<html lang="en">
|
|
28
|
+
<body className={`${geistSans.variable} ${geistMono.variable} antialiased`}>
|
|
29
|
+
<div id="root">{children}</div>
|
|
30
|
+
</body>
|
|
31
|
+
</html>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
|
|
2
|
+
{
|
|
3
|
+
"name": "vista-app",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vista dev",
|
|
8
|
+
"build": "vista build",
|
|
9
|
+
"start": "vista start",
|
|
10
|
+
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
|
11
|
+
"preview": "vite preview"
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@vista/core": "^0.0.2",
|
|
15
|
+
"create-vista-app": "^0.0.1",
|
|
16
|
+
"react": "^18.3.1",
|
|
17
|
+
"react-dom": "^18.3.1"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@types/react": "^18.3.3",
|
|
21
|
+
"@types/react-dom": "^18.2.0",
|
|
22
|
+
"typescript": "^5.4.5",
|
|
23
|
+
"vite": "^5.2.11",
|
|
24
|
+
"@tailwindcss/vite": "^4.0.0-beta.9",
|
|
25
|
+
"tailwindcss": "^4.0.0-beta.9"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1563" zoomAndPan="magnify" viewBox="0 0 1172.25 299.999988" height="400" preserveAspectRatio="xMidYMid meet" version="1.0"><defs><g/><clipPath id="f9753e23e9"><path d="M 0 0.0976562 L 1171.5 0.0976562 L 1171.5 299.902344 L 0 299.902344 Z M 0 0.0976562 " clip-rule="nonzero"/></clipPath><clipPath id="b9e908fa44"><path d="M 317 92 L 975 92 L 975 299.902344 L 317 299.902344 Z M 317 92 " clip-rule="nonzero"/></clipPath><clipPath id="2af16fdd65"><rect x="0" width="658" y="0" height="208"/></clipPath><clipPath id="5c8fc6f23f"><path d="M 947 185 L 1171.5 185 L 1171.5 299.902344 L 947 299.902344 Z M 947 185 " clip-rule="nonzero"/></clipPath><clipPath id="52eb19aa0f"><rect x="0" width="225" y="0" height="115"/></clipPath><clipPath id="3cbca717fc"><path d="M 0 0.0976562 L 430 0.0976562 L 430 299.902344 L 0 299.902344 Z M 0 0.0976562 " clip-rule="nonzero"/></clipPath><clipPath id="ada831cbfc"><path d="M 4 0.0976562 L 384 0.0976562 L 384 279 L 4 279 Z M 4 0.0976562 " clip-rule="nonzero"/></clipPath><clipPath id="df54cfa995"><rect x="0" width="430" y="0" height="300"/></clipPath><clipPath id="048a39e378"><rect x="0" width="1172" y="0" height="300"/></clipPath></defs><g clip-path="url(#f9753e23e9)"><g transform="matrix(1, 0, 0, 1, 0, -0.000000000000011685)"><g clip-path="url(#048a39e378)"><g clip-path="url(#b9e908fa44)"><g transform="matrix(1, 0, 0, 1, 317, 92)"><g clip-path="url(#2af16fdd65)"><g fill="#000000" fill-opacity="1"><g transform="translate(4.502276, 185.411479)"><g><path d="M 24.875 -161.46875 C 22.488281 -161.46875 20.296875 -162.425781 18.296875 -164.34375 C 16.304688 -166.257812 15.3125 -168.492188 15.3125 -171.046875 C 15.3125 -173.753906 16.304688 -176.0625 18.296875 -177.96875 C 20.296875 -179.882812 22.488281 -180.84375 24.875 -180.84375 C 27.425781 -180.84375 29.660156 -179.882812 31.578125 -177.96875 C 33.492188 -176.0625 34.453125 -173.753906 34.453125 -171.046875 C 34.453125 -168.492188 33.492188 -166.257812 31.578125 -164.34375 C 29.660156 -162.425781 27.425781 -161.46875 24.875 -161.46875 Z M 18.65625 0 L 18.65625 -127.75 L 31.09375 -127.75 L 31.09375 0 Z M 18.65625 0 "/></g></g></g><g fill="#000000" fill-opacity="1"><g transform="translate(74.118463, 185.411479)"><g><path d="M 80.859375 2.875 C 66.503906 2.875 53.144531 1.28125 40.78125 -1.90625 C 28.425781 -5.101562 17.703125 -9.015625 8.609375 -13.640625 L 12.203125 -22.015625 C 20.171875 -17.546875 30.175781 -13.710938 42.21875 -10.515625 C 54.257812 -7.328125 66.976562 -5.734375 80.375 -5.734375 C 90.101562 -5.734375 98.675781 -6.890625 106.09375 -9.203125 C 113.507812 -11.515625 119.328125 -14.625 123.546875 -18.53125 C 127.773438 -22.445312 129.890625 -26.796875 129.890625 -31.578125 C 129.890625 -39.066406 125.941406 -45.046875 118.046875 -49.515625 C 110.160156 -53.984375 96.488281 -57.648438 77.03125 -60.515625 C 55.34375 -63.710938 39.832031 -68.378906 30.5 -74.515625 C 21.164062 -80.648438 16.5 -88.34375 16.5 -97.59375 C 16.5 -103.976562 19.128906 -109.601562 24.390625 -114.46875 C 29.660156 -119.332031 37.039062 -123.195312 46.53125 -126.0625 C 56.019531 -128.9375 67.144531 -130.375 79.90625 -130.375 C 90.582031 -130.375 100.109375 -129.734375 108.484375 -128.453125 C 116.859375 -127.179688 124.710938 -125.585938 132.046875 -123.671875 L 132.046875 -114.109375 C 125.191406 -116.179688 117.457031 -117.929688 108.84375 -119.359375 C 100.226562 -120.796875 90.5 -121.515625 79.65625 -121.515625 C 69.925781 -121.515625 61.15625 -120.519531 53.34375 -118.53125 C 45.53125 -116.539062 39.390625 -113.75 34.921875 -110.15625 C 30.460938 -106.570312 28.234375 -102.382812 28.234375 -97.59375 C 28.234375 -93.132812 29.742188 -89.148438 32.765625 -85.640625 C 35.796875 -82.128906 41.097656 -79.054688 48.671875 -76.421875 C 56.253906 -73.796875 66.898438 -71.445312 80.609375 -69.375 C 102.785156 -66.019531 118.5 -61.351562 127.75 -55.375 C 137 -49.394531 141.625 -41.460938 141.625 -31.578125 C 141.625 -25.203125 139.148438 -19.421875 134.203125 -14.234375 C 129.253906 -9.046875 122.234375 -4.894531 113.140625 -1.78125 C 104.054688 1.320312 93.296875 2.875 80.859375 2.875 Z M 80.859375 2.875 "/></g></g></g><g fill="#000000" fill-opacity="1"><g transform="translate(241.572183, 185.411479)"><g><path d="M 105.25 2.875 C 86.28125 2.875 72.085938 -0.867188 62.671875 -8.359375 C 53.265625 -15.859375 48.5625 -26.628906 48.5625 -40.671875 L 48.5625 -119.125 L 2.390625 -119.125 L 2.390625 -122.953125 L 55.015625 -154.53125 L 60.765625 -154.53125 L 60.765625 -127.75 L 145.4375 -127.75 L 145.4375 -118.40625 L 60.765625 -118.40625 L 60.765625 -41.859375 C 60.765625 -30.054688 64.234375 -21.285156 71.171875 -15.546875 C 78.109375 -9.804688 89.070312 -6.9375 104.0625 -6.9375 C 114.425781 -6.9375 123.195312 -7.691406 130.375 -9.203125 C 137.550781 -10.722656 141.535156 -11.640625 142.328125 -11.953125 L 145.4375 -2.625 C 144.320312 -2.46875 140.21875 -1.515625 133.125 0.234375 C 126.03125 1.992188 116.738281 2.875 105.25 2.875 Z M 105.25 2.875 "/></g></g></g><g fill="#000000" fill-opacity="1"><g transform="translate(412.614214, 185.411479)"><g><path d="M 105.5 2.875 C 92.582031 2.875 80.5 1.28125 69.25 -1.90625 C 58.007812 -5.101562 48.125 -9.691406 39.59375 -15.671875 C 31.0625 -21.648438 24.398438 -28.707031 19.609375 -36.84375 C 14.828125 -44.976562 12.4375 -53.988281 12.4375 -63.875 C 12.4375 -73.757812 14.828125 -82.726562 19.609375 -90.78125 C 24.398438 -98.832031 31.0625 -105.847656 39.59375 -111.828125 C 48.125 -117.816406 58.007812 -122.40625 69.25 -125.59375 C 80.5 -128.78125 92.582031 -130.375 105.5 -130.375 C 123.519531 -130.375 139.863281 -127.300781 154.53125 -121.15625 C 169.207031 -115.019531 180.453125 -106.609375 188.265625 -95.921875 L 190.171875 -95.921875 L 195.4375 -127.75 L 200.9375 -127.75 L 200.9375 0 L 188.75 0 L 188.75 -29.90625 L 186.828125 -29.90625 C 178.691406 -19.695312 167.488281 -11.679688 153.21875 -5.859375 C 138.945312 -0.0351562 123.039062 2.875 105.5 2.875 Z M 107.640625 -6.703125 C 122.640625 -6.703125 136.238281 -9.132812 148.4375 -14 C 160.632812 -18.863281 170.359375 -25.597656 177.609375 -34.203125 C 184.867188 -42.816406 188.5 -52.707031 188.5 -63.875 C 188.5 -75.195312 184.867188 -85.125 177.609375 -93.65625 C 170.359375 -102.1875 160.632812 -108.84375 148.4375 -113.625 C 136.238281 -118.414062 122.640625 -120.8125 107.640625 -120.8125 C 96.316406 -120.8125 85.628906 -119.453125 75.578125 -116.734375 C 65.535156 -114.023438 56.6875 -110.195312 49.03125 -105.25 C 41.382812 -100.3125 35.367188 -94.332031 30.984375 -87.3125 C 26.597656 -80.300781 24.40625 -72.488281 24.40625 -63.875 C 24.40625 -55.257812 26.597656 -47.441406 30.984375 -40.421875 C 35.367188 -33.410156 41.382812 -27.390625 49.03125 -22.359375 C 56.6875 -17.335938 65.535156 -13.472656 75.578125 -10.765625 C 85.628906 -8.054688 96.316406 -6.703125 107.640625 -6.703125 Z M 107.640625 -6.703125 "/></g></g></g></g></g></g><g clip-path="url(#5c8fc6f23f)"><g transform="matrix(1, 0, 0, 1, 947, 185)"><g clip-path="url(#52eb19aa0f)"><g fill="#000000" fill-opacity="1"><g transform="translate(1.079399, 93.921781)"><g><path d="M 11.875 0.921875 C 10.550781 0.921875 9.335938 0.394531 8.234375 -0.65625 C 7.140625 -1.71875 6.59375 -2.953125 6.59375 -4.359375 C 6.59375 -5.847656 7.140625 -7.097656 8.234375 -8.109375 C 9.335938 -9.117188 10.550781 -9.625 11.875 -9.625 C 13.28125 -9.625 14.507812 -9.117188 15.5625 -8.109375 C 16.625 -7.097656 17.15625 -5.847656 17.15625 -4.359375 C 17.15625 -2.953125 16.625 -1.71875 15.5625 -0.65625 C 14.507812 0.394531 13.28125 0.921875 11.875 0.921875 Z M 11.875 0.921875 "/></g></g></g><g fill="#000000" fill-opacity="1"><g transform="translate(35.775365, 93.921781)"><g><path d="M 25.453125 1.453125 C 21.328125 1.453125 17.175781 1.078125 13 0.328125 C 8.820312 -0.421875 5.148438 -1.234375 1.984375 -2.109375 L 3.296875 -8.046875 C 6.640625 -6.992188 10.242188 -6.09375 14.109375 -5.34375 C 17.984375 -4.59375 22.078125 -4.21875 26.390625 -4.21875 C 38.960938 -4.21875 48.695312 -6.832031 55.59375 -12.0625 C 62.5 -17.300781 65.953125 -25.238281 65.953125 -35.875 L 65.953125 -92.34375 L 72.5625 -92.34375 L 72.5625 -35.359375 C 72.5625 -10.816406 56.859375 1.453125 25.453125 1.453125 Z M 25.453125 1.453125 "/></g></g></g><g fill="#000000" fill-opacity="1"><g transform="translate(134.316886, 93.921781)"><g><path d="M 44.59375 1.578125 C 36.675781 1.578125 29.304688 0.703125 22.484375 -1.046875 C 15.671875 -2.804688 9.757812 -4.960938 4.75 -7.515625 L 6.734375 -12.140625 C 11.128906 -9.671875 16.644531 -7.554688 23.28125 -5.796875 C 29.925781 -4.046875 36.941406 -3.171875 44.328125 -3.171875 C 49.691406 -3.171875 54.414062 -3.804688 58.5 -5.078125 C 62.59375 -6.347656 65.804688 -8.0625 68.140625 -10.21875 C 70.472656 -12.375 71.640625 -14.769531 71.640625 -17.40625 C 71.640625 -21.539062 69.460938 -24.835938 65.109375 -27.296875 C 60.753906 -29.765625 53.210938 -31.789062 42.484375 -33.375 C 30.515625 -35.132812 21.957031 -37.707031 16.8125 -41.09375 C 11.675781 -44.476562 9.109375 -48.722656 9.109375 -53.828125 C 9.109375 -57.335938 10.554688 -60.429688 13.453125 -63.109375 C 16.359375 -65.796875 20.425781 -67.929688 25.65625 -69.515625 C 30.894531 -71.097656 37.03125 -71.890625 44.0625 -71.890625 C 49.957031 -71.890625 55.210938 -71.535156 59.828125 -70.828125 C 64.441406 -70.128906 68.773438 -69.253906 72.828125 -68.203125 L 72.828125 -62.921875 C 69.035156 -64.066406 64.765625 -65.035156 60.015625 -65.828125 C 55.273438 -66.617188 49.914062 -67.015625 43.9375 -67.015625 C 38.5625 -67.015625 33.71875 -66.460938 29.40625 -65.359375 C 25.101562 -64.265625 21.71875 -62.726562 19.25 -60.75 C 16.789062 -58.769531 15.5625 -56.460938 15.5625 -53.828125 C 15.5625 -51.359375 16.394531 -49.15625 18.0625 -47.21875 C 19.738281 -45.289062 22.664062 -43.597656 26.84375 -42.140625 C 31.019531 -40.691406 36.890625 -39.394531 44.453125 -38.25 C 56.679688 -36.40625 65.34375 -33.832031 70.4375 -30.53125 C 75.539062 -27.238281 78.09375 -22.863281 78.09375 -17.40625 C 78.09375 -13.894531 76.726562 -10.707031 74 -7.84375 C 71.28125 -4.988281 67.410156 -2.703125 62.390625 -0.984375 C 57.378906 0.722656 51.445312 1.578125 44.59375 1.578125 Z M 44.59375 1.578125 "/></g></g></g></g></g></g><g clip-path="url(#3cbca717fc)"><g transform="matrix(1, 0, 0, 1, 0, -0.000000000000011685)"><g clip-path="url(#df54cfa995)"><g clip-path="url(#ada831cbfc)"><g fill="#000000" fill-opacity="1"><g transform="translate(-2.567799, 274.170971)"><g><path d="M 192.46875 4.6875 L 7.046875 -273.84375 L 28.953125 -273.84375 L 195.609375 -22.6875 L 197.5625 -22.6875 L 365.390625 -273.84375 L 386.515625 -273.84375 L 200.296875 4.6875 Z M 192.46875 4.6875 "/></g></g></g></g></g></g></g></g></g></g></svg>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"useDefineForClassFields": true,
|
|
5
|
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
6
|
+
"module": "ESNext",
|
|
7
|
+
"skipLibCheck": true,
|
|
8
|
+
|
|
9
|
+
/* Bundler mode */
|
|
10
|
+
"moduleResolution": "bundler",
|
|
11
|
+
"allowImportingTsExtensions": true,
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"isolatedModules": true,
|
|
14
|
+
"noEmit": true,
|
|
15
|
+
"jsx": "react-jsx",
|
|
16
|
+
|
|
17
|
+
/* Linting */
|
|
18
|
+
"strict": true,
|
|
19
|
+
"noUnusedLocals": true,
|
|
20
|
+
"noUnusedParameters": true,
|
|
21
|
+
"noFallthroughCasesInSwitch": true
|
|
22
|
+
},
|
|
23
|
+
"include": ["."],
|
|
24
|
+
"references": [{ "path": "./tsconfig.node.json" }]
|
|
25
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { VistaConfig } from 'vista';
|
|
2
|
+
|
|
3
|
+
const config: VistaConfig = {
|
|
4
|
+
/*
|
|
5
|
+
* React Specific Options
|
|
6
|
+
* You can pass options to the React plugin here if needed.
|
|
7
|
+
* react: { ... },
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/*
|
|
11
|
+
* Server Configuration
|
|
12
|
+
* Customize the development server settings.
|
|
13
|
+
* server: {
|
|
14
|
+
* port: 3000,
|
|
15
|
+
* proxy: {
|
|
16
|
+
* '/api': 'http://localhost:8080',
|
|
17
|
+
* },
|
|
18
|
+
* },
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/*
|
|
22
|
+
* Build Options
|
|
23
|
+
* Configure build output, minification, and more.
|
|
24
|
+
* build: {
|
|
25
|
+
* outDir: 'dist',
|
|
26
|
+
* sourcemap: true,
|
|
27
|
+
* },
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
/*
|
|
31
|
+
* Resolve Aliases
|
|
32
|
+
* Create custom import aliases.
|
|
33
|
+
* resolve: {
|
|
34
|
+
* alias: {
|
|
35
|
+
* '@': '/src',
|
|
36
|
+
* },
|
|
37
|
+
* },
|
|
38
|
+
*/
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export default config;
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"useDefineForClassFields": true,
|
|
5
|
+
"module": "ESNext",
|
|
6
|
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
7
|
+
"skipLibCheck": true,
|
|
8
|
+
"moduleResolution": "bundler",
|
|
9
|
+
"resolveJsonModule": true,
|
|
10
|
+
"isolatedModules": true,
|
|
11
|
+
"noEmit": false,
|
|
12
|
+
"strict": true,
|
|
13
|
+
"noUnusedLocals": true,
|
|
14
|
+
"noUnusedParameters": true,
|
|
15
|
+
"noFallthroughCasesInSwitch": true,
|
|
16
|
+
"outDir": "dist",
|
|
17
|
+
"declaration": true
|
|
18
|
+
},
|
|
19
|
+
"include": ["."],
|
|
20
|
+
"exclude": ["node_modules", "dist", "templates"]
|
|
21
|
+
}
|