@cloudwerk/vite-plugin 0.6.0 → 0.6.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/dist/index.js +115 -3
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -57,6 +57,7 @@ function generateServerEntry(manifest, scanResult, options, entryOptions) {
|
|
|
57
57
|
let middlewareIndex = 0;
|
|
58
58
|
let errorIndex = 0;
|
|
59
59
|
let notFoundIndex = 0;
|
|
60
|
+
const ssgPageInfo = [];
|
|
60
61
|
for (const err of scanResult.errors) {
|
|
61
62
|
if (!importedModules.has(err.absolutePath)) {
|
|
62
63
|
const varName = `error_${errorIndex++}`;
|
|
@@ -109,6 +110,10 @@ function generateServerEntry(manifest, scanResult, options, entryOptions) {
|
|
|
109
110
|
if (route.fileType === "page") {
|
|
110
111
|
const varName = `page_${pageIndex++}`;
|
|
111
112
|
imports.push(`import * as ${varName} from '${route.absolutePath}'`);
|
|
113
|
+
const hasDynamicSegments = route.segments.some(
|
|
114
|
+
(s) => s.type === "dynamic" || s.type === "catchAll" || s.type === "optionalCatchAll"
|
|
115
|
+
);
|
|
116
|
+
ssgPageInfo.push({ varName, urlPattern: route.urlPattern, hasDynamicSegments });
|
|
112
117
|
const layoutChain = route.layouts.map((p) => layoutModules.get(p)).join(", ");
|
|
113
118
|
const middlewareChain = route.middleware.map((p) => middlewareModules.get(p)).join(", ");
|
|
114
119
|
const errorModule = route.errorBoundary ? errorModules.get(route.errorBoundary) : null;
|
|
@@ -140,6 +145,7 @@ function generateServerEntry(manifest, scanResult, options, entryOptions) {
|
|
|
140
145
|
*/
|
|
141
146
|
|
|
142
147
|
import { Hono } from 'hono'
|
|
148
|
+
import { ssgParams } from 'hono/ssg'
|
|
143
149
|
import { contextMiddleware, createHandlerAdapter, createMiddlewareAdapter, setRouteConfig, NotFoundError, RedirectError } from '@cloudwerk/core/runtime'
|
|
144
150
|
import { setActiveRenderer } from '@cloudwerk/ui'
|
|
145
151
|
|
|
@@ -310,6 +316,11 @@ function registerPage(app, pattern, pageModule, layoutModules, middlewareModules
|
|
|
310
316
|
})
|
|
311
317
|
}
|
|
312
318
|
|
|
319
|
+
// Apply SSG params middleware if page has generateStaticParams (for static generation)
|
|
320
|
+
if (typeof pageModule.generateStaticParams === 'function') {
|
|
321
|
+
app.use(pattern, ssgParams(pageModule.generateStaticParams))
|
|
322
|
+
}
|
|
323
|
+
|
|
313
324
|
// Register GET handler for page
|
|
314
325
|
app.get(pattern, async (c) => {
|
|
315
326
|
const params = c.req.param()
|
|
@@ -474,6 +485,13 @@ app.use('*', async (c, next) => {
|
|
|
474
485
|
${pageRegistrations.join("\n")}
|
|
475
486
|
${routeRegistrations.join("\n")}
|
|
476
487
|
|
|
488
|
+
// SSG routes endpoint - returns all static routes for build-time generation
|
|
489
|
+
app.get('/__ssg/routes', async (c) => {
|
|
490
|
+
const routes = []
|
|
491
|
+
${generateSSGRouteChecks(ssgPageInfo)}
|
|
492
|
+
return c.json({ routes })
|
|
493
|
+
})
|
|
494
|
+
|
|
477
495
|
// 404 handler
|
|
478
496
|
app.notFound(async (c) => {
|
|
479
497
|
const path = c.req.path
|
|
@@ -545,6 +563,36 @@ ${generateQueueExports(queueManifest)}
|
|
|
545
563
|
${generateServiceRegistration(serviceManifest)}
|
|
546
564
|
`;
|
|
547
565
|
}
|
|
566
|
+
function generateSSGRouteChecks(pages) {
|
|
567
|
+
const lines = [];
|
|
568
|
+
for (const page of pages) {
|
|
569
|
+
if (page.hasDynamicSegments) {
|
|
570
|
+
lines.push(` // ${page.urlPattern}`);
|
|
571
|
+
lines.push(` if (typeof ${page.varName}.generateStaticParams === 'function') {`);
|
|
572
|
+
lines.push(` try {`);
|
|
573
|
+
lines.push(` const params = await ${page.varName}.generateStaticParams()`);
|
|
574
|
+
lines.push(` if (Array.isArray(params)) {`);
|
|
575
|
+
lines.push(` for (const p of params) {`);
|
|
576
|
+
lines.push(` let url = '${page.urlPattern}'`);
|
|
577
|
+
lines.push(` for (const [key, value] of Object.entries(p)) {`);
|
|
578
|
+
lines.push(` url = url.replace(':' + key, String(value))`);
|
|
579
|
+
lines.push(` }`);
|
|
580
|
+
lines.push(` routes.push(url)`);
|
|
581
|
+
lines.push(` }`);
|
|
582
|
+
lines.push(` }`);
|
|
583
|
+
lines.push(` } catch (e) {`);
|
|
584
|
+
lines.push(` console.error('SSG: Failed to get params for ${page.urlPattern}:', e)`);
|
|
585
|
+
lines.push(` }`);
|
|
586
|
+
lines.push(` }`);
|
|
587
|
+
} else {
|
|
588
|
+
lines.push(` // ${page.urlPattern}`);
|
|
589
|
+
lines.push(` if ('config' in ${page.varName} && ${page.varName}.config?.rendering === 'static') {`);
|
|
590
|
+
lines.push(` routes.push('${page.urlPattern}')`);
|
|
591
|
+
lines.push(` }`);
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
return lines.join("\n");
|
|
595
|
+
}
|
|
548
596
|
function generateQueueExports(queueManifest) {
|
|
549
597
|
if (!queueManifest || queueManifest.queues.length === 0) {
|
|
550
598
|
return "";
|
|
@@ -1919,13 +1967,71 @@ function cloudwerkPlugin(options = {}) {
|
|
|
1919
1967
|
return null;
|
|
1920
1968
|
},
|
|
1921
1969
|
/**
|
|
1922
|
-
* Transform hook to detect and wrap client components
|
|
1970
|
+
* Transform hook to detect and wrap client components,
|
|
1971
|
+
* and rewrite binding imports to use the bindings proxy.
|
|
1923
1972
|
*/
|
|
1924
1973
|
transform(code, id) {
|
|
1925
1974
|
if (!state) return null;
|
|
1926
1975
|
if (id.includes("node_modules")) return null;
|
|
1927
1976
|
if (!id.endsWith(".tsx") && !id.endsWith(".ts")) return null;
|
|
1928
|
-
|
|
1977
|
+
let transformedCode = code;
|
|
1978
|
+
let wasTransformed = false;
|
|
1979
|
+
const bindingsImportRegex = /import\s*\{([^}]+)\}\s*from\s*['"]@cloudwerk\/core\/bindings['"]/g;
|
|
1980
|
+
if (bindingsImportRegex.test(code)) {
|
|
1981
|
+
bindingsImportRegex.lastIndex = 0;
|
|
1982
|
+
transformedCode = code.replace(bindingsImportRegex, (match, imports) => {
|
|
1983
|
+
const importNames = imports.split(",").map((s) => s.trim()).filter(Boolean);
|
|
1984
|
+
const knownExports = [
|
|
1985
|
+
"bindings",
|
|
1986
|
+
"getBinding",
|
|
1987
|
+
"hasBinding",
|
|
1988
|
+
"getBindingNames",
|
|
1989
|
+
"queues",
|
|
1990
|
+
"getQueue",
|
|
1991
|
+
"hasQueue",
|
|
1992
|
+
"getQueueNames",
|
|
1993
|
+
"services",
|
|
1994
|
+
"getService",
|
|
1995
|
+
"hasService",
|
|
1996
|
+
"getServiceNames",
|
|
1997
|
+
"registerLocalService",
|
|
1998
|
+
"unregisterLocalService",
|
|
1999
|
+
"clearLocalServices",
|
|
2000
|
+
"durableObjects",
|
|
2001
|
+
"getDurableObject",
|
|
2002
|
+
"hasDurableObject",
|
|
2003
|
+
"getDurableObjectNames",
|
|
2004
|
+
"createLazyBinding"
|
|
2005
|
+
];
|
|
2006
|
+
const runtimeImports = [];
|
|
2007
|
+
const bindingImports = [];
|
|
2008
|
+
for (const name of importNames) {
|
|
2009
|
+
const [originalName] = name.split(/\s+as\s+/);
|
|
2010
|
+
if (knownExports.includes(originalName.trim())) {
|
|
2011
|
+
runtimeImports.push(name);
|
|
2012
|
+
} else {
|
|
2013
|
+
bindingImports.push(name);
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
2016
|
+
if (bindingImports.length === 0) {
|
|
2017
|
+
return match;
|
|
2018
|
+
}
|
|
2019
|
+
wasTransformed = true;
|
|
2020
|
+
const parts = [];
|
|
2021
|
+
const helperImports = runtimeImports.includes("createLazyBinding") ? runtimeImports : ["createLazyBinding", ...runtimeImports];
|
|
2022
|
+
parts.push(`import { ${helperImports.join(", ")} } from '@cloudwerk/core/bindings'`);
|
|
2023
|
+
for (const name of bindingImports) {
|
|
2024
|
+
const aliasMatch = name.match(/^(\w+)\s+as\s+(\w+)$/);
|
|
2025
|
+
if (aliasMatch) {
|
|
2026
|
+
parts.push(`const ${aliasMatch[2]} = createLazyBinding('${aliasMatch[1]}')`);
|
|
2027
|
+
} else {
|
|
2028
|
+
parts.push(`const ${name.trim()} = createLazyBinding('${name.trim()}')`);
|
|
2029
|
+
}
|
|
2030
|
+
}
|
|
2031
|
+
return parts.join("\n");
|
|
2032
|
+
});
|
|
2033
|
+
}
|
|
2034
|
+
if (hasUseClientDirective(transformedCode)) {
|
|
1929
2035
|
const componentId = generateComponentId(id, state.options.root);
|
|
1930
2036
|
const bundlePath = `${state.options.hydrationEndpoint}/${componentId}.js`;
|
|
1931
2037
|
const info = {
|
|
@@ -1938,7 +2044,7 @@ function cloudwerkPlugin(options = {}) {
|
|
|
1938
2044
|
if (state.options.verbose) {
|
|
1939
2045
|
console.log(`[cloudwerk] Detected client component: ${componentId}`);
|
|
1940
2046
|
}
|
|
1941
|
-
const result = transformClientComponent(
|
|
2047
|
+
const result = transformClientComponent(transformedCode, {
|
|
1942
2048
|
componentId,
|
|
1943
2049
|
bundlePath: id
|
|
1944
2050
|
// Use file path for Vite to resolve in dev mode
|
|
@@ -1951,6 +2057,12 @@ function cloudwerkPlugin(options = {}) {
|
|
|
1951
2057
|
map: null
|
|
1952
2058
|
};
|
|
1953
2059
|
}
|
|
2060
|
+
if (wasTransformed) {
|
|
2061
|
+
return {
|
|
2062
|
+
code: transformedCode,
|
|
2063
|
+
map: null
|
|
2064
|
+
};
|
|
2065
|
+
}
|
|
1954
2066
|
return null;
|
|
1955
2067
|
}
|
|
1956
2068
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudwerk/vite-plugin",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "Vite plugin for Cloudwerk file-based routing with virtual entry generation",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@swc/core": "^1.3.100",
|
|
22
|
-
"@cloudwerk/core": "^0.
|
|
23
|
-
"@cloudwerk/ui": "^0.
|
|
22
|
+
"@cloudwerk/core": "^0.14.0",
|
|
23
|
+
"@cloudwerk/ui": "^0.14.0"
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|
|
26
26
|
"vite": "^5.0.0 || ^6.0.0",
|