@infinite-room-labs/claudesync-core 0.4.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/sync/__tests__/files-mode.test.d.ts +2 -0
- package/dist/sync/__tests__/files-mode.test.d.ts.map +1 -0
- package/dist/sync/__tests__/files-mode.test.js +156 -0
- package/dist/sync/__tests__/files-mode.test.js.map +1 -0
- package/dist/sync/files-mode.d.ts +47 -0
- package/dist/sync/files-mode.d.ts.map +1 -0
- package/dist/sync/files-mode.js +94 -0
- package/dist/sync/files-mode.js.map +1 -0
- package/dist/sync/incremental.d.ts +8 -0
- package/dist/sync/incremental.d.ts.map +1 -1
- package/dist/sync/incremental.js +19 -38
- package/dist/sync/incremental.js.map +1 -1
- package/dist/util/__tests__/glob.test.d.ts +2 -0
- package/dist/util/__tests__/glob.test.d.ts.map +1 -0
- package/dist/util/__tests__/glob.test.js +57 -0
- package/dist/util/__tests__/glob.test.js.map +1 -0
- package/dist/util/glob.d.ts +24 -0
- package/dist/util/glob.d.ts.map +1 -0
- package/dist/util/glob.js +94 -0
- package/dist/util/glob.js.map +1 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -24,5 +24,8 @@ export type { ExportFormat, SyncConversationOptions, SyncConversationResult, } f
|
|
|
24
24
|
export { syncConversation, isSameByListMetadata, } from "./sync/incremental.js";
|
|
25
25
|
export type { FetchAndBuildOptions, FetchAndBuildResult, } from "./sync/fetch.js";
|
|
26
26
|
export { fetchAndBuild } from "./sync/fetch.js";
|
|
27
|
+
export type { ReplaceWithPreserveOptions } from "./sync/files-mode.js";
|
|
28
|
+
export { replaceWithPreserve, walkRelative } from "./sync/files-mode.js";
|
|
27
29
|
export { slugify, safeSlug, displayName } from "./util/naming.js";
|
|
30
|
+
export { matchGlob, matchAnyGlob, compileGlob } from "./util/glob.js";
|
|
28
31
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAG7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAG5D,OAAO,EACL,kBAAkB,EAClB,0BAA0B,EAC1B,gBAAgB,EAChB,iBAAiB,EACjB,yBAAyB,EACzB,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,EACpB,0BAA0B,EAC1B,0BAA0B,EAC1B,aAAa,EACb,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAG7B,YAAY,EACV,YAAY,EACZ,oBAAoB,EACpB,UAAU,EACV,WAAW,EACX,mBAAmB,EACnB,YAAY,EACZ,WAAW,EACX,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACpB,OAAO,EACP,UAAU,GACX,MAAM,mBAAmB,CAAC;AAG3B,YAAY,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,cAAc,GACf,MAAM,wBAAwB,CAAC;AAGhC,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpE,YAAY,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAGxE,YAAY,EACV,SAAS,EACT,aAAa,EACb,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,cAAc,EACd,eAAe,EACf,aAAa,EACb,cAAc,GACf,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,gBAAgB,EAChB,UAAU,EACV,YAAY,EACZ,YAAY,GACb,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,YAAY,EACZ,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAG7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAG5D,OAAO,EACL,kBAAkB,EAClB,0BAA0B,EAC1B,gBAAgB,EAChB,iBAAiB,EACjB,yBAAyB,EACzB,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,EACpB,0BAA0B,EAC1B,0BAA0B,EAC1B,aAAa,EACb,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAG7B,YAAY,EACV,YAAY,EACZ,oBAAoB,EACpB,UAAU,EACV,WAAW,EACX,mBAAmB,EACnB,YAAY,EACZ,WAAW,EACX,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACpB,OAAO,EACP,UAAU,GACX,MAAM,mBAAmB,CAAC;AAG3B,YAAY,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,cAAc,GACf,MAAM,wBAAwB,CAAC;AAGhC,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpE,YAAY,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAGxE,YAAY,EACV,SAAS,EACT,aAAa,EACb,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,cAAc,EACd,eAAe,EACf,aAAa,EACb,cAAc,GACf,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,gBAAgB,EAChB,UAAU,EACV,YAAY,EACZ,YAAY,GACb,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACV,YAAY,EACZ,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGzE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAGlE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -16,6 +16,9 @@ export { diffConversation } from "./sync/diff.js";
|
|
|
16
16
|
export { CHANGELOG_FILENAME, renderChangelogSection, appendChangelog, } from "./sync/changelog.js";
|
|
17
17
|
export { syncConversation, isSameByListMetadata, } from "./sync/incremental.js";
|
|
18
18
|
export { fetchAndBuild } from "./sync/fetch.js";
|
|
19
|
+
export { replaceWithPreserve, walkRelative } from "./sync/files-mode.js";
|
|
19
20
|
// Naming helpers
|
|
20
21
|
export { slugify, safeSlug, displayName } from "./util/naming.js";
|
|
22
|
+
// Glob helpers
|
|
23
|
+
export { matchGlob, matchAnyGlob, compileGlob } from "./util/glob.js";
|
|
21
24
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,SAAS;AACT,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAE5D,oBAAoB;AACpB,OAAO,EACL,kBAAkB,EAClB,0BAA0B,EAC1B,gBAAgB,EAChB,iBAAiB,EACjB,yBAAyB,EACzB,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,EACpB,0BAA0B,EAC1B,0BAA0B,EAC1B,aAAa,EACb,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAoB7B,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,cAAc,GACf,MAAM,wBAAwB,CAAC;AAKhC,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAQxE,OAAO,EACL,cAAc,EACd,eAAe,EACf,aAAa,EACb,cAAc,GACf,MAAM,iBAAiB,CAAC;AAOzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAM7B,OAAO,EACL,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAK/B,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,iBAAiB;AACjB,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,SAAS;AACT,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAE5D,oBAAoB;AACpB,OAAO,EACL,kBAAkB,EAClB,0BAA0B,EAC1B,gBAAgB,EAChB,iBAAiB,EACjB,yBAAyB,EACzB,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,EACpB,0BAA0B,EAC1B,0BAA0B,EAC1B,aAAa,EACb,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAoB7B,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,cAAc,GACf,MAAM,wBAAwB,CAAC;AAKhC,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAQxE,OAAO,EACL,cAAc,EACd,eAAe,EACf,aAAa,EACb,cAAc,GACf,MAAM,iBAAiB,CAAC;AAOzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAM7B,OAAO,EACL,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAK/B,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzE,iBAAiB;AACjB,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAElE,eAAe;AACf,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files-mode.test.d.ts","sourceRoot":"","sources":["../../../src/sync/__tests__/files-mode.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { describe, expect, it, beforeEach, afterEach } from "vitest";
|
|
2
|
+
import { mkdtempSync, rmSync, writeFileSync, existsSync, readFileSync, mkdirSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { replaceWithPreserve, walkRelative } from "../files-mode.js";
|
|
6
|
+
let workdir;
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
workdir = mkdtempSync(join(tmpdir(), "claudesync-files-mode-"));
|
|
9
|
+
});
|
|
10
|
+
afterEach(() => {
|
|
11
|
+
rmSync(workdir, { recursive: true, force: true });
|
|
12
|
+
});
|
|
13
|
+
function writeFile(p, content) {
|
|
14
|
+
mkdirSync(join(workdir, p, ".."), { recursive: true });
|
|
15
|
+
writeFileSync(join(workdir, p), content, "utf-8");
|
|
16
|
+
}
|
|
17
|
+
describe("replaceWithPreserve", () => {
|
|
18
|
+
it("creates outputPath on first run (no stash to merge from)", async () => {
|
|
19
|
+
const outputPath = join(workdir, "convo");
|
|
20
|
+
await replaceWithPreserve({
|
|
21
|
+
outputPath,
|
|
22
|
+
writeFresh: async () => {
|
|
23
|
+
mkdirSync(outputPath, { recursive: true });
|
|
24
|
+
writeFileSync(join(outputPath, "conversation.md"), "fresh body", "utf-8");
|
|
25
|
+
},
|
|
26
|
+
alwaysPreserve: ["CHANGELOG.md"],
|
|
27
|
+
preserveGlobs: ["INDEX.md"],
|
|
28
|
+
});
|
|
29
|
+
expect(readFileSync(join(outputPath, "conversation.md"), "utf-8")).toBe("fresh body");
|
|
30
|
+
});
|
|
31
|
+
it("preserves alwaysPreserve files across re-sync", async () => {
|
|
32
|
+
const outputPath = join(workdir, "convo");
|
|
33
|
+
// Initial state.
|
|
34
|
+
mkdirSync(outputPath, { recursive: true });
|
|
35
|
+
writeFileSync(join(outputPath, "conversation.md"), "v1 body", "utf-8");
|
|
36
|
+
writeFileSync(join(outputPath, "CHANGELOG.md"), "## changelog v1\n", "utf-8");
|
|
37
|
+
// Re-sync rewrites the dir.
|
|
38
|
+
await replaceWithPreserve({
|
|
39
|
+
outputPath,
|
|
40
|
+
writeFresh: async () => {
|
|
41
|
+
mkdirSync(outputPath, { recursive: true });
|
|
42
|
+
writeFileSync(join(outputPath, "conversation.md"), "v2 body", "utf-8");
|
|
43
|
+
},
|
|
44
|
+
alwaysPreserve: ["CHANGELOG.md"],
|
|
45
|
+
});
|
|
46
|
+
expect(readFileSync(join(outputPath, "conversation.md"), "utf-8")).toBe("v2 body");
|
|
47
|
+
expect(readFileSync(join(outputPath, "CHANGELOG.md"), "utf-8")).toBe("## changelog v1\n");
|
|
48
|
+
});
|
|
49
|
+
it("preserves files matching preserveGlobs", async () => {
|
|
50
|
+
const outputPath = join(workdir, "convo");
|
|
51
|
+
mkdirSync(outputPath, { recursive: true });
|
|
52
|
+
writeFileSync(join(outputPath, "INDEX.md"), "indexer output\n", "utf-8");
|
|
53
|
+
writeFileSync(join(outputPath, "conversation.md"), "v1", "utf-8");
|
|
54
|
+
await replaceWithPreserve({
|
|
55
|
+
outputPath,
|
|
56
|
+
writeFresh: async () => {
|
|
57
|
+
mkdirSync(outputPath, { recursive: true });
|
|
58
|
+
writeFileSync(join(outputPath, "conversation.md"), "v2", "utf-8");
|
|
59
|
+
},
|
|
60
|
+
preserveGlobs: ["INDEX.md"],
|
|
61
|
+
});
|
|
62
|
+
expect(readFileSync(join(outputPath, "INDEX.md"), "utf-8")).toBe("indexer output\n");
|
|
63
|
+
expect(readFileSync(join(outputPath, "conversation.md"), "utf-8")).toBe("v2");
|
|
64
|
+
});
|
|
65
|
+
it("drops files matching alwaysDrop even if they match preserveGlobs", async () => {
|
|
66
|
+
const outputPath = join(workdir, "convo");
|
|
67
|
+
mkdirSync(outputPath, { recursive: true });
|
|
68
|
+
writeFileSync(join(outputPath, ".claudesync-state.json"), "{\"old\":true}", "utf-8");
|
|
69
|
+
writeFileSync(join(outputPath, "conversation.md"), "v1", "utf-8");
|
|
70
|
+
await replaceWithPreserve({
|
|
71
|
+
outputPath,
|
|
72
|
+
writeFresh: async () => {
|
|
73
|
+
mkdirSync(outputPath, { recursive: true });
|
|
74
|
+
writeFileSync(join(outputPath, "conversation.md"), "v2", "utf-8");
|
|
75
|
+
},
|
|
76
|
+
alwaysDrop: [".claudesync-state.json"],
|
|
77
|
+
preserveGlobs: ["**"], // even with greedy preserve, alwaysDrop wins
|
|
78
|
+
});
|
|
79
|
+
expect(existsSync(join(outputPath, ".claudesync-state.json"))).toBe(false);
|
|
80
|
+
});
|
|
81
|
+
it("preserves nested files matching ** globs", async () => {
|
|
82
|
+
const outputPath = join(workdir, "project");
|
|
83
|
+
mkdirSync(join(outputPath, "conversations/foo"), { recursive: true });
|
|
84
|
+
writeFileSync(join(outputPath, "conversations/foo/INDEX.md"), "nested index\n", "utf-8");
|
|
85
|
+
writeFileSync(join(outputPath, "README.md"), "v1", "utf-8");
|
|
86
|
+
await replaceWithPreserve({
|
|
87
|
+
outputPath,
|
|
88
|
+
writeFresh: async () => {
|
|
89
|
+
mkdirSync(join(outputPath, "conversations/foo"), { recursive: true });
|
|
90
|
+
writeFileSync(join(outputPath, "README.md"), "v2", "utf-8");
|
|
91
|
+
writeFileSync(join(outputPath, "conversations/foo/conversation.md"), "v2", "utf-8");
|
|
92
|
+
},
|
|
93
|
+
preserveGlobs: ["**/INDEX.md"],
|
|
94
|
+
});
|
|
95
|
+
expect(readFileSync(join(outputPath, "conversations/foo/INDEX.md"), "utf-8")).toBe("nested index\n");
|
|
96
|
+
expect(readFileSync(join(outputPath, "README.md"), "utf-8")).toBe("v2");
|
|
97
|
+
});
|
|
98
|
+
it("does not clobber when the bundle wrote the same relative path", async () => {
|
|
99
|
+
const outputPath = join(workdir, "convo");
|
|
100
|
+
mkdirSync(outputPath, { recursive: true });
|
|
101
|
+
writeFileSync(join(outputPath, "conversation.md"), "stash version", "utf-8");
|
|
102
|
+
await replaceWithPreserve({
|
|
103
|
+
outputPath,
|
|
104
|
+
writeFresh: async () => {
|
|
105
|
+
mkdirSync(outputPath, { recursive: true });
|
|
106
|
+
writeFileSync(join(outputPath, "conversation.md"), "bundle version", "utf-8");
|
|
107
|
+
},
|
|
108
|
+
preserveGlobs: ["conversation.md"], // user mis-glob; bundle should win
|
|
109
|
+
});
|
|
110
|
+
expect(readFileSync(join(outputPath, "conversation.md"), "utf-8")).toBe("bundle version");
|
|
111
|
+
});
|
|
112
|
+
it("restores the stash on writeFresh failure", async () => {
|
|
113
|
+
const outputPath = join(workdir, "convo");
|
|
114
|
+
mkdirSync(outputPath, { recursive: true });
|
|
115
|
+
writeFileSync(join(outputPath, "conversation.md"), "original", "utf-8");
|
|
116
|
+
await expect(replaceWithPreserve({
|
|
117
|
+
outputPath,
|
|
118
|
+
writeFresh: async () => {
|
|
119
|
+
throw new Error("boom");
|
|
120
|
+
},
|
|
121
|
+
})).rejects.toThrow("boom");
|
|
122
|
+
expect(readFileSync(join(outputPath, "conversation.md"), "utf-8")).toBe("original");
|
|
123
|
+
expect(existsSync(outputPath + ".prev")).toBe(false);
|
|
124
|
+
});
|
|
125
|
+
it("removes stale stash directory before renaming", async () => {
|
|
126
|
+
const outputPath = join(workdir, "convo");
|
|
127
|
+
mkdirSync(outputPath, { recursive: true });
|
|
128
|
+
writeFileSync(join(outputPath, "conversation.md"), "v1", "utf-8");
|
|
129
|
+
// Pre-existing stash from a previously-crashed run.
|
|
130
|
+
const staleStash = outputPath + ".prev";
|
|
131
|
+
mkdirSync(staleStash, { recursive: true });
|
|
132
|
+
writeFileSync(join(staleStash, "junk.md"), "leftover", "utf-8");
|
|
133
|
+
await replaceWithPreserve({
|
|
134
|
+
outputPath,
|
|
135
|
+
writeFresh: async () => {
|
|
136
|
+
mkdirSync(outputPath, { recursive: true });
|
|
137
|
+
writeFileSync(join(outputPath, "conversation.md"), "v2", "utf-8");
|
|
138
|
+
},
|
|
139
|
+
});
|
|
140
|
+
expect(readFileSync(join(outputPath, "conversation.md"), "utf-8")).toBe("v2");
|
|
141
|
+
expect(existsSync(staleStash)).toBe(false);
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
describe("walkRelative", () => {
|
|
145
|
+
it("yields all file paths with POSIX separators", () => {
|
|
146
|
+
writeFile("a.md", "1");
|
|
147
|
+
writeFile("nested/b.md", "2");
|
|
148
|
+
writeFile("nested/deep/c.md", "3");
|
|
149
|
+
const paths = [...walkRelative(workdir)].sort();
|
|
150
|
+
expect(paths).toEqual(["a.md", "nested/b.md", "nested/deep/c.md"]);
|
|
151
|
+
});
|
|
152
|
+
it("returns empty for nonexistent root", () => {
|
|
153
|
+
expect([...walkRelative(join(workdir, "missing"))]).toEqual([]);
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
//# sourceMappingURL=files-mode.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files-mode.test.js","sourceRoot":"","sources":["../../../src/sync/__tests__/files-mode.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stash-and-rebuild file-writing primitive shared between conversation and
|
|
3
|
+
* project export paths.
|
|
4
|
+
*
|
|
5
|
+
* Both code paths produce a fresh, claudesync-canonical directory tree on
|
|
6
|
+
* every re-sync. Without explicit rescue, anything the user added locally
|
|
7
|
+
* (INDEX.md from a downstream indexer, hand-written notes, etc.) would be
|
|
8
|
+
* wiped on every run.
|
|
9
|
+
*
|
|
10
|
+
* This helper:
|
|
11
|
+
* 1. Renames the existing outputPath to a `<outputPath>.prev` stash.
|
|
12
|
+
* 2. Runs the caller-supplied `writeFresh` to populate a clean outputPath.
|
|
13
|
+
* 3. Walks the stash and copies back files that either equal an entry in
|
|
14
|
+
* `alwaysPreserve` or match any glob in `preserveGlobs`.
|
|
15
|
+
* 4. Removes the stash on success, restores it on failure.
|
|
16
|
+
*
|
|
17
|
+
* Copies are non-destructive: if writeFresh already produced a file at the
|
|
18
|
+
* same relative path, the bundle wins and the stash copy is skipped. This
|
|
19
|
+
* protects against a user pattern accidentally clobbering conversation.md
|
|
20
|
+
* or README.md.
|
|
21
|
+
*/
|
|
22
|
+
export interface ReplaceWithPreserveOptions {
|
|
23
|
+
/** Final destination directory. May or may not exist. */
|
|
24
|
+
outputPath: string;
|
|
25
|
+
/** Callback that populates `outputPath` from scratch. Must create the dir. */
|
|
26
|
+
writeFresh: () => Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Files preserved by exact relative-path match. CHANGELOG.md is the
|
|
29
|
+
* canonical example; the changelog is appended to by the sync.
|
|
30
|
+
*/
|
|
31
|
+
alwaysPreserve?: readonly string[];
|
|
32
|
+
/**
|
|
33
|
+
* Files dropped by exact relative-path match, even if they would otherwise
|
|
34
|
+
* match `preserveGlobs`. `.claudesync-state.json` is the canonical example;
|
|
35
|
+
* the caller rewrites it after this returns.
|
|
36
|
+
*/
|
|
37
|
+
alwaysDrop?: readonly string[];
|
|
38
|
+
/**
|
|
39
|
+
* Glob patterns (POSIX) of locally-added files to preserve. Matched against
|
|
40
|
+
* paths relative to `outputPath`. See `util/glob.ts` for syntax.
|
|
41
|
+
*/
|
|
42
|
+
preserveGlobs?: readonly string[];
|
|
43
|
+
}
|
|
44
|
+
export declare function replaceWithPreserve(opts: ReplaceWithPreserveOptions): Promise<void>;
|
|
45
|
+
/** Yield every file path under root, as POSIX-separated paths relative to root. */
|
|
46
|
+
export declare function walkRelative(root: string): Generator<string>;
|
|
47
|
+
//# sourceMappingURL=files-mode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files-mode.d.ts","sourceRoot":"","sources":["../../src/sync/files-mode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAMH,MAAM,WAAW,0BAA0B;IACzC,yDAAyD;IACzD,UAAU,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC;;;OAGG;IACH,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC;;;;OAIG;IACH,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B;;;OAGG;IACH,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,0BAA0B,GAC/B,OAAO,CAAC,IAAI,CAAC,CAmCf;AAyBD,mFAAmF;AACnF,wBAAiB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAoB7D"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stash-and-rebuild file-writing primitive shared between conversation and
|
|
3
|
+
* project export paths.
|
|
4
|
+
*
|
|
5
|
+
* Both code paths produce a fresh, claudesync-canonical directory tree on
|
|
6
|
+
* every re-sync. Without explicit rescue, anything the user added locally
|
|
7
|
+
* (INDEX.md from a downstream indexer, hand-written notes, etc.) would be
|
|
8
|
+
* wiped on every run.
|
|
9
|
+
*
|
|
10
|
+
* This helper:
|
|
11
|
+
* 1. Renames the existing outputPath to a `<outputPath>.prev` stash.
|
|
12
|
+
* 2. Runs the caller-supplied `writeFresh` to populate a clean outputPath.
|
|
13
|
+
* 3. Walks the stash and copies back files that either equal an entry in
|
|
14
|
+
* `alwaysPreserve` or match any glob in `preserveGlobs`.
|
|
15
|
+
* 4. Removes the stash on success, restores it on failure.
|
|
16
|
+
*
|
|
17
|
+
* Copies are non-destructive: if writeFresh already produced a file at the
|
|
18
|
+
* same relative path, the bundle wins and the stash copy is skipped. This
|
|
19
|
+
* protects against a user pattern accidentally clobbering conversation.md
|
|
20
|
+
* or README.md.
|
|
21
|
+
*/
|
|
22
|
+
import fs from "node:fs";
|
|
23
|
+
import path from "node:path";
|
|
24
|
+
import { matchAnyGlob } from "../util/glob.js";
|
|
25
|
+
export async function replaceWithPreserve(opts) {
|
|
26
|
+
const { outputPath, writeFresh, alwaysPreserve = [], alwaysDrop = [], preserveGlobs = [], } = opts;
|
|
27
|
+
const stash = outputPath + ".prev";
|
|
28
|
+
const isUpdate = fs.existsSync(outputPath);
|
|
29
|
+
if (isUpdate) {
|
|
30
|
+
if (fs.existsSync(stash)) {
|
|
31
|
+
fs.rmSync(stash, { recursive: true, force: true });
|
|
32
|
+
}
|
|
33
|
+
fs.renameSync(outputPath, stash);
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
await writeFresh();
|
|
37
|
+
if (isUpdate) {
|
|
38
|
+
restoreFromStash(stash, outputPath, alwaysPreserve, alwaysDrop, preserveGlobs);
|
|
39
|
+
fs.rmSync(stash, { recursive: true, force: true });
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
if (isUpdate) {
|
|
44
|
+
if (fs.existsSync(outputPath)) {
|
|
45
|
+
fs.rmSync(outputPath, { recursive: true, force: true });
|
|
46
|
+
}
|
|
47
|
+
if (fs.existsSync(stash)) {
|
|
48
|
+
fs.renameSync(stash, outputPath);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
throw error;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function restoreFromStash(stash, outputPath, alwaysPreserve, alwaysDrop, preserveGlobs) {
|
|
55
|
+
const dropSet = new Set(alwaysDrop);
|
|
56
|
+
const preserveSet = new Set(alwaysPreserve);
|
|
57
|
+
for (const rel of walkRelative(stash)) {
|
|
58
|
+
if (dropSet.has(rel))
|
|
59
|
+
continue;
|
|
60
|
+
const shouldPreserve = preserveSet.has(rel) || matchAnyGlob(rel, preserveGlobs);
|
|
61
|
+
if (!shouldPreserve)
|
|
62
|
+
continue;
|
|
63
|
+
const dest = path.join(outputPath, rel);
|
|
64
|
+
if (fs.existsSync(dest))
|
|
65
|
+
continue; // bundle wins
|
|
66
|
+
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
67
|
+
fs.copyFileSync(path.join(stash, rel), dest);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/** Yield every file path under root, as POSIX-separated paths relative to root. */
|
|
71
|
+
export function* walkRelative(root) {
|
|
72
|
+
const stack = [""];
|
|
73
|
+
while (stack.length > 0) {
|
|
74
|
+
const rel = stack.pop();
|
|
75
|
+
const abs = rel === "" ? root : path.join(root, rel);
|
|
76
|
+
let entries;
|
|
77
|
+
try {
|
|
78
|
+
entries = fs.readdirSync(abs, { withFileTypes: true });
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
for (const entry of entries) {
|
|
84
|
+
const childRel = rel === "" ? entry.name : `${rel}/${entry.name}`;
|
|
85
|
+
if (entry.isDirectory()) {
|
|
86
|
+
stack.push(childRel);
|
|
87
|
+
}
|
|
88
|
+
else if (entry.isFile() || entry.isSymbolicLink()) {
|
|
89
|
+
yield childRel;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=files-mode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files-mode.js","sourceRoot":"","sources":["../../src/sync/files-mode.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,6 +12,14 @@ export interface SyncConversationOptions {
|
|
|
12
12
|
skipExisting?: boolean;
|
|
13
13
|
/** Don't fetch artifacts. */
|
|
14
14
|
skipArtifacts?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Glob patterns (POSIX-style) of locally-added files inside the
|
|
17
|
+
* conversation directory that must survive a re-sync in `files` mode.
|
|
18
|
+
* Matched against paths relative to the conversation directory. The
|
|
19
|
+
* CHANGELOG.md sidecar is always preserved regardless of this list.
|
|
20
|
+
* Examples: ["INDEX.md", "notes/**", "*.local.md"].
|
|
21
|
+
*/
|
|
22
|
+
preserve?: string[];
|
|
15
23
|
}
|
|
16
24
|
export interface SyncConversationResult {
|
|
17
25
|
action: "skipped" | "skipped-existing" | "full" | "incremental";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"incremental.d.ts","sourceRoot":"","sources":["../../src/sync/incremental.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,KAAK,EAGV,mBAAmB,EACpB,MAAM,oBAAoB,CAAC;AAQ5B,OAAO,EAIL,KAAK,SAAS,EACf,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"incremental.d.ts","sourceRoot":"","sources":["../../src/sync/incremental.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,KAAK,EAGV,mBAAmB,EACpB,MAAM,oBAAoB,CAAC;AAQ5B,OAAO,EAIL,KAAK,SAAS,EACf,MAAM,YAAY,CAAC;AAMpB,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,OAAO,GAAG,MAAM,CAAC;AAEpD,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,YAAY,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,oEAAoE;IACpE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,iEAAiE;IACjE,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,6BAA6B;IAC7B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,SAAS,GAAG,kBAAkB,GAAG,MAAM,GAAG,aAAa,CAAC;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,0FAA0F;IAC1F,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,IAAI,CAAC,mBAAmB,EAAE,YAAY,GAAG,2BAA2B,CAAC,EAC9E,SAAS,EAAE,SAAS,GAAG,SAAS,GAC/B,OAAO,CAMT;AAED;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,gBAAgB,EACxB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,mBAAmB,EAC5B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,sBAAsB,CAAC,CAmGjC"}
|
package/dist/sync/incremental.js
CHANGED
|
@@ -8,6 +8,7 @@ import { readSyncState, writeSyncState, STATE_FILENAME, } from "./state.js";
|
|
|
8
8
|
import { buildMessageTree, findLeafMessages } from "../tree/message-tree.js";
|
|
9
9
|
import { fetchAndBuild } from "./fetch.js";
|
|
10
10
|
import { displayName as toDisplayName } from "../util/naming.js";
|
|
11
|
+
import { replaceWithPreserve } from "./files-mode.js";
|
|
11
12
|
/**
|
|
12
13
|
* Cheap predicate for --skip-same. Returns true when the list-endpoint summary
|
|
13
14
|
* matches what the sidecar state file recorded on the previous sync. Caller
|
|
@@ -97,7 +98,7 @@ export async function syncConversation(client, orgId, summary, outputPath, optio
|
|
|
97
98
|
}
|
|
98
99
|
}
|
|
99
100
|
else {
|
|
100
|
-
await writeFilesMode(bundle, outputPath);
|
|
101
|
+
await writeFilesMode(bundle, outputPath, options.preserve ?? []);
|
|
101
102
|
}
|
|
102
103
|
let changelogWritten = false;
|
|
103
104
|
const section = renderChangelogSection(diff, new Date());
|
|
@@ -118,44 +119,24 @@ export async function syncConversation(client, orgId, summary, outputPath, optio
|
|
|
118
119
|
/**
|
|
119
120
|
* Files mode: replay bundle into outputPath via the same tmp+swap pattern as
|
|
120
121
|
* exportToGit, but strip .git at the end.
|
|
122
|
+
*
|
|
123
|
+
* Preservation: every re-sync rebuilds the directory from scratch. Files that
|
|
124
|
+
* the user (or a downstream tool) added locally would be wiped without
|
|
125
|
+
* explicit rescue. We always preserve `CHANGELOG.md` (appended to by the
|
|
126
|
+
* sync), drop the prior `.claudesync-state.json` (rewritten by the caller),
|
|
127
|
+
* and copy back anything else in the stash matching the `preserve` glob list.
|
|
121
128
|
*/
|
|
122
|
-
async function writeFilesMode(bundle, outputPath) {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
try {
|
|
134
|
-
await exportToGit(bundle, outputPath);
|
|
135
|
-
rmSync(path.join(outputPath, ".git"), { recursive: true, force: true });
|
|
136
|
-
// Preserve CHANGELOG.md from the previous tree (we'll append to it after).
|
|
137
|
-
if (isUpdate && fs.existsSync(path.join(stash, CHANGELOG_FILENAME))) {
|
|
138
|
-
fs.copyFileSync(path.join(stash, CHANGELOG_FILENAME), path.join(outputPath, CHANGELOG_FILENAME));
|
|
139
|
-
}
|
|
140
|
-
if (isUpdate && fs.existsSync(path.join(stash, STATE_FILENAME))) {
|
|
141
|
-
// State file gets rewritten by caller; nothing to preserve.
|
|
142
|
-
}
|
|
143
|
-
if (isUpdate) {
|
|
144
|
-
fs.rmSync(stash, { recursive: true, force: true });
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
catch (error) {
|
|
148
|
-
// Restore original on failure.
|
|
149
|
-
if (isUpdate) {
|
|
150
|
-
if (fs.existsSync(outputPath)) {
|
|
151
|
-
fs.rmSync(outputPath, { recursive: true, force: true });
|
|
152
|
-
}
|
|
153
|
-
if (fs.existsSync(stash)) {
|
|
154
|
-
fs.renameSync(stash, outputPath);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
throw error;
|
|
158
|
-
}
|
|
129
|
+
async function writeFilesMode(bundle, outputPath, preserve) {
|
|
130
|
+
await replaceWithPreserve({
|
|
131
|
+
outputPath,
|
|
132
|
+
writeFresh: async () => {
|
|
133
|
+
await exportToGit(bundle, outputPath);
|
|
134
|
+
rmSync(path.join(outputPath, ".git"), { recursive: true, force: true });
|
|
135
|
+
},
|
|
136
|
+
alwaysPreserve: [CHANGELOG_FILENAME],
|
|
137
|
+
alwaysDrop: [STATE_FILENAME],
|
|
138
|
+
preserveGlobs: preserve,
|
|
139
|
+
});
|
|
159
140
|
}
|
|
160
141
|
function ensureGitignore(repoDir) {
|
|
161
142
|
const gitignorePath = path.join(repoDir, ".gitignore");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"incremental.js","sourceRoot":"","sources":["../../src/sync/incremental.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAOjC,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,aAAa,EACb,cAAc,EACd,cAAc,GAEf,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,WAAW,IAAI,aAAa,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"incremental.js","sourceRoot":"","sources":["../../src/sync/incremental.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glob.test.d.ts","sourceRoot":"","sources":["../../../src/util/__tests__/glob.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { matchGlob, matchAnyGlob } from "../glob.js";
|
|
3
|
+
describe("matchGlob", () => {
|
|
4
|
+
it("matches literal filenames", () => {
|
|
5
|
+
expect(matchGlob("INDEX.md", "INDEX.md")).toBe(true);
|
|
6
|
+
expect(matchGlob("README.md", "INDEX.md")).toBe(false);
|
|
7
|
+
});
|
|
8
|
+
it("matches single * within a segment", () => {
|
|
9
|
+
expect(matchGlob("foo.md", "*.md")).toBe(true);
|
|
10
|
+
expect(matchGlob("foo.txt", "*.md")).toBe(false);
|
|
11
|
+
expect(matchGlob("notes/foo.md", "*.md")).toBe(false); // * does not cross /
|
|
12
|
+
});
|
|
13
|
+
it("matches ** across path segments", () => {
|
|
14
|
+
expect(matchGlob("notes/foo.md", "notes/**")).toBe(true);
|
|
15
|
+
expect(matchGlob("notes/nested/deep.md", "notes/**")).toBe(true);
|
|
16
|
+
expect(matchGlob("notes/", "notes/**")).toBe(true);
|
|
17
|
+
expect(matchGlob("other/foo.md", "notes/**")).toBe(false);
|
|
18
|
+
});
|
|
19
|
+
it("**/ collapses zero or more path segments", () => {
|
|
20
|
+
expect(matchGlob("INDEX.md", "**/INDEX.md")).toBe(true);
|
|
21
|
+
expect(matchGlob("a/INDEX.md", "**/INDEX.md")).toBe(true);
|
|
22
|
+
expect(matchGlob("a/b/c/INDEX.md", "**/INDEX.md")).toBe(true);
|
|
23
|
+
expect(matchGlob("INDEX.txt", "**/INDEX.md")).toBe(false);
|
|
24
|
+
});
|
|
25
|
+
it("? matches exactly one non-slash char", () => {
|
|
26
|
+
expect(matchGlob("foo.md", "fo?.md")).toBe(true);
|
|
27
|
+
expect(matchGlob("foo.md", "f??.md")).toBe(true);
|
|
28
|
+
expect(matchGlob("fo.md", "fo?.md")).toBe(false);
|
|
29
|
+
expect(matchGlob("fo/o.md", "fo?o.md")).toBe(false);
|
|
30
|
+
});
|
|
31
|
+
it("character classes work", () => {
|
|
32
|
+
expect(matchGlob("a.md", "[ab].md")).toBe(true);
|
|
33
|
+
expect(matchGlob("b.md", "[ab].md")).toBe(true);
|
|
34
|
+
expect(matchGlob("c.md", "[ab].md")).toBe(false);
|
|
35
|
+
});
|
|
36
|
+
it("normalizes leading ./ and backslashes", () => {
|
|
37
|
+
expect(matchGlob("./INDEX.md", "INDEX.md")).toBe(true);
|
|
38
|
+
expect(matchGlob("notes\\foo.md", "notes/foo.md")).toBe(true);
|
|
39
|
+
});
|
|
40
|
+
it("escapes regex metacharacters in literal segments", () => {
|
|
41
|
+
expect(matchGlob("a.b+c.md", "a.b+c.md")).toBe(true);
|
|
42
|
+
expect(matchGlob("axb+c.md", "a.b+c.md")).toBe(false); // . is literal, not regex any-char
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
describe("matchAnyGlob", () => {
|
|
46
|
+
it("returns true when any pattern matches", () => {
|
|
47
|
+
expect(matchAnyGlob("INDEX.md", ["README.md", "INDEX.md"])).toBe(true);
|
|
48
|
+
expect(matchAnyGlob("notes/x.md", ["INDEX.md", "notes/**"])).toBe(true);
|
|
49
|
+
});
|
|
50
|
+
it("returns false when no pattern matches", () => {
|
|
51
|
+
expect(matchAnyGlob("foo.txt", ["INDEX.md", "*.md"])).toBe(false);
|
|
52
|
+
});
|
|
53
|
+
it("returns false on empty pattern list", () => {
|
|
54
|
+
expect(matchAnyGlob("INDEX.md", [])).toBe(false);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
//# sourceMappingURL=glob.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glob.test.js","sourceRoot":"","sources":["../../../src/util/__tests__/glob.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal POSIX-style glob matcher for relative paths.
|
|
3
|
+
*
|
|
4
|
+
* Supports:
|
|
5
|
+
* * -- any sequence of non-slash chars
|
|
6
|
+
* ** -- any sequence including slashes
|
|
7
|
+
* ? -- single non-slash char
|
|
8
|
+
* [abc] -- character class
|
|
9
|
+
* literal segments
|
|
10
|
+
*
|
|
11
|
+
* Paths are normalized to forward slashes before matching. Patterns must use
|
|
12
|
+
* forward slashes regardless of platform. Leading `./` is stripped.
|
|
13
|
+
*
|
|
14
|
+
* No brace expansion ({a,b}) and no extglob -- if you need those, swap in
|
|
15
|
+
* minimatch. This helper exists so core can ship zero-dep glob matching for
|
|
16
|
+
* the --preserve flag without dragging in a 30KB dependency.
|
|
17
|
+
*/
|
|
18
|
+
/** Compile a pattern once for repeated matching. */
|
|
19
|
+
export declare function compileGlob(pattern: string): (subject: string) => boolean;
|
|
20
|
+
/** Match a relative path against a single pattern. Convenience wrapper. */
|
|
21
|
+
export declare function matchGlob(subject: string, pattern: string): boolean;
|
|
22
|
+
/** True if any pattern matches. Compiles each pattern once per call. */
|
|
23
|
+
export declare function matchAnyGlob(subject: string, patterns: readonly string[]): boolean;
|
|
24
|
+
//# sourceMappingURL=glob.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glob.d.ts","sourceRoot":"","sources":["../../src/util/glob.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AA0DH,oDAAoD;AACpD,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAMzE;AAED,2EAA2E;AAC3E,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAEnE;AAED,wEAAwE;AACxE,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAMlF"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal POSIX-style glob matcher for relative paths.
|
|
3
|
+
*
|
|
4
|
+
* Supports:
|
|
5
|
+
* * -- any sequence of non-slash chars
|
|
6
|
+
* ** -- any sequence including slashes
|
|
7
|
+
* ? -- single non-slash char
|
|
8
|
+
* [abc] -- character class
|
|
9
|
+
* literal segments
|
|
10
|
+
*
|
|
11
|
+
* Paths are normalized to forward slashes before matching. Patterns must use
|
|
12
|
+
* forward slashes regardless of platform. Leading `./` is stripped.
|
|
13
|
+
*
|
|
14
|
+
* No brace expansion ({a,b}) and no extglob -- if you need those, swap in
|
|
15
|
+
* minimatch. This helper exists so core can ship zero-dep glob matching for
|
|
16
|
+
* the --preserve flag without dragging in a 30KB dependency.
|
|
17
|
+
*/
|
|
18
|
+
function globToRegExp(pattern) {
|
|
19
|
+
// Normalize: strip leading ./ and any duplicate slashes.
|
|
20
|
+
const norm = pattern.replace(/^\.\//, "").replace(/\/+/g, "/");
|
|
21
|
+
let re = "^";
|
|
22
|
+
let i = 0;
|
|
23
|
+
while (i < norm.length) {
|
|
24
|
+
const ch = norm[i];
|
|
25
|
+
if (ch === "*") {
|
|
26
|
+
if (norm[i + 1] === "*") {
|
|
27
|
+
// ** -> match anything including /
|
|
28
|
+
// **/ -> match zero or more path segments (consume the trailing /)
|
|
29
|
+
if (norm[i + 2] === "/") {
|
|
30
|
+
re += "(?:.*/)?";
|
|
31
|
+
i += 3;
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
re += ".*";
|
|
35
|
+
i += 2;
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
// single * -> any sequence of non-/ chars
|
|
39
|
+
re += "[^/]*";
|
|
40
|
+
i += 1;
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
if (ch === "?") {
|
|
44
|
+
re += "[^/]";
|
|
45
|
+
i += 1;
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (ch === "[") {
|
|
49
|
+
// copy character class verbatim until matching ]
|
|
50
|
+
const close = norm.indexOf("]", i + 1);
|
|
51
|
+
if (close === -1) {
|
|
52
|
+
// unterminated class -- treat as literal [
|
|
53
|
+
re += "\\[";
|
|
54
|
+
i += 1;
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
re += norm.slice(i, close + 1);
|
|
58
|
+
i = close + 1;
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
// Escape regex metachars; keep slashes literal.
|
|
62
|
+
if (/[.+^${}()|\\]/.test(ch)) {
|
|
63
|
+
re += "\\" + ch;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
re += ch;
|
|
67
|
+
}
|
|
68
|
+
i += 1;
|
|
69
|
+
}
|
|
70
|
+
re += "$";
|
|
71
|
+
return new RegExp(re);
|
|
72
|
+
}
|
|
73
|
+
/** Compile a pattern once for repeated matching. */
|
|
74
|
+
export function compileGlob(pattern) {
|
|
75
|
+
const rx = globToRegExp(pattern);
|
|
76
|
+
return (subject) => {
|
|
77
|
+
const norm = subject.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
78
|
+
return rx.test(norm);
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/** Match a relative path against a single pattern. Convenience wrapper. */
|
|
82
|
+
export function matchGlob(subject, pattern) {
|
|
83
|
+
return compileGlob(pattern)(subject);
|
|
84
|
+
}
|
|
85
|
+
/** True if any pattern matches. Compiles each pattern once per call. */
|
|
86
|
+
export function matchAnyGlob(subject, patterns) {
|
|
87
|
+
const norm = subject.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
88
|
+
for (const p of patterns) {
|
|
89
|
+
if (globToRegExp(p).test(norm))
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=glob.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glob.js","sourceRoot":"","sources":["../../src/util/glob.ts"],"names":[],"mappings":"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"}
|