11import type { WatchOptions } from 'chokidar'
22
33type MaybePromise < T > = T | Promise < T >
4+ type WithRequiredSingleKey < T , K extends keyof T > = {
5+ [ P in K ] -?: Required < T [ P ] >
6+ } & T
7+
8+ type OptionalRenameObject = { stripBase ?: number | true ; name ?: string }
9+ export type RenameObject =
10+ | WithRequiredSingleKey < OptionalRenameObject , 'stripBase' >
11+ | WithRequiredSingleKey < OptionalRenameObject , 'name' >
412
513export type RenameFunc = (
614 fileName : string ,
715 fileExtension : string ,
816 fullPath : string ,
9- ) => MaybePromise < string >
10-
11- export type RenameObject = { stripBase : number | true }
17+ ) => MaybePromise < string | RenameObject >
1218
1319/**
1420 * @param content content of file
@@ -46,18 +52,23 @@ export type Target = {
4652 /**
4753 * Rename the output file.
4854 *
49- * When a string is provided, the matched file is renamed to that string.
55+ * When a string is provided, it is a shorthand for `{ name: string }` .
5056 *
51- * When an object `{ stripBase: number | true }` is provided, the given number
52- * of leading directory segments from the matched path are stripped from the
53- * destination. When `true`, all directory segments are stripped (equivalent to
54- * flat copy).
57+ * When an object is provided:
58+ * - `name`: replaces the file's basename (filename + extension).
59+ * - `stripBase`: the given number of leading directory segments from the matched
60+ * path are stripped from the destination. When `true`, all directory segments
61+ * are stripped (equivalent to flat copy).
62+ * - When both are provided, `stripBase` is applied first, then `name` replaces
63+ * the basename.
5564 *
5665 * When a function is provided, it receives `(fileName, fileExtension, fullPath)`
57- * and should return the new file name.
58- * The returned value is joined with the resolved `dest` directory using
59- * `path.join`, so it can include path segments (e.g. `subdir/file.txt`) or
60- * `../` traversals to restructure the output.
66+ * and should return the new file name or a `RenameObject`.
67+ * When a string is returned, it is joined with the resolved `dest` directory
68+ * using `path.join`, so it can include path segments (e.g. `subdir/file.txt`)
69+ * or `../` traversals to restructure the output.
70+ * When a `RenameObject` is returned, it is applied the same way as the object
71+ * form above.
6172 *
6273 * @example
6374 * ```js
@@ -69,6 +80,11 @@ export type Target = {
6980 * { src: 'src/pages/**\/*.html', dest: 'dist/', rename: { stripBase: true } }
7081 * // Copies ../../src/pages/events/test.html to dist/test.html
7182 * { src: '../../src/pages/**\/*.html', dest: 'dist/', rename: { stripBase: true } }
83+ * // Copies foo.txt to dist/newname.txt (name only)
84+ * { src: 'foo.txt', dest: 'dist/', rename: { name: 'newname.txt' } }
85+ * // Copies src/pages/events/test.html to dist/events/newname.txt (stripBase + name)
86+ * { src: 'src/pages/**\/*.html', dest: 'dist/', rename: { stripBase: 2, name: 'newname.txt' } }
87+ *
7288 * // Copies src/pages/events/test.html to dist/src/pages/events/test2.html
7389 * { src: 'src/pages/**\/*.html', dest: 'dist/', rename: (name, ext) => `${name}2.${ext}` }
7490 * // Copies src/pages/events/test.html to dist/pages/events/test.html
0 commit comments