@ncukondo/reference-manager 0.24.1 → 0.26.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 +53 -1
- package/dist/chunks/{SearchableMultiSelect-CKRfbnka.js → SearchableMultiSelect-D2IzthN4.js} +2 -2
- package/dist/chunks/{SearchableMultiSelect-CKRfbnka.js.map → SearchableMultiSelect-D2IzthN4.js.map} +1 -1
- package/dist/chunks/{action-menu-BCgv1m3v.js → action-menu-DWdoHTFh.js} +3 -3
- package/dist/chunks/{action-menu-BCgv1m3v.js.map → action-menu-DWdoHTFh.js.map} +1 -1
- package/dist/chunks/checker-CKfdG8Ia.js +170 -0
- package/dist/chunks/checker-CKfdG8Ia.js.map +1 -0
- package/dist/chunks/crossref-client-Gs75LMVf.js +94 -0
- package/dist/chunks/crossref-client-Gs75LMVf.js.map +1 -0
- package/dist/chunks/fix-interaction-DNXbmlPr.js +262 -0
- package/dist/chunks/fix-interaction-DNXbmlPr.js.map +1 -0
- package/dist/chunks/{index-JA964gjc.js → index-BEQ4YIXx.js} +356 -27
- package/dist/chunks/index-BEQ4YIXx.js.map +1 -0
- package/dist/chunks/{index-zafRwZEZ.js → index-k67fQbe4.js} +3 -3
- package/dist/chunks/index-k67fQbe4.js.map +1 -0
- package/dist/chunks/{index-DWAtvFtp.js → index-of6eJn8N.js} +209 -21
- package/dist/chunks/index-of6eJn8N.js.map +1 -0
- package/dist/chunks/{index-C36Us_zC.js → index-tdmbNN9b.js} +4 -4
- package/dist/chunks/{index-C36Us_zC.js.map → index-tdmbNN9b.js.map} +1 -1
- package/dist/chunks/{loader-CV71qNY2.js → loader-B-fte1uv.js} +19 -8
- package/dist/chunks/loader-B-fte1uv.js.map +1 -0
- package/dist/chunks/metadata-comparator-C5zfoYdK.js +137 -0
- package/dist/chunks/metadata-comparator-C5zfoYdK.js.map +1 -0
- package/dist/chunks/pubmed-client-CGReJIOz.js +51 -0
- package/dist/chunks/pubmed-client-CGReJIOz.js.map +1 -0
- package/dist/chunks/{reference-select-Bbl-roAS.js → reference-select-i1Cnmc16.js} +3 -3
- package/dist/chunks/{reference-select-Bbl-roAS.js.map → reference-select-i1Cnmc16.js.map} +1 -1
- package/dist/chunks/{style-select-BeAktUts.js → style-select-COnY01qb.js} +3 -3
- package/dist/chunks/{style-select-BeAktUts.js.map → style-select-COnY01qb.js.map} +1 -1
- package/dist/cli/commands/check.d.ts +43 -0
- package/dist/cli/commands/check.d.ts.map +1 -0
- package/dist/cli/commands/index.d.ts +2 -0
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/server-client.d.ts +2 -1
- package/dist/cli/server-client.d.ts.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/env-override.d.ts.map +1 -1
- package/dist/config/key-parser.d.ts.map +1 -1
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/schema.d.ts +3 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/features/check/checker.d.ts +19 -0
- package/dist/features/check/checker.d.ts.map +1 -0
- package/dist/features/check/crossref-client.d.ts +40 -0
- package/dist/features/check/crossref-client.d.ts.map +1 -0
- package/dist/features/check/fix-actions.d.ts +16 -0
- package/dist/features/check/fix-actions.d.ts.map +1 -0
- package/dist/features/check/fix-interaction.d.ts +11 -0
- package/dist/features/check/fix-interaction.d.ts.map +1 -0
- package/dist/features/check/metadata-comparator.d.ts +37 -0
- package/dist/features/check/metadata-comparator.d.ts.map +1 -0
- package/dist/features/check/metadata-similarity.d.ts +22 -0
- package/dist/features/check/metadata-similarity.d.ts.map +1 -0
- package/dist/features/check/pubmed-client.d.ts +20 -0
- package/dist/features/check/pubmed-client.d.ts.map +1 -0
- package/dist/features/check/types.d.ts +28 -0
- package/dist/features/check/types.d.ts.map +1 -0
- package/dist/features/operations/check.d.ts +29 -0
- package/dist/features/operations/check.d.ts.map +1 -0
- package/dist/features/operations/index.d.ts +1 -0
- package/dist/features/operations/index.d.ts.map +1 -1
- package/dist/features/operations/library-operations.d.ts +8 -0
- package/dist/features/operations/library-operations.d.ts.map +1 -1
- package/dist/features/operations/operations-library.d.ts +2 -0
- package/dist/features/operations/operations-library.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/mcp/tools/check.d.ts +11 -0
- package/dist/mcp/tools/check.d.ts.map +1 -0
- package/dist/mcp/tools/index.d.ts.map +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/routes/check.d.ts +4 -0
- package/dist/server/routes/check.d.ts.map +1 -0
- package/dist/server.js +3 -3
- package/package.json +1 -1
- package/dist/chunks/index-DWAtvFtp.js.map +0 -1
- package/dist/chunks/index-JA964gjc.js.map +0 -1
- package/dist/chunks/index-zafRwZEZ.js.map +0 -1
- package/dist/chunks/loader-CV71qNY2.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a } from "./index-
|
|
2
|
-
import { d, g, l, o, s } from "./index-
|
|
1
|
+
import { a } from "./index-of6eJn8N.js";
|
|
2
|
+
import { d, g, l, o, s } from "./index-BEQ4YIXx.js";
|
|
3
3
|
export {
|
|
4
4
|
a as addAttachment,
|
|
5
5
|
d as detachAttachment,
|
|
@@ -8,4 +8,4 @@ export {
|
|
|
8
8
|
o as openAttachment,
|
|
9
9
|
s as syncAttachments
|
|
10
10
|
};
|
|
11
|
-
//# sourceMappingURL=index-
|
|
11
|
+
//# sourceMappingURL=index-k67fQbe4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-k67fQbe4.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
|
|
@@ -11342,6 +11342,12 @@ async function fetchIsbn(isbn) {
|
|
|
11342
11342
|
};
|
|
11343
11343
|
}
|
|
11344
11344
|
}
|
|
11345
|
+
const fetcher = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
11346
|
+
__proto__: null,
|
|
11347
|
+
fetchDoi,
|
|
11348
|
+
fetchIsbn,
|
|
11349
|
+
fetchPmids
|
|
11350
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
11345
11351
|
function parseBibtex(content) {
|
|
11346
11352
|
return parseWithCitationJs(content, "bibtex");
|
|
11347
11353
|
}
|
|
@@ -12064,6 +12070,183 @@ function createAddRoute(library, config) {
|
|
|
12064
12070
|
});
|
|
12065
12071
|
return route;
|
|
12066
12072
|
}
|
|
12073
|
+
const CHECK_CONCURRENCY = 5;
|
|
12074
|
+
async function checkReferences(library, options) {
|
|
12075
|
+
const { checkReference } = await import("./checker-CKfdG8Ia.js");
|
|
12076
|
+
const save = options.save !== false;
|
|
12077
|
+
const skipDays = options.skipDays ?? 7;
|
|
12078
|
+
const items = await resolveItems(library, options);
|
|
12079
|
+
const tasks = items.map((item, index) => ({
|
|
12080
|
+
index,
|
|
12081
|
+
item,
|
|
12082
|
+
skip: shouldSkipRecentCheck(item, skipDays)
|
|
12083
|
+
}));
|
|
12084
|
+
const results = new Array(items.length);
|
|
12085
|
+
fillSkippedResults(tasks, results);
|
|
12086
|
+
const toCheck = tasks.filter((t) => !t.skip);
|
|
12087
|
+
const checkConfig = {
|
|
12088
|
+
...options.config,
|
|
12089
|
+
...options.metadata !== void 0 ? { metadata: options.metadata } : {}
|
|
12090
|
+
};
|
|
12091
|
+
await checkInParallel(toCheck, results, checkReference, checkConfig);
|
|
12092
|
+
if (save) {
|
|
12093
|
+
await saveAllResults(library, toCheck, results);
|
|
12094
|
+
}
|
|
12095
|
+
return { results, summary: computeSummary(results) };
|
|
12096
|
+
}
|
|
12097
|
+
function fillSkippedResults(tasks, results) {
|
|
12098
|
+
for (const task of tasks) {
|
|
12099
|
+
if (task.skip) {
|
|
12100
|
+
results[task.index] = {
|
|
12101
|
+
id: task.item.id,
|
|
12102
|
+
uuid: task.item.custom?.uuid ?? "",
|
|
12103
|
+
status: "skipped",
|
|
12104
|
+
findings: [],
|
|
12105
|
+
checkedAt: task.item.custom?.check?.checked_at,
|
|
12106
|
+
checkedSources: []
|
|
12107
|
+
};
|
|
12108
|
+
}
|
|
12109
|
+
}
|
|
12110
|
+
}
|
|
12111
|
+
async function checkInParallel(tasks, results, checkFn, config) {
|
|
12112
|
+
for (let i = 0; i < tasks.length; i += CHECK_CONCURRENCY) {
|
|
12113
|
+
const chunk = tasks.slice(i, i + CHECK_CONCURRENCY);
|
|
12114
|
+
const settled = await Promise.allSettled(chunk.map((task) => checkFn(task.item, config)));
|
|
12115
|
+
for (const [j, task] of chunk.entries()) {
|
|
12116
|
+
const outcome = settled[j];
|
|
12117
|
+
results[task.index] = outcome?.status === "fulfilled" ? outcome.value : buildFallbackResult(task.item);
|
|
12118
|
+
}
|
|
12119
|
+
}
|
|
12120
|
+
}
|
|
12121
|
+
function buildFallbackResult(item) {
|
|
12122
|
+
return {
|
|
12123
|
+
id: item.id,
|
|
12124
|
+
uuid: item.custom?.uuid ?? "",
|
|
12125
|
+
status: "ok",
|
|
12126
|
+
findings: [],
|
|
12127
|
+
checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
12128
|
+
checkedSources: []
|
|
12129
|
+
};
|
|
12130
|
+
}
|
|
12131
|
+
async function saveAllResults(library, tasks, results) {
|
|
12132
|
+
for (const task of tasks) {
|
|
12133
|
+
const result = results[task.index];
|
|
12134
|
+
if (result.status !== "skipped") {
|
|
12135
|
+
await saveCheckResult(library, task.item, result);
|
|
12136
|
+
}
|
|
12137
|
+
}
|
|
12138
|
+
if (results.some((r) => r.status !== "skipped")) {
|
|
12139
|
+
await library.save();
|
|
12140
|
+
}
|
|
12141
|
+
}
|
|
12142
|
+
async function resolveItems(library, options) {
|
|
12143
|
+
if (options.all) {
|
|
12144
|
+
return library.getAll();
|
|
12145
|
+
}
|
|
12146
|
+
if (options.searchQuery) {
|
|
12147
|
+
const { searchReferences: searchReferences2 } = await Promise.resolve().then(() => search);
|
|
12148
|
+
const result = await searchReferences2(library, { query: options.searchQuery });
|
|
12149
|
+
return result.items;
|
|
12150
|
+
}
|
|
12151
|
+
if (options.identifiers && options.identifiers.length > 0) {
|
|
12152
|
+
const idType = options.idType ?? "id";
|
|
12153
|
+
const items = [];
|
|
12154
|
+
for (const identifier of options.identifiers) {
|
|
12155
|
+
const item = await library.find(identifier, { idType });
|
|
12156
|
+
if (!item) {
|
|
12157
|
+
throw new Error(`Reference not found: ${identifier}`);
|
|
12158
|
+
}
|
|
12159
|
+
items.push(item);
|
|
12160
|
+
}
|
|
12161
|
+
return items;
|
|
12162
|
+
}
|
|
12163
|
+
return [];
|
|
12164
|
+
}
|
|
12165
|
+
function shouldSkipRecentCheck(item, skipDays) {
|
|
12166
|
+
if (skipDays <= 0) return false;
|
|
12167
|
+
const check2 = item.custom?.check;
|
|
12168
|
+
if (!check2?.checked_at) return false;
|
|
12169
|
+
const checkedAt = new Date(check2.checked_at);
|
|
12170
|
+
const now = /* @__PURE__ */ new Date();
|
|
12171
|
+
const daysSince = (now.getTime() - checkedAt.getTime()) / (1e3 * 60 * 60 * 24);
|
|
12172
|
+
return daysSince < skipDays;
|
|
12173
|
+
}
|
|
12174
|
+
async function saveCheckResult(library, item, result) {
|
|
12175
|
+
const checkData = {
|
|
12176
|
+
checked_at: result.checkedAt,
|
|
12177
|
+
status: result.status === "warning" ? result.findings[0]?.type ?? "warning" : result.status,
|
|
12178
|
+
findings: result.findings.map((f) => ({
|
|
12179
|
+
type: f.type,
|
|
12180
|
+
message: f.message,
|
|
12181
|
+
...f.details ? { details: snakeCaseKeys(f.details) } : {}
|
|
12182
|
+
}))
|
|
12183
|
+
};
|
|
12184
|
+
const existingCustom = item.custom ?? {};
|
|
12185
|
+
await library.update(item.id, {
|
|
12186
|
+
custom: { ...existingCustom, check: checkData }
|
|
12187
|
+
});
|
|
12188
|
+
}
|
|
12189
|
+
function snakeCaseKeys(obj) {
|
|
12190
|
+
const result = {};
|
|
12191
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
12192
|
+
const snakeKey = key.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
|
|
12193
|
+
result[snakeKey] = value;
|
|
12194
|
+
}
|
|
12195
|
+
return result;
|
|
12196
|
+
}
|
|
12197
|
+
function computeSummary(results) {
|
|
12198
|
+
return {
|
|
12199
|
+
total: results.length,
|
|
12200
|
+
ok: results.filter((r) => r.status === "ok").length,
|
|
12201
|
+
warnings: results.filter((r) => r.status === "warning").length,
|
|
12202
|
+
skipped: results.filter((r) => r.status === "skipped").length
|
|
12203
|
+
};
|
|
12204
|
+
}
|
|
12205
|
+
const check = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
12206
|
+
__proto__: null,
|
|
12207
|
+
checkReferences
|
|
12208
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
12209
|
+
const CheckRequestSchema = z.object({
|
|
12210
|
+
identifiers: z.array(z.string()).optional(),
|
|
12211
|
+
idType: z.enum(["id", "uuid"]).optional(),
|
|
12212
|
+
all: z.boolean().optional(),
|
|
12213
|
+
searchQuery: z.string().optional(),
|
|
12214
|
+
skipDays: z.number().optional(),
|
|
12215
|
+
save: z.boolean().optional(),
|
|
12216
|
+
metadata: z.boolean().optional()
|
|
12217
|
+
}).refine((data) => data.identifiers?.length || data.all || data.searchQuery, {
|
|
12218
|
+
message: "Must provide identifiers, all, or searchQuery"
|
|
12219
|
+
});
|
|
12220
|
+
function buildCheckOptions(data) {
|
|
12221
|
+
const options = {};
|
|
12222
|
+
if (data.identifiers?.length) options.identifiers = data.identifiers;
|
|
12223
|
+
if (data.idType) options.idType = data.idType;
|
|
12224
|
+
if (data.all) options.all = true;
|
|
12225
|
+
if (data.searchQuery) options.searchQuery = data.searchQuery;
|
|
12226
|
+
if (data.skipDays !== void 0) options.skipDays = data.skipDays;
|
|
12227
|
+
if (data.save !== void 0) options.save = data.save;
|
|
12228
|
+
if (data.metadata !== void 0) options.metadata = data.metadata;
|
|
12229
|
+
return options;
|
|
12230
|
+
}
|
|
12231
|
+
function createCheckRoute(library) {
|
|
12232
|
+
const route = new Hono();
|
|
12233
|
+
route.post("/", async (c) => {
|
|
12234
|
+
let rawBody;
|
|
12235
|
+
try {
|
|
12236
|
+
rawBody = await c.req.json();
|
|
12237
|
+
} catch {
|
|
12238
|
+
return c.json({ error: "Invalid JSON" }, 400);
|
|
12239
|
+
}
|
|
12240
|
+
const parseResult = CheckRequestSchema.safeParse(rawBody);
|
|
12241
|
+
if (!parseResult.success) {
|
|
12242
|
+
const errorMessage = parseResult.error.issues[0]?.message ?? "Invalid request body";
|
|
12243
|
+
return c.json({ error: errorMessage }, 400);
|
|
12244
|
+
}
|
|
12245
|
+
const result = await checkReferences(library, buildCheckOptions(parseResult.data));
|
|
12246
|
+
return c.json(result);
|
|
12247
|
+
});
|
|
12248
|
+
return route;
|
|
12249
|
+
}
|
|
12067
12250
|
function shouldUseFallback(style, hasCustomXml) {
|
|
12068
12251
|
if (hasCustomXml) {
|
|
12069
12252
|
return false;
|
|
@@ -12506,6 +12689,8 @@ function createServer(library, config) {
|
|
|
12506
12689
|
app.route("/api/list", listRoute);
|
|
12507
12690
|
const searchRoute = createSearchRoute(library);
|
|
12508
12691
|
app.route("/api/search", searchRoute);
|
|
12692
|
+
const checkRoute = createCheckRoute(library);
|
|
12693
|
+
app.route("/api/check", checkRoute);
|
|
12509
12694
|
return app;
|
|
12510
12695
|
}
|
|
12511
12696
|
async function startServerWithFileWatcher(libraryPath, config) {
|
|
@@ -12534,34 +12719,37 @@ async function startServerWithFileWatcher(libraryPath, config) {
|
|
|
12534
12719
|
};
|
|
12535
12720
|
}
|
|
12536
12721
|
export {
|
|
12537
|
-
|
|
12722
|
+
check as A,
|
|
12538
12723
|
BUILTIN_STYLES as B,
|
|
12724
|
+
cite as C,
|
|
12725
|
+
list as D,
|
|
12726
|
+
search as E,
|
|
12539
12727
|
RESERVED_ROLES as R,
|
|
12540
12728
|
addAttachment as a,
|
|
12541
|
-
|
|
12542
|
-
|
|
12729
|
+
generateFilename as b,
|
|
12730
|
+
findFulltextFiles as c,
|
|
12543
12731
|
deleteDirectoryIfEmpty as d,
|
|
12544
12732
|
ensureDirectory as e,
|
|
12545
12733
|
formatBibliographyCSL as f,
|
|
12546
|
-
|
|
12547
|
-
|
|
12734
|
+
getRateLimiter as g,
|
|
12735
|
+
findFulltextFile as h,
|
|
12548
12736
|
isReservedRole as i,
|
|
12549
|
-
|
|
12550
|
-
|
|
12551
|
-
|
|
12552
|
-
|
|
12737
|
+
extensionToFormat as j,
|
|
12738
|
+
fulltextAttach as k,
|
|
12739
|
+
fulltextGet as l,
|
|
12740
|
+
fulltextDiscover as m,
|
|
12553
12741
|
normalizePathForOutput as n,
|
|
12554
|
-
|
|
12742
|
+
fulltextFetch as o,
|
|
12555
12743
|
parseFilename as p,
|
|
12556
|
-
|
|
12557
|
-
|
|
12558
|
-
|
|
12559
|
-
|
|
12560
|
-
|
|
12561
|
-
|
|
12562
|
-
|
|
12563
|
-
|
|
12564
|
-
|
|
12565
|
-
|
|
12744
|
+
fulltextConvert as q,
|
|
12745
|
+
getExtension as r,
|
|
12746
|
+
getDefaultExportFromCjs as s,
|
|
12747
|
+
getFulltextAttachmentTypes as t,
|
|
12748
|
+
startServerWithFileWatcher as u,
|
|
12749
|
+
createServer as v,
|
|
12750
|
+
fetch$1 as w,
|
|
12751
|
+
remove as x,
|
|
12752
|
+
fetcher as y,
|
|
12753
|
+
add as z
|
|
12566
12754
|
};
|
|
12567
|
-
//# sourceMappingURL=index-
|
|
12755
|
+
//# sourceMappingURL=index-of6eJn8N.js.map
|