paper-manager 0.3.0 → 0.4.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/ai/embed.test.d.ts +1 -0
- package/dist/ai/embed.test.js +93 -0
- package/dist/ai/embed.test.js.map +1 -0
- package/dist/commands/knowledge-base.js +10 -7
- package/dist/commands/knowledge-base.js.map +1 -1
- package/dist/commands/literature.js +29 -22
- package/dist/commands/literature.js.map +1 -1
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.js +2 -2
- package/dist/config/index.js.map +1 -1
- package/dist/config/index.test.d.ts +1 -0
- package/dist/config/index.test.js +143 -0
- package/dist/config/index.test.js.map +1 -0
- package/dist/config/init.d.ts +1 -1
- package/dist/config/init.js +24 -7
- package/dist/config/init.js.map +1 -1
- package/dist/config/init.test.d.ts +1 -0
- package/dist/config/init.test.js +61 -0
- package/dist/config/init.test.js.map +1 -0
- package/dist/db/index.test.d.ts +1 -0
- package/dist/db/index.test.js +79 -0
- package/dist/db/index.test.js.map +1 -0
- package/dist/db/operations/knowledge-bases.test.d.ts +1 -0
- package/dist/db/operations/knowledge-bases.test.js +73 -0
- package/dist/db/operations/knowledge-bases.test.js.map +1 -0
- package/dist/db/operations/literatures.test.d.ts +1 -0
- package/dist/db/operations/literatures.test.js +159 -0
- package/dist/db/operations/literatures.test.js.map +1 -0
- package/dist/db/test-utils.d.ts +6 -0
- package/dist/db/test-utils.js +14 -0
- package/dist/db/test-utils.js.map +1 -0
- package/dist/extractor/index.d.ts +5 -0
- package/dist/extractor/index.js +23 -0
- package/dist/extractor/index.js.map +1 -0
- package/dist/extractor/pdf.d.ts +2 -0
- package/dist/extractor/pdf.js +18 -0
- package/dist/extractor/pdf.js.map +1 -0
- package/dist/extractor/text.d.ts +2 -0
- package/dist/extractor/text.js +17 -0
- package/dist/extractor/text.js.map +1 -0
- package/dist/types/index.test.d.ts +1 -0
- package/dist/types/index.test.js +157 -0
- package/dist/types/index.test.js.map +1 -0
- package/package.json +8 -3
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
4
|
+
import { getFilesDir, getProjectDataDir, getVectorStoreDir } from "./index.js";
|
|
5
|
+
import { initScope } from "./init.js";
|
|
6
|
+
// initScope() uses getProjectDataDir() which is a module-level constant resolved at import time.
|
|
7
|
+
// This means process.chdir() cannot redirect it. We must clean up the actual project data dir
|
|
8
|
+
// between tests to ensure isolation.
|
|
9
|
+
let origCwd;
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
origCwd = process.cwd();
|
|
12
|
+
const projectDir = getProjectDataDir();
|
|
13
|
+
if (fs.existsSync(projectDir)) {
|
|
14
|
+
fs.rmSync(projectDir, { recursive: true, force: true });
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
afterEach(() => {
|
|
18
|
+
process.chdir(origCwd);
|
|
19
|
+
const projectDir = getProjectDataDir();
|
|
20
|
+
if (fs.existsSync(projectDir)) {
|
|
21
|
+
fs.rmSync(projectDir, { recursive: true, force: true });
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
describe("initScope (project scope)", () => {
|
|
25
|
+
it("creates all expected files and directories on first run", () => {
|
|
26
|
+
const result = initScope();
|
|
27
|
+
const baseDir = result.baseDir;
|
|
28
|
+
// All items should be "created"
|
|
29
|
+
expect(result.items.every((item) => item.status === "created")).toBe(true);
|
|
30
|
+
expect(result.items).toHaveLength(5);
|
|
31
|
+
// Verify filesystem
|
|
32
|
+
expect(fs.existsSync(baseDir)).toBe(true);
|
|
33
|
+
expect(fs.existsSync(path.join(baseDir, "config.json"))).toBe(true);
|
|
34
|
+
expect(fs.existsSync(path.join(baseDir, "papers.db"))).toBe(true);
|
|
35
|
+
expect(fs.existsSync(getFilesDir(baseDir))).toBe(true);
|
|
36
|
+
expect(fs.existsSync(getVectorStoreDir(baseDir))).toBe(true);
|
|
37
|
+
});
|
|
38
|
+
it("config.json contains $schema field", () => {
|
|
39
|
+
const result = initScope();
|
|
40
|
+
const configContent = fs.readFileSync(path.join(result.baseDir, "config.json"), "utf-8");
|
|
41
|
+
const config = JSON.parse(configContent);
|
|
42
|
+
expect(config["$schema"]).toContain("config.schema.json");
|
|
43
|
+
});
|
|
44
|
+
it("is idempotent — second run reports all items as exists", () => {
|
|
45
|
+
initScope();
|
|
46
|
+
const result = initScope();
|
|
47
|
+
expect(result.items.every((item) => item.status === "exists")).toBe(true);
|
|
48
|
+
expect(result.items).toHaveLength(5);
|
|
49
|
+
});
|
|
50
|
+
it("preserves existing config.json content on second run", () => {
|
|
51
|
+
const result = initScope();
|
|
52
|
+
const configPath = path.join(result.baseDir, "config.json");
|
|
53
|
+
// Write custom content
|
|
54
|
+
fs.writeFileSync(configPath, JSON.stringify({ custom: "data" }));
|
|
55
|
+
// Second init should not overwrite
|
|
56
|
+
initScope();
|
|
57
|
+
const content = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
58
|
+
expect(content["custom"]).toBe("data");
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
//# sourceMappingURL=init.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.test.js","sourceRoot":"","sources":["../../src/config/init.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { dbRowToKnowledgeBase, dbRowToLiterature, isRecord } from "./index.js";
|
|
3
|
+
// ─── isRecord ────────────────────────────────────────────────
|
|
4
|
+
describe("isRecord", () => {
|
|
5
|
+
it("returns true for plain objects", () => {
|
|
6
|
+
expect(isRecord({})).toBe(true);
|
|
7
|
+
expect(isRecord({ a: 1 })).toBe(true);
|
|
8
|
+
});
|
|
9
|
+
it("returns false for arrays", () => {
|
|
10
|
+
expect(isRecord([])).toBe(false);
|
|
11
|
+
expect(isRecord([1, 2])).toBe(false);
|
|
12
|
+
});
|
|
13
|
+
it("returns false for primitives and null", () => {
|
|
14
|
+
expect(isRecord(null)).toBe(false);
|
|
15
|
+
expect(isRecord(undefined)).toBe(false);
|
|
16
|
+
expect(isRecord(42)).toBe(false);
|
|
17
|
+
expect(isRecord("string")).toBe(false);
|
|
18
|
+
expect(isRecord(true)).toBe(false);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
// ─── dbRowToKnowledgeBase ────────────────────────────────────
|
|
22
|
+
describe("dbRowToKnowledgeBase", () => {
|
|
23
|
+
const validRow = {
|
|
24
|
+
id: "550e8400-e29b-41d4-a716-446655440000",
|
|
25
|
+
name: "Test KB",
|
|
26
|
+
description: "A description",
|
|
27
|
+
embedding_model_id: "model-1",
|
|
28
|
+
created_at: 1700000000000,
|
|
29
|
+
updated_at: 1700000000000,
|
|
30
|
+
};
|
|
31
|
+
it("converts a valid DB row to KnowledgeBaseMetadata", () => {
|
|
32
|
+
const result = dbRowToKnowledgeBase(validRow);
|
|
33
|
+
expect(result.id).toBe(validRow.id);
|
|
34
|
+
expect(result.name).toBe("Test KB");
|
|
35
|
+
expect(result.embeddingModelId).toBe("model-1");
|
|
36
|
+
expect(result.createdAt).toBeInstanceOf(Date);
|
|
37
|
+
expect(result.createdAt.getTime()).toBe(1700000000000);
|
|
38
|
+
});
|
|
39
|
+
it("throws on non-object input", () => {
|
|
40
|
+
expect(() => dbRowToKnowledgeBase(null)).toThrow("Invalid database row");
|
|
41
|
+
expect(() => dbRowToKnowledgeBase("string")).toThrow("Invalid database row");
|
|
42
|
+
expect(() => dbRowToKnowledgeBase([])).toThrow("Invalid database row");
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
// ─── dbRowToLiterature ───────────────────────────────────────
|
|
46
|
+
describe("dbRowToLiterature", () => {
|
|
47
|
+
const validRow = {
|
|
48
|
+
id: "550e8400-e29b-41d4-a716-446655440000",
|
|
49
|
+
title: "A Paper",
|
|
50
|
+
title_translation: null,
|
|
51
|
+
author: "Alice",
|
|
52
|
+
abstract: "This paper...",
|
|
53
|
+
summary: null,
|
|
54
|
+
keywords: '["ai","ml"]',
|
|
55
|
+
url: null,
|
|
56
|
+
notes: '{"read":"yes"}',
|
|
57
|
+
knowledge_base_id: "550e8400-e29b-41d4-a716-446655440000",
|
|
58
|
+
created_at: 1700000000000,
|
|
59
|
+
updated_at: 1700000000000,
|
|
60
|
+
};
|
|
61
|
+
it("converts a valid DB row with JSON fields", () => {
|
|
62
|
+
const result = dbRowToLiterature(validRow);
|
|
63
|
+
expect(result.title).toBe("A Paper");
|
|
64
|
+
expect(result.author).toBe("Alice");
|
|
65
|
+
expect(result.keywords).toEqual(["ai", "ml"]);
|
|
66
|
+
expect(result.notes).toEqual({ read: "yes" });
|
|
67
|
+
expect(result.knowledgeBaseId).toBe(validRow.knowledge_base_id);
|
|
68
|
+
});
|
|
69
|
+
it("handles missing keywords/notes with defaults", () => {
|
|
70
|
+
const row = { ...validRow, keywords: undefined, notes: undefined };
|
|
71
|
+
const result = dbRowToLiterature(row);
|
|
72
|
+
expect(result.keywords).toEqual([]);
|
|
73
|
+
expect(result.notes).toEqual({});
|
|
74
|
+
});
|
|
75
|
+
it("throws on non-object input", () => {
|
|
76
|
+
expect(() => dbRowToLiterature(42)).toThrow("Invalid database row");
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
//# sourceMappingURL=index.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../src/db/index.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
2
|
+
import { createTestDb } from "../test-utils.js";
|
|
3
|
+
import { createKnowledgeBase, deleteKnowledgeBase, getKnowledgeBase, listKnowledgeBases, } from "./knowledge-bases.js";
|
|
4
|
+
let db;
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
db = createTestDb();
|
|
7
|
+
});
|
|
8
|
+
afterEach(() => {
|
|
9
|
+
db.close();
|
|
10
|
+
});
|
|
11
|
+
const input = {
|
|
12
|
+
name: "Test KB",
|
|
13
|
+
description: "A test knowledge base",
|
|
14
|
+
embeddingModelId: "model-1",
|
|
15
|
+
};
|
|
16
|
+
// ─── createKnowledgeBase ─────────────────────────────────────
|
|
17
|
+
describe("createKnowledgeBase", () => {
|
|
18
|
+
it("creates and returns a knowledge base with generated id and timestamps", () => {
|
|
19
|
+
const kb = createKnowledgeBase(db, input);
|
|
20
|
+
expect(kb.id).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/);
|
|
21
|
+
expect(kb.name).toBe("Test KB");
|
|
22
|
+
expect(kb.description).toBe("A test knowledge base");
|
|
23
|
+
expect(kb.embeddingModelId).toBe("model-1");
|
|
24
|
+
expect(kb.createdAt).toBeInstanceOf(Date);
|
|
25
|
+
expect(kb.updatedAt).toBeInstanceOf(Date);
|
|
26
|
+
});
|
|
27
|
+
it("rejects duplicate names due to UNIQUE constraint", () => {
|
|
28
|
+
createKnowledgeBase(db, input);
|
|
29
|
+
expect(() => createKnowledgeBase(db, input)).toThrow();
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
// ─── getKnowledgeBase ────────────────────────────────────────
|
|
33
|
+
describe("getKnowledgeBase", () => {
|
|
34
|
+
it("returns the knowledge base by id", () => {
|
|
35
|
+
const created = createKnowledgeBase(db, input);
|
|
36
|
+
const found = getKnowledgeBase(db, created.id);
|
|
37
|
+
expect(found).not.toBeNull();
|
|
38
|
+
expect(found.id).toBe(created.id);
|
|
39
|
+
expect(found.name).toBe("Test KB");
|
|
40
|
+
});
|
|
41
|
+
it("returns null for non-existent id", () => {
|
|
42
|
+
expect(getKnowledgeBase(db, "non-existent")).toBeNull();
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
// ─── listKnowledgeBases ──────────────────────────────────────
|
|
46
|
+
describe("listKnowledgeBases", () => {
|
|
47
|
+
it("returns an empty array when no knowledge bases exist", () => {
|
|
48
|
+
expect(listKnowledgeBases(db)).toEqual([]);
|
|
49
|
+
});
|
|
50
|
+
it("returns knowledge bases ordered by created_at DESC", () => {
|
|
51
|
+
const kb1 = createKnowledgeBase(db, { ...input, name: "First" });
|
|
52
|
+
// Manually backdate kb1 so ordering is deterministic
|
|
53
|
+
db.prepare("UPDATE knowledge_bases SET created_at = created_at - 1000 WHERE id = ?").run(kb1.id);
|
|
54
|
+
const kb2 = createKnowledgeBase(db, { ...input, name: "Second" });
|
|
55
|
+
const list = listKnowledgeBases(db);
|
|
56
|
+
expect(list).toHaveLength(2);
|
|
57
|
+
// Second was created after First, so it should come first in DESC order
|
|
58
|
+
expect(list[0].id).toBe(kb2.id);
|
|
59
|
+
expect(list[1].id).toBe(kb1.id);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
// ─── deleteKnowledgeBase ─────────────────────────────────────
|
|
63
|
+
describe("deleteKnowledgeBase", () => {
|
|
64
|
+
it("deletes an existing knowledge base and returns true", () => {
|
|
65
|
+
const kb = createKnowledgeBase(db, input);
|
|
66
|
+
expect(deleteKnowledgeBase(db, kb.id)).toBe(true);
|
|
67
|
+
expect(getKnowledgeBase(db, kb.id)).toBeNull();
|
|
68
|
+
});
|
|
69
|
+
it("returns false for non-existent id", () => {
|
|
70
|
+
expect(deleteKnowledgeBase(db, "non-existent")).toBe(false);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
//# sourceMappingURL=knowledge-bases.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knowledge-bases.test.js","sourceRoot":"","sources":["../../../src/db/operations/knowledge-bases.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
2
|
+
import { createTestDb } from "../test-utils.js";
|
|
3
|
+
import { createKnowledgeBase } from "./knowledge-bases.js";
|
|
4
|
+
import { createLiterature, deleteLiterature, deleteLiteraturesByKnowledgeBaseId, getLiterature, listLiteratures, updateLiterature, } from "./literatures.js";
|
|
5
|
+
let db;
|
|
6
|
+
let kbId;
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
db = createTestDb();
|
|
9
|
+
// Every literature needs a knowledge base
|
|
10
|
+
const kb = createKnowledgeBase(db, {
|
|
11
|
+
name: "Test KB",
|
|
12
|
+
description: "test",
|
|
13
|
+
embeddingModelId: "model-1",
|
|
14
|
+
});
|
|
15
|
+
kbId = kb.id;
|
|
16
|
+
});
|
|
17
|
+
afterEach(() => {
|
|
18
|
+
db.close();
|
|
19
|
+
});
|
|
20
|
+
function makeInput(overrides) {
|
|
21
|
+
return {
|
|
22
|
+
title: "A Paper",
|
|
23
|
+
titleTranslation: null,
|
|
24
|
+
author: "Alice",
|
|
25
|
+
abstract: "This paper explores...",
|
|
26
|
+
summary: null,
|
|
27
|
+
keywords: ["ai", "ml"],
|
|
28
|
+
url: null,
|
|
29
|
+
notes: { read: "yes" },
|
|
30
|
+
knowledgeBaseId: kbId,
|
|
31
|
+
...overrides,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
// ─── createLiterature ────────────────────────────────────────
|
|
35
|
+
describe("createLiterature", () => {
|
|
36
|
+
it("creates a literature with generated id and timestamps", () => {
|
|
37
|
+
const lit = createLiterature(db, makeInput());
|
|
38
|
+
expect(lit.id).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/);
|
|
39
|
+
expect(lit.title).toBe("A Paper");
|
|
40
|
+
expect(lit.author).toBe("Alice");
|
|
41
|
+
expect(lit.knowledgeBaseId).toBe(kbId);
|
|
42
|
+
});
|
|
43
|
+
it("round-trips JSON fields (keywords and notes)", () => {
|
|
44
|
+
const lit = createLiterature(db, makeInput({
|
|
45
|
+
keywords: ["deep learning", "transformer"],
|
|
46
|
+
notes: { chapter1: "interesting", chapter2: "review" },
|
|
47
|
+
}));
|
|
48
|
+
expect(lit.keywords).toEqual(["deep learning", "transformer"]);
|
|
49
|
+
expect(lit.notes).toEqual({ chapter1: "interesting", chapter2: "review" });
|
|
50
|
+
});
|
|
51
|
+
it("handles empty keywords and notes", () => {
|
|
52
|
+
const lit = createLiterature(db, makeInput({ keywords: [], notes: {} }));
|
|
53
|
+
expect(lit.keywords).toEqual([]);
|
|
54
|
+
expect(lit.notes).toEqual({});
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
// ─── getLiterature ───────────────────────────────────────────
|
|
58
|
+
describe("getLiterature", () => {
|
|
59
|
+
it("returns the literature by id", () => {
|
|
60
|
+
const created = createLiterature(db, makeInput());
|
|
61
|
+
const found = getLiterature(db, created.id);
|
|
62
|
+
expect(found).not.toBeNull();
|
|
63
|
+
expect(found.title).toBe("A Paper");
|
|
64
|
+
});
|
|
65
|
+
it("returns null for non-existent id", () => {
|
|
66
|
+
expect(getLiterature(db, "non-existent")).toBeNull();
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
// ─── listLiteratures ─────────────────────────────────────────
|
|
70
|
+
describe("listLiteratures", () => {
|
|
71
|
+
it("returns only literatures belonging to the given KB", () => {
|
|
72
|
+
const kb2 = createKnowledgeBase(db, {
|
|
73
|
+
name: "Other KB",
|
|
74
|
+
description: "other",
|
|
75
|
+
embeddingModelId: "model-1",
|
|
76
|
+
});
|
|
77
|
+
createLiterature(db, makeInput({ title: "Paper A" }));
|
|
78
|
+
createLiterature(db, makeInput({ title: "Paper B", knowledgeBaseId: kb2.id }));
|
|
79
|
+
const list = listLiteratures(db, kbId);
|
|
80
|
+
expect(list).toHaveLength(1);
|
|
81
|
+
expect(list[0].title).toBe("Paper A");
|
|
82
|
+
});
|
|
83
|
+
it("returns an empty array for a KB with no literatures", () => {
|
|
84
|
+
expect(listLiteratures(db, kbId)).toEqual([]);
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
// ─── updateLiterature ────────────────────────────────────────
|
|
88
|
+
describe("updateLiterature", () => {
|
|
89
|
+
it("updates only the specified fields", () => {
|
|
90
|
+
const lit = createLiterature(db, makeInput());
|
|
91
|
+
const updated = updateLiterature(db, lit.id, { title: "New Title" });
|
|
92
|
+
expect(updated).not.toBeNull();
|
|
93
|
+
expect(updated.title).toBe("New Title");
|
|
94
|
+
// Other fields stay unchanged
|
|
95
|
+
expect(updated.author).toBe("Alice");
|
|
96
|
+
expect(updated.keywords).toEqual(["ai", "ml"]);
|
|
97
|
+
});
|
|
98
|
+
it("updates JSON fields correctly", () => {
|
|
99
|
+
const lit = createLiterature(db, makeInput());
|
|
100
|
+
const updated = updateLiterature(db, lit.id, {
|
|
101
|
+
keywords: ["new-tag"],
|
|
102
|
+
notes: { updated: "true" },
|
|
103
|
+
});
|
|
104
|
+
expect(updated.keywords).toEqual(["new-tag"]);
|
|
105
|
+
expect(updated.notes).toEqual({ updated: "true" });
|
|
106
|
+
});
|
|
107
|
+
it("advances updatedAt on update", () => {
|
|
108
|
+
const lit = createLiterature(db, makeInput());
|
|
109
|
+
const updated = updateLiterature(db, lit.id, { title: "Changed" });
|
|
110
|
+
expect(updated.updatedAt.getTime()).toBeGreaterThanOrEqual(lit.updatedAt.getTime());
|
|
111
|
+
});
|
|
112
|
+
it("returns the original when input is empty (no fields to update)", () => {
|
|
113
|
+
const lit = createLiterature(db, makeInput());
|
|
114
|
+
const unchanged = updateLiterature(db, lit.id, {});
|
|
115
|
+
expect(unchanged).not.toBeNull();
|
|
116
|
+
expect(unchanged.title).toBe(lit.title);
|
|
117
|
+
expect(unchanged.updatedAt.getTime()).toBe(lit.updatedAt.getTime());
|
|
118
|
+
});
|
|
119
|
+
it("returns null for non-existent id", () => {
|
|
120
|
+
expect(updateLiterature(db, "non-existent", { title: "X" })).toBeNull();
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
// ─── deleteLiterature ────────────────────────────────────────
|
|
124
|
+
describe("deleteLiterature", () => {
|
|
125
|
+
it("deletes an existing literature and returns true", () => {
|
|
126
|
+
const lit = createLiterature(db, makeInput());
|
|
127
|
+
expect(deleteLiterature(db, lit.id)).toBe(true);
|
|
128
|
+
expect(getLiterature(db, lit.id)).toBeNull();
|
|
129
|
+
});
|
|
130
|
+
it("returns false for non-existent id", () => {
|
|
131
|
+
expect(deleteLiterature(db, "non-existent")).toBe(false);
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
// ─── deleteLiteraturesByKnowledgeBaseId ──────────────────────
|
|
135
|
+
describe("deleteLiteraturesByKnowledgeBaseId", () => {
|
|
136
|
+
it("deletes all literatures in a KB and returns the count", () => {
|
|
137
|
+
createLiterature(db, makeInput({ title: "Paper 1" }));
|
|
138
|
+
createLiterature(db, makeInput({ title: "Paper 2" }));
|
|
139
|
+
expect(deleteLiteraturesByKnowledgeBaseId(db, kbId)).toBe(2);
|
|
140
|
+
expect(listLiteratures(db, kbId)).toEqual([]);
|
|
141
|
+
});
|
|
142
|
+
it("returns 0 when the KB has no literatures", () => {
|
|
143
|
+
expect(deleteLiteraturesByKnowledgeBaseId(db, kbId)).toBe(0);
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
// ─── Foreign Key Behavior ────────────────────────────────────
|
|
147
|
+
describe("foreign key: ON DELETE SET NULL", () => {
|
|
148
|
+
it("sets knowledge_base_id to null when KB is deleted", () => {
|
|
149
|
+
const lit = createLiterature(db, makeInput());
|
|
150
|
+
// Delete the KB directly via SQL to trigger FK cascade
|
|
151
|
+
db.prepare("DELETE FROM knowledge_bases WHERE id = ?").run(kbId);
|
|
152
|
+
// getLiterature() will throw because Zod schema requires knowledgeBaseId to be a UUID,
|
|
153
|
+
// but FK cascade sets it to NULL. Check the raw row instead.
|
|
154
|
+
const raw = db.prepare("SELECT knowledge_base_id FROM literatures WHERE id = ?").get(lit.id);
|
|
155
|
+
expect(raw).toBeDefined();
|
|
156
|
+
expect(raw["knowledge_base_id"]).toBeNull();
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
//# sourceMappingURL=literatures.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"literatures.test.js","sourceRoot":"","sources":["../../../src/db/operations/literatures.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import Database from "better-sqlite3";
|
|
2
|
+
import { initializeDatabase } from "./index.js";
|
|
3
|
+
/**
|
|
4
|
+
* Creates an in-memory SQLite database with the schema initialized.
|
|
5
|
+
* Each call returns a fresh, isolated database instance.
|
|
6
|
+
*/
|
|
7
|
+
export function createTestDb() {
|
|
8
|
+
const db = new Database(":memory:");
|
|
9
|
+
db.pragma("journal_mode = WAL");
|
|
10
|
+
db.pragma("foreign_keys = ON");
|
|
11
|
+
initializeDatabase(db);
|
|
12
|
+
return db;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=test-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-utils.js","sourceRoot":"","sources":["../../src/db/test-utils.ts"],"names":[],"mappings":"AACA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAEtC,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEhD;;;GAGG;AACH,MAAM,UAAU,YAAY;IAC1B,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,UAAU,CAAC,CAAC;IACpC,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAChC,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAC/B,kBAAkB,CAAC,EAAE,CAAC,CAAC;IACvB,OAAO,EAAE,CAAC;AACZ,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Document } from "@langchain/core/documents";
|
|
2
|
+
import { extractPdfContent } from "./pdf.js";
|
|
3
|
+
import { extractTextContent } from "./text.js";
|
|
4
|
+
export { extractPdfContent, extractTextContent };
|
|
5
|
+
export declare function extractContent(filePath: string): Promise<Document[]>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import mime from "mime-types";
|
|
2
|
+
import { extractPdfContent } from "./pdf.js";
|
|
3
|
+
import { extractTextContent } from "./text.js";
|
|
4
|
+
export { extractPdfContent, extractTextContent };
|
|
5
|
+
const TEXT_LIKE_MIME_TYPES = new Set([
|
|
6
|
+
"application/x-tex",
|
|
7
|
+
"application/x-latex",
|
|
8
|
+
]);
|
|
9
|
+
function isTextLike(mimeType) {
|
|
10
|
+
return mimeType.startsWith("text/") || TEXT_LIKE_MIME_TYPES.has(mimeType);
|
|
11
|
+
}
|
|
12
|
+
export async function extractContent(filePath) {
|
|
13
|
+
const mimeType = mime.lookup(filePath);
|
|
14
|
+
if (mimeType === "application/pdf") {
|
|
15
|
+
return extractPdfContent(filePath);
|
|
16
|
+
}
|
|
17
|
+
if (typeof mimeType === "string" && isTextLike(mimeType)) {
|
|
18
|
+
return extractTextContent(filePath);
|
|
19
|
+
}
|
|
20
|
+
const ext = filePath.split(".").pop() ?? "unknown";
|
|
21
|
+
throw new Error(`Unsupported file type: .${ext} (${String(mimeType)})`);
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/extractor/index.ts"],"names":[],"mappings":"AACA,OAAO,IAAI,MAAM,YAAY,CAAC;AAE9B,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAE/C,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,CAAC;AAEjD,MAAM,oBAAoB,GAAwB,IAAI,GAAG,CAAC;IACxD,mBAAmB;IACnB,qBAAqB;CACtB,CAAC,CAAC;AAEH,SAAS,UAAU,CAAC,QAAgB;IAClC,OAAO,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,oBAAoB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AAC5E,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,QAAgB;IACnD,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAEvC,IAAI,QAAQ,KAAK,iBAAiB,EAAE,CAAC;QACnC,OAAO,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IACrC,CAAC;IAED,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzD,OAAO,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IACtC,CAAC;IAED,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,SAAS,CAAC;IACnD,MAAM,IAAI,KAAK,CAAC,2BAA2B,GAAG,KAAK,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AAC1E,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { Document } from "@langchain/core/documents";
|
|
3
|
+
import { PDFParse } from "pdf-parse";
|
|
4
|
+
export async function extractPdfContent(pdfPath) {
|
|
5
|
+
const data = await readFile(pdfPath);
|
|
6
|
+
const parser = new PDFParse({ data });
|
|
7
|
+
const result = await parser.getText();
|
|
8
|
+
await parser.destroy();
|
|
9
|
+
return result.pages.map((page) => new Document({
|
|
10
|
+
pageContent: page.text,
|
|
11
|
+
metadata: {
|
|
12
|
+
source: pdfPath,
|
|
13
|
+
pdf: { totalPages: result.total },
|
|
14
|
+
loc: { pageNumber: page.num },
|
|
15
|
+
},
|
|
16
|
+
}));
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=pdf.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pdf.js","sourceRoot":"","sources":["../../src/extractor/pdf.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,OAAe;IACrD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,IAAI,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;IACtC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;IACtC,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;IAEvB,OAAO,MAAM,CAAC,KAAK,CAAC,GAAG,CACrB,CAAC,IAAI,EAAE,EAAE,CACP,IAAI,QAAQ,CAAC;QACX,WAAW,EAAE,IAAI,CAAC,IAAI;QACtB,QAAQ,EAAE;YACR,MAAM,EAAE,OAAO;YACf,GAAG,EAAE,EAAE,UAAU,EAAE,MAAM,CAAC,KAAK,EAAE;YACjC,GAAG,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE;SAC9B;KACF,CAAC,CACL,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { readFile, stat } from "node:fs/promises";
|
|
2
|
+
import { Document } from "@langchain/core/documents";
|
|
3
|
+
const MAX_FILE_SIZE = 10 * 1024 * 1024; // 10 MB
|
|
4
|
+
export async function extractTextContent(filePath) {
|
|
5
|
+
const fileStats = await stat(filePath);
|
|
6
|
+
if (fileStats.size > MAX_FILE_SIZE) {
|
|
7
|
+
throw new Error(`File too large: ${String(Math.round(fileStats.size / 1024 / 1024))} MB exceeds the 10 MB limit`);
|
|
8
|
+
}
|
|
9
|
+
const content = await readFile(filePath, "utf-8");
|
|
10
|
+
return [
|
|
11
|
+
new Document({
|
|
12
|
+
pageContent: content,
|
|
13
|
+
metadata: { source: filePath },
|
|
14
|
+
}),
|
|
15
|
+
];
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=text.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.js","sourceRoot":"","sources":["../../src/extractor/text.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAErD,MAAM,aAAa,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,QAAQ;AAEhD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,QAAgB;IACvD,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,SAAS,CAAC,IAAI,GAAG,aAAa,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CACb,mBAAmB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,6BAA6B,CACjG,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAClD,OAAO;QACL,IAAI,QAAQ,CAAC;YACX,WAAW,EAAE,OAAO;YACpB,QAAQ,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE;SAC/B,CAAC;KACH,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|