-
Notifications
You must be signed in to change notification settings - Fork 0
/
write.ts
69 lines (62 loc) · 2.28 KB
/
write.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import fs from 'fs-extra';
import path from 'path';
import expose, { TExposedOverload } from '~/utils/expose';
import { IFsWriteOptions } from './types';
import { exists, absolute } from '~/utils/file';
import confirm from '~/utils/confirm';
import logger from '~/utils/logger';
import { open } from '~/utils/errors';
export default expose(write) as TExposedOverload<
typeof write,
| [string]
| [string, string | (() => string | Promise<string>)]
| [string, IFsWriteOptions]
| [string, string | (() => string | Promise<string>), IFsWriteOptions]
>;
function write(
file: string,
raw?: string | (() => string | Promise<string>)
): () => Promise<void>;
function write(file: string, options?: IFsWriteOptions): () => Promise<void>;
function write(
file: string,
raw: string | (() => string | Promise<string>),
options?: IFsWriteOptions
): () => Promise<void>;
/**
* Writes a `file` with `raw`. If no `raw` content is passed, it will simply ensure it does exist.
* It is an *exposed* function: call `write.fn()`, which takes the same arguments, in order to execute on call.
* @returns An asynchronous function -hence, calling `write` won't have any effect until the returned function is called.
*/
function write(file: string, ...args: any[]): () => Promise<void> {
return async () => {
const hasRaw = typeof args[0] === 'string' || typeof args[0] === 'function';
const options: IFsWriteOptions = Object.assign(
{ overwrite: true },
(hasRaw ? args[1] : args[0]) || {}
);
let raw: string | (() => string | Promise<string>) = hasRaw ? args[0] : '';
if (typeof raw === 'function') {
try {
raw = await raw();
} catch (err) {
throw open(err);
}
}
const cwd = process.cwd();
file = absolute({ path: file, cwd });
const relative = './' + path.relative(process.cwd(), file);
const doesExist = await exists(file);
if (options.fail && doesExist) {
throw Error(`File already exists: ${relative}`);
}
if (doesExist && !options.overwrite) {
logger.info(`Write skipped: ${relative}`);
return;
}
if (!(await confirm(`Write "${relative}"?`, options))) return;
await fs.ensureDir(path.parse(file).dir);
await fs.writeFile(file, String(raw));
logger.info(`Written: ${relative}`);
};
}