|
| 1 | +// Copyright 2018-2025 the Deno authors. MIT license. |
| 2 | + |
| 3 | +import { getNodeFs, getNodeOs, getNodePath, isDeno } from "./_utils.ts"; |
| 4 | +import type { MakeTempOptions } from "./unstable_types.ts"; |
| 5 | +import { mapError } from "./_map_error.ts"; |
| 6 | + |
| 7 | +/** |
| 8 | + * Creates a new temporary directory in the default directory for temporary |
| 9 | + * files, unless `dir` is specified. Other optional options include |
| 10 | + * prefixing and suffixing the directory name with `prefix` and `suffix` |
| 11 | + * respectively. |
| 12 | + * |
| 13 | + * This call resolves to the full path to the newly created directory. |
| 14 | + * |
| 15 | + * Multiple programs calling this function simultaneously will create different |
| 16 | + * directories. It is the caller's responsibility to remove the directory when |
| 17 | + * no longer needed. |
| 18 | + * |
| 19 | + * Requires `allow-write` permission. |
| 20 | + * |
| 21 | + * @example Usage |
| 22 | + * ```ts ignore |
| 23 | + * import { makeTempDir } from "@std/unstable-make-temp-dir"; |
| 24 | + * const tempDirName0 = await makeTempDir(); // e.g. /tmp/2894ea76 |
| 25 | + * const tempDirName1 = await makeTempDir({ prefix: 'my_temp' }); // e.g. /tmp/my_temp339c944d |
| 26 | + * ``` |
| 27 | + * |
| 28 | + * @tags allow-write |
| 29 | + * |
| 30 | + * @param options The options specified when creating a temporary directory. |
| 31 | + * @returns A promise that resolves to a path to the temporary directory. |
| 32 | + */ |
| 33 | +export async function makeTempDir(options?: MakeTempOptions): Promise<string> { |
| 34 | + if (isDeno) { |
| 35 | + return Deno.makeTempDir({ ...options }); |
| 36 | + } else { |
| 37 | + const { |
| 38 | + dir = undefined, |
| 39 | + prefix = undefined, |
| 40 | + suffix = undefined, |
| 41 | + } = options ?? {}; |
| 42 | + |
| 43 | + try { |
| 44 | + const { mkdtemp, rename } = getNodeFs().promises; |
| 45 | + const { tmpdir } = getNodeOs(); |
| 46 | + const { join, sep } = getNodePath(); |
| 47 | + |
| 48 | + if (!options) { |
| 49 | + return await mkdtemp(join(tmpdir(), sep)); |
| 50 | + } |
| 51 | + |
| 52 | + let prependPath = tmpdir(); |
| 53 | + if (dir != null) { |
| 54 | + prependPath = typeof dir === "string" ? dir : "."; |
| 55 | + if (prependPath === "") { |
| 56 | + prependPath = "."; |
| 57 | + } |
| 58 | + } |
| 59 | + |
| 60 | + if (prefix != null && typeof prefix === "string") { |
| 61 | + prependPath = join(prependPath, prefix || sep); |
| 62 | + } else { |
| 63 | + prependPath = join(prependPath, sep); |
| 64 | + } |
| 65 | + |
| 66 | + if (suffix != null && typeof suffix === "string") { |
| 67 | + const tempPath = await mkdtemp(prependPath); |
| 68 | + const combinedTempPath = "".concat(tempPath, suffix); |
| 69 | + await rename(tempPath, combinedTempPath); |
| 70 | + return combinedTempPath; |
| 71 | + } |
| 72 | + |
| 73 | + return await mkdtemp(prependPath); |
| 74 | + } catch (error) { |
| 75 | + throw mapError(error); |
| 76 | + } |
| 77 | + } |
| 78 | +} |
| 79 | + |
| 80 | +/** |
| 81 | + * Synchronously creates a new temporary directory in the default directory |
| 82 | + * for temporary files, unless `dir` is specified. Other optional options |
| 83 | + * include prefixing and suffixing the directory name with `prefix` and |
| 84 | + * `suffix` respectively. |
| 85 | + * |
| 86 | + * The full path to the newly created directory is returned. |
| 87 | + * |
| 88 | + * Multiple programs calling this function simultaneously will create different |
| 89 | + * directories. It is the caller's responsibility to remove the directory when |
| 90 | + * no longer needed. |
| 91 | + * |
| 92 | + * Requires `allow-write` permission. |
| 93 | + * |
| 94 | + * @example Usage |
| 95 | + * ```ts ignore |
| 96 | + * import { makeTempDirSync } from "@std/fs/unstable-make-temp-dir"; |
| 97 | + * const tempDirName0 = makeTempDirSync(); // e.g. /tmp/2894ea76 |
| 98 | + * const tempDirName1 = makeTempDirSync({ prefix: 'my_temp' }); // e.g. /tmp/my_temp339c944d |
| 99 | + * ``` |
| 100 | + * |
| 101 | + * @tags allow-write |
| 102 | + * |
| 103 | + * @param options The options specified when creating a temporary directory. |
| 104 | + * @returns The path of the temporary directory. |
| 105 | + */ |
| 106 | +export function makeTempDirSync(options?: MakeTempOptions): string { |
| 107 | + if (isDeno) { |
| 108 | + return Deno.makeTempDirSync({ ...options }); |
| 109 | + } else { |
| 110 | + const { |
| 111 | + dir = undefined, |
| 112 | + prefix = undefined, |
| 113 | + suffix = undefined, |
| 114 | + } = options ?? {}; |
| 115 | + |
| 116 | + try { |
| 117 | + const { mkdtempSync, renameSync } = getNodeFs(); |
| 118 | + const { tmpdir } = getNodeOs(); |
| 119 | + const { join, sep } = getNodePath(); |
| 120 | + |
| 121 | + if (!options) { |
| 122 | + return mkdtempSync(join(tmpdir(), sep)); |
| 123 | + } |
| 124 | + |
| 125 | + let prependPath = tmpdir(); |
| 126 | + if (dir != null) { |
| 127 | + prependPath = typeof dir === "string" ? dir : "."; |
| 128 | + if (prependPath === "") { |
| 129 | + prependPath = "."; |
| 130 | + } |
| 131 | + } |
| 132 | + |
| 133 | + if (prefix != null && typeof prefix === "string") { |
| 134 | + prependPath = join(prependPath, prefix || sep); |
| 135 | + } else { |
| 136 | + prependPath = join(prependPath, sep); |
| 137 | + } |
| 138 | + |
| 139 | + if (suffix != null && typeof prefix === "string") { |
| 140 | + const tempPath = mkdtempSync(prependPath); |
| 141 | + const combinedTempPath = "".concat(tempPath, suffix); |
| 142 | + renameSync(tempPath, combinedTempPath); |
| 143 | + return combinedTempPath; |
| 144 | + } |
| 145 | + |
| 146 | + return mkdtempSync(prependPath); |
| 147 | + } catch (error) { |
| 148 | + throw mapError(error); |
| 149 | + } |
| 150 | + } |
| 151 | +} |
0 commit comments