@ncukondo/reference-manager 0.15.2 → 0.15.3

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.
@@ -1,4 +1,4 @@
1
- import { f as formatBibtex } from "./index-BIFsFHVj.js";
1
+ import { f as formatBibtex } from "./index-TKhWlXl1.js";
2
2
  import { f as formatBibliographyCSL } from "./index-DHgeuWGP.js";
3
3
  const ACTION_CHOICES = [
4
4
  { name: "output-ids", message: "Output IDs (citation keys)", value: "output-ids" },
@@ -116,4 +116,4 @@ export {
116
116
  runActionMenu,
117
117
  runStyleSelectPrompt
118
118
  };
119
- //# sourceMappingURL=action-menu-CLBXtpmg.js.map
119
+ //# sourceMappingURL=action-menu-yzuB0WT3.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"action-menu-CLBXtpmg.js","sources":["../../src/features/interactive/action-menu.ts"],"sourcesContent":["/**\n * Action menu for interactive search mode.\n * Allows users to perform actions on selected references.\n */\n\nimport type { CslItem } from \"../../core/csl-json/types.js\";\nimport { formatBibliographyCSL, formatBibtex } from \"../format/index.js\";\n\n/**\n * Action types available in the action menu.\n */\nexport type ActionType =\n | \"output-ids\"\n | \"output-csl-json\"\n | \"output-bibtex\"\n | \"cite-apa\"\n | \"cite-choose\"\n | \"cancel\";\n\n/**\n * Result from action menu selection.\n */\nexport interface ActionMenuResult {\n /** Selected action type */\n action: ActionType;\n /** Generated output (empty for cancel) */\n output: string;\n /** Whether the prompt was cancelled */\n cancelled: boolean;\n}\n\n/**\n * Result from style selection prompt.\n */\nexport interface StyleSelectResult {\n /** Selected style (undefined if cancelled) */\n style?: string;\n /** Whether the prompt was cancelled */\n cancelled: boolean;\n}\n\n/**\n * Choice definition for Enquirer Select prompt.\n */\ninterface SelectChoice {\n name: string;\n message: string;\n value: ActionType | string;\n}\n\n/**\n * Available action choices for the action menu.\n */\nexport const ACTION_CHOICES: SelectChoice[] = [\n { name: \"output-ids\", message: \"Output IDs (citation keys)\", value: \"output-ids\" },\n { name: \"output-csl-json\", message: \"Output as CSL-JSON\", value: \"output-csl-json\" },\n { name: \"output-bibtex\", message: \"Output as BibTeX\", value: \"output-bibtex\" },\n { name: \"cite-apa\", message: \"Generate citation (APA)\", value: \"cite-apa\" },\n { name: \"cite-choose\", message: \"Generate citation (choose style)\", value: \"cite-choose\" },\n { name: \"cancel\", message: \"Cancel\", value: \"cancel\" },\n];\n\n/**\n * Available style choices for citation style selection.\n * Uses BUILTIN_STYLES from config/csl-styles.ts\n */\nexport const STYLE_CHOICES: SelectChoice[] = [\n { name: \"apa\", message: \"APA\", value: \"apa\" },\n { name: \"vancouver\", message: \"Vancouver\", value: \"vancouver\" },\n { name: \"harvard\", message: \"Harvard\", value: \"harvard\" },\n];\n\n/**\n * Run the style selection prompt.\n */\n\n/**\n * Generate output for the given action and items.\n */\nfunction generateOutput(action: ActionType, items: CslItem[], style = \"apa\"): string {\n switch (action) {\n case \"output-ids\":\n return items.map((item) => item.id).join(\"\\n\");\n\n case \"output-csl-json\":\n return JSON.stringify(items, null, 2);\n\n case \"output-bibtex\":\n return formatBibtex(items);\n\n case \"cite-apa\":\n return formatBibliographyCSL(items, { style: \"apa\" });\n\n case \"cite-choose\":\n return formatBibliographyCSL(items, { style });\n\n case \"cancel\":\n return \"\";\n\n default:\n return \"\";\n }\n}\n\n/**\n * Process the selected action and generate result.\n */\nasync function processAction(action: ActionType, items: CslItem[]): Promise<ActionMenuResult> {\n // Handle cite-choose: prompt for style first\n if (action === \"cite-choose\") {\n const styleResult = await runStyleSelectPrompt();\n if (styleResult.cancelled) {\n return {\n action: \"cancel\",\n output: \"\",\n cancelled: true,\n };\n }\n return {\n action,\n output: generateOutput(action, items, styleResult.style),\n cancelled: false,\n };\n }\n\n // Handle cancel\n if (action === \"cancel\") {\n return {\n action,\n output: \"\",\n cancelled: true,\n };\n }\n\n // Handle other actions\n return {\n action,\n output: generateOutput(action, items),\n cancelled: false,\n };\n}\n\nexport async function runStyleSelectPrompt(): Promise<StyleSelectResult> {\n // Dynamic import to allow mocking in tests\n // enquirer is a CommonJS module, so we must use default import\n const enquirer = await import(\"enquirer\");\n const Select = (enquirer.default as unknown as Record<string, unknown>).Select as new (\n options: Record<string, unknown>\n ) => { run(): Promise<string> };\n\n const promptOptions = {\n name: \"style\",\n message: \"Select citation style:\",\n choices: STYLE_CHOICES,\n };\n\n try {\n const prompt = new Select(promptOptions);\n const result = (await prompt.run()) as string;\n\n return {\n style: result,\n cancelled: false,\n };\n } catch (error) {\n // Enquirer throws an empty string when cancelled\n if (error === \"\" || (error instanceof Error && error.message === \"\")) {\n return {\n cancelled: true,\n };\n }\n throw error;\n }\n}\n\n/**\n * Run the action menu for selected references.\n *\n * @param items - Selected references\n * @returns Action result with output\n */\nexport async function runActionMenu(items: CslItem[]): Promise<ActionMenuResult> {\n // Dynamic import to allow mocking in tests\n // enquirer is a CommonJS module, so we must use default import\n const enquirer = await import(\"enquirer\");\n const Select = (enquirer.default as unknown as Record<string, unknown>).Select as new (\n options: Record<string, unknown>\n ) => { run(): Promise<string> };\n\n const count = items.length;\n const refWord = count === 1 ? \"reference\" : \"references\";\n const message = `Action for ${count} selected ${refWord}:`;\n\n const promptOptions = {\n name: \"action\",\n message,\n choices: ACTION_CHOICES,\n };\n\n try {\n const prompt = new Select(promptOptions);\n const action = (await prompt.run()) as ActionType;\n\n return processAction(action, items);\n } catch (error) {\n // Enquirer throws an empty string when cancelled\n if (error === \"\" || (error instanceof Error && error.message === \"\")) {\n return {\n action: \"cancel\",\n output: \"\",\n cancelled: true,\n };\n }\n throw error;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"action-menu-yzuB0WT3.js","sources":["../../src/features/interactive/action-menu.ts"],"sourcesContent":["/**\n * Action menu for interactive search mode.\n * Allows users to perform actions on selected references.\n */\n\nimport type { CslItem } from \"../../core/csl-json/types.js\";\nimport { formatBibliographyCSL, formatBibtex } from \"../format/index.js\";\n\n/**\n * Action types available in the action menu.\n */\nexport type ActionType =\n | \"output-ids\"\n | \"output-csl-json\"\n | \"output-bibtex\"\n | \"cite-apa\"\n | \"cite-choose\"\n | \"cancel\";\n\n/**\n * Result from action menu selection.\n */\nexport interface ActionMenuResult {\n /** Selected action type */\n action: ActionType;\n /** Generated output (empty for cancel) */\n output: string;\n /** Whether the prompt was cancelled */\n cancelled: boolean;\n}\n\n/**\n * Result from style selection prompt.\n */\nexport interface StyleSelectResult {\n /** Selected style (undefined if cancelled) */\n style?: string;\n /** Whether the prompt was cancelled */\n cancelled: boolean;\n}\n\n/**\n * Choice definition for Enquirer Select prompt.\n */\ninterface SelectChoice {\n name: string;\n message: string;\n value: ActionType | string;\n}\n\n/**\n * Available action choices for the action menu.\n */\nexport const ACTION_CHOICES: SelectChoice[] = [\n { name: \"output-ids\", message: \"Output IDs (citation keys)\", value: \"output-ids\" },\n { name: \"output-csl-json\", message: \"Output as CSL-JSON\", value: \"output-csl-json\" },\n { name: \"output-bibtex\", message: \"Output as BibTeX\", value: \"output-bibtex\" },\n { name: \"cite-apa\", message: \"Generate citation (APA)\", value: \"cite-apa\" },\n { name: \"cite-choose\", message: \"Generate citation (choose style)\", value: \"cite-choose\" },\n { name: \"cancel\", message: \"Cancel\", value: \"cancel\" },\n];\n\n/**\n * Available style choices for citation style selection.\n * Uses BUILTIN_STYLES from config/csl-styles.ts\n */\nexport const STYLE_CHOICES: SelectChoice[] = [\n { name: \"apa\", message: \"APA\", value: \"apa\" },\n { name: \"vancouver\", message: \"Vancouver\", value: \"vancouver\" },\n { name: \"harvard\", message: \"Harvard\", value: \"harvard\" },\n];\n\n/**\n * Run the style selection prompt.\n */\n\n/**\n * Generate output for the given action and items.\n */\nfunction generateOutput(action: ActionType, items: CslItem[], style = \"apa\"): string {\n switch (action) {\n case \"output-ids\":\n return items.map((item) => item.id).join(\"\\n\");\n\n case \"output-csl-json\":\n return JSON.stringify(items, null, 2);\n\n case \"output-bibtex\":\n return formatBibtex(items);\n\n case \"cite-apa\":\n return formatBibliographyCSL(items, { style: \"apa\" });\n\n case \"cite-choose\":\n return formatBibliographyCSL(items, { style });\n\n case \"cancel\":\n return \"\";\n\n default:\n return \"\";\n }\n}\n\n/**\n * Process the selected action and generate result.\n */\nasync function processAction(action: ActionType, items: CslItem[]): Promise<ActionMenuResult> {\n // Handle cite-choose: prompt for style first\n if (action === \"cite-choose\") {\n const styleResult = await runStyleSelectPrompt();\n if (styleResult.cancelled) {\n return {\n action: \"cancel\",\n output: \"\",\n cancelled: true,\n };\n }\n return {\n action,\n output: generateOutput(action, items, styleResult.style),\n cancelled: false,\n };\n }\n\n // Handle cancel\n if (action === \"cancel\") {\n return {\n action,\n output: \"\",\n cancelled: true,\n };\n }\n\n // Handle other actions\n return {\n action,\n output: generateOutput(action, items),\n cancelled: false,\n };\n}\n\nexport async function runStyleSelectPrompt(): Promise<StyleSelectResult> {\n // Dynamic import to allow mocking in tests\n // enquirer is a CommonJS module, so we must use default import\n const enquirer = await import(\"enquirer\");\n const Select = (enquirer.default as unknown as Record<string, unknown>).Select as new (\n options: Record<string, unknown>\n ) => { run(): Promise<string> };\n\n const promptOptions = {\n name: \"style\",\n message: \"Select citation style:\",\n choices: STYLE_CHOICES,\n };\n\n try {\n const prompt = new Select(promptOptions);\n const result = (await prompt.run()) as string;\n\n return {\n style: result,\n cancelled: false,\n };\n } catch (error) {\n // Enquirer throws an empty string when cancelled\n if (error === \"\" || (error instanceof Error && error.message === \"\")) {\n return {\n cancelled: true,\n };\n }\n throw error;\n }\n}\n\n/**\n * Run the action menu for selected references.\n *\n * @param items - Selected references\n * @returns Action result with output\n */\nexport async function runActionMenu(items: CslItem[]): Promise<ActionMenuResult> {\n // Dynamic import to allow mocking in tests\n // enquirer is a CommonJS module, so we must use default import\n const enquirer = await import(\"enquirer\");\n const Select = (enquirer.default as unknown as Record<string, unknown>).Select as new (\n options: Record<string, unknown>\n ) => { run(): Promise<string> };\n\n const count = items.length;\n const refWord = count === 1 ? \"reference\" : \"references\";\n const message = `Action for ${count} selected ${refWord}:`;\n\n const promptOptions = {\n name: \"action\",\n message,\n choices: ACTION_CHOICES,\n };\n\n try {\n const prompt = new Select(promptOptions);\n const action = (await prompt.run()) as ActionType;\n\n return processAction(action, items);\n } catch (error) {\n // Enquirer throws an empty string when cancelled\n if (error === \"\" || (error instanceof Error && error.message === \"\")) {\n return {\n action: \"cancel\",\n output: \"\",\n cancelled: true,\n };\n }\n throw error;\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { a, d, g, l, o, s } from "./index-BIFsFHVj.js";
1
+ import { a, d, g, l, o, s } from "./index-TKhWlXl1.js";
2
2
  export {
3
3
  a as addAttachment,
4
4
  d as detachAttachment,
@@ -7,4 +7,4 @@ export {
7
7
  o as openAttachment,
8
8
  s as syncAttachments
9
9
  };
10
- //# sourceMappingURL=index-C30Ouuee.js.map
10
+ //# sourceMappingURL=index-DVFYLuQx.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-DVFYLuQx.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
@@ -8,7 +8,7 @@ import * as path from "node:path";
8
8
  import path__default, { extname, join, basename, dirname } from "node:path";
9
9
  import fs__default, { stat, rename, copyFile, readFile, unlink, readdir, mkdir, rm } from "node:fs/promises";
10
10
  import { g as getExtension, i as isValidFulltextFiles, a as isReservedRole, F as FULLTEXT_ROLE, b as formatToExtension, c as findFulltextFiles, d as findFulltextFile, e as extensionToFormat, B as BUILTIN_STYLES, h as getFulltextAttachmentTypes, s as startServerWithFileWatcher } from "./index-DHgeuWGP.js";
11
- import { o as openWithSystemApp, l as loadConfig, e as getDefaultCurrentDirConfigFilename, h as getDefaultUserConfigPath } from "./loader-DStZe-OB.js";
11
+ import { o as openWithSystemApp, l as loadConfig, e as getDefaultCurrentDirConfigFilename, h as getDefaultUserConfigPath } from "./loader-DuhmXjiI.js";
12
12
  import { spawn, spawnSync } from "node:child_process";
13
13
  import process$1, { stdin, stdout } from "node:process";
14
14
  import { parse as parse$2, stringify as stringify$2 } from "@iarna/toml";
@@ -17,7 +17,7 @@ import "@citation-js/plugin-csl";
17
17
  import { ZodOptional as ZodOptional$2, z } from "zod";
18
18
  import { serve } from "@hono/node-server";
19
19
  const name = "@ncukondo/reference-manager";
20
- const version$1 = "0.15.2";
20
+ const version$1 = "0.15.3";
21
21
  const description$1 = "A local reference management tool using CSL-JSON as the single source of truth";
22
22
  const packageJson = {
23
23
  name,
@@ -903,27 +903,27 @@ class OperationsLibrary {
903
903
  }
904
904
  // Attachment operations
905
905
  async attachAdd(options) {
906
- const { addAttachment: addAttachment2 } = await import("./index-C30Ouuee.js");
906
+ const { addAttachment: addAttachment2 } = await import("./index-DVFYLuQx.js");
907
907
  return addAttachment2(this.library, options);
908
908
  }
909
909
  async attachList(options) {
910
- const { listAttachments: listAttachments2 } = await import("./index-C30Ouuee.js");
910
+ const { listAttachments: listAttachments2 } = await import("./index-DVFYLuQx.js");
911
911
  return listAttachments2(this.library, options);
912
912
  }
913
913
  async attachGet(options) {
914
- const { getAttachment: getAttachment2 } = await import("./index-C30Ouuee.js");
914
+ const { getAttachment: getAttachment2 } = await import("./index-DVFYLuQx.js");
915
915
  return getAttachment2(this.library, options);
916
916
  }
917
917
  async attachDetach(options) {
918
- const { detachAttachment: detachAttachment2 } = await import("./index-C30Ouuee.js");
918
+ const { detachAttachment: detachAttachment2 } = await import("./index-DVFYLuQx.js");
919
919
  return detachAttachment2(this.library, options);
920
920
  }
921
921
  async attachSync(options) {
922
- const { syncAttachments: syncAttachments2 } = await import("./index-C30Ouuee.js");
922
+ const { syncAttachments: syncAttachments2 } = await import("./index-DVFYLuQx.js");
923
923
  return syncAttachments2(this.library, options);
924
924
  }
925
925
  async attachOpen(options) {
926
- const { openAttachment: openAttachment2 } = await import("./index-C30Ouuee.js");
926
+ const { openAttachment: openAttachment2 } = await import("./index-DVFYLuQx.js");
927
927
  return openAttachment2(this.library, options);
928
928
  }
929
929
  }
@@ -1577,6 +1577,15 @@ function formatAttachSyncOutput(result) {
1577
1577
  }
1578
1578
  return lines.join("\n").trimEnd();
1579
1579
  }
1580
+ function formatSyncPreview(result) {
1581
+ if (!result.success) {
1582
+ return `Error: ${result.error}`;
1583
+ }
1584
+ const lines = [];
1585
+ formatNewFilesSection(result, lines);
1586
+ formatMissingFilesSection(result, lines);
1587
+ return lines.join("\n").trimEnd();
1588
+ }
1580
1589
  function getAttachExitCode(result) {
1581
1590
  return result.success ? 0 : 1;
1582
1591
  }
@@ -1627,10 +1636,13 @@ async function waitForEnter() {
1627
1636
  process.stderr.write("Press Enter when done editing...");
1628
1637
  process.stdin.setRawMode(true);
1629
1638
  process.stdin.resume();
1639
+ const keepAliveTimer = setInterval(() => {
1640
+ }, 6e4);
1630
1641
  if (typeof process.stdin.ref === "function") {
1631
1642
  process.stdin.ref();
1632
1643
  }
1633
1644
  process.stdin.once("data", () => {
1645
+ clearInterval(keepAliveTimer);
1634
1646
  process.stdin.setRawMode(false);
1635
1647
  process.stdin.pause();
1636
1648
  process.stderr.write("\n\n");
@@ -1692,7 +1704,7 @@ async function handleAttachOpenAction(identifierArg, filenameArg, options, globa
1692
1704
  const context = await createExecutionContext(config2, Library.load);
1693
1705
  const identifier = await resolveIdentifier(identifierArg, context, config2);
1694
1706
  const isDirectoryMode = !filenameArg && !options.role;
1695
- const shouldUseInteractive = isTTY() && isDirectoryMode && !options.print && !options.noSync;
1707
+ const shouldUseInteractive = isTTY() && isDirectoryMode && !options.print && options.sync !== false;
1696
1708
  const openOptions = buildOpenOptions(
1697
1709
  identifier,
1698
1710
  filenameArg,
@@ -1847,11 +1859,10 @@ async function runInteractiveSyncMode(identifier, attachmentsDirectory, idType,
1847
1859
  `);
1848
1860
  return;
1849
1861
  }
1850
- process.stderr.write(`${formatAttachSyncOutput(dryRunResult)}
1851
-
1862
+ process.stderr.write(`${formatSyncPreview(dryRunResult)}
1852
1863
  `);
1853
1864
  const shouldApplyNew = hasNewFiles && await readConfirmation("Add new files to metadata?");
1854
- const shouldApplyFix = hasMissingFiles && shouldApplyNew && await readConfirmation("Remove missing files?");
1865
+ const shouldApplyFix = hasMissingFiles && await readConfirmation("Remove missing files from metadata?");
1855
1866
  if (!shouldApplyNew && !shouldApplyFix) {
1856
1867
  process.stderr.write("No changes applied.\n");
1857
1868
  return;
@@ -30709,7 +30720,7 @@ async function executeInteractiveSearch(options, context, config2) {
30709
30720
  validateInteractiveOptions(options);
30710
30721
  const { checkTTY } = await import("./tty-BMyaEOhX.js");
30711
30722
  const { runSearchPrompt } = await import("./search-prompt-BrWpOcij.js");
30712
- const { runActionMenu } = await import("./action-menu-CLBXtpmg.js");
30723
+ const { runActionMenu } = await import("./action-menu-yzuB0WT3.js");
30713
30724
  const { search } = await import("./file-watcher-B_WpVHSV.js").then((n) => n.y);
30714
30725
  const { tokenize } = await import("./file-watcher-B_WpVHSV.js").then((n) => n.x);
30715
30726
  checkTTY();
@@ -31785,4 +31796,4 @@ export {
31785
31796
  openAttachment as o,
31786
31797
  syncAttachments as s
31787
31798
  };
31788
- //# sourceMappingURL=index-BIFsFHVj.js.map
31799
+ //# sourceMappingURL=index-TKhWlXl1.js.map