@buzola/vite-plugin 0.0.11 → 0.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/plugin.test.d.ts +2 -0
- package/dist/__tests__/plugin.test.d.ts.map +1 -0
- package/dist/__tests__/plugin.test.js +110 -0
- package/dist/__tests__/plugin.test.js.map +1 -0
- package/dist/index.d.ts +0 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -7
- package/dist/index.js.map +1 -1
- package/dist/plugin.d.ts +2 -20
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +12 -31
- package/dist/plugin.js.map +1 -1
- package/package.json +3 -5
- package/src/__tests__/plugin.test.ts +129 -0
- package/src/index.ts +0 -21
- package/src/plugin.ts +22 -56
- package/dist/__tests__/codegen.test.d.ts +0 -2
- package/dist/__tests__/codegen.test.d.ts.map +0 -1
- package/dist/__tests__/codegen.test.js +0 -208
- package/dist/__tests__/codegen.test.js.map +0 -1
- package/dist/__tests__/conventions.test.d.ts +0 -2
- package/dist/__tests__/conventions.test.d.ts.map +0 -1
- package/dist/__tests__/conventions.test.js +0 -80
- package/dist/__tests__/conventions.test.js.map +0 -1
- package/dist/__tests__/page-extractor.test.d.ts +0 -2
- package/dist/__tests__/page-extractor.test.d.ts.map +0 -1
- package/dist/__tests__/page-extractor.test.js +0 -82
- package/dist/__tests__/page-extractor.test.js.map +0 -1
- package/dist/__tests__/tree-builder.test.d.ts +0 -2
- package/dist/__tests__/tree-builder.test.d.ts.map +0 -1
- package/dist/__tests__/tree-builder.test.js +0 -474
- package/dist/__tests__/tree-builder.test.js.map +0 -1
- package/dist/cli.d.ts +0 -3
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js +0 -39
- package/dist/cli.js.map +0 -1
- package/dist/config.d.ts +0 -20
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -20
- package/dist/config.js.map +0 -1
- package/dist/conventions.d.ts +0 -53
- package/dist/conventions.d.ts.map +0 -1
- package/dist/conventions.js +0 -82
- package/dist/conventions.js.map +0 -1
- package/dist/generate.d.ts +0 -26
- package/dist/generate.d.ts.map +0 -1
- package/dist/generate.js +0 -44
- package/dist/generate.js.map +0 -1
- package/dist/generator/codegen.d.ts +0 -19
- package/dist/generator/codegen.d.ts.map +0 -1
- package/dist/generator/codegen.js +0 -170
- package/dist/generator/codegen.js.map +0 -1
- package/dist/generator/page-extractor.d.ts +0 -21
- package/dist/generator/page-extractor.d.ts.map +0 -1
- package/dist/generator/page-extractor.js +0 -23
- package/dist/generator/page-extractor.js.map +0 -1
- package/dist/generator/scanner.d.ts +0 -11
- package/dist/generator/scanner.d.ts.map +0 -1
- package/dist/generator/scanner.js +0 -34
- package/dist/generator/scanner.js.map +0 -1
- package/dist/generator/tree-builder.d.ts +0 -54
- package/dist/generator/tree-builder.d.ts.map +0 -1
- package/dist/generator/tree-builder.js +0 -364
- package/dist/generator/tree-builder.js.map +0 -1
- package/src/__tests__/codegen.test.ts +0 -229
- package/src/__tests__/conventions.test.ts +0 -93
- package/src/__tests__/page-extractor.test.ts +0 -95
- package/src/__tests__/tree-builder.test.ts +0 -554
- package/src/cli.ts +0 -43
- package/src/config.ts +0 -35
- package/src/conventions.ts +0 -116
- package/src/generate.ts +0 -64
- package/src/generator/codegen.ts +0 -221
- package/src/generator/page-extractor.ts +0 -48
- package/src/generator/scanner.ts +0 -45
- package/src/generator/tree-builder.ts +0 -454
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/plugin.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { describe, expect, it } from 'bun:test';
|
|
2
|
+
import * as fs from 'node:fs';
|
|
3
|
+
import * as os from 'node:os';
|
|
4
|
+
import * as path from 'node:path';
|
|
5
|
+
import { build } from 'vite';
|
|
6
|
+
import { buzolaPlugin } from '../plugin.js';
|
|
7
|
+
function makeEmptyRoutesFixture() {
|
|
8
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'buzola-vite-test-'));
|
|
9
|
+
fs.mkdirSync(path.join(root, 'routes'));
|
|
10
|
+
return { root, cleanup: () => fs.rmSync(root, { recursive: true, force: true }) };
|
|
11
|
+
}
|
|
12
|
+
function writeEntry(root, body) {
|
|
13
|
+
const entryPath = path.join(root, 'entry.ts');
|
|
14
|
+
fs.writeFileSync(entryPath, body);
|
|
15
|
+
return entryPath;
|
|
16
|
+
}
|
|
17
|
+
describe('buzolaPlugin (Vite)', () => {
|
|
18
|
+
it('vite build resolves virtual:buzola/routes through the plugin', async () => {
|
|
19
|
+
const { root, cleanup } = makeEmptyRoutesFixture();
|
|
20
|
+
try {
|
|
21
|
+
const entryPath = writeEntry(root, `import { routes, pageRegistry } from 'virtual:buzola/routes'\nexport { routes, pageRegistry }\n`);
|
|
22
|
+
const result = await build({
|
|
23
|
+
root,
|
|
24
|
+
plugins: [buzolaPlugin({ routesDir: 'routes', output: 'buzola.gen.ts' })],
|
|
25
|
+
build: {
|
|
26
|
+
lib: { entry: entryPath, formats: ['es'], fileName: 'bundle' },
|
|
27
|
+
outDir: path.join(root, 'dist'),
|
|
28
|
+
write: false,
|
|
29
|
+
rollupOptions: { external: ['react', '@buzola/router'] },
|
|
30
|
+
},
|
|
31
|
+
logLevel: 'silent',
|
|
32
|
+
});
|
|
33
|
+
const chunk = result[0].output.find((o) => o.type === 'chunk');
|
|
34
|
+
expect(chunk).toBeDefined();
|
|
35
|
+
expect(chunk.code).toContain('pageRegistry');
|
|
36
|
+
expect(chunk.code).toContain('buildRouteTree');
|
|
37
|
+
}
|
|
38
|
+
finally {
|
|
39
|
+
cleanup();
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
it('vite build resolves named virtual module ID', async () => {
|
|
43
|
+
const { root, cleanup } = makeEmptyRoutesFixture();
|
|
44
|
+
try {
|
|
45
|
+
const entryPath = writeEntry(root, `import { routes, pageRegistry } from 'virtual:buzola/admin/routes'\nexport { routes, pageRegistry }\n`);
|
|
46
|
+
const result = await build({
|
|
47
|
+
root,
|
|
48
|
+
plugins: [buzolaPlugin({ name: 'admin', routesDir: 'routes', output: 'buzola.gen.ts' })],
|
|
49
|
+
build: {
|
|
50
|
+
lib: { entry: entryPath, formats: ['es'], fileName: 'bundle' },
|
|
51
|
+
outDir: path.join(root, 'dist'),
|
|
52
|
+
write: false,
|
|
53
|
+
rollupOptions: { external: ['react', '@buzola/router'] },
|
|
54
|
+
},
|
|
55
|
+
logLevel: 'silent',
|
|
56
|
+
});
|
|
57
|
+
const chunk = result[0].output.find((o) => o.type === 'chunk');
|
|
58
|
+
expect(chunk).toBeDefined();
|
|
59
|
+
expect(chunk.code).toContain('pageRegistry');
|
|
60
|
+
}
|
|
61
|
+
finally {
|
|
62
|
+
cleanup();
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
it('writes buzola.gen.ts during vite build', async () => {
|
|
66
|
+
const { root, cleanup } = makeEmptyRoutesFixture();
|
|
67
|
+
try {
|
|
68
|
+
const entryPath = writeEntry(root, `export const x = 1\n`);
|
|
69
|
+
const outputPath = path.join(root, 'buzola.gen.ts');
|
|
70
|
+
expect(fs.existsSync(outputPath)).toBe(false);
|
|
71
|
+
await build({
|
|
72
|
+
root,
|
|
73
|
+
plugins: [buzolaPlugin({ routesDir: 'routes', output: 'buzola.gen.ts' })],
|
|
74
|
+
build: {
|
|
75
|
+
lib: { entry: entryPath, formats: ['es'], fileName: 'bundle' },
|
|
76
|
+
outDir: path.join(root, 'dist'),
|
|
77
|
+
write: false,
|
|
78
|
+
},
|
|
79
|
+
logLevel: 'silent',
|
|
80
|
+
});
|
|
81
|
+
expect(fs.existsSync(outputPath)).toBe(true);
|
|
82
|
+
expect(fs.readFileSync(outputPath, 'utf-8')).toContain('pageRegistry');
|
|
83
|
+
}
|
|
84
|
+
finally {
|
|
85
|
+
cleanup();
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
it('vite build succeeds when routes dir does not exist', async () => {
|
|
89
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'buzola-vite-test-'));
|
|
90
|
+
try {
|
|
91
|
+
const entryPath = writeEntry(root, `export const x = 1\n`);
|
|
92
|
+
const result = await build({
|
|
93
|
+
root,
|
|
94
|
+
plugins: [buzolaPlugin({ routesDir: 'nonexistent', output: 'buzola.gen.ts' })],
|
|
95
|
+
build: {
|
|
96
|
+
lib: { entry: entryPath, formats: ['es'], fileName: 'bundle' },
|
|
97
|
+
outDir: path.join(root, 'dist'),
|
|
98
|
+
write: false,
|
|
99
|
+
},
|
|
100
|
+
logLevel: 'silent',
|
|
101
|
+
});
|
|
102
|
+
expect(result[0].output.length).toBeGreaterThan(0);
|
|
103
|
+
expect(fs.existsSync(path.join(root, 'buzola.gen.ts'))).toBe(false);
|
|
104
|
+
}
|
|
105
|
+
finally {
|
|
106
|
+
fs.rmSync(root, { recursive: true, force: true });
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
//# sourceMappingURL=plugin.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.test.js","sourceRoot":"","sources":["../../src/__tests__/plugin.test.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,17 +1,3 @@
|
|
|
1
1
|
export { buzolaPlugin } from './plugin.js';
|
|
2
2
|
export type { BuzolaPluginOptions } from './plugin.js';
|
|
3
|
-
export { generate } from './generate.js';
|
|
4
|
-
export type { GenerateOptions } from './generate.js';
|
|
5
|
-
export { loadConfig } from './config.js';
|
|
6
|
-
export type { BuzolaConfig } from './config.js';
|
|
7
|
-
export { scanRouteFiles } from './generator/scanner.js';
|
|
8
|
-
export type { ScannedFile } from './generator/scanner.js';
|
|
9
|
-
export { buildFileRouteTree } from './generator/tree-builder.js';
|
|
10
|
-
export type { FileRouteNode, PageExportInfo } from './generator/tree-builder.js';
|
|
11
|
-
export { generateRouteModule } from './generator/codegen.js';
|
|
12
|
-
export type { CodegenOptions } from './generator/codegen.js';
|
|
13
|
-
export { extractPages } from './generator/page-extractor.js';
|
|
14
|
-
export type { ExtractedPage, ExtractedParam, ModuleLoader } from './generator/page-extractor.js';
|
|
15
|
-
export { isRouteFile, parseDirName, parseFileName, parseRouteFile } from './conventions.js';
|
|
16
|
-
export type { ParsedRouteFile } from './conventions.js';
|
|
17
3
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,YAAY,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,YAAY,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,2 @@
|
|
|
1
1
|
export { buzolaPlugin } from './plugin.js';
|
|
2
|
-
export { generate } from './generate.js';
|
|
3
|
-
export { loadConfig } from './config.js';
|
|
4
|
-
export { scanRouteFiles } from './generator/scanner.js';
|
|
5
|
-
export { buildFileRouteTree } from './generator/tree-builder.js';
|
|
6
|
-
export { generateRouteModule } from './generator/codegen.js';
|
|
7
|
-
export { extractPages } from './generator/page-extractor.js';
|
|
8
|
-
export { isRouteFile, parseDirName, parseFileName, parseRouteFile } from './conventions.js';
|
|
9
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA"}
|
package/dist/plugin.d.ts
CHANGED
|
@@ -1,24 +1,6 @@
|
|
|
1
|
+
import { type BasePluginOptions } from '@buzola/codegen';
|
|
1
2
|
import type { Plugin } from 'vite';
|
|
2
|
-
export interface BuzolaPluginOptions {
|
|
3
|
-
/**
|
|
4
|
-
* Unique name for this plugin instance. Required when registering multiple
|
|
5
|
-
* entrypoints in the same Vite config. Affects the plugin name
|
|
6
|
-
* (`buzola:${name}`) and the virtual module ID (`virtual:buzola/${name}/routes`).
|
|
7
|
-
*
|
|
8
|
-
* When omitted, the plugin uses `buzola` as its name and
|
|
9
|
-
* `virtual:buzola/routes` as the virtual module ID.
|
|
10
|
-
*/
|
|
11
|
-
name?: string;
|
|
12
|
-
/** Path to routes directory, relative to project root. Defaults to "src/routes". */
|
|
13
|
-
routesDir?: string;
|
|
14
|
-
/** Path to output generated file, relative to project root. Defaults to "src/buzola.gen.ts". */
|
|
15
|
-
output?: string;
|
|
16
|
-
/**
|
|
17
|
-
* Parameter names that should be persistent across navigations.
|
|
18
|
-
* When set, generates a BuzolaPersistentParams type augmentation
|
|
19
|
-
* so these params become optional in Link and navigate() calls.
|
|
20
|
-
*/
|
|
21
|
-
persistentParams?: string[];
|
|
3
|
+
export interface BuzolaPluginOptions extends BasePluginOptions {
|
|
22
4
|
}
|
|
23
5
|
/**
|
|
24
6
|
* Vite plugin for Buzola page-centric routing.
|
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,iBAAiB,EAOtB,MAAM,iBAAiB,CAAA;AAExB,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAA;AAEjD,MAAM,WAAW,mBAAoB,SAAQ,iBAAiB;CAAG;AAEjE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAAC,OAAO,GAAE,mBAAwB,GAAG,MAAM,CAiEtE"}
|
package/dist/plugin.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { buildVirtualSource, generate, isRouteFile, resolveOptions, resolveVirtualModuleId, } from '@buzola/codegen';
|
|
2
2
|
import * as path from 'node:path';
|
|
3
|
-
import { loadConfig } from './config.js';
|
|
4
|
-
import { generate } from './generate.js';
|
|
5
3
|
/**
|
|
6
4
|
* Vite plugin for Buzola page-centric routing.
|
|
7
5
|
*
|
|
@@ -17,48 +15,35 @@ import { generate } from './generate.js';
|
|
|
17
15
|
* Plugin options take precedence over the config file.
|
|
18
16
|
*/
|
|
19
17
|
export function buzolaPlugin(options = {}) {
|
|
20
|
-
const {
|
|
21
|
-
const
|
|
22
|
-
const virtualModuleId = nameOption ? `virtual:buzola/${nameOption}/routes` : 'virtual:buzola/routes';
|
|
23
|
-
const resolvedVirtualId = '\0' + virtualModuleId;
|
|
24
|
-
let root;
|
|
18
|
+
const { pluginName, id: virtualId } = resolveVirtualModuleId(options.name);
|
|
19
|
+
const resolvedVirtualId = '\0' + virtualId;
|
|
25
20
|
let baseOptions;
|
|
21
|
+
let virtualSource;
|
|
26
22
|
let server;
|
|
27
23
|
return {
|
|
28
24
|
name: pluginName,
|
|
29
25
|
enforce: 'pre',
|
|
30
26
|
async configResolved(config) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const routesDir = options.routesDir ?? fileConfig.routesDir ?? 'src/routes';
|
|
34
|
-
const output = options.output ?? fileConfig.output ?? 'src/buzola.gen.ts';
|
|
35
|
-
const persistentParams = options.persistentParams ?? fileConfig.persistentParams;
|
|
36
|
-
baseOptions = {
|
|
37
|
-
routesDir: path.resolve(root, routesDir),
|
|
38
|
-
outputPath: path.resolve(root, output),
|
|
39
|
-
persistentParams,
|
|
40
|
-
};
|
|
27
|
+
baseOptions = await resolveOptions({ ...options, root: config.root });
|
|
28
|
+
virtualSource = buildVirtualSource(baseOptions.outputPath);
|
|
41
29
|
},
|
|
42
30
|
configureServer(srv) {
|
|
43
31
|
server = srv;
|
|
44
32
|
},
|
|
45
33
|
async buildStart() {
|
|
46
|
-
if (!fs.existsSync(baseOptions.routesDir))
|
|
47
|
-
return;
|
|
48
34
|
if (server) {
|
|
49
|
-
await generate({ ...baseOptions, moduleLoader: (p) => server.ssrLoadModule(p) });
|
|
35
|
+
await generate({ ...baseOptions, optional: true, moduleLoader: (p) => server.ssrLoadModule(p) });
|
|
50
36
|
}
|
|
51
37
|
else {
|
|
52
|
-
// Production build — create a temporary Vite server for module loading
|
|
53
38
|
const { createServer } = await import('vite');
|
|
54
39
|
const tempServer = await createServer({
|
|
55
|
-
root,
|
|
40
|
+
root: baseOptions.root,
|
|
56
41
|
server: { middlewareMode: true },
|
|
57
42
|
logLevel: 'silent',
|
|
58
43
|
optimizeDeps: { noDiscovery: true },
|
|
59
44
|
});
|
|
60
45
|
try {
|
|
61
|
-
await generate({ ...baseOptions, moduleLoader: (p) => tempServer.ssrLoadModule(p) });
|
|
46
|
+
await generate({ ...baseOptions, optional: true, moduleLoader: (p) => tempServer.ssrLoadModule(p) });
|
|
62
47
|
}
|
|
63
48
|
finally {
|
|
64
49
|
await tempServer.close();
|
|
@@ -66,25 +51,21 @@ export function buzolaPlugin(options = {}) {
|
|
|
66
51
|
}
|
|
67
52
|
},
|
|
68
53
|
resolveId(id) {
|
|
69
|
-
if (id ===
|
|
54
|
+
if (id === virtualId) {
|
|
70
55
|
return resolvedVirtualId;
|
|
71
56
|
}
|
|
72
57
|
},
|
|
73
58
|
load(id) {
|
|
74
59
|
if (id === resolvedVirtualId) {
|
|
75
|
-
return
|
|
60
|
+
return virtualSource;
|
|
76
61
|
}
|
|
77
62
|
},
|
|
78
63
|
async handleHotUpdate({ file }) {
|
|
79
|
-
if (!file.startsWith(baseOptions.routesDir) || !
|
|
64
|
+
if (!server || !file.startsWith(baseOptions.routesDir) || !isRouteFile(path.basename(file)))
|
|
80
65
|
return;
|
|
81
66
|
const changed = await generate({ ...baseOptions, moduleLoader: (p) => server.ssrLoadModule(p) });
|
|
82
67
|
if (!changed)
|
|
83
68
|
return;
|
|
84
|
-
// Invalidate the virtual module so Vite re-evaluates it.
|
|
85
|
-
// Vite propagates the update through the import chain — if the app
|
|
86
|
-
// supports HMR for the route tree, no full-page reload is needed.
|
|
87
|
-
// If not, Vite falls back to full-reload automatically.
|
|
88
69
|
const mod = server.moduleGraph.getModuleById(resolvedVirtualId);
|
|
89
70
|
if (mod) {
|
|
90
71
|
server.moduleGraph.invalidateModule(mod);
|
package/dist/plugin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@buzola/vite-plugin",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.12",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
7
|
-
"bin": {
|
|
8
|
-
"buzola": "./dist/cli.js"
|
|
9
|
-
},
|
|
10
7
|
"exports": {
|
|
11
8
|
".": {
|
|
12
9
|
"bun": "./src/index.ts",
|
|
@@ -24,7 +21,8 @@
|
|
|
24
21
|
"directory": "packages/vite-plugin"
|
|
25
22
|
},
|
|
26
23
|
"dependencies": {
|
|
27
|
-
"@buzola/
|
|
24
|
+
"@buzola/codegen": "^0.0.12",
|
|
25
|
+
"@buzola/router": "^0.0.12"
|
|
28
26
|
},
|
|
29
27
|
"devDependencies": {
|
|
30
28
|
"@types/node": "^25.3.3",
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { describe, expect, it } from 'bun:test'
|
|
2
|
+
import * as fs from 'node:fs'
|
|
3
|
+
import * as os from 'node:os'
|
|
4
|
+
import * as path from 'node:path'
|
|
5
|
+
import { build } from 'vite'
|
|
6
|
+
import { buzolaPlugin } from '../plugin.js'
|
|
7
|
+
|
|
8
|
+
// vite's build() returns RollupOutput[] (one per format) for non-watch builds.
|
|
9
|
+
// RollupOutput isn't re-exported from 'vite', so we declare a minimal shape here.
|
|
10
|
+
type BuildResult = { output: { type: string; code?: string }[] }[]
|
|
11
|
+
|
|
12
|
+
function makeEmptyRoutesFixture(): { root: string; cleanup: () => void } {
|
|
13
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'buzola-vite-test-'))
|
|
14
|
+
fs.mkdirSync(path.join(root, 'routes'))
|
|
15
|
+
return { root, cleanup: () => fs.rmSync(root, { recursive: true, force: true }) }
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function writeEntry(root: string, body: string): string {
|
|
19
|
+
const entryPath = path.join(root, 'entry.ts')
|
|
20
|
+
fs.writeFileSync(entryPath, body)
|
|
21
|
+
return entryPath
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
describe('buzolaPlugin (Vite)', () => {
|
|
25
|
+
it('vite build resolves virtual:buzola/routes through the plugin', async () => {
|
|
26
|
+
const { root, cleanup } = makeEmptyRoutesFixture()
|
|
27
|
+
try {
|
|
28
|
+
const entryPath = writeEntry(
|
|
29
|
+
root,
|
|
30
|
+
`import { routes, pageRegistry } from 'virtual:buzola/routes'\nexport { routes, pageRegistry }\n`,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
const result = await build({
|
|
34
|
+
root,
|
|
35
|
+
plugins: [buzolaPlugin({ routesDir: 'routes', output: 'buzola.gen.ts' })],
|
|
36
|
+
build: {
|
|
37
|
+
lib: { entry: entryPath, formats: ['es'], fileName: 'bundle' },
|
|
38
|
+
outDir: path.join(root, 'dist'),
|
|
39
|
+
write: false,
|
|
40
|
+
rollupOptions: { external: ['react', '@buzola/router'] },
|
|
41
|
+
},
|
|
42
|
+
logLevel: 'silent',
|
|
43
|
+
}) as BuildResult
|
|
44
|
+
|
|
45
|
+
const chunk = result[0]!.output.find((o) => o.type === 'chunk')
|
|
46
|
+
expect(chunk).toBeDefined()
|
|
47
|
+
expect(chunk!.code).toContain('pageRegistry')
|
|
48
|
+
expect(chunk!.code).toContain('buildRouteTree')
|
|
49
|
+
} finally {
|
|
50
|
+
cleanup()
|
|
51
|
+
}
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
it('vite build resolves named virtual module ID', async () => {
|
|
55
|
+
const { root, cleanup } = makeEmptyRoutesFixture()
|
|
56
|
+
try {
|
|
57
|
+
const entryPath = writeEntry(
|
|
58
|
+
root,
|
|
59
|
+
`import { routes, pageRegistry } from 'virtual:buzola/admin/routes'\nexport { routes, pageRegistry }\n`,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
const result = await build({
|
|
63
|
+
root,
|
|
64
|
+
plugins: [buzolaPlugin({ name: 'admin', routesDir: 'routes', output: 'buzola.gen.ts' })],
|
|
65
|
+
build: {
|
|
66
|
+
lib: { entry: entryPath, formats: ['es'], fileName: 'bundle' },
|
|
67
|
+
outDir: path.join(root, 'dist'),
|
|
68
|
+
write: false,
|
|
69
|
+
rollupOptions: { external: ['react', '@buzola/router'] },
|
|
70
|
+
},
|
|
71
|
+
logLevel: 'silent',
|
|
72
|
+
}) as BuildResult
|
|
73
|
+
|
|
74
|
+
const chunk = result[0]!.output.find((o) => o.type === 'chunk')
|
|
75
|
+
expect(chunk).toBeDefined()
|
|
76
|
+
expect(chunk!.code).toContain('pageRegistry')
|
|
77
|
+
} finally {
|
|
78
|
+
cleanup()
|
|
79
|
+
}
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
it('writes buzola.gen.ts during vite build', async () => {
|
|
83
|
+
const { root, cleanup } = makeEmptyRoutesFixture()
|
|
84
|
+
try {
|
|
85
|
+
const entryPath = writeEntry(root, `export const x = 1\n`)
|
|
86
|
+
const outputPath = path.join(root, 'buzola.gen.ts')
|
|
87
|
+
expect(fs.existsSync(outputPath)).toBe(false)
|
|
88
|
+
|
|
89
|
+
await build({
|
|
90
|
+
root,
|
|
91
|
+
plugins: [buzolaPlugin({ routesDir: 'routes', output: 'buzola.gen.ts' })],
|
|
92
|
+
build: {
|
|
93
|
+
lib: { entry: entryPath, formats: ['es'], fileName: 'bundle' },
|
|
94
|
+
outDir: path.join(root, 'dist'),
|
|
95
|
+
write: false,
|
|
96
|
+
},
|
|
97
|
+
logLevel: 'silent',
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
expect(fs.existsSync(outputPath)).toBe(true)
|
|
101
|
+
expect(fs.readFileSync(outputPath, 'utf-8')).toContain('pageRegistry')
|
|
102
|
+
} finally {
|
|
103
|
+
cleanup()
|
|
104
|
+
}
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
it('vite build succeeds when routes dir does not exist', async () => {
|
|
108
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'buzola-vite-test-'))
|
|
109
|
+
try {
|
|
110
|
+
const entryPath = writeEntry(root, `export const x = 1\n`)
|
|
111
|
+
|
|
112
|
+
const result = await build({
|
|
113
|
+
root,
|
|
114
|
+
plugins: [buzolaPlugin({ routesDir: 'nonexistent', output: 'buzola.gen.ts' })],
|
|
115
|
+
build: {
|
|
116
|
+
lib: { entry: entryPath, formats: ['es'], fileName: 'bundle' },
|
|
117
|
+
outDir: path.join(root, 'dist'),
|
|
118
|
+
write: false,
|
|
119
|
+
},
|
|
120
|
+
logLevel: 'silent',
|
|
121
|
+
}) as BuildResult
|
|
122
|
+
|
|
123
|
+
expect(result[0]!.output.length).toBeGreaterThan(0)
|
|
124
|
+
expect(fs.existsSync(path.join(root, 'buzola.gen.ts'))).toBe(false)
|
|
125
|
+
} finally {
|
|
126
|
+
fs.rmSync(root, { recursive: true, force: true })
|
|
127
|
+
}
|
|
128
|
+
})
|
|
129
|
+
})
|
package/src/index.ts
CHANGED
|
@@ -1,23 +1,2 @@
|
|
|
1
1
|
export { buzolaPlugin } from './plugin.js'
|
|
2
2
|
export type { BuzolaPluginOptions } from './plugin.js'
|
|
3
|
-
|
|
4
|
-
export { generate } from './generate.js'
|
|
5
|
-
export type { GenerateOptions } from './generate.js'
|
|
6
|
-
|
|
7
|
-
export { loadConfig } from './config.js'
|
|
8
|
-
export type { BuzolaConfig } from './config.js'
|
|
9
|
-
|
|
10
|
-
export { scanRouteFiles } from './generator/scanner.js'
|
|
11
|
-
export type { ScannedFile } from './generator/scanner.js'
|
|
12
|
-
|
|
13
|
-
export { buildFileRouteTree } from './generator/tree-builder.js'
|
|
14
|
-
export type { FileRouteNode, PageExportInfo } from './generator/tree-builder.js'
|
|
15
|
-
|
|
16
|
-
export { generateRouteModule } from './generator/codegen.js'
|
|
17
|
-
export type { CodegenOptions } from './generator/codegen.js'
|
|
18
|
-
|
|
19
|
-
export { extractPages } from './generator/page-extractor.js'
|
|
20
|
-
export type { ExtractedPage, ExtractedParam, ModuleLoader } from './generator/page-extractor.js'
|
|
21
|
-
|
|
22
|
-
export { isRouteFile, parseDirName, parseFileName, parseRouteFile } from './conventions.js'
|
|
23
|
-
export type { ParsedRouteFile } from './conventions.js'
|
package/src/plugin.ts
CHANGED
|
@@ -1,30 +1,16 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {
|
|
2
|
+
type BasePluginOptions,
|
|
3
|
+
buildVirtualSource,
|
|
4
|
+
generate,
|
|
5
|
+
isRouteFile,
|
|
6
|
+
type ResolvedOptions,
|
|
7
|
+
resolveOptions,
|
|
8
|
+
resolveVirtualModuleId,
|
|
9
|
+
} from '@buzola/codegen'
|
|
2
10
|
import * as path from 'node:path'
|
|
3
11
|
import type { Plugin, ViteDevServer } from 'vite'
|
|
4
|
-
import { loadConfig } from './config.js'
|
|
5
|
-
import { generate, type GenerateOptions } from './generate.js'
|
|
6
12
|
|
|
7
|
-
export interface BuzolaPluginOptions {
|
|
8
|
-
/**
|
|
9
|
-
* Unique name for this plugin instance. Required when registering multiple
|
|
10
|
-
* entrypoints in the same Vite config. Affects the plugin name
|
|
11
|
-
* (`buzola:${name}`) and the virtual module ID (`virtual:buzola/${name}/routes`).
|
|
12
|
-
*
|
|
13
|
-
* When omitted, the plugin uses `buzola` as its name and
|
|
14
|
-
* `virtual:buzola/routes` as the virtual module ID.
|
|
15
|
-
*/
|
|
16
|
-
name?: string
|
|
17
|
-
/** Path to routes directory, relative to project root. Defaults to "src/routes". */
|
|
18
|
-
routesDir?: string
|
|
19
|
-
/** Path to output generated file, relative to project root. Defaults to "src/buzola.gen.ts". */
|
|
20
|
-
output?: string
|
|
21
|
-
/**
|
|
22
|
-
* Parameter names that should be persistent across navigations.
|
|
23
|
-
* When set, generates a BuzolaPersistentParams type augmentation
|
|
24
|
-
* so these params become optional in Link and navigate() calls.
|
|
25
|
-
*/
|
|
26
|
-
persistentParams?: string[]
|
|
27
|
-
}
|
|
13
|
+
export interface BuzolaPluginOptions extends BasePluginOptions {}
|
|
28
14
|
|
|
29
15
|
/**
|
|
30
16
|
* Vite plugin for Buzola page-centric routing.
|
|
@@ -41,14 +27,11 @@ export interface BuzolaPluginOptions {
|
|
|
41
27
|
* Plugin options take precedence over the config file.
|
|
42
28
|
*/
|
|
43
29
|
export function buzolaPlugin(options: BuzolaPluginOptions = {}): Plugin {
|
|
44
|
-
const {
|
|
45
|
-
|
|
46
|
-
const pluginName = nameOption ? `buzola:${nameOption}` : 'buzola'
|
|
47
|
-
const virtualModuleId = nameOption ? `virtual:buzola/${nameOption}/routes` : 'virtual:buzola/routes'
|
|
48
|
-
const resolvedVirtualId = '\0' + virtualModuleId
|
|
30
|
+
const { pluginName, id: virtualId } = resolveVirtualModuleId(options.name)
|
|
31
|
+
const resolvedVirtualId = '\0' + virtualId
|
|
49
32
|
|
|
50
|
-
let
|
|
51
|
-
let
|
|
33
|
+
let baseOptions: ResolvedOptions
|
|
34
|
+
let virtualSource: string
|
|
52
35
|
let server: ViteDevServer | undefined
|
|
53
36
|
|
|
54
37
|
return {
|
|
@@ -56,18 +39,8 @@ export function buzolaPlugin(options: BuzolaPluginOptions = {}): Plugin {
|
|
|
56
39
|
enforce: 'pre',
|
|
57
40
|
|
|
58
41
|
async configResolved(config) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const routesDir = options.routesDir ?? fileConfig.routesDir ?? 'src/routes'
|
|
63
|
-
const output = options.output ?? fileConfig.output ?? 'src/buzola.gen.ts'
|
|
64
|
-
const persistentParams = options.persistentParams ?? fileConfig.persistentParams
|
|
65
|
-
|
|
66
|
-
baseOptions = {
|
|
67
|
-
routesDir: path.resolve(root, routesDir),
|
|
68
|
-
outputPath: path.resolve(root, output),
|
|
69
|
-
persistentParams,
|
|
70
|
-
}
|
|
42
|
+
baseOptions = await resolveOptions({ ...options, root: config.root })
|
|
43
|
+
virtualSource = buildVirtualSource(baseOptions.outputPath)
|
|
71
44
|
},
|
|
72
45
|
|
|
73
46
|
configureServer(srv) {
|
|
@@ -75,21 +48,18 @@ export function buzolaPlugin(options: BuzolaPluginOptions = {}): Plugin {
|
|
|
75
48
|
},
|
|
76
49
|
|
|
77
50
|
async buildStart() {
|
|
78
|
-
if (!fs.existsSync(baseOptions.routesDir)) return
|
|
79
|
-
|
|
80
51
|
if (server) {
|
|
81
|
-
await generate({ ...baseOptions, moduleLoader: (p) => server!.ssrLoadModule(p) })
|
|
52
|
+
await generate({ ...baseOptions, optional: true, moduleLoader: (p) => server!.ssrLoadModule(p) })
|
|
82
53
|
} else {
|
|
83
|
-
// Production build — create a temporary Vite server for module loading
|
|
84
54
|
const { createServer } = await import('vite')
|
|
85
55
|
const tempServer = await createServer({
|
|
86
|
-
root,
|
|
56
|
+
root: baseOptions.root,
|
|
87
57
|
server: { middlewareMode: true },
|
|
88
58
|
logLevel: 'silent',
|
|
89
59
|
optimizeDeps: { noDiscovery: true },
|
|
90
60
|
})
|
|
91
61
|
try {
|
|
92
|
-
await generate({ ...baseOptions, moduleLoader: (p) => tempServer.ssrLoadModule(p) })
|
|
62
|
+
await generate({ ...baseOptions, optional: true, moduleLoader: (p) => tempServer.ssrLoadModule(p) })
|
|
93
63
|
} finally {
|
|
94
64
|
await tempServer.close()
|
|
95
65
|
}
|
|
@@ -97,27 +67,23 @@ export function buzolaPlugin(options: BuzolaPluginOptions = {}): Plugin {
|
|
|
97
67
|
},
|
|
98
68
|
|
|
99
69
|
resolveId(id) {
|
|
100
|
-
if (id ===
|
|
70
|
+
if (id === virtualId) {
|
|
101
71
|
return resolvedVirtualId
|
|
102
72
|
}
|
|
103
73
|
},
|
|
104
74
|
|
|
105
75
|
load(id) {
|
|
106
76
|
if (id === resolvedVirtualId) {
|
|
107
|
-
return
|
|
77
|
+
return virtualSource
|
|
108
78
|
}
|
|
109
79
|
},
|
|
110
80
|
|
|
111
81
|
async handleHotUpdate({ file }) {
|
|
112
|
-
if (!file.startsWith(baseOptions.routesDir) || !
|
|
82
|
+
if (!server || !file.startsWith(baseOptions.routesDir) || !isRouteFile(path.basename(file))) return
|
|
113
83
|
|
|
114
84
|
const changed = await generate({ ...baseOptions, moduleLoader: (p) => server!.ssrLoadModule(p) })
|
|
115
85
|
if (!changed) return
|
|
116
86
|
|
|
117
|
-
// Invalidate the virtual module so Vite re-evaluates it.
|
|
118
|
-
// Vite propagates the update through the import chain — if the app
|
|
119
|
-
// supports HMR for the route tree, no full-page reload is needed.
|
|
120
|
-
// If not, Vite falls back to full-reload automatically.
|
|
121
87
|
const mod = server.moduleGraph.getModuleById(resolvedVirtualId)
|
|
122
88
|
if (mod) {
|
|
123
89
|
server.moduleGraph.invalidateModule(mod)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"codegen.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/codegen.test.ts"],"names":[],"mappings":""}
|