vitend 0.2.3 → 0.4.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/README.md CHANGED
@@ -13,6 +13,8 @@ Vitend brings a frontend-grade developer experience to backend development. It a
13
13
  Add the Vitend plugin into the Vite config:
14
14
 
15
15
  ```ts
16
+ // ./vite.config.ts
17
+
16
18
  import { defineConfig } from "vite";
17
19
  import { vitend } from "vitend/vite";
18
20
 
@@ -23,9 +25,69 @@ export default defineConfig({
23
25
  });
24
26
  ```
25
27
 
26
- Export the application:
28
+ For deploying to Vercel, add the `vercel` target:
27
29
 
28
30
  ```ts
31
+ // ./vite.config.ts
32
+
33
+ import { defineConfig } from "vite";
34
+ import { vitend } from "vitend/vite";
35
+
36
+ export default defineConfig({
37
+ plugins: [
38
+ vitend({
39
+ build: {
40
+ target: "vercel",
41
+ }
42
+ }),
43
+ ],
44
+ });
45
+ ```
46
+
47
+ For framework built on top of Web APIs, it is possible to directly export the application:
48
+
49
+ ```ts
50
+ // ./src/index.ts
51
+
52
+ import { Hono } from "hono";
53
+
54
+ const app: Hono = new Hono();
55
+
56
+ app.get("/", (c: Context): Response => {
57
+ return c.json({
58
+ success: true,
59
+ });
60
+ });
61
+
62
+ export default app;
63
+ ```
64
+
65
+ Or use the `defineServer` function to wrap the application for type-safety on more advanced options:
66
+
67
+ ```ts
68
+ // ./src/index.ts
69
+
70
+ import { Hono } from "hono";
71
+ import { defineServer } from "vitend";
72
+
73
+ const app: Hono = new Hono();
74
+
75
+ app.get("/", (c: Context): Response => {
76
+ return c.json({
77
+ success: true,
78
+ });
79
+ });
80
+
81
+ export default defineServer({
82
+ fetch: app.fetch,
83
+ });
84
+ ```
85
+
86
+ In the same time, it is also possible for directly usage without a framework:
87
+
88
+ ```ts
89
+ // ./src/index.ts
90
+
29
91
  export default {
30
92
  fetch: (req: Request): Response => {
31
93
  switch (new URL(req.url).pathname) {
@@ -40,7 +102,7 @@ export default {
40
102
  };
41
103
  ```
42
104
 
43
- Then run `vite` to start the server.
105
+ After the configuration, run `vite` to start the server.
44
106
 
45
107
  ## License
46
108
 
package/dist/vite.d.ts CHANGED
@@ -39,6 +39,22 @@ type CompleteDevOptions = {
39
39
  https: CompleteHttpsOptions;
40
40
  };
41
41
  /**
42
+ * Runtime target for the application.
43
+ *
44
+ * - Node.js - `node`
45
+ * - Deno - `deno`
46
+ * - Bun - `bun`
47
+ * - Cloudflare Workers - `workerd`
48
+ */
49
+ type Runtime = "node" | "deno" | "bun" | "workerd";
50
+ /**
51
+ * Bundle mode.
52
+ *
53
+ * - `external` - keeps all dependencies external.
54
+ * - `standalone` - bundles all dependencies into the output file.
55
+ */
56
+ type BundleMode = "external" | "standalone";
57
+ /**
42
58
  * Complete default build server options.
43
59
  */
44
60
  type CompleteDefaultBuildOptions = {
@@ -65,6 +81,12 @@ type CompleteDefaultBuildOptions = {
65
81
  */
66
82
  https: CompleteHttpsOptions;
67
83
  /**
84
+ * Whether to bundle all dependencies into the output file.
85
+ *
86
+ * By default, it is `external`.
87
+ */
88
+ bundle: BundleMode;
89
+ /**
68
90
  * The output directory for the application.
69
91
  *
70
92
  * By default, it is `./dist`.
@@ -109,6 +131,12 @@ type CompleteVercelBuildOptions = {
109
131
  */
110
132
  target: "vercel";
111
133
  /**
134
+ * Whether to bundle all dependencies into the output file.
135
+ *
136
+ * By default, it is `external`.
137
+ */
138
+ bundle: BundleMode;
139
+ /**
112
140
  * The output directory for the application.
113
141
  *
114
142
  * By default, it is `./dist`.
@@ -142,6 +170,12 @@ type CompleteVitendOptions = {
142
170
  */
143
171
  cwd: string;
144
172
  /**
173
+ * Runtime target for the application.
174
+ *
175
+ * By default, it is `node`.
176
+ */
177
+ runtime: Runtime;
178
+ /**
145
179
  * The entry file for the application.
146
180
  *
147
181
  * By default, it is `./src/index.ts` or `./src/index.js`.
@@ -155,6 +189,12 @@ type CompleteVitendOptions = {
155
189
  * The options for the production server.
156
190
  */
157
191
  build: CompleteBuildOptions;
192
+ /**
193
+ * Whether to output log messages to the console.
194
+ *
195
+ * By default, it is `false`.
196
+ */
197
+ verbose: boolean;
158
198
  };
159
199
  /**
160
200
  * HTTPS server options.
@@ -210,5 +250,5 @@ type VitendOptions = Format<Partial<Omit<CompleteVitendOptions, "dev" | "build">
210
250
  * ```
211
251
  */
212
252
  declare const vitend: (options?: VitendOptions) => Plugin[];
213
- export { type BuildOptions, type DevOptions, type HttpsOptions, type VitendOptions, vitend };
253
+ export { type BuildOptions, type BundleMode, type DevOptions, type HttpsOptions, type Runtime, type VitendOptions, vitend };
214
254
  //# sourceMappingURL=vite.d.ts.map
package/dist/vite.js CHANGED
@@ -26,14 +26,16 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
26
26
 
27
27
  let node_path = require("node:path");
28
28
  node_path = __toESM(node_path);
29
- let rollup_plugin_copy = require("rollup-plugin-copy");
30
- rollup_plugin_copy = __toESM(rollup_plugin_copy);
29
+ let rolldown_plugin_copy = require("rolldown-plugin-copy");
30
+ let consola = require("consola");
31
31
  let es_toolkit = require("es-toolkit");
32
32
  let node_fs = require("node:fs");
33
33
  node_fs = __toESM(node_fs);
34
34
  let node_module = require("node:module");
35
35
  let srvx = require("srvx");
36
36
 
37
+ const log = (0, consola.createConsola)({ formatOptions: { date: false } });
38
+
37
39
  const ENTRY_DEFAULT = ["./src/index.ts", "./src/index.js"];
38
40
  const getEntry = (cwd, entry) => {
39
41
  if (!entry) {
@@ -46,28 +48,32 @@ const getEntry = (cwd, entry) => {
46
48
  return node_path.resolve(cwd, entry);
47
49
  };
48
50
 
49
- const OPTIONS_BUILD_VERCEL = {
50
- target: "vercel",
51
- outputDir: "./dist",
52
- outputFile: "index.js",
53
- minify: false
54
- };
55
51
  const OPTIONS_BUILD_DEFAULT = {
56
52
  target: "default",
57
53
  host: "localhost",
58
54
  port: 3e3,
55
+ bundle: "external",
59
56
  outputDir: "./dist",
60
57
  outputFile: "index.js",
61
58
  minify: false,
62
59
  publicDir: "./public",
63
60
  copyPublicDir: false
64
61
  };
62
+ const OPTIONS_BUILD_VERCEL = {
63
+ target: "vercel",
64
+ bundle: "external",
65
+ outputDir: "./dist",
66
+ outputFile: "index.js",
67
+ minify: false
68
+ };
65
69
  const OPTIONS_DEFAULT = {
66
70
  cwd: process.cwd(),
71
+ runtime: "node",
67
72
  dev: {
68
73
  host: "localhost",
69
74
  port: 3001
70
- }
75
+ },
76
+ verbose: false
71
77
  };
72
78
  const getDefaultOptions = (isVercel) => {
73
79
  return {
@@ -90,6 +96,13 @@ const getPackageJson = (cwd) => {
90
96
  return JSON.parse(rawPackageJson);
91
97
  };
92
98
 
99
+ const getSsrTarget = (runtime) => {
100
+ switch (runtime) {
101
+ case "workerd": return "webworker";
102
+ default: return "node";
103
+ }
104
+ };
105
+
93
106
  const VIRTUAL_ENTRY = "virtual:vitend-entry";
94
107
  const VIRTUAL_ENTRY_RESOLVED = `\0${VIRTUAL_ENTRY}`;
95
108
  const buildPlugin = (opts) => {
@@ -100,14 +113,20 @@ const buildPlugin = (opts) => {
100
113
  apply: "build",
101
114
  config: (config) => {
102
115
  let result = {};
103
- result = (0, es_toolkit.toMerged)({
116
+ let baseConfig = {
117
+ resolve: { conditions: [opts.runtime] },
104
118
  ssr: {
105
- external: true,
106
- noExternal: void 0,
107
- target: "webworker"
119
+ target: getSsrTarget(opts.runtime),
120
+ resolve: { conditions: [opts.runtime] }
108
121
  },
109
122
  build: { copyPublicDir: false }
110
- }, config);
123
+ };
124
+ if (build.bundle === "external") baseConfig = (0, es_toolkit.toMerged)(baseConfig, { ssr: {
125
+ external: true,
126
+ noExternal: void 0
127
+ } });
128
+ if (build.bundle === "standalone") baseConfig = (0, es_toolkit.toMerged)(baseConfig, { ssr: { noExternal: true } });
129
+ result = (0, es_toolkit.toMerged)(baseConfig, config);
111
130
  const overrideConfig = { build: {
112
131
  ssr: true,
113
132
  outDir: build.outputDir,
@@ -220,6 +239,11 @@ const devPlugin = (opts) => {
220
239
  apply: "serve",
221
240
  config(config) {
222
241
  return (0, es_toolkit.toMerged)(config, {
242
+ resolve: { conditions: [opts.runtime] },
243
+ ssr: {
244
+ target: getSsrTarget(opts.runtime),
245
+ resolve: { conditions: [opts.runtime] }
246
+ },
223
247
  build: {
224
248
  ssr: true,
225
249
  rollupOptions: { input: opts.entry }
@@ -278,17 +302,32 @@ const devPlugin = (opts) => {
278
302
  const vitend = (options) => {
279
303
  const opts = createOptions(options);
280
304
  const build = opts.build;
281
- return [
282
- devPlugin({ ...opts }),
283
- buildPlugin({ ...opts }),
284
- ...build.target === "default" && build.copyPublicDir ? [(0, rollup_plugin_copy.default)({
285
- hook: "closeBundle",
286
- targets: [{
287
- src: node_path.resolve(build.publicDir, "**", "*"),
288
- dest: node_path.resolve(build.outputDir, build.publicDir)
289
- }]
290
- })] : []
291
- ];
305
+ const plugins = [devPlugin({ ...opts }), buildPlugin({ ...opts })];
306
+ if (build.target === "default" && build.copyPublicDir) {
307
+ const copyOptions = { targets: [{
308
+ src: node_path.resolve(build.publicDir, "**", "*"),
309
+ dest: node_path.resolve(build.outputDir, build.publicDir)
310
+ }] };
311
+ if (opts.verbose) {
312
+ copyOptions.onStart = () => {
313
+ console.log("");
314
+ console.log("");
315
+ };
316
+ copyOptions.onCopy = (event) => {
317
+ let message = `${node_path.relative(opts.cwd, event.target.src)} → ${node_path.relative(opts.cwd, event.target.dest)}`;
318
+ const flags = [];
319
+ if (event.target.renamed) flags.push("R");
320
+ if (event.target.transformed) flags.push("T");
321
+ if (flags.length > 0) message += ` [${flags.join(",")}]`;
322
+ log.success(message);
323
+ };
324
+ copyOptions.onEnd = () => {
325
+ console.log("");
326
+ };
327
+ }
328
+ plugins.push((0, rolldown_plugin_copy.copy)(copyOptions));
329
+ }
330
+ return plugins;
292
331
  };
293
332
 
294
333
  exports.__toESM = __toESM;
package/dist/vite.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"vite.js","names":["Fs","Path","Path","Fs","builtinModules","Path"],"sources":["../src/functions/entry.ts","../src/functions/options.ts","../src/functions/package-json.ts","../src/vite/build.ts","../src/vite/dev.ts","../src/vite/vitend.ts"],"sourcesContent":["import * as Fs from \"node:fs\";\nimport * as Path from \"node:path\";\n\nconst ENTRY_DEFAULT: string[] = [\n \"./src/index.ts\",\n \"./src/index.js\",\n];\n\nconst getEntry = (cwd: string, entry?: string): string => {\n if (!entry) {\n for (const ent of ENTRY_DEFAULT) {\n if (Fs.existsSync(Path.resolve(cwd, ent))) {\n entry = ent;\n break;\n }\n }\n\n if (!entry) {\n throw new Error(\"No entry file found\");\n }\n }\n\n return Path.resolve(cwd, entry);\n};\n\nexport { getEntry };\n","import type { Omit } from \"ts-vista\";\n\nimport type { VitendOptions } from \"#/@types/options/default\";\nimport type {\n ResolvedDefaultBuildOptions,\n ResolvedVercelBuildOptions,\n ResolvedVitendOptions,\n} from \"#/@types/options/resolved\";\n\nimport { toMerged } from \"es-toolkit\";\n\nimport { getEntry } from \"#/functions/entry\";\n\nconst OPTIONS_BUILD_VERCEL: ResolvedVercelBuildOptions = {\n target: \"vercel\",\n outputDir: \"./dist\",\n outputFile: \"index.js\",\n minify: false,\n};\n\nconst OPTIONS_BUILD_DEFAULT: ResolvedDefaultBuildOptions = {\n target: \"default\",\n host: \"localhost\",\n port: 3000,\n outputDir: \"./dist\",\n outputFile: \"index.js\",\n minify: false,\n publicDir: \"./public\",\n copyPublicDir: false,\n};\n\nconst OPTIONS_DEFAULT: Omit<ResolvedVitendOptions, \"entry\" | \"build\"> = {\n cwd: process.cwd(),\n dev: {\n host: \"localhost\",\n port: 3001,\n },\n};\n\nconst getDefaultOptions = (\n isVercel: boolean,\n): Omit<ResolvedVitendOptions, \"entry\"> => {\n return {\n ...OPTIONS_DEFAULT,\n build: isVercel ? OPTIONS_BUILD_VERCEL : OPTIONS_BUILD_DEFAULT,\n };\n};\n\nconst createOptions = (options?: VitendOptions): ResolvedVitendOptions => {\n const isVercel: boolean = options?.build?.target === \"vercel\";\n\n const merged = toMerged(getDefaultOptions(isVercel), options ?? {});\n\n return {\n ...merged,\n entry: getEntry(merged.cwd, options?.entry),\n };\n};\n\nexport { createOptions };\n","import type { Format, Partial } from \"ts-vista\";\n\nimport * as Fs from \"node:fs\";\nimport * as Path from \"node:path\";\n\ntype CompletePackageJson = {\n type: \"module\" | \"commonjs\";\n dependencies: Record<string, string>;\n devDependencies: Record<string, string>;\n peerDependencies: Record<string, string>;\n};\n\ntype PackageJson = Format<Partial<CompletePackageJson>>;\n\nconst getPackageJson = (cwd: string): PackageJson => {\n const path: string = Path.resolve(cwd, \"package.json\");\n\n if (!Fs.existsSync(path)) {\n throw new Error(\"Failed to find package.json\");\n }\n\n const rawPackageJson: string = Fs.readFileSync(path, \"utf-8\");\n\n return JSON.parse(rawPackageJson);\n};\n\nexport type { CompletePackageJson, PackageJson };\nexport { getPackageJson };\n","import type { LoadResult, ResolveIdResult } from \"rollup\";\nimport type { Plugin, UserConfig } from \"vite\";\n\nimport type {\n ResolvedBuildOptions,\n ResolvedVitendOptions,\n} from \"#/@types/options/resolved\";\nimport type { PackageJson } from \"#/functions/package-json\";\n\nimport { builtinModules } from \"node:module\";\n\nimport { toMerged } from \"es-toolkit\";\n\nimport { getPackageJson } from \"#/functions/package-json\";\n\nconst VIRTUAL_ENTRY = \"virtual:vitend-entry\" as const;\n\nconst VIRTUAL_ENTRY_RESOLVED = `\\0${VIRTUAL_ENTRY}` as const;\n\nconst buildPlugin = (opts: ResolvedVitendOptions): Plugin => {\n const build: ResolvedBuildOptions = opts.build;\n\n const packageJson: PackageJson = getPackageJson(opts.cwd);\n\n return {\n name: \"vitend/build\",\n apply: \"build\",\n config: (config: UserConfig): UserConfig => {\n let result: UserConfig = {};\n\n const baseConfig: UserConfig = {\n ssr: {\n external: true,\n noExternal: void 0,\n target: \"webworker\",\n },\n build: {\n copyPublicDir: false,\n },\n };\n\n result = toMerged(baseConfig, config);\n\n const overrideConfig: UserConfig = {\n build: {\n ssr: true,\n outDir: build.outputDir,\n rollupOptions: {\n input: VIRTUAL_ENTRY,\n output: {\n entryFileNames: build.outputFile,\n format:\n packageJson.type === \"module\" ? \"esm\" : \"cjs\",\n },\n external: [\n ...builtinModules,\n /^node:/,\n ],\n },\n minify: build.minify,\n },\n };\n\n result = toMerged(result, overrideConfig);\n\n return result;\n },\n resolveId: (id: string): ResolveIdResult => {\n if (id !== VIRTUAL_ENTRY) return void 0;\n return VIRTUAL_ENTRY_RESOLVED;\n },\n load: async (id: string): Promise<LoadResult> => {\n if (id !== VIRTUAL_ENTRY_RESOLVED) return void 0;\n\n let code: string = \"\";\n\n code += `import options from \"${opts.entry}\";`;\n code += `import { serve } from \"vitend/runtime\";`;\n\n // vercel export\n\n if (build.target === \"vercel\") {\n code += `const server = serve({ ...options, manual: true });`;\n code += `export default server;`;\n\n return code;\n }\n\n // default export\n\n code += `serve({`;\n code += `...options,`;\n\n if (build.host !== \"localhost\")\n code += `hostname: \"${build.host}\",`;\n if (build.port !== 3000) code += `port: ${build.port},`;\n\n if (build.https) {\n code += `tls: {`;\n if (build.https.cert) code += `cert: \"${build.https.cert}\",`;\n if (build.https.key) code += `key: \"${build.https.key}\",`;\n if (build.https.passphrase)\n code += `passphrase: \"${build.https.passphrase}\",`;\n code += `},`;\n }\n\n code += `});`;\n\n return code;\n },\n };\n};\n\nexport { buildPlugin };\n","import type HTTP from \"node:http\";\n\nimport type { Server, ServerHandler, ServerOptions } from \"srvx\";\nimport type { Connect, Plugin, UserConfig, ViteDevServer } from \"vite\";\n\nimport type {\n ResolvedDevOptions,\n ResolvedHttpsOptions,\n ResolvedVitendOptions,\n} from \"#/@types/options/resolved\";\n\nimport { toMerged } from \"es-toolkit\";\nimport { serve } from \"srvx\";\n\ntype CreateMiddlewareOptions = {\n vite: ViteDevServer;\n server: Server;\n};\n\nconst createRequestHeaders = (headers: HTTP.IncomingHttpHeaders): Headers => {\n const result: Headers = new Headers();\n\n const entries: [\n string,\n string | string[] | undefined,\n ][] = Object.entries(headers);\n\n for (let i: number = 0; i < entries.length; i++) {\n const entry:\n | [\n string,\n string | string[] | undefined,\n ]\n | undefined = entries[i];\n\n if (entry === void 0) continue;\n\n const [key, value] = entry;\n\n // ignore HTTP/2 pseudo-headers\n if (key.startsWith(\":\")) continue;\n\n if (value === void 0) continue;\n\n if (Array.isArray(value)) {\n for (let j: number = 0; j < value.length; j++) {\n const vl: string | undefined = value[j];\n\n if (vl === void 0) continue;\n\n result.append(key, vl);\n }\n } else {\n result.set(key, value);\n }\n }\n\n return result;\n};\n\nconst createMiddleware = ({ vite, server }: CreateMiddlewareOptions) => {\n return async (\n req: Connect.IncomingMessage,\n res: HTTP.ServerResponse,\n _next: Connect.NextFunction,\n ): Promise<void> => {\n const isHttps: boolean =\n vite.config.server.https?.cert !== void 0 &&\n vite.config.server.https?.key !== void 0;\n\n const protocol: string = `http${isHttps ? \"s\" : \"\"}`;\n\n const host: string = process.env.HOST ?? \"localhost\";\n\n const port: number = vite.config.server.port;\n\n const path: string = req.url ?? \"\";\n\n const url: URL = new URL(`${protocol}://${host}:${port}${path}`);\n\n const body: Connect.IncomingMessage | undefined =\n req.method !== \"GET\" && req.method !== \"HEAD\" ? req : void 0;\n\n const request: Request = new Request(url, {\n method: req.method,\n headers: createRequestHeaders(req.headers),\n body,\n duplex: \"half\",\n } as RequestInit);\n\n const response: Response = await server.fetch(request);\n\n res.statusCode = response.status;\n\n response.headers.forEach((value: string, key: string): void => {\n res.setHeader(key, value);\n });\n\n if (!response.body) {\n res.end();\n return void 0;\n }\n\n const reader: ReadableStreamDefaultReader<Uint8Array<ArrayBuffer>> =\n response.body.getReader();\n\n const stream = async (): Promise<void> => {\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) break;\n\n res.write(value);\n }\n\n res.end();\n } catch {\n res.end();\n }\n };\n\n await stream();\n };\n};\n\ntype Middleware = ReturnType<typeof createMiddleware>;\n\nconst devPlugin = (opts: ResolvedVitendOptions): Plugin => {\n const dev: ResolvedDevOptions = opts.dev;\n const https: ResolvedHttpsOptions = opts.dev.https ?? {};\n\n return {\n name: \"vitend/dev\",\n apply: \"serve\",\n config(config: UserConfig): UserConfig {\n const devConfig: UserConfig = {\n build: {\n ssr: true,\n rollupOptions: {\n input: opts.entry,\n },\n },\n server: {\n host: dev.host,\n port: dev.port,\n ...(https.cert !== void 0 && https.key !== void 0\n ? {\n https: {\n cert: https.cert,\n key: https.key,\n passphrase: https.passphrase,\n },\n }\n : {}),\n },\n };\n\n return toMerged(config, devConfig);\n },\n configureServer: async (vite: ViteDevServer): Promise<void> => {\n const serverOptions: ServerOptions = (\n await vite.ssrLoadModule(opts.entry)\n ).default;\n\n const server: Server<ServerHandler> = serve({\n // base\n gracefulShutdown: false,\n // user\n ...serverOptions,\n // override\n manual: true,\n hostname: dev.host,\n port: dev.port,\n tls: {\n cert: https.cert,\n key: https.key,\n passphrase: https.passphrase,\n },\n });\n\n const middleware: Middleware = createMiddleware({\n vite,\n server,\n });\n\n vite.middlewares.use(middleware);\n },\n };\n};\n\nexport { devPlugin };\n","import type { Plugin } from \"vite\";\n\nimport type { VitendOptions } from \"#/@types/options/default\";\nimport type {\n ResolvedBuildOptions,\n ResolvedVitendOptions,\n} from \"#/@types/options/resolved\";\n\nimport * as Path from \"node:path\";\n\nimport copy from \"rollup-plugin-copy\";\n\nimport { createOptions } from \"#/functions/options\";\nimport { buildPlugin } from \"#/vite/build\";\nimport { devPlugin } from \"#/vite/dev\";\n\n/**\n * The `vitend` plugin.\n *\n * ### Example\n *\n * ```ts\n * // ./vite.config.ts\n *\n * import { defineConfig } from \"vite\";\n * import { vitend } from \"vitend/vite\";\n *\n * export default defineConfig({\n * plugins: [\n * vitend(),\n * ],\n * });\n * ```\n */\nconst vitend = (options?: VitendOptions): Plugin[] => {\n const opts: ResolvedVitendOptions = createOptions(options);\n\n const build: ResolvedBuildOptions = opts.build;\n\n return [\n devPlugin({\n ...opts,\n }),\n buildPlugin({\n ...opts,\n }),\n ...(build.target === \"default\" && build.copyPublicDir\n ? ([\n copy({\n hook: \"closeBundle\",\n targets: [\n {\n src: Path.resolve(build.publicDir, \"**\", \"*\"),\n dest: Path.resolve(\n build.outputDir,\n build.publicDir,\n ),\n },\n ],\n }),\n ] as Plugin[])\n : []),\n ];\n};\n\nexport { vitend };\n"],"mappings":"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"}
1
+ {"version":3,"file":"vite.js","names":["Fs","Path","Path","Fs","builtinModules","Path"],"sources":["../src/configs/log.ts","../src/functions/entry.ts","../src/functions/options.ts","../src/functions/package-json.ts","../src/functions/ssr.ts","../src/vite/build.ts","../src/vite/dev.ts","../src/vite/vitend.ts"],"sourcesContent":["import type { ConsolaInstance } from \"consola\";\n\nimport { createConsola } from \"consola\";\n\nconst log: ConsolaInstance = createConsola({\n formatOptions: {\n date: false,\n },\n});\n\nexport { log };\n","import * as Fs from \"node:fs\";\nimport * as Path from \"node:path\";\n\nconst ENTRY_DEFAULT: string[] = [\n \"./src/index.ts\",\n \"./src/index.js\",\n];\n\nconst getEntry = (cwd: string, entry?: string): string => {\n if (!entry) {\n for (const ent of ENTRY_DEFAULT) {\n if (Fs.existsSync(Path.resolve(cwd, ent))) {\n entry = ent;\n break;\n }\n }\n\n if (!entry) {\n throw new Error(\"No entry file found\");\n }\n }\n\n return Path.resolve(cwd, entry);\n};\n\nexport { getEntry };\n","import type { Omit } from \"ts-vista\";\n\nimport type { VitendOptions } from \"#/@types/options/default\";\nimport type {\n ResolvedDefaultBuildOptions,\n ResolvedVercelBuildOptions,\n ResolvedVitendOptions,\n} from \"#/@types/options/resolved\";\n\nimport { toMerged } from \"es-toolkit\";\n\nimport { getEntry } from \"#/functions/entry\";\n\nconst OPTIONS_BUILD_DEFAULT: ResolvedDefaultBuildOptions = {\n target: \"default\",\n host: \"localhost\",\n port: 3000,\n bundle: \"external\",\n outputDir: \"./dist\",\n outputFile: \"index.js\",\n minify: false,\n publicDir: \"./public\",\n copyPublicDir: false,\n};\n\nconst OPTIONS_BUILD_VERCEL: ResolvedVercelBuildOptions = {\n target: \"vercel\",\n bundle: \"external\",\n outputDir: \"./dist\",\n outputFile: \"index.js\",\n minify: false,\n};\n\nconst OPTIONS_DEFAULT: Omit<ResolvedVitendOptions, \"entry\" | \"build\"> = {\n cwd: process.cwd(),\n runtime: \"node\",\n dev: {\n host: \"localhost\",\n port: 3001,\n },\n verbose: false,\n};\n\nconst getDefaultOptions = (\n isVercel: boolean,\n): Omit<ResolvedVitendOptions, \"entry\"> => {\n return {\n ...OPTIONS_DEFAULT,\n build: isVercel ? OPTIONS_BUILD_VERCEL : OPTIONS_BUILD_DEFAULT,\n };\n};\n\nconst createOptions = (options?: VitendOptions): ResolvedVitendOptions => {\n const isVercel: boolean = options?.build?.target === \"vercel\";\n\n const merged = toMerged(getDefaultOptions(isVercel), options ?? {});\n\n return {\n ...merged,\n entry: getEntry(merged.cwd, options?.entry),\n };\n};\n\nexport { createOptions };\n","import type { Format, Partial } from \"ts-vista\";\n\nimport * as Fs from \"node:fs\";\nimport * as Path from \"node:path\";\n\ntype CompletePackageJson = {\n type: \"module\" | \"commonjs\";\n dependencies: Record<string, string>;\n devDependencies: Record<string, string>;\n peerDependencies: Record<string, string>;\n};\n\ntype PackageJson = Format<Partial<CompletePackageJson>>;\n\nconst getPackageJson = (cwd: string): PackageJson => {\n const path: string = Path.resolve(cwd, \"package.json\");\n\n if (!Fs.existsSync(path)) {\n throw new Error(\"Failed to find package.json\");\n }\n\n const rawPackageJson: string = Fs.readFileSync(path, \"utf-8\");\n\n return JSON.parse(rawPackageJson);\n};\n\nexport type { CompletePackageJson, PackageJson };\nexport { getPackageJson };\n","import type { SSRTarget } from \"vite\";\n\nimport type { Runtime } from \"#/@types/options/complete\";\n\nconst getSsrTarget = (runtime: Runtime): SSRTarget => {\n switch (runtime) {\n case \"workerd\":\n return \"webworker\";\n default:\n return \"node\";\n }\n};\n\nexport { getSsrTarget };\n","import type { LoadResult, ResolveIdResult } from \"rollup\";\nimport type { Plugin, UserConfig } from \"vite\";\n\nimport type {\n ResolvedBuildOptions,\n ResolvedVitendOptions,\n} from \"#/@types/options/resolved\";\nimport type { PackageJson } from \"#/functions/package-json\";\n\nimport { builtinModules } from \"node:module\";\n\nimport { toMerged } from \"es-toolkit\";\n\nimport { getPackageJson } from \"#/functions/package-json\";\nimport { getSsrTarget } from \"#/functions/ssr\";\n\nconst VIRTUAL_ENTRY = \"virtual:vitend-entry\" as const;\n\nconst VIRTUAL_ENTRY_RESOLVED = `\\0${VIRTUAL_ENTRY}` as const;\n\nconst buildPlugin = (opts: ResolvedVitendOptions): Plugin => {\n const build: ResolvedBuildOptions = opts.build;\n\n const packageJson: PackageJson = getPackageJson(opts.cwd);\n\n return {\n name: \"vitend/build\",\n apply: \"build\",\n config: (config: UserConfig): UserConfig => {\n let result: UserConfig = {};\n\n let baseConfig: UserConfig = {\n resolve: {\n conditions: [\n opts.runtime,\n ],\n },\n ssr: {\n target: getSsrTarget(opts.runtime),\n resolve: {\n conditions: [\n opts.runtime,\n ],\n },\n },\n build: {\n copyPublicDir: false,\n },\n };\n\n if (build.bundle === \"external\") {\n baseConfig = toMerged(baseConfig, {\n ssr: {\n external: true,\n noExternal: void 0,\n },\n });\n }\n\n if (build.bundle === \"standalone\") {\n baseConfig = toMerged(baseConfig, {\n ssr: {\n noExternal: true,\n },\n });\n }\n\n result = toMerged(baseConfig, config);\n\n const overrideConfig: UserConfig = {\n build: {\n ssr: true,\n outDir: build.outputDir,\n rollupOptions: {\n input: VIRTUAL_ENTRY,\n output: {\n entryFileNames: build.outputFile,\n format:\n packageJson.type === \"module\" ? \"esm\" : \"cjs\",\n },\n external: [\n ...builtinModules,\n /^node:/,\n ],\n },\n minify: build.minify,\n },\n };\n\n result = toMerged(result, overrideConfig);\n\n return result;\n },\n resolveId: (id: string): ResolveIdResult => {\n if (id !== VIRTUAL_ENTRY) return void 0;\n return VIRTUAL_ENTRY_RESOLVED;\n },\n load: async (id: string): Promise<LoadResult> => {\n if (id !== VIRTUAL_ENTRY_RESOLVED) return void 0;\n\n let code: string = \"\";\n\n code += `import options from \"${opts.entry}\";`;\n code += `import { serve } from \"vitend/runtime\";`;\n\n // vercel export\n\n if (build.target === \"vercel\") {\n code += `const server = serve({ ...options, manual: true });`;\n code += `export default server;`;\n\n return code;\n }\n\n // default export\n\n code += `serve({`;\n code += `...options,`;\n\n if (build.host !== \"localhost\")\n code += `hostname: \"${build.host}\",`;\n if (build.port !== 3000) code += `port: ${build.port},`;\n\n if (build.https) {\n code += `tls: {`;\n if (build.https.cert) code += `cert: \"${build.https.cert}\",`;\n if (build.https.key) code += `key: \"${build.https.key}\",`;\n if (build.https.passphrase)\n code += `passphrase: \"${build.https.passphrase}\",`;\n code += `},`;\n }\n\n code += `});`;\n\n return code;\n },\n };\n};\n\nexport { buildPlugin };\n","import type HTTP from \"node:http\";\n\nimport type { Server, ServerHandler, ServerOptions } from \"srvx\";\nimport type { Connect, Plugin, UserConfig, ViteDevServer } from \"vite\";\n\nimport type {\n ResolvedDevOptions,\n ResolvedHttpsOptions,\n ResolvedVitendOptions,\n} from \"#/@types/options/resolved\";\n\nimport { toMerged } from \"es-toolkit\";\nimport { serve } from \"srvx\";\n\nimport { getSsrTarget } from \"#/functions/ssr\";\n\ntype CreateMiddlewareOptions = {\n vite: ViteDevServer;\n server: Server;\n};\n\nconst createRequestHeaders = (headers: HTTP.IncomingHttpHeaders): Headers => {\n const result: Headers = new Headers();\n\n const entries: [\n string,\n string | string[] | undefined,\n ][] = Object.entries(headers);\n\n for (let i: number = 0; i < entries.length; i++) {\n const entry:\n | [\n string,\n string | string[] | undefined,\n ]\n | undefined = entries[i];\n\n if (entry === void 0) continue;\n\n const [key, value] = entry;\n\n // ignore HTTP/2 pseudo-headers\n if (key.startsWith(\":\")) continue;\n\n if (value === void 0) continue;\n\n if (Array.isArray(value)) {\n for (let j: number = 0; j < value.length; j++) {\n const vl: string | undefined = value[j];\n\n if (vl === void 0) continue;\n\n result.append(key, vl);\n }\n } else {\n result.set(key, value);\n }\n }\n\n return result;\n};\n\nconst createMiddleware = ({ vite, server }: CreateMiddlewareOptions) => {\n return async (\n req: Connect.IncomingMessage,\n res: HTTP.ServerResponse,\n _next: Connect.NextFunction,\n ): Promise<void> => {\n const isHttps: boolean =\n vite.config.server.https?.cert !== void 0 &&\n vite.config.server.https?.key !== void 0;\n\n const protocol: string = `http${isHttps ? \"s\" : \"\"}`;\n\n const host: string = process.env.HOST ?? \"localhost\";\n\n const port: number = vite.config.server.port;\n\n const path: string = req.url ?? \"\";\n\n const url: URL = new URL(`${protocol}://${host}:${port}${path}`);\n\n const body: Connect.IncomingMessage | undefined =\n req.method !== \"GET\" && req.method !== \"HEAD\" ? req : void 0;\n\n const request: Request = new Request(url, {\n method: req.method,\n headers: createRequestHeaders(req.headers),\n body,\n duplex: \"half\",\n } as RequestInit);\n\n const response: Response = await server.fetch(request);\n\n res.statusCode = response.status;\n\n response.headers.forEach((value: string, key: string): void => {\n res.setHeader(key, value);\n });\n\n if (!response.body) {\n res.end();\n return void 0;\n }\n\n const reader: ReadableStreamDefaultReader<Uint8Array<ArrayBuffer>> =\n response.body.getReader();\n\n const stream = async (): Promise<void> => {\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) break;\n\n res.write(value);\n }\n\n res.end();\n } catch {\n res.end();\n }\n };\n\n await stream();\n };\n};\n\ntype Middleware = ReturnType<typeof createMiddleware>;\n\nconst devPlugin = (opts: ResolvedVitendOptions): Plugin => {\n const dev: ResolvedDevOptions = opts.dev;\n const https: ResolvedHttpsOptions = opts.dev.https ?? {};\n\n return {\n name: \"vitend/dev\",\n apply: \"serve\",\n config(config: UserConfig): UserConfig {\n const devConfig: UserConfig = {\n resolve: {\n conditions: [\n opts.runtime,\n ],\n },\n ssr: {\n target: getSsrTarget(opts.runtime),\n resolve: {\n conditions: [\n opts.runtime,\n ],\n },\n },\n build: {\n ssr: true,\n rollupOptions: {\n input: opts.entry,\n },\n },\n server: {\n host: dev.host,\n port: dev.port,\n ...(https.cert !== void 0 && https.key !== void 0\n ? {\n https: {\n cert: https.cert,\n key: https.key,\n passphrase: https.passphrase,\n },\n }\n : {}),\n },\n };\n\n return toMerged(config, devConfig);\n },\n configureServer: async (vite: ViteDevServer): Promise<void> => {\n const serverOptions: ServerOptions = (\n await vite.ssrLoadModule(opts.entry)\n ).default;\n\n const server: Server<ServerHandler> = serve({\n // base\n gracefulShutdown: false,\n // user\n ...serverOptions,\n // override\n manual: true,\n hostname: dev.host,\n port: dev.port,\n tls: {\n cert: https.cert,\n key: https.key,\n passphrase: https.passphrase,\n },\n });\n\n const middleware: Middleware = createMiddleware({\n vite,\n server,\n });\n\n vite.middlewares.use(middleware);\n },\n };\n};\n\nexport { devPlugin };\n","import type { CopyEvent, Options as CopyOptions } from \"rolldown-plugin-copy\";\nimport type { Plugin } from \"vite\";\n\nimport type { VitendOptions } from \"#/@types/options/default\";\nimport type {\n ResolvedBuildOptions,\n ResolvedVitendOptions,\n} from \"#/@types/options/resolved\";\n\nimport * as Path from \"node:path\";\n\nimport { copy } from \"rolldown-plugin-copy\";\n\nimport { log } from \"#/configs/log\";\nimport { createOptions } from \"#/functions/options\";\nimport { buildPlugin } from \"#/vite/build\";\nimport { devPlugin } from \"#/vite/dev\";\n\n/**\n * The `vitend` plugin.\n *\n * ### Example\n *\n * ```ts\n * // ./vite.config.ts\n *\n * import { defineConfig } from \"vite\";\n * import { vitend } from \"vitend/vite\";\n *\n * export default defineConfig({\n * plugins: [\n * vitend(),\n * ],\n * });\n * ```\n */\nconst vitend = (options?: VitendOptions): Plugin[] => {\n const opts: ResolvedVitendOptions = createOptions(options);\n\n const build: ResolvedBuildOptions = opts.build;\n\n const plugins: Plugin[] = [\n devPlugin({\n ...opts,\n }),\n buildPlugin({\n ...opts,\n }),\n ];\n\n if (build.target === \"default\" && build.copyPublicDir) {\n const copyOptions: CopyOptions = {\n targets: [\n {\n src: Path.resolve(build.publicDir, \"**\", \"*\"),\n dest: Path.resolve(build.outputDir, build.publicDir),\n },\n ],\n };\n\n if (opts.verbose) {\n copyOptions.onStart = (): void => {\n console.log(\"\");\n console.log(\"\");\n };\n\n copyOptions.onCopy = (event: CopyEvent): void => {\n const src: string = Path.relative(opts.cwd, event.target.src);\n\n const dest: string = Path.relative(opts.cwd, event.target.dest);\n\n let message: string = `${src} → ${dest}`;\n\n const flags: string[] = [];\n\n if (event.target.renamed) {\n flags.push(\"R\");\n }\n\n if (event.target.transformed) {\n flags.push(\"T\");\n }\n\n if (flags.length > 0) {\n message += ` [${flags.join(\",\")}]`;\n }\n\n log.success(message);\n };\n\n copyOptions.onEnd = (): void => {\n console.log(\"\");\n };\n }\n\n plugins.push(copy(copyOptions) as Plugin);\n }\n\n return plugins;\n};\n\nexport { vitend };\n"],"mappings":"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"}
package/dist/vite.mjs CHANGED
@@ -1,10 +1,13 @@
1
1
  import { builtinModules } from "node:module";
2
2
  import * as Path from "node:path";
3
- import copy from "rollup-plugin-copy";
3
+ import { copy } from "rolldown-plugin-copy";
4
+ import { createConsola } from "consola";
4
5
  import { toMerged } from "es-toolkit";
5
6
  import * as Fs from "node:fs";
6
7
  import { serve } from "srvx";
7
8
 
9
+ const log = createConsola({ formatOptions: { date: false } });
10
+
8
11
  const ENTRY_DEFAULT = ["./src/index.ts", "./src/index.js"];
9
12
  const getEntry = (cwd, entry) => {
10
13
  if (!entry) {
@@ -17,28 +20,32 @@ const getEntry = (cwd, entry) => {
17
20
  return Path.resolve(cwd, entry);
18
21
  };
19
22
 
20
- const OPTIONS_BUILD_VERCEL = {
21
- target: "vercel",
22
- outputDir: "./dist",
23
- outputFile: "index.js",
24
- minify: false
25
- };
26
23
  const OPTIONS_BUILD_DEFAULT = {
27
24
  target: "default",
28
25
  host: "localhost",
29
26
  port: 3e3,
27
+ bundle: "external",
30
28
  outputDir: "./dist",
31
29
  outputFile: "index.js",
32
30
  minify: false,
33
31
  publicDir: "./public",
34
32
  copyPublicDir: false
35
33
  };
34
+ const OPTIONS_BUILD_VERCEL = {
35
+ target: "vercel",
36
+ bundle: "external",
37
+ outputDir: "./dist",
38
+ outputFile: "index.js",
39
+ minify: false
40
+ };
36
41
  const OPTIONS_DEFAULT = {
37
42
  cwd: process.cwd(),
43
+ runtime: "node",
38
44
  dev: {
39
45
  host: "localhost",
40
46
  port: 3001
41
- }
47
+ },
48
+ verbose: false
42
49
  };
43
50
  const getDefaultOptions = (isVercel) => {
44
51
  return {
@@ -61,6 +68,13 @@ const getPackageJson = (cwd) => {
61
68
  return JSON.parse(rawPackageJson);
62
69
  };
63
70
 
71
+ const getSsrTarget = (runtime) => {
72
+ switch (runtime) {
73
+ case "workerd": return "webworker";
74
+ default: return "node";
75
+ }
76
+ };
77
+
64
78
  const VIRTUAL_ENTRY = "virtual:vitend-entry";
65
79
  const VIRTUAL_ENTRY_RESOLVED = `\0${VIRTUAL_ENTRY}`;
66
80
  const buildPlugin = (opts) => {
@@ -71,14 +85,20 @@ const buildPlugin = (opts) => {
71
85
  apply: "build",
72
86
  config: (config) => {
73
87
  let result = {};
74
- result = toMerged({
88
+ let baseConfig = {
89
+ resolve: { conditions: [opts.runtime] },
75
90
  ssr: {
76
- external: true,
77
- noExternal: void 0,
78
- target: "webworker"
91
+ target: getSsrTarget(opts.runtime),
92
+ resolve: { conditions: [opts.runtime] }
79
93
  },
80
94
  build: { copyPublicDir: false }
81
- }, config);
95
+ };
96
+ if (build.bundle === "external") baseConfig = toMerged(baseConfig, { ssr: {
97
+ external: true,
98
+ noExternal: void 0
99
+ } });
100
+ if (build.bundle === "standalone") baseConfig = toMerged(baseConfig, { ssr: { noExternal: true } });
101
+ result = toMerged(baseConfig, config);
82
102
  const overrideConfig = { build: {
83
103
  ssr: true,
84
104
  outDir: build.outputDir,
@@ -191,6 +211,11 @@ const devPlugin = (opts) => {
191
211
  apply: "serve",
192
212
  config(config) {
193
213
  return toMerged(config, {
214
+ resolve: { conditions: [opts.runtime] },
215
+ ssr: {
216
+ target: getSsrTarget(opts.runtime),
217
+ resolve: { conditions: [opts.runtime] }
218
+ },
194
219
  build: {
195
220
  ssr: true,
196
221
  rollupOptions: { input: opts.entry }
@@ -249,17 +274,32 @@ const devPlugin = (opts) => {
249
274
  const vitend = (options) => {
250
275
  const opts = createOptions(options);
251
276
  const build = opts.build;
252
- return [
253
- devPlugin({ ...opts }),
254
- buildPlugin({ ...opts }),
255
- ...build.target === "default" && build.copyPublicDir ? [copy({
256
- hook: "closeBundle",
257
- targets: [{
258
- src: Path.resolve(build.publicDir, "**", "*"),
259
- dest: Path.resolve(build.outputDir, build.publicDir)
260
- }]
261
- })] : []
262
- ];
277
+ const plugins = [devPlugin({ ...opts }), buildPlugin({ ...opts })];
278
+ if (build.target === "default" && build.copyPublicDir) {
279
+ const copyOptions = { targets: [{
280
+ src: Path.resolve(build.publicDir, "**", "*"),
281
+ dest: Path.resolve(build.outputDir, build.publicDir)
282
+ }] };
283
+ if (opts.verbose) {
284
+ copyOptions.onStart = () => {
285
+ console.log("");
286
+ console.log("");
287
+ };
288
+ copyOptions.onCopy = (event) => {
289
+ let message = `${Path.relative(opts.cwd, event.target.src)} → ${Path.relative(opts.cwd, event.target.dest)}`;
290
+ const flags = [];
291
+ if (event.target.renamed) flags.push("R");
292
+ if (event.target.transformed) flags.push("T");
293
+ if (flags.length > 0) message += ` [${flags.join(",")}]`;
294
+ log.success(message);
295
+ };
296
+ copyOptions.onEnd = () => {
297
+ console.log("");
298
+ };
299
+ }
300
+ plugins.push(copy(copyOptions));
301
+ }
302
+ return plugins;
263
303
  };
264
304
 
265
305
  export { vitend };
package/dist/vite.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"vite.mjs","names":[],"sources":["../src/functions/entry.ts","../src/functions/options.ts","../src/functions/package-json.ts","../src/vite/build.ts","../src/vite/dev.ts","../src/vite/vitend.ts"],"sourcesContent":["import * as Fs from \"node:fs\";\nimport * as Path from \"node:path\";\n\nconst ENTRY_DEFAULT: string[] = [\n \"./src/index.ts\",\n \"./src/index.js\",\n];\n\nconst getEntry = (cwd: string, entry?: string): string => {\n if (!entry) {\n for (const ent of ENTRY_DEFAULT) {\n if (Fs.existsSync(Path.resolve(cwd, ent))) {\n entry = ent;\n break;\n }\n }\n\n if (!entry) {\n throw new Error(\"No entry file found\");\n }\n }\n\n return Path.resolve(cwd, entry);\n};\n\nexport { getEntry };\n","import type { Omit } from \"ts-vista\";\n\nimport type { VitendOptions } from \"#/@types/options/default\";\nimport type {\n ResolvedDefaultBuildOptions,\n ResolvedVercelBuildOptions,\n ResolvedVitendOptions,\n} from \"#/@types/options/resolved\";\n\nimport { toMerged } from \"es-toolkit\";\n\nimport { getEntry } from \"#/functions/entry\";\n\nconst OPTIONS_BUILD_VERCEL: ResolvedVercelBuildOptions = {\n target: \"vercel\",\n outputDir: \"./dist\",\n outputFile: \"index.js\",\n minify: false,\n};\n\nconst OPTIONS_BUILD_DEFAULT: ResolvedDefaultBuildOptions = {\n target: \"default\",\n host: \"localhost\",\n port: 3000,\n outputDir: \"./dist\",\n outputFile: \"index.js\",\n minify: false,\n publicDir: \"./public\",\n copyPublicDir: false,\n};\n\nconst OPTIONS_DEFAULT: Omit<ResolvedVitendOptions, \"entry\" | \"build\"> = {\n cwd: process.cwd(),\n dev: {\n host: \"localhost\",\n port: 3001,\n },\n};\n\nconst getDefaultOptions = (\n isVercel: boolean,\n): Omit<ResolvedVitendOptions, \"entry\"> => {\n return {\n ...OPTIONS_DEFAULT,\n build: isVercel ? OPTIONS_BUILD_VERCEL : OPTIONS_BUILD_DEFAULT,\n };\n};\n\nconst createOptions = (options?: VitendOptions): ResolvedVitendOptions => {\n const isVercel: boolean = options?.build?.target === \"vercel\";\n\n const merged = toMerged(getDefaultOptions(isVercel), options ?? {});\n\n return {\n ...merged,\n entry: getEntry(merged.cwd, options?.entry),\n };\n};\n\nexport { createOptions };\n","import type { Format, Partial } from \"ts-vista\";\n\nimport * as Fs from \"node:fs\";\nimport * as Path from \"node:path\";\n\ntype CompletePackageJson = {\n type: \"module\" | \"commonjs\";\n dependencies: Record<string, string>;\n devDependencies: Record<string, string>;\n peerDependencies: Record<string, string>;\n};\n\ntype PackageJson = Format<Partial<CompletePackageJson>>;\n\nconst getPackageJson = (cwd: string): PackageJson => {\n const path: string = Path.resolve(cwd, \"package.json\");\n\n if (!Fs.existsSync(path)) {\n throw new Error(\"Failed to find package.json\");\n }\n\n const rawPackageJson: string = Fs.readFileSync(path, \"utf-8\");\n\n return JSON.parse(rawPackageJson);\n};\n\nexport type { CompletePackageJson, PackageJson };\nexport { getPackageJson };\n","import type { LoadResult, ResolveIdResult } from \"rollup\";\nimport type { Plugin, UserConfig } from \"vite\";\n\nimport type {\n ResolvedBuildOptions,\n ResolvedVitendOptions,\n} from \"#/@types/options/resolved\";\nimport type { PackageJson } from \"#/functions/package-json\";\n\nimport { builtinModules } from \"node:module\";\n\nimport { toMerged } from \"es-toolkit\";\n\nimport { getPackageJson } from \"#/functions/package-json\";\n\nconst VIRTUAL_ENTRY = \"virtual:vitend-entry\" as const;\n\nconst VIRTUAL_ENTRY_RESOLVED = `\\0${VIRTUAL_ENTRY}` as const;\n\nconst buildPlugin = (opts: ResolvedVitendOptions): Plugin => {\n const build: ResolvedBuildOptions = opts.build;\n\n const packageJson: PackageJson = getPackageJson(opts.cwd);\n\n return {\n name: \"vitend/build\",\n apply: \"build\",\n config: (config: UserConfig): UserConfig => {\n let result: UserConfig = {};\n\n const baseConfig: UserConfig = {\n ssr: {\n external: true,\n noExternal: void 0,\n target: \"webworker\",\n },\n build: {\n copyPublicDir: false,\n },\n };\n\n result = toMerged(baseConfig, config);\n\n const overrideConfig: UserConfig = {\n build: {\n ssr: true,\n outDir: build.outputDir,\n rollupOptions: {\n input: VIRTUAL_ENTRY,\n output: {\n entryFileNames: build.outputFile,\n format:\n packageJson.type === \"module\" ? \"esm\" : \"cjs\",\n },\n external: [\n ...builtinModules,\n /^node:/,\n ],\n },\n minify: build.minify,\n },\n };\n\n result = toMerged(result, overrideConfig);\n\n return result;\n },\n resolveId: (id: string): ResolveIdResult => {\n if (id !== VIRTUAL_ENTRY) return void 0;\n return VIRTUAL_ENTRY_RESOLVED;\n },\n load: async (id: string): Promise<LoadResult> => {\n if (id !== VIRTUAL_ENTRY_RESOLVED) return void 0;\n\n let code: string = \"\";\n\n code += `import options from \"${opts.entry}\";`;\n code += `import { serve } from \"vitend/runtime\";`;\n\n // vercel export\n\n if (build.target === \"vercel\") {\n code += `const server = serve({ ...options, manual: true });`;\n code += `export default server;`;\n\n return code;\n }\n\n // default export\n\n code += `serve({`;\n code += `...options,`;\n\n if (build.host !== \"localhost\")\n code += `hostname: \"${build.host}\",`;\n if (build.port !== 3000) code += `port: ${build.port},`;\n\n if (build.https) {\n code += `tls: {`;\n if (build.https.cert) code += `cert: \"${build.https.cert}\",`;\n if (build.https.key) code += `key: \"${build.https.key}\",`;\n if (build.https.passphrase)\n code += `passphrase: \"${build.https.passphrase}\",`;\n code += `},`;\n }\n\n code += `});`;\n\n return code;\n },\n };\n};\n\nexport { buildPlugin };\n","import type HTTP from \"node:http\";\n\nimport type { Server, ServerHandler, ServerOptions } from \"srvx\";\nimport type { Connect, Plugin, UserConfig, ViteDevServer } from \"vite\";\n\nimport type {\n ResolvedDevOptions,\n ResolvedHttpsOptions,\n ResolvedVitendOptions,\n} from \"#/@types/options/resolved\";\n\nimport { toMerged } from \"es-toolkit\";\nimport { serve } from \"srvx\";\n\ntype CreateMiddlewareOptions = {\n vite: ViteDevServer;\n server: Server;\n};\n\nconst createRequestHeaders = (headers: HTTP.IncomingHttpHeaders): Headers => {\n const result: Headers = new Headers();\n\n const entries: [\n string,\n string | string[] | undefined,\n ][] = Object.entries(headers);\n\n for (let i: number = 0; i < entries.length; i++) {\n const entry:\n | [\n string,\n string | string[] | undefined,\n ]\n | undefined = entries[i];\n\n if (entry === void 0) continue;\n\n const [key, value] = entry;\n\n // ignore HTTP/2 pseudo-headers\n if (key.startsWith(\":\")) continue;\n\n if (value === void 0) continue;\n\n if (Array.isArray(value)) {\n for (let j: number = 0; j < value.length; j++) {\n const vl: string | undefined = value[j];\n\n if (vl === void 0) continue;\n\n result.append(key, vl);\n }\n } else {\n result.set(key, value);\n }\n }\n\n return result;\n};\n\nconst createMiddleware = ({ vite, server }: CreateMiddlewareOptions) => {\n return async (\n req: Connect.IncomingMessage,\n res: HTTP.ServerResponse,\n _next: Connect.NextFunction,\n ): Promise<void> => {\n const isHttps: boolean =\n vite.config.server.https?.cert !== void 0 &&\n vite.config.server.https?.key !== void 0;\n\n const protocol: string = `http${isHttps ? \"s\" : \"\"}`;\n\n const host: string = process.env.HOST ?? \"localhost\";\n\n const port: number = vite.config.server.port;\n\n const path: string = req.url ?? \"\";\n\n const url: URL = new URL(`${protocol}://${host}:${port}${path}`);\n\n const body: Connect.IncomingMessage | undefined =\n req.method !== \"GET\" && req.method !== \"HEAD\" ? req : void 0;\n\n const request: Request = new Request(url, {\n method: req.method,\n headers: createRequestHeaders(req.headers),\n body,\n duplex: \"half\",\n } as RequestInit);\n\n const response: Response = await server.fetch(request);\n\n res.statusCode = response.status;\n\n response.headers.forEach((value: string, key: string): void => {\n res.setHeader(key, value);\n });\n\n if (!response.body) {\n res.end();\n return void 0;\n }\n\n const reader: ReadableStreamDefaultReader<Uint8Array<ArrayBuffer>> =\n response.body.getReader();\n\n const stream = async (): Promise<void> => {\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) break;\n\n res.write(value);\n }\n\n res.end();\n } catch {\n res.end();\n }\n };\n\n await stream();\n };\n};\n\ntype Middleware = ReturnType<typeof createMiddleware>;\n\nconst devPlugin = (opts: ResolvedVitendOptions): Plugin => {\n const dev: ResolvedDevOptions = opts.dev;\n const https: ResolvedHttpsOptions = opts.dev.https ?? {};\n\n return {\n name: \"vitend/dev\",\n apply: \"serve\",\n config(config: UserConfig): UserConfig {\n const devConfig: UserConfig = {\n build: {\n ssr: true,\n rollupOptions: {\n input: opts.entry,\n },\n },\n server: {\n host: dev.host,\n port: dev.port,\n ...(https.cert !== void 0 && https.key !== void 0\n ? {\n https: {\n cert: https.cert,\n key: https.key,\n passphrase: https.passphrase,\n },\n }\n : {}),\n },\n };\n\n return toMerged(config, devConfig);\n },\n configureServer: async (vite: ViteDevServer): Promise<void> => {\n const serverOptions: ServerOptions = (\n await vite.ssrLoadModule(opts.entry)\n ).default;\n\n const server: Server<ServerHandler> = serve({\n // base\n gracefulShutdown: false,\n // user\n ...serverOptions,\n // override\n manual: true,\n hostname: dev.host,\n port: dev.port,\n tls: {\n cert: https.cert,\n key: https.key,\n passphrase: https.passphrase,\n },\n });\n\n const middleware: Middleware = createMiddleware({\n vite,\n server,\n });\n\n vite.middlewares.use(middleware);\n },\n };\n};\n\nexport { devPlugin };\n","import type { Plugin } from \"vite\";\n\nimport type { VitendOptions } from \"#/@types/options/default\";\nimport type {\n ResolvedBuildOptions,\n ResolvedVitendOptions,\n} from \"#/@types/options/resolved\";\n\nimport * as Path from \"node:path\";\n\nimport copy from \"rollup-plugin-copy\";\n\nimport { createOptions } from \"#/functions/options\";\nimport { buildPlugin } from \"#/vite/build\";\nimport { devPlugin } from \"#/vite/dev\";\n\n/**\n * The `vitend` plugin.\n *\n * ### Example\n *\n * ```ts\n * // ./vite.config.ts\n *\n * import { defineConfig } from \"vite\";\n * import { vitend } from \"vitend/vite\";\n *\n * export default defineConfig({\n * plugins: [\n * vitend(),\n * ],\n * });\n * ```\n */\nconst vitend = (options?: VitendOptions): Plugin[] => {\n const opts: ResolvedVitendOptions = createOptions(options);\n\n const build: ResolvedBuildOptions = opts.build;\n\n return [\n devPlugin({\n ...opts,\n }),\n buildPlugin({\n ...opts,\n }),\n ...(build.target === \"default\" && build.copyPublicDir\n ? ([\n copy({\n hook: \"closeBundle\",\n targets: [\n {\n src: Path.resolve(build.publicDir, \"**\", \"*\"),\n dest: Path.resolve(\n build.outputDir,\n build.publicDir,\n ),\n },\n ],\n }),\n ] as Plugin[])\n : []),\n ];\n};\n\nexport { vitend };\n"],"mappings":"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"}
1
+ {"version":3,"file":"vite.mjs","names":[],"sources":["../src/configs/log.ts","../src/functions/entry.ts","../src/functions/options.ts","../src/functions/package-json.ts","../src/functions/ssr.ts","../src/vite/build.ts","../src/vite/dev.ts","../src/vite/vitend.ts"],"sourcesContent":["import type { ConsolaInstance } from \"consola\";\n\nimport { createConsola } from \"consola\";\n\nconst log: ConsolaInstance = createConsola({\n formatOptions: {\n date: false,\n },\n});\n\nexport { log };\n","import * as Fs from \"node:fs\";\nimport * as Path from \"node:path\";\n\nconst ENTRY_DEFAULT: string[] = [\n \"./src/index.ts\",\n \"./src/index.js\",\n];\n\nconst getEntry = (cwd: string, entry?: string): string => {\n if (!entry) {\n for (const ent of ENTRY_DEFAULT) {\n if (Fs.existsSync(Path.resolve(cwd, ent))) {\n entry = ent;\n break;\n }\n }\n\n if (!entry) {\n throw new Error(\"No entry file found\");\n }\n }\n\n return Path.resolve(cwd, entry);\n};\n\nexport { getEntry };\n","import type { Omit } from \"ts-vista\";\n\nimport type { VitendOptions } from \"#/@types/options/default\";\nimport type {\n ResolvedDefaultBuildOptions,\n ResolvedVercelBuildOptions,\n ResolvedVitendOptions,\n} from \"#/@types/options/resolved\";\n\nimport { toMerged } from \"es-toolkit\";\n\nimport { getEntry } from \"#/functions/entry\";\n\nconst OPTIONS_BUILD_DEFAULT: ResolvedDefaultBuildOptions = {\n target: \"default\",\n host: \"localhost\",\n port: 3000,\n bundle: \"external\",\n outputDir: \"./dist\",\n outputFile: \"index.js\",\n minify: false,\n publicDir: \"./public\",\n copyPublicDir: false,\n};\n\nconst OPTIONS_BUILD_VERCEL: ResolvedVercelBuildOptions = {\n target: \"vercel\",\n bundle: \"external\",\n outputDir: \"./dist\",\n outputFile: \"index.js\",\n minify: false,\n};\n\nconst OPTIONS_DEFAULT: Omit<ResolvedVitendOptions, \"entry\" | \"build\"> = {\n cwd: process.cwd(),\n runtime: \"node\",\n dev: {\n host: \"localhost\",\n port: 3001,\n },\n verbose: false,\n};\n\nconst getDefaultOptions = (\n isVercel: boolean,\n): Omit<ResolvedVitendOptions, \"entry\"> => {\n return {\n ...OPTIONS_DEFAULT,\n build: isVercel ? OPTIONS_BUILD_VERCEL : OPTIONS_BUILD_DEFAULT,\n };\n};\n\nconst createOptions = (options?: VitendOptions): ResolvedVitendOptions => {\n const isVercel: boolean = options?.build?.target === \"vercel\";\n\n const merged = toMerged(getDefaultOptions(isVercel), options ?? {});\n\n return {\n ...merged,\n entry: getEntry(merged.cwd, options?.entry),\n };\n};\n\nexport { createOptions };\n","import type { Format, Partial } from \"ts-vista\";\n\nimport * as Fs from \"node:fs\";\nimport * as Path from \"node:path\";\n\ntype CompletePackageJson = {\n type: \"module\" | \"commonjs\";\n dependencies: Record<string, string>;\n devDependencies: Record<string, string>;\n peerDependencies: Record<string, string>;\n};\n\ntype PackageJson = Format<Partial<CompletePackageJson>>;\n\nconst getPackageJson = (cwd: string): PackageJson => {\n const path: string = Path.resolve(cwd, \"package.json\");\n\n if (!Fs.existsSync(path)) {\n throw new Error(\"Failed to find package.json\");\n }\n\n const rawPackageJson: string = Fs.readFileSync(path, \"utf-8\");\n\n return JSON.parse(rawPackageJson);\n};\n\nexport type { CompletePackageJson, PackageJson };\nexport { getPackageJson };\n","import type { SSRTarget } from \"vite\";\n\nimport type { Runtime } from \"#/@types/options/complete\";\n\nconst getSsrTarget = (runtime: Runtime): SSRTarget => {\n switch (runtime) {\n case \"workerd\":\n return \"webworker\";\n default:\n return \"node\";\n }\n};\n\nexport { getSsrTarget };\n","import type { LoadResult, ResolveIdResult } from \"rollup\";\nimport type { Plugin, UserConfig } from \"vite\";\n\nimport type {\n ResolvedBuildOptions,\n ResolvedVitendOptions,\n} from \"#/@types/options/resolved\";\nimport type { PackageJson } from \"#/functions/package-json\";\n\nimport { builtinModules } from \"node:module\";\n\nimport { toMerged } from \"es-toolkit\";\n\nimport { getPackageJson } from \"#/functions/package-json\";\nimport { getSsrTarget } from \"#/functions/ssr\";\n\nconst VIRTUAL_ENTRY = \"virtual:vitend-entry\" as const;\n\nconst VIRTUAL_ENTRY_RESOLVED = `\\0${VIRTUAL_ENTRY}` as const;\n\nconst buildPlugin = (opts: ResolvedVitendOptions): Plugin => {\n const build: ResolvedBuildOptions = opts.build;\n\n const packageJson: PackageJson = getPackageJson(opts.cwd);\n\n return {\n name: \"vitend/build\",\n apply: \"build\",\n config: (config: UserConfig): UserConfig => {\n let result: UserConfig = {};\n\n let baseConfig: UserConfig = {\n resolve: {\n conditions: [\n opts.runtime,\n ],\n },\n ssr: {\n target: getSsrTarget(opts.runtime),\n resolve: {\n conditions: [\n opts.runtime,\n ],\n },\n },\n build: {\n copyPublicDir: false,\n },\n };\n\n if (build.bundle === \"external\") {\n baseConfig = toMerged(baseConfig, {\n ssr: {\n external: true,\n noExternal: void 0,\n },\n });\n }\n\n if (build.bundle === \"standalone\") {\n baseConfig = toMerged(baseConfig, {\n ssr: {\n noExternal: true,\n },\n });\n }\n\n result = toMerged(baseConfig, config);\n\n const overrideConfig: UserConfig = {\n build: {\n ssr: true,\n outDir: build.outputDir,\n rollupOptions: {\n input: VIRTUAL_ENTRY,\n output: {\n entryFileNames: build.outputFile,\n format:\n packageJson.type === \"module\" ? \"esm\" : \"cjs\",\n },\n external: [\n ...builtinModules,\n /^node:/,\n ],\n },\n minify: build.minify,\n },\n };\n\n result = toMerged(result, overrideConfig);\n\n return result;\n },\n resolveId: (id: string): ResolveIdResult => {\n if (id !== VIRTUAL_ENTRY) return void 0;\n return VIRTUAL_ENTRY_RESOLVED;\n },\n load: async (id: string): Promise<LoadResult> => {\n if (id !== VIRTUAL_ENTRY_RESOLVED) return void 0;\n\n let code: string = \"\";\n\n code += `import options from \"${opts.entry}\";`;\n code += `import { serve } from \"vitend/runtime\";`;\n\n // vercel export\n\n if (build.target === \"vercel\") {\n code += `const server = serve({ ...options, manual: true });`;\n code += `export default server;`;\n\n return code;\n }\n\n // default export\n\n code += `serve({`;\n code += `...options,`;\n\n if (build.host !== \"localhost\")\n code += `hostname: \"${build.host}\",`;\n if (build.port !== 3000) code += `port: ${build.port},`;\n\n if (build.https) {\n code += `tls: {`;\n if (build.https.cert) code += `cert: \"${build.https.cert}\",`;\n if (build.https.key) code += `key: \"${build.https.key}\",`;\n if (build.https.passphrase)\n code += `passphrase: \"${build.https.passphrase}\",`;\n code += `},`;\n }\n\n code += `});`;\n\n return code;\n },\n };\n};\n\nexport { buildPlugin };\n","import type HTTP from \"node:http\";\n\nimport type { Server, ServerHandler, ServerOptions } from \"srvx\";\nimport type { Connect, Plugin, UserConfig, ViteDevServer } from \"vite\";\n\nimport type {\n ResolvedDevOptions,\n ResolvedHttpsOptions,\n ResolvedVitendOptions,\n} from \"#/@types/options/resolved\";\n\nimport { toMerged } from \"es-toolkit\";\nimport { serve } from \"srvx\";\n\nimport { getSsrTarget } from \"#/functions/ssr\";\n\ntype CreateMiddlewareOptions = {\n vite: ViteDevServer;\n server: Server;\n};\n\nconst createRequestHeaders = (headers: HTTP.IncomingHttpHeaders): Headers => {\n const result: Headers = new Headers();\n\n const entries: [\n string,\n string | string[] | undefined,\n ][] = Object.entries(headers);\n\n for (let i: number = 0; i < entries.length; i++) {\n const entry:\n | [\n string,\n string | string[] | undefined,\n ]\n | undefined = entries[i];\n\n if (entry === void 0) continue;\n\n const [key, value] = entry;\n\n // ignore HTTP/2 pseudo-headers\n if (key.startsWith(\":\")) continue;\n\n if (value === void 0) continue;\n\n if (Array.isArray(value)) {\n for (let j: number = 0; j < value.length; j++) {\n const vl: string | undefined = value[j];\n\n if (vl === void 0) continue;\n\n result.append(key, vl);\n }\n } else {\n result.set(key, value);\n }\n }\n\n return result;\n};\n\nconst createMiddleware = ({ vite, server }: CreateMiddlewareOptions) => {\n return async (\n req: Connect.IncomingMessage,\n res: HTTP.ServerResponse,\n _next: Connect.NextFunction,\n ): Promise<void> => {\n const isHttps: boolean =\n vite.config.server.https?.cert !== void 0 &&\n vite.config.server.https?.key !== void 0;\n\n const protocol: string = `http${isHttps ? \"s\" : \"\"}`;\n\n const host: string = process.env.HOST ?? \"localhost\";\n\n const port: number = vite.config.server.port;\n\n const path: string = req.url ?? \"\";\n\n const url: URL = new URL(`${protocol}://${host}:${port}${path}`);\n\n const body: Connect.IncomingMessage | undefined =\n req.method !== \"GET\" && req.method !== \"HEAD\" ? req : void 0;\n\n const request: Request = new Request(url, {\n method: req.method,\n headers: createRequestHeaders(req.headers),\n body,\n duplex: \"half\",\n } as RequestInit);\n\n const response: Response = await server.fetch(request);\n\n res.statusCode = response.status;\n\n response.headers.forEach((value: string, key: string): void => {\n res.setHeader(key, value);\n });\n\n if (!response.body) {\n res.end();\n return void 0;\n }\n\n const reader: ReadableStreamDefaultReader<Uint8Array<ArrayBuffer>> =\n response.body.getReader();\n\n const stream = async (): Promise<void> => {\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) break;\n\n res.write(value);\n }\n\n res.end();\n } catch {\n res.end();\n }\n };\n\n await stream();\n };\n};\n\ntype Middleware = ReturnType<typeof createMiddleware>;\n\nconst devPlugin = (opts: ResolvedVitendOptions): Plugin => {\n const dev: ResolvedDevOptions = opts.dev;\n const https: ResolvedHttpsOptions = opts.dev.https ?? {};\n\n return {\n name: \"vitend/dev\",\n apply: \"serve\",\n config(config: UserConfig): UserConfig {\n const devConfig: UserConfig = {\n resolve: {\n conditions: [\n opts.runtime,\n ],\n },\n ssr: {\n target: getSsrTarget(opts.runtime),\n resolve: {\n conditions: [\n opts.runtime,\n ],\n },\n },\n build: {\n ssr: true,\n rollupOptions: {\n input: opts.entry,\n },\n },\n server: {\n host: dev.host,\n port: dev.port,\n ...(https.cert !== void 0 && https.key !== void 0\n ? {\n https: {\n cert: https.cert,\n key: https.key,\n passphrase: https.passphrase,\n },\n }\n : {}),\n },\n };\n\n return toMerged(config, devConfig);\n },\n configureServer: async (vite: ViteDevServer): Promise<void> => {\n const serverOptions: ServerOptions = (\n await vite.ssrLoadModule(opts.entry)\n ).default;\n\n const server: Server<ServerHandler> = serve({\n // base\n gracefulShutdown: false,\n // user\n ...serverOptions,\n // override\n manual: true,\n hostname: dev.host,\n port: dev.port,\n tls: {\n cert: https.cert,\n key: https.key,\n passphrase: https.passphrase,\n },\n });\n\n const middleware: Middleware = createMiddleware({\n vite,\n server,\n });\n\n vite.middlewares.use(middleware);\n },\n };\n};\n\nexport { devPlugin };\n","import type { CopyEvent, Options as CopyOptions } from \"rolldown-plugin-copy\";\nimport type { Plugin } from \"vite\";\n\nimport type { VitendOptions } from \"#/@types/options/default\";\nimport type {\n ResolvedBuildOptions,\n ResolvedVitendOptions,\n} from \"#/@types/options/resolved\";\n\nimport * as Path from \"node:path\";\n\nimport { copy } from \"rolldown-plugin-copy\";\n\nimport { log } from \"#/configs/log\";\nimport { createOptions } from \"#/functions/options\";\nimport { buildPlugin } from \"#/vite/build\";\nimport { devPlugin } from \"#/vite/dev\";\n\n/**\n * The `vitend` plugin.\n *\n * ### Example\n *\n * ```ts\n * // ./vite.config.ts\n *\n * import { defineConfig } from \"vite\";\n * import { vitend } from \"vitend/vite\";\n *\n * export default defineConfig({\n * plugins: [\n * vitend(),\n * ],\n * });\n * ```\n */\nconst vitend = (options?: VitendOptions): Plugin[] => {\n const opts: ResolvedVitendOptions = createOptions(options);\n\n const build: ResolvedBuildOptions = opts.build;\n\n const plugins: Plugin[] = [\n devPlugin({\n ...opts,\n }),\n buildPlugin({\n ...opts,\n }),\n ];\n\n if (build.target === \"default\" && build.copyPublicDir) {\n const copyOptions: CopyOptions = {\n targets: [\n {\n src: Path.resolve(build.publicDir, \"**\", \"*\"),\n dest: Path.resolve(build.outputDir, build.publicDir),\n },\n ],\n };\n\n if (opts.verbose) {\n copyOptions.onStart = (): void => {\n console.log(\"\");\n console.log(\"\");\n };\n\n copyOptions.onCopy = (event: CopyEvent): void => {\n const src: string = Path.relative(opts.cwd, event.target.src);\n\n const dest: string = Path.relative(opts.cwd, event.target.dest);\n\n let message: string = `${src} → ${dest}`;\n\n const flags: string[] = [];\n\n if (event.target.renamed) {\n flags.push(\"R\");\n }\n\n if (event.target.transformed) {\n flags.push(\"T\");\n }\n\n if (flags.length > 0) {\n message += ` [${flags.join(\",\")}]`;\n }\n\n log.success(message);\n };\n\n copyOptions.onEnd = (): void => {\n console.log(\"\");\n };\n }\n\n plugins.push(copy(copyOptions) as Plugin);\n }\n\n return plugins;\n};\n\nexport { vitend };\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://raw.githubusercontent.com/vitejs/vite-plugin-registry/refs/heads/main/data/schema/extended-package-json.schema.json",
3
3
  "name": "vitend",
4
- "version": "0.2.3",
4
+ "version": "0.4.0",
5
5
  "description": "A library for backend development with Vite",
6
6
  "keywords": [
7
7
  "vitend",
@@ -57,8 +57,9 @@
57
57
  "dist"
58
58
  ],
59
59
  "dependencies": {
60
+ "consola": "^3.4.0",
60
61
  "es-toolkit": "^1.40.0",
61
- "rollup-plugin-copy": "^3.5.0",
62
+ "rolldown-plugin-copy": "~0.2.0",
62
63
  "srvx": "~0.11.0",
63
64
  "ts-vista": "~0.2.3"
64
65
  },