···
1
+
import type { Stats, PathLike } from 'node:fs';
2
+
import fs from 'node:fs/promises';
import type { GraphQLSchema, IntrospectionQuery } from 'graphql';
···
import { ts } from '../ts';
import { Logger } from '../index';
21
+
predicate: (stat: Stats) => boolean
22
+
): Promise<boolean> => {
26
+
.catch(() => false);
29
+
const touchFile = async (file: PathLike): Promise<void> => {
31
+
const now = new Date();
32
+
await fs.utimes(file, now, now);
36
+
/** Writes a file to a swapfile then moves it into place to prevent excess change events. */
37
+
export const swapWrite = async (
40
+
): Promise<void> => {
41
+
if (!(await statFile(target, stat => stat.isFile()))) {
42
+
// If the file doesn't exist, we can write directly, and not
43
+
// try-catch so the error falls through
44
+
await fs.writeFile(target, contents);
46
+
// If the file exists, we write to a swap-file, then rename (i.e. move)
47
+
// the file into place. No try-catch around `writeFile` for proper
48
+
// directory/permission errors
49
+
const tempTarget = target + '.tmp';
50
+
await fs.writeFile(tempTarget, contents);
52
+
await fs.rename(tempTarget, target);
54
+
await fs.unlink(tempTarget);
57
+
// When we move the file into place, we also update its access and
58
+
// modification time manually, in case the rename doesn't trigger
60
+
await touchFile(target);
async function saveTadaIntrospection(
introspection: IntrospectionQuery,
tadaOutputLocation: string,
···
let output = tadaOutputLocation;
31
-
let stat: fs.Stats | undefined;
34
-
stat = await fs.promises.stat(output);
36
-
logger(`Failed to resolve path @ ${output}`);
41
-
stat = await fs.promises.stat(path.dirname(output));
42
-
if (!stat.isDirectory()) {
43
-
logger(`Output file is not inside a directory @ ${output}`);
47
-
logger(`Directory does not exist @ ${output}`);
50
-
} else if (stat.isDirectory()) {
79
+
if (await statFile(output, stat => stat.isDirectory())) {
output = path.join(output, 'introspection.d.ts');
52
-
} else if (!stat.isFile()) {
53
-
logger(`No file or directory found on path @ ${output}`);
82
+
!(await statFile(path.dirname(output), stat => stat.isDirectory()))
84
+
logger(`Output file is not inside a directory @ ${output}`);
57
-
await fs.promises.writeFile(output, contents);
58
-
logger(`Introspection saved to path @ ${output}`);
89
+
await swapWrite(output, contents);
90
+
logger(`Introspection saved to path @ ${output}`);
92
+
logger(`Failed to write introspection @ ${error}`);
export interface SchemaRef {