@narumitw/pi-sync 0.49.14 → 0.50.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +134 -241
- package/dist/chunks/chunk-2B2ELUF5.ts +29 -0
- package/dist/chunks/chunk-2B2ELUF5.ts.map +7 -0
- package/dist/chunks/chunk-6LP3MCR2.ts +115 -0
- package/dist/chunks/chunk-6LP3MCR2.ts.map +7 -0
- package/dist/chunks/chunk-6UHKGALE.ts +134 -0
- package/dist/chunks/chunk-6UHKGALE.ts.map +7 -0
- package/dist/chunks/{chunk-RGJ6SOYR.ts → chunk-AUSDLD6F.ts} +4 -4
- package/dist/chunks/chunk-AUSDLD6F.ts.map +7 -0
- package/dist/chunks/{chunk-3NDD5QPM.ts → chunk-AXXS2BPA.ts} +9 -9
- package/dist/chunks/chunk-AXXS2BPA.ts.map +7 -0
- package/dist/chunks/{chunk-APZVBSM6.ts → chunk-C7XY5NF5.ts} +214 -365
- package/dist/chunks/chunk-C7XY5NF5.ts.map +7 -0
- package/dist/chunks/{chunk-4U6AFLJB.ts → chunk-CHH26D4F.ts} +3 -2
- package/dist/chunks/chunk-CHH26D4F.ts.map +7 -0
- package/dist/chunks/chunk-CPEHGXJV.ts +50 -0
- package/dist/chunks/chunk-CPEHGXJV.ts.map +7 -0
- package/dist/chunks/{chunk-5MQ76BK5.ts → chunk-D5X27LCA.ts} +2 -2
- package/dist/chunks/chunk-D5X27LCA.ts.map +7 -0
- package/dist/chunks/{chunk-LJDSHNS3.ts → chunk-GWMHAQG4.ts} +4 -4
- package/dist/chunks/chunk-GWMHAQG4.ts.map +7 -0
- package/dist/chunks/{chunk-FR6CVXAL.ts → chunk-HUDQATCL.ts} +25 -25
- package/dist/chunks/chunk-HUDQATCL.ts.map +7 -0
- package/dist/chunks/{chunk-YQ6UW7IF.ts → chunk-JAAKLL6M.ts} +2 -2
- package/dist/chunks/chunk-JAAKLL6M.ts.map +7 -0
- package/dist/chunks/chunk-JSYMGJQQ.ts +51 -0
- package/dist/chunks/chunk-JSYMGJQQ.ts.map +7 -0
- package/dist/chunks/chunk-L7TBO32M.ts +25 -0
- package/dist/chunks/chunk-L7TBO32M.ts.map +7 -0
- package/dist/chunks/{chunk-4F3W4CSC.ts → chunk-LCRI3ABW.ts} +22 -8
- package/dist/chunks/chunk-LCRI3ABW.ts.map +7 -0
- package/dist/chunks/chunk-LTBWGSBV.ts +12 -0
- package/dist/chunks/chunk-LTBWGSBV.ts.map +7 -0
- package/dist/chunks/chunk-NJFUIVYL.ts +17 -0
- package/dist/chunks/chunk-NJFUIVYL.ts.map +7 -0
- package/dist/chunks/{chunk-EWX3TPLQ.ts → chunk-OEX4ABY6.ts} +39 -37
- package/dist/chunks/chunk-OEX4ABY6.ts.map +7 -0
- package/dist/chunks/chunk-OUHGBFYF.ts +1255 -0
- package/dist/chunks/chunk-OUHGBFYF.ts.map +7 -0
- package/dist/chunks/{chunk-HGV24P4T.ts → chunk-Q2TUM5X6.ts} +3 -3
- package/dist/chunks/chunk-Q2TUM5X6.ts.map +7 -0
- package/dist/chunks/{chunk-BHJUISB4.ts → chunk-SL64RLXR.ts} +8 -6
- package/dist/chunks/chunk-SL64RLXR.ts.map +7 -0
- package/dist/chunks/chunk-T3HH3UEJ.ts +96 -0
- package/dist/chunks/chunk-T3HH3UEJ.ts.map +7 -0
- package/dist/chunks/chunk-TEN2ZBJV.ts +101 -0
- package/dist/chunks/chunk-TEN2ZBJV.ts.map +7 -0
- package/dist/chunks/chunk-THMF4BVL.ts +18 -0
- package/dist/chunks/chunk-THMF4BVL.ts.map +7 -0
- package/dist/chunks/{chunk-LONPFFNP.ts → chunk-X5OM6GXT.ts} +9 -7
- package/dist/chunks/chunk-X5OM6GXT.ts.map +7 -0
- package/dist/chunks/chunk-XBX4HBLG.ts +57 -0
- package/dist/chunks/chunk-XBX4HBLG.ts.map +7 -0
- package/dist/chunks/{chunk-5WJNWFTG.ts → chunk-YKJHPTGO.ts} +23 -55
- package/dist/chunks/chunk-YKJHPTGO.ts.map +7 -0
- package/dist/chunks/chunk-Z4DQF6L3.ts +12 -0
- package/dist/chunks/chunk-Z4DQF6L3.ts.map +7 -0
- package/dist/chunks/{chunk-F5QL2GPY.ts → chunk-ZI5MXMEX.ts} +5 -99
- package/dist/chunks/chunk-ZI5MXMEX.ts.map +7 -0
- package/dist/chunks/{file-selection-4UABOP44.ts → file-selection-FTTKAOYX.ts} +10 -7
- package/dist/chunks/file-selection-FTTKAOYX.ts.map +7 -0
- package/dist/chunks/{git-backend-E3UOUUOM.ts → git-backend-OQW46G2X.ts} +42 -17
- package/dist/chunks/git-backend-OQW46G2X.ts.map +7 -0
- package/dist/chunks/manager-result-dispatcher-U23ODD32.ts +22 -0
- package/dist/chunks/manager-ui-ABATHC36.ts +1680 -0
- package/dist/chunks/manager-ui-ABATHC36.ts.map +7 -0
- package/dist/chunks/remote-selection-ui-ZE3TY67S.ts +21 -0
- package/dist/chunks/{s3-backend-3QZGO2EF.ts → s3-backend-3P33LQHU.ts} +96 -18
- package/dist/chunks/s3-backend-3P33LQHU.ts.map +7 -0
- package/dist/chunks/{setup-switch-X3W3FALZ.ts → setup-switch-IS2PEZ3J.ts} +9 -9
- package/dist/chunks/setup-wizard-VB3VDOV5.ts +89 -0
- package/dist/chunks/setup-wizard-VB3VDOV5.ts.map +7 -0
- package/dist/chunks/{snapshot-WBSV4MQG.ts → snapshot-HKEWCVK6.ts} +7 -6
- package/dist/chunks/sync-inspection-FEP4L5TR.ts +20 -0
- package/dist/chunks/{sync-operations-MPAFVVHA.ts → sync-operations-ONJ27QRL.ts} +381 -299
- package/dist/chunks/sync-operations-ONJ27QRL.ts.map +7 -0
- package/dist/chunks/{sync-state-36H7ULG2.ts → sync-state-Q2FTXTW6.ts} +6 -6
- package/dist/chunks/sync-state-Q2FTXTW6.ts.map +7 -0
- package/dist/chunks/{webdav-backend-ZD5RHRIU.ts → webdav-backend-ECIKD7SO.ts} +26 -13
- package/dist/chunks/webdav-backend-ECIKD7SO.ts.map +7 -0
- package/dist/index.ts +477 -342
- package/dist/index.ts.map +4 -4
- package/docs/settings.md +211 -0
- package/package.json +6 -8
- package/src/{backend-factory.ts → backends/backend-factory.ts} +4 -4
- package/src/backends/backend-identity.ts +40 -0
- package/src/backends/backend-types.ts +81 -0
- package/src/{git-backend.ts → backends/git/git-backend.ts} +43 -19
- package/src/{git-config.ts → backends/git/git-config.ts} +1 -0
- package/src/{git-storage.ts → backends/git/git-storage.ts} +2 -2
- package/src/{s3-backend.ts → backends/s3/s3-backend.ts} +45 -9
- package/src/{s3-client.ts → backends/s3/s3-client.ts} +56 -8
- package/src/{sync-backend.ts → backends/sync-backend.ts} +1 -1
- package/src/{webdav-backend.ts → backends/webdav/webdav-backend.ts} +22 -10
- package/src/{webdav-client.ts → backends/webdav/webdav-client.ts} +1 -1
- package/src/{webdav-config.ts → backends/webdav/webdav-config.ts} +1 -0
- package/src/commands/command-execution.ts +330 -0
- package/src/commands/command-handler.ts +201 -0
- package/src/commands/command-types.ts +18 -0
- package/src/{command.ts → commands/command.ts} +2 -1
- package/src/commands/setup-completions.ts +6 -0
- package/src/settings/config.ts +238 -0
- package/src/{settings-management.ts → settings/settings-management.ts} +40 -14
- package/src/settings/settings-store.ts +109 -0
- package/src/settings/settings-types.ts +128 -0
- package/src/settings/settings-validation.ts +443 -0
- package/src/snapshot/session-paths.ts +84 -0
- package/src/{snapshot-apply.ts → snapshot/snapshot-apply.ts} +3 -3
- package/src/{snapshot-codec.ts → snapshot/snapshot-codec.ts} +2 -2
- package/src/{snapshot-transaction.ts → snapshot/snapshot-transaction.ts} +5 -4
- package/src/snapshot/snapshot-types.ts +38 -0
- package/src/{snapshot.ts → snapshot/snapshot.ts} +39 -20
- package/src/state/json-file.ts +20 -0
- package/src/{lock.ts → state/lock.ts} +3 -2
- package/src/{operation-availability.ts → state/operation-availability.ts} +2 -2
- package/src/state/state-types.ts +20 -0
- package/src/state/sync-state-store.ts +62 -0
- package/src/sync/automatic-sync.ts +103 -0
- package/src/{remote-snapshot.ts → sync/remote-snapshot.ts} +27 -4
- package/src/{setup-switch.ts → sync/setup-switch.ts} +6 -7
- package/src/sync/signals.ts +10 -0
- package/src/sync/startup-check.ts +128 -0
- package/src/{sync-decision.ts → sync/sync-decision.ts} +6 -3
- package/src/sync/sync-error-guidance.ts +53 -0
- package/src/sync/sync-inspection.ts +51 -0
- package/src/sync/sync-loaders.ts +54 -0
- package/src/{sync-operations.ts → sync/sync-mutations.ts} +41 -330
- package/src/sync/sync-operations.ts +12 -0
- package/src/{sync-policy.ts → sync/sync-policy.ts} +2 -2
- package/src/sync/sync-queries.ts +235 -0
- package/src/{sync-state.ts → sync/sync-state.ts} +5 -4
- package/src/sync-extension.ts +64 -708
- package/src/sync.ts +8 -8
- package/src/types.ts +47 -284
- package/src/ui/automatic-sync-summary.ts +6 -0
- package/src/{cancellable-operation.ts → ui/cancellable-operation.ts} +4 -4
- package/src/{file-selection.ts → ui/file-selection.ts} +5 -3
- package/src/{manager-attention.ts → ui/manager-attention.ts} +5 -1
- package/src/{manager-recovery.ts → ui/manager-recovery.ts} +6 -2
- package/src/{manager-state.ts → ui/manager-state.ts} +35 -14
- package/src/ui/manager-ui.ts +386 -0
- package/src/{remote-selection-ui.ts → ui/remote-selection-ui.ts} +21 -13
- package/src/{secret-input.ts → ui/secret-input.ts} +22 -4
- package/src/{settings-ui.ts → ui/settings-ui.ts} +42 -11
- package/src/ui/setup/git-ui.ts +293 -0
- package/src/{s3-credentials-ui.ts → ui/setup/s3-credentials-ui.ts} +13 -21
- package/src/ui/setup/s3-ui.ts +217 -0
- package/src/ui/setup/setup-actions.ts +127 -0
- package/src/ui/setup/setup-location-ui.ts +167 -0
- package/src/ui/setup/setup-name-ui.ts +34 -0
- package/src/ui/setup/setup-prompts.ts +92 -0
- package/src/ui/setup/setup-review.ts +70 -0
- package/src/ui/setup/setup-switcher.ts +181 -0
- package/src/ui/setup/setup-wizard.ts +39 -0
- package/src/ui/setup/text-input.ts +78 -0
- package/src/ui/setup/webdav-ui.ts +330 -0
- package/src/{storage-connections-ui.ts → ui/storage-connections-ui.ts} +99 -69
- package/src/{sync-attention.ts → ui/sync-attention.ts} +75 -6
- package/src/{sync-format.ts → ui/sync-format.ts} +7 -13
- package/src/{sync-resolution-ui.ts → ui/sync-resolution-ui.ts} +4 -3
- package/src/{sync-setups-ui.ts → ui/sync-setups-ui.ts} +23 -10
- package/src/ui/terminal-text.ts +4 -0
- package/dist/chunks/chunk-3NDD5QPM.ts.map +0 -7
- package/dist/chunks/chunk-4F3W4CSC.ts.map +0 -7
- package/dist/chunks/chunk-4U6AFLJB.ts.map +0 -7
- package/dist/chunks/chunk-5MQ76BK5.ts.map +0 -7
- package/dist/chunks/chunk-5WJNWFTG.ts.map +0 -7
- package/dist/chunks/chunk-APZVBSM6.ts.map +0 -7
- package/dist/chunks/chunk-BHJUISB4.ts.map +0 -7
- package/dist/chunks/chunk-EWX3TPLQ.ts.map +0 -7
- package/dist/chunks/chunk-F5QL2GPY.ts.map +0 -7
- package/dist/chunks/chunk-FR6CVXAL.ts.map +0 -7
- package/dist/chunks/chunk-HGV24P4T.ts.map +0 -7
- package/dist/chunks/chunk-JNOOSPEW.ts +0 -82
- package/dist/chunks/chunk-JNOOSPEW.ts.map +0 -7
- package/dist/chunks/chunk-LJDSHNS3.ts.map +0 -7
- package/dist/chunks/chunk-LONPFFNP.ts.map +0 -7
- package/dist/chunks/chunk-RGJ6SOYR.ts.map +0 -7
- package/dist/chunks/chunk-W64NEHXT.ts +0 -167
- package/dist/chunks/chunk-W64NEHXT.ts.map +0 -7
- package/dist/chunks/chunk-YQ6UW7IF.ts.map +0 -7
- package/dist/chunks/file-selection-4UABOP44.ts.map +0 -7
- package/dist/chunks/git-backend-E3UOUUOM.ts.map +0 -7
- package/dist/chunks/manager-result-dispatcher-RNRQA3PW.ts +0 -18
- package/dist/chunks/manager-ui-QO2P4V3Z.ts +0 -2757
- package/dist/chunks/manager-ui-QO2P4V3Z.ts.map +0 -7
- package/dist/chunks/remote-selection-ui-LHSAGKGA.ts +0 -17
- package/dist/chunks/s3-backend-3QZGO2EF.ts.map +0 -7
- package/dist/chunks/sync-operations-MPAFVVHA.ts.map +0 -7
- package/dist/chunks/webdav-backend-ZD5RHRIU.ts.map +0 -7
- package/src/config.ts +0 -910
- package/src/git-ui.ts +0 -307
- package/src/manager-helpers.ts +0 -64
- package/src/manager-ui.ts +0 -997
- package/src/webdav-ui.ts +0 -421
- /package/dist/chunks/{manager-result-dispatcher-RNRQA3PW.ts.map → manager-result-dispatcher-U23ODD32.ts.map} +0 -0
- /package/dist/chunks/{remote-selection-ui-LHSAGKGA.ts.map → remote-selection-ui-ZE3TY67S.ts.map} +0 -0
- /package/dist/chunks/{setup-switch-X3W3FALZ.ts.map → setup-switch-IS2PEZ3J.ts.map} +0 -0
- /package/dist/chunks/{snapshot-WBSV4MQG.ts.map → snapshot-HKEWCVK6.ts.map} +0 -0
- /package/dist/chunks/{sync-state-36H7ULG2.ts.map → sync-inspection-FEP4L5TR.ts.map} +0 -0
- /package/src/{git-runner.ts → backends/git/git-runner.ts} +0 -0
- /package/src/{config-errors.ts → settings/config-errors.ts} +0 -0
- /package/src/{config-file.ts → settings/config-file.ts} +0 -0
- /package/src/{snapshot-paths.ts → snapshot/snapshot-paths.ts} +0 -0
- /package/src/{lock-policy.ts → state/lock-policy.ts} +0 -0
- /package/src/{lockfile-fs.ts → state/lockfile-fs.ts} +0 -0
- /package/src/{state-directory.ts → state/state-directory.ts} +0 -0
- /package/src/{sync-errors.ts → sync/sync-errors.ts} +0 -0
- /package/src/{manager-result-dispatcher.ts → ui/manager-result-dispatcher.ts} +0 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// @generated by scripts/build-runtime.mjs; do not edit.
|
|
2
|
+
// @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
|
|
3
|
+
import {
|
|
4
|
+
stateDir
|
|
5
|
+
} from "./chunk-ZI5MXMEX.ts";
|
|
6
|
+
import {
|
|
7
|
+
backendIdentityCoordinates
|
|
8
|
+
} from "./chunk-6LP3MCR2.ts";
|
|
9
|
+
import {
|
|
10
|
+
readJsonIfExists,
|
|
11
|
+
writeJson
|
|
12
|
+
} from "./chunk-T3HH3UEJ.ts";
|
|
13
|
+
|
|
14
|
+
// src/state/sync-state-store.ts
|
|
15
|
+
import { createHash } from "node:crypto";
|
|
16
|
+
import fs from "node:fs/promises";
|
|
17
|
+
import path from "node:path";
|
|
18
|
+
var STATE_VERSION = 2;
|
|
19
|
+
function syncStateFingerprint(state) {
|
|
20
|
+
return createHash("sha256").update(JSON.stringify(state)).digest("hex");
|
|
21
|
+
}
|
|
22
|
+
async function readStateForConfig(config) {
|
|
23
|
+
return await readJsonIfExists(statePathForConfig(config)) ?? {
|
|
24
|
+
version: STATE_VERSION,
|
|
25
|
+
profile: config.snapshotIdentity,
|
|
26
|
+
lastFileHashes: {}
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
async function writeStateForConfig(config, state) {
|
|
30
|
+
await writeJson(statePathForConfig(config), state);
|
|
31
|
+
}
|
|
32
|
+
function statePathForConfig(config) {
|
|
33
|
+
const identity = backendIdentityCoordinates(config);
|
|
34
|
+
const hash = createHash("sha256").update(identity).digest("hex").slice(0, 16);
|
|
35
|
+
return path.join(stateDir(), "setups", `${config.backend.type}-${hash}.state.json`);
|
|
36
|
+
}
|
|
37
|
+
function lockPath() {
|
|
38
|
+
return path.join(stateDir(), "lock");
|
|
39
|
+
}
|
|
40
|
+
async function ensureStateDir() {
|
|
41
|
+
await fs.mkdir(stateDir(), { recursive: true });
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export {
|
|
45
|
+
syncStateFingerprint,
|
|
46
|
+
readStateForConfig,
|
|
47
|
+
writeStateForConfig,
|
|
48
|
+
lockPath,
|
|
49
|
+
ensureStateDir
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=chunk-JSYMGJQQ.ts.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/state/sync-state-store.ts"],
|
|
4
|
+
"sourcesContent": ["import { createHash } from \"node:crypto\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { backendIdentityCoordinates } from \"../backends/backend-identity.js\";\nimport { safeName } from \"../paths.js\";\nimport type { AnySyncConfig } from \"../settings/settings-types.js\";\nimport { readJsonIfExists, writeJson } from \"./json-file.js\";\nimport { stateDir } from \"./state-directory.js\";\nimport type { SyncState } from \"./state-types.js\";\n\nconst STATE_VERSION = 2;\n\n/** Bounded observation token; do not retain the full baseline in passive UI state. */\nexport function syncStateFingerprint(state: SyncState) {\n\treturn createHash(\"sha256\").update(JSON.stringify(state)).digest(\"hex\");\n}\n\nexport async function readState(profile: string): Promise<SyncState> {\n\treturn (\n\t\t(await readJsonIfExists<SyncState>(statePath(profile))) ?? {\n\t\t\tversion: STATE_VERSION,\n\t\t\tprofile,\n\t\t\tlastFileHashes: {},\n\t\t}\n\t);\n}\n\nexport async function writeState(profile: string, state: SyncState) {\n\tawait writeJson(statePath(profile), state);\n}\n\nexport async function readStateForConfig(config: AnySyncConfig): Promise<SyncState> {\n\treturn (\n\t\t(await readJsonIfExists<SyncState>(statePathForConfig(config))) ?? {\n\t\t\tversion: STATE_VERSION,\n\t\t\tprofile: config.snapshotIdentity,\n\t\t\tlastFileHashes: {},\n\t\t}\n\t);\n}\n\nexport async function writeStateForConfig(config: AnySyncConfig, state: SyncState) {\n\tawait writeJson(statePathForConfig(config), state);\n}\n\nexport function statePathForConfig(config: AnySyncConfig) {\n\tconst identity = backendIdentityCoordinates(config);\n\tconst hash = createHash(\"sha256\").update(identity).digest(\"hex\").slice(0, 16);\n\treturn path.join(stateDir(), \"setups\", `${config.backend.type}-${hash}.state.json`);\n}\n\nfunction statePath(profile: string) {\n\treturn path.join(stateDir(), `${safeName(profile)}.state.json`);\n}\n\nexport function lockPath() {\n\treturn path.join(stateDir(), \"lock\");\n}\n\nexport async function ensureStateDir() {\n\tawait fs.mkdir(stateDir(), { recursive: true });\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;AAAA,SAAS,kBAAkB;AAC3B,OAAO,QAAQ;AACf,OAAO,UAAU;AAQjB,IAAM,gBAAgB;AAGf,SAAS,qBAAqB,OAAkB;AACtD,SAAO,WAAW,QAAQ,EAAE,OAAO,KAAK,UAAU,KAAK,CAAC,EAAE,OAAO,KAAK;AACvE;AAgBA,eAAsB,mBAAmB,QAA2C;AACnF,SACE,MAAM,iBAA4B,mBAAmB,MAAM,CAAC,KAAM;AAAA,IAClE,SAAS;AAAA,IACT,SAAS,OAAO;AAAA,IAChB,gBAAgB,CAAC;AAAA,EAClB;AAEF;AAEA,eAAsB,oBAAoB,QAAuB,OAAkB;AAClF,QAAM,UAAU,mBAAmB,MAAM,GAAG,KAAK;AAClD;AAEO,SAAS,mBAAmB,QAAuB;AACzD,QAAM,WAAW,2BAA2B,MAAM;AAClD,QAAM,OAAO,WAAW,QAAQ,EAAE,OAAO,QAAQ,EAAE,OAAO,KAAK,EAAE,MAAM,GAAG,EAAE;AAC5E,SAAO,KAAK,KAAK,SAAS,GAAG,UAAU,GAAG,OAAO,QAAQ,IAAI,IAAI,IAAI,aAAa;AACnF;AAMO,SAAS,WAAW;AAC1B,SAAO,KAAK,KAAK,SAAS,GAAG,MAAM;AACpC;AAEA,eAAsB,iBAAiB;AACtC,QAAM,GAAG,MAAM,SAAS,GAAG,EAAE,WAAW,KAAK,CAAC;AAC/C;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// @generated by scripts/build-runtime.mjs; do not edit.
|
|
2
|
+
// @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
|
|
3
|
+
|
|
4
|
+
// src/backends/backend-factory.ts
|
|
5
|
+
var createSyncBackend = async (config) => {
|
|
6
|
+
switch (config.backend.type) {
|
|
7
|
+
case "s3": {
|
|
8
|
+
const { S3SyncBackend } = await import("./s3-backend-3P33LQHU.ts");
|
|
9
|
+
return new S3SyncBackend(config.backend);
|
|
10
|
+
}
|
|
11
|
+
case "webdav": {
|
|
12
|
+
const { WebDavSyncBackend } = await import("./webdav-backend-ECIKD7SO.ts");
|
|
13
|
+
return new WebDavSyncBackend(config.backend);
|
|
14
|
+
}
|
|
15
|
+
case "git": {
|
|
16
|
+
const { GitSyncBackend } = await import("./git-backend-OQW46G2X.ts");
|
|
17
|
+
return new GitSyncBackend(config.backend);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export {
|
|
23
|
+
createSyncBackend
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=chunk-L7TBO32M.ts.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/backends/backend-factory.ts"],
|
|
4
|
+
"sourcesContent": ["import type { AnySyncConfig } from \"../settings/settings-types.js\";\nimport type { SyncBackend } from \"./sync-backend.js\";\n\nexport type SyncBackendFactory = {\n\tbivarianceHack(config: AnySyncConfig): SyncBackend | Promise<SyncBackend>;\n}[\"bivarianceHack\"];\n\nexport const createSyncBackend: SyncBackendFactory = async (config) => {\n\tswitch (config.backend.type) {\n\t\tcase \"s3\": {\n\t\t\tconst { S3SyncBackend } = await import(\"./s3/s3-backend.js\");\n\t\t\treturn new S3SyncBackend(config.backend);\n\t\t}\n\t\tcase \"webdav\": {\n\t\t\tconst { WebDavSyncBackend } = await import(\"./webdav/webdav-backend.js\");\n\t\t\treturn new WebDavSyncBackend(config.backend);\n\t\t}\n\t\tcase \"git\": {\n\t\t\tconst { GitSyncBackend } = await import(\"./git/git-backend.js\");\n\t\t\treturn new GitSyncBackend(config.backend);\n\t\t}\n\t}\n};\n"],
|
|
5
|
+
"mappings": ";;;;AAOO,IAAM,oBAAwC,OAAO,WAAW;AACtE,UAAQ,OAAO,QAAQ,MAAM;AAAA,IAC5B,KAAK,MAAM;AACV,YAAM,EAAE,cAAc,IAAI,MAAM,OAAO,0BAAoB;AAC3D,aAAO,IAAI,cAAc,OAAO,OAAO;AAAA,IACxC;AAAA,IACA,KAAK,UAAU;AACd,YAAM,EAAE,kBAAkB,IAAI,MAAM,OAAO,8BAA4B;AACvE,aAAO,IAAI,kBAAkB,OAAO,OAAO;AAAA,IAC5C;AAAA,IACA,KAAK,OAAO;AACX,YAAM,EAAE,eAAe,IAAI,MAAM,OAAO,2BAAsB;AAC9D,aAAO,IAAI,eAAe,OAAO,OAAO;AAAA,IACzC;AAAA,EACD;AACD;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -6,12 +6,13 @@ import {
|
|
|
6
6
|
syncSetupStorageReview,
|
|
7
7
|
updateLocalConfig,
|
|
8
8
|
validateConfigName
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-C7XY5NF5.ts";
|
|
10
10
|
import {
|
|
11
11
|
normalizeSyncInclude
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-JAAKLL6M.ts";
|
|
13
13
|
|
|
14
|
-
// src/settings-management.ts
|
|
14
|
+
// src/settings/settings-management.ts
|
|
15
|
+
import { isDeepStrictEqual } from "node:util";
|
|
15
16
|
var SyncSetupReviewChangedError = class extends Error {
|
|
16
17
|
constructor(message) {
|
|
17
18
|
super(message);
|
|
@@ -25,6 +26,7 @@ async function saveNewV3Settings(input, signal) {
|
|
|
25
26
|
version: 3,
|
|
26
27
|
activeSyncSetup: input.setupName,
|
|
27
28
|
onSwitch: "ask-before-pull",
|
|
29
|
+
skipSecretScan: false,
|
|
28
30
|
storageConnections: { [input.connectionName]: structuredClone(input.connection) },
|
|
29
31
|
syncSetups: {
|
|
30
32
|
[input.setupName]: {
|
|
@@ -33,13 +35,12 @@ async function saveNewV3Settings(input, signal) {
|
|
|
33
35
|
}
|
|
34
36
|
}
|
|
35
37
|
};
|
|
36
|
-
|
|
38
|
+
return updateLocalConfig((current) => {
|
|
37
39
|
if (Object.keys(current.storageConnections).length || Object.keys(current.syncSetups).length) {
|
|
38
40
|
throw new Error(`Settings already exist: ${localConfigPath()}`);
|
|
39
41
|
}
|
|
40
|
-
return settings;
|
|
42
|
+
return { ...current, ...settings };
|
|
41
43
|
}, signal);
|
|
42
|
-
return settings;
|
|
43
44
|
}
|
|
44
45
|
async function addStorageConnection(name, connection, signal) {
|
|
45
46
|
validateConfigName(name, "storage connection");
|
|
@@ -73,7 +74,7 @@ async function updateStorageConnection(name, update, expectedSetups, signal) {
|
|
|
73
74
|
return { ...settings, storageConnections: nextConnections };
|
|
74
75
|
}, signal);
|
|
75
76
|
}
|
|
76
|
-
async function addSyncSetup(name, setup, signal) {
|
|
77
|
+
async function addSyncSetup(name, setup, signal, expectedConnection) {
|
|
77
78
|
validateConfigName(name, "sync setup");
|
|
78
79
|
await updateSettings((settings) => {
|
|
79
80
|
if (Object.hasOwn(settings.syncSetups, name))
|
|
@@ -81,6 +82,11 @@ async function addSyncSetup(name, setup, signal) {
|
|
|
81
82
|
if (!Object.hasOwn(settings.storageConnections, setup.storage.connection)) {
|
|
82
83
|
throw new Error(`Storage connection not found: ${setup.storage.connection}`);
|
|
83
84
|
}
|
|
85
|
+
if (expectedConnection && !isDeepStrictEqual(settings.storageConnections[setup.storage.connection], expectedConnection)) {
|
|
86
|
+
throw new SyncSetupReviewChangedError(
|
|
87
|
+
"Storage connection changed while the setup review was open; reopen it."
|
|
88
|
+
);
|
|
89
|
+
}
|
|
84
90
|
const nextSetups = { ...settings.syncSetups, [name]: structuredClone(setup) };
|
|
85
91
|
assertUniqueLocations(nextSetups, settings.storageConnections);
|
|
86
92
|
return {
|
|
@@ -112,6 +118,14 @@ async function updateSyncSetup(name, update, options = {}) {
|
|
|
112
118
|
);
|
|
113
119
|
}
|
|
114
120
|
}
|
|
121
|
+
if (options.expectedConnection && !isDeepStrictEqual(
|
|
122
|
+
settings.storageConnections[setup.storage.connection],
|
|
123
|
+
options.expectedConnection
|
|
124
|
+
)) {
|
|
125
|
+
throw new SyncSetupReviewChangedError(
|
|
126
|
+
"Storage connection changed while the setup review was open; reopen it."
|
|
127
|
+
);
|
|
128
|
+
}
|
|
115
129
|
const nextSetup = update(structuredClone(setup));
|
|
116
130
|
if (!Object.hasOwn(settings.storageConnections, nextSetup.storage.connection)) {
|
|
117
131
|
throw new Error(`Storage connection not found: ${nextSetup.storage.connection}`);
|
|
@@ -192,4 +206,4 @@ export {
|
|
|
192
206
|
removeSyncSetup,
|
|
193
207
|
removeStorageConnection
|
|
194
208
|
};
|
|
195
|
-
//# sourceMappingURL=chunk-
|
|
209
|
+
//# sourceMappingURL=chunk-LCRI3ABW.ts.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/settings/settings-management.ts"],
|
|
4
|
+
"sourcesContent": ["import { isDeepStrictEqual } from \"node:util\";\nimport { normalizeSyncInclude } from \"../sync/sync-policy.js\";\nimport { type SyncSetupStorageReview, syncSetupStorageReview } from \"./config.js\";\nimport { localConfigPath } from \"./config-file.js\";\nimport { updateLocalConfig } from \"./settings-store.js\";\nimport type {\n\tPiSyncSettingsV3,\n\tStorageConnectionSettings,\n\tSyncSetupSettings,\n} from \"./settings-types.js\";\nimport { effectiveSyncSetupRemoteIdentity, validateConfigName } from \"./settings-validation.js\";\n\nexport class SyncSetupReviewChangedError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"SyncSetupReviewChangedError\";\n\t}\n}\n\nexport async function saveNewV3Settings(\n\tinput: {\n\t\tsetupName: string;\n\t\tconnectionName: string;\n\t\tconnection: StorageConnectionSettings;\n\t\tsetup: SyncSetupSettings;\n\t},\n\tsignal?: AbortSignal,\n) {\n\tvalidateConfigName(input.setupName, \"sync setup\");\n\tvalidateConfigName(input.connectionName, \"storage connection\");\n\tconst settings: PiSyncSettingsV3 = {\n\t\tversion: 3,\n\t\tactiveSyncSetup: input.setupName,\n\t\tonSwitch: \"ask-before-pull\",\n\t\tskipSecretScan: false,\n\t\tstorageConnections: { [input.connectionName]: structuredClone(input.connection) },\n\t\tsyncSetups: {\n\t\t\t[input.setupName]: {\n\t\t\t\t...structuredClone(input.setup),\n\t\t\t\tstorage: { ...input.setup.storage, connection: input.connectionName },\n\t\t\t},\n\t\t},\n\t};\n\treturn updateLocalConfig((current) => {\n\t\tif (Object.keys(current.storageConnections).length || Object.keys(current.syncSetups).length) {\n\t\t\tthrow new Error(`Settings already exist: ${localConfigPath()}`);\n\t\t}\n\t\treturn { ...current, ...settings };\n\t}, signal);\n}\n\nexport async function addStorageConnection(\n\tname: string,\n\tconnection: StorageConnectionSettings,\n\tsignal?: AbortSignal,\n) {\n\tvalidateConfigName(name, \"storage connection\");\n\tawait updateSettings((settings) => {\n\t\tif (Object.hasOwn(settings.storageConnections, name)) {\n\t\t\tthrow new Error(`Storage connection already exists: ${name}`);\n\t\t}\n\t\treturn {\n\t\t\t...settings,\n\t\t\tstorageConnections: {\n\t\t\t\t...settings.storageConnections,\n\t\t\t\t[name]: structuredClone(connection),\n\t\t\t},\n\t\t};\n\t}, signal);\n}\n\nexport async function updateStorageConnection(\n\tname: string,\n\tupdate: (connection: StorageConnectionSettings) => StorageConnectionSettings,\n\texpectedSetups?: readonly string[],\n\tsignal?: AbortSignal,\n) {\n\tvalidateConfigName(name, \"storage connection\");\n\tawait updateSettings((settings) => {\n\t\tconst connection = settings.storageConnections[name];\n\t\tif (!connection) throw new Error(`Storage connection not found: ${name}`);\n\t\tconst currentSetups = referencingSetupNames(settings.syncSetups, name);\n\t\tif (expectedSetups && !sameNames(currentSetups, expectedSetups)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Storage connection \u201C${name}\u201D usage changed while it was open; reopen it and review the affected sync setups.`,\n\t\t\t);\n\t\t}\n\t\tconst nextConnection = update(structuredClone(connection));\n\t\tconst nextConnections = { ...settings.storageConnections, [name]: nextConnection };\n\t\tassertUniqueLocations(settings.syncSetups, nextConnections);\n\t\treturn { ...settings, storageConnections: nextConnections };\n\t}, signal);\n}\n\nexport async function addSyncSetup(\n\tname: string,\n\tsetup: SyncSetupSettings,\n\tsignal?: AbortSignal,\n\texpectedConnection?: StorageConnectionSettings,\n) {\n\tvalidateConfigName(name, \"sync setup\");\n\tawait updateSettings((settings) => {\n\t\tif (Object.hasOwn(settings.syncSetups, name))\n\t\t\tthrow new Error(`Sync setup already exists: ${name}`);\n\t\tif (!Object.hasOwn(settings.storageConnections, setup.storage.connection)) {\n\t\t\tthrow new Error(`Storage connection not found: ${setup.storage.connection}`);\n\t\t}\n\t\tif (\n\t\t\texpectedConnection &&\n\t\t\t!isDeepStrictEqual(settings.storageConnections[setup.storage.connection], expectedConnection)\n\t\t) {\n\t\t\tthrow new SyncSetupReviewChangedError(\n\t\t\t\t\"Storage connection changed while the setup review was open; reopen it.\",\n\t\t\t);\n\t\t}\n\t\tconst nextSetups = { ...settings.syncSetups, [name]: structuredClone(setup) };\n\t\tassertUniqueLocations(nextSetups, settings.storageConnections);\n\t\treturn {\n\t\t\t...settings,\n\t\t\tsyncSetups: nextSetups,\n\t\t\t...(settings.activeSyncSetup ? {} : { activeSyncSetup: name }),\n\t\t};\n\t}, signal);\n}\n\nexport async function updateSyncSetup(\n\tname: string,\n\tupdate: (setup: SyncSetupSettings) => SyncSetupSettings,\n\toptions: {\n\t\texpectedStorage?: SyncSetupStorageReview;\n\t\texpectedInclude?: readonly string[];\n\t\texpectedConnection?: StorageConnectionSettings;\n\t\tsignal?: AbortSignal;\n\t} = {},\n) {\n\tvalidateConfigName(name, \"sync setup\");\n\tawait updateSettings((settings) => {\n\t\tconst setup = settings.syncSetups[name];\n\t\tif (!setup) throw new Error(`Sync setup not found: ${name}`);\n\t\tif (\n\t\t\toptions.expectedInclude &&\n\t\t\t!sameNames(normalizeSyncInclude(setup.sync.include), options.expectedInclude)\n\t\t) {\n\t\t\tthrow new SyncSetupReviewChangedError(\n\t\t\t\t`Sync setup \u201C${name}\u201D included content changed while it was open; reopen it and review the current selection.`,\n\t\t\t);\n\t\t}\n\t\tif (options.expectedStorage) {\n\t\t\tconst connectionName = setup.storage.connection;\n\t\t\tconst connection = settings.storageConnections[connectionName];\n\t\t\tif (\n\t\t\t\t!connection ||\n\t\t\t\t!sameStorageReview(\n\t\t\t\t\tsyncSetupStorageReview(name, setup, connectionName, connection),\n\t\t\t\t\toptions.expectedStorage,\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\tthrow new SyncSetupReviewChangedError(\n\t\t\t\t\t`Sync setup \u201C${name}\u201D storage changed while it was open; reopen it and review the current storage location.`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tif (\n\t\t\toptions.expectedConnection &&\n\t\t\t!isDeepStrictEqual(\n\t\t\t\tsettings.storageConnections[setup.storage.connection],\n\t\t\t\toptions.expectedConnection,\n\t\t\t)\n\t\t) {\n\t\t\tthrow new SyncSetupReviewChangedError(\n\t\t\t\t\"Storage connection changed while the setup review was open; reopen it.\",\n\t\t\t);\n\t\t}\n\t\tconst nextSetup = update(structuredClone(setup));\n\t\tif (!Object.hasOwn(settings.storageConnections, nextSetup.storage.connection)) {\n\t\t\tthrow new Error(`Storage connection not found: ${nextSetup.storage.connection}`);\n\t\t}\n\t\tconst nextSetups = { ...settings.syncSetups, [name]: nextSetup };\n\t\tassertUniqueLocations(nextSetups, settings.storageConnections);\n\t\treturn { ...settings, syncSetups: nextSetups };\n\t}, options.signal);\n}\n\nexport async function removeSyncSetup(name: string, signal?: AbortSignal) {\n\tvalidateConfigName(name, \"sync setup\");\n\tawait updateSettings((settings) => {\n\t\tif (!Object.hasOwn(settings.syncSetups, name)) throw new Error(`Sync setup not found: ${name}`);\n\t\tconst isCurrent = settings.activeSyncSetup === name;\n\t\tif (isCurrent && Object.keys(settings.syncSetups).length > 1) {\n\t\t\tthrow new Error(\"Switch to another sync setup before removing the current setup.\");\n\t\t}\n\t\tconst syncSetups = { ...settings.syncSetups };\n\t\tdelete syncSetups[name];\n\t\tconst next = { ...settings, syncSetups };\n\t\tif (isCurrent) delete next.activeSyncSetup;\n\t\treturn next;\n\t}, signal);\n}\n\nexport async function removeStorageConnection(name: string, signal?: AbortSignal) {\n\tvalidateConfigName(name, \"storage connection\");\n\tawait updateSettings((settings) => {\n\t\tconst referenced = referencingSetupNames(settings.syncSetups, name)[0];\n\t\tif (referenced) {\n\t\t\tthrow new Error(`Storage connection \u201C${name}\u201D is used by sync setup \u201C${referenced}\u201D.`);\n\t\t}\n\t\tif (!Object.hasOwn(settings.storageConnections, name)) {\n\t\t\tthrow new Error(`Storage connection not found: ${name}`);\n\t\t}\n\t\tconst storageConnections = { ...settings.storageConnections };\n\t\tdelete storageConnections[name];\n\t\treturn { ...settings, storageConnections };\n\t}, signal);\n}\n\nasync function updateSettings(\n\tupdate: (settings: PiSyncSettingsV3) => PiSyncSettingsV3,\n\tsignal?: AbortSignal,\n) {\n\treturn updateLocalConfig((settings) => {\n\t\tif (settings.version !== 3) {\n\t\t\tthrow new Error(\"Storage connections and sync setups require version 3 pi-sync settings.\");\n\t\t}\n\t\treturn update(settings);\n\t}, signal);\n}\n\nfunction referencingSetupNames(setups: Record<string, SyncSetupSettings>, connection: string) {\n\treturn Object.entries(setups)\n\t\t.filter(([, setup]) => setup.storage.connection === connection)\n\t\t.map(([name]) => name)\n\t\t.sort((left, right) => left.localeCompare(right));\n}\n\nfunction assertUniqueLocations(\n\tsetups: Record<string, SyncSetupSettings>,\n\tconnections: Record<string, StorageConnectionSettings>,\n) {\n\tconst identities = new Map<string, string>();\n\tfor (const [name, setup] of Object.entries(setups)) {\n\t\tconst connection = connections[setup.storage.connection];\n\t\tif (!connection) throw new Error(`Storage connection not found: ${setup.storage.connection}`);\n\t\tconst identity = effectiveSyncSetupRemoteIdentity(setup, connection);\n\t\tconst previous = identities.get(identity);\n\t\tif (previous) {\n\t\t\tthrow new Error(`Sync setup \u201C${name}\u201D duplicates the storage location of \u201C${previous}\u201D.`);\n\t\t}\n\t\tidentities.set(identity, name);\n\t}\n}\n\nfunction sameNames(left: readonly string[], right: readonly string[]) {\n\treturn left.length === right.length && left.every((name, index) => name === right[index]);\n}\n\nfunction sameStorageReview(left: SyncSetupStorageReview, right: SyncSetupStorageReview) {\n\treturn (\n\t\tleft.connectionName === right.connectionName &&\n\t\tleft.storageKind === right.storageKind &&\n\t\tleft.storagePath === right.storagePath &&\n\t\tleft.bucket === right.bucket &&\n\t\tleft.branch === right.branch\n\t);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// @generated by scripts/build-runtime.mjs; do not edit.
|
|
2
|
+
// @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
|
|
3
|
+
|
|
4
|
+
// src/ui/terminal-text.ts
|
|
5
|
+
function safeTerminalText(value) {
|
|
6
|
+
return value.replace(/[\u0000-\u001f\u007f-\u009f]/gu, "?");
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export {
|
|
10
|
+
safeTerminalText
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=chunk-LTBWGSBV.ts.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/ui/terminal-text.ts"],
|
|
4
|
+
"sourcesContent": ["export function safeTerminalText(value: string) {\n\t// biome-ignore lint/suspicious/noControlCharactersInRegex: Escape untrusted terminal controls.\n\treturn value.replace(/[\\u0000-\\u001f\\u007f-\\u009f]/gu, \"?\");\n}\n"],
|
|
5
|
+
"mappings": ";;;;AAAO,SAAS,iBAAiB,OAAe;AAE/C,SAAO,MAAM,QAAQ,kCAAkC,GAAG;AAC3D;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// @generated by scripts/build-runtime.mjs; do not edit.
|
|
2
|
+
// @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
|
|
3
|
+
|
|
4
|
+
// src/sync/signals.ts
|
|
5
|
+
function throwIfAborted(signal) {
|
|
6
|
+
if (!signal?.aborted) return;
|
|
7
|
+
throw signal.reason instanceof Error ? signal.reason : new DOMException("The operation was aborted", "AbortError");
|
|
8
|
+
}
|
|
9
|
+
function combineSignals(primary, secondary) {
|
|
10
|
+
return secondary ? AbortSignal.any([primary, secondary]) : primary;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export {
|
|
14
|
+
throwIfAborted,
|
|
15
|
+
combineSignals
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=chunk-NJFUIVYL.ts.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/sync/signals.ts"],
|
|
4
|
+
"sourcesContent": ["export function throwIfAborted(signal?: AbortSignal) {\n\tif (!signal?.aborted) return;\n\tthrow signal.reason instanceof Error\n\t\t? signal.reason\n\t\t: new DOMException(\"The operation was aborted\", \"AbortError\");\n}\n\nexport function combineSignals(primary: AbortSignal, secondary?: AbortSignal) {\n\treturn secondary ? AbortSignal.any([primary, secondary]) : primary;\n}\n"],
|
|
5
|
+
"mappings": ";;;;AAAO,SAAS,eAAe,QAAsB;AACpD,MAAI,CAAC,QAAQ,QAAS;AACtB,QAAM,OAAO,kBAAkB,QAC5B,OAAO,SACP,IAAI,aAAa,6BAA6B,YAAY;AAC9D;AAEO,SAAS,eAAe,SAAsB,WAAyB;AAC7E,SAAO,YAAY,YAAY,IAAI,CAAC,SAAS,SAAS,CAAC,IAAI;AAC5D;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
// @generated by scripts/build-runtime.mjs; do not edit.
|
|
2
2
|
// @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
|
|
3
|
+
import {
|
|
4
|
+
sessionStorageRoot
|
|
5
|
+
} from "./chunk-THMF4BVL.ts";
|
|
3
6
|
import {
|
|
4
7
|
agentDir,
|
|
5
8
|
configuredSessionDir
|
|
6
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-T3HH3UEJ.ts";
|
|
7
10
|
import {
|
|
8
11
|
DEFAULT_SYNC_INCLUDE,
|
|
9
12
|
canonicalSnapshotPathForConfig,
|
|
@@ -20,26 +23,13 @@ import {
|
|
|
20
23
|
snapshotSelectionInclude,
|
|
21
24
|
syncIncludeSelection,
|
|
22
25
|
toPosix
|
|
23
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-JAAKLL6M.ts";
|
|
24
27
|
|
|
25
|
-
// src/snapshot.ts
|
|
28
|
+
// src/snapshot/snapshot.ts
|
|
26
29
|
import { createHash, randomUUID } from "node:crypto";
|
|
27
30
|
import fs from "node:fs/promises";
|
|
28
31
|
import os from "node:os";
|
|
29
|
-
import path2 from "node:path";
|
|
30
|
-
|
|
31
|
-
// src/snapshot-paths.ts
|
|
32
32
|
import path from "node:path";
|
|
33
|
-
function expandHome(value) {
|
|
34
|
-
if (value === "~") return process.env.HOME ?? value;
|
|
35
|
-
if (value.startsWith("~/")) return path.join(process.env.HOME ?? "~", value.slice(2));
|
|
36
|
-
return value;
|
|
37
|
-
}
|
|
38
|
-
function sessionStorageRoot(root, configuredSessionDir2) {
|
|
39
|
-
return configuredSessionDir2 ? path.resolve(expandHome(configuredSessionDir2)) : path.resolve(root, "sessions");
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// src/snapshot.ts
|
|
43
33
|
var VERSION = 1;
|
|
44
34
|
var TOP_LEVEL_FILES = DEFAULT_SYNC_INCLUDE.filter(
|
|
45
35
|
(name) => name.includes(".")
|
|
@@ -64,7 +54,7 @@ function sha256(value) {
|
|
|
64
54
|
function isSafeSnapshotPath(relativePath) {
|
|
65
55
|
if (relativePath.includes("\\")) return false;
|
|
66
56
|
const normalized = toPosix(relativePath);
|
|
67
|
-
return Boolean(normalized) && normalized !== "." && normalized !== ".." && !normalized.startsWith("../") && !
|
|
57
|
+
return Boolean(normalized) && normalized !== "." && normalized !== ".." && !normalized.startsWith("../") && !path.posix.isAbsolute(normalized) && path.posix.normalize(normalized) === normalized && !isDeniedPath(normalized);
|
|
68
58
|
}
|
|
69
59
|
function snapshotsMatch(left, right) {
|
|
70
60
|
const leftHashes = new Map(left.files.map((file) => [file.path, file.sha256]));
|
|
@@ -83,12 +73,13 @@ function regenerateSnapshotIdentity(snapshot) {
|
|
|
83
73
|
};
|
|
84
74
|
}
|
|
85
75
|
async function createSnapshot(profile, options = {}) {
|
|
76
|
+
options.signal?.throwIfAborted();
|
|
86
77
|
const include = effectiveInclude(options);
|
|
87
78
|
const syncSessions = include.includes("sessions");
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
79
|
+
const sessionDir = options.sessionDir ?? await configuredSessionDir();
|
|
80
|
+
options.signal?.throwIfAborted();
|
|
81
|
+
const files = await collectFiles(agentDir(), { include, sessionDir, signal: options.signal });
|
|
82
|
+
options.signal?.throwIfAborted();
|
|
92
83
|
return {
|
|
93
84
|
version: VERSION,
|
|
94
85
|
id: snapshotId(),
|
|
@@ -109,67 +100,79 @@ function effectiveInclude(options) {
|
|
|
109
100
|
];
|
|
110
101
|
}
|
|
111
102
|
async function collectFiles(root, options = {}) {
|
|
103
|
+
const signal = options.signal;
|
|
104
|
+
signal?.throwIfAborted();
|
|
112
105
|
const results = [];
|
|
113
106
|
const entries = await fs.readdir(root, { withFileTypes: true });
|
|
107
|
+
signal?.throwIfAborted();
|
|
114
108
|
const selection = syncIncludeSelection(effectiveInclude(options));
|
|
115
109
|
const selectedFiles = new Set(selection.builtIns);
|
|
116
110
|
for (const entry of entries) {
|
|
117
111
|
if (entry.isDirectory() && TOP_LEVEL_DIRS.has(entry.name) && selectedFiles.has(entry.name)) {
|
|
118
|
-
await collectDirectory(results, root, entry.name);
|
|
112
|
+
await collectDirectory(results, root, entry.name, { signal });
|
|
119
113
|
}
|
|
120
114
|
}
|
|
121
115
|
for (const fileName of TOP_LEVEL_FILES) {
|
|
122
116
|
if (!selectedFiles.has(fileName)) continue;
|
|
123
117
|
const entry = selectTopLevelFileEntry(entries, fileName);
|
|
124
|
-
if (entry) await addFile(results, root, entry.name, fileName);
|
|
118
|
+
if (entry) await addFile(results, root, entry.name, fileName, signal);
|
|
125
119
|
}
|
|
126
120
|
for (const relativePath of selection.custom) {
|
|
127
|
-
await collectIncludedPath(results, root, relativePath);
|
|
121
|
+
await collectIncludedPath(results, root, relativePath, signal);
|
|
128
122
|
}
|
|
129
123
|
if (selection.sessions) {
|
|
130
124
|
try {
|
|
131
125
|
await collectDirectory(results, sessionStorageRoot(root, options.sessionDir), "", {
|
|
132
126
|
sessionsOnly: true,
|
|
133
|
-
virtualPrefix: "sessions"
|
|
127
|
+
virtualPrefix: "sessions",
|
|
128
|
+
signal
|
|
134
129
|
});
|
|
135
130
|
} catch (error) {
|
|
136
131
|
if (error.code !== "ENOENT") throw error;
|
|
137
132
|
}
|
|
138
133
|
}
|
|
134
|
+
signal?.throwIfAborted();
|
|
139
135
|
return results.sort((left, right) => left.path.localeCompare(right.path));
|
|
140
136
|
}
|
|
141
|
-
async function collectIncludedPath(results, root, relativePath) {
|
|
137
|
+
async function collectIncludedPath(results, root, relativePath, signal) {
|
|
138
|
+
signal?.throwIfAborted();
|
|
142
139
|
const absolutePath = safeJoin(root, relativePath);
|
|
143
140
|
try {
|
|
144
141
|
const stat = await fs.lstat(absolutePath);
|
|
145
|
-
|
|
146
|
-
|
|
142
|
+
signal?.throwIfAborted();
|
|
143
|
+
if (stat.isFile()) await addFile(results, root, relativePath, relativePath, signal);
|
|
144
|
+
else if (stat.isDirectory()) await collectDirectory(results, root, relativePath, { signal });
|
|
147
145
|
} catch (error) {
|
|
148
146
|
if (error.code !== "ENOENT") throw error;
|
|
149
147
|
if (!relativePath.includes("/")) {
|
|
150
148
|
const entries = await fs.readdir(root, { withFileTypes: true });
|
|
149
|
+
signal?.throwIfAborted();
|
|
151
150
|
const entry = selectTopLevelFileEntry(entries, relativePath);
|
|
152
|
-
if (entry) await addFile(results, root, entry.name, relativePath);
|
|
151
|
+
if (entry) await addFile(results, root, entry.name, relativePath, signal);
|
|
153
152
|
}
|
|
154
153
|
}
|
|
155
154
|
}
|
|
156
155
|
async function collectDirectory(results, root, relativeDirectory, options = {}) {
|
|
157
|
-
|
|
156
|
+
options.signal?.throwIfAborted();
|
|
157
|
+
const absoluteDirectory = path.join(root, relativeDirectory);
|
|
158
158
|
for (const entry of await fs.readdir(absoluteDirectory, { withFileTypes: true })) {
|
|
159
|
+
options.signal?.throwIfAborted();
|
|
159
160
|
const relativePath = relativeDirectory ? posixJoin(relativeDirectory, entry.name) : entry.name;
|
|
160
161
|
const snapshotPath = options.virtualPrefix ? posixJoin(options.virtualPrefix, relativePath) : relativePath;
|
|
161
162
|
if (isDeniedPath(snapshotPath)) continue;
|
|
162
163
|
if (entry.isDirectory()) {
|
|
163
164
|
await collectDirectory(results, root, relativePath, options);
|
|
164
165
|
} else if (entry.isFile() && (!options.sessionsOnly || isSessionFilePath(snapshotPath))) {
|
|
165
|
-
await addFile(results, root, relativePath, snapshotPath);
|
|
166
|
+
await addFile(results, root, relativePath, snapshotPath, options.signal);
|
|
166
167
|
}
|
|
167
168
|
}
|
|
168
169
|
}
|
|
169
|
-
async function addFile(results, root, relativePath, snapshotPath = relativePath) {
|
|
170
|
+
async function addFile(results, root, relativePath, snapshotPath = relativePath, signal) {
|
|
171
|
+
signal?.throwIfAborted();
|
|
170
172
|
if (!isSafeSnapshotPath(snapshotPath)) return;
|
|
171
173
|
const absolutePath = safeJoin(root, relativePath);
|
|
172
|
-
const content = await fs.readFile(absolutePath);
|
|
174
|
+
const content = await fs.readFile(absolutePath, { signal });
|
|
175
|
+
signal?.throwIfAborted();
|
|
173
176
|
results.push({
|
|
174
177
|
path: snapshotPath,
|
|
175
178
|
contentBase64: content.toString("base64"),
|
|
@@ -185,9 +188,9 @@ function isSessionFilePath(relativePath) {
|
|
|
185
188
|
}
|
|
186
189
|
function sessionSnapshotPathFromAbsolute(sessionFile, configuredSessionDir2) {
|
|
187
190
|
const relativePath = toPosix(
|
|
188
|
-
|
|
191
|
+
path.relative(sessionStorageRoot(agentDir(), configuredSessionDir2), sessionFile)
|
|
189
192
|
);
|
|
190
|
-
if (!relativePath || relativePath.startsWith("../") ||
|
|
193
|
+
if (!relativePath || relativePath.startsWith("../") || path.posix.isAbsolute(relativePath)) {
|
|
191
194
|
return void 0;
|
|
192
195
|
}
|
|
193
196
|
const snapshotPath = posixJoin("sessions", relativePath);
|
|
@@ -338,7 +341,6 @@ function sameOptionalInclude(left, right) {
|
|
|
338
341
|
}
|
|
339
342
|
|
|
340
343
|
export {
|
|
341
|
-
sessionStorageRoot,
|
|
342
344
|
regenerateSnapshotIdentity,
|
|
343
345
|
createSnapshot,
|
|
344
346
|
collectFiles,
|
|
@@ -353,4 +355,4 @@ export {
|
|
|
353
355
|
mergeRemotePreservedFiles,
|
|
354
356
|
mergeRemoteSessionFiles
|
|
355
357
|
};
|
|
356
|
-
//# sourceMappingURL=chunk-
|
|
358
|
+
//# sourceMappingURL=chunk-OEX4ABY6.ts.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/snapshot/snapshot.ts"],
|
|
4
|
+
"sourcesContent": ["import { createHash, randomUUID } from \"node:crypto\";\nimport type { Dirent } from \"node:fs\";\nimport fs from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { isDeniedPath, posixJoin, safeJoin, toPosix } from \"../paths.js\";\nimport { agentDir, configuredSessionDir } from \"./session-paths.js\";\nimport { sessionStorageRoot } from \"./snapshot-paths.js\";\n\nexport { isDeniedPath } from \"../paths.js\";\nexport { sessionStorageRoot } from \"./snapshot-paths.js\";\n\nimport {\n\tcanonicalSnapshotPathForConfig,\n\tcustomIncludePathsByLower,\n\tDEFAULT_SYNC_INCLUDE,\n\tincludeFromSelectionConfig,\n\tisConfiguredSnapshotPath,\n\tisPreservableUnmanagedSnapshotPath,\n\tnormalizeExtraFiles,\n\tnormalizeSyncFiles,\n\ttype SyncSelectionConfig,\n\tselectionForSnapshot,\n\tsnapshotSelectionInclude,\n\tsyncIncludeSelection,\n} from \"../sync/sync-policy.js\";\nimport type { Snapshot, SnapshotFile, SnapshotOptions } from \"./snapshot-types.js\";\n\nexport { canonicalSnapshotPathForConfig, isConfiguredSnapshotPath } from \"../sync/sync-policy.js\";\n\nconst VERSION = 1;\nconst TOP_LEVEL_FILES: readonly string[] = DEFAULT_SYNC_INCLUDE.filter((name) =>\n\tname.includes(\".\"),\n);\nconst TOP_LEVEL_DIRS = new Set<string>(DEFAULT_SYNC_INCLUDE.filter((name) => !name.includes(\".\")));\nconst SECRET_PATTERNS = [\n\t/AWS_SECRET_ACCESS_KEY\\s*[=:]\\s*['\"]?[A-Za-z0-9/+]{35,}/i,\n\t/(ANTHROPIC|OPENAI|GEMINI|GOOGLE|FIRECRAWL|GITHUB|CLOUDFLARE|R2|S3)_[A-Z0-9_]*(KEY|TOKEN|SECRET)\\s*[=:]\\s*['\"]?[^\\s'\"]{12,}/i,\n\t/sk-ant-[A-Za-z0-9_-]{20,}/,\n\t/sk-[A-Za-z0-9]{20,}/,\n\t/gh[pousr]_[A-Za-z0-9_]{20,}/,\n];\n\nfunction selectTopLevelFileEntry(entries: Dirent[], fileName: string) {\n\tconst exact = entries.find((entry) => entry.isFile() && entry.name === fileName);\n\tif (exact) return exact;\n\tconst lower = fileName.toLowerCase();\n\treturn entries\n\t\t.filter((entry) => entry.isFile() && entry.name.toLowerCase() === lower)\n\t\t.sort((left, right) => left.name.localeCompare(right.name))[0];\n}\n\nfunction sha256(value: Buffer) {\n\treturn createHash(\"sha256\").update(value).digest(\"hex\");\n}\n\nfunction isSafeSnapshotPath(relativePath: string) {\n\tif (relativePath.includes(\"\\\\\")) return false;\n\tconst normalized = toPosix(relativePath);\n\treturn (\n\t\tBoolean(normalized) &&\n\t\tnormalized !== \".\" &&\n\t\tnormalized !== \"..\" &&\n\t\t!normalized.startsWith(\"../\") &&\n\t\t!path.posix.isAbsolute(normalized) &&\n\t\tpath.posix.normalize(normalized) === normalized &&\n\t\t!isDeniedPath(normalized)\n\t);\n}\n\nfunction snapshotsMatch(left: Snapshot, right: Snapshot) {\n\tconst leftHashes = new Map(left.files.map((file) => [file.path, file.sha256]));\n\tconst rightHashes = new Map(right.files.map((file) => [file.path, file.sha256]));\n\treturn (\n\t\tleft.syncSessions === right.syncSessions &&\n\t\tsameOptionalInclude(snapshotSelectionInclude(left), snapshotSelectionInclude(right)) &&\n\t\tleftHashes.size === rightHashes.size &&\n\t\t[...leftHashes].every(([filePath, hash]) => rightHashes.get(filePath) === hash)\n\t);\n}\n\nfunction snapshotId() {\n\treturn `${new Date().toISOString().replace(/[:.]/g, \"-\")}-${randomUUID().slice(0, 8)}`;\n}\n\nexport function regenerateSnapshotIdentity(snapshot: Snapshot): Snapshot {\n\treturn {\n\t\t...snapshot,\n\t\tid: snapshotId(),\n\t\tcreatedAt: new Date().toISOString(),\n\t\tmachine: os.hostname(),\n\t};\n}\n\nexport async function createSnapshot(\n\tprofile: string,\n\toptions: SnapshotOptions = {},\n): Promise<Snapshot> {\n\toptions.signal?.throwIfAborted();\n\tconst include = effectiveInclude(options);\n\tconst syncSessions = include.includes(\"sessions\");\n\tconst sessionDir = options.sessionDir ?? (await configuredSessionDir());\n\toptions.signal?.throwIfAborted();\n\tconst files = await collectFiles(agentDir(), { include, sessionDir, signal: options.signal });\n\toptions.signal?.throwIfAborted();\n\treturn {\n\t\tversion: VERSION,\n\t\tid: snapshotId(),\n\t\tcreatedAt: new Date().toISOString(),\n\t\tmachine: os.hostname(),\n\t\tprofile,\n\t\tsyncSessions,\n\t\tselection: selectionForSnapshot(include),\n\t\tfiles,\n\t};\n}\n\nfunction effectiveInclude(options: SnapshotOptions) {\n\tif (options.include) return options.include;\n\treturn [\n\t\t...normalizeSyncFiles(options.syncFiles),\n\t\t...normalizeExtraFiles(options.extraFiles),\n\t\t...(options.syncSessions ? [\"sessions\"] : []),\n\t];\n}\n\nexport async function collectFiles(\n\troot: string,\n\toptions: SnapshotOptions = {},\n): Promise<SnapshotFile[]> {\n\tconst signal = options.signal;\n\tsignal?.throwIfAborted();\n\tconst results: SnapshotFile[] = [];\n\tconst entries = await fs.readdir(root, { withFileTypes: true });\n\tsignal?.throwIfAborted();\n\tconst selection = syncIncludeSelection(effectiveInclude(options));\n\tconst selectedFiles = new Set<string>(selection.builtIns);\n\tfor (const entry of entries) {\n\t\tif (entry.isDirectory() && TOP_LEVEL_DIRS.has(entry.name) && selectedFiles.has(entry.name)) {\n\t\t\tawait collectDirectory(results, root, entry.name, { signal });\n\t\t}\n\t}\n\tfor (const fileName of TOP_LEVEL_FILES) {\n\t\tif (!selectedFiles.has(fileName)) continue;\n\t\tconst entry = selectTopLevelFileEntry(entries, fileName);\n\t\tif (entry) await addFile(results, root, entry.name, fileName, signal);\n\t}\n\tfor (const relativePath of selection.custom) {\n\t\tawait collectIncludedPath(results, root, relativePath, signal);\n\t}\n\tif (selection.sessions) {\n\t\ttry {\n\t\t\tawait collectDirectory(results, sessionStorageRoot(root, options.sessionDir), \"\", {\n\t\t\t\tsessionsOnly: true,\n\t\t\t\tvirtualPrefix: \"sessions\",\n\t\t\t\tsignal,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tif ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n\t\t}\n\t}\n\tsignal?.throwIfAborted();\n\treturn results.sort((left, right) => left.path.localeCompare(right.path));\n}\n\nasync function collectIncludedPath(\n\tresults: SnapshotFile[],\n\troot: string,\n\trelativePath: string,\n\tsignal?: AbortSignal,\n) {\n\tsignal?.throwIfAborted();\n\tconst absolutePath = safeJoin(root, relativePath);\n\ttry {\n\t\tconst stat = await fs.lstat(absolutePath);\n\t\tsignal?.throwIfAborted();\n\t\tif (stat.isFile()) await addFile(results, root, relativePath, relativePath, signal);\n\t\telse if (stat.isDirectory()) await collectDirectory(results, root, relativePath, { signal });\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error;\n\t\tif (!relativePath.includes(\"/\")) {\n\t\t\tconst entries = await fs.readdir(root, { withFileTypes: true });\n\t\t\tsignal?.throwIfAborted();\n\t\t\tconst entry = selectTopLevelFileEntry(entries, relativePath);\n\t\t\tif (entry) await addFile(results, root, entry.name, relativePath, signal);\n\t\t}\n\t}\n}\n\nasync function collectDirectory(\n\tresults: SnapshotFile[],\n\troot: string,\n\trelativeDirectory: string,\n\toptions: { sessionsOnly?: boolean; virtualPrefix?: string; signal?: AbortSignal } = {},\n) {\n\toptions.signal?.throwIfAborted();\n\tconst absoluteDirectory = path.join(root, relativeDirectory);\n\tfor (const entry of await fs.readdir(absoluteDirectory, { withFileTypes: true })) {\n\t\toptions.signal?.throwIfAborted();\n\t\tconst relativePath = relativeDirectory ? posixJoin(relativeDirectory, entry.name) : entry.name;\n\t\tconst snapshotPath = options.virtualPrefix\n\t\t\t? posixJoin(options.virtualPrefix, relativePath)\n\t\t\t: relativePath;\n\t\tif (isDeniedPath(snapshotPath)) continue;\n\t\tif (entry.isDirectory()) {\n\t\t\tawait collectDirectory(results, root, relativePath, options);\n\t\t} else if (entry.isFile() && (!options.sessionsOnly || isSessionFilePath(snapshotPath))) {\n\t\t\tawait addFile(results, root, relativePath, snapshotPath, options.signal);\n\t\t}\n\t}\n}\n\nasync function addFile(\n\tresults: SnapshotFile[],\n\troot: string,\n\trelativePath: string,\n\tsnapshotPath = relativePath,\n\tsignal?: AbortSignal,\n) {\n\tsignal?.throwIfAborted();\n\tif (!isSafeSnapshotPath(snapshotPath)) return;\n\tconst absolutePath = safeJoin(root, relativePath);\n\tconst content = await fs.readFile(absolutePath, { signal });\n\tsignal?.throwIfAborted();\n\tresults.push({\n\t\tpath: snapshotPath,\n\t\tcontentBase64: content.toString(\"base64\"),\n\t\tsha256: sha256(content),\n\t});\n}\n\nexport function isSessionPath(relativePath: string) {\n\treturn toPosix(relativePath).startsWith(\"sessions/\");\n}\n\nexport function isSessionFilePath(relativePath: string) {\n\tconst normalized = toPosix(relativePath);\n\treturn isSessionPath(normalized) && normalized.endsWith(\".jsonl\");\n}\n\nexport function sessionSnapshotPathFromAbsolute(\n\tsessionFile: string,\n\tconfiguredSessionDir?: string,\n) {\n\tconst relativePath = toPosix(\n\t\tpath.relative(sessionStorageRoot(agentDir(), configuredSessionDir), sessionFile),\n\t);\n\tif (!relativePath || relativePath.startsWith(\"../\") || path.posix.isAbsolute(relativePath)) {\n\t\treturn undefined;\n\t}\n\tconst snapshotPath = posixJoin(\"sessions\", relativePath);\n\treturn isSessionFilePath(snapshotPath) ? snapshotPath : undefined;\n}\n\nexport function snapshotTarget(root: string, relativePath: string, configuredSessionDir?: string) {\n\tif (isSessionPath(relativePath)) {\n\t\treturn safeJoin(\n\t\t\tsessionStorageRoot(root, configuredSessionDir),\n\t\t\trelativePath.slice(\"sessions/\".length),\n\t\t);\n\t}\n\treturn safeJoin(root, relativePath);\n}\n\nexport function snapshotIncludesSessions(snapshot: Snapshot) {\n\treturn (\n\t\tsnapshot.syncSessions === true ||\n\t\tsnapshotSelectionInclude(snapshot)?.includes(\"sessions\") === true ||\n\t\tsnapshot.files.some((file) => isSessionPath(file.path))\n\t);\n}\n\nexport function filterSnapshotForConfigPolicy(\n\tsnapshot: Snapshot,\n\tconfig: SyncSelectionConfig,\n\toptions: { regenerateId?: boolean } = {},\n) {\n\tconst include = includeFromSelectionConfig(config);\n\tconst includePaths = customIncludePathsByLower(include);\n\tconst filtered = {\n\t\t...snapshot,\n\t\tsyncSessions: include.includes(\"sessions\") ? snapshot.syncSessions : false,\n\t\tselection: selectionForSnapshot(include),\n\t\tfiles: canonicalizeSnapshotFilesForConfig(snapshot.files, config, includePaths),\n\t};\n\tif (!options.regenerateId || snapshotsMatch(snapshot, filtered)) return filtered;\n\treturn {\n\t\t...filtered,\n\t\tid: snapshotId(),\n\t\tcreatedAt: new Date().toISOString(),\n\t\tmachine: os.hostname(),\n\t};\n}\n\nfunction canonicalizeSnapshotFilesForConfig(\n\tfiles: SnapshotFile[],\n\tconfig: SyncSelectionConfig,\n\tincludePaths: Map<string, string>,\n) {\n\tconst configuredFiles: SnapshotFile[] = [];\n\tconst extraCandidates = new Map<\n\t\tstring,\n\t\t{ exact: boolean; file: SnapshotFile; originalPath: string }\n\t>();\n\tfor (const file of files) {\n\t\tconst normalized = toPosix(file.path);\n\t\tif (!isSafeSnapshotPath(file.path) || !isConfiguredSnapshotPath(normalized, config)) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (normalized.includes(\"/\")) {\n\t\t\tconfiguredFiles.push(normalized === file.path ? file : { ...file, path: normalized });\n\t\t\tcontinue;\n\t\t}\n\t\tconst topLevelPath = canonicalSnapshotPathForConfig(normalized, includePaths);\n\t\tconst candidate = {\n\t\t\texact: normalized === topLevelPath,\n\t\t\tfile: { ...file, path: topLevelPath },\n\t\t\toriginalPath: normalized,\n\t\t};\n\t\tconst current = extraCandidates.get(topLevelPath.toLowerCase());\n\t\tif (!current || isPreferredExtraCandidate(candidate, current)) {\n\t\t\textraCandidates.set(topLevelPath.toLowerCase(), candidate);\n\t\t}\n\t}\n\treturn [\n\t\t...configuredFiles,\n\t\t...[...extraCandidates.values()].map((candidate) => candidate.file),\n\t].sort((left, right) => left.path.localeCompare(right.path));\n}\n\nfunction isPreferredExtraCandidate(\n\tleft: { exact: boolean; originalPath: string },\n\tright: { exact: boolean; originalPath: string },\n) {\n\tif (left.exact !== right.exact) return left.exact;\n\treturn left.originalPath.localeCompare(right.originalPath) < 0;\n}\n\nexport function snapshotWithoutSessions(snapshot: Snapshot) {\n\tconst files = snapshot.files.filter((file) => !isSessionPath(file.path));\n\tconst include = snapshotSelectionInclude(snapshot)?.filter((item) => item !== \"sessions\");\n\tif (\n\t\tfiles.length === snapshot.files.length &&\n\t\tsnapshot.syncSessions !== true &&\n\t\tinclude?.length === snapshot.selection?.include.length\n\t) {\n\t\treturn snapshot;\n\t}\n\treturn {\n\t\t...snapshot,\n\t\tid: snapshotId(),\n\t\tcreatedAt: new Date().toISOString(),\n\t\tmachine: os.hostname(),\n\t\tsyncSessions: false,\n\t\t...(include ? { selection: selectionForSnapshot(include) } : {}),\n\t\tfiles,\n\t};\n}\n\nexport function scanSnapshot(snapshot: Snapshot) {\n\tconst findings: string[] = [];\n\tfor (const file of snapshot.files) {\n\t\tconst content = Buffer.from(file.contentBase64, \"base64\");\n\t\tif (content.includes(0)) continue;\n\t\tconst text = content.toString(\"utf8\");\n\t\tfor (const pattern of SECRET_PATTERNS) {\n\t\t\tif (pattern.test(text)) {\n\t\t\t\tfindings.push(file.path);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn findings;\n}\n\nexport function mergeRemotePreservedFiles(\n\tlocal: Snapshot,\n\tremote: Snapshot,\n\tconfig: SyncSelectionConfig,\n) {\n\tconst localPathNames = new Set(local.files.map((file) => file.path.toLowerCase()));\n\tconst preservedPathNames = new Set<string>();\n\tconst preserved = remote.files.filter((file) => {\n\t\tconst normalized = toPosix(file.path);\n\t\tconst lower = normalized.toLowerCase();\n\t\tif (\n\t\t\tlocalPathNames.has(lower) ||\n\t\t\tpreservedPathNames.has(lower) ||\n\t\t\t!isSafeSnapshotPath(file.path) ||\n\t\t\tisConfiguredSnapshotPath(normalized, config) ||\n\t\t\t!isPreservableUnmanagedSnapshotPath(normalized)\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\t\tpreservedPathNames.add(lower);\n\t\treturn true;\n\t});\n\tif (preserved.length === 0) return local;\n\treturn {\n\t\t...local,\n\t\tid: snapshotId(),\n\t\tcreatedAt: new Date().toISOString(),\n\t\tmachine: os.hostname(),\n\t\tsyncSessions: snapshotIncludesSessions(local) || snapshotIncludesSessions(remote),\n\t\tfiles: [...local.files, ...preserved].sort((left, right) =>\n\t\t\tleft.path.localeCompare(right.path),\n\t\t),\n\t};\n}\n\nexport function mergeRemoteSessionFiles(local: Snapshot, remote: Snapshot) {\n\tconst remoteSessions = remote.files.filter((file) => {\n\t\tconst normalized = toPosix(file.path);\n\t\treturn isSessionFilePath(normalized) && isSafeSnapshotPath(file.path);\n\t});\n\tif (remoteSessions.length === 0 && !snapshotIncludesSessions(remote)) return local;\n\tconst localInclude = snapshotSelectionInclude(local);\n\treturn {\n\t\t...local,\n\t\tid: snapshotId(),\n\t\tcreatedAt: new Date().toISOString(),\n\t\tmachine: os.hostname(),\n\t\tsyncSessions: true,\n\t\t...(localInclude\n\t\t\t? {\n\t\t\t\t\tselection: selectionForSnapshot(\n\t\t\t\t\t\tlocalInclude.includes(\"sessions\") ? localInclude : [...localInclude, \"sessions\"],\n\t\t\t\t\t),\n\t\t\t\t}\n\t\t\t: {}),\n\t\tfiles: [...local.files.filter((file) => !isSessionPath(file.path)), ...remoteSessions].sort(\n\t\t\t(left, right) => left.path.localeCompare(right.path),\n\t\t),\n\t};\n}\n\nfunction sameOptionalInclude(left: string[] | undefined, right: string[] | undefined) {\n\tif (!left || !right) return left === right;\n\treturn left.length === right.length && left.every((item, index) => item === right[index]);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["configuredSessionDir"]
|
|
7
|
+
}
|