@vistagenic/vista 0.3.6 → 0.3.9
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/flashpack-agent-playground.mjs +134 -0
- package/bin/flashpack-boot.mjs +506 -0
- package/bin/flashpack-ssr-loader.mjs +42 -0
- package/bin/flashpack-ssr.mjs +202 -0
- package/bin/flashpack-vendor.mjs +97 -0
- package/bin/vista.js +56 -42
- package/dist/ai/providers/base.js +7 -1
- package/dist/bin/build-rsc.js +16 -0
- package/dist/bin/build.js +17 -11
- package/dist/bin/deploy.js +7 -0
- package/dist/bin/dev-client-runtime.d.ts +6 -0
- package/dist/bin/dev-client-runtime.js +99 -0
- package/dist/bin/dev-error-overlay-snippet.js +79 -21
- package/dist/bin/dev-error-overlay-snippet.ts +840 -0
- package/dist/bin/devtools-indicator-snippet.js +29 -13
- package/dist/bin/file-scanner.js +7 -24
- package/dist/bin/generate.js +94 -2
- package/dist/bin/webpack.config.js +3 -1
- package/dist/build/rsc/compiler.d.ts +14 -0
- package/dist/build/rsc/compiler.js +66 -6
- package/dist/build/rsc/server-manifest.js +5 -4
- package/dist/config.d.ts +5 -0
- package/dist/config.js +15 -1
- package/dist/deploy/adapters/render.js +2 -2
- package/dist/deploy/index.d.ts +1 -0
- package/dist/deploy/index.js +3 -0
- package/dist/deploy/runtime-pack.js +22 -1
- package/dist/deploy/utils.js +16 -6
- package/dist/flashpack/command.d.ts +1 -0
- package/dist/flashpack/command.js +42 -76
- package/dist/flashpack/runtime.d.ts +12 -0
- package/dist/flashpack/runtime.js +124 -22
- package/dist/metadata/generate.d.ts +1 -0
- package/dist/metadata/generate.js +117 -21
- package/dist/metadata/index.d.ts +5 -0
- package/dist/metadata/index.js +15 -1
- package/dist/metadata/json-ld.d.ts +15 -0
- package/dist/metadata/json-ld.js +19 -0
- package/dist/metadata/merge.d.ts +17 -0
- package/dist/metadata/merge.js +161 -0
- package/dist/metadata/routes.d.ts +66 -0
- package/dist/metadata/routes.js +143 -0
- package/dist/metadata/types.d.ts +1 -1
- package/dist/metadata/types.js +3 -1
- package/dist/og/image-response.d.ts +38 -0
- package/dist/og/image-response.js +88 -0
- package/dist/og/index.d.ts +2 -0
- package/dist/og/index.js +5 -0
- package/dist/rust/index.d.ts +13 -0
- package/dist/rust/index.js +132 -0
- package/dist/server/engine.js +13 -3
- package/dist/server/logger.js +2 -1
- package/dist/server/project-alias-resolver.d.ts +7 -0
- package/dist/server/project-alias-resolver.js +70 -0
- package/dist/server/rsc-engine.js +93 -16
- package/dist/server/static-generator.js +4 -3
- package/dist/server/typed-api-runtime.js +92 -0
- package/docs/ai.md +69 -0
- package/docs/app.md +30 -0
- package/docs/cli.md +29 -0
- package/docs/index.md +18 -0
- package/docs/rag.md +54 -0
- package/native/win32-x64/flashpack-cli.exe +0 -0
- package/package.json +196 -178
- package/skills/README.md +9 -0
- package/skills/vista-agent/SKILL.md +28 -0
- package/skills/vista-dev-loop/SKILL.md +25 -0
- package/skills/vista-rag/SKILL.md +26 -0
|
@@ -47,21 +47,22 @@ function getDevToolsIndicatorBootstrapSource(bootSessionId) {
|
|
|
47
47
|
style.id = '__vista-devtools-style';
|
|
48
48
|
style.textContent = [
|
|
49
49
|
'#__vista-devtools-root{position:fixed;left:28px;bottom:22px;z-index:2147482000;font-family:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;color:#fff;}',
|
|
50
|
-
'#__vista-devtools-root [data-vista-trigger]{width:
|
|
51
|
-
'#__vista-devtools-root [data-vista-trigger]:hover{transform:translateY(-
|
|
52
|
-
'#__vista-devtools-root [data-vista-trigger]:focus-visible{outline:2px solid rgba(255,255,255,0.
|
|
53
|
-
'#__vista-devtools-root [data-vista-trigger][data-busy="true"]{border-color:rgba(255,255,255,0.
|
|
54
|
-
'#__vista-devtools-root [data-vista-trigger][data-error="true"]{width:
|
|
55
|
-
'#__vista-devtools-root
|
|
50
|
+
'#__vista-devtools-root [data-vista-trigger]{width:42px;height:42px;border-radius:9999px;border:1px solid rgba(255,255,255,0.16);background:rgba(12,12,12,0.88);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 8px 28px rgba(0,0,0,0.38),inset 0 1px 0 rgba(255,255,255,0.08);position:relative;gap:0;padding:0;transition:transform 200ms cubic-bezier(0.22,1,0.36,1),border-color 200ms ease,background 200ms ease,width 220ms cubic-bezier(0.22,1,0.36,1),padding 220ms cubic-bezier(0.22,1,0.36,1),gap 220ms cubic-bezier(0.22,1,0.36,1),box-shadow 220ms ease;}',
|
|
51
|
+
'#__vista-devtools-root [data-vista-trigger]:hover{transform:translateY(-2px);border-color:rgba(255,255,255,0.34);background:rgba(18,18,18,0.94);box-shadow:0 12px 32px rgba(0,0,0,0.45),inset 0 1px 0 rgba(255,255,255,0.1);}',
|
|
52
|
+
'#__vista-devtools-root [data-vista-trigger]:focus-visible{outline:2px solid rgba(255,255,255,0.55);outline-offset:3px;}',
|
|
53
|
+
'#__vista-devtools-root [data-vista-trigger][data-busy="true"]{border-color:rgba(255,255,255,0.42);}',
|
|
54
|
+
'#__vista-devtools-root [data-vista-trigger][data-error="true"]{width:auto;min-width:42px;height:42px;padding:0 12px 0 11px;justify-content:flex-start;gap:9px;border-color:rgba(255,255,255,0.14);background:linear-gradient(180deg,rgba(28,16,18,0.96),rgba(14,10,11,0.96));box-shadow:0 10px 30px rgba(0,0,0,0.42),0 0 0 1px rgba(255,90,90,0.18),inset 0 1px 0 rgba(255,255,255,0.06);}',
|
|
55
|
+
'#__vista-devtools-root [data-vista-trigger][data-error="true"]:hover{border-color:rgba(255,255,255,0.22);box-shadow:0 14px 34px rgba(0,0,0,0.48),0 0 0 1px rgba(255,90,90,0.28),inset 0 1px 0 rgba(255,255,255,0.08);}',
|
|
56
|
+
'#__vista-devtools-root .vista-devtools-logo{display:block;width:15px;height:15px;flex:0 0 auto;}',
|
|
56
57
|
'#__vista-devtools-root .vista-devtools-logo svg{width:100%;height:100%;display:block;}',
|
|
57
|
-
'#__vista-devtools-root [data-vista-trigger][data-error="true"] .vista-devtools-logo{width:14px;height:14px;}',
|
|
58
58
|
'#__vista-devtools-root .vista-devtools-logo-fill{fill:#fff;opacity:1;transition:opacity 180ms ease;}',
|
|
59
59
|
'#__vista-devtools-root .vista-devtools-logo-draw{fill:none;stroke:#fff;stroke-width:12;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:100;stroke-dashoffset:100;opacity:0;}',
|
|
60
60
|
'#__vista-devtools-root [data-vista-trigger][data-busy="true"] .vista-devtools-logo-fill{opacity:0.18;}',
|
|
61
61
|
'#__vista-devtools-root [data-vista-trigger][data-busy="true"] .vista-devtools-logo-draw{opacity:1;animation:vista-devtools-v-draw 900ms ease-in-out infinite;}',
|
|
62
|
-
'#__vista-devtools-root .vista-devtools-error-pill{display:inline-flex;align-items:center;gap:
|
|
63
|
-
'#__vista-devtools-root .vista-devtools-error-
|
|
64
|
-
'#__vista-devtools-root
|
|
62
|
+
'#__vista-devtools-root .vista-devtools-error-pill{display:inline-flex;align-items:center;gap:5px;height:22px;padding:0 8px;border-radius:999px;border:1px solid rgba(255,120,120,0.28);background:rgba(255,255,255,0.06);color:rgba(255,228,228,0.96);font-size:11px;font-weight:600;letter-spacing:0.01em;font-variant-numeric:tabular-nums;line-height:1;white-space:nowrap;}',
|
|
63
|
+
'#__vista-devtools-root .vista-devtools-error-dot{width:6px;height:6px;border-radius:999px;background:#ff6b6b;box-shadow:0 0 0 0 rgba(255,107,107,0.45);animation:vista-devtools-error-pulse 1.8s ease-out infinite;flex:0 0 auto;}',
|
|
64
|
+
'#__vista-devtools-root .vista-devtools-error-label{opacity:0.72;font-weight:550;}',
|
|
65
|
+
'#__vista-devtools-root [data-vista-panel]{position:absolute;left:0;bottom:54px;width:244px;padding:10px;border-radius:14px;border:1px solid rgba(255,255,255,0.14);background:rgba(10,10,10,0.94);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);box-shadow:0 18px 40px rgba(0,0,0,0.5);}',
|
|
65
66
|
'#__vista-devtools-root [data-vista-panel][hidden]{display:none;}',
|
|
66
67
|
'#__vista-devtools-root .vista-devtools-title{font-size:11px;letter-spacing:0.08em;text-transform:uppercase;color:rgba(255,255,255,0.72);margin:0 0 8px;}',
|
|
67
68
|
'#__vista-devtools-root .vista-devtools-row{font-size:12px;display:flex;justify-content:space-between;gap:10px;margin:4px 0;color:rgba(255,255,255,0.92);}',
|
|
@@ -72,6 +73,7 @@ function getDevToolsIndicatorBootstrapSource(bootSessionId) {
|
|
|
72
73
|
'#__vista-devtools-root [data-vista-hide]:hover{background:rgba(255,255,255,0.12);border-color:rgba(255,255,255,0.5);color:#fff;}',
|
|
73
74
|
'#__vista-devtools-root .vista-hide-icon{width:12px;height:12px;display:block;}',
|
|
74
75
|
'@keyframes vista-devtools-v-draw{0%{stroke-dashoffset:100;opacity:0.35;}45%{stroke-dashoffset:0;opacity:1;}72%{stroke-dashoffset:0;opacity:1;}100%{stroke-dashoffset:-100;opacity:0.35;}}',
|
|
76
|
+
'@keyframes vista-devtools-error-pulse{0%{box-shadow:0 0 0 0 rgba(255,107,107,0.45);}70%{box-shadow:0 0 0 7px rgba(255,107,107,0);}100%{box-shadow:0 0 0 0 rgba(255,107,107,0);}}',
|
|
75
77
|
'@media (max-width:640px){#__vista-devtools-root{left:16px;bottom:14px;}#__vista-devtools-root [data-vista-panel]{width:220px;}}',
|
|
76
78
|
].join('');
|
|
77
79
|
}
|
|
@@ -92,8 +94,9 @@ function getDevToolsIndicatorBootstrapSource(bootSessionId) {
|
|
|
92
94
|
'</svg>' +
|
|
93
95
|
'</span>' +
|
|
94
96
|
'<span class="vista-devtools-error-pill" data-vista-error-pill hidden>' +
|
|
95
|
-
'<span class="vista-devtools-error-
|
|
97
|
+
'<span class="vista-devtools-error-dot" aria-hidden="true"></span>' +
|
|
96
98
|
'<span data-vista-error-count>1</span>' +
|
|
99
|
+
'<span class="vista-devtools-error-label" data-vista-error-label>issue</span>' +
|
|
97
100
|
'</span>' +
|
|
98
101
|
'</button>' +
|
|
99
102
|
'<div data-vista-panel hidden>' +
|
|
@@ -123,6 +126,7 @@ function getDevToolsIndicatorBootstrapSource(bootSessionId) {
|
|
|
123
126
|
var hideButton = null;
|
|
124
127
|
var errorPill = null;
|
|
125
128
|
var errorCountNode = null;
|
|
129
|
+
var errorLabelNode = null;
|
|
126
130
|
var open = false;
|
|
127
131
|
var pendingCount = 0;
|
|
128
132
|
var busyStartedAt = 0;
|
|
@@ -143,6 +147,7 @@ function getDevToolsIndicatorBootstrapSource(bootSessionId) {
|
|
|
143
147
|
hideButton = root.querySelector('[data-vista-hide]');
|
|
144
148
|
errorPill = root.querySelector('[data-vista-error-pill]');
|
|
145
149
|
errorCountNode = root.querySelector('[data-vista-error-count]');
|
|
150
|
+
errorLabelNode = root.querySelector('[data-vista-error-label]');
|
|
146
151
|
}
|
|
147
152
|
|
|
148
153
|
function ensureAttached() {
|
|
@@ -211,9 +216,16 @@ function getDevToolsIndicatorBootstrapSource(bootSessionId) {
|
|
|
211
216
|
} else {
|
|
212
217
|
errorCount = 1;
|
|
213
218
|
}
|
|
214
|
-
if (button)
|
|
219
|
+
if (button) {
|
|
220
|
+
button.setAttribute('data-error', 'true');
|
|
221
|
+
button.setAttribute(
|
|
222
|
+
'aria-label',
|
|
223
|
+
'Vista Dev Tools — ' + errorCount + (errorCount === 1 ? ' issue' : ' issues')
|
|
224
|
+
);
|
|
225
|
+
}
|
|
215
226
|
if (errorPill) errorPill.hidden = false;
|
|
216
227
|
if (errorCountNode) errorCountNode.textContent = String(errorCount);
|
|
228
|
+
if (errorLabelNode) errorLabelNode.textContent = errorCount === 1 ? 'issue' : 'issues';
|
|
217
229
|
if (statusValue) statusValue.textContent = 'error';
|
|
218
230
|
if (reasonValue)
|
|
219
231
|
reasonValue.textContent =
|
|
@@ -223,8 +235,12 @@ function getDevToolsIndicatorBootstrapSource(bootSessionId) {
|
|
|
223
235
|
function clearError() {
|
|
224
236
|
ensureAttached();
|
|
225
237
|
hasError = false;
|
|
226
|
-
if (button)
|
|
238
|
+
if (button) {
|
|
239
|
+
button.setAttribute('data-error', 'false');
|
|
240
|
+
button.setAttribute('aria-label', 'Vista Dev Tools');
|
|
241
|
+
}
|
|
227
242
|
if (errorPill) errorPill.hidden = true;
|
|
243
|
+
if (errorLabelNode) errorLabelNode.textContent = 'issue';
|
|
228
244
|
errorCount = 1;
|
|
229
245
|
setState(currentBusy, currentReason);
|
|
230
246
|
}
|
package/dist/bin/file-scanner.js
CHANGED
|
@@ -53,6 +53,7 @@ exports.getVersion = getVersion;
|
|
|
53
53
|
const fs = __importStar(require("fs"));
|
|
54
54
|
const path = __importStar(require("path"));
|
|
55
55
|
const native_scanner_1 = require("../build/rsc/native-scanner");
|
|
56
|
+
const rust_1 = require("../rust");
|
|
56
57
|
const RESERVED_INTERNAL_SEGMENTS = new Set(['[not-found]']);
|
|
57
58
|
function hasReservedInternalSegment(relativePath) {
|
|
58
59
|
return relativePath
|
|
@@ -111,34 +112,16 @@ function getRouteTree(appDir) {
|
|
|
111
112
|
// JS Fallback - build route tree from file system
|
|
112
113
|
return buildRouteTreeJS(appDir, appDir);
|
|
113
114
|
}
|
|
114
|
-
function classifySegment(segment) {
|
|
115
|
-
if (segment.startsWith('[[...') && segment.endsWith(']]'))
|
|
116
|
-
return 'optional-catch-all';
|
|
117
|
-
if (segment.startsWith('[...'))
|
|
118
|
-
return 'catch-all';
|
|
119
|
-
if (segment.startsWith('(.)') ||
|
|
120
|
-
segment.startsWith('(..)') ||
|
|
121
|
-
segment.startsWith('(..)(..)') ||
|
|
122
|
-
segment.startsWith('(...)')) {
|
|
123
|
-
return 'interception';
|
|
124
|
-
}
|
|
125
|
-
if (segment.startsWith('(') && segment.endsWith(')'))
|
|
126
|
-
return 'group';
|
|
127
|
-
if (segment.startsWith('@'))
|
|
128
|
-
return 'parallel';
|
|
129
|
-
if (segment.startsWith('['))
|
|
130
|
-
return 'dynamic';
|
|
131
|
-
return 'static';
|
|
132
|
-
}
|
|
133
115
|
/**
|
|
134
|
-
* JS Fallback for building route tree when Rust bindings are unavailable
|
|
116
|
+
* JS Fallback for building route tree when Rust bindings are unavailable.
|
|
117
|
+
* Classification goes through `vista/rust`, which uses the native addon when it is loaded.
|
|
135
118
|
*/
|
|
136
119
|
function buildRouteTreeJS(dir, appDir) {
|
|
137
|
-
const
|
|
138
|
-
const
|
|
120
|
+
const folder = dir === appDir ? '' : path.basename(dir);
|
|
121
|
+
const classified = folder === '' ? { kind: 'static', segment: '' } : (0, rust_1.classifyAppSegment)(folder);
|
|
139
122
|
const node = {
|
|
140
|
-
segment:
|
|
141
|
-
kind,
|
|
123
|
+
segment: classified.segment,
|
|
124
|
+
kind: classified.kind,
|
|
142
125
|
children: [],
|
|
143
126
|
};
|
|
144
127
|
if (!fs.existsSync(dir)) {
|
package/dist/bin/generate.js
CHANGED
|
@@ -62,7 +62,7 @@ function renderAgent(kebabName) {
|
|
|
62
62
|
function renderAgentRoute(kebabName) {
|
|
63
63
|
const camelName = toCamelCase(kebabName);
|
|
64
64
|
return [
|
|
65
|
-
`import { ${camelName}Agent } from '
|
|
65
|
+
`import { ${camelName}Agent } from '../../../agents/${kebabName}/agent';`,
|
|
66
66
|
'',
|
|
67
67
|
'export async function POST(req: Request) {',
|
|
68
68
|
' const { prompt, messages, sessionId } = await req.json();',
|
|
@@ -116,6 +116,18 @@ function insertTypedApiConfigIntoObject(source, objectStartIndex) {
|
|
|
116
116
|
if (closeBraceIndex < 0) {
|
|
117
117
|
return null;
|
|
118
118
|
}
|
|
119
|
+
const objectContent = source.slice(openBraceIndex, closeBraceIndex);
|
|
120
|
+
const expMatch = objectContent.match(/\bexperimental\s*:\s*\{/);
|
|
121
|
+
if (expMatch && typeof expMatch.index === 'number') {
|
|
122
|
+
const absExpBrace = openBraceIndex + expMatch.index + expMatch[0].lastIndexOf('{');
|
|
123
|
+
const expCloseBrace = findMatchingBrace(source, absExpBrace);
|
|
124
|
+
if (expCloseBrace >= 0) {
|
|
125
|
+
const expBefore = source.slice(0, expCloseBrace);
|
|
126
|
+
const expAfter = source.slice(expCloseBrace);
|
|
127
|
+
const insertion = ` typedApi: {\n enabled: true,\n },\n `;
|
|
128
|
+
return `${expBefore}${insertion}${expAfter}`;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
119
131
|
const before = source.slice(0, closeBraceIndex);
|
|
120
132
|
const after = source.slice(closeBraceIndex);
|
|
121
133
|
const insertion = `\n experimental: {\n typedApi: {\n enabled: true,\n },\n },`;
|
|
@@ -335,6 +347,8 @@ function renderSignInPage() {
|
|
|
335
347
|
}
|
|
336
348
|
function renderAccountPage() {
|
|
337
349
|
return [
|
|
350
|
+
"export const dynamic = 'force-dynamic';",
|
|
351
|
+
'',
|
|
338
352
|
"import { auth } from '../../auth';",
|
|
339
353
|
'',
|
|
340
354
|
'export default async function AccountPage() {',
|
|
@@ -384,6 +398,69 @@ function patchRootWithSessionProvider(cwd) {
|
|
|
384
398
|
fs_1.default.writeFileSync(absolutePath, next, 'utf8');
|
|
385
399
|
return { path: absolutePath, patched: true };
|
|
386
400
|
}
|
|
401
|
+
function renderSeoRobots() {
|
|
402
|
+
return [
|
|
403
|
+
"import { robots } from 'vista/metadata';",
|
|
404
|
+
'',
|
|
405
|
+
'const siteUrl = process.env.NEXT_PUBLIC_SITE_URL || process.env.VISTA_SITE_URL || \'http://localhost:3003\';',
|
|
406
|
+
'',
|
|
407
|
+
'export default function robotsTxt() {',
|
|
408
|
+
' return robots({',
|
|
409
|
+
" rules: {",
|
|
410
|
+
" userAgent: '*',",
|
|
411
|
+
" allow: '/',",
|
|
412
|
+
' },',
|
|
413
|
+
' sitemap: `${siteUrl}/sitemap.xml`,',
|
|
414
|
+
' host: new URL(siteUrl).host,',
|
|
415
|
+
' });',
|
|
416
|
+
'}',
|
|
417
|
+
'',
|
|
418
|
+
].join('\n');
|
|
419
|
+
}
|
|
420
|
+
function renderSeoSitemap() {
|
|
421
|
+
return [
|
|
422
|
+
"import { sitemap } from 'vista/metadata';",
|
|
423
|
+
'',
|
|
424
|
+
'const siteUrl = process.env.NEXT_PUBLIC_SITE_URL || process.env.VISTA_SITE_URL || \'http://localhost:3003\';',
|
|
425
|
+
'',
|
|
426
|
+
'export default function sitemapXml() {',
|
|
427
|
+
' return sitemap([',
|
|
428
|
+
' {',
|
|
429
|
+
' url: siteUrl,',
|
|
430
|
+
' lastModified: new Date(),',
|
|
431
|
+
" changeFrequency: 'weekly',",
|
|
432
|
+
' priority: 1,',
|
|
433
|
+
' },',
|
|
434
|
+
' ]);',
|
|
435
|
+
'}',
|
|
436
|
+
'',
|
|
437
|
+
].join('\n');
|
|
438
|
+
}
|
|
439
|
+
function renderSeoManifest() {
|
|
440
|
+
return [
|
|
441
|
+
"import { manifest } from 'vista/metadata';",
|
|
442
|
+
'',
|
|
443
|
+
'export default function webManifest() {',
|
|
444
|
+
' return manifest({',
|
|
445
|
+
" name: 'My Vista App',",
|
|
446
|
+
" short_name: 'Vista App',",
|
|
447
|
+
" description: 'Built with Vista Framework',",
|
|
448
|
+
" start_url: '/',",
|
|
449
|
+
" display: 'standalone',",
|
|
450
|
+
" background_color: '#ffffff',",
|
|
451
|
+
" theme_color: '#111111',",
|
|
452
|
+
' icons: [',
|
|
453
|
+
' {',
|
|
454
|
+
" src: '/favicon.ico',",
|
|
455
|
+
" sizes: 'any',",
|
|
456
|
+
" type: 'image/x-icon',",
|
|
457
|
+
' },',
|
|
458
|
+
' ],',
|
|
459
|
+
' });',
|
|
460
|
+
'}',
|
|
461
|
+
'',
|
|
462
|
+
].join('\n');
|
|
463
|
+
}
|
|
387
464
|
function printGenerateUsage(log) {
|
|
388
465
|
log('Vista generator usage:');
|
|
389
466
|
log(' vista g api-init');
|
|
@@ -391,13 +468,14 @@ function printGenerateUsage(log) {
|
|
|
391
468
|
log(' vista g procedure <name> [get|post]');
|
|
392
469
|
log(' vista g agent <name>');
|
|
393
470
|
log(' vista g auth');
|
|
471
|
+
log(' vista g seo');
|
|
394
472
|
}
|
|
395
473
|
async function runGenerateCommand(args, options = {}) {
|
|
396
474
|
const cwd = options.cwd ?? process.cwd();
|
|
397
475
|
const log = options.log ?? console.log;
|
|
398
476
|
const error = options.error ?? console.error;
|
|
399
477
|
const command = (args[0] || '').toLowerCase();
|
|
400
|
-
if (!command || !['api-init', 'router', 'procedure', 'agent', 'auth'].includes(command)) {
|
|
478
|
+
if (!command || !['api-init', 'router', 'procedure', 'agent', 'auth', 'seo'].includes(command)) {
|
|
401
479
|
printGenerateUsage(log);
|
|
402
480
|
return 1;
|
|
403
481
|
}
|
|
@@ -508,6 +586,20 @@ async function runGenerateCommand(args, options = {}) {
|
|
|
508
586
|
log('Credentials sign-in POSTs from /signin. OAuth honors callbackUrl. /account is auth-gated.');
|
|
509
587
|
return 0;
|
|
510
588
|
}
|
|
589
|
+
if (command === 'seo') {
|
|
590
|
+
const writes = [
|
|
591
|
+
writeFileIfMissing(cwd, path_1.default.join(appDirRelative, 'robots.ts'), renderSeoRobots()),
|
|
592
|
+
writeFileIfMissing(cwd, path_1.default.join(appDirRelative, 'sitemap.ts'), renderSeoSitemap()),
|
|
593
|
+
writeFileIfMissing(cwd, path_1.default.join(appDirRelative, 'manifest.ts'), renderSeoManifest()),
|
|
594
|
+
];
|
|
595
|
+
writes.forEach((result) => {
|
|
596
|
+
const relativePath = path_1.default.relative(cwd, result.path).replace(/\\/g, '/');
|
|
597
|
+
log(`${result.created ? 'created' : 'skipped'} ${relativePath}`);
|
|
598
|
+
});
|
|
599
|
+
log('SEO routes: /robots.txt, /sitemap.xml, /manifest.webmanifest');
|
|
600
|
+
log('Set VISTA_SITE_URL (or NEXT_PUBLIC_SITE_URL) for absolute sitemap/robots URLs.');
|
|
601
|
+
return 0;
|
|
602
|
+
}
|
|
511
603
|
printGenerateUsage(log);
|
|
512
604
|
return 1;
|
|
513
605
|
}
|
|
@@ -12,6 +12,7 @@ const server_component_plugin_1 = require("./server-component-plugin");
|
|
|
12
12
|
const vista_flight_plugin_1 = require("../build/webpack/plugins/vista-flight-plugin");
|
|
13
13
|
const constants_1 = require("../constants");
|
|
14
14
|
const app_dir_1 = require("../server/app-dir");
|
|
15
|
+
const project_alias_resolver_1 = require("../server/project-alias-resolver");
|
|
15
16
|
function createWebpackConfig(options) {
|
|
16
17
|
const { cwd, isDev, engineVariant = 'default', cacheComponentsEnabled = false, imagesUnoptimized = false, deployOutput, } = options;
|
|
17
18
|
const vistaDir = path_1.default.join(cwd, constants_1.BUILD_DIR);
|
|
@@ -76,6 +77,7 @@ function createWebpackConfig(options) {
|
|
|
76
77
|
resolve: {
|
|
77
78
|
extensions: ['.tsx', '.ts', '.jsx', '.js'],
|
|
78
79
|
alias: {
|
|
80
|
+
...(0, project_alias_resolver_1.loadProjectWebpackAliases)(cwd),
|
|
79
81
|
react: reactPath,
|
|
80
82
|
'react-dom': reactDomPath,
|
|
81
83
|
'react/jsx-runtime': path_1.default.join(reactPath, 'jsx-runtime'),
|
|
@@ -177,7 +179,7 @@ function createWebpackConfig(options) {
|
|
|
177
179
|
devtool: isDev ? 'eval-cheap-module-source-map' : 'source-map',
|
|
178
180
|
stats: 'minimal',
|
|
179
181
|
infrastructureLogging: {
|
|
180
|
-
level: '
|
|
182
|
+
level: isDev ? 'none' : 'error',
|
|
181
183
|
},
|
|
182
184
|
};
|
|
183
185
|
}
|
|
@@ -18,6 +18,19 @@ export interface RSCCompilerOptions {
|
|
|
18
18
|
imagesUnoptimized?: boolean;
|
|
19
19
|
deployOutput?: DeployOutput;
|
|
20
20
|
}
|
|
21
|
+
type FlightClientReferenceOption = string | {
|
|
22
|
+
directory: string;
|
|
23
|
+
recursive: boolean;
|
|
24
|
+
include: RegExp;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Build ReactFlightWebpackPlugin `clientReferences`.
|
|
28
|
+
*
|
|
29
|
+
* Project roots (`app/`, `components/`, `lib/`, ...) are passed as watched
|
|
30
|
+
* directories so newly added `'use client'` files are registered without a full
|
|
31
|
+
* rebuild. Framework package paths stay as absolute files.
|
|
32
|
+
*/
|
|
33
|
+
export declare function buildFlightClientReferenceOptions(cwd: string, explicitFiles?: string[]): FlightClientReferenceOption[];
|
|
21
34
|
/**
|
|
22
35
|
* Create Server-Side Webpack Configuration
|
|
23
36
|
*
|
|
@@ -39,3 +52,4 @@ export declare function runRSCBuild(cwd: string, isDev: boolean): Promise<{
|
|
|
39
52
|
serverCompiler: webpack.Compiler;
|
|
40
53
|
clientCompiler: webpack.Compiler;
|
|
41
54
|
}>;
|
|
55
|
+
export {};
|
|
@@ -10,6 +10,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
10
10
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
11
|
};
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.buildFlightClientReferenceOptions = buildFlightClientReferenceOptions;
|
|
13
14
|
exports.createServerWebpackConfig = createServerWebpackConfig;
|
|
14
15
|
exports.createClientWebpackConfig = createClientWebpackConfig;
|
|
15
16
|
exports.runRSCBuild = runRSCBuild;
|
|
@@ -22,6 +23,51 @@ const server_manifest_1 = require("./server-manifest");
|
|
|
22
23
|
const react_client_reference_manifest_1 = require("./react-client-reference-manifest");
|
|
23
24
|
const constants_1 = require("../../constants");
|
|
24
25
|
const app_dir_1 = require("../../server/app-dir");
|
|
26
|
+
const project_alias_resolver_1 = require("../../server/project-alias-resolver");
|
|
27
|
+
function isPathInside(target, ancestor) {
|
|
28
|
+
const resolvedTarget = path_1.default.resolve(target);
|
|
29
|
+
const resolvedAncestor = path_1.default.resolve(ancestor);
|
|
30
|
+
if (resolvedTarget === resolvedAncestor)
|
|
31
|
+
return true;
|
|
32
|
+
const prefix = resolvedAncestor.endsWith(path_1.default.sep)
|
|
33
|
+
? resolvedAncestor
|
|
34
|
+
: `${resolvedAncestor}${path_1.default.sep}`;
|
|
35
|
+
return resolvedTarget.startsWith(prefix);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Build ReactFlightWebpackPlugin `clientReferences`.
|
|
39
|
+
*
|
|
40
|
+
* Project roots (`app/`, `components/`, `lib/`, ...) are passed as watched
|
|
41
|
+
* directories so newly added `'use client'` files are registered without a full
|
|
42
|
+
* rebuild. Framework package paths stay as absolute files.
|
|
43
|
+
*/
|
|
44
|
+
function buildFlightClientReferenceOptions(cwd, explicitFiles = []) {
|
|
45
|
+
const roots = (0, client_manifest_1.discoverProjectClientRoots)(cwd).filter((root) => fs_1.default.existsSync(root.dir));
|
|
46
|
+
const directoryRefs = roots.map((root) => ({
|
|
47
|
+
directory: path_1.default.resolve(root.dir),
|
|
48
|
+
recursive: true,
|
|
49
|
+
include: /\.[cm]?[jt]sx?$/,
|
|
50
|
+
}));
|
|
51
|
+
// Always include app/ even if discover somehow missed it (empty cwd edge cases).
|
|
52
|
+
const appDir = (0, app_dir_1.resolveAppDir)(cwd);
|
|
53
|
+
if (fs_1.default.existsSync(appDir) &&
|
|
54
|
+
!directoryRefs.some((entry) => typeof entry !== 'string' && path_1.default.resolve(entry.directory) === path_1.default.resolve(appDir))) {
|
|
55
|
+
directoryRefs.unshift({
|
|
56
|
+
directory: path_1.default.resolve(appDir),
|
|
57
|
+
recursive: true,
|
|
58
|
+
include: /\.[cm]?[jt]sx?$/,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
const rootDirs = roots.map((root) => path_1.default.resolve(root.dir));
|
|
62
|
+
if (fs_1.default.existsSync(appDir)) {
|
|
63
|
+
rootDirs.push(path_1.default.resolve(appDir));
|
|
64
|
+
}
|
|
65
|
+
const externalFiles = Array.from(new Set(explicitFiles
|
|
66
|
+
.filter((entry) => typeof entry === 'string' && entry.length > 0)
|
|
67
|
+
.map((entry) => path_1.default.resolve(entry))
|
|
68
|
+
.filter((entry) => !rootDirs.some((dir) => isPathInside(entry, dir)))));
|
|
69
|
+
return [...directoryRefs, ...externalFiles];
|
|
70
|
+
}
|
|
25
71
|
// Find module path (handles monorepo hoisting)
|
|
26
72
|
const findModulePath = (moduleName, cwd) => {
|
|
27
73
|
const localPath = path_1.default.resolve(cwd, 'node_modules', moduleName);
|
|
@@ -65,6 +111,7 @@ function createServerWebpackConfig(options) {
|
|
|
65
111
|
const swcLoaderPath = resolveFromWorkspace('swc-loader', cwd);
|
|
66
112
|
const nullLoaderPath = resolveFromWorkspace('null-loader', cwd);
|
|
67
113
|
const cssLoaderPath = resolveFromWorkspace('css-loader', cwd);
|
|
114
|
+
const projectAliases = (0, project_alias_resolver_1.loadProjectWebpackAliases)(cwd);
|
|
68
115
|
// Generate server manifest first
|
|
69
116
|
const serverManifest = (0, server_manifest_1.generateServerManifest)(cwd, (0, app_dir_1.resolveAppDir)(cwd));
|
|
70
117
|
fs_1.default.writeFileSync(path_1.default.join(vistaDirs.server, 'server-manifest.json'), JSON.stringify(serverManifest, null, 2));
|
|
@@ -109,12 +156,13 @@ function createServerWebpackConfig(options) {
|
|
|
109
156
|
clean: !isDev,
|
|
110
157
|
},
|
|
111
158
|
externals: [
|
|
112
|
-
// Don't bundle node_modules on server
|
|
159
|
+
// Don't bundle node_modules on server. Project path aliases (@/…) stay inside the bundle.
|
|
113
160
|
({ request }, callback) => {
|
|
114
161
|
if (request &&
|
|
115
162
|
!request.startsWith('.') &&
|
|
116
163
|
!request.startsWith('/') &&
|
|
117
|
-
!path_1.default.isAbsolute(request)
|
|
164
|
+
!path_1.default.isAbsolute(request) &&
|
|
165
|
+
!(0, project_alias_resolver_1.requestUsesProjectAlias)(request, projectAliases)) {
|
|
118
166
|
// External - don't bundle
|
|
119
167
|
return callback(null, 'commonjs ' + request);
|
|
120
168
|
}
|
|
@@ -126,6 +174,7 @@ function createServerWebpackConfig(options) {
|
|
|
126
174
|
: false,
|
|
127
175
|
resolve: {
|
|
128
176
|
extensions: ['.tsx', '.ts', '.jsx', '.js'],
|
|
177
|
+
alias: projectAliases,
|
|
129
178
|
modules: [path_1.default.resolve(cwd, 'node_modules'), 'node_modules'],
|
|
130
179
|
},
|
|
131
180
|
module: {
|
|
@@ -189,6 +238,11 @@ function createServerWebpackConfig(options) {
|
|
|
189
238
|
],
|
|
190
239
|
devtool: isDev ? 'source-map' : false,
|
|
191
240
|
stats: 'minimal',
|
|
241
|
+
// Webpack's infrastructure logger prints `<i> [webpack-dev-middleware] …`.
|
|
242
|
+
// Vista logs compile failures itself.
|
|
243
|
+
infrastructureLogging: {
|
|
244
|
+
level: isDev ? 'none' : 'error',
|
|
245
|
+
},
|
|
192
246
|
};
|
|
193
247
|
}
|
|
194
248
|
/**
|
|
@@ -211,9 +265,11 @@ function createClientWebpackConfig(options) {
|
|
|
211
265
|
const reactFlightPluginPath = resolveFromWorkspace('react-server-dom-webpack/plugin', cwd);
|
|
212
266
|
const reactFlightClientPath = resolveFromWorkspace('react-server-dom-webpack/client.browser', cwd);
|
|
213
267
|
const ReactFlightWebpackPlugin = require(reactFlightPluginPath);
|
|
214
|
-
const
|
|
215
|
-
|
|
216
|
-
|
|
268
|
+
const projectAliases = (0, project_alias_resolver_1.loadProjectWebpackAliases)(cwd);
|
|
269
|
+
// Prefer watched project directories over a frozen absolute-file list so that
|
|
270
|
+
// newly added `'use client'` modules under components/, lib/, etc. enter the
|
|
271
|
+
// Flight client manifest without restarting the compiler.
|
|
272
|
+
const flightClientReferences = buildFlightClientReferenceOptions(cwd, clientReferenceFiles);
|
|
217
273
|
// Entry: Only client components
|
|
218
274
|
const clientEntry = path_1.default.join(vistaDirs.root, 'rsc-client.tsx');
|
|
219
275
|
return {
|
|
@@ -238,6 +294,7 @@ function createClientWebpackConfig(options) {
|
|
|
238
294
|
resolve: {
|
|
239
295
|
extensions: ['.tsx', '.ts', '.jsx', '.js'],
|
|
240
296
|
alias: {
|
|
297
|
+
...projectAliases,
|
|
241
298
|
react: reactPath,
|
|
242
299
|
'react-dom': reactDomPath,
|
|
243
300
|
'react/jsx-runtime': path_1.default.join(reactPath, 'jsx-runtime'),
|
|
@@ -340,7 +397,7 @@ function createClientWebpackConfig(options) {
|
|
|
340
397
|
{
|
|
341
398
|
directory: (0, app_dir_1.resolveAppDir)(cwd),
|
|
342
399
|
recursive: true,
|
|
343
|
-
include: /\.[jt]sx?$/,
|
|
400
|
+
include: /\.[cm]?[jt]sx?$/,
|
|
344
401
|
},
|
|
345
402
|
],
|
|
346
403
|
}),
|
|
@@ -422,6 +479,9 @@ function createClientWebpackConfig(options) {
|
|
|
422
479
|
],
|
|
423
480
|
devtool: isDev ? 'eval-cheap-module-source-map' : 'source-map',
|
|
424
481
|
stats: 'minimal',
|
|
482
|
+
infrastructureLogging: {
|
|
483
|
+
level: isDev ? 'none' : 'error',
|
|
484
|
+
},
|
|
425
485
|
};
|
|
426
486
|
}
|
|
427
487
|
/**
|
|
@@ -286,17 +286,18 @@ function scanForServerComponents(dir, appDir, components) {
|
|
|
286
286
|
continue;
|
|
287
287
|
try {
|
|
288
288
|
const source = fs_1.default.readFileSync(fullPath, 'utf-8');
|
|
289
|
-
|
|
290
|
-
|
|
289
|
+
const componentType = getComponentType(item.name);
|
|
290
|
+
const isClient = hasClientDirective(source);
|
|
291
|
+
if (!isClient || componentType !== 'component') {
|
|
291
292
|
const relativePath = (0, component_identity_1.relativeComponentPath)(appDir, fullPath);
|
|
292
|
-
const moduleId = (0, component_identity_1.createComponentId)('server', relativePath);
|
|
293
|
+
const moduleId = (0, component_identity_1.createComponentId)(isClient ? 'client' : 'server', relativePath);
|
|
293
294
|
const metadata = analyzeMetadata(source);
|
|
294
295
|
const renderConfig = analyzeRenderConfig(source);
|
|
295
296
|
components.push({
|
|
296
297
|
id: moduleId,
|
|
297
298
|
path: relativePath,
|
|
298
299
|
absolutePath: fullPath,
|
|
299
|
-
type:
|
|
300
|
+
type: componentType,
|
|
300
301
|
hasMetadata: metadata.hasMetadata,
|
|
301
302
|
hasGenerateMetadata: metadata.hasGenerateMetadata,
|
|
302
303
|
hasGenerateStaticParams: renderConfig.hasGenerateStaticParams,
|
package/dist/config.d.ts
CHANGED
|
@@ -12,6 +12,11 @@ export interface VistaEngineConfig {
|
|
|
12
12
|
* Compatibility alias accepted: webpack.
|
|
13
13
|
*/
|
|
14
14
|
variant?: VistaEngineVariant | VistaEngineAlias;
|
|
15
|
+
/**
|
|
16
|
+
* Flashpack crate pipeline launched by the vista package.
|
|
17
|
+
* Set by create-vista-app when the selected engine is flashpack.
|
|
18
|
+
*/
|
|
19
|
+
pipeline?: 'flashpack-cli';
|
|
15
20
|
}
|
|
16
21
|
export interface StructureValidationConfig {
|
|
17
22
|
/** Enable structure validation. Default: true */
|
package/dist/config.js
CHANGED
|
@@ -90,8 +90,22 @@ function readEngineVariantFromEnv(env) {
|
|
|
90
90
|
return 'default';
|
|
91
91
|
return undefined;
|
|
92
92
|
}
|
|
93
|
+
function readEngineVariantFromPackage(cwd) {
|
|
94
|
+
try {
|
|
95
|
+
const pkg = JSON.parse(fs_1.default.readFileSync(path_1.default.join(cwd, 'package.json'), 'utf8'));
|
|
96
|
+
const vista = pkg.vista;
|
|
97
|
+
const raw = typeof vista === 'string' ? vista : vista?.engine;
|
|
98
|
+
return normalizeEngineVariant(raw);
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
93
104
|
function resolveEngineVariant(config, env = process.env) {
|
|
94
|
-
return readEngineVariantFromEnv(env) ||
|
|
105
|
+
return (readEngineVariantFromEnv(env) ||
|
|
106
|
+
readEngineVariantFromPackage(env.VISTA_ARTIFACT_ROOT || process.cwd()) ||
|
|
107
|
+
readEngineVariantFromConfig(config) ||
|
|
108
|
+
'default');
|
|
95
109
|
}
|
|
96
110
|
function applyEngineVariantToEnv(variant, env = process.env) {
|
|
97
111
|
env.VISTA_ENGINE = variant;
|
|
@@ -17,7 +17,7 @@ const RENDER_YAML_TEMPLATE = `services:
|
|
|
17
17
|
buildCommand: |
|
|
18
18
|
npm install --no-audit --no-fund
|
|
19
19
|
npm run build
|
|
20
|
-
startCommand:
|
|
20
|
+
startCommand: node .vista/standalone/server.js
|
|
21
21
|
envVars:
|
|
22
22
|
- key: NODE_ENV
|
|
23
23
|
value: production
|
|
@@ -45,7 +45,7 @@ exports.renderAdapter = {
|
|
|
45
45
|
artifactPaths,
|
|
46
46
|
instructions: [
|
|
47
47
|
'Connect this repository on Render and select Blueprint (render.yaml).',
|
|
48
|
-
'Or create a Web Service with buildCommand "npm run build" and startCommand "
|
|
48
|
+
'Or create a Web Service with buildCommand "npm run build" and startCommand "node .vista/standalone/server.js".',
|
|
49
49
|
],
|
|
50
50
|
};
|
|
51
51
|
},
|
package/dist/deploy/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export type { DeployContext, DeployResult, DeployAdapter, ResolvedDeployTarget }
|
|
|
5
5
|
export interface RunDeployOptions {
|
|
6
6
|
cwd?: string;
|
|
7
7
|
target?: string | null;
|
|
8
|
+
output?: 'standalone' | 'static' | 'hybrid';
|
|
8
9
|
dryRun?: boolean;
|
|
9
10
|
skipBuild?: boolean;
|
|
10
11
|
prod?: boolean;
|
package/dist/deploy/index.js
CHANGED
|
@@ -23,6 +23,9 @@ function createContext(options) {
|
|
|
23
23
|
const cwd = options.cwd ?? process.cwd();
|
|
24
24
|
const config = (0, config_1.loadConfig)(cwd);
|
|
25
25
|
const deployConfig = (0, config_1.resolveDeployConfig)(config);
|
|
26
|
+
if (options.output) {
|
|
27
|
+
deployConfig.output = options.output;
|
|
28
|
+
}
|
|
26
29
|
const target = (0, detect_1.resolveDeployTarget)(cwd, deployConfig, options.target ?? null);
|
|
27
30
|
return {
|
|
28
31
|
cwd,
|
|
@@ -17,7 +17,28 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
17
17
|
const path_1 = __importDefault(require("path"));
|
|
18
18
|
const utils_1 = require("./utils");
|
|
19
19
|
function isStaticOnlyDeploy(ctx) {
|
|
20
|
-
|
|
20
|
+
if (ctx.deployConfig.output === 'static') {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
if (ctx.target === 'cloudflare') {
|
|
24
|
+
if (ctx.config.deploy?.output === 'standalone') {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
if (process.env.CF_PAGES === '1' || process.env.CLOUDFLARE_PAGES) {
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
const wranglerPath = path_1.default.join(ctx.cwd, 'wrangler.toml');
|
|
31
|
+
if (fs_1.default.existsSync(wranglerPath)) {
|
|
32
|
+
const content = fs_1.default.readFileSync(wranglerPath, 'utf8');
|
|
33
|
+
if (content.includes('pages_build_output_dir')) {
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
if (content.includes('[[containers]]') || content.includes('main =')) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return false;
|
|
21
42
|
}
|
|
22
43
|
function resolveStandaloneServerPath(ctx) {
|
|
23
44
|
return path_1.default.join(ctx.vistaDir, 'standalone', 'server.js');
|