paper-manager 0.3.1 → 0.4.1

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.
Files changed (53) hide show
  1. package/README.md +2 -2
  2. package/dist/ai/embed.test.d.ts +1 -0
  3. package/dist/ai/embed.test.js +93 -0
  4. package/dist/ai/embed.test.js.map +1 -0
  5. package/dist/commands/knowledge-base.js +10 -7
  6. package/dist/commands/knowledge-base.js.map +1 -1
  7. package/dist/commands/literature.js +25 -20
  8. package/dist/commands/literature.js.map +1 -1
  9. package/dist/config/index.d.ts +1 -1
  10. package/dist/config/index.js +2 -2
  11. package/dist/config/index.js.map +1 -1
  12. package/dist/config/index.test.d.ts +1 -0
  13. package/dist/config/index.test.js +143 -0
  14. package/dist/config/index.test.js.map +1 -0
  15. package/dist/config/init.d.ts +1 -1
  16. package/dist/config/init.js +7 -7
  17. package/dist/config/init.js.map +1 -1
  18. package/dist/config/init.test.d.ts +1 -0
  19. package/dist/config/init.test.js +61 -0
  20. package/dist/config/init.test.js.map +1 -0
  21. package/dist/db/index.test.d.ts +1 -0
  22. package/dist/db/index.test.js +79 -0
  23. package/dist/db/index.test.js.map +1 -0
  24. package/dist/db/operations/knowledge-bases.test.d.ts +1 -0
  25. package/dist/db/operations/knowledge-bases.test.js +73 -0
  26. package/dist/db/operations/knowledge-bases.test.js.map +1 -0
  27. package/dist/db/operations/literatures.test.d.ts +1 -0
  28. package/dist/db/operations/literatures.test.js +159 -0
  29. package/dist/db/operations/literatures.test.js.map +1 -0
  30. package/dist/db/test-utils.d.ts +6 -0
  31. package/dist/db/test-utils.js +14 -0
  32. package/dist/db/test-utils.js.map +1 -0
  33. package/dist/extractor/index.d.ts +5 -0
  34. package/dist/extractor/index.js +23 -0
  35. package/dist/extractor/index.js.map +1 -0
  36. package/dist/extractor/pdf.d.ts +2 -0
  37. package/dist/extractor/pdf.js +18 -0
  38. package/dist/extractor/pdf.js.map +1 -0
  39. package/dist/extractor/text.d.ts +2 -0
  40. package/dist/extractor/text.js +17 -0
  41. package/dist/extractor/text.js.map +1 -0
  42. package/dist/index.js +4 -0
  43. package/dist/index.js.map +1 -1
  44. package/dist/lifecycle.d.ts +1 -0
  45. package/dist/lifecycle.js +7 -0
  46. package/dist/lifecycle.js.map +1 -0
  47. package/dist/migrations.d.ts +5 -0
  48. package/dist/migrations.js +28 -0
  49. package/dist/migrations.js.map +1 -0
  50. package/dist/types/index.test.d.ts +1 -0
  51. package/dist/types/index.test.js +157 -0
  52. package/dist/types/index.test.js.map +1 -0
  53. package/package.json +7 -3
@@ -0,0 +1,157 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { ConfigSchema, CreateLiteratureSchema, EmbeddingModelConfigSchema, KnowledgeBaseMetadataSchema, LiteratureMetadataSchema, UpdateLiteratureSchema, } from "./index.js";
3
+ // ─── Helpers ─────────────────────────────────────────────────
4
+ const validUuid = "550e8400-e29b-41d4-a716-446655440000";
5
+ const now = new Date();
6
+ // ─── EmbeddingModelConfigSchema ──────────────────────────────
7
+ describe("EmbeddingModelConfigSchema", () => {
8
+ const minimal = { provider: "openai", model: "text-embedding-3-small", apiKey: "sk-test" };
9
+ it("accepts a minimal valid config", () => {
10
+ expect(EmbeddingModelConfigSchema.parse(minimal)).toMatchObject(minimal);
11
+ });
12
+ it("accepts optional fields", () => {
13
+ const full = {
14
+ ...minimal,
15
+ baseUrl: "https://api.example.com",
16
+ dimensions: 1536,
17
+ batchSize: 100,
18
+ };
19
+ expect(EmbeddingModelConfigSchema.parse(full)).toMatchObject(full);
20
+ });
21
+ it("rejects invalid provider", () => {
22
+ expect(() => EmbeddingModelConfigSchema.parse({ ...minimal, provider: "anthropic" })).toThrow();
23
+ });
24
+ it("rejects non-positive dimensions", () => {
25
+ expect(() => EmbeddingModelConfigSchema.parse({ ...minimal, dimensions: 0 })).toThrow();
26
+ expect(() => EmbeddingModelConfigSchema.parse({ ...minimal, dimensions: -1 })).toThrow();
27
+ });
28
+ it("rejects non-integer dimensions", () => {
29
+ expect(() => EmbeddingModelConfigSchema.parse({ ...minimal, dimensions: 1.5 })).toThrow();
30
+ });
31
+ it("rejects invalid baseUrl", () => {
32
+ expect(() => EmbeddingModelConfigSchema.parse({ ...minimal, baseUrl: "not-a-url" })).toThrow();
33
+ });
34
+ });
35
+ // ─── KnowledgeBaseMetadataSchema ─────────────────────────────
36
+ describe("KnowledgeBaseMetadataSchema", () => {
37
+ const valid = {
38
+ id: validUuid,
39
+ name: "My KB",
40
+ description: "A test knowledge base",
41
+ embeddingModelId: "model-1",
42
+ createdAt: now,
43
+ updatedAt: now,
44
+ };
45
+ it("accepts a valid knowledge base", () => {
46
+ expect(KnowledgeBaseMetadataSchema.parse(valid)).toMatchObject(valid);
47
+ });
48
+ it("rejects non-uuid id", () => {
49
+ expect(() => KnowledgeBaseMetadataSchema.parse({ ...valid, id: "not-a-uuid" })).toThrow();
50
+ });
51
+ it("rejects empty name", () => {
52
+ expect(() => KnowledgeBaseMetadataSchema.parse({ ...valid, name: "" })).toThrow();
53
+ });
54
+ it("rejects empty embeddingModelId", () => {
55
+ expect(() => KnowledgeBaseMetadataSchema.parse({ ...valid, embeddingModelId: "" })).toThrow();
56
+ });
57
+ });
58
+ // ─── LiteratureMetadataSchema ────────────────────────────────
59
+ describe("LiteratureMetadataSchema", () => {
60
+ const valid = {
61
+ id: validUuid,
62
+ title: "A Paper",
63
+ titleTranslation: null,
64
+ author: null,
65
+ abstract: null,
66
+ summary: null,
67
+ keywords: [],
68
+ url: null,
69
+ notes: {},
70
+ knowledgeBaseId: validUuid,
71
+ createdAt: now,
72
+ updatedAt: now,
73
+ };
74
+ it("accepts a minimal valid literature", () => {
75
+ expect(LiteratureMetadataSchema.parse(valid)).toMatchObject(valid);
76
+ });
77
+ it("fills defaults for keywords and notes", () => {
78
+ const { keywords: _, notes: __, ...without } = valid;
79
+ const result = LiteratureMetadataSchema.parse(without);
80
+ expect(result.keywords).toEqual([]);
81
+ expect(result.notes).toEqual({});
82
+ });
83
+ it("accepts populated optional fields", () => {
84
+ const full = {
85
+ ...valid,
86
+ titleTranslation: "一篇论文",
87
+ author: "Alice",
88
+ abstract: "This paper...",
89
+ summary: "Summary here",
90
+ keywords: ["ai", "ml"],
91
+ url: "https://arxiv.org/abs/1234.5678",
92
+ notes: { key: "value" },
93
+ };
94
+ expect(LiteratureMetadataSchema.parse(full)).toMatchObject(full);
95
+ });
96
+ it("rejects empty title", () => {
97
+ expect(() => LiteratureMetadataSchema.parse({ ...valid, title: "" })).toThrow();
98
+ });
99
+ it("rejects invalid url", () => {
100
+ expect(() => LiteratureMetadataSchema.parse({ ...valid, url: "not-a-url" })).toThrow();
101
+ });
102
+ });
103
+ // ─── CreateLiteratureSchema ──────────────────────────────────
104
+ describe("CreateLiteratureSchema", () => {
105
+ it("does not require id, createdAt, updatedAt", () => {
106
+ const input = {
107
+ title: "New Paper",
108
+ titleTranslation: null,
109
+ author: null,
110
+ abstract: null,
111
+ summary: null,
112
+ knowledgeBaseId: validUuid,
113
+ url: null,
114
+ };
115
+ expect(() => CreateLiteratureSchema.parse(input)).not.toThrow();
116
+ });
117
+ });
118
+ // ─── UpdateLiteratureSchema ──────────────────────────────────
119
+ describe("UpdateLiteratureSchema", () => {
120
+ it("accepts a partial update with only title", () => {
121
+ expect(UpdateLiteratureSchema.parse({ title: "Updated" })).toMatchObject({
122
+ title: "Updated",
123
+ });
124
+ });
125
+ it("accepts an empty object", () => {
126
+ expect(() => UpdateLiteratureSchema.parse({})).not.toThrow();
127
+ });
128
+ });
129
+ // ─── ConfigSchema ────────────────────────────────────────────
130
+ describe("ConfigSchema", () => {
131
+ it("accepts an empty object with defaults", () => {
132
+ const result = ConfigSchema.parse({});
133
+ expect(result.embeddingModels).toEqual({});
134
+ expect(result.defaultEmbeddingModelId).toBeUndefined();
135
+ });
136
+ it("accepts a full config", () => {
137
+ const config = {
138
+ embeddingModels: {
139
+ "model-1": {
140
+ provider: "openai",
141
+ model: "text-embedding-3-small",
142
+ apiKey: "sk-test",
143
+ },
144
+ },
145
+ defaultEmbeddingModelId: "model-1",
146
+ };
147
+ expect(ConfigSchema.parse(config)).toMatchObject(config);
148
+ });
149
+ it("rejects empty string as model key", () => {
150
+ expect(() => ConfigSchema.parse({
151
+ embeddingModels: {
152
+ "": { provider: "openai", model: "m", apiKey: "k" },
153
+ },
154
+ })).toThrow();
155
+ });
156
+ });
157
+ //# sourceMappingURL=index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../src/types/index.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "paper-manager",
3
- "version": "0.3.1",
3
+ "version": "0.4.1",
4
4
  "description": "A paper management system.",
5
5
  "keywords": [],
6
6
  "homepage": "https://github.com/EurFelux/paper-manager",
@@ -31,6 +31,7 @@
31
31
  "commander": "^14.0.3",
32
32
  "faiss-node": "^0.5.1",
33
33
  "langchain": "^1.2.28",
34
+ "mime-types": "^3.0.2",
34
35
  "pdf-parse": "^2.4.5",
35
36
  "zod": "^4.3.6"
36
37
  },
@@ -38,12 +39,14 @@
38
39
  "@j178/prek": "^0.3.4",
39
40
  "@types/better-sqlite3": "^7.6.13",
40
41
  "@types/cli-progress": "^3.11.6",
42
+ "@types/mime-types": "^3.0.1",
41
43
  "eslint-plugin-simple-import-sort": "^12.1.1",
42
44
  "oxfmt": "^0.35.0",
43
45
  "oxlint": "^1.50.0",
44
46
  "oxlint-tsgolint": "^0.15.0",
45
47
  "tsx": "^4.21.0",
46
- "typescript": "^5.9.3"
48
+ "typescript": "^5.9.3",
49
+ "vitest": "^4.0.18"
47
50
  },
48
51
  "engines": {
49
52
  "node": ">=24"
@@ -52,7 +55,8 @@
52
55
  "build": "tsc",
53
56
  "generate:schema": "tsx scripts/generate-schema.ts && oxfmt config.schema.json",
54
57
  "release": "tsx scripts/release.ts",
55
- "test": "echo \"Error: no test specified\" && exit 1",
58
+ "test": "vitest run",
59
+ "test:watch": "vitest",
56
60
  "typecheck": "tsc --noEmit",
57
61
  "lint": "oxlint --type-aware",
58
62
  "lint:fix": "oxlint --type-aware --fix",