@indigoai-us/hq-cloud 6.15.2 → 6.15.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/sync-mutation.d.ts +1 -3
- package/dist/bin/sync-mutation.d.ts.map +1 -1
- package/dist/bin/sync-mutation.js +5 -5
- package/dist/bin/sync-mutation.js.map +1 -1
- package/dist/bin/sync-mutation.test.js +36 -137
- package/dist/bin/sync-mutation.test.js.map +1 -1
- package/dist/bin/sync-runner-company.d.ts.map +1 -1
- package/dist/bin/sync-runner-company.js +15 -0
- package/dist/bin/sync-runner-company.js.map +1 -1
- package/dist/bin/sync-runner-company.test.js +71 -0
- package/dist/bin/sync-runner-company.test.js.map +1 -1
- package/dist/bin/sync-runner-events.test.js +21 -0
- package/dist/bin/sync-runner-events.test.js.map +1 -1
- package/dist/bin/sync-runner.d.ts +5 -0
- package/dist/bin/sync-runner.d.ts.map +1 -1
- package/dist/bin/sync-runner.js.map +1 -1
- package/dist/cli/share.d.ts.map +1 -1
- package/dist/cli/share.js +23 -6
- package/dist/cli/share.js.map +1 -1
- package/dist/cli/share.test.js +54 -1
- package/dist/cli/share.test.js.map +1 -1
- package/dist/cli/sync.d.ts +31 -6
- package/dist/cli/sync.d.ts.map +1 -1
- package/dist/cli/sync.js +58 -38
- package/dist/cli/sync.js.map +1 -1
- package/dist/cli/sync.test.js +180 -47
- package/dist/cli/sync.test.js.map +1 -1
- package/dist/s3.d.ts +36 -0
- package/dist/s3.d.ts.map +1 -1
- package/dist/s3.js +61 -1
- package/dist/s3.js.map +1 -1
- package/dist/s3.symlink-materialize.test.js +161 -1
- package/dist/s3.symlink-materialize.test.js.map +1 -1
- package/dist/sync/base-version-resolver.d.ts +11 -0
- package/dist/sync/base-version-resolver.d.ts.map +1 -0
- package/dist/sync/base-version-resolver.js +48 -0
- package/dist/sync/base-version-resolver.js.map +1 -0
- package/dist/sync/base-version-resolver.test.d.ts +2 -0
- package/dist/sync/base-version-resolver.test.d.ts.map +1 -0
- package/dist/sync/base-version-resolver.test.js +24 -0
- package/dist/sync/base-version-resolver.test.js.map +1 -0
- package/dist/sync/lease-client.d.ts +17 -0
- package/dist/sync/lease-client.d.ts.map +1 -1
- package/dist/sync/lease-client.js +46 -1
- package/dist/sync/lease-client.js.map +1 -1
- package/dist/sync/mutation-client.d.ts +2 -0
- package/dist/sync/mutation-client.d.ts.map +1 -1
- package/dist/sync/mutation-client.js +2 -0
- package/dist/sync/mutation-client.js.map +1 -1
- package/dist/sync/mutation-session.d.ts +49 -0
- package/dist/sync/mutation-session.d.ts.map +1 -0
- package/dist/sync/mutation-session.js +282 -0
- package/dist/sync/mutation-session.js.map +1 -0
- package/dist/sync/mutation-session.test.d.ts +2 -0
- package/dist/sync/mutation-session.test.d.ts.map +1 -0
- package/dist/sync/mutation-session.test.js +190 -0
- package/dist/sync/mutation-session.test.js.map +1 -0
- package/dist/sync/uploader-finalization.d.ts +20 -0
- package/dist/sync/uploader-finalization.d.ts.map +1 -1
- package/dist/sync/uploader-finalization.js +48 -0
- package/dist/sync/uploader-finalization.js.map +1 -1
- package/dist/sync/uploader-finalization.test.js +15 -0
- package/dist/sync/uploader-finalization.test.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/share.test.js
CHANGED
|
@@ -27,6 +27,18 @@ vi.mock("../s3.js", () => ({
|
|
|
27
27
|
headRemoteFile: vi.fn().mockResolvedValue(null),
|
|
28
28
|
primeObjectTransport: vi.fn().mockResolvedValue(undefined),
|
|
29
29
|
primeUploads: vi.fn().mockResolvedValue(undefined),
|
|
30
|
+
// Real exports share.ts now imports for the HQ-DESKTOP-54 privilege skip.
|
|
31
|
+
WINDOWS_SYMLINK_PRIVILEGE_REMEDY: "Enable Windows Developer Mode (Settings > Privacy & security > For developers) or run HQ sync once from an elevated terminal, then sync again.",
|
|
32
|
+
WindowsSymlinkPrivilegeError: class WindowsSymlinkPrivilegeError extends Error {
|
|
33
|
+
target;
|
|
34
|
+
code;
|
|
35
|
+
constructor(target, code) {
|
|
36
|
+
super(`symlink skipped: creating a file symlink to ${target} requires a Windows privilege`);
|
|
37
|
+
this.name = "WindowsSymlinkPrivilegeError";
|
|
38
|
+
this.target = target;
|
|
39
|
+
this.code = code;
|
|
40
|
+
}
|
|
41
|
+
},
|
|
30
42
|
}));
|
|
31
43
|
// Mock readline so the interactive-conflict serialization test can observe
|
|
32
44
|
// prompt lifecycle (createInterface + close) without ever touching stdin.
|
|
@@ -40,7 +52,7 @@ vi.mock("readline", () => ({
|
|
|
40
52
|
}));
|
|
41
53
|
import * as readline from "readline";
|
|
42
54
|
import { share, isForbiddenCompanyVaultKey, UnreachablePushPathsError, _testing as shareTesting } from "./share.js";
|
|
43
|
-
import { deleteRemoteFile, downloadFile, headRemoteFile, uploadFile, uploadSymlink } from "../s3.js";
|
|
55
|
+
import { deleteRemoteFile, downloadFile, headRemoteFile, uploadFile, uploadSymlink, WindowsSymlinkPrivilegeError } from "../s3.js";
|
|
44
56
|
import { VaultAuthError } from "../vault-client.js";
|
|
45
57
|
import { hashFile } from "../journal.js";
|
|
46
58
|
const mockConfig = {
|
|
@@ -879,6 +891,47 @@ describe("share", () => {
|
|
|
879
891
|
expect(result.conflictPaths).toEqual(["v7b-abort.txt"]);
|
|
880
892
|
expect(result.filesUploaded).toBe(0);
|
|
881
893
|
});
|
|
894
|
+
it("HQ-DESKTOP-54: a privilege refusal while writing the push conflict mirror is a skip, not an error", async () => {
|
|
895
|
+
// The keep-mirror also materializes the remote object (to a .conflict-*
|
|
896
|
+
// file). On an unprivileged Windows host that throws the typed privilege
|
|
897
|
+
// error; it must be downgraded to the deliberate skip so the push stays
|
|
898
|
+
// complete and the runner exits 0 — never type:error. The conflict itself
|
|
899
|
+
// is still recorded and the local file is untouched.
|
|
900
|
+
const companyRoot = path.join(tmpDir, "companies", "acme");
|
|
901
|
+
fs.mkdirSync(companyRoot, { recursive: true });
|
|
902
|
+
const testFile = path.join(companyRoot, "v7b-priv.txt");
|
|
903
|
+
fs.writeFileSync(testFile, "local-collision-content");
|
|
904
|
+
vi.mocked(headRemoteFile).mockResolvedValueOnce({
|
|
905
|
+
lastModified: new Date(),
|
|
906
|
+
etag: '"remote-version-etag"',
|
|
907
|
+
size: 40,
|
|
908
|
+
});
|
|
909
|
+
// On a real unprivileged host BOTH the fresh-collision reconciled probe and
|
|
910
|
+
// the keep-mirror materialize the remote symlink, so both downloadFile calls
|
|
911
|
+
// refuse. The probe's catch returns "differs" (conflict) without erroring;
|
|
912
|
+
// the mirror must downgrade the refusal to the deliberate skip.
|
|
913
|
+
vi.mocked(downloadFile)
|
|
914
|
+
.mockRejectedValueOnce(new WindowsSymlinkPrivilegeError("../target.md", "EPERM"))
|
|
915
|
+
.mockRejectedValueOnce(new WindowsSymlinkPrivilegeError("../target.md", "EPERM"));
|
|
916
|
+
const events = [];
|
|
917
|
+
const result = await share({
|
|
918
|
+
paths: [testFile],
|
|
919
|
+
company: "acme",
|
|
920
|
+
vaultConfig: mockConfig,
|
|
921
|
+
hqRoot: tmpDir,
|
|
922
|
+
onConflict: "keep",
|
|
923
|
+
onEvent: (e) => events.push(e),
|
|
924
|
+
});
|
|
925
|
+
expect(events).toContainEqual(expect.objectContaining({
|
|
926
|
+
type: "skip-symlink-privilege",
|
|
927
|
+
path: "v7b-priv.txt",
|
|
928
|
+
target: "../target.md",
|
|
929
|
+
}));
|
|
930
|
+
expect(events.some((e) => e.type === "error")).toBe(false);
|
|
931
|
+
// The conflict is still recorded; the local file is preserved.
|
|
932
|
+
expect(result.conflictPaths).toEqual(["v7b-priv.txt"]);
|
|
933
|
+
expect(fs.readFileSync(testFile, "utf-8")).toBe("local-collision-content");
|
|
934
|
+
});
|
|
882
935
|
it("fresh-install SSE-KMS etag: byte-identical remote is reconciled without a conflict", async () => {
|
|
883
936
|
const companyRoot = path.join(tmpDir, "companies", "acme");
|
|
884
937
|
fs.mkdirSync(companyRoot, { recursive: true });
|