@augment-vir/node 31.0.0 → 31.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/dist/augments/fs/dir-contents.js +1 -1
- package/dist/augments/terminal/relevant-args.d.ts +1 -7
- package/dist/augments/terminal/relevant-args.js +1 -7
- package/dist/augments/terminal/run-cli-script.js +1 -5
- package/dist/augments/terminal/shell.js +1 -4
- package/dist/docker/containers/docker-command-inputs.js +1 -1
- package/dist/docker/containers/run-container.mock.js +1 -4
- package/dist/docker/docker-image.js +1 -6
- package/dist/prisma/model-data.js +2 -5
- package/dist/prisma/prisma-migrations.js +2 -7
- package/dist/prisma/run-prisma-command.js +3 -15
- package/dist/scripts/fix-ts-bin.script.d.ts +1 -0
- package/dist/scripts/fix-ts-bin.script.js +48 -0
- package/package.json +4 -4
- package/src/augments/docker.ts +118 -0
- package/src/augments/fs/dir-contents.ts +116 -0
- package/src/augments/fs/download.ts +31 -0
- package/src/augments/fs/json.ts +87 -0
- package/src/augments/fs/read-dir.ts +60 -0
- package/src/augments/fs/read-file.ts +18 -0
- package/src/augments/fs/symlink.ts +37 -0
- package/src/augments/fs/write.ts +18 -0
- package/src/augments/npm/query-workspace.ts +47 -0
- package/src/augments/npm/read-package-json.ts +28 -0
- package/src/augments/os/operating-system.ts +55 -0
- package/src/augments/path/ancestor.ts +78 -0
- package/src/augments/path/os-path.ts +45 -0
- package/src/augments/path/root.ts +14 -0
- package/src/augments/prisma.ts +174 -0
- package/src/augments/terminal/question.ts +142 -0
- package/src/augments/terminal/relevant-args.ts +81 -0
- package/src/augments/terminal/run-cli-script.ts +60 -0
- package/src/augments/terminal/shell.ts +312 -0
- package/src/docker/containers/container-info.ts +83 -0
- package/src/docker/containers/container-status.ts +110 -0
- package/src/docker/containers/copy-to-container.ts +34 -0
- package/src/docker/containers/docker-command-inputs.ts +119 -0
- package/src/docker/containers/kill-container.ts +25 -0
- package/src/docker/containers/run-command.ts +51 -0
- package/src/docker/containers/run-container.mock.ts +17 -0
- package/src/docker/containers/run-container.ts +92 -0
- package/src/docker/containers/try-or-kill-container.ts +18 -0
- package/src/docker/docker-image.ts +56 -0
- package/src/docker/docker-startup.ts +49 -0
- package/src/docker/run-docker-test.mock.ts +26 -0
- package/src/file-paths.mock.ts +29 -0
- package/src/index.ts +19 -0
- package/src/prisma/disable-ci-env.mock.ts +88 -0
- package/src/prisma/model-data.ts +213 -0
- package/src/prisma/prisma-client.ts +43 -0
- package/src/prisma/prisma-database.mock.ts +31 -0
- package/src/prisma/prisma-database.ts +35 -0
- package/src/prisma/prisma-errors.ts +45 -0
- package/src/prisma/prisma-migrations.ts +149 -0
- package/src/prisma/run-prisma-command.ts +59 -0
- package/src/scripts/fix-ts-bin.script.ts +60 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import {readdir, stat} from 'node:fs/promises';
|
|
2
|
+
import {join, relative} from 'node:path';
|
|
3
|
+
import type {RequireExactlyOne} from 'type-fest';
|
|
4
|
+
|
|
5
|
+
async function internalReadDirPathsRecursive(dirPath: string, basePath: string): Promise<string[]> {
|
|
6
|
+
const dirContents = await readdir(dirPath);
|
|
7
|
+
const recursiveContents: string[] = (
|
|
8
|
+
await Promise.all(
|
|
9
|
+
dirContents.map(async (fileName): Promise<string | ReadonlyArray<string>> => {
|
|
10
|
+
const filePath = join(dirPath, fileName);
|
|
11
|
+
if ((await stat(filePath)).isDirectory()) {
|
|
12
|
+
return internalReadDirPathsRecursive(filePath, basePath);
|
|
13
|
+
} else {
|
|
14
|
+
return relative(basePath, filePath);
|
|
15
|
+
}
|
|
16
|
+
}),
|
|
17
|
+
)
|
|
18
|
+
).flat();
|
|
19
|
+
|
|
20
|
+
return recursiveContents;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Gets all files within a directory and its subdirectories, recursively. Returns an array of paths
|
|
25
|
+
* relative to the given input path.
|
|
26
|
+
*
|
|
27
|
+
* @category Node : File
|
|
28
|
+
* @category Package : @augment-vir/node
|
|
29
|
+
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
30
|
+
*/
|
|
31
|
+
export async function readDirRecursive(dirPath: string): Promise<string[]> {
|
|
32
|
+
return await internalReadDirPathsRecursive(dirPath, dirPath);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Reads all files within a single directory and filters them by the given extension or extensions.
|
|
37
|
+
*
|
|
38
|
+
* @category Node : File
|
|
39
|
+
* @category Package : @augment-vir/node
|
|
40
|
+
* @returns That filtered list of paths.
|
|
41
|
+
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
42
|
+
*/
|
|
43
|
+
export async function readDirFilesByExtension({
|
|
44
|
+
dirPath,
|
|
45
|
+
extension,
|
|
46
|
+
extensions,
|
|
47
|
+
}: {
|
|
48
|
+
dirPath: string;
|
|
49
|
+
} & RequireExactlyOne<{
|
|
50
|
+
extension: string;
|
|
51
|
+
extensions: ReadonlyArray<string>;
|
|
52
|
+
}>) {
|
|
53
|
+
const extensionsToCheck: ReadonlyArray<string> = extensions || [extension];
|
|
54
|
+
|
|
55
|
+
const fileNames = await readdir(dirPath);
|
|
56
|
+
|
|
57
|
+
return fileNames.filter((fileName) =>
|
|
58
|
+
extensionsToCheck.some((extensionToCheck) => fileName.endsWith(extensionToCheck)),
|
|
59
|
+
);
|
|
60
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import {existsSync} from 'node:fs';
|
|
2
|
+
import {readFile} from 'node:fs/promises';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Reads a file if it exists, or just return `undefined`.
|
|
6
|
+
*
|
|
7
|
+
* @category Node : File
|
|
8
|
+
* @category Package : @augment-vir/node
|
|
9
|
+
* @returns The file contents as a string if the file exists, otherwise `undefined`.
|
|
10
|
+
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
11
|
+
*/
|
|
12
|
+
export async function readFileIfExists(path: string): Promise<string | undefined> {
|
|
13
|
+
if (existsSync(path)) {
|
|
14
|
+
return (await readFile(path)).toString();
|
|
15
|
+
} else {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import {existsSync} from 'node:fs';
|
|
2
|
+
import {lstat, readlink, stat, symlink} from 'node:fs/promises';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Creates a symlink.
|
|
6
|
+
*
|
|
7
|
+
* @category Node : File
|
|
8
|
+
* @category Package : @augment-vir/node
|
|
9
|
+
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
10
|
+
*/
|
|
11
|
+
export async function createSymlink({
|
|
12
|
+
linkTo,
|
|
13
|
+
symlinkPath,
|
|
14
|
+
}: {
|
|
15
|
+
/**
|
|
16
|
+
* Path that the symlink will link to. If relative, it will be linked relative to the symlink
|
|
17
|
+
* location.
|
|
18
|
+
*/
|
|
19
|
+
linkTo: string;
|
|
20
|
+
/** The location and name the symlink file to be created. */
|
|
21
|
+
symlinkPath: string;
|
|
22
|
+
}): Promise<void> {
|
|
23
|
+
if (existsSync(symlinkPath)) {
|
|
24
|
+
if (!(await lstat(symlinkPath)).isSymbolicLink()) {
|
|
25
|
+
throw new Error(
|
|
26
|
+
`Tried to create symlink at '${symlinkPath}' but a non-symlink file already exists in that location.`,
|
|
27
|
+
);
|
|
28
|
+
} else if ((await readlink(symlinkPath)) !== linkTo) {
|
|
29
|
+
throw new Error(
|
|
30
|
+
`Symlink already exists at '${symlinkPath}' but has a differently link path.`,
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
} else {
|
|
34
|
+
const isDir = (await stat(linkTo)).isDirectory();
|
|
35
|
+
await symlink(linkTo, symlinkPath, isDir ? 'dir' : 'file');
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import {mkdir, writeFile} from 'node:fs/promises';
|
|
2
|
+
import {dirname} from 'node:path';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Writes to the given file path and always ensures that the path's parent directories are all
|
|
6
|
+
* created.
|
|
7
|
+
*
|
|
8
|
+
* @category Node : File
|
|
9
|
+
* @category Package : @augment-vir/node
|
|
10
|
+
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
11
|
+
*/
|
|
12
|
+
export async function writeFileAndDir(
|
|
13
|
+
path: string,
|
|
14
|
+
contents: string | NodeJS.ArrayBufferView,
|
|
15
|
+
): Promise<void> {
|
|
16
|
+
await mkdir(dirname(path), {recursive: true});
|
|
17
|
+
await writeFile(path, contents);
|
|
18
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type {UnknownObject} from '@augment-vir/core';
|
|
2
|
+
import type {PackageJson} from 'type-fest';
|
|
3
|
+
import {runShellCommand} from '../terminal/shell.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* An npm workspace object. This is the return type for {@link queryNpmWorkspace}.
|
|
7
|
+
*
|
|
8
|
+
* @category Node : Npm
|
|
9
|
+
* @category Package : @augment-vir/node
|
|
10
|
+
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
11
|
+
*/
|
|
12
|
+
export type NpmWorkspace = PackageJson & {
|
|
13
|
+
_id: string;
|
|
14
|
+
deduped: boolean;
|
|
15
|
+
dev: boolean;
|
|
16
|
+
from: string[];
|
|
17
|
+
inBundle: boolean;
|
|
18
|
+
location: string;
|
|
19
|
+
overridden: boolean;
|
|
20
|
+
path: string;
|
|
21
|
+
pkgid: string;
|
|
22
|
+
queryContext: UnknownObject;
|
|
23
|
+
realpath: string;
|
|
24
|
+
resolved: null;
|
|
25
|
+
to: string[];
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Get a list of all NPM workspaces in the given mono-repo directory using npm's CLI.
|
|
30
|
+
*
|
|
31
|
+
* @category Node : Npm
|
|
32
|
+
* @category Package : @augment-vir/node
|
|
33
|
+
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
34
|
+
*/
|
|
35
|
+
export async function queryNpmWorkspace(cwd: string): Promise<NpmWorkspace[]> {
|
|
36
|
+
const queryOutput = await runShellCommand('npm query .workspace', {
|
|
37
|
+
cwd,
|
|
38
|
+
rejectOnError: true,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
return JSON.parse(queryOutput.stdout);
|
|
43
|
+
/* node:coverage ignore next 3 */
|
|
44
|
+
} catch {
|
|
45
|
+
throw new Error(`Failed to read npm workspace data for '${cwd}'`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {check} from '@augment-vir/assert';
|
|
2
|
+
import {join} from 'node:path';
|
|
3
|
+
import {PackageJson} from 'type-fest';
|
|
4
|
+
import {readJsonFile} from '../fs/json.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Read the `package.json` file contained within the given directory.
|
|
8
|
+
*
|
|
9
|
+
* @category Node : Npm
|
|
10
|
+
* @category Package : @augment-vir/node
|
|
11
|
+
* @throws `TypeError` if the given directory has no `package.json` or the `package.json` is
|
|
12
|
+
* invalid.
|
|
13
|
+
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
14
|
+
*/
|
|
15
|
+
export async function readPackageJson(dirPath: string): Promise<PackageJson> {
|
|
16
|
+
const packageJsonPath = join(dirPath, 'package.json');
|
|
17
|
+
const packageJson = (await readJsonFile(packageJsonPath)) as PackageJson | undefined;
|
|
18
|
+
|
|
19
|
+
if (!packageJson) {
|
|
20
|
+
throw new TypeError(`package.json file does not exist in '${dirPath}'`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (!check.isObject(packageJson)) {
|
|
24
|
+
throw new TypeError(`Parsing package.json file did not return an object in '${dirPath}'`);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return packageJson;
|
|
28
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The three major operating system types.
|
|
3
|
+
*
|
|
4
|
+
* @category Node : OS
|
|
5
|
+
* @category Package : @augment-vir/node
|
|
6
|
+
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
7
|
+
*/
|
|
8
|
+
export enum OperatingSystem {
|
|
9
|
+
Linux = 'linux',
|
|
10
|
+
Mac = 'mac',
|
|
11
|
+
Windows = 'windows',
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The current operating system type, as deduced from
|
|
16
|
+
* [`process.platform`](https://nodejs.org/api/process.html#processplatform).
|
|
17
|
+
*
|
|
18
|
+
* @category Node : OS
|
|
19
|
+
* @category Package : @augment-vir/node
|
|
20
|
+
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
21
|
+
*/
|
|
22
|
+
export const currentOperatingSystem: OperatingSystem = getOperatingSystem();
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Checks if the current operating system is the requested one.
|
|
26
|
+
*
|
|
27
|
+
* @category Node : OS
|
|
28
|
+
* @category Package : @augment-vir/node
|
|
29
|
+
* @example
|
|
30
|
+
*
|
|
31
|
+
* ```ts
|
|
32
|
+
* import {isOperatingSystem, OperatingSystem} from '@augment-vir/node';
|
|
33
|
+
*
|
|
34
|
+
* if (isOperatingSystem(OperatingSystem.Mac)) {
|
|
35
|
+
* // do something
|
|
36
|
+
* }
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
40
|
+
*/
|
|
41
|
+
export function isOperatingSystem(operatingSystem: OperatingSystem): boolean {
|
|
42
|
+
return currentOperatingSystem === operatingSystem;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function getOperatingSystem(): OperatingSystem {
|
|
46
|
+
/** We can't test all of these on a single system. */
|
|
47
|
+
/* node:coverage ignore next 7 */
|
|
48
|
+
if (process.platform === 'win32') {
|
|
49
|
+
return OperatingSystem.Windows;
|
|
50
|
+
} else if (process.platform === 'darwin') {
|
|
51
|
+
return OperatingSystem.Mac;
|
|
52
|
+
} else {
|
|
53
|
+
return OperatingSystem.Linux;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import {check} from '@augment-vir/assert';
|
|
2
|
+
import {type MaybePromise} from '@augment-vir/common';
|
|
3
|
+
import {dirname, join} from 'node:path';
|
|
4
|
+
import {systemRootPath} from './root.js';
|
|
5
|
+
|
|
6
|
+
export function findAncestor(
|
|
7
|
+
currentPath: string,
|
|
8
|
+
callback: (path: string) => Promise<boolean>,
|
|
9
|
+
): Promise<string | undefined>;
|
|
10
|
+
export function findAncestor(
|
|
11
|
+
currentPath: string,
|
|
12
|
+
callback: (path: string) => boolean,
|
|
13
|
+
): string | undefined;
|
|
14
|
+
export function findAncestor(
|
|
15
|
+
currentPath: string,
|
|
16
|
+
callback: (path: string) => MaybePromise<boolean>,
|
|
17
|
+
): MaybePromise<string | undefined>;
|
|
18
|
+
/**
|
|
19
|
+
* Find an ancestor file path that matches the given `callback`. If no matches are found all the way
|
|
20
|
+
* up until the system root, this returns `undefined`.
|
|
21
|
+
*
|
|
22
|
+
* @category Path : Node
|
|
23
|
+
* @category Package : @augment-vir/node
|
|
24
|
+
* @returns `undefined` if no matches are found.
|
|
25
|
+
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
26
|
+
*/
|
|
27
|
+
export function findAncestor(
|
|
28
|
+
currentPath: string,
|
|
29
|
+
callback: (path: string) => MaybePromise<boolean>,
|
|
30
|
+
): MaybePromise<string | undefined> {
|
|
31
|
+
if (currentPath === systemRootPath) {
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const result = callback(currentPath);
|
|
36
|
+
|
|
37
|
+
if (check.isPromise(result)) {
|
|
38
|
+
return new Promise<string | undefined>(async (resolve) => {
|
|
39
|
+
const awaitedResult = await result;
|
|
40
|
+
|
|
41
|
+
if (awaitedResult) {
|
|
42
|
+
resolve(currentPath);
|
|
43
|
+
} else {
|
|
44
|
+
resolve(await findAncestor(dirname(currentPath), callback));
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
} else if (result) {
|
|
48
|
+
return currentPath;
|
|
49
|
+
} else {
|
|
50
|
+
return findAncestor(dirname(currentPath), callback);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Join a list of paths to the given `parentDirPath`. This is particularly useful for getting full
|
|
56
|
+
* paths from the output of
|
|
57
|
+
* [`readdir`](https://nodejs.org/api/fs.html#fspromisesreaddirpath-options).
|
|
58
|
+
*
|
|
59
|
+
* @category Path : Node
|
|
60
|
+
* @category Package : @augment-vir/node
|
|
61
|
+
* @example
|
|
62
|
+
*
|
|
63
|
+
* ```ts
|
|
64
|
+
* import {readdir} from 'node:fs/promises';
|
|
65
|
+
* import {join} from 'node:path';
|
|
66
|
+
*
|
|
67
|
+
* const parentDir = join('my', 'path');
|
|
68
|
+
* const dirs = joinFilesToDir(parentDir, await readdir(parentDir));
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
72
|
+
*/
|
|
73
|
+
export function joinFilesToDir(
|
|
74
|
+
parentDirPath: string,
|
|
75
|
+
childNames: ReadonlyArray<string>,
|
|
76
|
+
): Array<string> {
|
|
77
|
+
return childNames.map((childName) => join(parentDirPath, childName));
|
|
78
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import {sep} from 'node:path';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Convert a given path to a windows path if the current system doesn't use `/`.
|
|
5
|
+
*
|
|
6
|
+
* @category Path : Node
|
|
7
|
+
* @category Package : @augment-vir/node
|
|
8
|
+
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
9
|
+
*/
|
|
10
|
+
export function replaceWithWindowsPathIfNeeded(input: string): string {
|
|
11
|
+
/** No single system will test all of these lines so we must ignore them all. */
|
|
12
|
+
/* node:coverage ignore next 5 */
|
|
13
|
+
if (sep === '/') {
|
|
14
|
+
return input;
|
|
15
|
+
} else {
|
|
16
|
+
return input.replace(/\//g, sep);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Convert a Windows path to a posix path.
|
|
22
|
+
*
|
|
23
|
+
* @category Path : Node
|
|
24
|
+
* @category Package : @augment-vir/node
|
|
25
|
+
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
26
|
+
*/
|
|
27
|
+
export function toPosixPath(maybeWindowsPath: string): string {
|
|
28
|
+
return maybeWindowsPath
|
|
29
|
+
.replace(/^(.+?):\\+/, (match, captureGroup) => {
|
|
30
|
+
return `/${captureGroup.toLowerCase()}/`;
|
|
31
|
+
})
|
|
32
|
+
.replace(/\\+/g, '/');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Use this to interpolate paths into bash commands. If the given path is not a Windows path, the
|
|
37
|
+
* path structure will not be modified.
|
|
38
|
+
*
|
|
39
|
+
* @category Path : Node
|
|
40
|
+
* @category Package : @augment-vir/node
|
|
41
|
+
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
42
|
+
*/
|
|
43
|
+
export function interpolationSafeWindowsPath(input: string): string {
|
|
44
|
+
return input.replace(/\\/g, '\\\\\\\\');
|
|
45
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {parse} from 'node:path';
|
|
2
|
+
|
|
3
|
+
function getSystemRootPath() {
|
|
4
|
+
return parse(process.cwd()).root;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The root path of the system containing the cwd.
|
|
9
|
+
*
|
|
10
|
+
* @category Path : Node
|
|
11
|
+
* @category Package : @augment-vir/node
|
|
12
|
+
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
13
|
+
*/
|
|
14
|
+
export const systemRootPath = getSystemRootPath();
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import {addData, dumpData, getAllPrismaModelNames} from '../prisma/model-data.js';
|
|
2
|
+
import {generatePrismaClient, isGeneratedPrismaClientCurrent} from '../prisma/prisma-client.js';
|
|
3
|
+
import {
|
|
4
|
+
doesPrismaDiffExist,
|
|
5
|
+
getPrismaDiff,
|
|
6
|
+
resetDevPrismaDatabase,
|
|
7
|
+
} from '../prisma/prisma-database.js';
|
|
8
|
+
import {
|
|
9
|
+
applyPrismaMigrationsToDev,
|
|
10
|
+
applyPrismaMigrationsToProd,
|
|
11
|
+
createPrismaMigration,
|
|
12
|
+
getMigrationStatus,
|
|
13
|
+
} from '../prisma/prisma-migrations.js';
|
|
14
|
+
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
16
|
+
import type {PrismaMigrationNeededError, PrismaResetNeededError} from '../prisma/prisma-errors.js';
|
|
17
|
+
|
|
18
|
+
export type {
|
|
19
|
+
PrismaAddDataData as PrismaAddModelData,
|
|
20
|
+
PrismaDataDumpOptions,
|
|
21
|
+
} from '../prisma/model-data.js';
|
|
22
|
+
export * from '../prisma/prisma-errors.js';
|
|
23
|
+
export type {PrismaMigrationStatus} from '../prisma/prisma-migrations.js';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Centralized Prisma API from `@augment-vir/node`.
|
|
27
|
+
*
|
|
28
|
+
* ## Prisma flows
|
|
29
|
+
*
|
|
30
|
+
* - Deploy to production
|
|
31
|
+
*
|
|
32
|
+
* - {@link prisma.migration.applyProd}
|
|
33
|
+
* - Update dev environment
|
|
34
|
+
*
|
|
35
|
+
* - Apply migrations: {@link prisma.migration.applyDev}
|
|
36
|
+
*
|
|
37
|
+
* - If throws {@link PrismaMigrationNeededError}, prompt user for a new migration name and pass it to
|
|
38
|
+
* {@link prisma.migration.create}
|
|
39
|
+
* - If throws {@link PrismaResetNeededError}, reset the database with {@link prisma.database.resetDev}
|
|
40
|
+
* - Generate client: `prisma.client.isCurrent`
|
|
41
|
+
*
|
|
42
|
+
* - If `false`, run {@link prisma.client.generate}
|
|
43
|
+
*
|
|
44
|
+
* @category Prisma : Node
|
|
45
|
+
* @category Package : @augment-vir/node
|
|
46
|
+
* @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
|
|
47
|
+
*/
|
|
48
|
+
export const prisma = {
|
|
49
|
+
migration: {
|
|
50
|
+
/**
|
|
51
|
+
* Get current migration status.
|
|
52
|
+
*
|
|
53
|
+
* @see https://www.prisma.io/docs/orm/reference/prisma-cli-reference#migrate-status
|
|
54
|
+
*/
|
|
55
|
+
status: getMigrationStatus,
|
|
56
|
+
/**
|
|
57
|
+
* Creates a new migration.
|
|
58
|
+
*
|
|
59
|
+
* @see https://www.prisma.io/docs/orm/reference/prisma-cli-reference#migrate-dev
|
|
60
|
+
*/
|
|
61
|
+
create: createPrismaMigration,
|
|
62
|
+
/**
|
|
63
|
+
* Apply all migrations. Meant for a production environment.
|
|
64
|
+
*
|
|
65
|
+
* @see https://www.prisma.io/docs/orm/reference/prisma-cli-reference#migrate-deploy
|
|
66
|
+
*/
|
|
67
|
+
applyProd: applyPrismaMigrationsToProd,
|
|
68
|
+
/**
|
|
69
|
+
* Apply all migrations. Meant for a development environment, with less protections than
|
|
70
|
+
* {@link prisma.migration.applyProd}.
|
|
71
|
+
*
|
|
72
|
+
* @throws `PrismaMigrationNeededError` when a new migration is required so the user needs
|
|
73
|
+
* to input a name.
|
|
74
|
+
* @throws `PrismaResetNeededError` when there's a migration mismatch with the database and
|
|
75
|
+
* it needs to be reset.
|
|
76
|
+
* @see https://www.prisma.io/docs/orm/reference/prisma-cli-reference#migrate-dev
|
|
77
|
+
*/
|
|
78
|
+
applyDev: applyPrismaMigrationsToDev,
|
|
79
|
+
},
|
|
80
|
+
database: {
|
|
81
|
+
/**
|
|
82
|
+
* Force resets a dev database to match the current Prisma schema and migrations.
|
|
83
|
+
*
|
|
84
|
+
* **This will destroy all data. Do not use in production.**
|
|
85
|
+
*
|
|
86
|
+
* @see https://www.prisma.io/docs/orm/reference/prisma-cli-reference#migrate-reset
|
|
87
|
+
*/
|
|
88
|
+
resetDev: resetDevPrismaDatabase,
|
|
89
|
+
/**
|
|
90
|
+
* Uses {@link prisma.database.diff} to detect if there are any differences between the
|
|
91
|
+
* current database and the Prisma schema that should control it.
|
|
92
|
+
*/
|
|
93
|
+
hasDiff: doesPrismaDiffExist,
|
|
94
|
+
/**
|
|
95
|
+
* Gets a string list of all differences between the current database and the Prisma schema
|
|
96
|
+
* that should control it.
|
|
97
|
+
*
|
|
98
|
+
* @see https://www.prisma.io/docs/orm/reference/prisma-cli-reference#migrate-diff
|
|
99
|
+
*/
|
|
100
|
+
diff: getPrismaDiff,
|
|
101
|
+
},
|
|
102
|
+
client: {
|
|
103
|
+
/**
|
|
104
|
+
* Runs Prisma generators included in the given Prisma schema (which usually includes the
|
|
105
|
+
* Prisma JS client). This will work even if the database doesn't exist yet.
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
*
|
|
109
|
+
* ```ts
|
|
110
|
+
* import {prisma} from '@augment-vir/node';
|
|
111
|
+
*
|
|
112
|
+
* prisma.client.generate('../../prisma/schema.prisma');
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
generate: generatePrismaClient,
|
|
116
|
+
/**
|
|
117
|
+
* Detects if the current generated Prisma JS Client was generated from the current Prisma
|
|
118
|
+
* schema.
|
|
119
|
+
*/
|
|
120
|
+
isCurrent: isGeneratedPrismaClientCurrent,
|
|
121
|
+
/**
|
|
122
|
+
* Adds a collection of create data to a database through a `PrismaClient` instance. This is
|
|
123
|
+
* particularly useful for setting up mocks in a mock PrismaClient.
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
*
|
|
127
|
+
* ```ts
|
|
128
|
+
* import {addPrismaModelData} from '@augment-vir/common';
|
|
129
|
+
* import {PrismaClient} from '@prisma/client';
|
|
130
|
+
*
|
|
131
|
+
* await addPrismaModelData(new PrismaClient(), [
|
|
132
|
+
* {
|
|
133
|
+
* user: {
|
|
134
|
+
* mockUser1: {
|
|
135
|
+
* first_name: 'one',
|
|
136
|
+
* id: 123,
|
|
137
|
+
* // etc.
|
|
138
|
+
* },
|
|
139
|
+
* mockUser2: {
|
|
140
|
+
* first_name: 'two',
|
|
141
|
+
* id: 124,
|
|
142
|
+
* authRole: 'user',
|
|
143
|
+
* // etc.
|
|
144
|
+
* },
|
|
145
|
+
* },
|
|
146
|
+
* },
|
|
147
|
+
* {
|
|
148
|
+
* region: [
|
|
149
|
+
* {
|
|
150
|
+
* id: 1,
|
|
151
|
+
* name: 'North America',
|
|
152
|
+
* // etc.
|
|
153
|
+
* },
|
|
154
|
+
* {
|
|
155
|
+
* id: 2,
|
|
156
|
+
* name: 'Europe',
|
|
157
|
+
* // etc.
|
|
158
|
+
* },
|
|
159
|
+
* ],
|
|
160
|
+
* },
|
|
161
|
+
* ]);
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
addData: addData,
|
|
165
|
+
/**
|
|
166
|
+
* Dump data from the current database through a `PrismaClient` instance.
|
|
167
|
+
*
|
|
168
|
+
* @see {@link PrismaDataDumpOptions}
|
|
169
|
+
*/
|
|
170
|
+
dumpData: dumpData,
|
|
171
|
+
/** List all model names in the given Prisma client. */
|
|
172
|
+
listModelNames: getAllPrismaModelNames,
|
|
173
|
+
},
|
|
174
|
+
};
|