vitek-plugin 0.1.2-beta.5 → 0.2.0-beta
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/README.md +35 -4
- package/dist/adapters/vite/dev-server-middleware.d.ts +8 -0
- package/dist/adapters/vite/dev-server-middleware.d.ts.map +1 -0
- package/dist/adapters/vite/dev-server-middleware.js +30 -0
- package/dist/adapters/vite/dev-server-state.d.ts +41 -0
- package/dist/adapters/vite/dev-server-state.d.ts.map +1 -0
- package/dist/adapters/vite/dev-server-state.js +191 -0
- package/dist/adapters/vite/dev-server.d.ts +2 -21
- package/dist/adapters/vite/dev-server.d.ts.map +1 -1
- package/dist/adapters/vite/dev-server.js +7 -379
- package/dist/adapters/vite/path-utils.d.ts +20 -0
- package/dist/adapters/vite/path-utils.d.ts.map +1 -0
- package/dist/adapters/vite/path-utils.js +46 -0
- package/dist/adapters/vite/path-utils.test.d.ts +2 -0
- package/dist/adapters/vite/path-utils.test.d.ts.map +1 -0
- package/dist/adapters/vite/path-utils.test.js +79 -0
- package/dist/build/build-api-bundle.d.ts +1 -0
- package/dist/build/build-api-bundle.d.ts.map +1 -1
- package/dist/build/build-api-bundle.js +38 -3
- package/dist/build/build-api-bundle.test.d.ts +2 -0
- package/dist/build/build-api-bundle.test.d.ts.map +1 -0
- package/dist/build/build-api-bundle.test.js +50 -0
- package/dist/build/build-sockets-bundle.test.d.ts +2 -0
- package/dist/build/build-sockets-bundle.test.d.ts.map +1 -0
- package/dist/build/build-sockets-bundle.test.js +49 -0
- package/dist/cli/cli.d.ts +8 -0
- package/dist/cli/cli.d.ts.map +1 -0
- package/dist/cli/cli.js +25 -0
- package/dist/cli/fixtures/serve-config/vitek.config.d.mts +6 -0
- package/dist/cli/fixtures/serve-config/vitek.config.d.mts.map +1 -0
- package/dist/cli/fixtures/serve-config/vitek.config.mjs +19 -0
- package/dist/cli/init.d.ts +15 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +99 -0
- package/dist/cli/init.test.d.ts +2 -0
- package/dist/cli/init.test.d.ts.map +1 -0
- package/dist/cli/init.test.js +117 -0
- package/dist/cli/mcp-project-config.d.ts +8 -0
- package/dist/cli/mcp-project-config.d.ts.map +1 -0
- package/dist/cli/mcp-project-config.js +26 -0
- package/dist/cli/mcp-project.d.ts +2 -0
- package/dist/cli/mcp-project.d.ts.map +1 -0
- package/dist/cli/mcp-project.js +101 -0
- package/dist/cli/serve.d.ts +27 -1
- package/dist/cli/serve.d.ts.map +1 -1
- package/dist/cli/serve.js +85 -10
- package/dist/cli/serve.test.d.ts +2 -0
- package/dist/cli/serve.test.d.ts.map +1 -0
- package/dist/cli/serve.test.js +108 -0
- package/dist/core/asyncapi/generate.d.ts +5 -3
- package/dist/core/asyncapi/generate.d.ts.map +1 -1
- package/dist/core/asyncapi/generate.test.d.ts +2 -0
- package/dist/core/asyncapi/generate.test.d.ts.map +1 -0
- package/dist/core/asyncapi/generate.test.js +120 -0
- package/dist/core/context/create-context.d.ts +2 -0
- package/dist/core/context/create-context.d.ts.map +1 -1
- package/dist/core/file-system/extract-type-from-file.d.ts +4 -0
- package/dist/core/file-system/extract-type-from-file.d.ts.map +1 -0
- package/dist/core/file-system/extract-type-from-file.js +77 -0
- package/dist/core/file-system/extract-type-from-file.test.d.ts +2 -0
- package/dist/core/file-system/extract-type-from-file.test.d.ts.map +1 -0
- package/dist/core/file-system/extract-type-from-file.test.js +75 -0
- package/dist/core/file-system/watch-api-dir.d.ts +4 -1
- package/dist/core/file-system/watch-api-dir.d.ts.map +1 -1
- package/dist/core/file-system/watch-api-dir.js +31 -6
- package/dist/core/file-system/watch-api-dir.test.d.ts +2 -0
- package/dist/core/file-system/watch-api-dir.test.d.ts.map +1 -0
- package/dist/core/file-system/watch-api-dir.test.js +38 -0
- package/dist/core/generation/run-file-generation.d.ts +24 -0
- package/dist/core/generation/run-file-generation.d.ts.map +1 -0
- package/dist/core/generation/run-file-generation.js +90 -0
- package/dist/core/generation/run-file-generation.test.d.ts +2 -0
- package/dist/core/generation/run-file-generation.test.d.ts.map +1 -0
- package/dist/core/generation/run-file-generation.test.js +151 -0
- package/dist/core/introspection/manifest.d.ts +24 -0
- package/dist/core/introspection/manifest.d.ts.map +1 -0
- package/dist/core/introspection/manifest.js +41 -0
- package/dist/core/introspection/manifest.test.d.ts +2 -0
- package/dist/core/introspection/manifest.test.d.ts.map +1 -0
- package/dist/core/introspection/manifest.test.js +62 -0
- package/dist/core/middleware/get-applicable-middlewares.d.ts +7 -0
- package/dist/core/middleware/get-applicable-middlewares.d.ts.map +1 -1
- package/dist/core/middleware/get-applicable-middlewares.js +23 -15
- package/dist/core/middleware/get-applicable-middlewares.test.js +36 -1
- package/dist/core/openapi/generate.d.ts +5 -74
- package/dist/core/openapi/generate.d.ts.map +1 -1
- package/dist/core/openapi/generate.js +4 -419
- package/dist/core/openapi/generate.test.d.ts +2 -0
- package/dist/core/openapi/generate.test.d.ts.map +1 -0
- package/dist/core/openapi/generate.test.js +184 -0
- package/dist/core/openapi/jsdoc.d.ts +3 -0
- package/dist/core/openapi/jsdoc.d.ts.map +1 -0
- package/dist/core/openapi/jsdoc.js +68 -0
- package/dist/core/openapi/jsdoc.test.d.ts +2 -0
- package/dist/core/openapi/jsdoc.test.d.ts.map +1 -0
- package/dist/core/openapi/jsdoc.test.js +111 -0
- package/dist/core/openapi/spec-builder.d.ts +4 -0
- package/dist/core/openapi/spec-builder.d.ts.map +1 -0
- package/dist/core/openapi/spec-builder.js +257 -0
- package/dist/core/openapi/spec-builder.test.d.ts +2 -0
- package/dist/core/openapi/spec-builder.test.d.ts.map +1 -0
- package/dist/core/openapi/spec-builder.test.js +93 -0
- package/dist/core/openapi/types.d.ts +42 -0
- package/dist/core/openapi/types.d.ts.map +1 -0
- package/dist/core/openapi/types.js +5 -0
- package/dist/core/server/cors.d.ts +29 -0
- package/dist/core/server/cors.d.ts.map +1 -0
- package/dist/core/server/cors.js +55 -0
- package/dist/core/server/cors.test.d.ts +2 -0
- package/dist/core/server/cors.test.d.ts.map +1 -0
- package/dist/core/server/cors.test.js +49 -0
- package/dist/core/server/proxy.d.ts +16 -0
- package/dist/core/server/proxy.d.ts.map +1 -0
- package/dist/core/server/proxy.js +20 -0
- package/dist/core/server/proxy.test.d.ts +2 -0
- package/dist/core/server/proxy.test.d.ts.map +1 -0
- package/dist/core/server/proxy.test.js +53 -0
- package/dist/core/server/request-handler.d.ts +17 -3
- package/dist/core/server/request-handler.d.ts.map +1 -1
- package/dist/core/server/request-handler.js +192 -84
- package/dist/core/server/request-handler.test.js +287 -22
- package/dist/core/socket/socket-handler.test.d.ts +2 -0
- package/dist/core/socket/socket-handler.test.d.ts.map +1 -0
- package/dist/core/socket/socket-handler.test.js +107 -0
- package/dist/core/types/schema.test.d.ts +2 -0
- package/dist/core/types/schema.test.d.ts.map +1 -0
- package/dist/core/types/schema.test.js +41 -0
- package/dist/core/validation/types.d.ts +2 -1
- package/dist/core/validation/types.d.ts.map +1 -1
- package/dist/core/validation/validator.d.ts +4 -16
- package/dist/core/validation/validator.d.ts.map +1 -1
- package/dist/core/validation/validator.js +4 -16
- package/dist/index.d.ts +6 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/plugin/context.d.ts +15 -0
- package/dist/plugin/context.d.ts.map +1 -0
- package/dist/plugin/context.js +12 -0
- package/dist/plugin/options.d.ts +46 -0
- package/dist/plugin/options.d.ts.map +1 -0
- package/dist/plugin/options.js +1 -0
- package/dist/plugin/plugin-api.d.ts +49 -0
- package/dist/plugin/plugin-api.d.ts.map +1 -0
- package/dist/plugin/plugin-api.js +5 -0
- package/dist/plugin/vitek-build.d.ts +7 -0
- package/dist/plugin/vitek-build.d.ts.map +1 -0
- package/dist/plugin/vitek-build.js +104 -0
- package/dist/plugin/vitek-config.d.ts +4 -0
- package/dist/plugin/vitek-config.d.ts.map +1 -0
- package/dist/plugin/vitek-config.js +51 -0
- package/dist/plugin/vitek-config.test.d.ts +2 -0
- package/dist/plugin/vitek-config.test.d.ts.map +1 -0
- package/dist/plugin/vitek-config.test.js +62 -0
- package/dist/plugin/vitek-dev.d.ts +7 -0
- package/dist/plugin/vitek-dev.d.ts.map +1 -0
- package/dist/plugin/vitek-dev.js +71 -0
- package/dist/plugin/vitek-preview.d.ts +7 -0
- package/dist/plugin/vitek-preview.d.ts.map +1 -0
- package/dist/plugin/vitek-preview.js +107 -0
- package/dist/plugin/vitek-resolve.d.ts +7 -0
- package/dist/plugin/vitek-resolve.d.ts.map +1 -0
- package/dist/plugin/vitek-resolve.js +25 -0
- package/dist/plugin/vitek-transform.d.ts +7 -0
- package/dist/plugin/vitek-transform.d.ts.map +1 -0
- package/dist/plugin/vitek-transform.js +55 -0
- package/dist/plugin/vitek.d.ts +10 -0
- package/dist/plugin/vitek.d.ts.map +1 -0
- package/dist/plugin/vitek.js +27 -0
- package/dist/plugin.d.ts +3 -32
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +2 -246
- package/dist/plugin.test.js +114 -28
- package/dist/shared/response-helpers.d.ts +21 -0
- package/dist/shared/response-helpers.d.ts.map +1 -1
- package/dist/shared/response-helpers.js +41 -0
- package/dist/shared/response-helpers.test.js +54 -1
- package/package.json +19 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vitek-config.test.d.ts","sourceRoot":"","sources":["../../src/plugin/vitek-config.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import { createConfigPlugin } from './vitek-config.js';
|
|
5
|
+
import { createPluginContext } from './context.js';
|
|
6
|
+
describe('vitek:config', () => {
|
|
7
|
+
it('config hook merges optimizeDeps.exclude with vitek-plugin', () => {
|
|
8
|
+
const ctx = createPluginContext({}, 'src/api', true);
|
|
9
|
+
const plugin = createConfigPlugin(ctx);
|
|
10
|
+
const configFn = plugin.config;
|
|
11
|
+
if (!configFn || typeof configFn !== 'function') {
|
|
12
|
+
throw new Error('config hook not found');
|
|
13
|
+
}
|
|
14
|
+
const result = configFn({ root: process.cwd(), optimizeDeps: {} }, { command: 'build', mode: 'production' });
|
|
15
|
+
expect(result).toBeDefined();
|
|
16
|
+
expect(result.optimizeDeps?.exclude).toContain('vitek-plugin');
|
|
17
|
+
});
|
|
18
|
+
it('config hook preserves existing optimizeDeps.exclude', () => {
|
|
19
|
+
const ctx = createPluginContext({}, 'src/api', true);
|
|
20
|
+
const plugin = createConfigPlugin(ctx);
|
|
21
|
+
const configFn = plugin.config;
|
|
22
|
+
if (!configFn || typeof configFn !== 'function')
|
|
23
|
+
return;
|
|
24
|
+
const result = configFn({ root: process.cwd(), optimizeDeps: { exclude: ['some-pkg'] } }, { command: 'build', mode: 'production' });
|
|
25
|
+
expect(result.optimizeDeps?.exclude).toContain('some-pkg');
|
|
26
|
+
expect(result.optimizeDeps?.exclude).toContain('vitek-plugin');
|
|
27
|
+
});
|
|
28
|
+
it('config hook merges alias when options.alias is set', () => {
|
|
29
|
+
const root = fs.mkdtempSync(path.join(process.cwd(), 'vitek-config-test-'));
|
|
30
|
+
try {
|
|
31
|
+
const ctx = createPluginContext({ alias: { '@lib': 'src/lib' } }, 'src/api', true);
|
|
32
|
+
const plugin = createConfigPlugin(ctx);
|
|
33
|
+
const configFn = plugin.config;
|
|
34
|
+
if (!configFn || typeof configFn !== 'function')
|
|
35
|
+
return;
|
|
36
|
+
const result = configFn({ root }, { command: 'build', mode: 'production' });
|
|
37
|
+
expect(result.resolve?.alias).toBeDefined();
|
|
38
|
+
const entries = result.resolve.alias;
|
|
39
|
+
expect(Array.isArray(entries)).toBe(true);
|
|
40
|
+
const our = entries.find((e) => e.find === '@lib');
|
|
41
|
+
expect(our).toBeDefined();
|
|
42
|
+
expect(our.replacement).toContain('src/lib');
|
|
43
|
+
}
|
|
44
|
+
finally {
|
|
45
|
+
try {
|
|
46
|
+
fs.rmSync(root, { recursive: true });
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// ignore
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
it('config hook does not touch resolve when options.alias is empty', () => {
|
|
54
|
+
const ctx = createPluginContext({}, 'src/api', true);
|
|
55
|
+
const plugin = createConfigPlugin(ctx);
|
|
56
|
+
const configFn = plugin.config;
|
|
57
|
+
if (!configFn || typeof configFn !== 'function')
|
|
58
|
+
return;
|
|
59
|
+
const result = configFn({ root: process.cwd(), resolve: {} }, { command: 'build', mode: 'production' });
|
|
60
|
+
expect(result.resolve).toBeUndefined();
|
|
61
|
+
});
|
|
62
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vitek-dev.d.ts","sourceRoot":"","sources":["../../src/plugin/vitek-dev.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACnC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CA6E1D"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vitek:dev — configureServer, middleware, watcher
|
|
3
|
+
*/
|
|
4
|
+
import * as path from 'path';
|
|
5
|
+
import * as fs from 'fs';
|
|
6
|
+
import { createViteDevServerMiddleware } from '../adapters/vite/dev-server.js';
|
|
7
|
+
import { createViteLogger } from '../adapters/vite/logger.js';
|
|
8
|
+
import { API_BASE_PATH, getSocketBasePath } from '../shared/constants.js';
|
|
9
|
+
export function createDevPlugin(ctx) {
|
|
10
|
+
return {
|
|
11
|
+
name: 'vitek:dev',
|
|
12
|
+
async configureServer(server) {
|
|
13
|
+
if (!ctx.root)
|
|
14
|
+
return;
|
|
15
|
+
const fullApiDir = path.resolve(ctx.root, ctx.apiDirOption);
|
|
16
|
+
if (!fs.existsSync(fullApiDir)) {
|
|
17
|
+
server.config.logger.warn(`[vitek] API directory not found: ${fullApiDir}`);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const logger = createViteLogger(server.config.logger, ctx.options.logging);
|
|
21
|
+
const socketsEnabled = ctx.options.sockets !== false;
|
|
22
|
+
const socketBasePath = getSocketBasePath(ctx.options.apiBasePath, typeof ctx.options.sockets === 'object' ? ctx.options.sockets?.path : undefined);
|
|
23
|
+
const beforeApiRequest = (ctx.options.plugins ?? [])
|
|
24
|
+
.filter((p) => !!p.beforeApiRequest)
|
|
25
|
+
.map((p) => (hookCtx, next) => p.beforeApiRequest({ ...hookCtx, next }));
|
|
26
|
+
const afterTypesGenerated = (ctx.options.plugins ?? [])
|
|
27
|
+
.map((p) => p.afterTypesGenerated)
|
|
28
|
+
.filter((h) => !!h);
|
|
29
|
+
const { ready, middleware, cleanup, setupSockets } = createViteDevServerMiddleware({
|
|
30
|
+
root: ctx.root,
|
|
31
|
+
apiDir: fullApiDir,
|
|
32
|
+
logger,
|
|
33
|
+
viteServer: server,
|
|
34
|
+
enableValidation: ctx.options.enableValidation || false,
|
|
35
|
+
openApi: ctx.options.openApi,
|
|
36
|
+
sockets: socketsEnabled,
|
|
37
|
+
socketBasePath,
|
|
38
|
+
apiBasePath: ctx.options.apiBasePath ?? API_BASE_PATH,
|
|
39
|
+
onGenerationError: ctx.options.onGenerationError,
|
|
40
|
+
beforeApiRequest,
|
|
41
|
+
afterTypesGenerated,
|
|
42
|
+
cors: ctx.options.cors,
|
|
43
|
+
trustProxy: ctx.options.trustProxy,
|
|
44
|
+
maxBodySize: ctx.options.maxBodySize,
|
|
45
|
+
onError: ctx.options.onError,
|
|
46
|
+
});
|
|
47
|
+
ctx.cleanupFn = cleanup;
|
|
48
|
+
server.middlewares.use(middleware);
|
|
49
|
+
await ready;
|
|
50
|
+
if (socketsEnabled && server.httpServer) {
|
|
51
|
+
setupSockets(server.httpServer);
|
|
52
|
+
}
|
|
53
|
+
logger.info('Vitek plugin initialized');
|
|
54
|
+
const port = server.config.server?.port ?? 5173;
|
|
55
|
+
const apiPath = ctx.options.apiBasePath ?? API_BASE_PATH;
|
|
56
|
+
const originalPrintUrls = server.printUrls?.bind(server);
|
|
57
|
+
if (typeof originalPrintUrls === 'function') {
|
|
58
|
+
server.printUrls = () => {
|
|
59
|
+
originalPrintUrls();
|
|
60
|
+
const host = 'localhost';
|
|
61
|
+
const apiUrl = `http://${host}:${port}${apiPath}`;
|
|
62
|
+
server.config.logger.info(` ➜ API: ${apiUrl}`);
|
|
63
|
+
if (socketsEnabled) {
|
|
64
|
+
const wsUrl = `ws://${host}:${port}${socketBasePath}`;
|
|
65
|
+
server.config.logger.info(` ➜ WS: ${wsUrl}`);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vitek:preview — configurePreviewServer, bundle loading
|
|
3
|
+
*/
|
|
4
|
+
import type { Plugin } from 'vite';
|
|
5
|
+
import type { PluginContext } from './context.js';
|
|
6
|
+
export declare function createPreviewPlugin(ctx: PluginContext): Plugin;
|
|
7
|
+
//# sourceMappingURL=vitek-preview.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vitek-preview.d.ts","sourceRoot":"","sources":["../../src/plugin/vitek-preview.ts"],"names":[],"mappings":"AAAA;;GAEG;AAUH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAGnC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAkH9D"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vitek:preview — configurePreviewServer, bundle loading
|
|
3
|
+
*/
|
|
4
|
+
import * as path from 'path';
|
|
5
|
+
import * as fs from 'fs';
|
|
6
|
+
import { pathToFileURL } from 'url';
|
|
7
|
+
import { createRequestHandler } from '../core/server/request-handler.js';
|
|
8
|
+
import { createSocketHandler } from '../core/socket/socket-handler.js';
|
|
9
|
+
import { getApiBundleFilename } from '../build/build-api-bundle.js';
|
|
10
|
+
import { getSocketsBundleFilename } from '../build/build-sockets-bundle.js';
|
|
11
|
+
import { API_BASE_PATH, getSocketBasePath } from '../shared/constants.js';
|
|
12
|
+
export function createPreviewPlugin(ctx) {
|
|
13
|
+
return {
|
|
14
|
+
name: 'vitek:preview',
|
|
15
|
+
async configurePreviewServer(server) {
|
|
16
|
+
if (!ctx.buildApi || !ctx.root || !ctx.buildOutDir)
|
|
17
|
+
return;
|
|
18
|
+
const bundlePath = path.join(ctx.buildOutDir, getApiBundleFilename());
|
|
19
|
+
if (!fs.existsSync(bundlePath)) {
|
|
20
|
+
server.config.logger.warn('[vitek] API bundle not found; preview serving static assets only. Run `vite build` first.');
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const previewPort = server.config.preview?.port ?? 4173;
|
|
24
|
+
const apiBaseUrl = `http://127.0.0.1:${previewPort}${API_BASE_PATH}`;
|
|
25
|
+
const api = {
|
|
26
|
+
async fetch(path, fetchOptions) {
|
|
27
|
+
const url = `${apiBaseUrl}/${path.replace(/^\//, '')}`;
|
|
28
|
+
const res = await fetch(url, {
|
|
29
|
+
method: fetchOptions?.method ?? 'GET',
|
|
30
|
+
headers: fetchOptions?.body !== undefined
|
|
31
|
+
? { 'Content-Type': 'application/json' }
|
|
32
|
+
: undefined,
|
|
33
|
+
body: fetchOptions?.body !== undefined
|
|
34
|
+
? JSON.stringify(fetchOptions.body)
|
|
35
|
+
: undefined,
|
|
36
|
+
});
|
|
37
|
+
const text = await res.text();
|
|
38
|
+
if (!text)
|
|
39
|
+
return undefined;
|
|
40
|
+
try {
|
|
41
|
+
return JSON.parse(text);
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return text;
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
const noopSockets = { emit() { } };
|
|
49
|
+
const shared = { sockets: noopSockets, api };
|
|
50
|
+
const bundleUrl = pathToFileURL(bundlePath).href;
|
|
51
|
+
const bundleLoadPromise = import(bundleUrl);
|
|
52
|
+
let apiHandler = null;
|
|
53
|
+
const apiMiddleware = (req, res, next) => {
|
|
54
|
+
const pathname = req.url?.split('?')[0] ?? '';
|
|
55
|
+
if (pathname !== API_BASE_PATH && !pathname.startsWith(API_BASE_PATH + '/')) {
|
|
56
|
+
return next();
|
|
57
|
+
}
|
|
58
|
+
bundleLoadPromise
|
|
59
|
+
.then((mod) => {
|
|
60
|
+
if (!apiHandler) {
|
|
61
|
+
const beforeApiRequest = (ctx.options.plugins ?? [])
|
|
62
|
+
.filter((p) => !!p.beforeApiRequest)
|
|
63
|
+
.map((p) => (hookCtx, next) => p.beforeApiRequest({ ...hookCtx, next }));
|
|
64
|
+
apiHandler = createRequestHandler({
|
|
65
|
+
routes: mod.routes,
|
|
66
|
+
middlewares: mod.middlewares,
|
|
67
|
+
beforeApiRequest,
|
|
68
|
+
cors: ctx.options.cors,
|
|
69
|
+
trustProxy: ctx.options.trustProxy,
|
|
70
|
+
maxBodySize: ctx.options.maxBodySize,
|
|
71
|
+
onError: ctx.options.onError,
|
|
72
|
+
shared,
|
|
73
|
+
});
|
|
74
|
+
server.config.logger.info('[vitek] API middleware registered for preview');
|
|
75
|
+
}
|
|
76
|
+
apiHandler(req, res, next);
|
|
77
|
+
})
|
|
78
|
+
.catch((err) => {
|
|
79
|
+
server.config.logger.error(`[vitek] Failed to load API bundle: ${err instanceof Error ? err.message : String(err)}`);
|
|
80
|
+
res.statusCode = 500;
|
|
81
|
+
res.setHeader('Content-Type', 'application/json');
|
|
82
|
+
res.end(JSON.stringify({ error: 'Internal server error', message: 'Failed to load API bundle' }));
|
|
83
|
+
});
|
|
84
|
+
};
|
|
85
|
+
server.middlewares.use(apiMiddleware);
|
|
86
|
+
const socketsEnabled = ctx.options.sockets !== false;
|
|
87
|
+
const socketBasePath = getSocketBasePath(ctx.options.apiBasePath, typeof ctx.options.sockets === 'object' ? ctx.options.sockets?.path : undefined);
|
|
88
|
+
const socketsBundlePath = path.join(ctx.buildOutDir, getSocketsBundleFilename());
|
|
89
|
+
if (socketsEnabled && fs.existsSync(socketsBundlePath)) {
|
|
90
|
+
try {
|
|
91
|
+
const socketsUrl = pathToFileURL(socketsBundlePath).href;
|
|
92
|
+
const mod = await import(socketsUrl);
|
|
93
|
+
const handler = createSocketHandler({
|
|
94
|
+
sockets: mod.sockets,
|
|
95
|
+
socketBasePath,
|
|
96
|
+
shared,
|
|
97
|
+
});
|
|
98
|
+
server.httpServer?.on('upgrade', handler);
|
|
99
|
+
server.config.logger.info('[vitek] WebSocket sockets registered for preview');
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
server.config.logger.warn(`[vitek] Failed to load sockets bundle: ${err instanceof Error ? err.message : String(err)}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vitek:resolve — resolveId for relative imports in API files
|
|
3
|
+
*/
|
|
4
|
+
import type { Plugin } from 'vite';
|
|
5
|
+
import type { PluginContext } from './context.js';
|
|
6
|
+
export declare function createResolvePlugin(ctx: PluginContext): Plugin;
|
|
7
|
+
//# sourceMappingURL=vitek-resolve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vitek-resolve.d.ts","sourceRoot":"","sources":["../../src/plugin/vitek-resolve.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAOnC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAiB9D"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vitek:resolve — resolveId for relative imports in API files
|
|
3
|
+
*/
|
|
4
|
+
import * as path from 'path';
|
|
5
|
+
import { pathToFileURL } from 'url';
|
|
6
|
+
import { normalizeImporterPath, resolveWithExtension, } from '../adapters/vite/path-utils.js';
|
|
7
|
+
export function createResolvePlugin(ctx) {
|
|
8
|
+
return {
|
|
9
|
+
name: 'vitek:resolve',
|
|
10
|
+
enforce: 'pre',
|
|
11
|
+
resolveId(id, importer) {
|
|
12
|
+
if (!id.startsWith('.') || !importer || !ctx.root)
|
|
13
|
+
return null;
|
|
14
|
+
const fullApiDir = path.resolve(ctx.root, ctx.apiDirOption);
|
|
15
|
+
const importerPath = normalizeImporterPath(importer, ctx.root);
|
|
16
|
+
const normalizedApiDir = path.resolve(fullApiDir);
|
|
17
|
+
const normalizedImporter = path.resolve(importerPath);
|
|
18
|
+
if (!normalizedImporter.startsWith(normalizedApiDir))
|
|
19
|
+
return null;
|
|
20
|
+
const candidate = path.resolve(path.dirname(normalizedImporter), id);
|
|
21
|
+
const resolved = resolveWithExtension(candidate);
|
|
22
|
+
return resolved ? pathToFileURL(resolved).href : null;
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vitek:transform — rewrite relative imports to root-relative paths
|
|
3
|
+
*/
|
|
4
|
+
import type { Plugin } from 'vite';
|
|
5
|
+
import type { PluginContext } from './context.js';
|
|
6
|
+
export declare function createTransformPlugin(ctx: PluginContext): Plugin;
|
|
7
|
+
//# sourceMappingURL=vitek-transform.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vitek-transform.d.ts","sourceRoot":"","sources":["../../src/plugin/vitek-transform.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAOnC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CA2ChE"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vitek:transform — rewrite relative imports to root-relative paths
|
|
3
|
+
*/
|
|
4
|
+
import * as path from 'path';
|
|
5
|
+
import MagicString from 'magic-string';
|
|
6
|
+
import { normalizeModuleIdPath, resolveWithExtension, } from '../adapters/vite/path-utils.js';
|
|
7
|
+
export function createTransformPlugin(ctx) {
|
|
8
|
+
return {
|
|
9
|
+
name: 'vitek:transform',
|
|
10
|
+
enforce: 'pre',
|
|
11
|
+
// filter is supported in Vite 6.3+; ignored in Vite 5 (handler still works)
|
|
12
|
+
transform: {
|
|
13
|
+
filter: {
|
|
14
|
+
id: { include: /\.(tsx?|jsx?|mjs)$/, exclude: /node_modules/ },
|
|
15
|
+
},
|
|
16
|
+
handler(code, id) {
|
|
17
|
+
if (!ctx.root)
|
|
18
|
+
return null;
|
|
19
|
+
// Early return for Vite 5 (filter ignored); filter handles this in Vite 6.3+
|
|
20
|
+
if (id.includes('node_modules') || !/\.(tsx?|jsx?|mjs)$/.test(id))
|
|
21
|
+
return null;
|
|
22
|
+
const srcDir = path.resolve(ctx.root, ctx.options.srcDir ?? 'src');
|
|
23
|
+
const normalizedId = normalizeModuleIdPath(id, ctx.root);
|
|
24
|
+
if (!normalizedId.startsWith(srcDir))
|
|
25
|
+
return null;
|
|
26
|
+
const dir = path.dirname(normalizedId);
|
|
27
|
+
const rootSlash = path.resolve(ctx.root) + path.sep;
|
|
28
|
+
const relImportRe = /from\s+['"](\.\.?[^'"]+)['"]/g;
|
|
29
|
+
let match;
|
|
30
|
+
const s = new MagicString(code);
|
|
31
|
+
let hasChanges = false;
|
|
32
|
+
while ((match = relImportRe.exec(code)) !== null) {
|
|
33
|
+
const specifier = match[1];
|
|
34
|
+
const candidate = path.resolve(dir, specifier);
|
|
35
|
+
if (!candidate.startsWith(rootSlash))
|
|
36
|
+
continue;
|
|
37
|
+
const target = resolveWithExtension(candidate);
|
|
38
|
+
if (!target)
|
|
39
|
+
continue;
|
|
40
|
+
const rootRelative = path.relative(ctx.root, target).replace(/\\/g, '/');
|
|
41
|
+
const newSpecifier = `/${rootRelative}`;
|
|
42
|
+
const quote = match[0].includes('"') ? '"' : "'";
|
|
43
|
+
s.overwrite(match.index, match.index + match[0].length, `from ${quote}${newSpecifier}${quote}`);
|
|
44
|
+
hasChanges = true;
|
|
45
|
+
}
|
|
46
|
+
if (!hasChanges)
|
|
47
|
+
return null;
|
|
48
|
+
return {
|
|
49
|
+
code: s.toString(),
|
|
50
|
+
map: s.generateMap({ hires: 'boundary' }),
|
|
51
|
+
};
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main Vitek plugin — aggregates sub-plugins
|
|
3
|
+
*/
|
|
4
|
+
import type { Plugin } from 'vite';
|
|
5
|
+
import type { VitekOptions } from './options.js';
|
|
6
|
+
/**
|
|
7
|
+
* Vite plugin for Vitek — returns array of sub-plugins.
|
|
8
|
+
*/
|
|
9
|
+
export declare function vitek(options?: VitekOptions): Plugin[];
|
|
10
|
+
//# sourceMappingURL=vitek.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vitek.d.ts","sourceRoot":"","sources":["../../src/plugin/vitek.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AASnC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD;;GAEG;AACH,wBAAgB,KAAK,CAAC,OAAO,GAAE,YAAiB,GAAG,MAAM,EAAE,CAa1D"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main Vitek plugin — aggregates sub-plugins
|
|
3
|
+
*/
|
|
4
|
+
import { API_DIR_NAME } from '../shared/constants.js';
|
|
5
|
+
import { createPluginContext } from './context.js';
|
|
6
|
+
import { createConfigPlugin } from './vitek-config.js';
|
|
7
|
+
import { createBuildPlugin } from './vitek-build.js';
|
|
8
|
+
import { createResolvePlugin } from './vitek-resolve.js';
|
|
9
|
+
import { createTransformPlugin } from './vitek-transform.js';
|
|
10
|
+
import { createDevPlugin } from './vitek-dev.js';
|
|
11
|
+
import { createPreviewPlugin } from './vitek-preview.js';
|
|
12
|
+
/**
|
|
13
|
+
* Vite plugin for Vitek — returns array of sub-plugins.
|
|
14
|
+
*/
|
|
15
|
+
export function vitek(options = {}) {
|
|
16
|
+
const apiDirOption = options.apiDir || `src/${API_DIR_NAME}`;
|
|
17
|
+
const buildApi = options.buildApi !== false;
|
|
18
|
+
const ctx = createPluginContext(options, apiDirOption, buildApi);
|
|
19
|
+
return [
|
|
20
|
+
createConfigPlugin(ctx),
|
|
21
|
+
createBuildPlugin(ctx),
|
|
22
|
+
createResolvePlugin(ctx),
|
|
23
|
+
createTransformPlugin(ctx),
|
|
24
|
+
createDevPlugin(ctx),
|
|
25
|
+
createPreviewPlugin(ctx),
|
|
26
|
+
];
|
|
27
|
+
}
|
package/dist/plugin.d.ts
CHANGED
|
@@ -1,36 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Main Vite plugin
|
|
3
|
-
*
|
|
3
|
+
* Exports VitekOptions and vitek() — aggregates sub-plugins
|
|
4
4
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export interface VitekOptions {
|
|
8
|
-
/** API directory (relative to root) */
|
|
9
|
-
apiDir?: string;
|
|
10
|
-
/** API base path (default: /api) */
|
|
11
|
-
apiBasePath?: string;
|
|
12
|
-
/** Build API bundle for preview/production (default: true). Set to false to skip. */
|
|
13
|
-
buildApi?: boolean;
|
|
14
|
-
/** Enable request validation (default: false) */
|
|
15
|
-
enableValidation?: boolean;
|
|
16
|
-
/** Logging configuration */
|
|
17
|
-
logging?: {
|
|
18
|
-
/** Log level: 'debug' | 'info' | 'warn' | 'error' (default: 'info') */
|
|
19
|
-
level?: 'debug' | 'info' | 'warn' | 'error';
|
|
20
|
-
/** Enable request/response logging (default: false) */
|
|
21
|
-
enableRequestLogging?: boolean;
|
|
22
|
-
/** Enable route matching logs (default: true) */
|
|
23
|
-
enableRouteLogging?: boolean;
|
|
24
|
-
};
|
|
25
|
-
/** Enable OpenAPI/Swagger documentation generation */
|
|
26
|
-
openApi?: OpenApiOptions | boolean;
|
|
27
|
-
/** Enable WebSocket sockets (default: true). Set to false to disable, or { path: '/ws' } to customize base path. */
|
|
28
|
-
sockets?: boolean | {
|
|
29
|
-
path?: string;
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Vite plugin for Vitek
|
|
34
|
-
*/
|
|
35
|
-
export declare function vitek(options?: VitekOptions): Plugin;
|
|
5
|
+
export type { VitekOptions } from './plugin/options.js';
|
|
6
|
+
export { vitek } from './plugin/vitek.js';
|
|
36
7
|
//# sourceMappingURL=plugin.d.ts.map
|
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC"}
|