@taserjs/plugin 0.2.0
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/LICENSE +15 -0
- package/README.md +21 -0
- package/dist/esbuild.d.ts +7 -0
- package/dist/esbuild.d.ts.map +1 -0
- package/dist/esbuild.js +8 -0
- package/dist/esbuild.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +337 -0
- package/dist/index.js.map +1 -0
- package/dist/next.d.ts +18 -0
- package/dist/next.d.ts.map +1 -0
- package/dist/next.js +90 -0
- package/dist/next.js.map +1 -0
- package/dist/nitro.d.ts +17 -0
- package/dist/nitro.d.ts.map +1 -0
- package/dist/nitro.js +149 -0
- package/dist/nitro.js.map +1 -0
- package/dist/rolldown.d.ts +6 -0
- package/dist/rolldown.d.ts.map +1 -0
- package/dist/rolldown.js +7 -0
- package/dist/rolldown.js.map +1 -0
- package/dist/rollup.d.ts +7 -0
- package/dist/rollup.d.ts.map +1 -0
- package/dist/rollup.js +8 -0
- package/dist/rollup.js.map +1 -0
- package/dist/rspack.d.ts +7 -0
- package/dist/rspack.d.ts.map +1 -0
- package/dist/rspack.js +8 -0
- package/dist/rspack.js.map +1 -0
- package/dist/vite.d.ts +7 -0
- package/dist/vite.d.ts.map +1 -0
- package/dist/vite.js +8 -0
- package/dist/vite.js.map +1 -0
- package/dist/webpack.d.ts +7 -0
- package/dist/webpack.d.ts.map +1 -0
- package/dist/webpack.js +8 -0
- package/dist/webpack.js.map +1 -0
- package/package.json +155 -0
- package/src/esbuild.ts +5 -0
- package/src/index.ts +538 -0
- package/src/next.ts +121 -0
- package/src/nitro.ts +189 -0
- package/src/rolldown.ts +5 -0
- package/src/rollup.ts +5 -0
- package/src/rspack.ts +5 -0
- package/src/vite.ts +20 -0
- package/src/webpack.ts +5 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
ISC License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026, Taser.js contributors
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
copyright notice and this permission notice appear in all copies.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
10
|
+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
11
|
+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
12
|
+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
13
|
+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
14
|
+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
15
|
+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# @taserjs/plugin
|
|
2
|
+
|
|
3
|
+
Universal bundler integration for Taser.js (Vite, Next.js, Nitro, Webpack, Rspack, Rollup, Rolldown, and esbuild).
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -D @taserjs/plugin
|
|
9
|
+
# or
|
|
10
|
+
pnpm add -D @taserjs/plugin
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Subpath exports are available for each bundler (for example `@taserjs/plugin/vite`).
|
|
14
|
+
|
|
15
|
+
## Documentation
|
|
16
|
+
|
|
17
|
+
Guides and API reference: [taserjs.dev](https://taserjs.dev)
|
|
18
|
+
|
|
19
|
+
## License
|
|
20
|
+
|
|
21
|
+
[ISC](https://github.com/taserjs/taserjs/blob/main/LICENSE)
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { TaserPluginOptions } from "./index.js";
|
|
2
|
+
//#region src/esbuild.d.ts
|
|
3
|
+
export declare const taser: (options?: TaserPluginOptions | undefined) => import("unplugin").EsbuildPlugin;
|
|
4
|
+
declare const _default: (options?: TaserPluginOptions | undefined) => import("unplugin").EsbuildPlugin;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { type TaserPluginOptions, _default as default };
|
|
7
|
+
//# sourceMappingURL=esbuild.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"esbuild.d.ts","names":[],"sources":["../src/esbuild.ts"],"mappings":";;qBAEa,QAAK,UAAA,sDAAA"}
|
package/dist/esbuild.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"esbuild.js","names":[],"sources":["../src/esbuild.ts"],"sourcesContent":["import { taserPlugin, type TaserPluginOptions } from \"./index.js\";\n\nexport const taser = taserPlugin.esbuild;\nexport default taserPlugin.esbuild;\nexport type { TaserPluginOptions };\n"],"mappings":";;AAEA,MAAa,QAAQ,YAAY;AACjC,IAAA,kBAAe,YAAY"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ResolvedTaserConfig } from "@taserjs/cli";
|
|
2
|
+
//#region src/index.d.ts
|
|
3
|
+
export declare const DEFAULT_WATCH_DEBOUNCE_MS = 50;
|
|
4
|
+
export declare const DEFAULT_OUTPUT_IGNORE_PATTERN = "**/.taserjs/**";
|
|
5
|
+
export interface TaserPluginOptions {
|
|
6
|
+
server?: boolean | undefined;
|
|
7
|
+
serverEntry?: string | undefined;
|
|
8
|
+
cwd?: string | undefined;
|
|
9
|
+
config?: string | undefined;
|
|
10
|
+
standalone?: boolean | undefined;
|
|
11
|
+
}
|
|
12
|
+
export interface HostServerInfo {
|
|
13
|
+
type: "node" | "fetch";
|
|
14
|
+
path: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function detectHostServer(serverDir: string, cwd?: string, explicitEntry?: string): HostServerInfo | null;
|
|
17
|
+
export declare function normalizeImportPath(pathStr: string): string;
|
|
18
|
+
export declare function isSubPath(child: string, parent: string): boolean;
|
|
19
|
+
export declare function isOutputDir(filePath: string, outputDir: string): boolean;
|
|
20
|
+
export declare function getHostServer(config: ResolvedTaserConfig, cwd: string, options?: TaserPluginOptions): HostServerInfo | null;
|
|
21
|
+
export declare function resolveHostFetchHandler(hostMod: unknown, type: "node" | "fetch"): ((fetchReq: Request) => Promise<Response> | Response) | null;
|
|
22
|
+
export declare function mountHostFallback(app: any, hostMod: unknown, type: "node" | "fetch"): boolean;
|
|
23
|
+
export declare function buildHostFallbackCode(hostImportPath: string, type: "node" | "fetch", appVarName?: string): {
|
|
24
|
+
imports: string;
|
|
25
|
+
setup: string;
|
|
26
|
+
};
|
|
27
|
+
export declare function emitServeShim(serveShimPath: string, routesGenImportPath: string, hostServer?: HostServerInfo | null, ext?: string): void;
|
|
28
|
+
export declare const taserPlugin: import("unplugin").UnpluginInstance<TaserPluginOptions | undefined, boolean>;
|
|
29
|
+
export declare const taser: ((options?: TaserPluginOptions) => import("unplugin").UnpluginOptions | import("unplugin").UnpluginOptions[]) & import("unplugin").UnpluginInstance<TaserPluginOptions | undefined, boolean>;
|
|
30
|
+
//#endregion
|
|
31
|
+
export { taserPlugin as default };
|
|
32
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;qBAgBa;qBACA;iBAEI;EACf;EACA;EACA;EACA;EACA;;iBAGe;EACf;EACA;;wBAYc,iBACd,mBACA,cACA,yBACC;wBAwFa,oBAAoB;wBAQpB,UAAU,eAAe;wBAKzB,YAAY,kBAAkB;wBA0B9B,cACd,QAAQ,qBACR,aACA,UAAU,qBACT;wBAKa,wBACd,kBACA,2BACG,UAAU,YAAY,QAAQ,YAAY;wBAY/B,kBAAkB,UAAU,kBAAkB;wBAa9C,sBACd,wBACA,wBACA;EACG;EAAiB;;wBAgBN,cACd,uBACA,6BACA,aAAa,uBACb;qBA0CW,gCAAW,iBAAA;qBAkQX,SAAK,UACL,0CAAkB,qCAAA,wCAAA,iBAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { isAbsolute, join, normalize, relative, resolve } from "pathe";
|
|
3
|
+
import { generateManifest, loadConfig, resolveAppFile, resolveImportExtension, resolveOutputDir, resolveRoutesDir, resolveServerDir, scanRoutes } from "@taserjs/cli";
|
|
4
|
+
import { toFetchHandler, toNodeHandler } from "srvx/node";
|
|
5
|
+
import { createUnplugin } from "unplugin";
|
|
6
|
+
//#region src/index.ts
|
|
7
|
+
const DEFAULT_WATCH_DEBOUNCE_MS = 50;
|
|
8
|
+
const DEFAULT_OUTPUT_IGNORE_PATTERN = "**/.taserjs/**";
|
|
9
|
+
const NODE_SERVER_CANDIDATES = [
|
|
10
|
+
"server.node.ts",
|
|
11
|
+
"server.node.js",
|
|
12
|
+
"server.node.mjs",
|
|
13
|
+
"server.node.cjs"
|
|
14
|
+
];
|
|
15
|
+
const FETCH_SERVER_CANDIDATES = [
|
|
16
|
+
"server.ts",
|
|
17
|
+
"server.js",
|
|
18
|
+
"server.mjs",
|
|
19
|
+
"server.cjs"
|
|
20
|
+
];
|
|
21
|
+
function detectHostServer(serverDir, cwd, explicitEntry) {
|
|
22
|
+
if (explicitEntry) {
|
|
23
|
+
const resolvedPath = isAbsolute(explicitEntry) ? explicitEntry : resolve(cwd ?? process.cwd(), explicitEntry);
|
|
24
|
+
if (existsSync(resolvedPath)) return {
|
|
25
|
+
type: resolvedPath.includes(".node.") || resolvedPath.endsWith(".node") ? "node" : "fetch",
|
|
26
|
+
path: resolvedPath
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
for (const candidate of NODE_SERVER_CANDIDATES) {
|
|
30
|
+
const candidatePath = join(serverDir, candidate);
|
|
31
|
+
if (existsSync(candidatePath)) return {
|
|
32
|
+
type: "node",
|
|
33
|
+
path: candidatePath
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
for (const candidate of FETCH_SERVER_CANDIDATES) {
|
|
37
|
+
const candidatePath = join(serverDir, candidate);
|
|
38
|
+
if (existsSync(candidatePath)) return {
|
|
39
|
+
type: "fetch",
|
|
40
|
+
path: candidatePath
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
const FULLSTACK_PLUGIN_PATTERNS = [
|
|
46
|
+
"nitro",
|
|
47
|
+
"tanstack-start",
|
|
48
|
+
"tanstack:router",
|
|
49
|
+
"react-router",
|
|
50
|
+
"remix",
|
|
51
|
+
"astro",
|
|
52
|
+
"sveltekit"
|
|
53
|
+
];
|
|
54
|
+
function isFullStackPluginName(name) {
|
|
55
|
+
const lower = name.toLowerCase();
|
|
56
|
+
for (const pattern of FULLSTACK_PLUGIN_PATTERNS) if (lower.includes(pattern)) return true;
|
|
57
|
+
if (lower.includes("tanstack") && lower.includes("start")) return true;
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
function detectFullStack(viteConfig) {
|
|
61
|
+
if (!viteConfig) return false;
|
|
62
|
+
if (viteConfig.nitro) return true;
|
|
63
|
+
const plugins = viteConfig.plugins;
|
|
64
|
+
if (!plugins) return false;
|
|
65
|
+
return (Array.isArray(plugins) ? plugins.flat(Infinity) : [plugins]).some((p) => {
|
|
66
|
+
const name = p?.name;
|
|
67
|
+
return typeof name === "string" && isFullStackPluginName(name);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
function isRunnableEnvironment(environment) {
|
|
71
|
+
if (!environment) return true;
|
|
72
|
+
try {
|
|
73
|
+
if (environment.constructor?.name === "FetchableDevEnvironment") return false;
|
|
74
|
+
if (environment.constructor?.name === "RunnableDevEnvironment") return true;
|
|
75
|
+
if (typeof environment.dispatchFetch === "function" && !environment.runner) return false;
|
|
76
|
+
if (environment.runner) return true;
|
|
77
|
+
} catch (err) {
|
|
78
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
79
|
+
console.warn(`[taserjs] Warning checking Vite environment runnability: ${message}`);
|
|
80
|
+
}
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
function normalizeImportPath(pathStr) {
|
|
84
|
+
let normalized = normalize(pathStr);
|
|
85
|
+
if (!isAbsolute(normalized) && !normalized.startsWith("./") && !normalized.startsWith("../")) normalized = `./${normalized}`;
|
|
86
|
+
return normalized;
|
|
87
|
+
}
|
|
88
|
+
function isSubPath(child, parent) {
|
|
89
|
+
const rel = relative(parent, child);
|
|
90
|
+
return !rel.startsWith("../") && rel !== ".." && !isAbsolute(rel);
|
|
91
|
+
}
|
|
92
|
+
function isOutputDir(filePath, outputDir) {
|
|
93
|
+
const normalizedFile = resolve(filePath);
|
|
94
|
+
const normalizedOutput = resolve(outputDir);
|
|
95
|
+
return normalizedFile === normalizedOutput || isSubPath(normalizedFile, normalizedOutput) || filePath.includes(".taserjs");
|
|
96
|
+
}
|
|
97
|
+
function mergeWatchIgnored(current, ...patterns) {
|
|
98
|
+
const existing = Array.isArray(current) ? [...current] : current ? [current] : [];
|
|
99
|
+
for (const pattern of patterns) if (!existing.includes(pattern)) existing.push(pattern);
|
|
100
|
+
return existing;
|
|
101
|
+
}
|
|
102
|
+
function getHostServer(config, cwd, options) {
|
|
103
|
+
return detectHostServer(resolveServerDir(config, cwd), cwd, options?.serverEntry);
|
|
104
|
+
}
|
|
105
|
+
function resolveHostFetchHandler(hostMod, type) {
|
|
106
|
+
const rawHost = hostMod?.default ?? hostMod;
|
|
107
|
+
if (type === "node") {
|
|
108
|
+
const nodeHandler = typeof rawHost === "function" ? rawHost : rawHost?.routing ?? rawHost;
|
|
109
|
+
return typeof nodeHandler === "function" ? toFetchHandler(nodeHandler) : null;
|
|
110
|
+
}
|
|
111
|
+
if (typeof rawHost?.fetch === "function") return (fetchReq) => rawHost.fetch(fetchReq);
|
|
112
|
+
return typeof rawHost === "function" ? rawHost : null;
|
|
113
|
+
}
|
|
114
|
+
function mountHostFallback(app, hostMod, type) {
|
|
115
|
+
if (!app || typeof app.all !== "function" || app._hasHostFallback) return false;
|
|
116
|
+
const hostFetch = resolveHostFetchHandler(hostMod, type);
|
|
117
|
+
if (hostFetch) {
|
|
118
|
+
app.all("*", (c) => hostFetch(c.req.raw));
|
|
119
|
+
app._hasHostFallback = true;
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
function buildHostFallbackCode(hostImportPath, type, appVarName = "app") {
|
|
125
|
+
const isNode = type === "node";
|
|
126
|
+
return {
|
|
127
|
+
imports: `${isNode ? "import { toFetchHandler } from \"srvx/node\";\n" : ""}import hostServerEntry from "${hostImportPath}";`,
|
|
128
|
+
setup: isNode ? `const rawHost = hostServerEntry?.default ?? hostServerEntry;
|
|
129
|
+
const nodeHandler = typeof rawHost === "function" ? rawHost : (rawHost?.routing ?? rawHost);
|
|
130
|
+
const hostFetch = typeof nodeHandler === "function" ? toFetchHandler(nodeHandler) : null;
|
|
131
|
+
if (hostFetch) ${appVarName}.all("*", (c) => hostFetch(c.req.raw));` : `const rawHost = hostServerEntry?.default ?? hostServerEntry;
|
|
132
|
+
const hostFetch = typeof rawHost?.fetch === "function" ? (r) => rawHost.fetch(r) : typeof rawHost === "function" ? rawHost : null;
|
|
133
|
+
if (hostFetch) ${appVarName}.all("*", (c) => hostFetch(c.req.raw));`
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
function emitServeShim(serveShimPath, routesGenImportPath, hostServer, ext = ".js") {
|
|
137
|
+
const normalizedRoutesPath = normalizeImportPath(routesGenImportPath);
|
|
138
|
+
const outputDir = resolve(serveShimPath, "..");
|
|
139
|
+
let code;
|
|
140
|
+
if (hostServer) {
|
|
141
|
+
let hostImportPath = normalizeImportPath(relative(outputDir, hostServer.path));
|
|
142
|
+
if (hostImportPath.endsWith(".ts")) hostImportPath = hostImportPath.slice(0, -3) + ext;
|
|
143
|
+
else if (hostImportPath.endsWith(".js") && ext === "") hostImportPath = hostImportPath.slice(0, -3);
|
|
144
|
+
const fallbackCode = buildHostFallbackCode(hostImportPath, hostServer.type, "app");
|
|
145
|
+
code = `// @ts-nocheck
|
|
146
|
+
import { FastResponse } from "srvx";
|
|
147
|
+
globalThis.Response = FastResponse;
|
|
148
|
+
import { serve } from "srvx/node";
|
|
149
|
+
${fallbackCode.imports}
|
|
150
|
+
import { app } from "${normalizedRoutesPath}";
|
|
151
|
+
|
|
152
|
+
${fallbackCode.setup}
|
|
153
|
+
|
|
154
|
+
export { app };
|
|
155
|
+
serve(app);
|
|
156
|
+
`;
|
|
157
|
+
} else code = `// @ts-nocheck
|
|
158
|
+
import { FastResponse } from "srvx";
|
|
159
|
+
globalThis.Response = FastResponse;
|
|
160
|
+
import { serve } from "srvx/node";
|
|
161
|
+
import { app } from "${normalizedRoutesPath}";
|
|
162
|
+
|
|
163
|
+
serve(app);
|
|
164
|
+
`;
|
|
165
|
+
mkdirSync(resolve(serveShimPath, ".."), { recursive: true });
|
|
166
|
+
writeFileSync(serveShimPath, code, "utf-8");
|
|
167
|
+
}
|
|
168
|
+
const taserPlugin = createUnplugin((options = {}, meta) => {
|
|
169
|
+
let cwd = options.cwd ? resolve(options.cwd) : process.cwd();
|
|
170
|
+
let cachedConfig = null;
|
|
171
|
+
let detectedFullStack = null;
|
|
172
|
+
async function getConfig() {
|
|
173
|
+
if (!cachedConfig) cachedConfig = await loadConfig(cwd, options.config);
|
|
174
|
+
return cachedConfig;
|
|
175
|
+
}
|
|
176
|
+
async function resolveIsServerMode(viteConfig) {
|
|
177
|
+
if (options.server !== void 0) return options.server;
|
|
178
|
+
const config = await getConfig();
|
|
179
|
+
if (config.server !== void 0) return config.server;
|
|
180
|
+
if (detectedFullStack !== null) return !detectedFullStack;
|
|
181
|
+
if (viteConfig && detectFullStack(viteConfig)) {
|
|
182
|
+
detectedFullStack = true;
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
async function executeGeneration(isDev = false) {
|
|
188
|
+
try {
|
|
189
|
+
const config = await getConfig();
|
|
190
|
+
const routesDir = resolveRoutesDir(config, cwd);
|
|
191
|
+
const scanResult = scanRoutes({
|
|
192
|
+
routesDir,
|
|
193
|
+
cwd,
|
|
194
|
+
scaffold: isDev,
|
|
195
|
+
formatting: config.formatting
|
|
196
|
+
});
|
|
197
|
+
generateManifest(scanResult, config, cwd);
|
|
198
|
+
} catch (err) {
|
|
199
|
+
if (isDev) {
|
|
200
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
201
|
+
console.error(`[taserjs] Route generation warning: ${message}`);
|
|
202
|
+
} else throw err;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
let debounceTimer = null;
|
|
206
|
+
function triggerDebouncedGeneration() {
|
|
207
|
+
if (debounceTimer) clearTimeout(debounceTimer);
|
|
208
|
+
debounceTimer = setTimeout(() => {
|
|
209
|
+
executeGeneration(true).catch(() => {});
|
|
210
|
+
}, 50);
|
|
211
|
+
}
|
|
212
|
+
let cachedDevHandler = null;
|
|
213
|
+
const VITE_INTERNAL_PREFIXES = [
|
|
214
|
+
"/@",
|
|
215
|
+
"/__vite",
|
|
216
|
+
"/__open-in-editor",
|
|
217
|
+
"/@fs/",
|
|
218
|
+
"/@id/"
|
|
219
|
+
];
|
|
220
|
+
const VITE_QUERY_PATTERN = /[?&](?:import|raw|url|worker)\b/;
|
|
221
|
+
function shouldSkipDevRequest(url) {
|
|
222
|
+
for (let i = 0; i < VITE_INTERNAL_PREFIXES.length; i++) if (url.startsWith(VITE_INTERNAL_PREFIXES[i])) return true;
|
|
223
|
+
if (url.startsWith("/node_modules/")) return true;
|
|
224
|
+
return VITE_QUERY_PATTERN.test(url);
|
|
225
|
+
}
|
|
226
|
+
return {
|
|
227
|
+
name: "taserjs:plugin",
|
|
228
|
+
async buildStart() {
|
|
229
|
+
await executeGeneration(meta.framework === "vite");
|
|
230
|
+
if (await resolveIsServerMode()) {
|
|
231
|
+
const config = await getConfig();
|
|
232
|
+
const outputDir = resolveOutputDir(config, cwd);
|
|
233
|
+
const hostServer = getHostServer(config, cwd, options);
|
|
234
|
+
const serveShimPath = join(outputDir, "serve.ts");
|
|
235
|
+
const ext = resolveImportExtension(config.extension);
|
|
236
|
+
emitServeShim(serveShimPath, `./routes.gen${ext}`, hostServer, ext);
|
|
237
|
+
}
|
|
238
|
+
},
|
|
239
|
+
async watchChange(id, _change) {
|
|
240
|
+
cachedDevHandler = null;
|
|
241
|
+
const config = await getConfig();
|
|
242
|
+
if (isOutputDir(id, resolveOutputDir(config, cwd))) return;
|
|
243
|
+
const routesDir = resolveRoutesDir(config, cwd);
|
|
244
|
+
const serverDir = resolveServerDir(config, cwd);
|
|
245
|
+
if (id === resolveAppFile(config, cwd) || isSubPath(id, routesDir) || isSubPath(id, serverDir)) await executeGeneration(true);
|
|
246
|
+
},
|
|
247
|
+
vite: {
|
|
248
|
+
async config(config, env) {
|
|
249
|
+
if (!options.cwd && config.root) {
|
|
250
|
+
cwd = resolve(config.root);
|
|
251
|
+
cachedConfig = null;
|
|
252
|
+
}
|
|
253
|
+
config.server = config.server || {};
|
|
254
|
+
config.server.watch = config.server.watch || {};
|
|
255
|
+
config.server.watch.ignored = mergeWatchIgnored(config.server.watch.ignored, DEFAULT_OUTPUT_IGNORE_PATTERN);
|
|
256
|
+
detectedFullStack = detectFullStack(config);
|
|
257
|
+
if (await resolveIsServerMode(config) && env?.command === "build") {
|
|
258
|
+
const taserConfig = await getConfig();
|
|
259
|
+
const outputDir = resolveOutputDir(taserConfig, cwd);
|
|
260
|
+
const hostServer = getHostServer(taserConfig, cwd, options);
|
|
261
|
+
const serveShimPath = join(outputDir, "serve.ts");
|
|
262
|
+
const ext = resolveImportExtension(taserConfig.extension);
|
|
263
|
+
emitServeShim(serveShimPath, `./routes.gen${ext}`, hostServer, ext);
|
|
264
|
+
return { build: {
|
|
265
|
+
ssr: serveShimPath,
|
|
266
|
+
rollupOptions: {
|
|
267
|
+
external: [
|
|
268
|
+
"srvx",
|
|
269
|
+
"srvx/node",
|
|
270
|
+
"@taserjs/runtime",
|
|
271
|
+
"hono"
|
|
272
|
+
],
|
|
273
|
+
output: { entryFileNames: "serve.mjs" }
|
|
274
|
+
}
|
|
275
|
+
} };
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
configResolved(resolvedConfig) {
|
|
279
|
+
if (detectFullStack(resolvedConfig)) detectedFullStack = true;
|
|
280
|
+
else if (detectedFullStack === null) detectedFullStack = false;
|
|
281
|
+
},
|
|
282
|
+
async configureServer(server) {
|
|
283
|
+
const handleFileChange = async (file) => {
|
|
284
|
+
cachedDevHandler = null;
|
|
285
|
+
const config = await getConfig();
|
|
286
|
+
if (isOutputDir(file, resolveOutputDir(config, cwd))) return;
|
|
287
|
+
const routesDir = resolveRoutesDir(config, cwd);
|
|
288
|
+
const serverDir = resolveServerDir(config, cwd);
|
|
289
|
+
if (file === resolveAppFile(config, cwd) || isSubPath(file, routesDir) || isSubPath(file, serverDir)) triggerDebouncedGeneration();
|
|
290
|
+
};
|
|
291
|
+
server.watcher.on("add", handleFileChange);
|
|
292
|
+
server.watcher.on("unlink", handleFileChange);
|
|
293
|
+
server.watcher.on("change", handleFileChange);
|
|
294
|
+
server.watcher.on("unlinkDir", handleFileChange);
|
|
295
|
+
if (!await resolveIsServerMode(server.config)) return;
|
|
296
|
+
server.middlewares.use(async (req, res, next) => {
|
|
297
|
+
const url = req.url;
|
|
298
|
+
if (!url || shouldSkipDevRequest(url)) return next();
|
|
299
|
+
const ssrEnv = server.environments?.ssr;
|
|
300
|
+
if (server.environments && ssrEnv && !isRunnableEnvironment(ssrEnv)) return next();
|
|
301
|
+
try {
|
|
302
|
+
if (!cachedDevHandler) {
|
|
303
|
+
const taserConfig = await getConfig();
|
|
304
|
+
const outputDir = resolveOutputDir(taserConfig, cwd);
|
|
305
|
+
const routesGenPath = join(outputDir, "routes.gen.ts");
|
|
306
|
+
if (!existsSync(routesGenPath)) await executeGeneration(true);
|
|
307
|
+
const mod = await server.ssrLoadModule(routesGenPath);
|
|
308
|
+
const app = mod.app ?? mod.default;
|
|
309
|
+
if (!app || typeof app.fetch !== "function") return next();
|
|
310
|
+
const hostServer = getHostServer(taserConfig, cwd, options);
|
|
311
|
+
if (hostServer) mountHostFallback(app, await server.ssrLoadModule(hostServer.path), hostServer.type);
|
|
312
|
+
cachedDevHandler = toNodeHandler((fetchReq) => app.fetch(fetchReq));
|
|
313
|
+
}
|
|
314
|
+
if (cachedDevHandler) await cachedDevHandler(req, res);
|
|
315
|
+
else next();
|
|
316
|
+
} catch (error) {
|
|
317
|
+
server.ssrFixStacktrace(error);
|
|
318
|
+
next(error);
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
},
|
|
323
|
+
webpack(compiler) {
|
|
324
|
+
compiler.options.watchOptions = compiler.options.watchOptions || {};
|
|
325
|
+
compiler.options.watchOptions.ignored = mergeWatchIgnored(compiler.options.watchOptions.ignored, DEFAULT_OUTPUT_IGNORE_PATTERN);
|
|
326
|
+
},
|
|
327
|
+
rspack(compiler) {
|
|
328
|
+
compiler.options.watchOptions = compiler.options.watchOptions || {};
|
|
329
|
+
compiler.options.watchOptions.ignored = mergeWatchIgnored(compiler.options.watchOptions.ignored, DEFAULT_OUTPUT_IGNORE_PATTERN);
|
|
330
|
+
}
|
|
331
|
+
};
|
|
332
|
+
});
|
|
333
|
+
const taser = Object.assign((options) => taserPlugin.raw(options, {}), taserPlugin);
|
|
334
|
+
//#endregion
|
|
335
|
+
export { DEFAULT_OUTPUT_IGNORE_PATTERN, DEFAULT_WATCH_DEBOUNCE_MS, buildHostFallbackCode, taserPlugin as default, taserPlugin, detectHostServer, emitServeShim, getHostServer, isOutputDir, isSubPath, mountHostFallback, normalizeImportPath, resolveHostFetchHandler, taser };
|
|
336
|
+
|
|
337
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import { existsSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { isAbsolute, join, normalize, relative, resolve } from \"pathe\";\nimport {\n generateManifest,\n loadConfig,\n resolveAppFile,\n resolveImportExtension,\n resolveOutputDir,\n resolveRoutesDir,\n resolveServerDir,\n scanRoutes,\n type ResolvedTaserConfig,\n} from \"@taserjs/cli\";\nimport { toFetchHandler, toNodeHandler } from \"srvx/node\";\nimport { createUnplugin } from \"unplugin\";\n\nexport const DEFAULT_WATCH_DEBOUNCE_MS = 50;\nexport const DEFAULT_OUTPUT_IGNORE_PATTERN = \"**/.taserjs/**\";\n\nexport interface TaserPluginOptions {\n server?: boolean | undefined;\n serverEntry?: string | undefined;\n cwd?: string | undefined;\n config?: string | undefined;\n standalone?: boolean | undefined;\n}\n\nexport interface HostServerInfo {\n type: \"node\" | \"fetch\";\n path: string;\n}\n\nconst NODE_SERVER_CANDIDATES = [\n \"server.node.ts\",\n \"server.node.js\",\n \"server.node.mjs\",\n \"server.node.cjs\",\n];\n\nconst FETCH_SERVER_CANDIDATES = [\"server.ts\", \"server.js\", \"server.mjs\", \"server.cjs\"];\n\nexport function detectHostServer(\n serverDir: string,\n cwd?: string,\n explicitEntry?: string,\n): HostServerInfo | null {\n if (explicitEntry) {\n const resolvedPath = isAbsolute(explicitEntry)\n ? explicitEntry\n : resolve(cwd ?? process.cwd(), explicitEntry);\n if (existsSync(resolvedPath)) {\n const isNode = resolvedPath.includes(\".node.\") || resolvedPath.endsWith(\".node\");\n return {\n type: isNode ? \"node\" : \"fetch\",\n path: resolvedPath,\n };\n }\n }\n\n for (const candidate of NODE_SERVER_CANDIDATES) {\n const candidatePath = join(serverDir, candidate);\n if (existsSync(candidatePath)) {\n return { type: \"node\", path: candidatePath };\n }\n }\n\n for (const candidate of FETCH_SERVER_CANDIDATES) {\n const candidatePath = join(serverDir, candidate);\n if (existsSync(candidatePath)) {\n return { type: \"fetch\", path: candidatePath };\n }\n }\n\n return null;\n}\n\nconst FULLSTACK_PLUGIN_PATTERNS = [\n \"nitro\",\n \"tanstack-start\",\n \"tanstack:router\",\n \"react-router\",\n \"remix\",\n \"astro\",\n \"sveltekit\",\n];\n\nfunction isFullStackPluginName(name: string): boolean {\n const lower = name.toLowerCase();\n for (const pattern of FULLSTACK_PLUGIN_PATTERNS) {\n if (lower.includes(pattern)) {\n return true;\n }\n }\n if (lower.includes(\"tanstack\") && lower.includes(\"start\")) {\n return true;\n }\n return false;\n}\n\nfunction detectFullStack(viteConfig: any): boolean {\n if (!viteConfig) return false;\n if (viteConfig.nitro) return true;\n const plugins = viteConfig.plugins;\n if (!plugins) return false;\n const flat = Array.isArray(plugins) ? plugins.flat(Infinity) : [plugins];\n return flat.some((p: any) => {\n const name = p?.name;\n return typeof name === \"string\" && isFullStackPluginName(name);\n });\n}\n\nfunction isRunnableEnvironment(environment: any): boolean {\n if (!environment) return true;\n try {\n if (environment.constructor?.name === \"FetchableDevEnvironment\") {\n return false;\n }\n if (environment.constructor?.name === \"RunnableDevEnvironment\") {\n return true;\n }\n if (typeof (environment as any).dispatchFetch === \"function\" && !(environment as any).runner) {\n return false;\n }\n if ((environment as any).runner) {\n return true;\n }\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n console.warn(`[taserjs] Warning checking Vite environment runnability: ${message}`);\n }\n return true;\n}\n\nexport function normalizeImportPath(pathStr: string): string {\n let normalized = normalize(pathStr);\n if (!isAbsolute(normalized) && !normalized.startsWith(\"./\") && !normalized.startsWith(\"../\")) {\n normalized = `./${normalized}`;\n }\n return normalized;\n}\n\nexport function isSubPath(child: string, parent: string): boolean {\n const rel = relative(parent, child);\n return !rel.startsWith(\"../\") && rel !== \"..\" && !isAbsolute(rel);\n}\n\nexport function isOutputDir(filePath: string, outputDir: string): boolean {\n const normalizedFile = resolve(filePath);\n const normalizedOutput = resolve(outputDir);\n return (\n normalizedFile === normalizedOutput ||\n isSubPath(normalizedFile, normalizedOutput) ||\n filePath.includes(\".taserjs\")\n );\n}\n\nfunction mergeWatchIgnored(current: unknown, ...patterns: string[]): Array<string | RegExp> {\n const existing: Array<string | RegExp> = Array.isArray(current)\n ? [...current]\n : current\n ? [current as string | RegExp]\n : [];\n\n for (const pattern of patterns) {\n if (!existing.includes(pattern)) {\n existing.push(pattern);\n }\n }\n\n return existing;\n}\n\nexport function getHostServer(\n config: ResolvedTaserConfig,\n cwd: string,\n options?: TaserPluginOptions,\n): HostServerInfo | null {\n const serverDir = resolveServerDir(config, cwd);\n return detectHostServer(serverDir, cwd, options?.serverEntry);\n}\n\nexport function resolveHostFetchHandler(\n hostMod: unknown,\n type: \"node\" | \"fetch\",\n): ((fetchReq: Request) => Promise<Response> | Response) | null {\n const rawHost = (hostMod as Record<string, any>)?.default ?? hostMod;\n if (type === \"node\") {\n const nodeHandler = typeof rawHost === \"function\" ? rawHost : (rawHost?.routing ?? rawHost);\n return typeof nodeHandler === \"function\" ? toFetchHandler(nodeHandler) : null;\n }\n if (typeof (rawHost as any)?.fetch === \"function\") {\n return (fetchReq: Request) => (rawHost as any).fetch(fetchReq);\n }\n return typeof rawHost === \"function\" ? (rawHost as any) : null;\n}\n\nexport function mountHostFallback(app: any, hostMod: unknown, type: \"node\" | \"fetch\"): boolean {\n if (!app || typeof app.all !== \"function\" || app._hasHostFallback) {\n return false;\n }\n const hostFetch = resolveHostFetchHandler(hostMod, type);\n if (hostFetch) {\n app.all(\"*\", (c: any) => hostFetch(c.req.raw));\n app._hasHostFallback = true;\n return true;\n }\n return false;\n}\n\nexport function buildHostFallbackCode(\n hostImportPath: string,\n type: \"node\" | \"fetch\",\n appVarName: string = \"app\",\n): { imports: string; setup: string } {\n const isNode = type === \"node\";\n const imports = `${isNode ? 'import { toFetchHandler } from \"srvx/node\";\\n' : \"\"}import hostServerEntry from \"${hostImportPath}\";`;\n\n const setup = isNode\n ? `const rawHost = hostServerEntry?.default ?? hostServerEntry;\nconst nodeHandler = typeof rawHost === \"function\" ? rawHost : (rawHost?.routing ?? rawHost);\nconst hostFetch = typeof nodeHandler === \"function\" ? toFetchHandler(nodeHandler) : null;\nif (hostFetch) ${appVarName}.all(\"*\", (c) => hostFetch(c.req.raw));`\n : `const rawHost = hostServerEntry?.default ?? hostServerEntry;\nconst hostFetch = typeof rawHost?.fetch === \"function\" ? (r) => rawHost.fetch(r) : typeof rawHost === \"function\" ? rawHost : null;\nif (hostFetch) ${appVarName}.all(\"*\", (c) => hostFetch(c.req.raw));`;\n\n return { imports, setup };\n}\n\nexport function emitServeShim(\n serveShimPath: string,\n routesGenImportPath: string,\n hostServer?: HostServerInfo | null,\n ext: string = \".js\",\n): void {\n const normalizedRoutesPath = normalizeImportPath(routesGenImportPath);\n const outputDir = resolve(serveShimPath, \"..\");\n\n let code: string;\n if (hostServer) {\n let hostImportPath = normalizeImportPath(relative(outputDir, hostServer.path));\n if (hostImportPath.endsWith(\".ts\")) {\n hostImportPath = hostImportPath.slice(0, -3) + ext;\n } else if (hostImportPath.endsWith(\".js\") && ext === \"\") {\n hostImportPath = hostImportPath.slice(0, -3);\n }\n\n const fallbackCode = buildHostFallbackCode(hostImportPath, hostServer.type, \"app\");\n code = `// @ts-nocheck\nimport { FastResponse } from \"srvx\";\nglobalThis.Response = FastResponse;\nimport { serve } from \"srvx/node\";\n${fallbackCode.imports}\nimport { app } from \"${normalizedRoutesPath}\";\n\n${fallbackCode.setup}\n\nexport { app };\nserve(app);\n`;\n } else {\n code = `// @ts-nocheck\nimport { FastResponse } from \"srvx\";\nglobalThis.Response = FastResponse;\nimport { serve } from \"srvx/node\";\nimport { app } from \"${normalizedRoutesPath}\";\n\nserve(app);\n`;\n }\n\n mkdirSync(resolve(serveShimPath, \"..\"), { recursive: true });\n writeFileSync(serveShimPath, code, \"utf-8\");\n}\n\nexport const taserPlugin = createUnplugin((options: TaserPluginOptions | undefined = {}, meta) => {\n let cwd = options.cwd ? resolve(options.cwd) : process.cwd();\n let cachedConfig: ResolvedTaserConfig | null = null;\n let detectedFullStack: boolean | null = null;\n\n async function getConfig(): Promise<ResolvedTaserConfig> {\n if (!cachedConfig) {\n cachedConfig = await loadConfig(cwd, options.config);\n }\n return cachedConfig;\n }\n\n async function resolveIsServerMode(viteConfig?: any): Promise<boolean> {\n if (options.server !== undefined) {\n return options.server;\n }\n const config = await getConfig();\n if (config.server !== undefined) {\n return config.server;\n }\n if (detectedFullStack !== null) {\n return !detectedFullStack;\n }\n if (viteConfig && detectFullStack(viteConfig)) {\n detectedFullStack = true;\n return false;\n }\n return true;\n }\n\n async function executeGeneration(isDev = false): Promise<void> {\n try {\n const config = await getConfig();\n const routesDir = resolveRoutesDir(config, cwd);\n const scanResult = scanRoutes({\n routesDir,\n cwd,\n scaffold: isDev,\n formatting: config.formatting,\n });\n\n generateManifest(scanResult, config, cwd);\n } catch (err: unknown) {\n if (isDev) {\n const message = err instanceof Error ? err.message : String(err);\n console.error(`[taserjs] Route generation warning: ${message}`);\n } else {\n throw err;\n }\n }\n }\n\n let debounceTimer: ReturnType<typeof setTimeout> | null = null;\n function triggerDebouncedGeneration(): void {\n if (debounceTimer) {\n clearTimeout(debounceTimer);\n }\n debounceTimer = setTimeout(() => {\n executeGeneration(true).catch(() => {});\n }, DEFAULT_WATCH_DEBOUNCE_MS);\n }\n\n let cachedDevHandler: ((req: any, res: any) => any) | null = null;\n const VITE_INTERNAL_PREFIXES = [\"/@\", \"/__vite\", \"/__open-in-editor\", \"/@fs/\", \"/@id/\"];\n const VITE_QUERY_PATTERN = /[?&](?:import|raw|url|worker)\\b/;\n\n function shouldSkipDevRequest(url: string): boolean {\n for (let i = 0; i < VITE_INTERNAL_PREFIXES.length; i++) {\n if (url.startsWith(VITE_INTERNAL_PREFIXES[i]!)) {\n return true;\n }\n }\n if (url.startsWith(\"/node_modules/\")) {\n return true;\n }\n return VITE_QUERY_PATTERN.test(url);\n }\n\n return {\n name: \"taserjs:plugin\",\n\n async buildStart() {\n const isDev = meta.framework === \"vite\";\n await executeGeneration(isDev);\n\n const isServerMode = await resolveIsServerMode();\n if (isServerMode) {\n const config = await getConfig();\n const outputDir = resolveOutputDir(config, cwd);\n const hostServer = getHostServer(config, cwd, options);\n const serveShimPath = join(outputDir, \"serve.ts\");\n const ext = resolveImportExtension(config.extension);\n emitServeShim(serveShimPath, `./routes.gen${ext}`, hostServer, ext);\n }\n },\n\n async watchChange(id, _change) {\n cachedDevHandler = null;\n const config = await getConfig();\n const outputDir = resolveOutputDir(config, cwd);\n if (isOutputDir(id, outputDir)) {\n return;\n }\n\n const routesDir = resolveRoutesDir(config, cwd);\n const serverDir = resolveServerDir(config, cwd);\n const appFile = resolveAppFile(config, cwd);\n\n if (id === appFile || isSubPath(id, routesDir) || isSubPath(id, serverDir)) {\n await executeGeneration(true);\n }\n },\n\n vite: {\n async config(config, env) {\n if (!options.cwd && config.root) {\n cwd = resolve(config.root);\n cachedConfig = null;\n }\n config.server = config.server || {};\n config.server.watch = config.server.watch || {};\n config.server.watch.ignored = mergeWatchIgnored(\n config.server.watch.ignored,\n DEFAULT_OUTPUT_IGNORE_PATTERN,\n );\n\n const isFullStack = detectFullStack(config);\n detectedFullStack = isFullStack;\n\n const isServerMode = await resolveIsServerMode(config);\n\n if (isServerMode && env?.command === \"build\") {\n const taserConfig = await getConfig();\n const outputDir = resolveOutputDir(taserConfig, cwd);\n const hostServer = getHostServer(taserConfig, cwd, options);\n const serveShimPath = join(outputDir, \"serve.ts\");\n const ext = resolveImportExtension(taserConfig.extension);\n emitServeShim(serveShimPath, `./routes.gen${ext}`, hostServer, ext);\n\n return {\n build: {\n ssr: serveShimPath,\n rollupOptions: {\n external: [\"srvx\", \"srvx/node\", \"@taserjs/runtime\", \"hono\"],\n output: {\n entryFileNames: \"serve.mjs\",\n },\n },\n },\n };\n }\n },\n\n configResolved(resolvedConfig) {\n if (detectFullStack(resolvedConfig)) {\n detectedFullStack = true;\n } else if (detectedFullStack === null) {\n detectedFullStack = false;\n }\n },\n\n async configureServer(server) {\n const handleFileChange = async (file: string) => {\n cachedDevHandler = null;\n const config = await getConfig();\n const outputDir = resolveOutputDir(config, cwd);\n if (isOutputDir(file, outputDir)) {\n return;\n }\n\n const routesDir = resolveRoutesDir(config, cwd);\n const serverDir = resolveServerDir(config, cwd);\n const appFile = resolveAppFile(config, cwd);\n\n if (file === appFile || isSubPath(file, routesDir) || isSubPath(file, serverDir)) {\n triggerDebouncedGeneration();\n }\n };\n\n server.watcher.on(\"add\", handleFileChange);\n server.watcher.on(\"unlink\", handleFileChange);\n server.watcher.on(\"change\", handleFileChange);\n server.watcher.on(\"unlinkDir\", handleFileChange);\n\n const isServerMode = await resolveIsServerMode(server.config);\n if (!isServerMode) {\n return;\n }\n\n server.middlewares.use(async (req: any, res: any, next: any) => {\n const url = req.url;\n if (!url || shouldSkipDevRequest(url)) {\n return next();\n }\n\n const ssrEnv = (server as any).environments?.ssr;\n if ((server as any).environments && ssrEnv && !isRunnableEnvironment(ssrEnv)) {\n return next();\n }\n\n try {\n if (!cachedDevHandler) {\n const taserConfig = await getConfig();\n const outputDir = resolveOutputDir(taserConfig, cwd);\n const routesGenPath = join(outputDir, \"routes.gen.ts\");\n\n if (!existsSync(routesGenPath)) {\n await executeGeneration(true);\n }\n\n const mod = (await server.ssrLoadModule(routesGenPath)) as Record<string, any>;\n const app = mod.app ?? mod.default;\n\n if (!app || typeof app.fetch !== \"function\") {\n return next();\n }\n\n const hostServer = getHostServer(taserConfig, cwd, options);\n\n if (hostServer) {\n const hostMod = await server.ssrLoadModule(hostServer.path);\n mountHostFallback(app, hostMod, hostServer.type);\n }\n\n cachedDevHandler = toNodeHandler((fetchReq: Request) => app.fetch(fetchReq));\n }\n\n if (cachedDevHandler) {\n await cachedDevHandler(req, res);\n } else {\n next();\n }\n } catch (error) {\n server.ssrFixStacktrace(error as Error);\n next(error);\n }\n });\n },\n },\n\n webpack(compiler) {\n compiler.options.watchOptions = compiler.options.watchOptions || {};\n compiler.options.watchOptions.ignored = mergeWatchIgnored(\n compiler.options.watchOptions.ignored,\n DEFAULT_OUTPUT_IGNORE_PATTERN,\n );\n },\n\n rspack(compiler) {\n compiler.options.watchOptions = compiler.options.watchOptions || {};\n compiler.options.watchOptions.ignored = mergeWatchIgnored(\n compiler.options.watchOptions.ignored,\n DEFAULT_OUTPUT_IGNORE_PATTERN,\n );\n },\n };\n});\n\nexport const taser = Object.assign(\n (options?: TaserPluginOptions) => taserPlugin.raw(options, {} as any),\n taserPlugin,\n);\nexport default taserPlugin;\n"],"mappings":"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"}
|
package/dist/next.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { FSWatcher } from "chokidar";
|
|
2
|
+
//#region src/next.d.ts
|
|
3
|
+
export interface NextTaserOptions {
|
|
4
|
+
cwd?: string | undefined;
|
|
5
|
+
config?: string | undefined;
|
|
6
|
+
}
|
|
7
|
+
export declare function runNextTaserGeneration(cwd: string, options?: NextTaserOptions): Promise<void>;
|
|
8
|
+
export declare function startTurbopackWatcher(cwd: string, options?: NextTaserOptions): Promise<FSWatcher | null>;
|
|
9
|
+
export declare function closeTurbopackWatcher(): Promise<void> | void;
|
|
10
|
+
/**
|
|
11
|
+
* Higher-order Next.js configuration wrapper for Taser.js.
|
|
12
|
+
* Supports both Webpack and Turbopack dev/build flows.
|
|
13
|
+
*/
|
|
14
|
+
export declare function createTaser(pluginOptions?: NextTaserOptions): <TNextConfig extends Record<string, any>>(nextConfig?: TNextConfig) => TNextConfig;
|
|
15
|
+
export declare const withTaser: (nextConfig: any, options?: NextTaserOptions) => any;
|
|
16
|
+
//#endregion
|
|
17
|
+
export { createTaser as default };
|
|
18
|
+
//# sourceMappingURL=next.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"next.d.ts","names":[],"sources":["../src/next.ts"],"mappings":";;iBAMiB;EACf;EACA;;wBAKoB,uBACpB,aACA,UAAU,mBACT;wBAYmB,sBACpB,aACA,UAAU,mBACT,QAAQ;wBAkCK,yBAAyB;;;;;wBAYzB,YAAY,gBAAe,oBACf,oBAAoB,qBAC5C,aAAY,gBACX;qBAqCQ,YAAa,iBAAiB,UAAU"}
|
package/dist/next.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import taserPlugin from "./index.js";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { resolve } from "pathe";
|
|
4
|
+
import { generateManifest, loadConfig, resolveRoutesDir, scanRoutes } from "@taserjs/cli";
|
|
5
|
+
import { watch } from "chokidar";
|
|
6
|
+
//#region src/next.ts
|
|
7
|
+
let turbopackWatcher = null;
|
|
8
|
+
async function runNextTaserGeneration(cwd, options) {
|
|
9
|
+
const config = await loadConfig(cwd, options?.config);
|
|
10
|
+
const routesDir = resolveRoutesDir(config, cwd);
|
|
11
|
+
if (existsSync(routesDir)) {
|
|
12
|
+
const scanResult = scanRoutes({
|
|
13
|
+
routesDir,
|
|
14
|
+
cwd
|
|
15
|
+
});
|
|
16
|
+
generateManifest(scanResult, config, cwd);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
async function startTurbopackWatcher(cwd, options) {
|
|
20
|
+
if (turbopackWatcher) return turbopackWatcher;
|
|
21
|
+
const config = await loadConfig(cwd, options?.config);
|
|
22
|
+
const routesDir = resolveRoutesDir(config, cwd);
|
|
23
|
+
if (existsSync(routesDir)) {
|
|
24
|
+
turbopackWatcher = watch([routesDir], {
|
|
25
|
+
ignoreInitial: true,
|
|
26
|
+
usePolling: true,
|
|
27
|
+
interval: 100,
|
|
28
|
+
ignored: [
|
|
29
|
+
/(^|[/\\])\../,
|
|
30
|
+
/(^|[/\\])-/,
|
|
31
|
+
/node_modules/,
|
|
32
|
+
/\.taserjs/
|
|
33
|
+
]
|
|
34
|
+
});
|
|
35
|
+
let timer = null;
|
|
36
|
+
turbopackWatcher.on("all", () => {
|
|
37
|
+
if (timer) clearTimeout(timer);
|
|
38
|
+
timer = setTimeout(() => {
|
|
39
|
+
const scanResult = scanRoutes({
|
|
40
|
+
routesDir,
|
|
41
|
+
cwd,
|
|
42
|
+
scaffold: true,
|
|
43
|
+
formatting: config.formatting
|
|
44
|
+
});
|
|
45
|
+
generateManifest(scanResult, config, cwd);
|
|
46
|
+
}, 50);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
return turbopackWatcher;
|
|
50
|
+
}
|
|
51
|
+
function closeTurbopackWatcher() {
|
|
52
|
+
if (turbopackWatcher) {
|
|
53
|
+
const p = turbopackWatcher.close();
|
|
54
|
+
turbopackWatcher = null;
|
|
55
|
+
return p;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Higher-order Next.js configuration wrapper for Taser.js.
|
|
60
|
+
* Supports both Webpack and Turbopack dev/build flows.
|
|
61
|
+
*/
|
|
62
|
+
function createTaser(pluginOptions = {}) {
|
|
63
|
+
return function withTaser(nextConfig = {}) {
|
|
64
|
+
const cwd = pluginOptions.cwd ? resolve(pluginOptions.cwd) : process.cwd();
|
|
65
|
+
const nextPluginOptions = {
|
|
66
|
+
cwd,
|
|
67
|
+
...pluginOptions.config ? { config: pluginOptions.config } : {}
|
|
68
|
+
};
|
|
69
|
+
runNextTaserGeneration(cwd, nextPluginOptions).catch((err) => {
|
|
70
|
+
console.error(`[taserjs/next] Route generation error: ${err.message}`);
|
|
71
|
+
});
|
|
72
|
+
if (process.env.NODE_ENV !== "production") startTurbopackWatcher(cwd, nextPluginOptions).catch(() => {});
|
|
73
|
+
return {
|
|
74
|
+
...nextConfig,
|
|
75
|
+
turbopack: nextConfig.turbopack ?? {},
|
|
76
|
+
webpack(config, webpackOptions) {
|
|
77
|
+
const webpackPlugin = taserPlugin.webpack(nextPluginOptions);
|
|
78
|
+
config.plugins = config.plugins || [];
|
|
79
|
+
config.plugins.push(webpackPlugin);
|
|
80
|
+
if (typeof nextConfig.webpack === "function") return nextConfig.webpack(config, webpackOptions);
|
|
81
|
+
return config;
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
const withTaser = (nextConfig, options) => createTaser(options)(nextConfig);
|
|
87
|
+
//#endregion
|
|
88
|
+
export { closeTurbopackWatcher, createTaser, createTaser as default, runNextTaserGeneration, startTurbopackWatcher, withTaser };
|
|
89
|
+
|
|
90
|
+
//# sourceMappingURL=next.js.map
|
package/dist/next.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"next.js","names":[],"sources":["../src/next.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport { resolve } from \"pathe\";\nimport { generateManifest, loadConfig, resolveRoutesDir, scanRoutes } from \"@taserjs/cli\";\nimport { watch, type FSWatcher } from \"chokidar\";\nimport { taserPlugin } from \"./index.js\";\n\nexport interface NextTaserOptions {\n cwd?: string | undefined;\n config?: string | undefined;\n}\n\nlet turbopackWatcher: FSWatcher | null = null;\n\nexport async function runNextTaserGeneration(\n cwd: string,\n options?: NextTaserOptions,\n): Promise<void> {\n const config = await loadConfig(cwd, options?.config);\n const routesDir = resolveRoutesDir(config, cwd);\n if (existsSync(routesDir)) {\n const scanResult = scanRoutes({\n routesDir,\n cwd,\n });\n generateManifest(scanResult, config, cwd);\n }\n}\n\nexport async function startTurbopackWatcher(\n cwd: string,\n options?: NextTaserOptions,\n): Promise<FSWatcher | null> {\n if (turbopackWatcher) {\n return turbopackWatcher;\n }\n\n const config = await loadConfig(cwd, options?.config);\n const routesDir = resolveRoutesDir(config, cwd);\n\n if (existsSync(routesDir)) {\n turbopackWatcher = watch([routesDir], {\n ignoreInitial: true,\n usePolling: true,\n interval: 100,\n ignored: [/(^|[/\\\\])\\../, /(^|[/\\\\])-/, /node_modules/, /\\.taserjs/],\n });\n\n let timer: ReturnType<typeof setTimeout> | null = null;\n turbopackWatcher.on(\"all\", () => {\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => {\n const scanResult = scanRoutes({\n routesDir,\n cwd,\n scaffold: true,\n formatting: config.formatting,\n });\n generateManifest(scanResult, config, cwd);\n }, 50);\n });\n }\n\n return turbopackWatcher;\n}\n\nexport function closeTurbopackWatcher(): Promise<void> | void {\n if (turbopackWatcher) {\n const p = turbopackWatcher.close();\n turbopackWatcher = null;\n return p;\n }\n}\n\n/**\n * Higher-order Next.js configuration wrapper for Taser.js.\n * Supports both Webpack and Turbopack dev/build flows.\n */\nexport function createTaser(pluginOptions: NextTaserOptions = {}) {\n return function withTaser<TNextConfig extends Record<string, any>>(\n nextConfig: TNextConfig = {} as TNextConfig,\n ): TNextConfig {\n const cwd = pluginOptions.cwd ? resolve(pluginOptions.cwd) : process.cwd();\n const nextPluginOptions = {\n cwd,\n ...(pluginOptions.config ? { config: pluginOptions.config } : {}),\n };\n\n // 1. Trigger initial generation\n runNextTaserGeneration(cwd, nextPluginOptions).catch((err) => {\n console.error(`[taserjs/next] Route generation error: ${err.message}`);\n });\n\n // 2. Start watcher for Turbopack dev mode if active or NODE_ENV != production\n if (process.env.NODE_ENV !== \"production\") {\n startTurbopackWatcher(cwd, nextPluginOptions).catch(() => {});\n }\n\n const enhancedConfig: any = {\n ...nextConfig,\n turbopack: nextConfig.turbopack ?? {},\n webpack(config: any, webpackOptions: any) {\n // Run generation during Webpack compile\n const webpackPlugin = taserPlugin.webpack(nextPluginOptions);\n config.plugins = config.plugins || [];\n config.plugins.push(webpackPlugin);\n\n if (typeof nextConfig.webpack === \"function\") {\n return nextConfig.webpack(config, webpackOptions);\n }\n return config;\n },\n };\n\n return enhancedConfig;\n };\n}\n\nexport const withTaser = (nextConfig: any, options?: NextTaserOptions) =>\n createTaser(options)(nextConfig);\n\nexport default createTaser;\n"],"mappings":";;;;;;AAWA,IAAI,mBAAqC;AAEzC,eAAsB,uBACpB,KACA,SACe;CACf,MAAM,SAAS,MAAM,WAAW,KAAK,SAAS,MAAM;CACpD,MAAM,YAAY,iBAAiB,QAAQ,GAAG;CAC9C,IAAI,WAAW,SAAS,GAAG;EACzB,MAAM,aAAa,WAAW;GAC5B;GACA;EACF,CAAC;EACD,iBAAiB,YAAY,QAAQ,GAAG;CAC1C;AACF;AAEA,eAAsB,sBACpB,KACA,SAC2B;CAC3B,IAAI,kBACF,OAAO;CAGT,MAAM,SAAS,MAAM,WAAW,KAAK,SAAS,MAAM;CACpD,MAAM,YAAY,iBAAiB,QAAQ,GAAG;CAE9C,IAAI,WAAW,SAAS,GAAG;EACzB,mBAAmB,MAAM,CAAC,SAAS,GAAG;GACpC,eAAe;GACf,YAAY;GACZ,UAAU;GACV,SAAS;IAAC;IAAgB;IAAc;IAAgB;GAAW;EACrE,CAAC;EAED,IAAI,QAA8C;EAClD,iBAAiB,GAAG,aAAa;GAC/B,IAAI,OAAO,aAAa,KAAK;GAC7B,QAAQ,iBAAiB;IACvB,MAAM,aAAa,WAAW;KAC5B;KACA;KACA,UAAU;KACV,YAAY,OAAO;IACrB,CAAC;IACD,iBAAiB,YAAY,QAAQ,GAAG;GAC1C,GAAG,EAAE;EACP,CAAC;CACH;CAEA,OAAO;AACT;AAEA,SAAgB,wBAA8C;CAC5D,IAAI,kBAAkB;EACpB,MAAM,IAAI,iBAAiB,MAAM;EACjC,mBAAmB;EACnB,OAAO;CACT;AACF;;;;;AAMA,SAAgB,YAAY,gBAAkC,CAAC,GAAG;CAChE,OAAO,SAAS,UACd,aAA0B,CAAC,GACd;EACb,MAAM,MAAM,cAAc,MAAM,QAAQ,cAAc,GAAG,IAAI,QAAQ,IAAI;EACzE,MAAM,oBAAoB;GACxB;GACA,GAAI,cAAc,SAAS,EAAE,QAAQ,cAAc,OAAO,IAAI,CAAC;EACjE;EAGA,uBAAuB,KAAK,iBAAiB,CAAC,CAAC,OAAO,QAAQ;GAC5D,QAAQ,MAAM,0CAA0C,IAAI,SAAS;EACvE,CAAC;EAGD,IAAI,QAAQ,IAAI,aAAa,cAC3B,sBAAsB,KAAK,iBAAiB,CAAC,CAAC,YAAY,CAAC,CAAC;EAmB9D,OAAO;GAfL,GAAG;GACH,WAAW,WAAW,aAAa,CAAC;GACpC,QAAQ,QAAa,gBAAqB;IAExC,MAAM,gBAAgB,YAAY,QAAQ,iBAAiB;IAC3D,OAAO,UAAU,OAAO,WAAW,CAAC;IACpC,OAAO,QAAQ,KAAK,aAAa;IAEjC,IAAI,OAAO,WAAW,YAAY,YAChC,OAAO,WAAW,QAAQ,QAAQ,cAAc;IAElD,OAAO;GACT;EAGkB;CACtB;AACF;AAEA,MAAa,aAAa,YAAiB,YACzC,YAAY,OAAO,CAAC,CAAC,UAAU"}
|
package/dist/nitro.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { HostServerInfo, TaserPluginOptions } from "./index.js";
|
|
2
|
+
//#region src/nitro.d.ts
|
|
3
|
+
export declare function buildNitroRoutingVirtualSource(): string;
|
|
4
|
+
export declare function buildNitroStandaloneAppSource(routesGenPath: string, hostServer?: HostServerInfo | null): string;
|
|
5
|
+
export declare function buildNitroMiddlewareHandlerSource(routesGenPath: string, hostServer?: HostServerInfo | null): string;
|
|
6
|
+
export declare function setupTaserNitro(nitro: any, options?: TaserPluginOptions): void;
|
|
7
|
+
export declare function applyTaserNitro(nitro: any, options: TaserPluginOptions): Promise<void>;
|
|
8
|
+
/**
|
|
9
|
+
* Taser Nitro module.
|
|
10
|
+
*
|
|
11
|
+
* Can be used as a Nitro module (`modules: [taser()]`) in `nitro.config.ts`,
|
|
12
|
+
* or chained as a rollup plugin.
|
|
13
|
+
*/
|
|
14
|
+
export declare function taser(options?: TaserPluginOptions): any;
|
|
15
|
+
//#endregion
|
|
16
|
+
export { taser as default };
|
|
17
|
+
//# sourceMappingURL=nitro.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nitro.d.ts","names":[],"sources":["../src/nitro.ts"],"mappings":";;wBAqBgB;wBASA,8BACd,uBACA,aAAa;wBAmCC,kCACd,uBACA,aAAa;wBAoBC,gBAAgB,YAAY,UAAS;wBAY/B,gBAAgB,YAAY,SAAS,qBAAqB;;;;;;;wBA6EhE,MAAM,UAAS"}
|