@tinyrack/dotweave 0.42.13 → 0.42.21
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/README.md +6 -2
- package/dist/application.d.ts +0 -3
- package/dist/application.d.ts.map +1 -1
- package/dist/application.js +23 -22
- package/dist/application.js.map +1 -1
- package/dist/cli/autocomplete.d.ts +5 -4
- package/dist/cli/autocomplete.d.ts.map +1 -1
- package/dist/cli/autocomplete.js +33 -28
- package/dist/cli/autocomplete.js.map +1 -1
- package/dist/cli/cd.d.ts +2 -2
- package/dist/cli/cd.d.ts.map +1 -1
- package/dist/cli/cd.js +1 -4
- package/dist/cli/cd.js.map +1 -1
- package/dist/cli/doctor.d.ts +2 -2
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +19 -28
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/index.d.ts +1 -3
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +5 -5
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init.d.ts +2 -2
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +9 -15
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/profile/add.d.ts +4 -0
- package/dist/cli/profile/add.d.ts.map +1 -0
- package/dist/cli/profile/add.js +29 -0
- package/dist/cli/profile/add.js.map +1 -0
- package/dist/cli/profile/index.d.ts +1 -1
- package/dist/cli/profile/index.d.ts.map +1 -1
- package/dist/cli/profile/index.js +5 -1
- package/dist/cli/profile/index.js.map +1 -1
- package/dist/cli/profile/list.d.ts +2 -2
- package/dist/cli/profile/list.d.ts.map +1 -1
- package/dist/cli/profile/list.js +8 -26
- package/dist/cli/profile/list.js.map +1 -1
- package/dist/cli/profile/remove.d.ts +4 -0
- package/dist/cli/profile/remove.d.ts.map +1 -0
- package/dist/cli/profile/remove.js +29 -0
- package/dist/cli/profile/remove.js.map +1 -0
- package/dist/cli/profile/use.d.ts +2 -2
- package/dist/cli/profile/use.d.ts.map +1 -1
- package/dist/cli/profile/use.js +5 -14
- package/dist/cli/profile/use.js.map +1 -1
- package/dist/cli/pull.d.ts +2 -2
- package/dist/cli/pull.d.ts.map +1 -1
- package/dist/cli/pull.js +22 -41
- package/dist/cli/pull.js.map +1 -1
- package/dist/cli/push.d.ts +2 -2
- package/dist/cli/push.d.ts.map +1 -1
- package/dist/cli/push.js +17 -23
- package/dist/cli/push.js.map +1 -1
- package/dist/cli/root-commands.d.ts +9 -10
- package/dist/cli/root-commands.d.ts.map +1 -1
- package/dist/cli/root-commands.js +0 -4
- package/dist/cli/root-commands.js.map +1 -1
- package/dist/cli/shared-flags.d.ts +9 -0
- package/dist/cli/shared-flags.d.ts.map +1 -0
- package/dist/cli/shared-flags.js +8 -0
- package/dist/cli/shared-flags.js.map +1 -0
- package/dist/cli/status.d.ts +2 -2
- package/dist/cli/status.d.ts.map +1 -1
- package/dist/cli/status.js +26 -55
- package/dist/cli/status.js.map +1 -1
- package/dist/cli/track.d.ts +2 -2
- package/dist/cli/track.d.ts.map +1 -1
- package/dist/cli/track.js +19 -35
- package/dist/cli/track.js.map +1 -1
- package/dist/cli/untrack.d.ts +2 -2
- package/dist/cli/untrack.d.ts.map +1 -1
- package/dist/cli/untrack.js +5 -14
- package/dist/cli/untrack.js.map +1 -1
- package/dist/config/constants.d.ts +2 -2
- package/dist/config/constants.d.ts.map +1 -1
- package/dist/config/constants.js +2 -2
- package/dist/config/constants.js.map +1 -1
- package/dist/config/global-config.d.ts +3 -3
- package/dist/config/global-config.d.ts.map +1 -1
- package/dist/config/global-config.js +7 -8
- package/dist/config/global-config.js.map +1 -1
- package/dist/config/identity-file.d.ts +0 -7
- package/dist/config/identity-file.d.ts.map +1 -1
- package/dist/config/identity-file.js +2 -44
- package/dist/config/identity-file.js.map +1 -1
- package/dist/config/migration.d.ts +6 -0
- package/dist/config/migration.d.ts.map +1 -1
- package/dist/config/migration.js +35 -13
- package/dist/config/migration.js.map +1 -1
- package/dist/config/runtime-env.d.ts.map +1 -1
- package/dist/config/runtime-env.js +2 -7
- package/dist/config/runtime-env.js.map +1 -1
- package/dist/config/{sync-entry.d.ts → sync-queries.d.ts} +5 -3
- package/dist/config/sync-queries.d.ts.map +1 -0
- package/dist/config/{sync-entry.js → sync-queries.js} +15 -6
- package/dist/config/sync-queries.js.map +1 -0
- package/dist/config/sync-schema.d.ts +13 -8
- package/dist/config/sync-schema.d.ts.map +1 -1
- package/dist/config/sync-schema.js +138 -18
- package/dist/config/sync-schema.js.map +1 -1
- package/dist/config/xdg.d.ts.map +1 -1
- package/dist/config/xdg.js +15 -34
- package/dist/config/xdg.js.map +1 -1
- package/dist/lib/error.js +1 -1
- package/dist/lib/error.js.map +1 -1
- package/dist/lib/git.d.ts +3 -4
- package/dist/lib/git.d.ts.map +1 -1
- package/dist/lib/git.js +7 -48
- package/dist/lib/git.js.map +1 -1
- package/dist/lib/jsonc.d.ts +1 -1
- package/dist/lib/jsonc.d.ts.map +1 -1
- package/dist/lib/jsonc.js +1 -1
- package/dist/lib/jsonc.js.map +1 -1
- package/dist/lib/path.d.ts +3 -16
- package/dist/lib/path.d.ts.map +1 -1
- package/dist/lib/path.js +36 -19
- package/dist/lib/path.js.map +1 -1
- package/dist/lib/string.d.ts +1 -4
- package/dist/lib/string.d.ts.map +1 -1
- package/dist/lib/string.js +6 -4
- package/dist/lib/string.js.map +1 -1
- package/dist/lib/version.d.ts.map +1 -1
- package/dist/lib/version.js +2 -2
- package/dist/lib/version.js.map +1 -1
- package/dist/migrations/sync-v8.d.ts +3 -0
- package/dist/migrations/sync-v8.d.ts.map +1 -0
- package/dist/migrations/sync-v8.js +66 -0
- package/dist/migrations/sync-v8.js.map +1 -0
- package/dist/services/autocomplete.js +13 -13
- package/dist/services/autocomplete.js.map +1 -1
- package/dist/services/config-file.d.ts +6 -5
- package/dist/services/config-file.d.ts.map +1 -1
- package/dist/services/config-file.js +9 -8
- package/dist/services/config-file.js.map +1 -1
- package/dist/services/doctor.d.ts +1 -4
- package/dist/services/doctor.d.ts.map +1 -1
- package/dist/services/doctor.js +10 -37
- package/dist/services/doctor.js.map +1 -1
- package/dist/services/init.d.ts +1 -5
- package/dist/services/init.d.ts.map +1 -1
- package/dist/services/init.js +25 -59
- package/dist/services/init.js.map +1 -1
- package/dist/services/local-snapshot.d.ts +2 -7
- package/dist/services/local-snapshot.d.ts.map +1 -1
- package/dist/services/local-snapshot.js +12 -35
- package/dist/services/local-snapshot.js.map +1 -1
- package/dist/services/profile.d.ts +8 -4
- package/dist/services/profile.d.ts.map +1 -1
- package/dist/services/profile.js +110 -34
- package/dist/services/profile.js.map +1 -1
- package/dist/services/pull-apply.d.ts +30 -0
- package/dist/services/pull-apply.d.ts.map +1 -0
- package/dist/services/{local-materialization.js → pull-apply.js} +150 -210
- package/dist/services/pull-apply.js.map +1 -0
- package/dist/services/pull.d.ts +7 -10
- package/dist/services/pull.d.ts.map +1 -1
- package/dist/services/pull.js +19 -30
- package/dist/services/pull.js.map +1 -1
- package/dist/services/push.d.ts +4 -7
- package/dist/services/push.d.ts.map +1 -1
- package/dist/services/push.js +15 -38
- package/dist/services/push.js.map +1 -1
- package/dist/services/repo-artifacts.d.ts +5 -6
- package/dist/services/repo-artifacts.d.ts.map +1 -1
- package/dist/services/repo-artifacts.js +21 -60
- package/dist/services/repo-artifacts.js.map +1 -1
- package/dist/services/repo-snapshot.d.ts +2 -3
- package/dist/services/repo-snapshot.d.ts.map +1 -1
- package/dist/services/repo-snapshot.js +14 -26
- package/dist/services/repo-snapshot.js.map +1 -1
- package/dist/services/status.d.ts +1 -5
- package/dist/services/status.d.ts.map +1 -1
- package/dist/services/status.js +7 -17
- package/dist/services/status.js.map +1 -1
- package/dist/services/{runtime.d.ts → sync-context.d.ts} +9 -3
- package/dist/services/sync-context.d.ts.map +1 -0
- package/dist/services/{runtime.js → sync-context.js} +24 -8
- package/dist/services/sync-context.js.map +1 -0
- package/dist/services/{set.d.ts → sync-mode.d.ts} +7 -9
- package/dist/services/sync-mode.d.ts.map +1 -0
- package/dist/services/{set.js → sync-mode.js} +9 -23
- package/dist/services/sync-mode.js.map +1 -0
- package/dist/services/{paths.d.ts → sync-paths.d.ts} +2 -2
- package/dist/services/sync-paths.d.ts.map +1 -0
- package/dist/services/{paths.js → sync-paths.js} +4 -6
- package/dist/services/sync-paths.js.map +1 -0
- package/dist/services/terminal/logger.d.ts +30 -5
- package/dist/services/terminal/logger.d.ts.map +1 -1
- package/dist/services/terminal/logger.js +61 -14
- package/dist/services/terminal/logger.js.map +1 -1
- package/dist/services/terminal/path-completion.d.ts +2 -2
- package/dist/services/terminal/path-completion.d.ts.map +1 -1
- package/dist/services/terminal/path-completion.js +16 -13
- package/dist/services/terminal/path-completion.js.map +1 -1
- package/dist/services/terminal/shell.d.ts +1 -12
- package/dist/services/terminal/shell.d.ts.map +1 -1
- package/dist/services/terminal/shell.js +7 -160
- package/dist/services/terminal/shell.js.map +1 -1
- package/dist/services/terminal/spinner.d.ts +10 -0
- package/dist/services/terminal/spinner.d.ts.map +1 -0
- package/dist/services/terminal/spinner.js +61 -0
- package/dist/services/terminal/spinner.js.map +1 -0
- package/dist/services/terminal/theme.d.ts +31 -0
- package/dist/services/terminal/theme.d.ts.map +1 -0
- package/dist/services/terminal/theme.js +32 -0
- package/dist/services/terminal/theme.js.map +1 -0
- package/dist/services/track.d.ts +1 -3
- package/dist/services/track.d.ts.map +1 -1
- package/dist/services/track.js +27 -23
- package/dist/services/track.js.map +1 -1
- package/dist/services/untrack.d.ts +0 -2
- package/dist/services/untrack.d.ts.map +1 -1
- package/dist/services/untrack.js +4 -11
- package/dist/services/untrack.js.map +1 -1
- package/package.json +1 -2
- package/dist/config/sync-entry.d.ts.map +0 -1
- package/dist/config/sync-entry.js.map +0 -1
- package/dist/config/sync.d.ts +0 -8
- package/dist/config/sync.d.ts.map +0 -1
- package/dist/config/sync.js +0 -53
- package/dist/config/sync.js.map +0 -1
- package/dist/services/local-materialization.d.ts +0 -30
- package/dist/services/local-materialization.d.ts.map +0 -1
- package/dist/services/local-materialization.js.map +0 -1
- package/dist/services/paths.d.ts.map +0 -1
- package/dist/services/paths.js.map +0 -1
- package/dist/services/runtime.d.ts.map +0 -1
- package/dist/services/runtime.js.map +0 -1
- package/dist/services/set.d.ts.map +0 -1
- package/dist/services/set.js.map +0 -1
- package/dist/services/terminal/cli-runtime.d.ts +0 -18
- package/dist/services/terminal/cli-runtime.d.ts.map +0 -1
- package/dist/services/terminal/cli-runtime.js +0 -19
- package/dist/services/terminal/cli-runtime.js.map +0 -1
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
export type ConfigMigrationFn = (config: Record<string, unknown>) => Record<string, unknown>;
|
|
2
2
|
export type ConfigMigrationRegistry = ReadonlyMap<number, ConfigMigrationFn>;
|
|
3
|
+
export type ConfigMigrationResult = Readonly<{
|
|
4
|
+
config: unknown;
|
|
5
|
+
migrated: boolean;
|
|
6
|
+
originalVersion?: number;
|
|
7
|
+
}>;
|
|
8
|
+
export declare const applyConfigMigrations: (rawConfig: unknown, registry: ConfigMigrationRegistry, targetVersion: number, filePath: string) => ConfigMigrationResult;
|
|
3
9
|
/**
|
|
4
10
|
* Applies sequential config migrations from the detected version up to targetVersion.
|
|
5
11
|
* Creates a backup file before the first migration step, then saves the result.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration.d.ts","sourceRoot":"","sources":["../../src/config/migration.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,iBAAiB,GAAG,CAC9B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE7B,MAAM,MAAM,uBAAuB,GAAG,WAAW,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;AAE7E;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAC9B,WAAW,OAAO,EAClB,UAAU,uBAAuB,EACjC,eAAe,MAAM,EACrB,UAAU,MAAM,KACf,OAAO,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"migration.d.ts","sourceRoot":"","sources":["../../src/config/migration.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,iBAAiB,GAAG,CAC9B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE7B,MAAM,MAAM,uBAAuB,GAAG,WAAW,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;AAE7E,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAC3C,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC,CAAC;AAkBH,eAAO,MAAM,qBAAqB,GAChC,WAAW,OAAO,EAClB,UAAU,uBAAuB,EACjC,eAAe,MAAM,EACrB,UAAU,MAAM,KACf,qBAsEF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAC9B,WAAW,OAAO,EAClB,UAAU,uBAAuB,EACjC,eAAe,MAAM,EACrB,UAAU,MAAM,KACf,OAAO,CAAC,OAAO,CA4BjB,CAAC"}
|
package/dist/config/migration.js
CHANGED
|
@@ -3,25 +3,31 @@ import { basename, dirname, join } from "node:path";
|
|
|
3
3
|
import { DotweaveError } from "#app/lib/error.ts";
|
|
4
4
|
import { writeTextFileAtomically } from "#app/lib/filesystem.ts";
|
|
5
5
|
import { ensureTrailingNewline } from "#app/lib/string.ts";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
const withMigrationContext = (error, filePath, fromVersion) => {
|
|
7
|
+
return new DotweaveError(error.message, {
|
|
8
|
+
code: error.code,
|
|
9
|
+
details: [
|
|
10
|
+
...error.details,
|
|
11
|
+
`Config file: ${filePath}`,
|
|
12
|
+
`Migration: ${fromVersion} → ${fromVersion + 1}`,
|
|
13
|
+
],
|
|
14
|
+
hint: error.hint,
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
export const applyConfigMigrations = (rawConfig, registry, targetVersion, filePath) => {
|
|
12
18
|
if (typeof rawConfig !== "object" ||
|
|
13
19
|
rawConfig === null ||
|
|
14
20
|
Array.isArray(rawConfig)) {
|
|
15
|
-
return rawConfig;
|
|
21
|
+
return { config: rawConfig, migrated: false };
|
|
16
22
|
}
|
|
17
23
|
const configObject = rawConfig;
|
|
18
24
|
// biome-ignore lint/complexity/useLiteralKeys: noPropertyAccessFromIndexSignature requires bracket notation
|
|
19
25
|
const version = configObject["version"];
|
|
20
26
|
if (typeof version !== "number") {
|
|
21
|
-
return rawConfig;
|
|
27
|
+
return { config: rawConfig, migrated: false };
|
|
22
28
|
}
|
|
23
29
|
if (version === targetVersion) {
|
|
24
|
-
return rawConfig;
|
|
30
|
+
return { config: rawConfig, migrated: false, originalVersion: version };
|
|
25
31
|
}
|
|
26
32
|
if (version > targetVersion) {
|
|
27
33
|
throw new DotweaveError(`Config file version ${version} is newer than this CLI supports (max: ${targetVersion}).`, {
|
|
@@ -30,8 +36,6 @@ export const runConfigMigrations = async (rawConfig, registry, targetVersion, fi
|
|
|
30
36
|
hint: "Upgrade dotweave to the latest version.",
|
|
31
37
|
});
|
|
32
38
|
}
|
|
33
|
-
const backupPath = join(dirname(filePath), `${basename(filePath)}.v${version}.bak`);
|
|
34
|
-
await writeFile(backupPath, ensureTrailingNewline(JSON.stringify(configObject, null, 2)), "utf8");
|
|
35
39
|
let current = configObject;
|
|
36
40
|
for (let v = version; v < targetVersion; v++) {
|
|
37
41
|
const migrateFn = registry.get(v);
|
|
@@ -46,16 +50,34 @@ export const runConfigMigrations = async (rawConfig, registry, targetVersion, fi
|
|
|
46
50
|
current = migrateFn(current);
|
|
47
51
|
}
|
|
48
52
|
catch (error) {
|
|
53
|
+
if (error instanceof DotweaveError) {
|
|
54
|
+
throw withMigrationContext(error, filePath, v);
|
|
55
|
+
}
|
|
49
56
|
throw new DotweaveError(`Failed to migrate config from version ${v} to ${v + 1}.`, {
|
|
50
57
|
code: "CONFIG_MIGRATION_FAILED",
|
|
51
58
|
details: [
|
|
52
59
|
`Config file: ${filePath}`,
|
|
60
|
+
`Migration: ${v} → ${v + 1}`,
|
|
53
61
|
...(error instanceof Error ? [error.message] : []),
|
|
54
62
|
],
|
|
55
63
|
});
|
|
56
64
|
}
|
|
57
65
|
}
|
|
58
|
-
|
|
59
|
-
|
|
66
|
+
return { config: current, migrated: true, originalVersion: version };
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Applies sequential config migrations from the detected version up to targetVersion.
|
|
70
|
+
* Creates a backup file before the first migration step, then saves the result.
|
|
71
|
+
* Returns the migrated config (or the original if no migration was needed).
|
|
72
|
+
*/
|
|
73
|
+
export const runConfigMigrations = async (rawConfig, registry, targetVersion, filePath) => {
|
|
74
|
+
const { config, migrated, originalVersion } = applyConfigMigrations(rawConfig, registry, targetVersion, filePath);
|
|
75
|
+
if (!migrated || originalVersion === undefined) {
|
|
76
|
+
return config;
|
|
77
|
+
}
|
|
78
|
+
const backupPath = join(dirname(filePath), `${basename(filePath)}.v${originalVersion}.bak`);
|
|
79
|
+
await writeFile(backupPath, ensureTrailingNewline(JSON.stringify(rawConfig, null, 2)), "utf8");
|
|
80
|
+
await writeTextFileAtomically(filePath, ensureTrailingNewline(JSON.stringify(config, null, 2)));
|
|
81
|
+
return config;
|
|
60
82
|
};
|
|
61
83
|
//# sourceMappingURL=migration.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration.js","sourceRoot":"","sources":["../../src/config/migration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEpD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"migration.js","sourceRoot":"","sources":["../../src/config/migration.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-env.d.ts","sourceRoot":"","sources":["../../src/config/runtime-env.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runtime-env.d.ts","sourceRoot":"","sources":["../../src/config/runtime-env.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,uBAExC,CAAC;AAEF,eAAO,MAAM,2BAA2B,cAEvC,CAAC;AAEF,eAAO,MAAM,2BAA2B,cAKvC,CAAC;AAEF,eAAO,MAAM,0CAA0C,cAKtD,CAAC;AAEF,eAAO,MAAM,mCAAmC,cAK/C,CAAC;AAEF,eAAO,MAAM,yBAAyB,qDAOrC,CAAC"}
|
|
@@ -2,14 +2,9 @@ import { platform, release } from "node:os";
|
|
|
2
2
|
import { detectCurrentPlatformKey } from "#app/config/platform.ts";
|
|
3
3
|
import { resolveDotweaveConfigDirectory, resolveDotweaveGlobalConfigFilePath, resolveDotweaveSyncDirectory, resolveHomeDirectory, resolveXdgConfigHome, } from "#app/config/xdg.ts";
|
|
4
4
|
import { ENV } from "#app/lib/env.ts";
|
|
5
|
-
|
|
6
|
-
const trimmedValue = value?.trim();
|
|
7
|
-
return trimmedValue === undefined || trimmedValue === ""
|
|
8
|
-
? undefined
|
|
9
|
-
: trimmedValue;
|
|
10
|
-
};
|
|
5
|
+
import { normalizeConfiguredValue } from "#app/lib/string.ts";
|
|
11
6
|
export const readEnvValue = (name) => {
|
|
12
|
-
return
|
|
7
|
+
return normalizeConfiguredValue(ENV[name]);
|
|
13
8
|
};
|
|
14
9
|
export const resolveHomeDirectoryFromEnv = () => {
|
|
15
10
|
return resolveHomeDirectory(readEnvValue("HOME"));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-env.js","sourceRoot":"","sources":["../../src/config/runtime-env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAE5C,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EACL,8BAA8B,EAC9B,mCAAmC,EACnC,4BAA4B,EAC5B,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"runtime-env.js","sourceRoot":"","sources":["../../src/config/runtime-env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAE5C,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EACL,8BAA8B,EAC9B,mCAAmC,EACnC,4BAA4B,EAC5B,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AACtC,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAE9D,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,IAAY,EAAE,EAAE;IAC3C,OAAO,wBAAwB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;AAC7C,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAAG,EAAE;IAC9C,OAAO,oBAAoB,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;AACpD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAAG,EAAE;IAC9C,OAAO,oBAAoB,CACzB,YAAY,CAAC,MAAM,CAAC,EACpB,YAAY,CAAC,iBAAiB,CAAC,CAChC,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,0CAA0C,GAAG,GAAG,EAAE;IAC7D,MAAM,eAAe,GAAG,8BAA8B,CACpD,2BAA2B,EAAE,CAC9B,CAAC;IACF,OAAO,mCAAmC,CAAC,eAAe,CAAC,CAAC;AAC9D,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,mCAAmC,GAAG,GAAG,EAAE;IACtD,MAAM,eAAe,GAAG,8BAA8B,CACpD,2BAA2B,EAAE,CAC9B,CAAC;IACF,OAAO,4BAA4B,CAAC,eAAe,CAAC,CAAC;AACvD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAG,EAAE;IAC5C,OAAO,wBAAwB,CAC7B,QAAQ,EAAE,EACV,OAAO,EAAE,EACT,YAAY,CAAC,iBAAiB,CAAC,EAC/B,YAAY,CAAC,aAAa,CAAC,CAC5B,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ResolvedSyncConfig, ResolvedSyncConfigEntry, SyncMode } from "#app/config/sync-schema.ts";
|
|
1
|
+
import type { PlatformSyncMode, ResolvedSyncConfig, ResolvedSyncConfigEntry, SyncMode } from "#app/config/sync-schema.ts";
|
|
2
2
|
export declare const findOwningSyncEntry: (config: Pick<ResolvedSyncConfig, "entries">, repoPath: string) => ResolvedSyncConfigEntry | undefined;
|
|
3
3
|
export declare const collectChildEntryPaths: (config: Pick<ResolvedSyncConfig, "entries">, repoPath: string) => ReadonlySet<string>;
|
|
4
4
|
export declare const resolveEntryRelativeRepoPath: (entry: Pick<ResolvedSyncConfigEntry, "kind" | "repoPath">, repoPath: string) => string | undefined;
|
|
@@ -9,6 +9,8 @@ export declare const resolveSyncRule: (config: ResolvedSyncConfig, repoPath: str
|
|
|
9
9
|
export declare const resolveSyncMode: (config: ResolvedSyncConfig, repoPath: string, activeProfile?: string) => SyncMode | undefined;
|
|
10
10
|
export declare const isIgnoredSyncPath: (config: ResolvedSyncConfig, repoPath: string) => boolean;
|
|
11
11
|
export declare const isSecretSyncPath: (config: ResolvedSyncConfig, repoPath: string) => boolean;
|
|
12
|
-
export declare const
|
|
12
|
+
export declare const requireManagedSyncMode: (config: ResolvedSyncConfig, repoPath: string, activeProfile?: string, context?: string) => "normal" | "secret" | "ignore";
|
|
13
|
+
export declare const buildDefaultPlatformMode: (mode: SyncMode) => PlatformSyncMode;
|
|
14
|
+
export declare const hasPlatformSpecificModeOverride: (configuredMode: PlatformSyncMode) => boolean;
|
|
13
15
|
export declare const collectAllProfileNames: (entries: readonly ResolvedSyncConfigEntry[]) => string[];
|
|
14
|
-
//# sourceMappingURL=sync-
|
|
16
|
+
//# sourceMappingURL=sync-queries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-queries.d.ts","sourceRoot":"","sources":["../../src/config/sync-queries.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,EACvB,QAAQ,EACT,MAAM,4BAA4B,CAAC;AAiBpC,eAAO,MAAM,mBAAmB,GAC9B,QAAQ,IAAI,CAAC,kBAAkB,EAAE,SAAS,CAAC,EAC3C,UAAU,MAAM,KACf,uBAAuB,GAAG,SAa5B,CAAC;AAEF,eAAO,MAAM,sBAAsB,GACjC,QAAQ,IAAI,CAAC,kBAAkB,EAAE,SAAS,CAAC,EAC3C,UAAU,MAAM,KACf,WAAW,CAAC,MAAM,CASpB,CAAC;AAEF,eAAO,MAAM,4BAA4B,GACvC,OAAO,IAAI,CAAC,uBAAuB,EAAE,MAAM,GAAG,UAAU,CAAC,EACzD,UAAU,MAAM,uBAejB,CAAC;AAuBF,eAAO,MAAM,eAAe,GAC1B,QAAQ,kBAAkB,EAC1B,UAAU,MAAM,EAChB,gBAAgB,MAAM,KACrB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,SAcxC,CAAC;AAEF,eAAO,MAAM,eAAe,GAC1B,QAAQ,kBAAkB,EAC1B,UAAU,MAAM,EAChB,gBAAgB,MAAM,KACrB,QAAQ,GAAG,SAEb,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,kBAAkB,EAC1B,UAAU,MAAM,YAGjB,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,QAAQ,kBAAkB,EAC1B,UAAU,MAAM,YAGjB,CAAC;AAEF,eAAO,MAAM,sBAAsB,GACjC,QAAQ,kBAAkB,EAC1B,UAAU,MAAM,EAChB,gBAAgB,MAAM,EACtB,UAAU,MAAM,mCAmBjB,CAAC;AAMF,eAAO,MAAM,wBAAwB,GAAI,MAAM,QAAQ,KAAG,gBAExD,CAAC;AAEH,eAAO,MAAM,+BAA+B,GAC1C,gBAAgB,gBAAgB,YAQjC,CAAC;AAEF,eAAO,MAAM,sBAAsB,GACjC,SAAS,SAAS,uBAAuB,EAAE,KAC1C,MAAM,EAUR,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AppConstants } from "#app/config/constants.ts";
|
|
2
2
|
import { DotweaveError } from "#app/lib/error.ts";
|
|
3
3
|
// ---------------------------------------------------------------------------
|
|
4
4
|
// Entry lookup
|
|
@@ -42,12 +42,12 @@ export const resolveEntryRelativeRepoPath = (entry, repoPath) => {
|
|
|
42
42
|
// ---------------------------------------------------------------------------
|
|
43
43
|
const resolveProfileForEntry = (entry, activeProfile) => {
|
|
44
44
|
if (entry.profiles.length === 0) {
|
|
45
|
-
return
|
|
45
|
+
return AppConstants.SYNC.DEFAULT_PROFILE;
|
|
46
46
|
}
|
|
47
47
|
const effective = activeProfile !== undefined &&
|
|
48
|
-
activeProfile !==
|
|
48
|
+
activeProfile !== AppConstants.SYNC.DEFAULT_PROFILE
|
|
49
49
|
? activeProfile
|
|
50
|
-
:
|
|
50
|
+
: AppConstants.SYNC.DEFAULT_PROFILE;
|
|
51
51
|
return entry.profiles.includes(effective) ? effective : undefined;
|
|
52
52
|
};
|
|
53
53
|
export const resolveSyncRule = (config, repoPath, activeProfile) => {
|
|
@@ -70,7 +70,7 @@ export const isIgnoredSyncPath = (config, repoPath) => {
|
|
|
70
70
|
export const isSecretSyncPath = (config, repoPath) => {
|
|
71
71
|
return resolveSyncMode(config, repoPath) === "secret";
|
|
72
72
|
};
|
|
73
|
-
export const
|
|
73
|
+
export const requireManagedSyncMode = (config, repoPath, activeProfile, context) => {
|
|
74
74
|
const mode = resolveSyncMode(config, repoPath, activeProfile);
|
|
75
75
|
if (mode === undefined) {
|
|
76
76
|
throw new DotweaveError("Repository path is not managed by the current sync configuration.", {
|
|
@@ -87,6 +87,15 @@ export const resolveManagedSyncMode = (config, repoPath, activeProfile, context)
|
|
|
87
87
|
// ---------------------------------------------------------------------------
|
|
88
88
|
// Profile collection
|
|
89
89
|
// ---------------------------------------------------------------------------
|
|
90
|
+
export const buildDefaultPlatformMode = (mode) => ({
|
|
91
|
+
default: mode,
|
|
92
|
+
});
|
|
93
|
+
export const hasPlatformSpecificModeOverride = (configuredMode) => {
|
|
94
|
+
return (configuredMode.win !== undefined ||
|
|
95
|
+
configuredMode.mac !== undefined ||
|
|
96
|
+
configuredMode.linux !== undefined ||
|
|
97
|
+
configuredMode.wsl !== undefined);
|
|
98
|
+
};
|
|
90
99
|
export const collectAllProfileNames = (entries) => {
|
|
91
100
|
const profiles = new Set();
|
|
92
101
|
for (const entry of entries) {
|
|
@@ -96,4 +105,4 @@ export const collectAllProfileNames = (entries) => {
|
|
|
96
105
|
}
|
|
97
106
|
return [...profiles].sort((left, right) => left.localeCompare(right));
|
|
98
107
|
};
|
|
99
|
-
//# sourceMappingURL=sync-
|
|
108
|
+
//# sourceMappingURL=sync-queries.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-queries.js","sourceRoot":"","sources":["../../src/config/sync-queries.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import {
|
|
2
|
+
import { AppConstants } from "#app/config/constants.ts";
|
|
3
3
|
import { type PlatformKey, type PlatformStringValue } from "#app/config/platform.ts";
|
|
4
4
|
declare const platformSyncModeSchema: z.ZodObject<{
|
|
5
5
|
default: z.ZodEnum<{
|
|
@@ -35,11 +35,12 @@ declare const platformPermissionSchema: z.ZodObject<{
|
|
|
35
35
|
linux: z.ZodOptional<z.ZodString>;
|
|
36
36
|
wsl: z.ZodOptional<z.ZodString>;
|
|
37
37
|
}, z.core.$strip>;
|
|
38
|
-
declare const syncConfigSchema: z.ZodObject<{
|
|
39
|
-
version: z.ZodLiteral<7>;
|
|
38
|
+
export declare const syncConfigSchema: z.ZodObject<{
|
|
39
|
+
version: z.ZodUnion<readonly [z.ZodLiteral<7>, z.ZodLiteral<8>]>;
|
|
40
40
|
age: z.ZodOptional<z.ZodObject<{
|
|
41
41
|
recipients: z.ZodArray<z.ZodString>;
|
|
42
42
|
}, z.core.$strip>>;
|
|
43
|
+
profiles: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
43
44
|
entries: z.ZodArray<z.ZodObject<{
|
|
44
45
|
kind: z.ZodEnum<{
|
|
45
46
|
file: "file";
|
|
@@ -98,11 +99,11 @@ declare const syncConfigSchema: z.ZodObject<{
|
|
|
98
99
|
}, z.core.$strip>;
|
|
99
100
|
declare const syncEntryKinds: readonly ["file", "directory"];
|
|
100
101
|
export type SyncConfigEntryKind = (typeof syncEntryKinds)[number];
|
|
101
|
-
export type SyncMode = (typeof
|
|
102
|
+
export type SyncMode = (typeof AppConstants.SYNC.MODES)[number];
|
|
102
103
|
export type ConfiguredSyncRepoPath = PlatformStringValue;
|
|
103
104
|
export type PlatformSyncMode = z.infer<typeof platformSyncModeSchema>;
|
|
104
105
|
export type PlatformPermission = z.infer<typeof platformPermissionSchema>;
|
|
105
|
-
export type
|
|
106
|
+
export type RawSyncConfig = z.infer<typeof syncConfigSchema>;
|
|
106
107
|
export type SyncConfigResolutionContext = Readonly<{
|
|
107
108
|
homeDirectory: string;
|
|
108
109
|
platformKey: PlatformKey;
|
|
@@ -130,17 +131,21 @@ export type AgeConfig = Readonly<{
|
|
|
130
131
|
export type ResolvedSyncConfig = Readonly<{
|
|
131
132
|
age?: AgeConfig;
|
|
132
133
|
entries: readonly ResolvedSyncConfigEntry[];
|
|
133
|
-
|
|
134
|
+
profiles?: readonly string[];
|
|
135
|
+
version: 7 | typeof AppConstants.SYNC.CONFIG_VERSION;
|
|
134
136
|
}>;
|
|
135
137
|
export declare const normalizeSyncRepoPath: (value: string) => string;
|
|
136
138
|
export declare const normalizeSyncProfileName: (value: string, description?: string) => string;
|
|
137
139
|
export declare const hasReservedSyncArtifactSuffixSegment: (value: string) => boolean;
|
|
138
140
|
export declare const deriveRepoPathFromLocalPath: (localPath: PlatformStringValue, homeDirectory: string) => string;
|
|
139
141
|
export declare const validateResolvedSyncConfigEntries: (entries: readonly ResolvedSyncConfigEntry[]) => void;
|
|
142
|
+
export declare const validateRawSyncConfigProfileRegistry: (config: Pick<RawSyncConfig, "entries" | "profiles">) => string[];
|
|
140
143
|
export declare const parseSyncConfig: (input: unknown, context: SyncConfigResolutionContext) => ResolvedSyncConfig;
|
|
141
144
|
export declare const createInitialSyncConfig: (age: {
|
|
142
145
|
recipients: string[];
|
|
143
|
-
}) =>
|
|
144
|
-
export declare const formatSyncConfig: (config:
|
|
146
|
+
}) => RawSyncConfig;
|
|
147
|
+
export declare const formatSyncConfig: (config: RawSyncConfig) => string;
|
|
148
|
+
export declare const resolveSyncConfigFilePath: (syncDirectory: string) => string;
|
|
149
|
+
export declare const readSyncConfig: (syncDirectory: string, context: SyncConfigResolutionContext) => Promise<ResolvedSyncConfig>;
|
|
145
150
|
export {};
|
|
146
151
|
//# sourceMappingURL=sync-schema.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-schema.d.ts","sourceRoot":"","sources":["../../src/config/sync-schema.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sync-schema.d.ts","sourceRoot":"","sources":["../../src/config/sync-schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { basename, dirname, isAbsolute, join, posix, relative, sep, } from "node:path";
|
|
2
3
|
import { z } from "zod";
|
|
3
|
-
import {
|
|
4
|
+
import { AppConstants } from "#app/config/constants.ts";
|
|
5
|
+
import { applyConfigMigrations } from "#app/config/migration.ts";
|
|
4
6
|
import { resolvePlatformValue, } from "#app/config/platform.ts";
|
|
5
7
|
import { resolveConfiguredAbsolutePath } from "#app/config/xdg.ts";
|
|
6
8
|
import { DotweaveError } from "#app/lib/error.ts";
|
|
7
9
|
import { parsePermissionOctal } from "#app/lib/file-mode.ts";
|
|
10
|
+
import { writeTextFileAtomically } from "#app/lib/filesystem.ts";
|
|
11
|
+
import { parseJsonc, validateJsoncConfigPath } from "#app/lib/jsonc.ts";
|
|
8
12
|
import { doPathsOverlap } from "#app/lib/path.ts";
|
|
9
13
|
import { ensureTrailingNewline } from "#app/lib/string.ts";
|
|
10
14
|
import { formatInputIssues } from "#app/lib/validation.ts";
|
|
15
|
+
import { migrateSyncConfigV7ToV8 } from "#app/migrations/sync-v8.ts";
|
|
16
|
+
const syncConfigMigrationRegistry = new Map([[7, migrateSyncConfigV7ToV8]]);
|
|
11
17
|
// ---------------------------------------------------------------------------
|
|
12
18
|
// Zod schemas
|
|
13
19
|
// ---------------------------------------------------------------------------
|
|
@@ -18,6 +24,9 @@ const requiredTrimmedStringSchema = z
|
|
|
18
24
|
const syncProfileNameArraySchema = z
|
|
19
25
|
.array(requiredTrimmedStringSchema)
|
|
20
26
|
.min(1, "At least one profile must be specified.");
|
|
27
|
+
const syncProfileRegistrySchema = z
|
|
28
|
+
.array(requiredTrimmedStringSchema)
|
|
29
|
+
.default([]);
|
|
21
30
|
const platformLocalPathSchema = z.object({
|
|
22
31
|
default: requiredTrimmedStringSchema,
|
|
23
32
|
win: requiredTrimmedStringSchema.optional(),
|
|
@@ -35,11 +44,11 @@ const platformRepoPathSchema = z.object({
|
|
|
35
44
|
});
|
|
36
45
|
const repoPathSchema = platformRepoPathSchema;
|
|
37
46
|
const platformSyncModeSchema = z.object({
|
|
38
|
-
default: z.enum(
|
|
39
|
-
win: z.enum(
|
|
40
|
-
mac: z.enum(
|
|
41
|
-
linux: z.enum(
|
|
42
|
-
wsl: z.enum(
|
|
47
|
+
default: z.enum(AppConstants.SYNC.MODES),
|
|
48
|
+
win: z.enum(AppConstants.SYNC.MODES).optional(),
|
|
49
|
+
mac: z.enum(AppConstants.SYNC.MODES).optional(),
|
|
50
|
+
linux: z.enum(AppConstants.SYNC.MODES).optional(),
|
|
51
|
+
wsl: z.enum(AppConstants.SYNC.MODES).optional(),
|
|
43
52
|
});
|
|
44
53
|
const permissionOctalSchema = z
|
|
45
54
|
.string()
|
|
@@ -65,11 +74,12 @@ const syncConfigAgeSchema = z.object({
|
|
|
65
74
|
.min(1, "At least one age recipient is required."),
|
|
66
75
|
});
|
|
67
76
|
const syncConfigSchemaV7 = z.object({
|
|
68
|
-
version: z.literal(
|
|
77
|
+
version: z.union([z.literal(7), z.literal(AppConstants.SYNC.CONFIG_VERSION)]),
|
|
69
78
|
age: syncConfigAgeSchema.optional(),
|
|
79
|
+
profiles: syncProfileRegistrySchema,
|
|
70
80
|
entries: z.array(syncConfigEntrySchema),
|
|
71
81
|
});
|
|
72
|
-
const syncConfigSchema = syncConfigSchemaV7;
|
|
82
|
+
export const syncConfigSchema = syncConfigSchemaV7;
|
|
73
83
|
// ---------------------------------------------------------------------------
|
|
74
84
|
// Exported types
|
|
75
85
|
// ---------------------------------------------------------------------------
|
|
@@ -91,7 +101,7 @@ export const normalizeSyncRepoPath = (value) => {
|
|
|
91
101
|
});
|
|
92
102
|
}
|
|
93
103
|
if (hasReservedSyncArtifactSuffixSegment(normalizedValue)) {
|
|
94
|
-
throw new DotweaveError(`Repository path must not use the reserved suffix ${
|
|
104
|
+
throw new DotweaveError(`Repository path must not use the reserved suffix ${AppConstants.SYNC.SECRET_ARTIFACT_SUFFIX}.`, {
|
|
95
105
|
code: "RESERVED_SECRET_SUFFIX",
|
|
96
106
|
details: [`Repository path: ${value}`],
|
|
97
107
|
hint: "Rename the path so no segment ends with the secret artifact suffix.",
|
|
@@ -134,7 +144,7 @@ export const hasReservedSyncArtifactSuffixSegment = (value) => {
|
|
|
134
144
|
return value
|
|
135
145
|
.replaceAll("\\", "/")
|
|
136
146
|
.split("/")
|
|
137
|
-
.some((segment) => segment.endsWith(
|
|
147
|
+
.some((segment) => segment.endsWith(AppConstants.SYNC.SECRET_ARTIFACT_SUFFIX));
|
|
138
148
|
};
|
|
139
149
|
export const deriveRepoPathFromLocalPath = (localPath, homeDirectory) => {
|
|
140
150
|
const resolvedDefaultPath = resolveConfiguredAbsolutePath(localPath.default, homeDirectory, undefined);
|
|
@@ -160,8 +170,8 @@ const validatePathOverlaps = (entries, property, description) => {
|
|
|
160
170
|
if (currentValue === otherValue) {
|
|
161
171
|
const isRepoPath = property === "repoPath";
|
|
162
172
|
throw new DotweaveError(isRepoPath
|
|
163
|
-
? `Multiple entries target the same repository path in ${
|
|
164
|
-
: `Duplicate ${description.toLowerCase()} paths in ${
|
|
173
|
+
? `Multiple entries target the same repository path in ${AppConstants.SYNC.CONFIG_FILE_NAME}.`
|
|
174
|
+
: `Duplicate ${description.toLowerCase()} paths in ${AppConstants.SYNC.CONFIG_FILE_NAME}.`, {
|
|
165
175
|
code: "DUPLICATE_PATHS",
|
|
166
176
|
details: isRepoPath
|
|
167
177
|
? [
|
|
@@ -174,7 +184,7 @@ const validatePathOverlaps = (entries, property, description) => {
|
|
|
174
184
|
],
|
|
175
185
|
hint: isRepoPath
|
|
176
186
|
? "Each entry must use a unique repoPath. Change or remove one of the conflicting entries."
|
|
177
|
-
: `Remove the duplicate entry from ${
|
|
187
|
+
: `Remove the duplicate entry from ${AppConstants.SYNC.CONFIG_FILE_NAME}.`,
|
|
178
188
|
});
|
|
179
189
|
}
|
|
180
190
|
const isParentChild = currentValue.startsWith(`${otherValue}/`) ||
|
|
@@ -188,7 +198,7 @@ const validatePathOverlaps = (entries, property, description) => {
|
|
|
188
198
|
? false
|
|
189
199
|
: doPathsOverlap(currentValue, otherValue);
|
|
190
200
|
if (overlaps) {
|
|
191
|
-
throw new DotweaveError(`${description} paths must not overlap in ${
|
|
201
|
+
throw new DotweaveError(`${description} paths must not overlap in ${AppConstants.SYNC.CONFIG_FILE_NAME}.`, {
|
|
192
202
|
code: "OVERLAPPING_PATHS",
|
|
193
203
|
details: [
|
|
194
204
|
`${currentEntry.repoPath}: ${currentValue}`,
|
|
@@ -204,10 +214,76 @@ export const validateResolvedSyncConfigEntries = (entries) => {
|
|
|
204
214
|
validatePathOverlaps(entries, "repoPath", "Repository");
|
|
205
215
|
validatePathOverlaps(entries, "localPath", "Local");
|
|
206
216
|
};
|
|
217
|
+
const normalizeProfileRegistry = (profiles) => {
|
|
218
|
+
const normalizedProfiles = profiles.map((profile) => normalizeSyncProfileName(profile));
|
|
219
|
+
const seenProfiles = new Set();
|
|
220
|
+
for (const profile of normalizedProfiles) {
|
|
221
|
+
if (profile === AppConstants.SYNC.DEFAULT_PROFILE) {
|
|
222
|
+
throw new DotweaveError(`Profile '${AppConstants.SYNC.DEFAULT_PROFILE}' is implicit and must not be listed in manifest profiles.`, {
|
|
223
|
+
code: "INVALID_PROFILE_REGISTRY",
|
|
224
|
+
hint: `Remove '${AppConstants.SYNC.DEFAULT_PROFILE}' from profiles in ${AppConstants.SYNC.CONFIG_FILE_NAME}.`,
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
if (seenProfiles.has(profile)) {
|
|
228
|
+
throw new DotweaveError(`Duplicate profile '${profile}' in manifest.`, {
|
|
229
|
+
code: "DUPLICATE_PROFILE",
|
|
230
|
+
hint: `Remove duplicate profile names from profiles in ${AppConstants.SYNC.CONFIG_FILE_NAME}.`,
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
seenProfiles.add(profile);
|
|
234
|
+
}
|
|
235
|
+
return normalizedProfiles;
|
|
236
|
+
};
|
|
237
|
+
const validateProfileReferences = (references, profiles) => {
|
|
238
|
+
const availableProfiles = new Set([
|
|
239
|
+
AppConstants.SYNC.DEFAULT_PROFILE,
|
|
240
|
+
...profiles,
|
|
241
|
+
]);
|
|
242
|
+
for (const [entryLabel, entryProfiles] of references) {
|
|
243
|
+
for (const profile of entryProfiles) {
|
|
244
|
+
const normalizedProfile = normalizeSyncProfileName(profile);
|
|
245
|
+
if (!availableProfiles.has(normalizedProfile)) {
|
|
246
|
+
throw new DotweaveError(`Unknown profile '${normalizedProfile}'.`, {
|
|
247
|
+
code: "UNKNOWN_PROFILE",
|
|
248
|
+
details: [`Entry: ${entryLabel}`],
|
|
249
|
+
hint: `Add it with 'dotweave profile add ${normalizedProfile}', or remove it from the entry profiles.`,
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
const validateEntryProfileReferences = (entries, profiles) => {
|
|
256
|
+
validateProfileReferences(entries.map((entry) => [entry.repoPath, entry.profiles]), profiles);
|
|
257
|
+
};
|
|
258
|
+
export const validateRawSyncConfigProfileRegistry = (config) => {
|
|
259
|
+
const profiles = normalizeProfileRegistry(config.profiles ?? []);
|
|
260
|
+
validateProfileReferences(config.entries.map((entry, index) => [
|
|
261
|
+
entry.repoPath?.default ?? entry.localPath.default ?? `#${index}`,
|
|
262
|
+
entry.profiles ?? [],
|
|
263
|
+
]), profiles);
|
|
264
|
+
return profiles;
|
|
265
|
+
};
|
|
266
|
+
const collectLegacyProfileRegistry = (entries) => {
|
|
267
|
+
const profiles = new Set();
|
|
268
|
+
for (const entry of entries) {
|
|
269
|
+
if (entry.profiles === undefined) {
|
|
270
|
+
continue;
|
|
271
|
+
}
|
|
272
|
+
for (const profile of entry.profiles) {
|
|
273
|
+
const normalizedProfile = normalizeSyncProfileName(profile);
|
|
274
|
+
if (normalizedProfile !== AppConstants.SYNC.DEFAULT_PROFILE) {
|
|
275
|
+
profiles.add(normalizedProfile);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return [...profiles].sort((left, right) => left.localeCompare(right));
|
|
280
|
+
};
|
|
207
281
|
// ---------------------------------------------------------------------------
|
|
208
282
|
// Internal parsing helpers
|
|
209
283
|
// ---------------------------------------------------------------------------
|
|
210
|
-
const defaultSyncMode = {
|
|
284
|
+
const defaultSyncMode = {
|
|
285
|
+
default: AppConstants.SYNC.MODES[0],
|
|
286
|
+
};
|
|
211
287
|
const resolveSyncModeForPlatform = (configuredMode, platformKey) => {
|
|
212
288
|
if (platformKey === "wsl") {
|
|
213
289
|
return configuredMode.wsl ?? configuredMode.linux ?? configuredMode.default;
|
|
@@ -327,9 +403,12 @@ export const parseSyncConfig = (input, context) => {
|
|
|
327
403
|
throw new DotweaveError("Sync configuration is invalid.", {
|
|
328
404
|
code: "CONFIG_VALIDATION_FAILED",
|
|
329
405
|
details: formatInputIssues(result.error.issues).split("\n"),
|
|
330
|
-
hint: `Fix the invalid fields in ${
|
|
406
|
+
hint: `Fix the invalid fields in ${AppConstants.SYNC.CONFIG_FILE_NAME}, then run the command again.`,
|
|
331
407
|
});
|
|
332
408
|
}
|
|
409
|
+
const profiles = normalizeProfileRegistry(result.data.version === 7
|
|
410
|
+
? collectLegacyProfileRegistry(result.data.entries)
|
|
411
|
+
: result.data.profiles);
|
|
333
412
|
const rawEntries = result.data.entries.map((entry) => {
|
|
334
413
|
const resolvedLocalPath = resolveSyncEntryLocalPath(entry.localPath, context);
|
|
335
414
|
const configuredRepoPath = entry.repoPath === undefined
|
|
@@ -368,6 +447,7 @@ export const parseSyncConfig = (input, context) => {
|
|
|
368
447
|
});
|
|
369
448
|
validateResolvedSyncConfigEntries(rawEntries);
|
|
370
449
|
const entries = applyEntryInheritance(rawEntries, platformKey);
|
|
450
|
+
validateEntryProfileReferences(entries, profiles);
|
|
371
451
|
const age = result.data.age === undefined
|
|
372
452
|
? undefined
|
|
373
453
|
: {
|
|
@@ -376,17 +456,57 @@ export const parseSyncConfig = (input, context) => {
|
|
|
376
456
|
return {
|
|
377
457
|
...(age === undefined ? {} : { age }),
|
|
378
458
|
entries,
|
|
459
|
+
profiles,
|
|
379
460
|
version: result.data.version,
|
|
380
461
|
};
|
|
381
462
|
};
|
|
382
463
|
export const createInitialSyncConfig = (age) => {
|
|
383
464
|
return {
|
|
384
|
-
version:
|
|
465
|
+
version: AppConstants.SYNC.CONFIG_VERSION,
|
|
385
466
|
age,
|
|
467
|
+
profiles: [],
|
|
386
468
|
entries: [],
|
|
387
469
|
};
|
|
388
470
|
};
|
|
389
471
|
export const formatSyncConfig = (config) => {
|
|
390
472
|
return ensureTrailingNewline(JSON.stringify(config, null, 2));
|
|
391
473
|
};
|
|
474
|
+
export const resolveSyncConfigFilePath = (syncDirectory) => {
|
|
475
|
+
return join(syncDirectory, AppConstants.SYNC.CONFIG_FILE_NAME);
|
|
476
|
+
};
|
|
477
|
+
export const readSyncConfig = async (syncDirectory, context) => {
|
|
478
|
+
const filePath = await validateJsoncConfigPath(resolveSyncConfigFilePath(syncDirectory));
|
|
479
|
+
try {
|
|
480
|
+
const contents = await readFile(filePath, "utf8");
|
|
481
|
+
const parsed = parseJsonc(contents);
|
|
482
|
+
const migration = applyConfigMigrations(parsed, syncConfigMigrationRegistry, AppConstants.SYNC.CONFIG_VERSION, filePath);
|
|
483
|
+
const resolved = parseSyncConfig(migration.config, context);
|
|
484
|
+
if (migration.migrated && migration.originalVersion !== undefined) {
|
|
485
|
+
const backupPath = join(dirname(filePath), `${basename(filePath)}.v${migration.originalVersion}.bak`);
|
|
486
|
+
await writeFile(backupPath, ensureTrailingNewline(JSON.stringify(parsed, null, 2)), "utf8");
|
|
487
|
+
await writeTextFileAtomically(filePath, ensureTrailingNewline(JSON.stringify(migration.config, null, 2)));
|
|
488
|
+
}
|
|
489
|
+
return resolved;
|
|
490
|
+
}
|
|
491
|
+
catch (error) {
|
|
492
|
+
if (error instanceof DotweaveError) {
|
|
493
|
+
throw error;
|
|
494
|
+
}
|
|
495
|
+
if (error instanceof SyntaxError) {
|
|
496
|
+
throw new DotweaveError("Sync configuration is not valid JSON.", {
|
|
497
|
+
code: "CONFIG_INVALID_JSON",
|
|
498
|
+
details: [`Config file: ${filePath}`, error.message],
|
|
499
|
+
hint: `Fix the JSON syntax in ${AppConstants.SYNC.CONFIG_FILE_NAME}, then run the command again.`,
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
throw new DotweaveError("Failed to read sync configuration.", {
|
|
503
|
+
code: "CONFIG_READ_FAILED",
|
|
504
|
+
details: [
|
|
505
|
+
`Config file: ${filePath}`,
|
|
506
|
+
...(error instanceof Error ? [error.message] : []),
|
|
507
|
+
],
|
|
508
|
+
hint: "Run 'dotweave init' if the sync directory has not been initialized yet.",
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
};
|
|
392
512
|
//# sourceMappingURL=sync-schema.js.map
|