Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | 27x 25x 25x 2x 1x 1x 1x 1x 1x 1x 2x 2x 1x 2x 2x 1x | /**
* vitek:build — buildStart, closeBundle, buildEnd, configResolved
*/
import type { Plugin } from 'vite';
import * as path from 'path';
import * as fs from 'fs';
import { scanApiDirectory } from '../core/file-system/scan-api-dir.js';
import { writeManifest } from '../core/introspection/manifest.js';
import { parsedRoutesToSchema, runFileGeneration } from '../core/generation/run-file-generation.js';
import { buildApiBundle, getApiBundleFilename } from '../build/build-api-bundle.js';
import { buildSocketsBundle, getSocketsBundleFilename } from '../build/build-sockets-bundle.js';
import { API_BASE_PATH, API_DIR_NAME, getSocketBasePath } from '../shared/constants.js';
import type { PluginContext } from './context.js';
export function createBuildPlugin(ctx: PluginContext): Plugin {
return {
name: 'vitek:build',
enforce: 'pre',
configResolved(config) {
ctx.root = config.root;
ctx.buildOutDir = path.resolve(ctx.root!, config.build?.outDir ?? 'dist');
},
async buildStart() {
if (!ctx.buildApi || !ctx.root) return;
const fullApiDir = path.resolve(ctx.root, ctx.apiDirOption);
Iif (!fs.existsSync(fullApiDir)) return;
const scanResult = scanApiDirectory(fullApiDir);
Iif (scanResult.routes.length === 0 && scanResult.sockets.length === 0) return;
const schema = parsedRoutesToSchema(scanResult.routes);
const socketBasePath = getSocketBasePath(
ctx.options.apiBasePath,
typeof ctx.options.sockets === 'object' ? ctx.options.sockets?.path : undefined
);
try {
await runFileGeneration({
root: ctx.root,
schema,
sockets: scanResult.sockets,
apiBasePath: ctx.options.apiBasePath ?? API_BASE_PATH,
socketBasePath,
openApi: ctx.options.openApi,
serverPort: 5173,
onGenerationError: ctx.options.onGenerationError,
});
const plugins = ctx.options.plugins ?? [];
const apiBasePath = ctx.options.apiBasePath ?? API_BASE_PATH;
for (const plugin of plugins) {
if (plugin.afterTypesGenerated) {
await plugin.afterTypesGenerated({
root: ctx.root,
schema,
sockets: scanResult.sockets,
apiBasePath,
socketBasePath,
});
}
}
} catch (err) {
const error = err instanceof Error ? err : new Error(String(err));
console.error('[vitek] Failed to generate types/services:', error.message);
ctx.options.onGenerationError?.(error);
}
},
async closeBundle() {
Eif (!ctx.buildApi || !ctx.root || !ctx.buildOutDir) return;
const fullApiDir = path.resolve(ctx.root, ctx.apiDirOption);
try {
writeManifest(ctx.root, ctx.apiDirOption, ctx.buildOutDir);
} catch (err) {
console.error('[vitek] Failed to write manifest:', err instanceof Error ? err.message : err);
}
try {
await buildApiBundle({
root: ctx.root,
apiDir: fullApiDir,
outDir: ctx.buildOutDir,
alias: ctx.options.alias,
});
} catch (err) {
console.error('[vitek] Failed to build API bundle:', err instanceof Error ? err.message : err);
}
const socketsEnabled = ctx.options.sockets !== false;
if (socketsEnabled && fs.existsSync(fullApiDir)) {
try {
await buildSocketsBundle({
root: ctx.root,
apiDir: fullApiDir,
outDir: ctx.buildOutDir,
});
} catch (err) {
console.error('[vitek] Failed to build sockets bundle:', err instanceof Error ? err.message : err);
}
}
},
buildEnd() {
if (ctx.cleanupFn) {
ctx.cleanupFn();
ctx.cleanupFn = null;
}
},
};
}
|