@ncukondo/reference-manager 0.7.1 → 0.9.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/README.md +71 -4
- package/dist/chunks/{action-menu-CTtINmWd.js → action-menu-BN2HHFPR.js} +2 -2
- package/dist/chunks/{action-menu-CTtINmWd.js.map → action-menu-BN2HHFPR.js.map} +1 -1
- package/dist/chunks/{file-watcher-D7oyc-9z.js → file-watcher-DdhXSm1l.js} +3 -3
- package/dist/chunks/file-watcher-DdhXSm1l.js.map +1 -0
- package/dist/chunks/{index-_7NEUoS7.js → index-DmMZCOno.js} +316 -41
- package/dist/chunks/index-DmMZCOno.js.map +1 -0
- package/dist/chunks/{loader-BItrdVWG.js → loader-C-bdImuO.js} +44 -7
- package/dist/chunks/loader-C-bdImuO.js.map +1 -0
- package/dist/cli/commands/add.d.ts +4 -0
- package/dist/cli/commands/add.d.ts.map +1 -1
- package/dist/cli/commands/fulltext.d.ts +20 -3
- package/dist/cli/commands/fulltext.d.ts.map +1 -1
- package/dist/cli/commands/remove.d.ts +7 -16
- package/dist/cli/commands/remove.d.ts.map +1 -1
- package/dist/cli/commands/update.d.ts +40 -0
- package/dist/cli/commands/update.d.ts.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli.js +582 -152
- package/dist/cli.js.map +1 -1
- package/dist/core/library.d.ts.map +1 -1
- package/dist/features/duplicate/types.d.ts +1 -1
- package/dist/features/duplicate/types.d.ts.map +1 -1
- package/dist/features/import/detector.d.ts +1 -1
- package/dist/features/import/detector.d.ts.map +1 -1
- package/dist/features/import/fetcher.d.ts +6 -0
- package/dist/features/import/fetcher.d.ts.map +1 -1
- package/dist/features/import/importer.d.ts +3 -1
- package/dist/features/import/importer.d.ts.map +1 -1
- package/dist/features/import/parser.d.ts +16 -0
- package/dist/features/import/parser.d.ts.map +1 -1
- package/dist/features/operations/add.d.ts +4 -0
- package/dist/features/operations/add.d.ts.map +1 -1
- package/dist/features/operations/fulltext/index.d.ts +1 -0
- package/dist/features/operations/fulltext/index.d.ts.map +1 -1
- package/dist/features/operations/fulltext/open.d.ts +36 -0
- package/dist/features/operations/fulltext/open.d.ts.map +1 -0
- package/dist/features/operations/index.d.ts +2 -0
- package/dist/features/operations/index.d.ts.map +1 -1
- package/dist/features/operations/json-output.d.ts +93 -0
- package/dist/features/operations/json-output.d.ts.map +1 -0
- package/dist/features/operations/remove.d.ts +11 -0
- package/dist/features/operations/remove.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/server.js +2 -2
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/opener.d.ts +13 -0
- package/dist/utils/opener.d.ts.map +1 -0
- package/package.json +1 -1
- package/dist/chunks/file-watcher-D7oyc-9z.js.map +0 -1
- package/dist/chunks/index-_7NEUoS7.js.map +0 -1
- package/dist/chunks/loader-BItrdVWG.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"library.d.ts","sourceRoot":"","sources":["../../src/core/library.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,KAAK,EACV,WAAW,EACX,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,aAAa,EACb,YAAY,EACb,MAAM,wBAAwB,CAAC;AAIhC,YAAY,EACV,WAAW,EACX,cAAc,EACd,QAAQ,EACR,aAAa,EACb,YAAY,GACb,MAAM,wBAAwB,CAAC;AAEhC;;;GAGG;AACH,qBAAa,OAAQ,YAAW,QAAQ;IACtC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,UAAU,CAAmB;IACrC,OAAO,CAAC,WAAW,CAAuB;IAG1C,OAAO,CAAC,SAAS,CAAqC;IACtD,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,QAAQ,CAAqC;IACrD,OAAO,CAAC,SAAS,CAAqC;IACtD,OAAO,CAAC,SAAS,CAAqC;IAEtD,OAAO;IAWP;;;OAGG;WACU,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAiBrD;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAO3B;;;;OAIG;IACG,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC;IA8BhC;;;;OAIG;IACG,GAAG,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAe1C;;;;;OAKG;IACG,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,YAAY,CAAC;IA4BpF;;;;;;OAMG;IACG,MAAM,CACV,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,EACzB,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,YAAY,CAAC;IA4BxB;;;;;OAKG;IACG,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC;IAyBvF;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAIlC;;OAEG;IACH,WAAW,IAAI,MAAM;IAIrB;;;OAGG;IACH,cAAc,IAAI,MAAM,GAAG,IAAI;IAI/B;;OAEG;IACH,OAAO,CAAC,YAAY;IA0BpB;;OAEG;IACH,OAAO,CAAC,eAAe;IAUvB;;;OAGG;IACH,OAAO,CAAC,eAAe;IAwCvB;;OAEG;IACH,OAAO,CAAC,YAAY;
|
|
1
|
+
{"version":3,"file":"library.d.ts","sourceRoot":"","sources":["../../src/core/library.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,KAAK,EACV,WAAW,EACX,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,aAAa,EACb,YAAY,EACb,MAAM,wBAAwB,CAAC;AAIhC,YAAY,EACV,WAAW,EACX,cAAc,EACd,QAAQ,EACR,aAAa,EACb,YAAY,GACb,MAAM,wBAAwB,CAAC;AAEhC;;;GAGG;AACH,qBAAa,OAAQ,YAAW,QAAQ;IACtC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,UAAU,CAAmB;IACrC,OAAO,CAAC,WAAW,CAAuB;IAG1C,OAAO,CAAC,SAAS,CAAqC;IACtD,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,QAAQ,CAAqC;IACrD,OAAO,CAAC,SAAS,CAAqC;IACtD,OAAO,CAAC,SAAS,CAAqC;IAEtD,OAAO;IAWP;;;OAGG;WACU,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAiBrD;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAO3B;;;;OAIG;IACG,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC;IA8BhC;;;;OAIG;IACG,GAAG,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAe1C;;;;;OAKG;IACG,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,YAAY,CAAC;IA4BpF;;;;;;OAMG;IACG,MAAM,CACV,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,EACzB,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,YAAY,CAAC;IA4BxB;;;;;OAKG;IACG,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC;IAyBvF;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAIlC;;OAEG;IACH,WAAW,IAAI,MAAM;IAIrB;;;OAGG;IACH,cAAc,IAAI,MAAM,GAAG,IAAI;IAI/B;;OAEG;IACH,OAAO,CAAC,YAAY;IA0BpB;;OAEG;IACH,OAAO,CAAC,eAAe;IAUvB;;;OAGG;IACH,OAAO,CAAC,eAAe;IAwCvB;;OAEG;IACH,OAAO,CAAC,YAAY;IA2BpB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAoBxB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAoBzB;;;OAGG;IACH,OAAO,CAAC,cAAc;IAatB;;OAEG;IACH,OAAO,CAAC,kBAAkB;CAgB3B"}
|
|
@@ -5,7 +5,7 @@ import type { CslItem } from "../../core/csl-json/types.js";
|
|
|
5
5
|
/**
|
|
6
6
|
* Type of duplicate match
|
|
7
7
|
*/
|
|
8
|
-
export type DuplicateType = "doi" | "pmid" | "isbn" | "title-author-year";
|
|
8
|
+
export type DuplicateType = "doi" | "pmid" | "isbn" | "isbn-title" | "title-author-year";
|
|
9
9
|
/**
|
|
10
10
|
* A single duplicate match result
|
|
11
11
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/features/duplicate/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAC;AAE5D;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/features/duplicate/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAC;AAE5D;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,YAAY,GAAG,mBAAmB,CAAC;AAEzF;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,IAAI,EAAE,aAAa,CAAC;IAEpB;;OAEG;IACH,QAAQ,EAAE,OAAO,CAAC;IAElB;;OAEG;IACH,OAAO,CAAC,EAAE;QACR,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,WAAW,EAAE,OAAO,CAAC;IAErB;;OAEG;IACH,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B"}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
/**
|
|
11
11
|
* Supported input formats
|
|
12
12
|
*/
|
|
13
|
-
export type InputFormat = "json" | "bibtex" | "ris" | "pmid" | "doi" | "isbn" | "identifiers" | "unknown";
|
|
13
|
+
export type InputFormat = "json" | "bibtex" | "ris" | "nbib" | "pmid" | "doi" | "isbn" | "identifiers" | "unknown";
|
|
14
14
|
/**
|
|
15
15
|
* Detect the format of the given input
|
|
16
16
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detector.d.ts","sourceRoot":"","sources":["../../../src/features/import/detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH;;GAEG;AACH,MAAM,MAAM,WAAW,GACnB,MAAM,GACN,QAAQ,GACR,KAAK,GACL,MAAM,GACN,KAAK,GACL,MAAM,GACN,aAAa,GACb,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"detector.d.ts","sourceRoot":"","sources":["../../../src/features/import/detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH;;GAEG;AACH,MAAM,MAAM,WAAW,GACnB,MAAM,GACN,QAAQ,GACR,KAAK,GACL,MAAM,GACN,MAAM,GACN,KAAK,GACL,MAAM,GACN,aAAa,GACb,SAAS,CAAC;AAsBd;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,WAAW,CAwBzE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAW5D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CA0B5D;AAkCD;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,SAAS,CAiBzF;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAW5C;AA0BD;;GAEG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAc7C;AAED;;;;;;GAMG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAgC7C"}
|
|
@@ -14,6 +14,10 @@ export interface PubmedConfig {
|
|
|
14
14
|
email?: string;
|
|
15
15
|
apiKey?: string;
|
|
16
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Categorized failure reasons for JSON output
|
|
19
|
+
*/
|
|
20
|
+
export type FailureReason = "not_found" | "fetch_error" | "parse_error" | "validation_error" | "unknown";
|
|
17
21
|
/**
|
|
18
22
|
* Result of fetching a single identifier
|
|
19
23
|
*/
|
|
@@ -23,6 +27,7 @@ export type FetchResult = {
|
|
|
23
27
|
} | {
|
|
24
28
|
success: false;
|
|
25
29
|
error: string;
|
|
30
|
+
reason: FailureReason;
|
|
26
31
|
};
|
|
27
32
|
/**
|
|
28
33
|
* Result of fetching a PMID (includes pmid for tracking)
|
|
@@ -35,6 +40,7 @@ export type PmidFetchResult = {
|
|
|
35
40
|
pmid: string;
|
|
36
41
|
success: false;
|
|
37
42
|
error: string;
|
|
43
|
+
reason: FailureReason;
|
|
38
44
|
};
|
|
39
45
|
/**
|
|
40
46
|
* Results of fetching multiple PMIDs
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetcher.d.ts","sourceRoot":"","sources":["../../../src/features/import/fetcher.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,yBAAyB,CAAC;AACjC,OAAO,0BAA0B,CAAC;AAClC,OAAO,EAAE,KAAK,OAAO,EAAiB,MAAM,8BAA8B,CAAC;AAY3E;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"fetcher.d.ts","sourceRoot":"","sources":["../../../src/features/import/fetcher.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,yBAAyB,CAAC;AACjC,OAAO,0BAA0B,CAAC;AAClC,OAAO,EAAE,KAAK,OAAO,EAAiB,MAAM,8BAA8B,CAAC;AAY3E;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GACrB,WAAW,GACX,aAAa,GACb,aAAa,GACb,kBAAkB,GAClB,SAAS,CAAC;AAEd;;GAEG;AACH,MAAM,MAAM,WAAW,GACnB;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAChC;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,aAAa,CAAA;CAAE,CAAC;AAE7D;;GAEG;AACH,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,aAAa,CAAA;CAAE,CAAC;AAE3E;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;AAmG7C,wBAAsB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAiD7F;AAED;;;;GAIG;AACH,wBAAsB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CA8ChE;AAQD;;;;;GAKG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CA8ClE"}
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import type { CslItem } from "../../core/csl-json/types.js";
|
|
8
8
|
import type { InputFormat } from "./detector.js";
|
|
9
|
-
import type { PubmedConfig } from "./fetcher.js";
|
|
9
|
+
import type { FailureReason, PubmedConfig } from "./fetcher.js";
|
|
10
|
+
export type { FailureReason } from "./fetcher.js";
|
|
10
11
|
/**
|
|
11
12
|
* Result of importing a single item
|
|
12
13
|
*/
|
|
@@ -18,6 +19,7 @@ export type ImportItemResult = {
|
|
|
18
19
|
success: false;
|
|
19
20
|
error: string;
|
|
20
21
|
source: string;
|
|
22
|
+
reason: FailureReason;
|
|
21
23
|
};
|
|
22
24
|
/**
|
|
23
25
|
* Result of an import operation
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"importer.d.ts","sourceRoot":"","sources":["../../../src/features/import/importer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAC;AAW5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"importer.d.ts","sourceRoot":"","sources":["../../../src/features/import/importer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAC;AAW5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAKhE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD;;GAEG;AACH,MAAM,MAAM,gBAAgB,GACxB;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,aAAa,CAAA;CAAE,CAAC;AAE7E;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,gBAAgB,EAAE,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAmSD;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,WAAW,GAAG,MAAM,EAC5B,QAAQ,EAAE,aAAa,GACtB,OAAO,CAAC,YAAY,CAAC,CA2CvB;AAED;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,WAAW,EAAE,MAAM,EAAE,EACrB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,YAAY,CAAC,CA2BvB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACxD,oDAAoD;IACpD,MAAM,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;IAC9B,gFAAgF;IAChF,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAyGD,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EAAE,EAChB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,YAAY,CAAC,CAiCvB"}
|
|
@@ -30,4 +30,20 @@ export declare function parseBibtex(content: string): ParseResult;
|
|
|
30
30
|
* @returns Parse result with CSL-JSON items
|
|
31
31
|
*/
|
|
32
32
|
export declare function parseRis(content: string): ParseResult;
|
|
33
|
+
/**
|
|
34
|
+
* Convert NBIB (PubMed MEDLINE) format to RIS format
|
|
35
|
+
*
|
|
36
|
+
* @param content - NBIB content string
|
|
37
|
+
* @returns RIS format string
|
|
38
|
+
*/
|
|
39
|
+
export declare function convertNbibToRis(content: string): string;
|
|
40
|
+
/**
|
|
41
|
+
* Parse NBIB (PubMed MEDLINE) content to CSL-JSON
|
|
42
|
+
*
|
|
43
|
+
* Converts NBIB to RIS format first, then parses with citation-js
|
|
44
|
+
*
|
|
45
|
+
* @param content - NBIB content string
|
|
46
|
+
* @returns Parse result with CSL-JSON items
|
|
47
|
+
*/
|
|
48
|
+
export declare function parseNbib(content: string): ParseResult;
|
|
33
49
|
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../../src/features/import/parser.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,4BAA4B,CAAC;AACpC,OAAO,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAC;AAE5D;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAExD;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAErD"}
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../../src/features/import/parser.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,4BAA4B,CAAC;AACpC,OAAO,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAC;AAE5D;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAExD;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAErD;AA0JD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAaxD;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAqBtD"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ILibrary } from "../../core/library-interface.js";
|
|
2
2
|
import type { InputFormat } from "../import/detector.js";
|
|
3
3
|
import type { PubmedConfig } from "../import/fetcher.js";
|
|
4
|
+
export type { FailureReason } from "../import/importer.js";
|
|
4
5
|
/**
|
|
5
6
|
* Options for adding references
|
|
6
7
|
*/
|
|
@@ -19,6 +20,7 @@ export interface AddReferencesOptions {
|
|
|
19
20
|
*/
|
|
20
21
|
export interface AddedItem {
|
|
21
22
|
id: string;
|
|
23
|
+
uuid: string;
|
|
22
24
|
title: string;
|
|
23
25
|
/** True if the ID was changed due to collision */
|
|
24
26
|
idChanged?: boolean;
|
|
@@ -31,6 +33,7 @@ export interface AddedItem {
|
|
|
31
33
|
export interface FailedItem {
|
|
32
34
|
source: string;
|
|
33
35
|
error: string;
|
|
36
|
+
reason: import("../import/importer.js").FailureReason;
|
|
34
37
|
}
|
|
35
38
|
/**
|
|
36
39
|
* Information about a skipped duplicate
|
|
@@ -38,6 +41,7 @@ export interface FailedItem {
|
|
|
38
41
|
export interface SkippedItem {
|
|
39
42
|
source: string;
|
|
40
43
|
existingId: string;
|
|
44
|
+
duplicateType: import("../duplicate/types.js").DuplicateType;
|
|
41
45
|
}
|
|
42
46
|
/**
|
|
43
47
|
* Result of addReferences operation
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../../src/features/operations/add.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAEhE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../../src/features/operations/add.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAEhE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAQzD,YAAY,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE3D;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,+BAA+B;IAC/B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;IAC9B,+BAA+B;IAC/B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,gFAAgF;IAChF,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,8CAA8C;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,uBAAuB,EAAE,aAAa,CAAC;CACvD;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,OAAO,uBAAuB,EAAE,aAAa,CAAC;CAC9D;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EAAE,EAChB,OAAO,EAAE,QAAQ,EACjB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,mBAAmB,CAAC,CAwC9B"}
|
|
@@ -6,4 +6,5 @@
|
|
|
6
6
|
export { fulltextAttach, type FulltextAttachOptions, type FulltextAttachResult } from "./attach.js";
|
|
7
7
|
export { fulltextGet, type FulltextGetOptions, type FulltextGetResult } from "./get.js";
|
|
8
8
|
export { fulltextDetach, type FulltextDetachOptions, type FulltextDetachResult } from "./detach.js";
|
|
9
|
+
export { fulltextOpen, type FulltextOpenOptions, type FulltextOpenResult } from "./open.js";
|
|
9
10
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/features/operations/fulltext/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,KAAK,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACpG,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,KAAK,iBAAiB,EAAE,MAAM,UAAU,CAAC;AACxF,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,KAAK,oBAAoB,EAAE,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/features/operations/fulltext/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,KAAK,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACpG,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,KAAK,iBAAiB,EAAE,MAAM,UAAU,CAAC;AACxF,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,KAAK,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACpG,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,KAAK,kBAAkB,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fulltext open operation
|
|
3
|
+
*/
|
|
4
|
+
import type { ILibrary, IdentifierType } from "../../../core/library-interface.js";
|
|
5
|
+
import type { FulltextType } from "../../fulltext/index.js";
|
|
6
|
+
/**
|
|
7
|
+
* Options for fulltextOpen operation
|
|
8
|
+
*/
|
|
9
|
+
export interface FulltextOpenOptions {
|
|
10
|
+
/** Reference identifier (id or uuid) */
|
|
11
|
+
identifier: string;
|
|
12
|
+
/** Specific type to open (pdf or markdown) */
|
|
13
|
+
type?: FulltextType | undefined;
|
|
14
|
+
/** Identifier type: 'id' (default), 'uuid', 'doi', 'pmid', or 'isbn' */
|
|
15
|
+
idType?: IdentifierType | undefined;
|
|
16
|
+
/** Directory for fulltext files */
|
|
17
|
+
fulltextDirectory: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Result of fulltextOpen operation
|
|
21
|
+
*/
|
|
22
|
+
export interface FulltextOpenResult {
|
|
23
|
+
success: boolean;
|
|
24
|
+
openedType?: FulltextType;
|
|
25
|
+
openedPath?: string;
|
|
26
|
+
error?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Open fulltext file with system default application.
|
|
30
|
+
*
|
|
31
|
+
* @param library - The library containing the reference
|
|
32
|
+
* @param options - Open options
|
|
33
|
+
* @returns Result with opened file info
|
|
34
|
+
*/
|
|
35
|
+
export declare function fulltextOpen(library: ILibrary, options: FulltextOpenOptions): Promise<FulltextOpenResult>;
|
|
36
|
+
//# sourceMappingURL=open.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open.d.ts","sourceRoot":"","sources":["../../../../src/features/operations/fulltext/open.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEnF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE5D;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,8CAA8C;IAC9C,IAAI,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IAChC,wEAAwE;IACxE,MAAM,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IACpC,mCAAmC;IACnC,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAgCD;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,QAAQ,EACjB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,kBAAkB,CAAC,CA8C7B"}
|
|
@@ -12,4 +12,6 @@ export type { SearchOperationOptions, SearchResult } from "./search.js";
|
|
|
12
12
|
export type { ListOptions, ListResult } from "./list.js";
|
|
13
13
|
export type { CiteOperationOptions, CiteResult, CiteItemResult } from "./cite.js";
|
|
14
14
|
export type { AddReferencesOptions, AddReferencesResult } from "./add.js";
|
|
15
|
+
export type { AddJsonOutput, RemoveJsonOutput, UpdateJsonOutput, } from "./json-output.js";
|
|
16
|
+
export { formatAddJsonOutput, formatRemoveJsonOutput, formatUpdateJsonOutput, } from "./json-output.js";
|
|
15
17
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/features/operations/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,YAAY,EACV,kBAAkB,EAClB,aAAa,EACb,YAAY,GACb,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAG5D,YAAY,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACxE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACzD,YAAY,EAAE,oBAAoB,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAClF,YAAY,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/features/operations/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,YAAY,EACV,kBAAkB,EAClB,aAAa,EACb,YAAY,GACb,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAG5D,YAAY,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACxE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACzD,YAAY,EAAE,oBAAoB,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAClF,YAAY,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAG1E,YAAY,EACV,aAAa,EACb,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON output formatters for add/remove/update commands
|
|
3
|
+
*
|
|
4
|
+
* This module provides machine-readable JSON output for external tool integration.
|
|
5
|
+
* The formatters are placed in the features layer to enable reuse by CLI, HTTP Server, and MCP Server.
|
|
6
|
+
*/
|
|
7
|
+
import type { CslItem } from "../../core/csl-json/types.js";
|
|
8
|
+
import type { DuplicateType } from "../duplicate/types.js";
|
|
9
|
+
import type { FailureReason } from "../import/importer.js";
|
|
10
|
+
import type { AddReferencesResult } from "./add.js";
|
|
11
|
+
import type { RemoveResult } from "./remove.js";
|
|
12
|
+
import type { UpdateOperationResult } from "./update.js";
|
|
13
|
+
export interface AddJsonOutputItem {
|
|
14
|
+
source: string;
|
|
15
|
+
id: string;
|
|
16
|
+
uuid: string;
|
|
17
|
+
title: string;
|
|
18
|
+
idChanged?: boolean;
|
|
19
|
+
originalId?: string;
|
|
20
|
+
item?: CslItem;
|
|
21
|
+
}
|
|
22
|
+
export interface SkippedJsonOutputItem {
|
|
23
|
+
source: string;
|
|
24
|
+
reason: "duplicate";
|
|
25
|
+
existingId: string;
|
|
26
|
+
duplicateType: DuplicateType;
|
|
27
|
+
}
|
|
28
|
+
export interface FailedJsonOutputItem {
|
|
29
|
+
source: string;
|
|
30
|
+
reason: FailureReason;
|
|
31
|
+
error: string;
|
|
32
|
+
}
|
|
33
|
+
export interface AddJsonOutput {
|
|
34
|
+
summary: {
|
|
35
|
+
total: number;
|
|
36
|
+
added: number;
|
|
37
|
+
skipped: number;
|
|
38
|
+
failed: number;
|
|
39
|
+
};
|
|
40
|
+
added: AddJsonOutputItem[];
|
|
41
|
+
skipped: SkippedJsonOutputItem[];
|
|
42
|
+
failed: FailedJsonOutputItem[];
|
|
43
|
+
}
|
|
44
|
+
export interface RemoveJsonOutput {
|
|
45
|
+
success: boolean;
|
|
46
|
+
id: string;
|
|
47
|
+
uuid?: string;
|
|
48
|
+
title?: string;
|
|
49
|
+
item?: CslItem;
|
|
50
|
+
error?: string;
|
|
51
|
+
}
|
|
52
|
+
export interface UpdateJsonOutput {
|
|
53
|
+
success: boolean;
|
|
54
|
+
id: string;
|
|
55
|
+
uuid?: string;
|
|
56
|
+
title?: string;
|
|
57
|
+
idChanged?: boolean;
|
|
58
|
+
previousId?: string;
|
|
59
|
+
before?: CslItem;
|
|
60
|
+
after?: CslItem;
|
|
61
|
+
error?: string;
|
|
62
|
+
}
|
|
63
|
+
export interface FormatAddJsonOptions {
|
|
64
|
+
/** Include full CSL-JSON data */
|
|
65
|
+
full?: boolean;
|
|
66
|
+
/** Map from added item ID to source string */
|
|
67
|
+
sources?: Map<string, string>;
|
|
68
|
+
/** Map from added item ID to CslItem (for --full) */
|
|
69
|
+
items?: Map<string, CslItem>;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Format add command result as JSON output
|
|
73
|
+
*/
|
|
74
|
+
export declare function formatAddJsonOutput(result: AddReferencesResult, options: FormatAddJsonOptions): AddJsonOutput;
|
|
75
|
+
export interface FormatRemoveJsonOptions {
|
|
76
|
+
/** Include full CSL-JSON data */
|
|
77
|
+
full?: boolean;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Format remove command result as JSON output
|
|
81
|
+
*/
|
|
82
|
+
export declare function formatRemoveJsonOutput(result: RemoveResult, id: string, options: FormatRemoveJsonOptions): RemoveJsonOutput;
|
|
83
|
+
export interface FormatUpdateJsonOptions {
|
|
84
|
+
/** Include full CSL-JSON data (before/after) */
|
|
85
|
+
full?: boolean;
|
|
86
|
+
/** The item before update (for --full) */
|
|
87
|
+
before?: CslItem;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Format update command result as JSON output
|
|
91
|
+
*/
|
|
92
|
+
export declare function formatUpdateJsonOutput(result: UpdateOperationResult, originalId: string, options: FormatUpdateJsonOptions): UpdateJsonOutput;
|
|
93
|
+
//# sourceMappingURL=json-output.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-output.d.ts","sourceRoot":"","sources":["../../../src/features/operations/json-output.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAMzD,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,WAAW,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,aAAa,CAAC;CAC9B;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,aAAa,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,OAAO,EAAE,qBAAqB,EAAE,CAAC;IACjC,MAAM,EAAE,oBAAoB,EAAE,CAAC;CAChC;AAMD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAMD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAMD,MAAM,WAAW,oBAAoB;IACnC,iCAAiC;IACjC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,8CAA8C;IAC9C,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,qDAAqD;IACrD,KAAK,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC9B;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,mBAAmB,EAC3B,OAAO,EAAE,oBAAoB,GAC5B,aAAa,CAkDf;AAED,MAAM,WAAW,uBAAuB;IACtC,iCAAiC;IACjC,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,YAAY,EACpB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,uBAAuB,GAC/B,gBAAgB,CAwBlB;AAED,MAAM,WAAW,uBAAuB;IACtC,gDAAgD;IAChD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,0CAA0C;IAC1C,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,qBAAqB,EAC7B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,uBAAuB,GAC/B,gBAAgB,CA2ClB"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { CslItem } from "../../core/csl-json/types.js";
|
|
2
2
|
import type { ILibrary, IdentifierType } from "../../core/library-interface.js";
|
|
3
|
+
import type { FulltextType } from "../fulltext/index.js";
|
|
3
4
|
/**
|
|
4
5
|
* Options for removeReference operation
|
|
5
6
|
*/
|
|
@@ -8,6 +9,10 @@ export interface RemoveOperationOptions {
|
|
|
8
9
|
identifier: string;
|
|
9
10
|
/** Identifier type: 'id' (default), 'uuid', 'doi', 'pmid', or 'isbn' */
|
|
10
11
|
idType?: IdentifierType;
|
|
12
|
+
/** Directory containing fulltext files (required if deleteFulltext is true) */
|
|
13
|
+
fulltextDirectory?: string;
|
|
14
|
+
/** Whether to delete associated fulltext files */
|
|
15
|
+
deleteFulltext?: boolean;
|
|
11
16
|
}
|
|
12
17
|
/**
|
|
13
18
|
* Result of removeReference operation
|
|
@@ -17,7 +22,13 @@ export interface RemoveResult {
|
|
|
17
22
|
removed: boolean;
|
|
18
23
|
/** The removed item (if found and removal succeeded) */
|
|
19
24
|
removedItem?: CslItem;
|
|
25
|
+
/** Fulltext types that were deleted (only when deleteFulltext=true) */
|
|
26
|
+
deletedFulltextTypes?: FulltextType[];
|
|
20
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Get fulltext attachment types from a CSL item.
|
|
30
|
+
*/
|
|
31
|
+
export declare function getFulltextAttachmentTypes(item: CslItem): FulltextType[];
|
|
21
32
|
/**
|
|
22
33
|
* Remove a reference from the library.
|
|
23
34
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remove.d.ts","sourceRoot":"","sources":["../../../src/features/operations/remove.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"remove.d.ts","sourceRoot":"","sources":["../../../src/features/operations/remove.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAChF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,2BAA2B;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,+EAA+E;IAC/E,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kDAAkD;IAClD,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,wCAAwC;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,wDAAwD;IACxD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,uEAAuE;IACvE,oBAAoB,CAAC,EAAE,YAAY,EAAE,CAAC;CACvC;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,OAAO,GAAG,YAAY,EAAE,CAYxE;AA6BD;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,QAAQ,EACjB,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,YAAY,CAAC,CAyBvB"}
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { C as CslLibrarySchema, c as computeFileHash, a as computeHash, p as pickDefined, n as normalize, s as search, b as sortResults, t as tokenize, d as detectDuplicate } from "./chunks/file-watcher-
|
|
2
|
-
import { e, F, L, R, m, o, h, i, k, l, j, f, g, w } from "./chunks/file-watcher-
|
|
1
|
+
import { C as CslLibrarySchema, c as computeFileHash, a as computeHash, p as pickDefined, n as normalize, s as search, b as sortResults, t as tokenize, d as detectDuplicate } from "./chunks/file-watcher-DdhXSm1l.js";
|
|
2
|
+
import { e, F, L, R, m, o, h, i, k, l, j, f, g, w } from "./chunks/file-watcher-DdhXSm1l.js";
|
|
3
3
|
import { mkdir, readFile, copyFile, stat, unlink, readdir } from "node:fs/promises";
|
|
4
4
|
import { dirname, join } from "node:path";
|
|
5
5
|
import writeFileAtomicLib from "write-file-atomic";
|
|
6
6
|
import { existsSync } from "node:fs";
|
|
7
7
|
import { tmpdir } from "node:os";
|
|
8
8
|
import { fileURLToPath } from "node:url";
|
|
9
|
-
import { b as backupConfigSchema, c as configSchema, d as defaultConfig,
|
|
9
|
+
import { g as getOpenerCommand, o as openWithSystemApp, b as backupConfigSchema, c as configSchema, d as defaultConfig, a as getDefaultBackupDirectory, e as getDefaultCurrentDirConfigFilename, f as getDefaultLibraryPath, h as getDefaultUserConfigPath, l as loadConfig, i as logLevelSchema, n as normalizePartialConfig, p as partialConfigSchema, w as watchConfigSchema } from "./chunks/loader-C-bdImuO.js";
|
|
10
10
|
function validateCslJson(data) {
|
|
11
11
|
const parseResult = CslLibrarySchema.safeParse(data);
|
|
12
12
|
if (!parseResult.success) {
|
|
@@ -119,7 +119,9 @@ const index$4 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePrope
|
|
|
119
119
|
createLogger,
|
|
120
120
|
ensureDirectoryExists,
|
|
121
121
|
getBackupDirectory,
|
|
122
|
+
getOpenerCommand,
|
|
122
123
|
listBackups,
|
|
124
|
+
openWithSystemApp,
|
|
123
125
|
pickDefined,
|
|
124
126
|
writeFileAtomic
|
|
125
127
|
}, Symbol.toStringTag, { value: "Module" }));
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/core/csl-json/validator.ts","../src/utils/logger.ts","../src/utils/file.ts","../src/utils/backup.ts","../src/features/merge/three-way.ts"],"sourcesContent":["import { CslItemSchema, CslLibrarySchema } from \"./types\";\nimport type { CslItem, CslLibrary } from \"./types\";\n\n/**\n * Validate CSL-JSON library structure\n * @param data - Data to validate (can be any type)\n * @returns Validated CSL-JSON library\n * @throws Error if validation fails\n */\nexport function validateCslJson(data: unknown): CslLibrary {\n const parseResult = CslLibrarySchema.safeParse(data);\n\n if (!parseResult.success) {\n throw new Error(`Invalid CSL-JSON structure: ${parseResult.error.message}`);\n }\n\n return parseResult.data;\n}\n\n/**\n * Validate a single CSL-JSON item\n * @param data - Data to validate (can be any type)\n * @returns Validation result with valid flag and errors\n */\nexport function validateCslItem(data: unknown): {\n valid: boolean;\n data?: CslItem;\n errors?: string[];\n} {\n const parseResult = CslItemSchema.safeParse(data);\n\n if (!parseResult.success) {\n return {\n valid: false,\n errors: parseResult.error.issues.map((issue) => issue.message),\n };\n }\n\n return {\n valid: true,\n data: parseResult.data,\n };\n}\n","export type LogLevel = \"silent\" | \"info\" | \"debug\";\n\nexport interface Logger {\n info(...args: unknown[]): void;\n debug(...args: unknown[]): void;\n error(...args: unknown[]): void;\n}\n\nexport function createLogger(level: LogLevel = \"info\"): Logger {\n const shouldLogInfo = level === \"info\" || level === \"debug\";\n const shouldLogDebug = level === \"debug\";\n\n function formatMessage(...args: unknown[]): string {\n return `${args.map((arg) => String(arg)).join(\" \")}\\n`;\n }\n\n return {\n info(...args: unknown[]): void {\n if (shouldLogInfo) {\n process.stderr.write(formatMessage(...args));\n }\n },\n\n debug(...args: unknown[]): void {\n if (shouldLogDebug) {\n process.stderr.write(formatMessage(...args));\n }\n },\n\n error(...args: unknown[]): void {\n process.stderr.write(formatMessage(...args));\n },\n };\n}\n","import { mkdir } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport writeFileAtomicLib from \"write-file-atomic\";\n\n/**\n * Write file atomically with parent directory creation\n */\nexport async function writeFileAtomic(filePath: string, content: string): Promise<void> {\n await ensureDirectoryExists(dirname(filePath));\n await writeFileAtomicLib(filePath, content, { encoding: \"utf-8\" });\n}\n\n/**\n * Ensure directory exists, creating it recursively if necessary\n */\nexport async function ensureDirectoryExists(dirPath: string): Promise<void> {\n await mkdir(dirPath, { recursive: true });\n}\n","import { existsSync } from \"node:fs\";\nimport { copyFile, readFile, readdir, stat, unlink } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { ensureDirectoryExists } from \"./file\";\n\nexport interface BackupOptions {\n maxGenerations?: number;\n maxAgeMs?: number;\n}\n\nconst DEFAULT_MAX_GENERATIONS = 50;\nconst DEFAULT_MAX_AGE_MS = 365 * 24 * 60 * 60 * 1000; // 1 year\n\n/**\n * Get package name from package.json\n */\nasync function resolvePackageName(): Promise<string> {\n try {\n const currentFile = fileURLToPath(import.meta.url);\n let currentDir = dirname(currentFile);\n\n for (let i = 0; i < 10; i++) {\n const packageJsonPath = join(currentDir, \"package.json\");\n if (existsSync(packageJsonPath)) {\n const content = await readFile(packageJsonPath, \"utf-8\");\n const pkg = JSON.parse(content);\n return pkg.name;\n }\n currentDir = dirname(currentDir);\n }\n } catch {\n // Fall back to hardcoded name if package.json is not found\n }\n\n return \"reference-manager\";\n}\n\nconst packageName = await resolvePackageName();\n\n/**\n * Get backup directory path for a library\n */\nexport function getBackupDirectory(libraryName: string): string {\n const pkgName = packageName ?? \"reference-manager\";\n return join(tmpdir(), pkgName, \"backups\", libraryName);\n}\n\n/**\n * Create a backup of the given file\n */\nexport async function createBackup(sourceFile: string, libraryName: string): Promise<string> {\n const backupDir = getBackupDirectory(libraryName);\n await ensureDirectoryExists(backupDir);\n\n const timestamp = Date.now();\n const backupFileName = `${timestamp}.backup`;\n const backupPath = join(backupDir, backupFileName);\n\n await copyFile(sourceFile, backupPath);\n\n return backupPath;\n}\n\n/**\n * List all backups for a library (sorted by modification time, newest first)\n */\nexport async function listBackups(libraryName: string): Promise<string[]> {\n const backupDir = getBackupDirectory(libraryName);\n\n if (!existsSync(backupDir)) {\n return [];\n }\n\n const files = await readdir(backupDir);\n const backupFiles = files.filter((f) => f.endsWith(\".backup\")).map((f) => join(backupDir, f));\n\n const filesWithStats = await Promise.all(\n backupFiles.map(async (file) => {\n const stats = await stat(file);\n return { file, mtime: stats.mtimeMs };\n })\n );\n\n filesWithStats.sort((a, b) => b.mtime - a.mtime);\n\n return filesWithStats.map((f) => f.file);\n}\n\n/**\n * Clean up old backups based on generation count and age\n */\nexport async function cleanupOldBackups(\n libraryName: string,\n options?: BackupOptions\n): Promise<void> {\n const maxGenerations = options?.maxGenerations ?? DEFAULT_MAX_GENERATIONS;\n const maxAgeMs = options?.maxAgeMs ?? DEFAULT_MAX_AGE_MS;\n\n const backups = await listBackups(libraryName);\n const now = Date.now();\n\n const backupsToDelete: string[] = [];\n\n for (let i = 0; i < backups.length; i++) {\n const backupPath = backups[i];\n if (!backupPath) continue;\n\n const stats = await stat(backupPath);\n const age = now - stats.mtimeMs;\n\n if (i >= maxGenerations || age > maxAgeMs) {\n backupsToDelete.push(backupPath);\n }\n }\n\n await Promise.all(backupsToDelete.map((backup) => unlink(backup)));\n}\n","/**\n * 3-way merge implementation with Last-Write-Wins (LWW) strategy\n */\n\nimport type { CslItem } from \"../../core/csl-json/types.js\";\nimport type {\n FieldConflict,\n ItemConflict,\n MergeOptions,\n MergeResult,\n MergeStatus,\n} from \"./types.js\";\n\n/**\n * Get UUID from item, with fallback to id if uuid is missing\n */\nfunction getItemUuid(item: CslItem): string {\n return item.custom?.uuid || item.id || \"unknown\";\n}\n\n/**\n * Get timestamp from item, with fallback to created_at\n */\nfunction getTimestamp(item: CslItem): string {\n return item.custom?.timestamp || item.custom?.created_at || \"1970-01-01T00:00:00.000Z\";\n}\n\n/**\n * Deep equality check for field values\n */\nfunction deepEqual(a: unknown, b: unknown): boolean {\n return JSON.stringify(a) === JSON.stringify(b);\n}\n\n/**\n * Resolve a field conflict using LWW or prefer option\n */\nfunction resolveFieldConflict(\n localValue: unknown,\n remoteValue: unknown,\n localTimestamp: string,\n remoteTimestamp: string,\n options?: MergeOptions\n): unknown {\n if (localTimestamp > remoteTimestamp) {\n return localValue;\n }\n if (remoteTimestamp > localTimestamp) {\n return remoteValue;\n }\n // Timestamps equal: use prefer option or default to local\n if (options?.prefer === \"remote\") {\n return remoteValue;\n }\n return localValue;\n}\n\n/**\n * Determine conflict resolution type\n */\nfunction determineResolution(\n fieldConflicts: FieldConflict[],\n localTimestamp: string,\n remoteTimestamp: string,\n options?: MergeOptions\n): ItemConflict[\"resolution\"] {\n const hasRealConflicts = fieldConflicts.every((fc) => fc.resolved !== undefined);\n const localIsNewer = fieldConflicts.some(\n (fc) => fc.local !== fc.remote && localTimestamp > remoteTimestamp\n );\n const remoteIsNewer = fieldConflicts.some(\n (fc) => fc.local !== fc.remote && remoteTimestamp > localTimestamp\n );\n\n if (hasRealConflicts && localIsNewer) return \"auto-lww\";\n if (hasRealConflicts && remoteIsNewer) return \"auto-lww\";\n if (options?.prefer === \"local\") return \"prefer-local\";\n if (options?.prefer === \"remote\") return \"prefer-remote\";\n return \"unresolved\";\n}\n\n/**\n * Merge a single field from base, local, and remote versions\n */\nfunction mergeField(\n key: string,\n baseValue: unknown,\n localValue: unknown,\n remoteValue: unknown,\n localTimestamp: string,\n remoteTimestamp: string,\n options?: MergeOptions\n): { value: unknown; conflict: FieldConflict | null } {\n const localChanged = !deepEqual(baseValue, localValue);\n const remoteChanged = !deepEqual(baseValue, remoteValue);\n\n if (!localChanged && !remoteChanged) {\n return { value: baseValue, conflict: null };\n }\n\n if (localChanged && !remoteChanged) {\n return { value: localValue, conflict: null };\n }\n\n if (!localChanged && remoteChanged) {\n return { value: remoteValue, conflict: null };\n }\n\n // Both changed\n if (deepEqual(localValue, remoteValue)) {\n return { value: localValue, conflict: null };\n }\n\n // Both changed to different values\n const resolved = resolveFieldConflict(\n localValue,\n remoteValue,\n localTimestamp,\n remoteTimestamp,\n options\n );\n\n // Don't record conflicts for 'custom' metadata field\n if (key === \"custom\") {\n return { value: resolved, conflict: null };\n }\n\n return {\n value: resolved,\n conflict: {\n field: key,\n base: baseValue,\n local: localValue,\n remote: remoteValue,\n resolved,\n },\n };\n}\n\n/**\n * Merge a single item from base, local, and remote versions\n */\nfunction mergeItem(\n base: CslItem,\n local: CslItem,\n remote: CslItem,\n options?: MergeOptions\n): { merged: CslItem; conflict: ItemConflict | null } {\n const uuid = getItemUuid(base);\n const localTimestamp = getTimestamp(local);\n const remoteTimestamp = getTimestamp(remote);\n\n const merged: CslItem = { ...base };\n const fieldConflicts: FieldConflict[] = [];\n\n // Get all unique keys from all three versions\n const allKeys = new Set<string>([\n ...Object.keys(base),\n ...Object.keys(local),\n ...Object.keys(remote),\n ]);\n\n for (const key of allKeys) {\n const baseValue = (base as Record<string, unknown>)[key];\n const localValue = (local as Record<string, unknown>)[key];\n const remoteValue = (remote as Record<string, unknown>)[key];\n\n const { value, conflict } = mergeField(\n key,\n baseValue,\n localValue,\n remoteValue,\n localTimestamp,\n remoteTimestamp,\n options\n );\n\n (merged as Record<string, unknown>)[key] = value;\n\n if (conflict) {\n fieldConflicts.push(conflict);\n }\n }\n\n // If there are field conflicts, create ItemConflict\n if (fieldConflicts.length > 0) {\n const resolution = determineResolution(\n fieldConflicts,\n localTimestamp,\n remoteTimestamp,\n options\n );\n\n return {\n merged,\n conflict: {\n uuid,\n id: base.id || \"unknown\",\n fields: fieldConflicts,\n localTimestamp,\n remoteTimestamp,\n resolution,\n },\n };\n }\n\n return { merged, conflict: null };\n}\n\n/**\n * Build UUID-indexed maps from item arrays\n */\nfunction buildItemMaps(base: CslItem[], local: CslItem[], remote: CslItem[]) {\n const baseMap = new Map<string, CslItem>();\n const localMap = new Map<string, CslItem>();\n const remoteMap = new Map<string, CslItem>();\n\n for (const item of base) {\n baseMap.set(getItemUuid(item), item);\n }\n for (const item of local) {\n localMap.set(getItemUuid(item), item);\n }\n for (const item of remote) {\n remoteMap.set(getItemUuid(item), item);\n }\n\n return { baseMap, localMap, remoteMap };\n}\n\n/**\n * Handle items that exist in all three versions\n */\nfunction mergeExistingItem(\n baseItem: CslItem,\n localItem: CslItem,\n remoteItem: CslItem,\n options: MergeOptions | undefined,\n merged: CslItem[],\n conflicts: ItemConflict[]\n): void {\n const { merged: mergedItem, conflict } = mergeItem(baseItem, localItem, remoteItem, options);\n merged.push(mergedItem);\n if (conflict) {\n conflicts.push(conflict);\n }\n}\n\n/**\n * Handle items added in both local and remote\n */\nfunction handleDualAddition(\n uuid: string,\n localItem: CslItem,\n remoteItem: CslItem,\n options: MergeOptions | undefined,\n merged: CslItem[],\n conflicts: ItemConflict[]\n): void {\n if (deepEqual(localItem, remoteItem)) {\n merged.push(localItem);\n } else {\n const syntheticBase: CslItem = {\n id: uuid,\n type: \"article\",\n custom: {\n uuid,\n created_at: \"1970-01-01T00:00:00.000Z\",\n timestamp: \"1970-01-01T00:00:00.000Z\",\n },\n };\n const { merged: mergedItem, conflict } = mergeItem(\n syntheticBase,\n localItem,\n remoteItem,\n options\n );\n merged.push(mergedItem);\n if (conflict) {\n conflicts.push(conflict);\n }\n }\n}\n\n/**\n * Process a single UUID across all three versions\n */\nfunction processItem(\n uuid: string,\n baseMap: Map<string, CslItem>,\n localMap: Map<string, CslItem>,\n remoteMap: Map<string, CslItem>,\n options: MergeOptions | undefined,\n result: {\n merged: CslItem[];\n conflicts: ItemConflict[];\n localOnly: CslItem[];\n remoteOnly: CslItem[];\n deletedInLocal: CslItem[];\n deletedInRemote: CslItem[];\n }\n): void {\n const baseItem = baseMap.get(uuid);\n const localItem = localMap.get(uuid);\n const remoteItem = remoteMap.get(uuid);\n\n if (baseItem && localItem && remoteItem) {\n mergeExistingItem(baseItem, localItem, remoteItem, options, result.merged, result.conflicts);\n } else if (!baseItem && localItem && remoteItem) {\n handleDualAddition(uuid, localItem, remoteItem, options, result.merged, result.conflicts);\n } else if (!baseItem && localItem && !remoteItem) {\n result.merged.push(localItem);\n result.localOnly.push(localItem);\n } else if (!baseItem && !localItem && remoteItem) {\n result.merged.push(remoteItem);\n result.remoteOnly.push(remoteItem);\n } else if (baseItem && !localItem && remoteItem) {\n result.deletedInLocal.push(baseItem);\n } else if (baseItem && localItem && !remoteItem) {\n result.deletedInRemote.push(baseItem);\n } else if (baseItem && !localItem && !remoteItem) {\n result.deletedInLocal.push(baseItem);\n result.deletedInRemote.push(baseItem);\n }\n}\n\n/**\n * Performs a 3-way merge of CSL-JSON items\n *\n * @param base - Base version (common ancestor)\n * @param local - Local version (current working copy)\n * @param remote - Remote version (incoming changes)\n * @param options - Merge options (e.g., prefer local/remote for tie-breaking)\n * @returns Merge result with merged items and conflict information\n */\nexport function threeWayMerge(\n base: CslItem[],\n local: CslItem[],\n remote: CslItem[],\n options?: MergeOptions\n): MergeResult {\n const { baseMap, localMap, remoteMap } = buildItemMaps(base, local, remote);\n\n const result = {\n merged: [] as CslItem[],\n conflicts: [] as ItemConflict[],\n localOnly: [] as CslItem[],\n remoteOnly: [] as CslItem[],\n deletedInLocal: [] as CslItem[],\n deletedInRemote: [] as CslItem[],\n };\n\n const allUuids = new Set<string>([...baseMap.keys(), ...localMap.keys(), ...remoteMap.keys()]);\n\n for (const uuid of allUuids) {\n processItem(uuid, baseMap, localMap, remoteMap, options, result);\n }\n\n // Determine overall status\n let status: MergeStatus = \"success\";\n if (result.conflicts.length > 0) {\n const hasUnresolved = result.conflicts.some((c) => c.resolution === \"unresolved\");\n status = hasUnresolved ? \"conflict\" : \"auto-resolved\";\n }\n\n return {\n status,\n ...result,\n };\n}\n"],"names":["i","f"],"mappings":";;;;;;;;;AASO,SAAS,gBAAgB,MAA2B;AACzD,QAAM,cAAc,iBAAiB,UAAU,IAAI;AAEnD,MAAI,CAAC,YAAY,SAAS;AACxB,UAAM,IAAI,MAAM,+BAA+B,YAAY,MAAM,OAAO,EAAE;AAAA,EAC5E;AAEA,SAAO,YAAY;AACrB;ACTO,SAAS,aAAa,QAAkB,QAAgB;AAC7D,QAAM,gBAAgB,UAAU,UAAU,UAAU;AACpD,QAAM,iBAAiB,UAAU;AAEjC,WAAS,iBAAiB,MAAyB;AACjD,WAAO,GAAG,KAAK,IAAI,CAAC,QAAQ,OAAO,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC;AAAA;AAAA,EACpD;AAEA,SAAO;AAAA,IACL,QAAQ,MAAuB;AAC7B,UAAI,eAAe;AACjB,gBAAQ,OAAO,MAAM,cAAc,GAAG,IAAI,CAAC;AAAA,MAC7C;AAAA,IACF;AAAA,IAEA,SAAS,MAAuB;AAC9B,UAAI,gBAAgB;AAClB,gBAAQ,OAAO,MAAM,cAAc,GAAG,IAAI,CAAC;AAAA,MAC7C;AAAA,IACF;AAAA,IAEA,SAAS,MAAuB;AAC9B,cAAQ,OAAO,MAAM,cAAc,GAAG,IAAI,CAAC;AAAA,IAC7C;AAAA,EAAA;AAEJ;AC1BA,eAAsB,gBAAgB,UAAkB,SAAgC;AACtF,QAAM,sBAAsB,QAAQ,QAAQ,CAAC;AAC7C,QAAM,mBAAmB,UAAU,SAAS,EAAE,UAAU,SAAS;AACnE;AAKA,eAAsB,sBAAsB,SAAgC;AAC1E,QAAM,MAAM,SAAS,EAAE,WAAW,MAAM;AAC1C;ACLA,MAAM,0BAA0B;AAChC,MAAM,qBAAqB,MAAM,KAAK,KAAK,KAAK;AAKhD,eAAe,qBAAsC;AACnD,MAAI;AACF,UAAM,cAAc,cAAc,YAAY,GAAG;AACjD,QAAI,aAAa,QAAQ,WAAW;AAEpC,aAASA,KAAI,GAAGA,KAAI,IAAIA,MAAK;AAC3B,YAAM,kBAAkB,KAAK,YAAY,cAAc;AACvD,UAAI,WAAW,eAAe,GAAG;AAC/B,cAAM,UAAU,MAAM,SAAS,iBAAiB,OAAO;AACvD,cAAM,MAAM,KAAK,MAAM,OAAO;AAC9B,eAAO,IAAI;AAAA,MACb;AACA,mBAAa,QAAQ,UAAU;AAAA,IACjC;AAAA,EACF,QAAQ;AAAA,EAER;AAEA,SAAO;AACT;AAEA,MAAM,cAAc,MAAM,mBAAA;AAKnB,SAAS,mBAAmB,aAA6B;AAC9D,QAAM,UAAU,eAAe;AAC/B,SAAO,KAAK,OAAA,GAAU,SAAS,WAAW,WAAW;AACvD;AAKA,eAAsB,aAAa,YAAoB,aAAsC;AAC3F,QAAM,YAAY,mBAAmB,WAAW;AAChD,QAAM,sBAAsB,SAAS;AAErC,QAAM,YAAY,KAAK,IAAA;AACvB,QAAM,iBAAiB,GAAG,SAAS;AACnC,QAAM,aAAa,KAAK,WAAW,cAAc;AAEjD,QAAM,SAAS,YAAY,UAAU;AAErC,SAAO;AACT;AAKA,eAAsB,YAAY,aAAwC;AACxE,QAAM,YAAY,mBAAmB,WAAW;AAEhD,MAAI,CAAC,WAAW,SAAS,GAAG;AAC1B,WAAO,CAAA;AAAA,EACT;AAEA,QAAM,QAAQ,MAAM,QAAQ,SAAS;AACrC,QAAM,cAAc,MAAM,OAAO,CAACC,OAAMA,GAAE,SAAS,SAAS,CAAC,EAAE,IAAI,CAACA,OAAM,KAAK,WAAWA,EAAC,CAAC;AAE5F,QAAM,iBAAiB,MAAM,QAAQ;AAAA,IACnC,YAAY,IAAI,OAAO,SAAS;AAC9B,YAAM,QAAQ,MAAM,KAAK,IAAI;AAC7B,aAAO,EAAE,MAAM,OAAO,MAAM,QAAA;AAAA,IAC9B,CAAC;AAAA,EAAA;AAGH,iBAAe,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AAE/C,SAAO,eAAe,IAAI,CAACA,OAAMA,GAAE,IAAI;AACzC;AAKA,eAAsB,kBACpB,aACA,SACe;AACf,QAAM,iBAAiB,SAAS,kBAAkB;AAClD,QAAM,WAAW,SAAS,YAAY;AAEtC,QAAM,UAAU,MAAM,YAAY,WAAW;AAC7C,QAAM,MAAM,KAAK,IAAA;AAEjB,QAAM,kBAA4B,CAAA;AAElC,WAASD,KAAI,GAAGA,KAAI,QAAQ,QAAQA,MAAK;AACvC,UAAM,aAAa,QAAQA,EAAC;AAC5B,QAAI,CAAC,WAAY;AAEjB,UAAM,QAAQ,MAAM,KAAK,UAAU;AACnC,UAAM,MAAM,MAAM,MAAM;AAExB,QAAIA,MAAK,kBAAkB,MAAM,UAAU;AACzC,sBAAgB,KAAK,UAAU;AAAA,IACjC;AAAA,EACF;AAEA,QAAM,QAAQ,IAAI,gBAAgB,IAAI,CAAC,WAAW,OAAO,MAAM,CAAC,CAAC;AACnE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACtGA,SAAS,YAAY,MAAuB;AAC1C,SAAO,KAAK,QAAQ,QAAQ,KAAK,MAAM;AACzC;AAKA,SAAS,aAAa,MAAuB;AAC3C,SAAO,KAAK,QAAQ,aAAa,KAAK,QAAQ,cAAc;AAC9D;AAKA,SAAS,UAAU,GAAY,GAAqB;AAClD,SAAO,KAAK,UAAU,CAAC,MAAM,KAAK,UAAU,CAAC;AAC/C;AAKA,SAAS,qBACP,YACA,aACA,gBACA,iBACA,SACS;AACT,MAAI,iBAAiB,iBAAiB;AACpC,WAAO;AAAA,EACT;AACA,MAAI,kBAAkB,gBAAgB;AACpC,WAAO;AAAA,EACT;AAEA,MAAI,SAAS,WAAW,UAAU;AAChC,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAKA,SAAS,oBACP,gBACA,gBACA,iBACA,SAC4B;AAC5B,QAAM,mBAAmB,eAAe,MAAM,CAAC,OAAO,GAAG,aAAa,MAAS;AAC/E,QAAM,eAAe,eAAe;AAAA,IAClC,CAAC,OAAO,GAAG,UAAU,GAAG,UAAU,iBAAiB;AAAA,EAAA;AAErD,QAAM,gBAAgB,eAAe;AAAA,IACnC,CAAC,OAAO,GAAG,UAAU,GAAG,UAAU,kBAAkB;AAAA,EAAA;AAGtD,MAAI,oBAAoB,aAAc,QAAO;AAC7C,MAAI,oBAAoB,cAAe,QAAO;AAC9C,MAAI,SAAS,WAAW,QAAS,QAAO;AACxC,MAAI,SAAS,WAAW,SAAU,QAAO;AACzC,SAAO;AACT;AAKA,SAAS,WACP,KACA,WACA,YACA,aACA,gBACA,iBACA,SACoD;AACpD,QAAM,eAAe,CAAC,UAAU,WAAW,UAAU;AACrD,QAAM,gBAAgB,CAAC,UAAU,WAAW,WAAW;AAEvD,MAAI,CAAC,gBAAgB,CAAC,eAAe;AACnC,WAAO,EAAE,OAAO,WAAW,UAAU,KAAA;AAAA,EACvC;AAEA,MAAI,gBAAgB,CAAC,eAAe;AAClC,WAAO,EAAE,OAAO,YAAY,UAAU,KAAA;AAAA,EACxC;AAEA,MAAI,CAAC,gBAAgB,eAAe;AAClC,WAAO,EAAE,OAAO,aAAa,UAAU,KAAA;AAAA,EACzC;AAGA,MAAI,UAAU,YAAY,WAAW,GAAG;AACtC,WAAO,EAAE,OAAO,YAAY,UAAU,KAAA;AAAA,EACxC;AAGA,QAAM,WAAW;AAAA,IACf;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAIF,MAAI,QAAQ,UAAU;AACpB,WAAO,EAAE,OAAO,UAAU,UAAU,KAAA;AAAA,EACtC;AAEA,SAAO;AAAA,IACL,OAAO;AAAA,IACP,UAAU;AAAA,MACR,OAAO;AAAA,MACP,MAAM;AAAA,MACN,OAAO;AAAA,MACP,QAAQ;AAAA,MACR;AAAA,IAAA;AAAA,EACF;AAEJ;AAKA,SAAS,UACP,MACA,OACA,QACA,SACoD;AACpD,QAAM,OAAO,YAAY,IAAI;AAC7B,QAAM,iBAAiB,aAAa,KAAK;AACzC,QAAM,kBAAkB,aAAa,MAAM;AAE3C,QAAM,SAAkB,EAAE,GAAG,KAAA;AAC7B,QAAM,iBAAkC,CAAA;AAGxC,QAAM,8BAAc,IAAY;AAAA,IAC9B,GAAG,OAAO,KAAK,IAAI;AAAA,IACnB,GAAG,OAAO,KAAK,KAAK;AAAA,IACpB,GAAG,OAAO,KAAK,MAAM;AAAA,EAAA,CACtB;AAED,aAAW,OAAO,SAAS;AACzB,UAAM,YAAa,KAAiC,GAAG;AACvD,UAAM,aAAc,MAAkC,GAAG;AACzD,UAAM,cAAe,OAAmC,GAAG;AAE3D,UAAM,EAAE,OAAO,SAAA,IAAa;AAAA,MAC1B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAGD,WAAmC,GAAG,IAAI;AAE3C,QAAI,UAAU;AACZ,qBAAe,KAAK,QAAQ;AAAA,IAC9B;AAAA,EACF;AAGA,MAAI,eAAe,SAAS,GAAG;AAC7B,UAAM,aAAa;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAGF,WAAO;AAAA,MACL;AAAA,MACA,UAAU;AAAA,QACR;AAAA,QACA,IAAI,KAAK,MAAM;AAAA,QACf,QAAQ;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,IACF;AAAA,EAEJ;AAEA,SAAO,EAAE,QAAQ,UAAU,KAAA;AAC7B;AAKA,SAAS,cAAc,MAAiB,OAAkB,QAAmB;AAC3E,QAAM,8BAAc,IAAA;AACpB,QAAM,+BAAe,IAAA;AACrB,QAAM,gCAAgB,IAAA;AAEtB,aAAW,QAAQ,MAAM;AACvB,YAAQ,IAAI,YAAY,IAAI,GAAG,IAAI;AAAA,EACrC;AACA,aAAW,QAAQ,OAAO;AACxB,aAAS,IAAI,YAAY,IAAI,GAAG,IAAI;AAAA,EACtC;AACA,aAAW,QAAQ,QAAQ;AACzB,cAAU,IAAI,YAAY,IAAI,GAAG,IAAI;AAAA,EACvC;AAEA,SAAO,EAAE,SAAS,UAAU,UAAA;AAC9B;AAKA,SAAS,kBACP,UACA,WACA,YACA,SACA,QACA,WACM;AACN,QAAM,EAAE,QAAQ,YAAY,SAAA,IAAa,UAAU,UAAU,WAAW,YAAY,OAAO;AAC3F,SAAO,KAAK,UAAU;AACtB,MAAI,UAAU;AACZ,cAAU,KAAK,QAAQ;AAAA,EACzB;AACF;AAKA,SAAS,mBACP,MACA,WACA,YACA,SACA,QACA,WACM;AACN,MAAI,UAAU,WAAW,UAAU,GAAG;AACpC,WAAO,KAAK,SAAS;AAAA,EACvB,OAAO;AACL,UAAM,gBAAyB;AAAA,MAC7B,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,QAAQ;AAAA,QACN;AAAA,QACA,YAAY;AAAA,QACZ,WAAW;AAAA,MAAA;AAAA,IACb;AAEF,UAAM,EAAE,QAAQ,YAAY,SAAA,IAAa;AAAA,MACvC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAEF,WAAO,KAAK,UAAU;AACtB,QAAI,UAAU;AACZ,gBAAU,KAAK,QAAQ;AAAA,IACzB;AAAA,EACF;AACF;AAKA,SAAS,YACP,MACA,SACA,UACA,WACA,SACA,QAQM;AACN,QAAM,WAAW,QAAQ,IAAI,IAAI;AACjC,QAAM,YAAY,SAAS,IAAI,IAAI;AACnC,QAAM,aAAa,UAAU,IAAI,IAAI;AAErC,MAAI,YAAY,aAAa,YAAY;AACvC,sBAAkB,UAAU,WAAW,YAAY,SAAS,OAAO,QAAQ,OAAO,SAAS;AAAA,EAC7F,WAAW,CAAC,YAAY,aAAa,YAAY;AAC/C,uBAAmB,MAAM,WAAW,YAAY,SAAS,OAAO,QAAQ,OAAO,SAAS;AAAA,EAC1F,WAAW,CAAC,YAAY,aAAa,CAAC,YAAY;AAChD,WAAO,OAAO,KAAK,SAAS;AAC5B,WAAO,UAAU,KAAK,SAAS;AAAA,EACjC,WAAW,CAAC,YAAY,CAAC,aAAa,YAAY;AAChD,WAAO,OAAO,KAAK,UAAU;AAC7B,WAAO,WAAW,KAAK,UAAU;AAAA,EACnC,WAAW,YAAY,CAAC,aAAa,YAAY;AAC/C,WAAO,eAAe,KAAK,QAAQ;AAAA,EACrC,WAAW,YAAY,aAAa,CAAC,YAAY;AAC/C,WAAO,gBAAgB,KAAK,QAAQ;AAAA,EACtC,WAAW,YAAY,CAAC,aAAa,CAAC,YAAY;AAChD,WAAO,eAAe,KAAK,QAAQ;AACnC,WAAO,gBAAgB,KAAK,QAAQ;AAAA,EACtC;AACF;AAWO,SAAS,cACd,MACA,OACA,QACA,SACa;AACb,QAAM,EAAE,SAAS,UAAU,UAAA,IAAc,cAAc,MAAM,OAAO,MAAM;AAE1E,QAAM,SAAS;AAAA,IACb,QAAQ,CAAA;AAAA,IACR,WAAW,CAAA;AAAA,IACX,WAAW,CAAA;AAAA,IACX,YAAY,CAAA;AAAA,IACZ,gBAAgB,CAAA;AAAA,IAChB,iBAAiB,CAAA;AAAA,EAAC;AAGpB,QAAM,WAAW,oBAAI,IAAY,CAAC,GAAG,QAAQ,KAAA,GAAQ,GAAG,SAAS,QAAQ,GAAG,UAAU,KAAA,CAAM,CAAC;AAE7F,aAAW,QAAQ,UAAU;AAC3B,gBAAY,MAAM,SAAS,UAAU,WAAW,SAAS,MAAM;AAAA,EACjE;AAGA,MAAI,SAAsB;AAC1B,MAAI,OAAO,UAAU,SAAS,GAAG;AAC/B,UAAM,gBAAgB,OAAO,UAAU,KAAK,CAAC,MAAM,EAAE,eAAe,YAAY;AAChF,aAAS,gBAAgB,aAAa;AAAA,EACxC;AAEA,SAAO;AAAA,IACL;AAAA,IACA,GAAG;AAAA,EAAA;AAEP;;;;;"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/core/csl-json/validator.ts","../src/utils/logger.ts","../src/utils/file.ts","../src/utils/backup.ts","../src/features/merge/three-way.ts"],"sourcesContent":["import { CslItemSchema, CslLibrarySchema } from \"./types\";\nimport type { CslItem, CslLibrary } from \"./types\";\n\n/**\n * Validate CSL-JSON library structure\n * @param data - Data to validate (can be any type)\n * @returns Validated CSL-JSON library\n * @throws Error if validation fails\n */\nexport function validateCslJson(data: unknown): CslLibrary {\n const parseResult = CslLibrarySchema.safeParse(data);\n\n if (!parseResult.success) {\n throw new Error(`Invalid CSL-JSON structure: ${parseResult.error.message}`);\n }\n\n return parseResult.data;\n}\n\n/**\n * Validate a single CSL-JSON item\n * @param data - Data to validate (can be any type)\n * @returns Validation result with valid flag and errors\n */\nexport function validateCslItem(data: unknown): {\n valid: boolean;\n data?: CslItem;\n errors?: string[];\n} {\n const parseResult = CslItemSchema.safeParse(data);\n\n if (!parseResult.success) {\n return {\n valid: false,\n errors: parseResult.error.issues.map((issue) => issue.message),\n };\n }\n\n return {\n valid: true,\n data: parseResult.data,\n };\n}\n","export type LogLevel = \"silent\" | \"info\" | \"debug\";\n\nexport interface Logger {\n info(...args: unknown[]): void;\n debug(...args: unknown[]): void;\n error(...args: unknown[]): void;\n}\n\nexport function createLogger(level: LogLevel = \"info\"): Logger {\n const shouldLogInfo = level === \"info\" || level === \"debug\";\n const shouldLogDebug = level === \"debug\";\n\n function formatMessage(...args: unknown[]): string {\n return `${args.map((arg) => String(arg)).join(\" \")}\\n`;\n }\n\n return {\n info(...args: unknown[]): void {\n if (shouldLogInfo) {\n process.stderr.write(formatMessage(...args));\n }\n },\n\n debug(...args: unknown[]): void {\n if (shouldLogDebug) {\n process.stderr.write(formatMessage(...args));\n }\n },\n\n error(...args: unknown[]): void {\n process.stderr.write(formatMessage(...args));\n },\n };\n}\n","import { mkdir } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport writeFileAtomicLib from \"write-file-atomic\";\n\n/**\n * Write file atomically with parent directory creation\n */\nexport async function writeFileAtomic(filePath: string, content: string): Promise<void> {\n await ensureDirectoryExists(dirname(filePath));\n await writeFileAtomicLib(filePath, content, { encoding: \"utf-8\" });\n}\n\n/**\n * Ensure directory exists, creating it recursively if necessary\n */\nexport async function ensureDirectoryExists(dirPath: string): Promise<void> {\n await mkdir(dirPath, { recursive: true });\n}\n","import { existsSync } from \"node:fs\";\nimport { copyFile, readFile, readdir, stat, unlink } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { ensureDirectoryExists } from \"./file\";\n\nexport interface BackupOptions {\n maxGenerations?: number;\n maxAgeMs?: number;\n}\n\nconst DEFAULT_MAX_GENERATIONS = 50;\nconst DEFAULT_MAX_AGE_MS = 365 * 24 * 60 * 60 * 1000; // 1 year\n\n/**\n * Get package name from package.json\n */\nasync function resolvePackageName(): Promise<string> {\n try {\n const currentFile = fileURLToPath(import.meta.url);\n let currentDir = dirname(currentFile);\n\n for (let i = 0; i < 10; i++) {\n const packageJsonPath = join(currentDir, \"package.json\");\n if (existsSync(packageJsonPath)) {\n const content = await readFile(packageJsonPath, \"utf-8\");\n const pkg = JSON.parse(content);\n return pkg.name;\n }\n currentDir = dirname(currentDir);\n }\n } catch {\n // Fall back to hardcoded name if package.json is not found\n }\n\n return \"reference-manager\";\n}\n\nconst packageName = await resolvePackageName();\n\n/**\n * Get backup directory path for a library\n */\nexport function getBackupDirectory(libraryName: string): string {\n const pkgName = packageName ?? \"reference-manager\";\n return join(tmpdir(), pkgName, \"backups\", libraryName);\n}\n\n/**\n * Create a backup of the given file\n */\nexport async function createBackup(sourceFile: string, libraryName: string): Promise<string> {\n const backupDir = getBackupDirectory(libraryName);\n await ensureDirectoryExists(backupDir);\n\n const timestamp = Date.now();\n const backupFileName = `${timestamp}.backup`;\n const backupPath = join(backupDir, backupFileName);\n\n await copyFile(sourceFile, backupPath);\n\n return backupPath;\n}\n\n/**\n * List all backups for a library (sorted by modification time, newest first)\n */\nexport async function listBackups(libraryName: string): Promise<string[]> {\n const backupDir = getBackupDirectory(libraryName);\n\n if (!existsSync(backupDir)) {\n return [];\n }\n\n const files = await readdir(backupDir);\n const backupFiles = files.filter((f) => f.endsWith(\".backup\")).map((f) => join(backupDir, f));\n\n const filesWithStats = await Promise.all(\n backupFiles.map(async (file) => {\n const stats = await stat(file);\n return { file, mtime: stats.mtimeMs };\n })\n );\n\n filesWithStats.sort((a, b) => b.mtime - a.mtime);\n\n return filesWithStats.map((f) => f.file);\n}\n\n/**\n * Clean up old backups based on generation count and age\n */\nexport async function cleanupOldBackups(\n libraryName: string,\n options?: BackupOptions\n): Promise<void> {\n const maxGenerations = options?.maxGenerations ?? DEFAULT_MAX_GENERATIONS;\n const maxAgeMs = options?.maxAgeMs ?? DEFAULT_MAX_AGE_MS;\n\n const backups = await listBackups(libraryName);\n const now = Date.now();\n\n const backupsToDelete: string[] = [];\n\n for (let i = 0; i < backups.length; i++) {\n const backupPath = backups[i];\n if (!backupPath) continue;\n\n const stats = await stat(backupPath);\n const age = now - stats.mtimeMs;\n\n if (i >= maxGenerations || age > maxAgeMs) {\n backupsToDelete.push(backupPath);\n }\n }\n\n await Promise.all(backupsToDelete.map((backup) => unlink(backup)));\n}\n","/**\n * 3-way merge implementation with Last-Write-Wins (LWW) strategy\n */\n\nimport type { CslItem } from \"../../core/csl-json/types.js\";\nimport type {\n FieldConflict,\n ItemConflict,\n MergeOptions,\n MergeResult,\n MergeStatus,\n} from \"./types.js\";\n\n/**\n * Get UUID from item, with fallback to id if uuid is missing\n */\nfunction getItemUuid(item: CslItem): string {\n return item.custom?.uuid || item.id || \"unknown\";\n}\n\n/**\n * Get timestamp from item, with fallback to created_at\n */\nfunction getTimestamp(item: CslItem): string {\n return item.custom?.timestamp || item.custom?.created_at || \"1970-01-01T00:00:00.000Z\";\n}\n\n/**\n * Deep equality check for field values\n */\nfunction deepEqual(a: unknown, b: unknown): boolean {\n return JSON.stringify(a) === JSON.stringify(b);\n}\n\n/**\n * Resolve a field conflict using LWW or prefer option\n */\nfunction resolveFieldConflict(\n localValue: unknown,\n remoteValue: unknown,\n localTimestamp: string,\n remoteTimestamp: string,\n options?: MergeOptions\n): unknown {\n if (localTimestamp > remoteTimestamp) {\n return localValue;\n }\n if (remoteTimestamp > localTimestamp) {\n return remoteValue;\n }\n // Timestamps equal: use prefer option or default to local\n if (options?.prefer === \"remote\") {\n return remoteValue;\n }\n return localValue;\n}\n\n/**\n * Determine conflict resolution type\n */\nfunction determineResolution(\n fieldConflicts: FieldConflict[],\n localTimestamp: string,\n remoteTimestamp: string,\n options?: MergeOptions\n): ItemConflict[\"resolution\"] {\n const hasRealConflicts = fieldConflicts.every((fc) => fc.resolved !== undefined);\n const localIsNewer = fieldConflicts.some(\n (fc) => fc.local !== fc.remote && localTimestamp > remoteTimestamp\n );\n const remoteIsNewer = fieldConflicts.some(\n (fc) => fc.local !== fc.remote && remoteTimestamp > localTimestamp\n );\n\n if (hasRealConflicts && localIsNewer) return \"auto-lww\";\n if (hasRealConflicts && remoteIsNewer) return \"auto-lww\";\n if (options?.prefer === \"local\") return \"prefer-local\";\n if (options?.prefer === \"remote\") return \"prefer-remote\";\n return \"unresolved\";\n}\n\n/**\n * Merge a single field from base, local, and remote versions\n */\nfunction mergeField(\n key: string,\n baseValue: unknown,\n localValue: unknown,\n remoteValue: unknown,\n localTimestamp: string,\n remoteTimestamp: string,\n options?: MergeOptions\n): { value: unknown; conflict: FieldConflict | null } {\n const localChanged = !deepEqual(baseValue, localValue);\n const remoteChanged = !deepEqual(baseValue, remoteValue);\n\n if (!localChanged && !remoteChanged) {\n return { value: baseValue, conflict: null };\n }\n\n if (localChanged && !remoteChanged) {\n return { value: localValue, conflict: null };\n }\n\n if (!localChanged && remoteChanged) {\n return { value: remoteValue, conflict: null };\n }\n\n // Both changed\n if (deepEqual(localValue, remoteValue)) {\n return { value: localValue, conflict: null };\n }\n\n // Both changed to different values\n const resolved = resolveFieldConflict(\n localValue,\n remoteValue,\n localTimestamp,\n remoteTimestamp,\n options\n );\n\n // Don't record conflicts for 'custom' metadata field\n if (key === \"custom\") {\n return { value: resolved, conflict: null };\n }\n\n return {\n value: resolved,\n conflict: {\n field: key,\n base: baseValue,\n local: localValue,\n remote: remoteValue,\n resolved,\n },\n };\n}\n\n/**\n * Merge a single item from base, local, and remote versions\n */\nfunction mergeItem(\n base: CslItem,\n local: CslItem,\n remote: CslItem,\n options?: MergeOptions\n): { merged: CslItem; conflict: ItemConflict | null } {\n const uuid = getItemUuid(base);\n const localTimestamp = getTimestamp(local);\n const remoteTimestamp = getTimestamp(remote);\n\n const merged: CslItem = { ...base };\n const fieldConflicts: FieldConflict[] = [];\n\n // Get all unique keys from all three versions\n const allKeys = new Set<string>([\n ...Object.keys(base),\n ...Object.keys(local),\n ...Object.keys(remote),\n ]);\n\n for (const key of allKeys) {\n const baseValue = (base as Record<string, unknown>)[key];\n const localValue = (local as Record<string, unknown>)[key];\n const remoteValue = (remote as Record<string, unknown>)[key];\n\n const { value, conflict } = mergeField(\n key,\n baseValue,\n localValue,\n remoteValue,\n localTimestamp,\n remoteTimestamp,\n options\n );\n\n (merged as Record<string, unknown>)[key] = value;\n\n if (conflict) {\n fieldConflicts.push(conflict);\n }\n }\n\n // If there are field conflicts, create ItemConflict\n if (fieldConflicts.length > 0) {\n const resolution = determineResolution(\n fieldConflicts,\n localTimestamp,\n remoteTimestamp,\n options\n );\n\n return {\n merged,\n conflict: {\n uuid,\n id: base.id || \"unknown\",\n fields: fieldConflicts,\n localTimestamp,\n remoteTimestamp,\n resolution,\n },\n };\n }\n\n return { merged, conflict: null };\n}\n\n/**\n * Build UUID-indexed maps from item arrays\n */\nfunction buildItemMaps(base: CslItem[], local: CslItem[], remote: CslItem[]) {\n const baseMap = new Map<string, CslItem>();\n const localMap = new Map<string, CslItem>();\n const remoteMap = new Map<string, CslItem>();\n\n for (const item of base) {\n baseMap.set(getItemUuid(item), item);\n }\n for (const item of local) {\n localMap.set(getItemUuid(item), item);\n }\n for (const item of remote) {\n remoteMap.set(getItemUuid(item), item);\n }\n\n return { baseMap, localMap, remoteMap };\n}\n\n/**\n * Handle items that exist in all three versions\n */\nfunction mergeExistingItem(\n baseItem: CslItem,\n localItem: CslItem,\n remoteItem: CslItem,\n options: MergeOptions | undefined,\n merged: CslItem[],\n conflicts: ItemConflict[]\n): void {\n const { merged: mergedItem, conflict } = mergeItem(baseItem, localItem, remoteItem, options);\n merged.push(mergedItem);\n if (conflict) {\n conflicts.push(conflict);\n }\n}\n\n/**\n * Handle items added in both local and remote\n */\nfunction handleDualAddition(\n uuid: string,\n localItem: CslItem,\n remoteItem: CslItem,\n options: MergeOptions | undefined,\n merged: CslItem[],\n conflicts: ItemConflict[]\n): void {\n if (deepEqual(localItem, remoteItem)) {\n merged.push(localItem);\n } else {\n const syntheticBase: CslItem = {\n id: uuid,\n type: \"article\",\n custom: {\n uuid,\n created_at: \"1970-01-01T00:00:00.000Z\",\n timestamp: \"1970-01-01T00:00:00.000Z\",\n },\n };\n const { merged: mergedItem, conflict } = mergeItem(\n syntheticBase,\n localItem,\n remoteItem,\n options\n );\n merged.push(mergedItem);\n if (conflict) {\n conflicts.push(conflict);\n }\n }\n}\n\n/**\n * Process a single UUID across all three versions\n */\nfunction processItem(\n uuid: string,\n baseMap: Map<string, CslItem>,\n localMap: Map<string, CslItem>,\n remoteMap: Map<string, CslItem>,\n options: MergeOptions | undefined,\n result: {\n merged: CslItem[];\n conflicts: ItemConflict[];\n localOnly: CslItem[];\n remoteOnly: CslItem[];\n deletedInLocal: CslItem[];\n deletedInRemote: CslItem[];\n }\n): void {\n const baseItem = baseMap.get(uuid);\n const localItem = localMap.get(uuid);\n const remoteItem = remoteMap.get(uuid);\n\n if (baseItem && localItem && remoteItem) {\n mergeExistingItem(baseItem, localItem, remoteItem, options, result.merged, result.conflicts);\n } else if (!baseItem && localItem && remoteItem) {\n handleDualAddition(uuid, localItem, remoteItem, options, result.merged, result.conflicts);\n } else if (!baseItem && localItem && !remoteItem) {\n result.merged.push(localItem);\n result.localOnly.push(localItem);\n } else if (!baseItem && !localItem && remoteItem) {\n result.merged.push(remoteItem);\n result.remoteOnly.push(remoteItem);\n } else if (baseItem && !localItem && remoteItem) {\n result.deletedInLocal.push(baseItem);\n } else if (baseItem && localItem && !remoteItem) {\n result.deletedInRemote.push(baseItem);\n } else if (baseItem && !localItem && !remoteItem) {\n result.deletedInLocal.push(baseItem);\n result.deletedInRemote.push(baseItem);\n }\n}\n\n/**\n * Performs a 3-way merge of CSL-JSON items\n *\n * @param base - Base version (common ancestor)\n * @param local - Local version (current working copy)\n * @param remote - Remote version (incoming changes)\n * @param options - Merge options (e.g., prefer local/remote for tie-breaking)\n * @returns Merge result with merged items and conflict information\n */\nexport function threeWayMerge(\n base: CslItem[],\n local: CslItem[],\n remote: CslItem[],\n options?: MergeOptions\n): MergeResult {\n const { baseMap, localMap, remoteMap } = buildItemMaps(base, local, remote);\n\n const result = {\n merged: [] as CslItem[],\n conflicts: [] as ItemConflict[],\n localOnly: [] as CslItem[],\n remoteOnly: [] as CslItem[],\n deletedInLocal: [] as CslItem[],\n deletedInRemote: [] as CslItem[],\n };\n\n const allUuids = new Set<string>([...baseMap.keys(), ...localMap.keys(), ...remoteMap.keys()]);\n\n for (const uuid of allUuids) {\n processItem(uuid, baseMap, localMap, remoteMap, options, result);\n }\n\n // Determine overall status\n let status: MergeStatus = \"success\";\n if (result.conflicts.length > 0) {\n const hasUnresolved = result.conflicts.some((c) => c.resolution === \"unresolved\");\n status = hasUnresolved ? \"conflict\" : \"auto-resolved\";\n }\n\n return {\n status,\n ...result,\n };\n}\n"],"names":["i","f"],"mappings":"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"}
|
package/dist/server.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "hono";
|
|
2
|
-
import "./chunks/file-watcher-
|
|
3
|
-
import { c, s } from "./chunks/index-
|
|
2
|
+
import "./chunks/file-watcher-DdhXSm1l.js";
|
|
3
|
+
import { c, s } from "./chunks/index-DmMZCOno.js";
|
|
4
4
|
export {
|
|
5
5
|
c as createServer,
|
|
6
6
|
s as startServerWithFileWatcher
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -3,4 +3,5 @@ export { computeHash, computeFileHash } from "./hash";
|
|
|
3
3
|
export { writeFileAtomic, ensureDirectoryExists } from "./file";
|
|
4
4
|
export { createBackup, cleanupOldBackups, getBackupDirectory, listBackups, type BackupOptions, } from "./backup";
|
|
5
5
|
export { pickDefined } from "./object";
|
|
6
|
+
export { getOpenerCommand, openWithSystemApp } from "./opener";
|
|
6
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,MAAM,EAAE,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,QAAQ,CAAC;AAChE,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,kBAAkB,EAClB,WAAW,EACX,KAAK,aAAa,GACnB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,MAAM,EAAE,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,QAAQ,CAAC;AAChE,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,kBAAkB,EAClB,WAAW,EACX,KAAK,aAAa,GACnB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get the system opener command for the specified platform.
|
|
3
|
+
* @param platform - The platform (darwin, linux, win32)
|
|
4
|
+
* @returns The command array to execute
|
|
5
|
+
*/
|
|
6
|
+
export declare function getOpenerCommand(platform: string): string[];
|
|
7
|
+
/**
|
|
8
|
+
* Open a file with the system's default application.
|
|
9
|
+
* @param filePath - The path to the file to open
|
|
10
|
+
* @param platform - The platform (defaults to process.platform)
|
|
11
|
+
*/
|
|
12
|
+
export declare function openWithSystemApp(filePath: string, platform?: string): Promise<void>;
|
|
13
|
+
//# sourceMappingURL=opener.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opener.d.ts","sourceRoot":"","sources":["../../src/utils/opener.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAW3D;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,MAAM,EAChB,QAAQ,GAAE,MAAyB,GAClC,OAAO,CAAC,IAAI,CAAC,CAyBf"}
|