@cueloop/integration-obsidian 0.1.0-alpha.21 → 0.1.0-alpha.22
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/package.json +3 -3
- package/src/detect.test.ts +3 -0
- package/src/export.test.ts +37 -0
- package/src/filename.test.ts +12 -0
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cueloop/integration-obsidian",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.22",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": "./src/index.ts"
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"@cueloop/extension-api": "0.1.0-alpha.
|
|
11
|
-
"@cueloop/schema": "0.1.0-alpha.
|
|
10
|
+
"@cueloop/extension-api": "0.1.0-alpha.22",
|
|
11
|
+
"@cueloop/schema": "0.1.0-alpha.22"
|
|
12
12
|
},
|
|
13
13
|
"publishConfig": {
|
|
14
14
|
"access": "public"
|
package/src/detect.test.ts
CHANGED
|
@@ -15,6 +15,7 @@ afterEach(() => {
|
|
|
15
15
|
|
|
16
16
|
describe("detectVaults", () => {
|
|
17
17
|
test("returns registered vault paths that exist on disk", () => {
|
|
18
|
+
// Arrange
|
|
18
19
|
const alive = join(dir, "notes");
|
|
19
20
|
mkdirSync(alive);
|
|
20
21
|
const gone = join(dir, "deleted-vault");
|
|
@@ -28,6 +29,8 @@ describe("detectVaults", () => {
|
|
|
28
29
|
},
|
|
29
30
|
}),
|
|
30
31
|
);
|
|
32
|
+
|
|
33
|
+
// Assert
|
|
31
34
|
expect(detectVaults(configPath)).toEqual([alive]);
|
|
32
35
|
});
|
|
33
36
|
|
package/src/export.test.ts
CHANGED
|
@@ -44,8 +44,13 @@ function config(overrides: Partial<ObsidianConfig> = {}): ObsidianConfig {
|
|
|
44
44
|
|
|
45
45
|
describe("exportSession", () => {
|
|
46
46
|
test("writes the final plan with frontmatter into vault/folder", () => {
|
|
47
|
+
// Arrange
|
|
47
48
|
const session = resolvedSession();
|
|
49
|
+
|
|
50
|
+
// Act
|
|
48
51
|
const result = exportSession(session, config(), NOW);
|
|
52
|
+
|
|
53
|
+
// Assert
|
|
49
54
|
expect(result.success).toBe(true);
|
|
50
55
|
expect(result.path).toBe(join(vault, "cueloop", "2026-08-07 - Migration Plan.md"));
|
|
51
56
|
const written = readFileSync(result.path!, "utf8");
|
|
@@ -57,40 +62,63 @@ describe("exportSession", () => {
|
|
|
57
62
|
});
|
|
58
63
|
|
|
59
64
|
test("the working copy wins over the submitted content", () => {
|
|
65
|
+
// Arrange
|
|
60
66
|
const session = resolvedSession({ workingCopy: "# Migration Plan\n\nMove the store carefully.\n" });
|
|
67
|
+
|
|
68
|
+
// Act
|
|
61
69
|
const result = exportSession(session, config(), NOW);
|
|
70
|
+
|
|
71
|
+
// Assert
|
|
62
72
|
expect(readFileSync(result.path!, "utf8")).toContain("Move the store carefully.");
|
|
63
73
|
});
|
|
64
74
|
|
|
65
75
|
test("never overwrites: collisions get counting suffixes", () => {
|
|
76
|
+
// Arrange
|
|
66
77
|
const session = resolvedSession();
|
|
78
|
+
|
|
79
|
+
// Act
|
|
67
80
|
const first = exportSession(session, config(), NOW);
|
|
68
81
|
const second = exportSession(session, config(), NOW);
|
|
69
82
|
const third = exportSession(session, config(), NOW);
|
|
83
|
+
|
|
84
|
+
// Assert
|
|
70
85
|
expect(second.path).toBe(join(vault, "cueloop", "2026-08-07 - Migration Plan 2.md"));
|
|
71
86
|
expect(third.path).toBe(join(vault, "cueloop", "2026-08-07 - Migration Plan 3.md"));
|
|
72
87
|
expect(existsSync(first.path!)).toBe(true);
|
|
73
88
|
});
|
|
74
89
|
|
|
75
90
|
test("no vault configured and none detected fails without writing", () => {
|
|
91
|
+
// Arrange
|
|
76
92
|
const emptyConfigPath = join(vault, "obsidian.json");
|
|
93
|
+
|
|
94
|
+
// Act
|
|
77
95
|
const result = exportSession(resolvedSession(), config({ vault: undefined, obsidianConfigPath: emptyConfigPath }), NOW);
|
|
96
|
+
|
|
97
|
+
// Assert
|
|
78
98
|
expect(result.success).toBe(false);
|
|
79
99
|
expect(result.error).toContain("no Obsidian vault");
|
|
80
100
|
});
|
|
81
101
|
|
|
82
102
|
test("a configured vault path that does not exist fails", () => {
|
|
103
|
+
// Act
|
|
83
104
|
const result = exportSession(resolvedSession(), config({ vault: join(vault, "missing") }), NOW);
|
|
105
|
+
|
|
106
|
+
// Assert
|
|
84
107
|
expect(result.success).toBe(false);
|
|
85
108
|
expect(result.error).toContain("vault not found");
|
|
86
109
|
});
|
|
87
110
|
|
|
88
111
|
test("falls back to the first auto-detected vault", () => {
|
|
112
|
+
// Arrange
|
|
89
113
|
const detected = join(vault, "detected-vault");
|
|
90
114
|
mkdirSync(detected);
|
|
91
115
|
const obsidianJson = join(vault, "obsidian.json");
|
|
92
116
|
writeFileSync(obsidianJson, JSON.stringify({ vaults: { v1: { path: detected } } }));
|
|
117
|
+
|
|
118
|
+
// Act
|
|
93
119
|
const result = exportSession(resolvedSession(), config({ vault: undefined, obsidianConfigPath: obsidianJson }), NOW);
|
|
120
|
+
|
|
121
|
+
// Assert
|
|
94
122
|
expect(result.success).toBe(true);
|
|
95
123
|
expect(result.path).toBe(join(detected, "cueloop", "2026-08-07 - Migration Plan.md"));
|
|
96
124
|
});
|
|
@@ -98,12 +126,21 @@ describe("exportSession", () => {
|
|
|
98
126
|
|
|
99
127
|
describe("obsidian extension", () => {
|
|
100
128
|
test("registers the exporter through the extension API and exports a resolved session", async () => {
|
|
129
|
+
// Arrange
|
|
101
130
|
const registry = new Registry();
|
|
131
|
+
|
|
132
|
+
// Act
|
|
102
133
|
const record = await registry.load("obsidian", createObsidianExtension(config()));
|
|
134
|
+
|
|
135
|
+
// Assert
|
|
103
136
|
expect(record.errors).toEqual([]);
|
|
104
137
|
const exporter = record.exporters.get("obsidian");
|
|
105
138
|
expect(exporter).toBeDefined();
|
|
139
|
+
|
|
140
|
+
// Act
|
|
106
141
|
const result = await exporter!(resolvedSession());
|
|
142
|
+
|
|
143
|
+
// Assert
|
|
107
144
|
expect(result.success).toBe(true);
|
|
108
145
|
expect(existsSync(result.path!)).toBe(true);
|
|
109
146
|
});
|
package/src/filename.test.ts
CHANGED
|
@@ -23,7 +23,10 @@ describe("titleFrom", () => {
|
|
|
23
23
|
});
|
|
24
24
|
|
|
25
25
|
test("caps the title at 50 characters", () => {
|
|
26
|
+
// Arrange
|
|
26
27
|
const long = "# " + "word ".repeat(20);
|
|
28
|
+
|
|
29
|
+
// Assert
|
|
27
30
|
expect(titleFrom(long).length).toBeLessThanOrEqual(50);
|
|
28
31
|
expect(titleFrom(long).endsWith(" ")).toBe(false);
|
|
29
32
|
});
|
|
@@ -54,10 +57,19 @@ describe("uniquePath", () => {
|
|
|
54
57
|
});
|
|
55
58
|
|
|
56
59
|
test("appends counting suffixes instead of overwriting", () => {
|
|
60
|
+
// Assert
|
|
57
61
|
expect(uniquePath(dir, "plan")).toBe(join(dir, "plan.md"));
|
|
62
|
+
|
|
63
|
+
// Act
|
|
58
64
|
writeFileSync(join(dir, "plan.md"), "");
|
|
65
|
+
|
|
66
|
+
// Assert
|
|
59
67
|
expect(uniquePath(dir, "plan")).toBe(join(dir, "plan 2.md"));
|
|
68
|
+
|
|
69
|
+
// Act
|
|
60
70
|
writeFileSync(join(dir, "plan 2.md"), "");
|
|
71
|
+
|
|
72
|
+
// Assert
|
|
61
73
|
expect(uniquePath(dir, "plan")).toBe(join(dir, "plan 3.md"));
|
|
62
74
|
});
|
|
63
75
|
});
|