rolldown-plugin-copy 0.1.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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026-present, Alpheus
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,42 @@
1
+ # Rolldown Plugin Copy
2
+
3
+ A utility to copy files and directories.
4
+
5
+ Partially compatible with [rollup-plugin-copy](https://github.com/vladshcherbin/rollup-plugin-copy).
6
+
7
+ ## Usage
8
+
9
+ Add the plugin into the Vite config:
10
+
11
+ ```ts
12
+ import { defineConfig } from "vite";
13
+ import { copy } from "rolldown-plugin-copy";
14
+
15
+ export default defineConfig({
16
+ plugins: [
17
+ copy({
18
+ targets: [
19
+ {
20
+ src: "./public/index.html",
21
+ dest: "./dist/public",
22
+ },
23
+ {
24
+ src: [
25
+ "./public/static/css/light.css",
26
+ "./public/static/css/dark.css",
27
+ ],
28
+ dest: "./dist/public/static/css",
29
+ },
30
+ {
31
+ src: "./public/static/images/**/*",
32
+ dest: "./dist/public/static/images",
33
+ },
34
+ ],
35
+ }),
36
+ ],
37
+ });
38
+ ```
39
+
40
+ ## License
41
+
42
+ This project is licensed under the terms of the MIT license.
@@ -0,0 +1,147 @@
1
+ import { AsyncPluginHooks, Plugin } from "rolldown";
2
+ import { Format, Partial } from "ts-vista";
3
+ import { writeFile } from "node:fs/promises";
4
+ /**
5
+ * Write file data.
6
+ */
7
+ type WriteFileData = Parameters<typeof writeFile>[1];
8
+ /**
9
+ * Rename options.
10
+ */
11
+ type TargetRenameOptions = {
12
+ /**
13
+ * The file path.
14
+ *
15
+ * For example, `/home/abc/dev/project/public/static/css/index.css`.
16
+ */
17
+ path: string;
18
+ /**
19
+ * The file name.
20
+ *
21
+ * For example, `index` in `index.css`.
22
+ */
23
+ name: string;
24
+ /**
25
+ * The file extension.
26
+ *
27
+ * For example, `css` in `index.css`.
28
+ */
29
+ extension: string;
30
+ };
31
+ /**
32
+ * Rename with string or function.
33
+ */
34
+ type TargetRename = string | ((options: TargetRenameOptions) => string);
35
+ /**
36
+ * Content transform options.
37
+ */
38
+ type TargetTransformOptions = {
39
+ /**
40
+ * The file name, such as `index.css`.
41
+ */
42
+ fileName: string;
43
+ /**
44
+ * The file content.
45
+ */
46
+ content: Buffer;
47
+ };
48
+ /**
49
+ * Content transform with function or string.
50
+ */
51
+ type TargetTransform = WriteFileData | ((options: TargetTransformOptions) => Promise<WriteFileData> | WriteFileData);
52
+ type CompleteTarget = {
53
+ /**
54
+ * Path or glob of what to copy.
55
+ */
56
+ src: string | string[];
57
+ /**
58
+ * destination(s) to copy.
59
+ */
60
+ dest: string | string[];
61
+ /**
62
+ * Change destination file or directory name.
63
+ */
64
+ rename: TargetRename;
65
+ /**
66
+ * Modify file contents.
67
+ */
68
+ transform: TargetTransform;
69
+ };
70
+ /**
71
+ * Target type for `copy` plugin.
72
+ */
73
+ type Target = Format<Partial<CompleteTarget, "rename" | "transform">>;
74
+ type CompleteOptions = {
75
+ /**
76
+ * Current working directory.
77
+ *
78
+ * By default, it is `process.cwd()`.
79
+ */
80
+ cwd: string;
81
+ /**
82
+ * Rolldown hook the plugin should use.
83
+ *
84
+ * By default, it is `generateBundle`.
85
+ */
86
+ hook: AsyncPluginHooks;
87
+ /**
88
+ * Copy items once. Useful in watch mode.
89
+ *
90
+ * By default, it is `false`.
91
+ */
92
+ copyOnce: boolean;
93
+ /**
94
+ * Copy items synchronous.
95
+ *
96
+ * By default, it is `false`.
97
+ */
98
+ copySync: boolean;
99
+ /**
100
+ * Remove the directory structure of copied files.
101
+ *
102
+ * By default, it is `false`.
103
+ */
104
+ flatten: boolean;
105
+ /**
106
+ * Output copied items to console.
107
+ *
108
+ * By default, it is `false`.
109
+ */
110
+ verbose: boolean;
111
+ /**
112
+ * Array of targets to copy.
113
+ *
114
+ * By default, it is `[]`.
115
+ */
116
+ targets: Target[];
117
+ };
118
+ /**
119
+ * Options for `copy` plugin.
120
+ */
121
+ type Options = Format<Partial<CompleteOptions>>;
122
+ /**
123
+ * A utility to copy files and directories.
124
+ *
125
+ * ### Example
126
+ *
127
+ * ```ts
128
+ * import { defineConfig } from "rolldown";
129
+ * import { copy } from "rolldown-plugin-copy";
130
+ *
131
+ * export default defineConfig({
132
+ * plugins: [
133
+ * copy({
134
+ * targets: [
135
+ * {
136
+ * src: "./public/static/css/index.css",
137
+ * dest: "./dist/public/static/css",
138
+ * },
139
+ * ],
140
+ * }),
141
+ * ],
142
+ * });
143
+ * ```
144
+ */
145
+ declare const copy: (options?: Options) => Plugin;
146
+ export { type Options, type Target, type TargetRename, type TargetRenameOptions, type TargetTransform, type TargetTransformOptions, type WriteFileData, copy, copy as default };
147
+ //# sourceMappingURL=index.d.ts.map
package/dist/index.js ADDED
@@ -0,0 +1,324 @@
1
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") {
10
+ for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) {
13
+ __defProp(to, key, {
14
+ get: ((k) => from[k]).bind(null, key),
15
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
+ });
17
+ }
18
+ }
19
+ }
20
+ return to;
21
+ };
22
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
23
+ value: mod,
24
+ enumerable: true
25
+ }) : target, mod));
26
+
27
+ let es_toolkit = require("es-toolkit");
28
+ let node_fs = require("node:fs");
29
+ node_fs = __toESM(node_fs);
30
+ let node_fs_promises = require("node:fs/promises");
31
+ node_fs_promises = __toESM(node_fs_promises);
32
+ let node_path = require("node:path");
33
+ node_path = __toESM(node_path);
34
+ let consola = require("consola");
35
+ let tinyglobby = require("tinyglobby");
36
+
37
+ const OPTIONS_DEFAULT = {
38
+ cwd: process.cwd(),
39
+ hook: "generateBundle",
40
+ copyOnce: false,
41
+ copySync: false,
42
+ flatten: false,
43
+ verbose: false,
44
+ targets: []
45
+ };
46
+
47
+ const log = (0, consola.createConsola)({ formatOptions: { date: false } });
48
+
49
+ const canCopyInParallel = (targets) => {
50
+ const destinations = /* @__PURE__ */ new Set();
51
+ for (let i = 0; i < targets.length; i++) {
52
+ const target = targets[i];
53
+ if (target === void 0) continue;
54
+ /**
55
+ * Raw directory copies write a whole subtree, so exact destination checks
56
+ * cannot detect nested conflicts with other targets in parallel.
57
+ */
58
+ if (target.kind === "directory") return false;
59
+ /**
60
+ * Multiple targets writing the same path leads to conflicts, so
61
+ * keep the original target order by falling back to sequential copies.
62
+ */
63
+ if (destinations.has(target.dest)) return false;
64
+ destinations.add(target.dest);
65
+ }
66
+ return true;
67
+ };
68
+ const ensureDirSync = (filePath) => {
69
+ node_fs.mkdirSync(node_path.dirname(filePath), { recursive: true });
70
+ };
71
+ const ensureDirAsync = async (filePath) => {
72
+ await node_fs_promises.mkdir(node_path.dirname(filePath), { recursive: true });
73
+ };
74
+ const copyFile = async ({ src, dest, copySync }) => {
75
+ if (copySync) {
76
+ ensureDirSync(dest);
77
+ node_fs.copyFileSync(src, dest);
78
+ return;
79
+ }
80
+ await ensureDirAsync(dest);
81
+ await node_fs_promises.copyFile(src, dest);
82
+ };
83
+ const copyDirectory = async ({ src, dest, copySync }) => {
84
+ if (copySync) {
85
+ node_fs.cpSync(src, dest, { recursive: true });
86
+ return;
87
+ }
88
+ await node_fs_promises.cp(src, dest, { recursive: true });
89
+ };
90
+ const writeTransformed = async (target) => {
91
+ await ensureDirAsync(target.dest);
92
+ await node_fs_promises.writeFile(target.dest, target.content ?? "");
93
+ };
94
+ const copyTarget = async ({ target, copySync }) => {
95
+ if (target.transformed) return await writeTransformed(target);
96
+ if (target.kind === "file") return await copyFile({
97
+ src: target.src,
98
+ dest: target.dest,
99
+ copySync
100
+ });
101
+ return await copyDirectory({
102
+ src: target.src,
103
+ dest: target.dest,
104
+ copySync
105
+ });
106
+ };
107
+ const buildLogMessage = ({ cwd, target }) => {
108
+ let message = `${node_path.relative(cwd, target.src)} → ${target.dest}`;
109
+ const flags = [];
110
+ if (target.renamed) flags.push("R");
111
+ if (target.transformed) flags.push("T");
112
+ if (flags.length > 0) message += ` [${flags.join(",")}]`;
113
+ return message;
114
+ };
115
+ const copyTargets = async ({ cwd, targets, copySync, verbose }) => {
116
+ if (targets.length === 0) {
117
+ if (verbose) {
118
+ log.success("no items to copy");
119
+ console.log("");
120
+ }
121
+ return;
122
+ }
123
+ const logs = [];
124
+ if (!copySync && canCopyInParallel(targets)) {
125
+ const result = (await Promise.all(targets.map(async (target) => {
126
+ await copyTarget({
127
+ target,
128
+ copySync
129
+ });
130
+ return verbose ? buildLogMessage({
131
+ cwd,
132
+ target
133
+ }) : void 0;
134
+ }))).filter((item) => item !== void 0);
135
+ if (verbose) for (let i = 0; i < result.length; i++) {
136
+ const message = result[i];
137
+ if (message === void 0) continue;
138
+ logs.push(message);
139
+ }
140
+ } else for (let i = 0; i < targets.length; i++) {
141
+ const target = targets[i];
142
+ if (target === void 0) continue;
143
+ await copyTarget({
144
+ target,
145
+ copySync
146
+ });
147
+ if (verbose) logs.push(buildLogMessage({
148
+ cwd,
149
+ target
150
+ }));
151
+ }
152
+ if (verbose) {
153
+ for (let i = 0; i < logs.length; i++) log.success(logs[i]);
154
+ console.log("");
155
+ }
156
+ };
157
+
158
+ const renameTarget = (options) => {
159
+ const parsed = node_path.parse(options.fileName);
160
+ return typeof options.rename === "function" ? options.rename({
161
+ path: options.path,
162
+ name: parsed.name,
163
+ extension: parsed.ext.replace(".", "")
164
+ }) : options.rename;
165
+ };
166
+
167
+ const resolveDestDir = ({ cwd, src, dest, flatten }) => {
168
+ if (flatten) return dest;
169
+ const relativeDir = node_path.dirname(node_path.relative(cwd, src));
170
+ if (relativeDir === ".") return dest;
171
+ const relativeDirParts = relativeDir.split(node_path.sep);
172
+ return node_path.join(dest, ...relativeDirParts.slice(1));
173
+ };
174
+ const generateTargets = async ({ cwd, src, target, flatten }) => {
175
+ const stats = await node_fs_promises.stat(src);
176
+ if (target.transform && stats.isDirectory()) return [];
177
+ const parsed = node_path.parse(src);
178
+ const destinations = typeof target.dest === "string" ? [target.dest] : target.dest;
179
+ const result = [];
180
+ for (let i = 0; i < destinations.length; i++) {
181
+ const dest = destinations[i];
182
+ if (dest === void 0) continue;
183
+ const destDir = resolveDestDir({
184
+ cwd,
185
+ src,
186
+ dest,
187
+ flatten
188
+ });
189
+ const destPath = target.rename ? renameTarget({
190
+ path: src,
191
+ fileName: parsed.base,
192
+ rename: target.rename
193
+ }) : parsed.base;
194
+ result.push({
195
+ kind: stats.isFile() ? "file" : "directory",
196
+ src,
197
+ dest: node_path.join(destDir, destPath),
198
+ renamed: Boolean(target.rename),
199
+ transformed: Boolean(target.transform),
200
+ ...target.transform && { content: typeof target.transform === "function" ? await target.transform({
201
+ fileName: parsed.base,
202
+ content: await node_fs_promises.readFile(src)
203
+ }) : target.transform }
204
+ });
205
+ }
206
+ return result;
207
+ };
208
+
209
+ const isGlobSource = (source) => source.startsWith("!") || source.includes("*") || source.includes("?") || source.includes("[") || source.includes("{");
210
+ const normalizeGlobSource = (cwd, source) => {
211
+ const negated = source.startsWith("!");
212
+ const path = negated ? source.slice(1) : source;
213
+ const pattern = node_path.isAbsolute(path) ? node_path.relative(cwd, path) : path;
214
+ return negated ? `!${pattern}` : pattern;
215
+ };
216
+ const resolveExplicitSourcePath = async (cwd, source) => {
217
+ const path = node_path.resolve(cwd, source);
218
+ try {
219
+ await node_fs_promises.stat(path);
220
+ return [path];
221
+ } catch {
222
+ return [];
223
+ }
224
+ };
225
+ const resolveGlobSourcePaths = async (cwd, sources) => {
226
+ const patterns = [];
227
+ for (let i = 0; i < sources.length; i++) {
228
+ const source = sources[i];
229
+ if (source === void 0) continue;
230
+ patterns.push(normalizeGlobSource(cwd, source));
231
+ }
232
+ return await (0, tinyglobby.glob)(patterns, {
233
+ absolute: true,
234
+ cwd,
235
+ onlyFiles: true
236
+ });
237
+ };
238
+ const resolveSourcePaths = async ({ cwd, sources }) => {
239
+ const paths = [];
240
+ const globSources = [];
241
+ for (let i = 0; i < sources.length; i++) {
242
+ const source = sources[i];
243
+ if (source === void 0) continue;
244
+ if (isGlobSource(source)) {
245
+ globSources.push(source);
246
+ continue;
247
+ }
248
+ paths.push(...await resolveExplicitSourcePath(cwd, source));
249
+ }
250
+ if (globSources.length > 0) paths.push(...await resolveGlobSourcePaths(cwd, globSources));
251
+ return paths;
252
+ };
253
+
254
+ var name = "rolldown-plugin-copy";
255
+ var version = "0.1.0";
256
+
257
+ /**
258
+ * A utility to copy files and directories.
259
+ *
260
+ * ### Example
261
+ *
262
+ * ```ts
263
+ * import { defineConfig } from "rolldown";
264
+ * import { copy } from "rolldown-plugin-copy";
265
+ *
266
+ * export default defineConfig({
267
+ * plugins: [
268
+ * copy({
269
+ * targets: [
270
+ * {
271
+ * src: "./public/static/css/index.css",
272
+ * dest: "./dist/public/static/css",
273
+ * },
274
+ * ],
275
+ * }),
276
+ * ],
277
+ * });
278
+ * ```
279
+ */
280
+ const copy = (options) => {
281
+ const opts = (0, es_toolkit.toMerged)(OPTIONS_DEFAULT, options ?? {});
282
+ let copied = false;
283
+ return {
284
+ name,
285
+ version,
286
+ [opts.hook]: async () => {
287
+ if (opts.copyOnce === true && copied === true) return void 0;
288
+ if (opts.targets.length === 0) return void 0;
289
+ const targets = [];
290
+ for (let i = 0; i < opts.targets.length; i++) {
291
+ const target = opts.targets[i];
292
+ if (target === void 0) continue;
293
+ const paths = await resolveSourcePaths({
294
+ cwd: opts.cwd,
295
+ sources: typeof target.src === "string" ? [target.src] : target.src
296
+ });
297
+ for (let j = 0; j < paths.length; j++) {
298
+ const src = paths[j];
299
+ if (src === void 0) continue;
300
+ const tg = await generateTargets({
301
+ cwd: opts.cwd,
302
+ src,
303
+ target,
304
+ flatten: opts.flatten
305
+ });
306
+ targets.push(...tg);
307
+ }
308
+ }
309
+ await copyTargets({
310
+ cwd: opts.cwd,
311
+ targets,
312
+ copySync: opts.copySync,
313
+ verbose: opts.verbose
314
+ });
315
+ copied = true;
316
+ }
317
+ };
318
+ };
319
+
320
+ var src_default = copy;
321
+
322
+ exports.copy = copy;
323
+ exports.default = src_default;
324
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["Path","Fsp","Path","Path","Fsp","Path","Fsp"],"sources":["../src/const/options.ts","../src/configs/log.ts","../src/functions/copy.ts","../src/functions/rename.ts","../src/functions/generate.ts","../src/functions/resolve.ts","../package.json","../src/plugins/copy.ts","../src/index.ts"],"sourcesContent":["import type { CompleteOptions } from \"#/@types/options\";\n\nconst OPTIONS_DEFAULT = {\n cwd: process.cwd(),\n hook: \"generateBundle\",\n copyOnce: false,\n copySync: false,\n flatten: false,\n verbose: false,\n targets: [],\n} as const satisfies CompleteOptions;\n\nexport { OPTIONS_DEFAULT };\n","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 type { GeneratedTarget } from \"#/functions/generate\";\n\nimport * as Fs from \"node:fs\";\nimport * as Fsp from \"node:fs/promises\";\nimport * as Path from \"node:path\";\n\nimport { log } from \"#/configs/log\";\n\nconst canCopyInParallel = (targets: GeneratedTarget[]): boolean => {\n const destinations: Set<string> = new Set();\n\n for (let i: number = 0; i < targets.length; i++) {\n const target: GeneratedTarget | undefined = targets[i];\n\n if (target === void 0) continue;\n\n /**\n * Raw directory copies write a whole subtree, so exact destination checks\n * cannot detect nested conflicts with other targets in parallel.\n */\n if (target.kind === \"directory\") return false;\n\n /**\n * Multiple targets writing the same path leads to conflicts, so\n * keep the original target order by falling back to sequential copies.\n */\n if (destinations.has(target.dest)) return false;\n\n destinations.add(target.dest);\n }\n\n return true;\n};\n\nconst ensureDirSync = (filePath: string): void => {\n Fs.mkdirSync(Path.dirname(filePath), {\n recursive: true,\n });\n};\n\nconst ensureDirAsync = async (filePath: string): Promise<void> => {\n await Fsp.mkdir(Path.dirname(filePath), {\n recursive: true,\n });\n};\n\ntype CopyFileOptions = {\n src: string;\n dest: string;\n copySync: boolean;\n};\n\nconst copyFile = async ({\n src,\n dest,\n copySync,\n}: CopyFileOptions): Promise<void> => {\n if (copySync) {\n ensureDirSync(dest);\n\n Fs.copyFileSync(src, dest);\n\n return void 0;\n }\n\n await ensureDirAsync(dest);\n\n await Fsp.copyFile(src, dest);\n};\n\ntype CopyDirectoryOptions = {\n src: string;\n dest: string;\n copySync: boolean;\n};\n\nconst copyDirectory = async ({\n src,\n dest,\n copySync,\n}: CopyDirectoryOptions): Promise<void> => {\n if (copySync) {\n Fs.cpSync(src, dest, {\n recursive: true,\n });\n\n return void 0;\n }\n\n await Fsp.cp(src, dest, {\n recursive: true,\n });\n};\n\nconst writeTransformed = async (target: GeneratedTarget): Promise<void> => {\n await ensureDirAsync(target.dest);\n await Fsp.writeFile(target.dest, target.content ?? \"\");\n};\n\ntype CopyTargetOptions = {\n target: GeneratedTarget;\n copySync: boolean;\n};\n\nconst copyTarget = async ({\n target,\n copySync,\n}: CopyTargetOptions): Promise<void> => {\n if (target.transformed) {\n return await writeTransformed(target);\n }\n\n if (target.kind === \"file\") {\n return await copyFile({\n src: target.src,\n dest: target.dest,\n copySync,\n });\n }\n\n return await copyDirectory({\n src: target.src,\n dest: target.dest,\n copySync,\n });\n};\n\ntype BuildLogMessageOptions = {\n cwd: string;\n target: GeneratedTarget;\n};\n\nconst buildLogMessage = ({ cwd, target }: BuildLogMessageOptions): string => {\n let message: string = `${Path.relative(cwd, target.src)} → ${target.dest}`;\n\n const flags: string[] = [];\n\n if (target.renamed) flags.push(\"R\");\n if (target.transformed) flags.push(\"T\");\n\n if (flags.length > 0) {\n message += ` [${flags.join(\",\")}]`;\n }\n\n return message;\n};\n\ntype CopyTargetsOptions = {\n cwd: string;\n targets: GeneratedTarget[];\n copySync: boolean;\n verbose: boolean;\n};\n\nconst copyTargets = async ({\n cwd,\n targets,\n copySync,\n verbose,\n}: CopyTargetsOptions): Promise<void> => {\n if (targets.length === 0) {\n if (verbose) {\n log.success(\"no items to copy\");\n console.log(\"\");\n }\n\n return void 0;\n }\n\n const logs: string[] = [];\n\n if (!copySync && canCopyInParallel(targets)) {\n const result: string[] = (\n await Promise.all(\n targets.map(\n async (\n target: GeneratedTarget,\n ): Promise<string | undefined> => {\n await copyTarget({\n target,\n copySync,\n });\n\n return verbose\n ? buildLogMessage({\n cwd,\n target,\n })\n : void 0;\n },\n ),\n )\n ).filter((item: string | undefined): item is string => item !== void 0);\n\n if (verbose) {\n for (let i: number = 0; i < result.length; i++) {\n const message: string | undefined = result[i];\n\n if (message === void 0) continue;\n\n logs.push(message);\n }\n }\n } else {\n for (let i: number = 0; i < targets.length; i++) {\n const target: GeneratedTarget | undefined = targets[i];\n\n if (target === void 0) continue;\n\n await copyTarget({\n target,\n copySync,\n });\n\n if (verbose) {\n logs.push(\n buildLogMessage({\n cwd,\n target,\n }),\n );\n }\n }\n }\n\n if (verbose) {\n for (let i: number = 0; i < logs.length; i++) {\n log.success(logs[i]);\n }\n\n console.log(\"\");\n }\n};\n\nexport type { CopyTargetsOptions };\nexport { copyTargets };\n","import type { TargetRename } from \"#/@types/target\";\n\nimport * as Path from \"node:path\";\n\ntype RenameTargetOptions = {\n path: string;\n fileName: string;\n rename: TargetRename;\n};\n\nconst renameTarget = (options: RenameTargetOptions): string => {\n const parsed: Path.ParsedPath = Path.parse(options.fileName);\n\n return typeof options.rename === \"function\"\n ? options.rename({\n path: options.path,\n name: parsed.name,\n extension: parsed.ext.replace(\".\", \"\"),\n })\n : options.rename;\n};\n\nexport { renameTarget };\n","import type * as Fs from \"node:fs\";\n\nimport type { Target, WriteFileData } from \"#/@types/target\";\n\nimport * as Fsp from \"node:fs/promises\";\nimport * as Path from \"node:path\";\n\nimport { renameTarget } from \"./rename\";\n\ntype ResolveDestDirOptions = {\n cwd: string;\n src: string;\n dest: string;\n flatten: boolean;\n};\n\nconst resolveDestDir = ({\n cwd,\n src,\n dest,\n flatten,\n}: ResolveDestDirOptions): string => {\n if (flatten) return dest;\n\n const relativeDir: string = Path.dirname(Path.relative(cwd, src));\n\n if (relativeDir === \".\") return dest;\n\n const relativeDirParts: string[] = relativeDir.split(Path.sep);\n\n return Path.join(dest, ...relativeDirParts.slice(1));\n};\n\ntype GenerateTargetsOptions = {\n cwd: string;\n src: string;\n target: Target;\n flatten: boolean;\n};\n\ntype GeneratedTargetKind = \"file\" | \"directory\";\n\ntype GeneratedTarget = {\n kind: GeneratedTargetKind;\n src: string;\n dest: string;\n renamed: boolean;\n transformed: boolean;\n content?: WriteFileData;\n};\n\nconst generateTargets = async ({\n cwd,\n src,\n target,\n flatten,\n}: GenerateTargetsOptions): Promise<GeneratedTarget[]> => {\n const stats: Fs.Stats = await Fsp.stat(src);\n\n if (target.transform && stats.isDirectory()) return [];\n\n const parsed = Path.parse(src);\n\n const destinations =\n typeof target.dest === \"string\"\n ? [\n target.dest,\n ]\n : target.dest;\n\n const result: GeneratedTarget[] = [];\n\n for (let i: number = 0; i < destinations.length; i++) {\n const dest: string | undefined = destinations[i];\n\n if (dest === void 0) continue;\n\n const destDir: string = resolveDestDir({\n cwd,\n src,\n dest,\n flatten,\n });\n\n const destPath: string = target.rename\n ? renameTarget({\n path: src,\n fileName: parsed.base,\n rename: target.rename,\n })\n : parsed.base;\n\n result.push({\n kind: stats.isFile() ? \"file\" : \"directory\",\n src,\n dest: Path.join(destDir, destPath),\n renamed: Boolean(target.rename),\n transformed: Boolean(target.transform),\n ...(target.transform && {\n content:\n typeof target.transform === \"function\"\n ? await target.transform({\n fileName: parsed.base,\n content: await Fsp.readFile(src),\n })\n : target.transform,\n }),\n });\n }\n\n return result;\n};\n\nexport type { GeneratedTarget, GeneratedTargetKind, GenerateTargetsOptions };\nexport { generateTargets };\n","import * as Fsp from \"node:fs/promises\";\nimport * as Path from \"node:path\";\n\nimport { glob } from \"tinyglobby\";\n\ntype ResolveSourcePathsOptions = {\n cwd: string;\n sources: string[];\n};\n\nconst isGlobSource = (source: string): boolean =>\n source.startsWith(\"!\") ||\n source.includes(\"*\") ||\n source.includes(\"?\") ||\n source.includes(\"[\") ||\n source.includes(\"{\");\n\nconst normalizeGlobSource = (cwd: string, source: string): string => {\n const negated: boolean = source.startsWith(\"!\");\n\n const path: string = negated ? source.slice(1) : source;\n\n const pattern: string = Path.isAbsolute(path)\n ? Path.relative(cwd, path)\n : path;\n\n return negated ? `!${pattern}` : pattern;\n};\n\nconst resolveExplicitSourcePath = async (\n cwd: string,\n source: string,\n): Promise<string[]> => {\n const path: string = Path.resolve(cwd, source);\n\n try {\n await Fsp.stat(path);\n\n return [\n path,\n ];\n } catch {\n return [];\n }\n};\n\nconst resolveGlobSourcePaths = async (\n cwd: string,\n sources: string[],\n): Promise<string[]> => {\n const patterns: string[] = [];\n\n for (let i: number = 0; i < sources.length; i++) {\n const source: string | undefined = sources[i];\n\n if (source === void 0) continue;\n\n patterns.push(normalizeGlobSource(cwd, source));\n }\n\n return await glob(patterns, {\n absolute: true,\n cwd,\n onlyFiles: true,\n });\n};\n\nconst resolveSourcePaths = async ({\n cwd,\n sources,\n}: ResolveSourcePathsOptions): Promise<string[]> => {\n const paths: string[] = [];\n const globSources: string[] = [];\n\n for (let i: number = 0; i < sources.length; i++) {\n const source: string | undefined = sources[i];\n\n if (source === void 0) continue;\n\n if (isGlobSource(source)) {\n globSources.push(source);\n continue;\n }\n\n paths.push(...(await resolveExplicitSourcePath(cwd, source)));\n }\n\n if (globSources.length > 0) {\n paths.push(...(await resolveGlobSourcePaths(cwd, globSources)));\n }\n\n return paths;\n};\n\nexport type { ResolveSourcePathsOptions };\nexport { resolveSourcePaths };\n","","import type { Plugin } from \"rolldown\";\n\nimport type { CompleteOptions, Options } from \"#/@types/options\";\nimport type { Target } from \"#/@types/target\";\nimport type { GeneratedTarget } from \"#/functions/generate\";\n\nimport { toMerged } from \"es-toolkit\";\n\nimport { OPTIONS_DEFAULT } from \"#/const/options\";\nimport { copyTargets } from \"#/functions/copy\";\nimport { generateTargets } from \"#/functions/generate\";\nimport { resolveSourcePaths } from \"#/functions/resolve\";\nimport { name, version } from \"../../package.json\";\n\n/**\n * A utility to copy files and directories.\n *\n * ### Example\n *\n * ```ts\n * import { defineConfig } from \"rolldown\";\n * import { copy } from \"rolldown-plugin-copy\";\n *\n * export default defineConfig({\n * plugins: [\n * copy({\n * targets: [\n * {\n * src: \"./public/static/css/index.css\",\n * dest: \"./dist/public/static/css\",\n * },\n * ],\n * }),\n * ],\n * });\n * ```\n */\nconst copy = (options?: Options): Plugin => {\n const opts: CompleteOptions = toMerged(OPTIONS_DEFAULT, options ?? {});\n\n let copied: boolean = false;\n\n return {\n name,\n version,\n [opts.hook]: async (): Promise<void> => {\n if (opts.copyOnce === true && copied === true) return void 0;\n\n if (opts.targets.length === 0) return void 0;\n\n const targets: GeneratedTarget[] = [];\n\n for (let i: number = 0; i < opts.targets.length; i++) {\n const target: Target | undefined = opts.targets[i];\n\n if (target === void 0) continue;\n\n const paths: string[] = await resolveSourcePaths({\n cwd: opts.cwd,\n sources:\n typeof target.src === \"string\"\n ? [\n target.src,\n ]\n : target.src,\n });\n\n for (let j: number = 0; j < paths.length; j++) {\n const src: string | undefined = paths[j];\n\n if (src === void 0) continue;\n\n const tg: GeneratedTarget[] = await generateTargets({\n cwd: opts.cwd,\n src,\n target,\n flatten: opts.flatten,\n });\n\n targets.push(...tg);\n }\n }\n\n await copyTargets({\n cwd: opts.cwd,\n targets,\n copySync: opts.copySync,\n verbose: opts.verbose,\n });\n\n copied = true;\n },\n };\n};\n\nexport { copy };\n","import { copy } from \"#/plugins/copy\";\n\nexport default copy;\n\nexport type { Options } from \"#/@types/options\";\nexport type {\n Target,\n TargetRename,\n TargetRenameOptions,\n TargetTransform,\n TargetTransformOptions,\n WriteFileData,\n} from \"#/@types/target\";\n\nexport { copy } from \"#/plugins/copy\";\n"],"mappings":"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"}
package/dist/index.mjs ADDED
@@ -0,0 +1,294 @@
1
+ import { toMerged } from "es-toolkit";
2
+ import * as Fs from "node:fs";
3
+ import * as Fsp from "node:fs/promises";
4
+ import * as Path from "node:path";
5
+ import { createConsola } from "consola";
6
+ import { glob } from "tinyglobby";
7
+
8
+ const OPTIONS_DEFAULT = {
9
+ cwd: process.cwd(),
10
+ hook: "generateBundle",
11
+ copyOnce: false,
12
+ copySync: false,
13
+ flatten: false,
14
+ verbose: false,
15
+ targets: []
16
+ };
17
+
18
+ const log = createConsola({ formatOptions: { date: false } });
19
+
20
+ const canCopyInParallel = (targets) => {
21
+ const destinations = /* @__PURE__ */ new Set();
22
+ for (let i = 0; i < targets.length; i++) {
23
+ const target = targets[i];
24
+ if (target === void 0) continue;
25
+ /**
26
+ * Raw directory copies write a whole subtree, so exact destination checks
27
+ * cannot detect nested conflicts with other targets in parallel.
28
+ */
29
+ if (target.kind === "directory") return false;
30
+ /**
31
+ * Multiple targets writing the same path leads to conflicts, so
32
+ * keep the original target order by falling back to sequential copies.
33
+ */
34
+ if (destinations.has(target.dest)) return false;
35
+ destinations.add(target.dest);
36
+ }
37
+ return true;
38
+ };
39
+ const ensureDirSync = (filePath) => {
40
+ Fs.mkdirSync(Path.dirname(filePath), { recursive: true });
41
+ };
42
+ const ensureDirAsync = async (filePath) => {
43
+ await Fsp.mkdir(Path.dirname(filePath), { recursive: true });
44
+ };
45
+ const copyFile = async ({ src, dest, copySync }) => {
46
+ if (copySync) {
47
+ ensureDirSync(dest);
48
+ Fs.copyFileSync(src, dest);
49
+ return;
50
+ }
51
+ await ensureDirAsync(dest);
52
+ await Fsp.copyFile(src, dest);
53
+ };
54
+ const copyDirectory = async ({ src, dest, copySync }) => {
55
+ if (copySync) {
56
+ Fs.cpSync(src, dest, { recursive: true });
57
+ return;
58
+ }
59
+ await Fsp.cp(src, dest, { recursive: true });
60
+ };
61
+ const writeTransformed = async (target) => {
62
+ await ensureDirAsync(target.dest);
63
+ await Fsp.writeFile(target.dest, target.content ?? "");
64
+ };
65
+ const copyTarget = async ({ target, copySync }) => {
66
+ if (target.transformed) return await writeTransformed(target);
67
+ if (target.kind === "file") return await copyFile({
68
+ src: target.src,
69
+ dest: target.dest,
70
+ copySync
71
+ });
72
+ return await copyDirectory({
73
+ src: target.src,
74
+ dest: target.dest,
75
+ copySync
76
+ });
77
+ };
78
+ const buildLogMessage = ({ cwd, target }) => {
79
+ let message = `${Path.relative(cwd, target.src)} → ${target.dest}`;
80
+ const flags = [];
81
+ if (target.renamed) flags.push("R");
82
+ if (target.transformed) flags.push("T");
83
+ if (flags.length > 0) message += ` [${flags.join(",")}]`;
84
+ return message;
85
+ };
86
+ const copyTargets = async ({ cwd, targets, copySync, verbose }) => {
87
+ if (targets.length === 0) {
88
+ if (verbose) {
89
+ log.success("no items to copy");
90
+ console.log("");
91
+ }
92
+ return;
93
+ }
94
+ const logs = [];
95
+ if (!copySync && canCopyInParallel(targets)) {
96
+ const result = (await Promise.all(targets.map(async (target) => {
97
+ await copyTarget({
98
+ target,
99
+ copySync
100
+ });
101
+ return verbose ? buildLogMessage({
102
+ cwd,
103
+ target
104
+ }) : void 0;
105
+ }))).filter((item) => item !== void 0);
106
+ if (verbose) for (let i = 0; i < result.length; i++) {
107
+ const message = result[i];
108
+ if (message === void 0) continue;
109
+ logs.push(message);
110
+ }
111
+ } else for (let i = 0; i < targets.length; i++) {
112
+ const target = targets[i];
113
+ if (target === void 0) continue;
114
+ await copyTarget({
115
+ target,
116
+ copySync
117
+ });
118
+ if (verbose) logs.push(buildLogMessage({
119
+ cwd,
120
+ target
121
+ }));
122
+ }
123
+ if (verbose) {
124
+ for (let i = 0; i < logs.length; i++) log.success(logs[i]);
125
+ console.log("");
126
+ }
127
+ };
128
+
129
+ const renameTarget = (options) => {
130
+ const parsed = Path.parse(options.fileName);
131
+ return typeof options.rename === "function" ? options.rename({
132
+ path: options.path,
133
+ name: parsed.name,
134
+ extension: parsed.ext.replace(".", "")
135
+ }) : options.rename;
136
+ };
137
+
138
+ const resolveDestDir = ({ cwd, src, dest, flatten }) => {
139
+ if (flatten) return dest;
140
+ const relativeDir = Path.dirname(Path.relative(cwd, src));
141
+ if (relativeDir === ".") return dest;
142
+ const relativeDirParts = relativeDir.split(Path.sep);
143
+ return Path.join(dest, ...relativeDirParts.slice(1));
144
+ };
145
+ const generateTargets = async ({ cwd, src, target, flatten }) => {
146
+ const stats = await Fsp.stat(src);
147
+ if (target.transform && stats.isDirectory()) return [];
148
+ const parsed = Path.parse(src);
149
+ const destinations = typeof target.dest === "string" ? [target.dest] : target.dest;
150
+ const result = [];
151
+ for (let i = 0; i < destinations.length; i++) {
152
+ const dest = destinations[i];
153
+ if (dest === void 0) continue;
154
+ const destDir = resolveDestDir({
155
+ cwd,
156
+ src,
157
+ dest,
158
+ flatten
159
+ });
160
+ const destPath = target.rename ? renameTarget({
161
+ path: src,
162
+ fileName: parsed.base,
163
+ rename: target.rename
164
+ }) : parsed.base;
165
+ result.push({
166
+ kind: stats.isFile() ? "file" : "directory",
167
+ src,
168
+ dest: Path.join(destDir, destPath),
169
+ renamed: Boolean(target.rename),
170
+ transformed: Boolean(target.transform),
171
+ ...target.transform && { content: typeof target.transform === "function" ? await target.transform({
172
+ fileName: parsed.base,
173
+ content: await Fsp.readFile(src)
174
+ }) : target.transform }
175
+ });
176
+ }
177
+ return result;
178
+ };
179
+
180
+ const isGlobSource = (source) => source.startsWith("!") || source.includes("*") || source.includes("?") || source.includes("[") || source.includes("{");
181
+ const normalizeGlobSource = (cwd, source) => {
182
+ const negated = source.startsWith("!");
183
+ const path = negated ? source.slice(1) : source;
184
+ const pattern = Path.isAbsolute(path) ? Path.relative(cwd, path) : path;
185
+ return negated ? `!${pattern}` : pattern;
186
+ };
187
+ const resolveExplicitSourcePath = async (cwd, source) => {
188
+ const path = Path.resolve(cwd, source);
189
+ try {
190
+ await Fsp.stat(path);
191
+ return [path];
192
+ } catch {
193
+ return [];
194
+ }
195
+ };
196
+ const resolveGlobSourcePaths = async (cwd, sources) => {
197
+ const patterns = [];
198
+ for (let i = 0; i < sources.length; i++) {
199
+ const source = sources[i];
200
+ if (source === void 0) continue;
201
+ patterns.push(normalizeGlobSource(cwd, source));
202
+ }
203
+ return await glob(patterns, {
204
+ absolute: true,
205
+ cwd,
206
+ onlyFiles: true
207
+ });
208
+ };
209
+ const resolveSourcePaths = async ({ cwd, sources }) => {
210
+ const paths = [];
211
+ const globSources = [];
212
+ for (let i = 0; i < sources.length; i++) {
213
+ const source = sources[i];
214
+ if (source === void 0) continue;
215
+ if (isGlobSource(source)) {
216
+ globSources.push(source);
217
+ continue;
218
+ }
219
+ paths.push(...await resolveExplicitSourcePath(cwd, source));
220
+ }
221
+ if (globSources.length > 0) paths.push(...await resolveGlobSourcePaths(cwd, globSources));
222
+ return paths;
223
+ };
224
+
225
+ var name = "rolldown-plugin-copy";
226
+ var version = "0.1.0";
227
+
228
+ /**
229
+ * A utility to copy files and directories.
230
+ *
231
+ * ### Example
232
+ *
233
+ * ```ts
234
+ * import { defineConfig } from "rolldown";
235
+ * import { copy } from "rolldown-plugin-copy";
236
+ *
237
+ * export default defineConfig({
238
+ * plugins: [
239
+ * copy({
240
+ * targets: [
241
+ * {
242
+ * src: "./public/static/css/index.css",
243
+ * dest: "./dist/public/static/css",
244
+ * },
245
+ * ],
246
+ * }),
247
+ * ],
248
+ * });
249
+ * ```
250
+ */
251
+ const copy = (options) => {
252
+ const opts = toMerged(OPTIONS_DEFAULT, options ?? {});
253
+ let copied = false;
254
+ return {
255
+ name,
256
+ version,
257
+ [opts.hook]: async () => {
258
+ if (opts.copyOnce === true && copied === true) return void 0;
259
+ if (opts.targets.length === 0) return void 0;
260
+ const targets = [];
261
+ for (let i = 0; i < opts.targets.length; i++) {
262
+ const target = opts.targets[i];
263
+ if (target === void 0) continue;
264
+ const paths = await resolveSourcePaths({
265
+ cwd: opts.cwd,
266
+ sources: typeof target.src === "string" ? [target.src] : target.src
267
+ });
268
+ for (let j = 0; j < paths.length; j++) {
269
+ const src = paths[j];
270
+ if (src === void 0) continue;
271
+ const tg = await generateTargets({
272
+ cwd: opts.cwd,
273
+ src,
274
+ target,
275
+ flatten: opts.flatten
276
+ });
277
+ targets.push(...tg);
278
+ }
279
+ }
280
+ await copyTargets({
281
+ cwd: opts.cwd,
282
+ targets,
283
+ copySync: opts.copySync,
284
+ verbose: opts.verbose
285
+ });
286
+ copied = true;
287
+ }
288
+ };
289
+ };
290
+
291
+ var src_default = copy;
292
+
293
+ export { copy, src_default as default };
294
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/const/options.ts","../src/configs/log.ts","../src/functions/copy.ts","../src/functions/rename.ts","../src/functions/generate.ts","../src/functions/resolve.ts","../package.json","../src/plugins/copy.ts","../src/index.ts"],"sourcesContent":["import type { CompleteOptions } from \"#/@types/options\";\n\nconst OPTIONS_DEFAULT = {\n cwd: process.cwd(),\n hook: \"generateBundle\",\n copyOnce: false,\n copySync: false,\n flatten: false,\n verbose: false,\n targets: [],\n} as const satisfies CompleteOptions;\n\nexport { OPTIONS_DEFAULT };\n","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 type { GeneratedTarget } from \"#/functions/generate\";\n\nimport * as Fs from \"node:fs\";\nimport * as Fsp from \"node:fs/promises\";\nimport * as Path from \"node:path\";\n\nimport { log } from \"#/configs/log\";\n\nconst canCopyInParallel = (targets: GeneratedTarget[]): boolean => {\n const destinations: Set<string> = new Set();\n\n for (let i: number = 0; i < targets.length; i++) {\n const target: GeneratedTarget | undefined = targets[i];\n\n if (target === void 0) continue;\n\n /**\n * Raw directory copies write a whole subtree, so exact destination checks\n * cannot detect nested conflicts with other targets in parallel.\n */\n if (target.kind === \"directory\") return false;\n\n /**\n * Multiple targets writing the same path leads to conflicts, so\n * keep the original target order by falling back to sequential copies.\n */\n if (destinations.has(target.dest)) return false;\n\n destinations.add(target.dest);\n }\n\n return true;\n};\n\nconst ensureDirSync = (filePath: string): void => {\n Fs.mkdirSync(Path.dirname(filePath), {\n recursive: true,\n });\n};\n\nconst ensureDirAsync = async (filePath: string): Promise<void> => {\n await Fsp.mkdir(Path.dirname(filePath), {\n recursive: true,\n });\n};\n\ntype CopyFileOptions = {\n src: string;\n dest: string;\n copySync: boolean;\n};\n\nconst copyFile = async ({\n src,\n dest,\n copySync,\n}: CopyFileOptions): Promise<void> => {\n if (copySync) {\n ensureDirSync(dest);\n\n Fs.copyFileSync(src, dest);\n\n return void 0;\n }\n\n await ensureDirAsync(dest);\n\n await Fsp.copyFile(src, dest);\n};\n\ntype CopyDirectoryOptions = {\n src: string;\n dest: string;\n copySync: boolean;\n};\n\nconst copyDirectory = async ({\n src,\n dest,\n copySync,\n}: CopyDirectoryOptions): Promise<void> => {\n if (copySync) {\n Fs.cpSync(src, dest, {\n recursive: true,\n });\n\n return void 0;\n }\n\n await Fsp.cp(src, dest, {\n recursive: true,\n });\n};\n\nconst writeTransformed = async (target: GeneratedTarget): Promise<void> => {\n await ensureDirAsync(target.dest);\n await Fsp.writeFile(target.dest, target.content ?? \"\");\n};\n\ntype CopyTargetOptions = {\n target: GeneratedTarget;\n copySync: boolean;\n};\n\nconst copyTarget = async ({\n target,\n copySync,\n}: CopyTargetOptions): Promise<void> => {\n if (target.transformed) {\n return await writeTransformed(target);\n }\n\n if (target.kind === \"file\") {\n return await copyFile({\n src: target.src,\n dest: target.dest,\n copySync,\n });\n }\n\n return await copyDirectory({\n src: target.src,\n dest: target.dest,\n copySync,\n });\n};\n\ntype BuildLogMessageOptions = {\n cwd: string;\n target: GeneratedTarget;\n};\n\nconst buildLogMessage = ({ cwd, target }: BuildLogMessageOptions): string => {\n let message: string = `${Path.relative(cwd, target.src)} → ${target.dest}`;\n\n const flags: string[] = [];\n\n if (target.renamed) flags.push(\"R\");\n if (target.transformed) flags.push(\"T\");\n\n if (flags.length > 0) {\n message += ` [${flags.join(\",\")}]`;\n }\n\n return message;\n};\n\ntype CopyTargetsOptions = {\n cwd: string;\n targets: GeneratedTarget[];\n copySync: boolean;\n verbose: boolean;\n};\n\nconst copyTargets = async ({\n cwd,\n targets,\n copySync,\n verbose,\n}: CopyTargetsOptions): Promise<void> => {\n if (targets.length === 0) {\n if (verbose) {\n log.success(\"no items to copy\");\n console.log(\"\");\n }\n\n return void 0;\n }\n\n const logs: string[] = [];\n\n if (!copySync && canCopyInParallel(targets)) {\n const result: string[] = (\n await Promise.all(\n targets.map(\n async (\n target: GeneratedTarget,\n ): Promise<string | undefined> => {\n await copyTarget({\n target,\n copySync,\n });\n\n return verbose\n ? buildLogMessage({\n cwd,\n target,\n })\n : void 0;\n },\n ),\n )\n ).filter((item: string | undefined): item is string => item !== void 0);\n\n if (verbose) {\n for (let i: number = 0; i < result.length; i++) {\n const message: string | undefined = result[i];\n\n if (message === void 0) continue;\n\n logs.push(message);\n }\n }\n } else {\n for (let i: number = 0; i < targets.length; i++) {\n const target: GeneratedTarget | undefined = targets[i];\n\n if (target === void 0) continue;\n\n await copyTarget({\n target,\n copySync,\n });\n\n if (verbose) {\n logs.push(\n buildLogMessage({\n cwd,\n target,\n }),\n );\n }\n }\n }\n\n if (verbose) {\n for (let i: number = 0; i < logs.length; i++) {\n log.success(logs[i]);\n }\n\n console.log(\"\");\n }\n};\n\nexport type { CopyTargetsOptions };\nexport { copyTargets };\n","import type { TargetRename } from \"#/@types/target\";\n\nimport * as Path from \"node:path\";\n\ntype RenameTargetOptions = {\n path: string;\n fileName: string;\n rename: TargetRename;\n};\n\nconst renameTarget = (options: RenameTargetOptions): string => {\n const parsed: Path.ParsedPath = Path.parse(options.fileName);\n\n return typeof options.rename === \"function\"\n ? options.rename({\n path: options.path,\n name: parsed.name,\n extension: parsed.ext.replace(\".\", \"\"),\n })\n : options.rename;\n};\n\nexport { renameTarget };\n","import type * as Fs from \"node:fs\";\n\nimport type { Target, WriteFileData } from \"#/@types/target\";\n\nimport * as Fsp from \"node:fs/promises\";\nimport * as Path from \"node:path\";\n\nimport { renameTarget } from \"./rename\";\n\ntype ResolveDestDirOptions = {\n cwd: string;\n src: string;\n dest: string;\n flatten: boolean;\n};\n\nconst resolveDestDir = ({\n cwd,\n src,\n dest,\n flatten,\n}: ResolveDestDirOptions): string => {\n if (flatten) return dest;\n\n const relativeDir: string = Path.dirname(Path.relative(cwd, src));\n\n if (relativeDir === \".\") return dest;\n\n const relativeDirParts: string[] = relativeDir.split(Path.sep);\n\n return Path.join(dest, ...relativeDirParts.slice(1));\n};\n\ntype GenerateTargetsOptions = {\n cwd: string;\n src: string;\n target: Target;\n flatten: boolean;\n};\n\ntype GeneratedTargetKind = \"file\" | \"directory\";\n\ntype GeneratedTarget = {\n kind: GeneratedTargetKind;\n src: string;\n dest: string;\n renamed: boolean;\n transformed: boolean;\n content?: WriteFileData;\n};\n\nconst generateTargets = async ({\n cwd,\n src,\n target,\n flatten,\n}: GenerateTargetsOptions): Promise<GeneratedTarget[]> => {\n const stats: Fs.Stats = await Fsp.stat(src);\n\n if (target.transform && stats.isDirectory()) return [];\n\n const parsed = Path.parse(src);\n\n const destinations =\n typeof target.dest === \"string\"\n ? [\n target.dest,\n ]\n : target.dest;\n\n const result: GeneratedTarget[] = [];\n\n for (let i: number = 0; i < destinations.length; i++) {\n const dest: string | undefined = destinations[i];\n\n if (dest === void 0) continue;\n\n const destDir: string = resolveDestDir({\n cwd,\n src,\n dest,\n flatten,\n });\n\n const destPath: string = target.rename\n ? renameTarget({\n path: src,\n fileName: parsed.base,\n rename: target.rename,\n })\n : parsed.base;\n\n result.push({\n kind: stats.isFile() ? \"file\" : \"directory\",\n src,\n dest: Path.join(destDir, destPath),\n renamed: Boolean(target.rename),\n transformed: Boolean(target.transform),\n ...(target.transform && {\n content:\n typeof target.transform === \"function\"\n ? await target.transform({\n fileName: parsed.base,\n content: await Fsp.readFile(src),\n })\n : target.transform,\n }),\n });\n }\n\n return result;\n};\n\nexport type { GeneratedTarget, GeneratedTargetKind, GenerateTargetsOptions };\nexport { generateTargets };\n","import * as Fsp from \"node:fs/promises\";\nimport * as Path from \"node:path\";\n\nimport { glob } from \"tinyglobby\";\n\ntype ResolveSourcePathsOptions = {\n cwd: string;\n sources: string[];\n};\n\nconst isGlobSource = (source: string): boolean =>\n source.startsWith(\"!\") ||\n source.includes(\"*\") ||\n source.includes(\"?\") ||\n source.includes(\"[\") ||\n source.includes(\"{\");\n\nconst normalizeGlobSource = (cwd: string, source: string): string => {\n const negated: boolean = source.startsWith(\"!\");\n\n const path: string = negated ? source.slice(1) : source;\n\n const pattern: string = Path.isAbsolute(path)\n ? Path.relative(cwd, path)\n : path;\n\n return negated ? `!${pattern}` : pattern;\n};\n\nconst resolveExplicitSourcePath = async (\n cwd: string,\n source: string,\n): Promise<string[]> => {\n const path: string = Path.resolve(cwd, source);\n\n try {\n await Fsp.stat(path);\n\n return [\n path,\n ];\n } catch {\n return [];\n }\n};\n\nconst resolveGlobSourcePaths = async (\n cwd: string,\n sources: string[],\n): Promise<string[]> => {\n const patterns: string[] = [];\n\n for (let i: number = 0; i < sources.length; i++) {\n const source: string | undefined = sources[i];\n\n if (source === void 0) continue;\n\n patterns.push(normalizeGlobSource(cwd, source));\n }\n\n return await glob(patterns, {\n absolute: true,\n cwd,\n onlyFiles: true,\n });\n};\n\nconst resolveSourcePaths = async ({\n cwd,\n sources,\n}: ResolveSourcePathsOptions): Promise<string[]> => {\n const paths: string[] = [];\n const globSources: string[] = [];\n\n for (let i: number = 0; i < sources.length; i++) {\n const source: string | undefined = sources[i];\n\n if (source === void 0) continue;\n\n if (isGlobSource(source)) {\n globSources.push(source);\n continue;\n }\n\n paths.push(...(await resolveExplicitSourcePath(cwd, source)));\n }\n\n if (globSources.length > 0) {\n paths.push(...(await resolveGlobSourcePaths(cwd, globSources)));\n }\n\n return paths;\n};\n\nexport type { ResolveSourcePathsOptions };\nexport { resolveSourcePaths };\n","","import type { Plugin } from \"rolldown\";\n\nimport type { CompleteOptions, Options } from \"#/@types/options\";\nimport type { Target } from \"#/@types/target\";\nimport type { GeneratedTarget } from \"#/functions/generate\";\n\nimport { toMerged } from \"es-toolkit\";\n\nimport { OPTIONS_DEFAULT } from \"#/const/options\";\nimport { copyTargets } from \"#/functions/copy\";\nimport { generateTargets } from \"#/functions/generate\";\nimport { resolveSourcePaths } from \"#/functions/resolve\";\nimport { name, version } from \"../../package.json\";\n\n/**\n * A utility to copy files and directories.\n *\n * ### Example\n *\n * ```ts\n * import { defineConfig } from \"rolldown\";\n * import { copy } from \"rolldown-plugin-copy\";\n *\n * export default defineConfig({\n * plugins: [\n * copy({\n * targets: [\n * {\n * src: \"./public/static/css/index.css\",\n * dest: \"./dist/public/static/css\",\n * },\n * ],\n * }),\n * ],\n * });\n * ```\n */\nconst copy = (options?: Options): Plugin => {\n const opts: CompleteOptions = toMerged(OPTIONS_DEFAULT, options ?? {});\n\n let copied: boolean = false;\n\n return {\n name,\n version,\n [opts.hook]: async (): Promise<void> => {\n if (opts.copyOnce === true && copied === true) return void 0;\n\n if (opts.targets.length === 0) return void 0;\n\n const targets: GeneratedTarget[] = [];\n\n for (let i: number = 0; i < opts.targets.length; i++) {\n const target: Target | undefined = opts.targets[i];\n\n if (target === void 0) continue;\n\n const paths: string[] = await resolveSourcePaths({\n cwd: opts.cwd,\n sources:\n typeof target.src === \"string\"\n ? [\n target.src,\n ]\n : target.src,\n });\n\n for (let j: number = 0; j < paths.length; j++) {\n const src: string | undefined = paths[j];\n\n if (src === void 0) continue;\n\n const tg: GeneratedTarget[] = await generateTargets({\n cwd: opts.cwd,\n src,\n target,\n flatten: opts.flatten,\n });\n\n targets.push(...tg);\n }\n }\n\n await copyTargets({\n cwd: opts.cwd,\n targets,\n copySync: opts.copySync,\n verbose: opts.verbose,\n });\n\n copied = true;\n },\n };\n};\n\nexport { copy };\n","import { copy } from \"#/plugins/copy\";\n\nexport default copy;\n\nexport type { Options } from \"#/@types/options\";\nexport type {\n Target,\n TargetRename,\n TargetRenameOptions,\n TargetTransform,\n TargetTransformOptions,\n WriteFileData,\n} from \"#/@types/target\";\n\nexport { copy } from \"#/plugins/copy\";\n"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,77 @@
1
+ {
2
+ "$schema": "https://raw.githubusercontent.com/vitejs/vite-plugin-registry/refs/heads/main/data/schema/extended-package-json.schema.json",
3
+ "name": "rolldown-plugin-copy",
4
+ "version": "0.1.0",
5
+ "description": "A utility to copy files and directories",
6
+ "keywords": [
7
+ "rolldown-plugin-copy",
8
+ "rolldown-plugin",
9
+ "rolldown",
10
+ "plugin",
11
+ "copy",
12
+ "development",
13
+ "ts",
14
+ "typescript",
15
+ "js",
16
+ "javascript"
17
+ ],
18
+ "homepage": "https://github.com/alpheusday/rolldown-plugin-copy",
19
+ "bugs": "https://github.com/alpheusday/rolldown-plugin-copy/issues",
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "https://github.com/alpheusday/rolldown-plugin-copy.git",
23
+ "directory": "package"
24
+ },
25
+ "license": "MIT",
26
+ "author": {
27
+ "name": "Alpheus",
28
+ "email": "contact@alphe.us"
29
+ },
30
+ "exports": {
31
+ ".": {
32
+ "types": "./dist/index.d.ts",
33
+ "import": "./dist/index.mjs",
34
+ "require": "./dist/index.js"
35
+ },
36
+ "./package.json": "./package.json"
37
+ },
38
+ "main": "./dist/index.js",
39
+ "module": "./dist/index.mjs",
40
+ "types": "./dist/index.d.ts",
41
+ "files": [
42
+ "dist"
43
+ ],
44
+ "dependencies": {
45
+ "consola": "^3.4.0",
46
+ "es-toolkit": "^1.40.0",
47
+ "tinyglobby": "~0.2.16",
48
+ "ts-vista": "~0.2.3"
49
+ },
50
+ "devDependencies": {
51
+ "@types/node": "^22.19.0",
52
+ "rolldown": "1.0.0-rc.18"
53
+ },
54
+ "peerDependencies": {
55
+ "@types/node": "*"
56
+ },
57
+ "peerDependenciesMeta": {
58
+ "@types/node": {
59
+ "optional": true
60
+ }
61
+ },
62
+ "compatiblePackages": {
63
+ "schemaVersion": 1,
64
+ "rollup": {
65
+ "type": "compatible",
66
+ "versions": "^4.0.0"
67
+ },
68
+ "rolldown": {
69
+ "type": "compatible",
70
+ "versions": "^1.0.0"
71
+ },
72
+ "vite": {
73
+ "type": "compatible",
74
+ "versions": "^7.0.0 || ^8.0.0"
75
+ }
76
+ }
77
+ }