@tinyrack/dotweave 0.39.4
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/bin/index.js +5 -0
- package/dist/application.d.ts +5 -0
- package/dist/application.d.ts.map +1 -0
- package/dist/application.js +86 -0
- package/dist/application.js.map +1 -0
- package/dist/cli/autocomplete.d.ts +7 -0
- package/dist/cli/autocomplete.d.ts.map +1 -0
- package/dist/cli/autocomplete.js +62 -0
- package/dist/cli/autocomplete.js.map +1 -0
- package/dist/cli/cd.d.ts +4 -0
- package/dist/cli/cd.d.ts.map +1 -0
- package/dist/cli/cd.js +23 -0
- package/dist/cli/cd.js.map +1 -0
- package/dist/cli/doctor.d.ts +4 -0
- package/dist/cli/doctor.d.ts.map +1 -0
- package/dist/cli/doctor.js +92 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/index.d.ts +4 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +22 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.d.ts +4 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +110 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/profile/index.d.ts +3 -0
- package/dist/cli/profile/index.d.ts.map +1 -0
- package/dist/cli/profile/index.js +15 -0
- package/dist/cli/profile/index.js.map +1 -0
- package/dist/cli/profile/list.d.ts +4 -0
- package/dist/cli/profile/list.d.ts.map +1 -0
- package/dist/cli/profile/list.js +42 -0
- package/dist/cli/profile/list.js.map +1 -0
- package/dist/cli/profile/use.d.ts +4 -0
- package/dist/cli/profile/use.d.ts.map +1 -0
- package/dist/cli/profile/use.js +49 -0
- package/dist/cli/profile/use.js.map +1 -0
- package/dist/cli/pull.d.ts +4 -0
- package/dist/cli/pull.d.ts.map +1 -0
- package/dist/cli/pull.js +107 -0
- package/dist/cli/pull.js.map +1 -0
- package/dist/cli/push.d.ts +4 -0
- package/dist/cli/push.d.ts.map +1 -0
- package/dist/cli/push.js +49 -0
- package/dist/cli/push.js.map +1 -0
- package/dist/cli/root-commands.d.ts +13 -0
- package/dist/cli/root-commands.d.ts.map +1 -0
- package/dist/cli/root-commands.js +25 -0
- package/dist/cli/root-commands.js.map +1 -0
- package/dist/cli/status.d.ts +4 -0
- package/dist/cli/status.d.ts.map +1 -0
- package/dist/cli/status.js +132 -0
- package/dist/cli/status.js.map +1 -0
- package/dist/cli/track.d.ts +4 -0
- package/dist/cli/track.d.ts.map +1 -0
- package/dist/cli/track.js +133 -0
- package/dist/cli/track.js.map +1 -0
- package/dist/cli/untrack.d.ts +4 -0
- package/dist/cli/untrack.d.ts.map +1 -0
- package/dist/cli/untrack.js +40 -0
- package/dist/cli/untrack.js.map +1 -0
- package/dist/config/constants.d.ts +31 -0
- package/dist/config/constants.d.ts.map +1 -0
- package/dist/config/constants.js +33 -0
- package/dist/config/constants.js.map +1 -0
- package/dist/config/global-config.d.ts +21 -0
- package/dist/config/global-config.d.ts.map +1 -0
- package/dist/config/global-config.js +89 -0
- package/dist/config/global-config.js.map +1 -0
- package/dist/config/identity-file.d.ts +9 -0
- package/dist/config/identity-file.d.ts.map +1 -0
- package/dist/config/identity-file.js +48 -0
- package/dist/config/identity-file.js.map +1 -0
- package/dist/config/migration.d.ts +9 -0
- package/dist/config/migration.d.ts.map +1 -0
- package/dist/config/migration.js +61 -0
- package/dist/config/migration.js.map +1 -0
- package/dist/config/platform.d.ts +12 -0
- package/dist/config/platform.d.ts.map +1 -0
- package/dist/config/platform.js +25 -0
- package/dist/config/platform.js.map +1 -0
- package/dist/config/runtime-env.d.ts +7 -0
- package/dist/config/runtime-env.d.ts.map +1 -0
- package/dist/config/runtime-env.js +31 -0
- package/dist/config/runtime-env.js.map +1 -0
- package/dist/config/sync-entry.d.ts +14 -0
- package/dist/config/sync-entry.d.ts.map +1 -0
- package/dist/config/sync-entry.js +99 -0
- package/dist/config/sync-entry.js.map +1 -0
- package/dist/config/sync-schema.d.ts +146 -0
- package/dist/config/sync-schema.d.ts.map +1 -0
- package/dist/config/sync-schema.js +392 -0
- package/dist/config/sync-schema.js.map +1 -0
- package/dist/config/sync.d.ts +8 -0
- package/dist/config/sync.d.ts.map +1 -0
- package/dist/config/sync.js +53 -0
- package/dist/config/sync.js.map +1 -0
- package/dist/config/xdg.d.ts +10 -0
- package/dist/config/xdg.d.ts.map +1 -0
- package/dist/config/xdg.js +90 -0
- package/dist/config/xdg.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/content.d.ts +5 -0
- package/dist/lib/content.d.ts.map +1 -0
- package/dist/lib/content.js +29 -0
- package/dist/lib/content.js.map +1 -0
- package/dist/lib/crypto.d.ts +45 -0
- package/dist/lib/crypto.d.ts.map +1 -0
- package/dist/lib/crypto.js +130 -0
- package/dist/lib/crypto.js.map +1 -0
- package/dist/lib/env.d.ts +13 -0
- package/dist/lib/env.d.ts.map +1 -0
- package/dist/lib/env.js +50 -0
- package/dist/lib/env.js.map +1 -0
- package/dist/lib/error.d.ts +22 -0
- package/dist/lib/error.d.ts.map +1 -0
- package/dist/lib/error.js +50 -0
- package/dist/lib/error.js.map +1 -0
- package/dist/lib/file-mode.d.ts +36 -0
- package/dist/lib/file-mode.d.ts.map +1 -0
- package/dist/lib/file-mode.js +55 -0
- package/dist/lib/file-mode.js.map +1 -0
- package/dist/lib/filesystem.d.ts +60 -0
- package/dist/lib/filesystem.d.ts.map +1 -0
- package/dist/lib/filesystem.js +190 -0
- package/dist/lib/filesystem.js.map +1 -0
- package/dist/lib/git.d.ts +23 -0
- package/dist/lib/git.d.ts.map +1 -0
- package/dist/lib/git.js +162 -0
- package/dist/lib/git.js.map +1 -0
- package/dist/lib/jsonc.d.ts +8 -0
- package/dist/lib/jsonc.d.ts.map +1 -0
- package/dist/lib/jsonc.js +78 -0
- package/dist/lib/jsonc.js.map +1 -0
- package/dist/lib/path.d.ts +21 -0
- package/dist/lib/path.d.ts.map +1 -0
- package/dist/lib/path.js +44 -0
- package/dist/lib/path.js.map +1 -0
- package/dist/lib/promise.d.ts +10 -0
- package/dist/lib/promise.d.ts.map +1 -0
- package/dist/lib/promise.js +25 -0
- package/dist/lib/promise.js.map +1 -0
- package/dist/lib/string.d.ts +6 -0
- package/dist/lib/string.d.ts.map +1 -0
- package/dist/lib/string.js +8 -0
- package/dist/lib/string.js.map +1 -0
- package/dist/lib/validation.d.ts +7 -0
- package/dist/lib/validation.d.ts.map +1 -0
- package/dist/lib/validation.js +13 -0
- package/dist/lib/validation.js.map +1 -0
- package/dist/lib/version.d.ts +2 -0
- package/dist/lib/version.d.ts.map +1 -0
- package/dist/lib/version.js +4 -0
- package/dist/lib/version.js.map +1 -0
- package/dist/migrations/global-v3.d.ts +3 -0
- package/dist/migrations/global-v3.d.ts.map +1 -0
- package/dist/migrations/global-v3.js +5 -0
- package/dist/migrations/global-v3.js.map +1 -0
- package/dist/services/autocomplete.d.ts +5 -0
- package/dist/services/autocomplete.d.ts.map +1 -0
- package/dist/services/autocomplete.js +185 -0
- package/dist/services/autocomplete.js.map +1 -0
- package/dist/services/config-file.d.ts +73 -0
- package/dist/services/config-file.d.ts.map +1 -0
- package/dist/services/config-file.js +40 -0
- package/dist/services/config-file.js.map +1 -0
- package/dist/services/doctor.d.ts +16 -0
- package/dist/services/doctor.d.ts.map +1 -0
- package/dist/services/doctor.js +126 -0
- package/dist/services/doctor.js.map +1 -0
- package/dist/services/init.d.ts +24 -0
- package/dist/services/init.d.ts.map +1 -0
- package/dist/services/init.js +265 -0
- package/dist/services/init.js.map +1 -0
- package/dist/services/local-materialization.d.ts +30 -0
- package/dist/services/local-materialization.d.ts.map +1 -0
- package/dist/services/local-materialization.js +451 -0
- package/dist/services/local-materialization.js.map +1 -0
- package/dist/services/local-snapshot.d.ts +26 -0
- package/dist/services/local-snapshot.d.ts.map +1 -0
- package/dist/services/local-snapshot.js +119 -0
- package/dist/services/local-snapshot.js.map +1 -0
- package/dist/services/paths.d.ts +8 -0
- package/dist/services/paths.d.ts.map +1 -0
- package/dist/services/paths.js +71 -0
- package/dist/services/paths.js.map +1 -0
- package/dist/services/profile.d.ts +39 -0
- package/dist/services/profile.d.ts.map +1 -0
- package/dist/services/profile.js +124 -0
- package/dist/services/profile.js.map +1 -0
- package/dist/services/pull.d.ts +38 -0
- package/dist/services/pull.d.ts.map +1 -0
- package/dist/services/pull.js +148 -0
- package/dist/services/pull.js.map +1 -0
- package/dist/services/push.d.ts +38 -0
- package/dist/services/push.d.ts.map +1 -0
- package/dist/services/push.js +120 -0
- package/dist/services/push.js.map +1 -0
- package/dist/services/repo-artifacts.d.ts +52 -0
- package/dist/services/repo-artifacts.d.ts.map +1 -0
- package/dist/services/repo-artifacts.js +325 -0
- package/dist/services/repo-artifacts.js.map +1 -0
- package/dist/services/repo-snapshot.d.ts +7 -0
- package/dist/services/repo-snapshot.d.ts.map +1 -0
- package/dist/services/repo-snapshot.js +181 -0
- package/dist/services/repo-snapshot.js.map +1 -0
- package/dist/services/runtime.d.ts +30 -0
- package/dist/services/runtime.d.ts.map +1 -0
- package/dist/services/runtime.js +71 -0
- package/dist/services/runtime.js.map +1 -0
- package/dist/services/set.d.ts +41 -0
- package/dist/services/set.d.ts.map +1 -0
- package/dist/services/set.js +288 -0
- package/dist/services/set.js.map +1 -0
- package/dist/services/status.d.ts +41 -0
- package/dist/services/status.d.ts.map +1 -0
- package/dist/services/status.js +87 -0
- package/dist/services/status.js.map +1 -0
- package/dist/services/terminal/cli-runtime.d.ts +18 -0
- package/dist/services/terminal/cli-runtime.d.ts.map +1 -0
- package/dist/services/terminal/cli-runtime.js +19 -0
- package/dist/services/terminal/cli-runtime.js.map +1 -0
- package/dist/services/terminal/logger.d.ts +9 -0
- package/dist/services/terminal/logger.d.ts.map +1 -0
- package/dist/services/terminal/logger.js +15 -0
- package/dist/services/terminal/logger.js.map +1 -0
- package/dist/services/terminal/path-completion.d.ts +3 -0
- package/dist/services/terminal/path-completion.d.ts.map +1 -0
- package/dist/services/terminal/path-completion.js +108 -0
- package/dist/services/terminal/path-completion.js.map +1 -0
- package/dist/services/terminal/shell.d.ts +24 -0
- package/dist/services/terminal/shell.d.ts.map +1 -0
- package/dist/services/terminal/shell.js +227 -0
- package/dist/services/terminal/shell.js.map +1 -0
- package/dist/services/track.d.ts +20 -0
- package/dist/services/track.d.ts.map +1 -0
- package/dist/services/track.js +224 -0
- package/dist/services/track.js.map +1 -0
- package/dist/services/untrack.d.ts +13 -0
- package/dist/services/untrack.d.ts.map +1 -0
- package/dist/services/untrack.js +133 -0
- package/dist/services/untrack.js.map +1 -0
- package/package.json +84 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { lstat } from "node:fs/promises";
|
|
2
|
+
/**
|
|
3
|
+
* @description
|
|
4
|
+
* Checks whether a filesystem path currently exists.
|
|
5
|
+
*/
|
|
6
|
+
export declare const pathExists: (path: string) => Promise<boolean>;
|
|
7
|
+
/**
|
|
8
|
+
* @description
|
|
9
|
+
* Reads path metadata while treating missing paths as an absent result.
|
|
10
|
+
*/
|
|
11
|
+
export declare const getPathStats: (path: string) => Promise<import("fs").Stats | undefined>;
|
|
12
|
+
/**
|
|
13
|
+
* @description
|
|
14
|
+
* Reads path metadata while following symlinks and treating missing paths as an absent result.
|
|
15
|
+
*/
|
|
16
|
+
export declare const getFollowedPathStats: (path: string) => Promise<import("fs").Stats | undefined>;
|
|
17
|
+
/**
|
|
18
|
+
* @description
|
|
19
|
+
* Lists directory entries in a stable name-sorted order.
|
|
20
|
+
*/
|
|
21
|
+
export declare const listDirectoryEntries: (path: string) => Promise<import("fs").Dirent<string>[]>;
|
|
22
|
+
/**
|
|
23
|
+
* @description
|
|
24
|
+
* Writes a regular file node with the permissions dotweave should preserve.
|
|
25
|
+
*/
|
|
26
|
+
export declare const writeFileNode: (path: string, node: Readonly<{
|
|
27
|
+
contents: string | Uint8Array;
|
|
28
|
+
executable: boolean;
|
|
29
|
+
}>, fileMode?: number) => Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* @description
|
|
32
|
+
* Creates a symlink while correctly handling Windows symlink types.
|
|
33
|
+
*/
|
|
34
|
+
export declare const createSymlink: (target: string, path: string, type?: "file" | "dir" | "junction") => Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* @description
|
|
37
|
+
* Replaces a path with a symlink node and its target.
|
|
38
|
+
*/
|
|
39
|
+
export declare const writeSymlinkNode: (path: string, linkTarget: string) => Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* @description
|
|
42
|
+
* Copies a filesystem node into the sync layout while preserving supported node types.
|
|
43
|
+
*/
|
|
44
|
+
export declare const copyFilesystemNode: (sourcePath: string, targetPath: string, stats?: Awaited<ReturnType<typeof lstat>>) => Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* @description
|
|
47
|
+
* Swaps a staged path into place with rollback protection for the previous target.
|
|
48
|
+
*/
|
|
49
|
+
export declare const replacePathAtomically: (targetPath: string, nextPath: string) => Promise<void>;
|
|
50
|
+
/**
|
|
51
|
+
* @description
|
|
52
|
+
* Removes a path through a temporary rename so deletion is completed atomically.
|
|
53
|
+
*/
|
|
54
|
+
export declare const removePathAtomically: (targetPath: string) => Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* @description
|
|
57
|
+
* Writes text content through a staging directory before replacing the target file.
|
|
58
|
+
*/
|
|
59
|
+
export declare const writeTextFileAtomically: (targetPath: string, contents: string) => Promise<void>;
|
|
60
|
+
//# sourceMappingURL=filesystem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filesystem.d.ts","sourceRoot":"","sources":["../../src/lib/filesystem.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,EAWN,MAAM,kBAAkB,CAAC;AAK1B;;;GAGG;AACH,eAAO,MAAM,UAAU,GAAU,MAAM,MAAM,qBAU5C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,YAAY,GAAU,MAAM,MAAM,4CAa9C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,GAAU,MAAM,MAAM,4CAatD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,GAAU,MAAM,MAAM,2CAKtD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,GACxB,MAAM,MAAM,EACZ,MAAM,QAAQ,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,UAAU,CAAC;IAC9B,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC,EACF,WAAW,MAAM,kBAKlB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,GACxB,QAAQ,MAAM,EACd,MAAM,MAAM,EACZ,OAAO,MAAM,GAAG,KAAK,GAAG,UAAU,kBAqBnC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,GAAU,MAAM,MAAM,EAAE,YAAY,MAAM,kBAItE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAC7B,YAAY,MAAM,EAClB,YAAY,MAAM,EAClB,QAAQ,OAAO,CAAC,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC,kBAkC1C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,qBAAqB,GAChC,YAAY,MAAM,EAClB,UAAU,MAAM,kBA6BjB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,GAAU,YAAY,MAAM,kBAc5D,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,uBAAuB,GAClC,YAAY,MAAM,EAClB,UAAU,MAAM,kBAcjB,CAAC"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { access, chmod, lstat, mkdir, mkdtemp, readdir, readFile, readlink, rename, rm, stat, symlink, writeFile, } from "node:fs/promises";
|
|
3
|
+
import { basename, dirname, isAbsolute, join } from "node:path";
|
|
4
|
+
import { DotweaveError } from "#app/lib/error.ts";
|
|
5
|
+
import { buildExecutableMode, isExecutableMode } from "#app/lib/file-mode.ts";
|
|
6
|
+
/**
|
|
7
|
+
* @description
|
|
8
|
+
* Checks whether a filesystem path currently exists.
|
|
9
|
+
*/
|
|
10
|
+
export const pathExists = async (path) => {
|
|
11
|
+
try {
|
|
12
|
+
await access(path);
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
throw error;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* @description
|
|
24
|
+
* Reads path metadata while treating missing paths as an absent result.
|
|
25
|
+
*/
|
|
26
|
+
export const getPathStats = async (path) => {
|
|
27
|
+
try {
|
|
28
|
+
return await lstat(path);
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
if (error instanceof Error &&
|
|
32
|
+
"code" in error &&
|
|
33
|
+
(error.code === "ENOENT" || error.code === "ENOTDIR")) {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
throw error;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* @description
|
|
41
|
+
* Reads path metadata while following symlinks and treating missing paths as an absent result.
|
|
42
|
+
*/
|
|
43
|
+
export const getFollowedPathStats = async (path) => {
|
|
44
|
+
try {
|
|
45
|
+
return await stat(path);
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
if (error instanceof Error &&
|
|
49
|
+
"code" in error &&
|
|
50
|
+
(error.code === "ENOENT" || error.code === "ENOTDIR")) {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* @description
|
|
58
|
+
* Lists directory entries in a stable name-sorted order.
|
|
59
|
+
*/
|
|
60
|
+
export const listDirectoryEntries = async (path) => {
|
|
61
|
+
const entries = await readdir(path, { withFileTypes: true });
|
|
62
|
+
return entries.sort((left, right) => {
|
|
63
|
+
return left.name.localeCompare(right.name);
|
|
64
|
+
});
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* @description
|
|
68
|
+
* Writes a regular file node with the permissions dotweave should preserve.
|
|
69
|
+
*/
|
|
70
|
+
export const writeFileNode = async (path, node, fileMode) => {
|
|
71
|
+
await mkdir(dirname(path), { recursive: true });
|
|
72
|
+
await writeFile(path, node.contents);
|
|
73
|
+
await chmod(path, fileMode ?? buildExecutableMode(node.executable));
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* @description
|
|
77
|
+
* Creates a symlink while correctly handling Windows symlink types.
|
|
78
|
+
*/
|
|
79
|
+
export const createSymlink = async (target, path, type) => {
|
|
80
|
+
if (process.platform !== "win32") {
|
|
81
|
+
await symlink(target, path);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
// On Windows, the symlink type (file, dir, junction) must be specified.
|
|
85
|
+
// Junctions are preferred for directories as they don't require admin privileges.
|
|
86
|
+
if (type !== undefined) {
|
|
87
|
+
await symlink(target, path, type);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const absoluteTarget = isAbsolute(target)
|
|
91
|
+
? target
|
|
92
|
+
: join(dirname(path), target);
|
|
93
|
+
const stats = await getFollowedPathStats(absoluteTarget);
|
|
94
|
+
const resolvedType = stats?.isDirectory() ? "junction" : "file";
|
|
95
|
+
await symlink(target, path, resolvedType);
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* @description
|
|
99
|
+
* Replaces a path with a symlink node and its target.
|
|
100
|
+
*/
|
|
101
|
+
export const writeSymlinkNode = async (path, linkTarget) => {
|
|
102
|
+
await mkdir(dirname(path), { recursive: true });
|
|
103
|
+
await rm(path, { force: true, recursive: true });
|
|
104
|
+
await createSymlink(linkTarget, path);
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* @description
|
|
108
|
+
* Copies a filesystem node into the sync layout while preserving supported node types.
|
|
109
|
+
*/
|
|
110
|
+
export const copyFilesystemNode = async (sourcePath, targetPath, stats) => {
|
|
111
|
+
const sourceStats = stats ?? (await lstat(sourcePath));
|
|
112
|
+
if (sourceStats.isDirectory()) {
|
|
113
|
+
await mkdir(targetPath, { recursive: true });
|
|
114
|
+
const entries = await listDirectoryEntries(sourcePath);
|
|
115
|
+
for (const entry of entries) {
|
|
116
|
+
await copyFilesystemNode(join(sourcePath, entry.name), join(targetPath, entry.name));
|
|
117
|
+
}
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
if (sourceStats.isSymbolicLink()) {
|
|
121
|
+
const linkTarget = await readlink(sourcePath);
|
|
122
|
+
await writeSymlinkNode(targetPath, linkTarget);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
if (!sourceStats.isFile()) {
|
|
126
|
+
throw new DotweaveError(`Unsupported filesystem entry: ${sourcePath}`);
|
|
127
|
+
}
|
|
128
|
+
await writeFileNode(targetPath, {
|
|
129
|
+
contents: await readFile(sourcePath),
|
|
130
|
+
executable: isExecutableMode(sourceStats.mode),
|
|
131
|
+
});
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* @description
|
|
135
|
+
* Swaps a staged path into place with rollback protection for the previous target.
|
|
136
|
+
*/
|
|
137
|
+
export const replacePathAtomically = async (targetPath, nextPath) => {
|
|
138
|
+
const backupPath = join(dirname(targetPath), `.${basename(targetPath)}.dotweave-sync-backup-${randomUUID()}`);
|
|
139
|
+
const existingStats = await getPathStats(targetPath);
|
|
140
|
+
let targetMoved = false;
|
|
141
|
+
try {
|
|
142
|
+
if (existingStats !== undefined) {
|
|
143
|
+
await rename(targetPath, backupPath);
|
|
144
|
+
targetMoved = true;
|
|
145
|
+
}
|
|
146
|
+
await rename(nextPath, targetPath);
|
|
147
|
+
if (targetMoved) {
|
|
148
|
+
await rm(backupPath, { force: true, recursive: true });
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
if (targetMoved && !(await pathExists(targetPath))) {
|
|
153
|
+
await rename(backupPath, targetPath).catch(() => { });
|
|
154
|
+
}
|
|
155
|
+
throw error;
|
|
156
|
+
}
|
|
157
|
+
finally {
|
|
158
|
+
await rm(backupPath, { force: true, recursive: true }).catch(() => { });
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
/**
|
|
162
|
+
* @description
|
|
163
|
+
* Removes a path through a temporary rename so deletion is completed atomically.
|
|
164
|
+
*/
|
|
165
|
+
export const removePathAtomically = async (targetPath) => {
|
|
166
|
+
const stats = await getPathStats(targetPath);
|
|
167
|
+
if (stats === undefined) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
const backupPath = join(dirname(targetPath), `.${basename(targetPath)}.dotweave-sync-remove-${randomUUID()}`);
|
|
171
|
+
await rename(targetPath, backupPath);
|
|
172
|
+
await rm(backupPath, { force: true, recursive: true });
|
|
173
|
+
};
|
|
174
|
+
/**
|
|
175
|
+
* @description
|
|
176
|
+
* Writes text content through a staging directory before replacing the target file.
|
|
177
|
+
*/
|
|
178
|
+
export const writeTextFileAtomically = async (targetPath, contents) => {
|
|
179
|
+
await mkdir(dirname(targetPath), { recursive: true });
|
|
180
|
+
const stagingDirectory = await mkdtemp(join(dirname(targetPath), `.${basename(targetPath)}.dotweave-sync-`));
|
|
181
|
+
const stagedPath = join(stagingDirectory, basename(targetPath));
|
|
182
|
+
try {
|
|
183
|
+
await writeFile(stagedPath, contents, "utf8");
|
|
184
|
+
await replacePathAtomically(targetPath, stagedPath);
|
|
185
|
+
}
|
|
186
|
+
finally {
|
|
187
|
+
await rm(stagingDirectory, { force: true, recursive: true });
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
//# sourceMappingURL=filesystem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filesystem.js","sourceRoot":"","sources":["../../src/lib/filesystem.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EACL,MAAM,EACN,KAAK,EACL,KAAK,EACL,KAAK,EACL,OAAO,EACP,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,EAAE,EACF,IAAI,EACJ,OAAO,EACP,SAAS,GACV,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9E;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,EAAE,IAAY,EAAE,EAAE;IAC/C,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,IAAI,KAAK,YAAY,KAAK,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACzE,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAAE,IAAY,EAAE,EAAE;IACjD,IAAI,CAAC;QACH,OAAO,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,IACE,KAAK,YAAY,KAAK;YACtB,MAAM,IAAI,KAAK;YACf,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,EACrD,CAAC;YACD,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,EAAE,IAAY,EAAE,EAAE;IACzD,IAAI,CAAC;QACH,OAAO,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,IACE,KAAK,YAAY,KAAK;YACtB,MAAM,IAAI,KAAK;YACf,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,EACrD,CAAC;YACD,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,EAAE,IAAY,EAAE,EAAE;IACzD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7D,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QAClC,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAChC,IAAY,EACZ,IAGE,EACF,QAAiB,EACjB,EAAE;IACF,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrC,MAAM,KAAK,CAAC,IAAI,EAAE,QAAQ,IAAI,mBAAmB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;AACtE,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAChC,MAAc,EACd,IAAY,EACZ,IAAkC,EAClC,EAAE;IACF,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,MAAM,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC5B,OAAO;IACT,CAAC;IAED,wEAAwE;IACxE,kFAAkF;IAClF,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,MAAM,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAClC,OAAO;IACT,CAAC;IAED,MAAM,cAAc,GAAG,UAAU,CAAC,MAAM,CAAC;QACvC,CAAC,CAAC,MAAM;QACR,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;IAChC,MAAM,KAAK,GAAG,MAAM,oBAAoB,CAAC,cAAc,CAAC,CAAC;IACzD,MAAM,YAAY,GAAG,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC;IAEhE,MAAM,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;AAC5C,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EAAE,IAAY,EAAE,UAAkB,EAAE,EAAE;IACzE,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACjD,MAAM,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;AACxC,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,EACrC,UAAkB,EAClB,UAAkB,EAClB,KAAyC,EACzC,EAAE;IACF,MAAM,WAAW,GAAG,KAAK,IAAI,CAAC,MAAM,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;IAEvD,IAAI,WAAW,CAAC,WAAW,EAAE,EAAE,CAAC;QAC9B,MAAM,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE7C,MAAM,OAAO,GAAG,MAAM,oBAAoB,CAAC,UAAU,CAAC,CAAC;QAEvD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,kBAAkB,CACtB,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,EAC5B,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,CAC7B,CAAC;QACJ,CAAC;QAED,OAAO;IACT,CAAC;IAED,IAAI,WAAW,CAAC,cAAc,EAAE,EAAE,CAAC;QACjC,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC,CAAC;QAC9C,MAAM,gBAAgB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;QAE/C,OAAO;IACT,CAAC;IAED,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC;QAC1B,MAAM,IAAI,aAAa,CAAC,iCAAiC,UAAU,EAAE,CAAC,CAAC;IACzE,CAAC;IAED,MAAM,aAAa,CAAC,UAAU,EAAE;QAC9B,QAAQ,EAAE,MAAM,QAAQ,CAAC,UAAU,CAAC;QACpC,UAAU,EAAE,gBAAgB,CAAC,WAAW,CAAC,IAAI,CAAC;KAC/C,CAAC,CAAC;AACL,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,EACxC,UAAkB,EAClB,QAAgB,EAChB,EAAE;IACF,MAAM,UAAU,GAAG,IAAI,CACrB,OAAO,CAAC,UAAU,CAAC,EACnB,IAAI,QAAQ,CAAC,UAAU,CAAC,yBAAyB,UAAU,EAAE,EAAE,CAChE,CAAC;IACF,MAAM,aAAa,GAAG,MAAM,YAAY,CAAC,UAAU,CAAC,CAAC;IACrD,IAAI,WAAW,GAAG,KAAK,CAAC;IAExB,IAAI,CAAC;QACH,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;YAChC,MAAM,MAAM,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;YACrC,WAAW,GAAG,IAAI,CAAC;QACrB,CAAC;QAED,MAAM,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QAEnC,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,EAAE,CAAC,UAAU,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,IAAI,WAAW,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;YACnD,MAAM,MAAM,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACvD,CAAC;QAED,MAAM,KAAK,CAAC;IACd,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,CAAC,UAAU,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACzE,CAAC;AACH,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,EAAE,UAAkB,EAAE,EAAE;IAC/D,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,UAAU,CAAC,CAAC;IAE7C,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO;IACT,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CACrB,OAAO,CAAC,UAAU,CAAC,EACnB,IAAI,QAAQ,CAAC,UAAU,CAAC,yBAAyB,UAAU,EAAE,EAAE,CAChE,CAAC;IAEF,MAAM,MAAM,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IACrC,MAAM,EAAE,CAAC,UAAU,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AACzD,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,KAAK,EAC1C,UAAkB,EAClB,QAAgB,EAChB,EAAE;IACF,MAAM,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,MAAM,gBAAgB,GAAG,MAAM,OAAO,CACpC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,IAAI,QAAQ,CAAC,UAAU,CAAC,iBAAiB,CAAC,CACrE,CAAC;IACF,MAAM,UAAU,GAAG,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;IAEhE,IAAI,CAAC;QACH,MAAM,SAAS,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC9C,MAAM,qBAAqB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IACtD,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,CAAC,gBAAgB,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ConsolaInstance } from "consola";
|
|
2
|
+
/**
|
|
3
|
+
* @description
|
|
4
|
+
* Verifies that a directory is already a git working tree.
|
|
5
|
+
*/
|
|
6
|
+
export declare const ensureRepository: (directory: string) => Promise<void>;
|
|
7
|
+
/**
|
|
8
|
+
* @description
|
|
9
|
+
* Creates a sync directory locally or clones it from a remote source.
|
|
10
|
+
*/
|
|
11
|
+
export declare const initializeRepository: (directory: string, source?: string, reporter?: ConsolaInstance) => Promise<{
|
|
12
|
+
action: "initialized";
|
|
13
|
+
source?: undefined;
|
|
14
|
+
} | {
|
|
15
|
+
action: "cloned";
|
|
16
|
+
source: string;
|
|
17
|
+
}>;
|
|
18
|
+
/**
|
|
19
|
+
* @description
|
|
20
|
+
* Ensures the sync directory is a usable git repository for dotweave commands.
|
|
21
|
+
*/
|
|
22
|
+
export declare const ensureGitRepository: (syncDirectory: string) => Promise<void>;
|
|
23
|
+
//# sourceMappingURL=git.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/lib/git.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAmK/C;;;GAGG;AACH,eAAO,MAAM,gBAAgB,GAAU,WAAW,MAAM,kBAEvD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,GAC/B,WAAW,MAAM,EACjB,SAAS,MAAM,EACf,WAAW,eAAe;;;;;;EAoB3B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAU,eAAe,MAAM,kBAU9D,CAAC"}
|
package/dist/lib/git.js
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { execFile, spawn } from "node:child_process";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
import { wrapUnknownError } from "#app/lib/error.ts";
|
|
4
|
+
const execFileAsync = promisify(execFile);
|
|
5
|
+
/**
|
|
6
|
+
* @description
|
|
7
|
+
* Runs a git command and normalizes failures into concise errors.
|
|
8
|
+
*/
|
|
9
|
+
const runGitCommand = async (args, options) => {
|
|
10
|
+
try {
|
|
11
|
+
const result = await execFileAsync("git", [...args], {
|
|
12
|
+
cwd: options?.cwd,
|
|
13
|
+
encoding: "utf8",
|
|
14
|
+
maxBuffer: 10_000_000,
|
|
15
|
+
});
|
|
16
|
+
return {
|
|
17
|
+
stderr: result.stderr,
|
|
18
|
+
stdout: result.stdout,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
if (error instanceof Error && "stderr" in error) {
|
|
23
|
+
const stderr = typeof error.stderr === "string" ? error.stderr.trim() : undefined;
|
|
24
|
+
const stdout = "stdout" in error && typeof error.stdout === "string"
|
|
25
|
+
? error.stdout.trim()
|
|
26
|
+
: undefined;
|
|
27
|
+
const message = stderr || stdout || error.message;
|
|
28
|
+
throw new Error(message);
|
|
29
|
+
}
|
|
30
|
+
throw new Error(error instanceof Error ? error.message : "git failed.");
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* @description
|
|
35
|
+
* Streams git progress lines to the reporter as complete messages arrive.
|
|
36
|
+
*/
|
|
37
|
+
const forwardGitProgressChunk = (reporter, state, chunk) => {
|
|
38
|
+
if (!((reporter?.level ?? 0) >= 4)) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
state.remainder += chunk.replaceAll("\r", "\n");
|
|
42
|
+
const lines = state.remainder.split("\n");
|
|
43
|
+
state.remainder = lines.pop() ?? "";
|
|
44
|
+
for (const line of lines) {
|
|
45
|
+
const trimmed = line.trim();
|
|
46
|
+
if (trimmed.length > 0) {
|
|
47
|
+
reporter?.verbose(`git: ${trimmed}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* @description
|
|
53
|
+
* Flushes any final buffered git progress line to the reporter.
|
|
54
|
+
*/
|
|
55
|
+
const flushGitProgressChunk = (reporter, state) => {
|
|
56
|
+
if (!((reporter?.level ?? 0) >= 4)) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const trimmed = state.remainder.trim();
|
|
60
|
+
if (trimmed.length > 0) {
|
|
61
|
+
reporter?.verbose(`git: ${trimmed}`);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* @description
|
|
66
|
+
* Runs a git command while collecting output and forwarding verbose progress.
|
|
67
|
+
*/
|
|
68
|
+
const runStreamingGitCommand = async (args, options) => {
|
|
69
|
+
return await new Promise((resolve, reject) => {
|
|
70
|
+
const child = spawn("git", [...args], {
|
|
71
|
+
cwd: options?.cwd,
|
|
72
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
73
|
+
});
|
|
74
|
+
let settled = false;
|
|
75
|
+
let stdout = "";
|
|
76
|
+
let stderr = "";
|
|
77
|
+
const stdoutState = { remainder: "" };
|
|
78
|
+
const stderrState = { remainder: "" };
|
|
79
|
+
const finish = (handler) => {
|
|
80
|
+
if (settled) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
settled = true;
|
|
84
|
+
handler();
|
|
85
|
+
};
|
|
86
|
+
child.stdout?.setEncoding("utf8");
|
|
87
|
+
child.stderr?.setEncoding("utf8");
|
|
88
|
+
child.stdout?.on("data", (chunk) => {
|
|
89
|
+
stdout += chunk;
|
|
90
|
+
forwardGitProgressChunk(options?.reporter, stdoutState, chunk);
|
|
91
|
+
});
|
|
92
|
+
child.stderr?.on("data", (chunk) => {
|
|
93
|
+
stderr += chunk;
|
|
94
|
+
forwardGitProgressChunk(options?.reporter, stderrState, chunk);
|
|
95
|
+
});
|
|
96
|
+
child.on("error", (error) => {
|
|
97
|
+
finish(() => {
|
|
98
|
+
reject(new Error(error instanceof Error ? error.message : "git failed."));
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
child.on("close", (code) => {
|
|
102
|
+
flushGitProgressChunk(options?.reporter, stdoutState);
|
|
103
|
+
flushGitProgressChunk(options?.reporter, stderrState);
|
|
104
|
+
if (code === 0) {
|
|
105
|
+
finish(() => {
|
|
106
|
+
resolve({ stderr, stdout });
|
|
107
|
+
});
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
finish(() => {
|
|
111
|
+
reject(new Error(stderr.trim() ||
|
|
112
|
+
stdout.trim() ||
|
|
113
|
+
`git exited with code ${code ?? "unknown"}.`));
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
};
|
|
118
|
+
/**
|
|
119
|
+
* @description
|
|
120
|
+
* Verifies that a directory is already a git working tree.
|
|
121
|
+
*/
|
|
122
|
+
export const ensureRepository = async (directory) => {
|
|
123
|
+
await runGitCommand(["-C", directory, "rev-parse", "--is-inside-work-tree"]);
|
|
124
|
+
};
|
|
125
|
+
/**
|
|
126
|
+
* @description
|
|
127
|
+
* Creates a sync directory locally or clones it from a remote source.
|
|
128
|
+
*/
|
|
129
|
+
export const initializeRepository = async (directory, source, reporter) => {
|
|
130
|
+
if (source === undefined) {
|
|
131
|
+
await runStreamingGitCommand(["init", "-b", "main", directory], {
|
|
132
|
+
reporter,
|
|
133
|
+
});
|
|
134
|
+
return {
|
|
135
|
+
action: "initialized",
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
await runStreamingGitCommand(["clone", source, directory], {
|
|
139
|
+
reporter,
|
|
140
|
+
});
|
|
141
|
+
return {
|
|
142
|
+
action: "cloned",
|
|
143
|
+
source,
|
|
144
|
+
};
|
|
145
|
+
};
|
|
146
|
+
/**
|
|
147
|
+
* @description
|
|
148
|
+
* Ensures the sync directory is a usable git repository for dotweave commands.
|
|
149
|
+
*/
|
|
150
|
+
export const ensureGitRepository = async (syncDirectory) => {
|
|
151
|
+
try {
|
|
152
|
+
await ensureRepository(syncDirectory);
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
throw wrapUnknownError("Sync repository is not initialized.", error, {
|
|
156
|
+
code: "SYNC_REPO_INVALID",
|
|
157
|
+
details: [`Sync directory: ${syncDirectory}`],
|
|
158
|
+
hint: "Run 'dotweave init' to create or clone the sync directory.",
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
//# sourceMappingURL=git.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/lib/git.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAE1C;;;GAGG;AACH,MAAM,aAAa,GAAG,KAAK,EACzB,IAAuB,EACvB,OAAoC,EACpC,EAAE;IACF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE;YACnD,GAAG,EAAE,OAAO,EAAE,GAAG;YACjB,QAAQ,EAAE,MAAM;YAChB,SAAS,EAAE,UAAU;SACtB,CAAC,CAAC;QAEH,OAAO;YACL,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,MAAM,EAAE,MAAM,CAAC,MAAM;SACtB,CAAC;IACJ,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,IAAI,KAAK,YAAY,KAAK,IAAI,QAAQ,IAAI,KAAK,EAAE,CAAC;YAChD,MAAM,MAAM,GACV,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;YACrE,MAAM,MAAM,GACV,QAAQ,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ;gBACnD,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE;gBACrB,CAAC,CAAC,SAAS,CAAC;YAChB,MAAM,OAAO,GAAG,MAAM,IAAI,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC;YAElD,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;QAC3B,CAAC;QAED,MAAM,IAAI,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;IAC1E,CAAC;AACH,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,uBAAuB,GAAG,CAC9B,QAAqC,EACrC,KAA4B,EAC5B,KAAa,EACb,EAAE;IACF,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,KAAK,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;QACnC,OAAO;IACT,CAAC;IAED,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAE1C,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;IAEpC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAE5B,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,QAAQ,EAAE,OAAO,CAAC,QAAQ,OAAO,EAAE,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;AACH,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,qBAAqB,GAAG,CAC5B,QAAqC,EACrC,KAA4B,EAC5B,EAAE;IACF,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,KAAK,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;QACnC,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;IAEvC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,QAAQ,EAAE,OAAO,CAAC,QAAQ,OAAO,EAAE,CAAC,CAAC;IACvC,CAAC;AACH,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,sBAAsB,GAAG,KAAK,EAClC,IAAuB,EACvB,OAGE,EACF,EAAE;IACF,OAAO,MAAM,IAAI,OAAO,CAGrB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrB,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE;YACpC,GAAG,EAAE,OAAO,EAAE,GAAG;YACjB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;SAClC,CAAC,CAAC;QACH,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,MAAM,WAAW,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;QACtC,MAAM,WAAW,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;QAEtC,MAAM,MAAM,GAAG,CAAC,OAAmB,EAAE,EAAE;YACrC,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO;YACT,CAAC;YAED,OAAO,GAAG,IAAI,CAAC;YACf,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC;QAEF,KAAK,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;QAClC,KAAK,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;QAClC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YACzC,MAAM,IAAI,KAAK,CAAC;YAChB,uBAAuB,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YACzC,MAAM,IAAI,KAAK,CAAC;YAChB,uBAAuB,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YAC1B,MAAM,CAAC,GAAG,EAAE;gBACV,MAAM,CACJ,IAAI,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAClE,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACzB,qBAAqB,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;YACtD,qBAAqB,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;YAEtD,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;gBACf,MAAM,CAAC,GAAG,EAAE;oBACV,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;gBAC9B,CAAC,CAAC,CAAC;gBAEH,OAAO;YACT,CAAC;YAED,MAAM,CAAC,GAAG,EAAE;gBACV,MAAM,CACJ,IAAI,KAAK,CACP,MAAM,CAAC,IAAI,EAAE;oBACX,MAAM,CAAC,IAAI,EAAE;oBACb,wBAAwB,IAAI,IAAI,SAAS,GAAG,CAC/C,CACF,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EAAE,SAAiB,EAAE,EAAE;IAC1D,MAAM,aAAa,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,uBAAuB,CAAC,CAAC,CAAC;AAC/E,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,EACvC,SAAiB,EACjB,MAAe,EACf,QAA0B,EAC1B,EAAE;IACF,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,sBAAsB,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE;YAC9D,QAAQ;SACT,CAAC,CAAC;QAEH,OAAO;YACL,MAAM,EAAE,aAAsB;SAC/B,CAAC;IACJ,CAAC;IAED,MAAM,sBAAsB,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE;QACzD,QAAQ;KACT,CAAC,CAAC;IAEH,OAAO;QACL,MAAM,EAAE,QAAiB;QACzB,MAAM;KACP,CAAC;AACJ,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,EAAE,aAAqB,EAAE,EAAE;IACjE,IAAI,CAAC;QACH,MAAM,gBAAgB,CAAC,aAAa,CAAC,CAAC;IACxC,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,MAAM,gBAAgB,CAAC,qCAAqC,EAAE,KAAK,EAAE;YACnE,IAAI,EAAE,mBAAmB;YACzB,OAAO,EAAE,CAAC,mBAAmB,aAAa,EAAE,CAAC;YAC7C,IAAI,EAAE,4DAA4D;SACnE,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Strips single-line (//) and block (/* *\/) comments from a JSONC string.
|
|
3
|
+
* Uses a state machine to avoid stripping comment-like sequences inside string literals.
|
|
4
|
+
*/
|
|
5
|
+
export declare const stripJsoncComments: (input: string) => string;
|
|
6
|
+
export declare const parseJsonc: (input: string) => unknown;
|
|
7
|
+
export declare const resolveJsoncConfigPath: (preferredPath: string) => Promise<string>;
|
|
8
|
+
//# sourceMappingURL=jsonc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonc.d.ts","sourceRoot":"","sources":["../../src/lib/jsonc.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAAI,OAAO,MAAM,KAAG,MAyDlD,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,OAAO,MAAM,KAAG,OAE1C,CAAC;AAEF,eAAO,MAAM,sBAAsB,GACjC,eAAe,MAAM,KACpB,OAAO,CAAC,MAAM,CAehB,CAAC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { DotweaveError } from "#app/lib/error.ts";
|
|
2
|
+
import { pathExists } from "#app/lib/filesystem.ts";
|
|
3
|
+
/**
|
|
4
|
+
* Strips single-line (//) and block (/* *\/) comments from a JSONC string.
|
|
5
|
+
* Uses a state machine to avoid stripping comment-like sequences inside string literals.
|
|
6
|
+
*/
|
|
7
|
+
export const stripJsoncComments = (input) => {
|
|
8
|
+
let result = "";
|
|
9
|
+
let i = 0;
|
|
10
|
+
while (i < input.length) {
|
|
11
|
+
const char = input[i] ?? "";
|
|
12
|
+
// String literal — pass through verbatim, handling escape sequences
|
|
13
|
+
if (char === '"') {
|
|
14
|
+
result += char;
|
|
15
|
+
i++;
|
|
16
|
+
while (i < input.length) {
|
|
17
|
+
const c = input[i] ?? "";
|
|
18
|
+
result += c;
|
|
19
|
+
if (c === "\\") {
|
|
20
|
+
i++;
|
|
21
|
+
if (i < input.length) {
|
|
22
|
+
result += input[i];
|
|
23
|
+
i++;
|
|
24
|
+
}
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
i++;
|
|
28
|
+
if (c === '"')
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
// Single-line comment: skip until end of line
|
|
34
|
+
if (char === "/" && input[i + 1] === "/") {
|
|
35
|
+
while (i < input.length && input[i] !== "\n") {
|
|
36
|
+
i++;
|
|
37
|
+
}
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
// Block comment: skip until */, preserving newlines for line numbers
|
|
41
|
+
if (char === "/" && input[i + 1] === "*") {
|
|
42
|
+
i += 2;
|
|
43
|
+
while (i < input.length) {
|
|
44
|
+
if (input[i] === "*" && input[i + 1] === "/") {
|
|
45
|
+
i += 2;
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
if (input[i] === "\n") {
|
|
49
|
+
result += "\n";
|
|
50
|
+
}
|
|
51
|
+
i++;
|
|
52
|
+
}
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
result += char;
|
|
56
|
+
i++;
|
|
57
|
+
}
|
|
58
|
+
return result;
|
|
59
|
+
};
|
|
60
|
+
export const parseJsonc = (input) => {
|
|
61
|
+
return JSON.parse(stripJsoncComments(input));
|
|
62
|
+
};
|
|
63
|
+
export const resolveJsoncConfigPath = async (preferredPath) => {
|
|
64
|
+
if (preferredPath.endsWith(".jsonc")) {
|
|
65
|
+
const jsonPath = preferredPath.slice(0, -1); // .jsonc → .json
|
|
66
|
+
if (await pathExists(jsonPath)) {
|
|
67
|
+
throw new DotweaveError("Unsupported dotweave config file.", {
|
|
68
|
+
code: "CONFIG_JSON_UNSUPPORTED",
|
|
69
|
+
details: [
|
|
70
|
+
`Unsupported config file: ${jsonPath}`,
|
|
71
|
+
`Supported config file: ${preferredPath}`,
|
|
72
|
+
],
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return preferredPath;
|
|
77
|
+
};
|
|
78
|
+
//# sourceMappingURL=jsonc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonc.js","sourceRoot":"","sources":["../../src/lib/jsonc.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description
|
|
3
|
+
* Normalizes repository directory paths into a stable keyed form.
|
|
4
|
+
*/
|
|
5
|
+
export declare const buildDirectoryKey: (repoPath: string) => string;
|
|
6
|
+
/**
|
|
7
|
+
* @description
|
|
8
|
+
* Checks whether a path is the same as or contained within a root path.
|
|
9
|
+
*/
|
|
10
|
+
export declare const isPathEqualOrNested: (path: string, rootPath: string) => boolean;
|
|
11
|
+
/**
|
|
12
|
+
* @description
|
|
13
|
+
* Detects whether two paths cover any shared directory scope.
|
|
14
|
+
*/
|
|
15
|
+
export declare const doPathsOverlap: (leftPath: string, rightPath: string) => boolean;
|
|
16
|
+
/**
|
|
17
|
+
* @description
|
|
18
|
+
* Identifies path inputs that should be treated as explicit local filesystem targets.
|
|
19
|
+
*/
|
|
20
|
+
export declare const isExplicitLocalPath: (target: string) => boolean;
|
|
21
|
+
//# sourceMappingURL=path.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../src/lib/path.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,eAAO,MAAM,iBAAiB,GAAI,UAAU,MAAM,WAEjD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,MAAM,MAAM,EAAE,UAAU,MAAM,YASjE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc,GAAI,UAAU,MAAM,EAAE,WAAW,MAAM,YAKjE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,QAAQ,MAAM,YAYjD,CAAC"}
|
package/dist/lib/path.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { isAbsolute, relative } from "node:path";
|
|
2
|
+
const homePrefix = "~";
|
|
3
|
+
const shellPathSeparator = "/";
|
|
4
|
+
/**
|
|
5
|
+
* @description
|
|
6
|
+
* Normalizes repository directory paths into a stable keyed form.
|
|
7
|
+
*/
|
|
8
|
+
export const buildDirectoryKey = (repoPath) => {
|
|
9
|
+
return `${repoPath}/`;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* @description
|
|
13
|
+
* Checks whether a path is the same as or contained within a root path.
|
|
14
|
+
*/
|
|
15
|
+
export const isPathEqualOrNested = (path, rootPath) => {
|
|
16
|
+
const rootToPath = relative(rootPath, path);
|
|
17
|
+
return (rootToPath === "" ||
|
|
18
|
+
(!isAbsolute(rootToPath) &&
|
|
19
|
+
!rootToPath.startsWith("..") &&
|
|
20
|
+
rootToPath !== ".."));
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* @description
|
|
24
|
+
* Detects whether two paths cover any shared directory scope.
|
|
25
|
+
*/
|
|
26
|
+
export const doPathsOverlap = (leftPath, rightPath) => {
|
|
27
|
+
return (isPathEqualOrNested(leftPath, rightPath) ||
|
|
28
|
+
isPathEqualOrNested(rightPath, leftPath));
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* @description
|
|
32
|
+
* Identifies path inputs that should be treated as explicit local filesystem targets.
|
|
33
|
+
*/
|
|
34
|
+
export const isExplicitLocalPath = (target) => {
|
|
35
|
+
const homePathPrefix = `${homePrefix}${shellPathSeparator}`;
|
|
36
|
+
return (target === "." ||
|
|
37
|
+
target === ".." ||
|
|
38
|
+
target === homePrefix ||
|
|
39
|
+
target.startsWith("./") ||
|
|
40
|
+
target.startsWith("../") ||
|
|
41
|
+
target.startsWith(homePathPrefix) ||
|
|
42
|
+
isAbsolute(target));
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=path.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path.js","sourceRoot":"","sources":["../../src/lib/path.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAEjD,MAAM,UAAU,GAAG,GAAG,CAAC;AACvB,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAE/B;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,QAAgB,EAAE,EAAE;IACpD,OAAO,GAAG,QAAQ,GAAG,CAAC;AACxB,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,IAAY,EAAE,QAAgB,EAAE,EAAE;IACpE,MAAM,UAAU,GAAG,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAE5C,OAAO,CACL,UAAU,KAAK,EAAE;QACjB,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC;YACtB,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC;YAC5B,UAAU,KAAK,IAAI,CAAC,CACvB,CAAC;AACJ,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,QAAgB,EAAE,SAAiB,EAAE,EAAE;IACpE,OAAO,CACL,mBAAmB,CAAC,QAAQ,EAAE,SAAS,CAAC;QACxC,mBAAmB,CAAC,SAAS,EAAE,QAAQ,CAAC,CACzC,CAAC;AACJ,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,MAAc,EAAE,EAAE;IACpD,MAAM,cAAc,GAAG,GAAG,UAAU,GAAG,kBAAkB,EAAE,CAAC;IAE5D,OAAO,CACL,MAAM,KAAK,GAAG;QACd,MAAM,KAAK,IAAI;QACf,MAAM,KAAK,UAAU;QACrB,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;QACvB,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC;QACxB,MAAM,CAAC,UAAU,CAAC,cAAc,CAAC;QACjC,UAAU,CAAC,MAAM,CAAC,CACnB,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Limits the number of concurrent asynchronous operations.
|
|
3
|
+
*
|
|
4
|
+
* @param concurrency - The maximum number of concurrent operations.
|
|
5
|
+
* @param items - The items to process.
|
|
6
|
+
* @param mapper - The mapping function that returns a promise.
|
|
7
|
+
* @returns A promise that resolves to an array of the results.
|
|
8
|
+
*/
|
|
9
|
+
export declare const limitConcurrency: <T, R>(concurrency: number, items: readonly T[], mapper: (item: T, index: number) => Promise<R>) => Promise<R[]>;
|
|
10
|
+
//# sourceMappingURL=promise.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promise.d.ts","sourceRoot":"","sources":["../../src/lib/promise.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,GAAU,CAAC,EAAE,CAAC,EACzC,aAAa,MAAM,EACnB,OAAO,SAAS,CAAC,EAAE,EACnB,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,KAC7C,OAAO,CAAC,CAAC,EAAE,CAsBb,CAAC"}
|