### Example Usage of GuideHelper Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-helpers.md Demonstrates how to create a GuideHelper instance, add multiple steps with element selectors and descriptions, and then display the guide. ```typescript const guide = new GuideHelper(); guide.addSteps([ { element: '#button-1', title: 'First Step', description: 'Click this button', position: 'after_start' }, { element: '#input-1', title: 'Second Step', description: 'Enter some text', position: 'after_start' } ]); await guide.show(document); ``` -------------------------------- ### BasicOptions Configuration Example Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/index.md Example of how to define the BasicOptions for toolkit components. Ensure all necessary fields are populated according to your plugin's requirements. ```typescript const options: BasicOptions = { log: { disableConsole: false, disableZLog: false, prefix: "MyPlugin" }, api: { pluginID: "my-plugin@example.com" }, debug: { disableDebugBridgePassword: false, password: "" }, listeners: { /* ... */ } }; ``` -------------------------------- ### Install Zotero Plugin Toolkit with npm Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/docs/quick-start.md Install the toolkit using npm. This is the standard package manager for Node.js projects. ```bash npm install --save zotero-plugin-toolkit ``` -------------------------------- ### GuideHelper show Method Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-helpers.md Displays the configured guide steps to the user. ```typescript async show(doc: Document): Promise ``` -------------------------------- ### Clone Repository and Install Dependencies Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/docs/contributing.md Clone the Zotero Plugin Toolkit repository and install its npm dependencies. Ensure Node.js and npm are installed before running these commands. ```bash git clone https://github.com/windingwind/zotero-plugin-toolkit cd zotero-plugin-toolkit npm install ``` -------------------------------- ### Install Zotero Plugin Toolkit with yarn Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/docs/quick-start.md Install the toolkit using yarn. Yarn is an alternative package manager for Node.js. ```bash yarn add zotero-plugin-toolkit ``` -------------------------------- ### Install Zotero Plugin Toolkit with pnpm Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/docs/quick-start.md Install the toolkit using pnpm. pnpm is a performant, disk-space-efficient package manager. ```bash pnpm add zotero-plugin-toolkit ``` -------------------------------- ### Plugin Discovery Pattern Example Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-managers.md Illustrates using a PromptManager to group and register commands by functionality. ```typescript const prompt = new PromptManager(); // Group commands by functionality const editorCommands = [ { name: 'Bold', id: 'bold', callback: () => {} }, { name: 'Italic', id: 'italic', callback: () => {} } ]; const fileCommands = [ { name: 'Save', id: 'save', callback: () => {} }, { name: 'Export', id: 'export', callback: () => {} } ]; prompt.register(editorCommands); prompt.register(fileCommands); ``` -------------------------------- ### MessageHelper Main Thread Example Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-helpers.md Example of setting up a MessageHelper on the main thread to communicate with a worker. It imports handlers from the worker and uses the proxy to call methods. ```typescript // main.ts import type { handlers } from "./worker.js"; const worker = new Worker("worker.js"); const server = new MessageHelper({ name: "main", handlers: {}, target: worker }); server.start(); console.log(await server.proxy.test()); // "worker response" ``` -------------------------------- ### Plugin Lifecycle Management Example Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-managers.md Demonstrates initializing managers, registering hooks and commands, and unregistering all on plugin unload. ```typescript // Plugin entry point const fieldHooks = new FieldHookManager(); const promptMgr = new PromptManager(); fieldHooks.basicOptions.api.pluginID = 'my-plugin@example.com'; promptMgr.basicOptions.api.pluginID = 'my-plugin@example.com'; // Register hooks and commands fieldHooks.register('getField', 'title', (field, unformatted, includeBaseMapped, item, original) => { return original.apply(item, [field, unformatted, includeBaseMapped]) + ' (custom)'; }); promptMgr.register([ { name: 'Custom Command', id: 'custom-cmd', callback: () => { /* ... */ } } ]); // On plugin exit ztoolkit.addListenerCallback('onPluginUnload', () => { fieldHooks.unregisterAll(); promptMgr.unregisterAll(); }); ``` -------------------------------- ### MessageHelper start Method Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-helpers.md Starts the message listener for the MessageHelper. This must be called before any messages can be sent or received. ```typescript start(): void ``` -------------------------------- ### Initialize BasicTool with Default Options Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/configuration.md Instantiate BasicTool using its default configuration. This is the simplest way to start. ```typescript // Option 1: Default options const tool = new BasicTool(); ``` -------------------------------- ### Dialog with Lifecycle Callbacks Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-dialog-helper.md This example shows how to use lifecycle callbacks (load, beforeUnload, unload) to manage dialog state and perform actions during different stages of the dialog's life. It also includes an example of fetching data on button click. ```typescript const dialog = new DialogHelper(1, 1); dialog.addCell(0, 0, { tag: 'button', properties: { innerText: 'Load Data' }, listeners: [{ type: 'click', listener: async () => { console.log('Loading data...'); // Fetch from server const data = await fetch('/api/data').then(r => r.json()); dialog.dialogData.loadedData = data; } }] }); dialog.setDialogData({ async loadCallback() { console.log('Dialog loaded'); // Initialize UI }, async beforeUnloadCallback() { console.log('Saving state...'); // Save preferences }, async unloadCallback() { console.log('Cleanup'); } }); dialog.addButton('OK', 'ok-btn'); dialog.open('Data Dialog'); ``` -------------------------------- ### Basic Zotero Toolkit Setup Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/index.md Initialize the ZoteroToolkit and register callbacks for main window load and plugin unload events. Ensure the pluginID is set for lifecycle tracking. ```typescript const ztoolkit = new ZoteroToolkit(); ztoolkit.basicOptions.api.pluginID = "my-plugin-id"; // Register for main window ztoolkit.addListenerCallback('onMainWindowLoad', (win) => { // Initialize UI and managers }); // Cleanup on unload ztoolkit.addListenerCallback('onPluginUnload', () => { ztoolkit.unregisterAll(); }); ``` -------------------------------- ### MessageHelper Worker Example Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-helpers.md Example of setting up a MessageHelper on the worker side to handle incoming messages and define test handlers. ```typescript // worker.js const handlers = { test: async () => "worker response" }; const server = new MessageHelper({ name: "worker", handlers, canBeDestroyed: true }); server.start(); export { handlers }; ``` -------------------------------- ### Get Extra Field Examples Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-tools.md Demonstrates how to retrieve single and multiple values for an extra field key, including handling non-existent keys. ```typescript const singleValue = extra.getExtraField(item, 'title'); // First value const allValues = extra.getExtraField(item, 'title', true); // All values const notExists = extra.getExtraField(item, 'nonexistent'); // undefined ``` -------------------------------- ### Install zotero-types for TypeScript support Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/docs/quick-start.md Install the zotero-types package as a dev dependency to enable full TypeScript support for Zotero APIs. ```bash npm install --save-dev zotero-types ``` -------------------------------- ### Initialize Zotero Toolkit Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/summary.md Instantiate the ZoteroToolkit and set the plugin ID. This is the basic setup required before using other toolkit features. ```typescript import { ZoteroToolkit } from 'zotero-plugin-toolkit'; const ztoolkit = new ZoteroToolkit(); ztoolkit.basicOptions.api.pluginID = 'my-plugin@example.com'; ``` -------------------------------- ### GuideHelper Class Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-helpers.md This snippet details the methods available on the GuideHelper class for creating and managing guides. ```APIDOC ## GuideHelper **Module**: `src/helpers/guide.ts` **Export**: `class GuideHelper extends BasicTool` Create step-by-step guides with highlighted elements. ### Constructor ```typescript constructor() ``` ### Methods #### addStep() ```typescript addStep(step: GuideStep): GuideHelper ``` Add a guide step. #### addSteps() ```typescript addSteps(steps: GuideStep[]): GuideHelper ``` Add multiple guide steps. #### show() ```typescript async show(doc: Document): Promise ``` Show the guide. #### highlight() ```typescript async highlight(doc: Document, step: GuideStep): Promise ``` Highlight a single element. ### GuideStep Interface ```typescript interface GuideStep { element?: string | Element | (() => Element); title?: string; description?: string; position?: "before_start" | "after_start" | "overlap" | "center" | ...; showButtons?: ("next" | "prev" | "close")[]; showProgress?: boolean; disableButtons?: ("next" | "prev" | "close")[]; onBeforeRender?: GuideHook; onRender?: GuideHook; onExit?: GuideHook; onNextClick?: GuideHook; onPrevClick?: GuideHook; onCloseClick?: GuideHook; onMask?: (props: { mask: (elem: Element) => void }) => void; } ``` **Example**: ```typescript const guide = new GuideHelper(); guide.addSteps([ { element: '#button-1', title: 'First Step', description: 'Click this button', position: 'after_start' }, { element: '#input-1', title: 'Second Step', description: 'Enter some text', position: 'after_start' } ]); await guide.show(document); ``` ``` -------------------------------- ### Initialize KeyboardManager Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-keyboard-manager.md Instantiate the KeyboardManager to begin listening for keyboard events. No setup is required beyond instantiation. ```typescript const kb = new KeyboardManager(); ``` -------------------------------- ### GuideHelper highlight Method Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-helpers.md Highlights a single element within the document for a guide step. ```typescript async highlight(doc: Document, step: GuideStep): Promise ``` -------------------------------- ### GuideHelper addStep Method Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-helpers.md Adds a single guide step to the GuideHelper instance. ```typescript addStep(step: GuideStep): GuideHelper ``` -------------------------------- ### Instantiate ReaderTool Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-tools.md Create a new instance of the ReaderTool. This is the starting point for interacting with Zotero Reader functionalities. ```typescript const reader = new ReaderTool(); ``` -------------------------------- ### PatchHelper Example Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-helpers.md Demonstrates how to use PatchHelper to patch the setField method of Zotero.Item.prototype, logging the field and value being set. ```typescript const patcher = new PatchHelper(); patcher.setData({ target: Zotero.Item.prototype, funcSign: 'setField', patcher: (origin) => function(field, value) { console.log(`Setting ${field} to ${value}`); return origin.call(this, field, value); }, enabled: true }); ``` -------------------------------- ### GuideHelper addSteps Method Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-helpers.md Adds an array of guide steps to the GuideHelper instance. ```typescript addSteps(steps: GuideStep[]): GuideHelper ``` -------------------------------- ### Register Basic Keyboard Shortcut Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-keyboard-manager.md Registers a keyboard shortcut with the KeyboardManager. This example shows how to log messages when specific key combinations like Ctrl+Shift+K or Ctrl+E are released. ```typescript const kb = new KeyboardManager(); kb.register((event, options) => { const { keyboard, type } = options; if (type === 'keyup') { if (keyboard?.equals('control,shift,k')) { console.log('Ctrl+Shift+K: Open command palette'); } if (keyboard?.equals('control,e')) { console.log('Ctrl+E: Export'); } } }); ``` -------------------------------- ### Instantiate FilePickerHelper for PDF Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-helpers.md Example of creating a FilePickerHelper instance specifically for opening PDF files. It sets a custom title and filter for PDF documents. ```typescript const picker = new FilePickerHelper( "Open PDF", "open", [["PDF Files (*.pdf)", "*.pdf"]], undefined, undefined, "all" ); ``` -------------------------------- ### KeyModifier Properties Example Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-keyboard-manager.md Demonstrates accessing the properties of a KeyModifier instance after initialization. Shows how to check for pressed modifier keys and the main key. ```typescript const km = new KeyModifier('control,shift,a'); console.log(km.key); // 'a' console.log(km.control); // true console.log(km.shift); // true console.log(km.alt); // false ``` -------------------------------- ### LargePrefHelper Methods Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-helpers.md Provides methods to interact with the stored data, including getting, setting, deleting, and checking for keys, as well as retrieving all keys or the data as different object types. ```APIDOC ## Methods ### getValue() #### Description Retrieves a value associated with a specific key. #### Parameters - **key** (string) - Required - The key of the value to retrieve. #### Returns - any - The value associated with the key, or undefined if the key does not exist. ``` ```APIDOC ### setValue() #### Description Sets a value for a given key. If the key already exists, its value will be updated. #### Parameters - **key** (string) - Required - The key to set the value for. - **value** (any) - Required - The value to store. #### Returns - void ``` ```APIDOC ### hasKey() #### Description Checks if a key exists in the storage. #### Parameters - **key** (string) - Required - The key to check for. #### Returns - boolean - `true` if the key exists, `false` otherwise. ``` ```APIDOC ### deleteKey() #### Description Deletes a key and its associated value from the storage. #### Parameters - **key** (string) - Required - The key to delete. #### Returns - boolean - `true` if the key was successfully deleted, `false` otherwise. ``` ```APIDOC ### getKeys() #### Description Retrieves an array of all keys currently stored. #### Returns - string[] - An array containing all the keys. ``` ```APIDOC ### setKeys() #### Description Replaces all existing keys with a new set of keys. This method automatically handles deduplication and filters out empty strings. #### Parameters - **keys** (string[]) - Required - An array of keys to set. #### Returns - void ``` ```APIDOC ### asObject() #### Description Returns the stored data as a Proxy object, allowing for direct property access (e.g., `storage.myKey`). #### Returns - ProxyObj - A Proxy object representing the stored data. ``` ```APIDOC ### asMapLike() #### Description Returns the stored data as a Map-like object, providing methods such as `get`, `set`, `has`, `delete`, and `clear` for data manipulation. #### Returns - Map - A Map-like object containing the stored data. ``` -------------------------------- ### GuideStep Interface Definition Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/types.md Defines the configuration for a step in a user guide, including target element, titles, descriptions, positioning, button visibility, and lifecycle hooks. ```typescript interface GuideStep { element?: string | Element | (() => Element); title?: string; description?: string; position?: | "before_start" | "before_end" | "after_start" | "after_end" | "start_before" | "start_after" | "end_before" | "end_after" | "overlap" | "after_pointer" | "center"; showButtons?: ("next" | "prev" | "close")[]; showProgress?: boolean; disableButtons?: ("next" | "prev" | "close")[]; progressText?: string; closeBtnText?: string; nextBtnText?: string; prevBtnText?: string; onBeforeRender?: GuideHook; onRender?: GuideHook; onExit?: GuideHook; onNextClick?: GuideHook; onPrevClick?: GuideHook; onCloseClick?: GuideHook; onMask?: (props: { mask: (elem: Element) => void }) => void; } ``` -------------------------------- ### Replace Extra Fields Example Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-tools.md Example of modifying extra fields by getting existing ones, adding a new key, deleting an old one, and then replacing the item's fields. ```typescript const fields = extra.getExtraFields(item, 'enhanced'); fields.set('newKey', ['value1', 'value2']); fields.delete('oldKey'); await extra.replaceExtraFields(item, fields); ``` -------------------------------- ### KeyModifier getLocalized() Method Example Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-keyboard-manager.md Gets a localized string representation of the KeyModifier. This provides platform-specific symbols for modifier keys. ```typescript const km = new KeyModifier('control,shift,a'); console.log(km.getLocalized()); // Windows: 'control,shift,a' // Mac: '⌃,⇧,a' ``` -------------------------------- ### Set Extra Field Examples Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-tools.md Demonstrates setting an extra field by replacing the value, appending to it, setting multiple values, and deleting a field by setting it to an empty string. ```typescript // Replace (default) await extra.setExtraField(item, 'myKey', 'newValue'); // Append await extra.setExtraField(item, 'myKey', 'anotherValue', { append: true }); // Multiple values await extra.setExtraField(item, 'myKey', ['val1', 'val2']); // Delete (set to empty string) await extra.setExtraField(item, 'myKey', ''); ``` -------------------------------- ### KeyModifier getRaw() Method Example Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-keyboard-manager.md Retrieves the original XUL shortcut format string from a KeyModifier instance. Use this to get a standardized string representation. ```typescript const km = new KeyModifier('control,shift,a'); console.log(km.getRaw()); // 'control,shift,a' ``` -------------------------------- ### GuideHelper Constructor Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-helpers.md Initializes a new instance of the GuideHelper class. ```typescript constructor() ``` -------------------------------- ### Set Basic Configuration Options Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/summary.md Demonstrates how to set specific configuration options for the toolkit. These settings are applied globally. ```typescript ztoolkit.basicOptions.api.pluginID = 'id'; ztoolkit.basicOptions.log.prefix = '[MyPlugin]'; ``` -------------------------------- ### Initialize BasicTool by Copying Options Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/configuration.md Create a new BasicTool instance by copying the configuration from an existing instance. Useful for maintaining consistent settings. ```typescript // Option 2: Copy from another instance const tool2 = new BasicTool(tool); ``` -------------------------------- ### Interact with Zotero Reader and Selection Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-tools.md Get the active Zotero reader and retrieve information about the currently selected annotation, such as its text and page label. Also shows how to get all open readers. ```typescript const reader = new ReaderTool(); // Get active reader and check selection const activeReader = await reader.getReader(); if (activeReader) { const annotation = reader.getSelectedAnnotationData(activeReader); if (annotation) { console.log(`Page ${annotation.pageLabel}: ${annotation.text}`); } } // Get all readers const allReaders = reader.getWindowReader(); console.log(`Total readers: ${allReaders.length}`); ``` -------------------------------- ### Basic Toolkit Usage: Logging and Global Access Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/docs/quick-start.md Demonstrates basic toolkit usage, including logging messages with context and accessing global Zotero objects like ZoteroPane. The `getGlobal` method provides type hints for Zotero, window, and document. ```typescript const ztoolkit = new ZoteroToolkit(); // Logging with context-aware output ztoolkit.log("This is Zotero:", ztoolkit.getGlobal("Zotero")); // Accessing a global object const ZoteroPane = ztoolkit.getGlobal("ZoteroPane"); ``` -------------------------------- ### Open File Picker and Handle Result Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-helpers.md Demonstrates how to use the open() method to prompt the user to select a file and then handle the returned path or cancellation. This is useful for user-initiated file loading. ```typescript const path = await new FilePickerHelper( "Choose a file", "open", [["All Files", "*"]] ).open(); if (path === false) { console.log("User cancelled"); } else { console.log("Selected:", path); } ``` -------------------------------- ### MessageHelper stop Method Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-helpers.md Stops the message listener. The server can be restarted later by calling start() again. ```typescript stop(): void ``` -------------------------------- ### Instantiate ProgressWindowHelper Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-helpers.md Create a new progress window with a specified header. This is the initial step before adding progress lines or showing the window. ```typescript const progress = new ProgressWindowHelper("Importing Items"); ``` -------------------------------- ### Configure and Show Progress Window Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/configuration.md Instantiate and display a progress window with custom options like close behavior and timing. The parent window defaults to the main window. ```typescript const progress = new ProgressWindowHelper( "Processing Items", // header { window: undefined, // parent window (use main window) closeOnClick: true, // close on click closeTime: 5000, // auto-close after 5s closeOtherProgressWindows: false // close other progress windows } ); progress.show(3000); // Show and auto-close after 3s ``` -------------------------------- ### Custom Manager Implementation Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-managers.md Example of extending ManagerTool to create a custom manager, ensuring auto-unregistration. ```typescript export class MyManager extends ManagerTool { constructor(base?: BasicTool | BasicOptions) { super(base); this._ensureAutoUnregisterAll(); } register(data) { /* ... */ } unregister(data) { /* ... */ } unregisterAll() { /* ... */ } } ``` -------------------------------- ### PromptManager Constructor Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-managers.md Initializes the global Prompt instance if not already created. Accepts an optional BasicTool or BasicOptions object. ```APIDOC ## PromptManager Constructor Initializes the global Prompt instance if not already created. ### Signature ```typescript constructor(base?: BasicTool | BasicOptions) ``` ### Example ```typescript const prompt = new PromptManager(); ``` ``` -------------------------------- ### Configure FilePickerHelper Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/configuration.md Configure a file picker with a title, mode, file filters, default suggestion, and initial directory. The `open()` method returns the selected path(s). ```typescript const picker = new FilePickerHelper( "Select a File", // title "open", // mode: "open" | "save" | "folder" | "multiple" [ ["PDF Files (*.pdf)", "*.pdf"], ["Text Files (*.txt)", "*.txt"], ["All Files", "*"] ], // filters "default.pdf", // suggestion (default filename) undefined, // window (use main window) "all", // filterMask: built-in filters "/home/user/documents" // directory (initial dir) ); const result = await picker.open(); ``` -------------------------------- ### Handle MainWindow Load Events Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-basic-tool.md Register a callback for the 'onMainWindowLoad' event to interact with the main Zotero window's document, such as querying for elements like the menubar. ```typescript const tool = new BasicTool(); tool.addListenerCallback('onMainWindowLoad', (win) => { const doc = win.document; const menubar = doc.querySelector('menubar'); console.log("Menubar:", menubar); }); ``` -------------------------------- ### Conditional Field Modification Example Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-managers.md Shows how to use a FieldHookManager to conditionally modify a field, including validation. ```typescript const hooks = new FieldHookManager(); hooks.register('setField', 'extra', (field, value, loadIn, item, original) => { // Validate extra field format before setting if (!isValidExtraField(value)) { console.warn('Invalid extra field format'); return false; } return original.apply(item, [field, value, loadIn]); }); ``` -------------------------------- ### MessageHelper get Method Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-helpers.md Retrieves the value of a property with the given key from the target context and returns it as a promise. ```typescript async get(key: string): Promise ``` -------------------------------- ### Global Toolkit Configuration Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/configuration.md Initialize the ZoteroToolkit and set global configuration options like pluginID and logging prefix once at startup. Sub-components inherit these settings automatically. ```typescript const ztoolkit = new ZoteroToolkit(); ztoolkit.basicOptions.api.pluginID = "my-plugin@example.com"; ztoolkit.basicOptions.log.prefix = "[MyPlugin]"; const ui = new UITool(ztoolkit); const keyboard = new KeyboardManager(ztoolkit); ztoolkit.log("Initialized"); // Prefixed as [MyPlugin] ui.log("UI Ready"); // Prefixed as [MyPlugin] ``` -------------------------------- ### Constructor Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-ui-tool.md Initializes a new instance of UITool. It can optionally copy options from an existing BasicTool instance or accept new BasicOptions. ```APIDOC ## Constructor ```typescript constructor(base?: BasicTool | BasicOptions) ``` ### Parameters - **base** (BasicTool | BasicOptions) - Optional - Copy options from BasicTool or provide BasicOptions ### Example ```typescript const ui = new UITool(); ``` ``` -------------------------------- ### Create and Manage Progress Lines Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-helpers.md Demonstrates creating a progress window, adding a progress line, showing the window, updating the line's status and text, and finally marking it as successful. Use this to provide real-time feedback on ongoing tasks. ```typescript const progress = new ProgressWindowHelper("Task") .createLine({ text: "Starting...", progress: 0 }) .show(); setTimeout(() => { progress.changeLine({ text: "Processing...", progress: 50 }); }, 1000); setTimeout(() => { progress.changeLine({ type: "success", text: "Done!", progress: 100 }); }, 2000); ``` -------------------------------- ### GuideStep Interface Definition Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-helpers.md Defines the structure for a single step in a guide, including element targeting, content, and interaction options. ```typescript interface GuideStep { element?: string | Element | (() => Element); title?: string; description?: string; position?: "before_start" | "after_start" | "overlap" | "center" | ...; showButtons?: ("next" | "prev" | "close")[]; showProgress?: boolean; disableButtons?: ("next" | "prev" | "close")[]; onBeforeRender?: GuideHook; onRender?: GuideHook; onExit?: GuideHook; onNextClick?: GuideHook; onPrevClick?: GuideHook; onCloseClick?: GuideHook; onMask?: (props: { mask: (elem: Element) => void }) => void; } ``` -------------------------------- ### ProgressWindowHelper Constructor Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-helpers.md Initializes a new instance of the ProgressWindowHelper class. It displays progress notifications with a specified header and optional configuration. ```APIDOC ## new ProgressWindowHelper(header, options) ### Description Initializes a new instance of the ProgressWindowHelper class to display progress notifications. ### Parameters #### Path Parameters - **header** (string) - Required - Window header text #### Query Parameters - **options.closeOnClick** (boolean) - Optional - Close on click. Defaults to true. - **options.closeTime** (number) - Optional - Auto-close after (ms). Defaults to 5000. - **options.closeOtherProgressWindows** (boolean) - Optional - Close other progress windows. ``` -------------------------------- ### Initialize BasicTool and Set PluginID Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-basic-tool.md Instantiate BasicTool and set the pluginID, which is required for proper unload tracking. Listen for plugin unload events to perform cleanup. ```typescript const tool = new BasicTool(); tool.basicOptions.api.pluginID = "my-plugin@example.com"; // Register for lifecycle events tool.addListenerCallback('onPluginUnload', (params, reason) => { console.log("Cleaning up..."); tool.unregisterAll(); }); ``` -------------------------------- ### KeyModifier equals() Method Example Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-keyboard-manager.md Compares this KeyModifier with another KeyModifier or string representation. The comparison is case-insensitive and platform-aware for the accelerator key. ```typescript const km1 = new KeyModifier('control,shift,z'); const km2 = new KeyModifier('control,shift,Z'); console.log(km1.equals(km2)); // true (case-insensitive) console.log(km1.equals('control,shift,z')); // true ``` -------------------------------- ### Get Zotero Plugin Toolkit Version Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-basic-tool.md Retrieve the version of the Zotero Plugin Toolkit. This can be accessed statically from the class or as an instance property. ```typescript static _version: string get _version: string ``` -------------------------------- ### Instantiate BasicTool Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-basic-tool.md Create a new BasicTool instance. Can be standalone, copied from another instance, or configured with custom options. ```typescript const tool = new BasicTool(); ``` ```typescript const tool2 = new BasicTool(tool); ``` ```typescript const tool3 = new BasicTool({ log: { disableConsole: false, disableZLog: false, prefix: "MyPlugin" }, api: { pluginID: "my-plugin@example.com" }, debug: { disableDebugBridgePassword: false, password: "" }, listeners: { callbacks: { onMainWindowLoad: new Set(), onMainWindowUnload: new Set(), onPluginUnload: new Set() }, _mainWindow: undefined, _plugin: undefined } }); ``` -------------------------------- ### Get BasicTool Options Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-basic-tool.md Access the configuration object for the current BasicTool instance. This includes settings for logging, debugging, API, and event listeners. ```typescript get basicOptions(): BasicOptions ``` -------------------------------- ### Get All Extra Field Values Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-tools.md Retrieve all values associated with a specific extra field key as an array. Returns undefined if the key does not exist. ```typescript getExtraField(item: Zotero.Item, key: string, all: true): string[] | undefined ``` -------------------------------- ### KeyModifier merge() Method Example Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-keyboard-manager.md Merges another KeyModifier into the current one. By default, existing modifier values are preserved unless allowOverwrite is true. ```typescript const km1 = new KeyModifier('control,a'); const km2 = new KeyModifier('shift,b'); km1.merge(km2); // km1 now has shift=true, key='a' (allowOverwrite=false preserves 'a') ``` -------------------------------- ### Configure DialogHelper Options Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/configuration.md Configure the appearance and behavior of a dialog window using the `open()` method. Options control dimensions, positioning, and window behavior. ```typescript const dialog = new DialogHelper(2, 2); dialog.open('My Dialog', { width: 400, height: 300, left: 100, top: 100, centerscreen: true, // Open at screen center resizable: true, // Allow resizing fitContent: true, // Auto-size to content noDialogMode: false, // Dialog-only (no maximize/minimize) alwaysRaised: false // Keep window on top }); ``` -------------------------------- ### Get Single Extra Field Value Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-tools.md Retrieve the first value associated with a specific extra field key. Returns undefined if the key does not exist. ```typescript getExtraField(item: Zotero.Item, key: string, all?: false): string | undefined ``` -------------------------------- ### Multi-Step Dialog with Navigation Buttons Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-dialog-helper.md This snippet illustrates creating a multi-step dialog (wizard) with navigation buttons like 'Back', 'Next', and 'Close'. Each button has a click listener to handle its specific action. ```typescript const dialog = new DialogHelper(2, 3); dialog.addCell(0, 0, { tag: 'label', properties: { innerText: 'Step 1' } }); dialog.addCell(1, 0, { tag: 'button', properties: { innerText: 'Back' }, listeners: [{ type: 'click', listener: () => console.log('Go back') }] }); dialog.addCell(1, 1, { tag: 'button', properties: { innerText: 'Next' }, listeners: [{ type: 'click', listener: () => console.log('Go next') }] }); dialog.addCell(1, 2, { tag: 'button', properties: { innerText: 'Close' }, listeners: [{ type: 'click', listener: () => dialog.window.close() }] }); dialog.open('Wizard', { centerscreen: true, fitContent: true }); ``` -------------------------------- ### Get Selected Annotation Data Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-tools.md Fetches the data for the currently selected annotation within a given reader instance. Returns undefined if no annotation is selected. ```typescript const annotation = readerTool.getSelectedAnnotationData(reader); if (annotation) { console.log(`Annotation on page ${annotation.pageLabel}: ${annotation.text}`); } ``` -------------------------------- ### Access and Interact with PDF Reader Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/summary.md Retrieves the active PDF reader instance and allows interaction, such as getting selected text. This requires an await operation. ```typescript const reader = await ztoolkit.Reader.getReader(); if (reader) { const text = ztoolkit.Reader.getSelectedText(reader); console.log('Selected:', text); } ``` -------------------------------- ### Register Basic Commands with PromptManager Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-managers.md Register commands with a name, label, and callback function. The callback is executed when the command is selected. ```typescript const prompt = new PromptManager(); prompt.register([ { name: 'Open Settings', label: 'MyPlugin', callback: () => openSettingsDialog() }, { name: 'Process Selection', label: 'MyPlugin', when: () => !!Zotero.getActiveZoteroPane(), callback: (promptUI) => { const selected = Zotero.getActiveZoteroPane().getSelectedItems(); processItems(selected); } } ]); ``` -------------------------------- ### KeyboardManager Constructor Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-keyboard-manager.md Initializes a new instance of KeyboardManager. It can optionally copy options from a BasicTool or accept BasicOptions. ```APIDOC ## KeyboardManager Constructor ### Description Initializes a new instance of KeyboardManager. It can optionally copy options from a BasicTool or accept BasicOptions. ### Method ```typescript constructor(base?: BasicTool | BasicOptions) ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```typescript const kb = new KeyboardManager(); ``` ### Response None ``` -------------------------------- ### Create and Open a Dialog Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/index.md Utilize the Dialog API to add cells (labels, inputs) and buttons to a custom dialog, then open it to get user input. ```typescript const dialog = ztoolkit.Dialog; dialog.addCell(0, 0, { tag: 'label', properties: { innerText: 'Name:' } }); dialog.addCell(0, 1, { tag: 'input', attributes: { type: 'text' } }); dialog.addButton('OK', 'ok-btn'); const result = dialog.open('My Dialog'); ``` -------------------------------- ### Configure MessageHelper Server Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/configuration.md Set up a MessageHelper server with a specific name, message handlers, target, and debug mode. Allows for message destruction if canBeDestroyed is true. ```typescript const server = new MessageHelper({ name: "my-worker", // Server name handlers: { myHandler: async () => "response" }, target: worker, // Message target dev: false, // Debug mode canBeDestroyed: true // Allow destroying server }); server.start(); ``` -------------------------------- ### Get Reader Instance Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-tools.md Asynchronously retrieves the currently selected tab's reader instance. It includes an optional wait time to ensure the reader has initialized. ```typescript const reader = await readerTool.getReader(5000); if (reader) { console.log('Reader is ready'); } else { console.log('No active reader'); } ``` -------------------------------- ### Import all modules via the main class Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/docs/quick-start.md Import the entire ZoteroToolkit class to access all toolkit functionalities. Instantiate it to use its methods. ```typescript import { ZoteroToolkit } from "zotero-plugin-toolkit"; const ztoolkit = new ZoteroToolkit(); ``` -------------------------------- ### FilePickerHelper Constructor Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-helpers.md Initializes a new instance of the FilePickerHelper class. It takes various parameters to configure the file picker dialog, such as its title, mode, file filters, and initial directory. ```APIDOC ## Constructor FilePickerHelper ### Description Initializes a new instance of the FilePickerHelper class. It takes various parameters to configure the file picker dialog, such as its title, mode, file filters, and initial directory. ### Parameters #### Path Parameters - **title** (string) - Required - Dialog title - **mode** (string) - Required - "open", "save", "folder", or "multiple" - **filters** (`[string, string][]`) - Optional - File filter pairs: `[["PDF Files (*.pdf)", "*.pdf"]]` - **suggestion** (string) - Optional - Default filename/folder - **window** (Window) - Optional - Parent window (default: main window) - **filterMask** (string) - Optional - Built-in filter: "all", "html", "text", "images", etc. - **directory** (string) - Optional - Initial directory ### Request Example ```typescript const picker = new FilePickerHelper( "Open PDF", "open", [["PDF Files (*.pdf)", "*.pdf"]], undefined, undefined, "all" ); ``` ``` -------------------------------- ### Get Zotero Globals Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-basic-tool.md Retrieve common global variables from the Zotero context. Use this to access core Zotero objects like Zotero, ZoteroPane, window, or document. ```typescript const Zotero = tool.getGlobal("Zotero"); const window = tool.getGlobal("window"); const ZoteroPane = tool.getGlobal("ZoteroPane"); const doc = tool.getGlobal("document"); ``` -------------------------------- ### Import ZoteroToolkit Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/index.md Import the main ZoteroToolkit class from the zotero-plugin-toolkit package. ```typescript import { ZoteroToolkit } from 'zotero-plugin-toolkit' ``` -------------------------------- ### Get Selected Annotation Text Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-tools.md Extracts the plain text content of the currently selected annotation in a reader instance. Returns an empty string if no text is selected or available. ```typescript const text = readerTool.getSelectedText(reader); console.log('Selected text:', text); ``` -------------------------------- ### getZotero() (static) Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-basic-tool.md A static method to access the Zotero global object directly, without needing an instance of the BasicTool. This is useful for initial setup or when an instance is not readily available. ```APIDOC ## getZotero() (static) ### Description Static method to get the Zotero global. Works without an instance. ### Method `static getZotero(): _ZoteroTypes.Zotero` ### Response Returns the Zotero global object. ### Example ```typescript const Zotero = BasicTool.getZotero(); ``` ``` -------------------------------- ### Import MessageHelper Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/index.md Import the MessageHelper utility for inter-worker/iframe messaging. ```javascript import MessageHelper from 'zotero-plugin-toolkit' ``` -------------------------------- ### Create a Simple Form Dialog Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-dialog-helper.md This snippet demonstrates creating a form with input fields for name, email, and a checkbox, along with submit and cancel buttons. Data is bound using 'data-bind' and 'data-prop'. ```typescript const dialog = new DialogHelper(3, 2); // Name field dialog.addCell(0, 0, { tag: 'label', attributes: { for: 'name' }, properties: { innerText: 'Name:' } }); dialog.addCell(0, 1, { tag: 'input', id: 'name', attributes: { 'data-bind': 'name' } }); // Email field dialog.addCell(1, 0, { tag: 'label', attributes: { for: 'email' }, properties: { innerText: 'Email:' } }); dialog.addCell(1, 1, { tag: 'input', id: 'email', attributes: { type: 'email', 'data-bind': 'email' } }); // Checkbox dialog.addCell(2, 0, { tag: 'input', id: 'agree', attributes: { type: 'checkbox', 'data-bind': 'agree', 'data-prop': 'checked' } }); dialog.addCell(2, 1, { tag: 'label', attributes: { for: 'agree' }, properties: { innerText: 'I agree to terms' } }); dialog.addButton('Submit', 'submit-btn', { callback: (ev) => { console.log('Form data:', { name: dialog.dialogData.name, email: dialog.dialogData.email, agree: dialog.dialogData.agree }); } }); dialog.addButton('Cancel', 'cancel-btn'); const data = { name: '', email: '', agree: false }; dialog.setDialogData(data); dialog.open('User Registration'); await dialog.dialogData.unloadLock?.promise; console.log('Final data:', dialog.dialogData); ``` -------------------------------- ### Import only needed modules Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/docs/quick-start.md Import specific modules like BasicTool, ClipboardHelper, or UITool to reduce plugin size. Instantiate each module as needed. ```typescript import { BasicTool, ClipboardHelper, UITool } from "zotero-plugin-toolkit"; const basic = new BasicTool(); const ui = new UITool(); ``` -------------------------------- ### Get All Reader Windows Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-tools.md Retrieves an array of all Zotero reader instances that are not part of the current window's tabs. Useful for managing readers across multiple browser windows. ```typescript const windowReaders = readerTool.getWindowReader(); console.log(`${windowReaders.length} readers in other windows`); ``` -------------------------------- ### Register a Basic Command Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-managers.md Register a command with a name, label, ID, and a callback. The callback is executed when the command is selected. ```typescript const promptMgr = new PromptManager(); promptMgr.register([ { name: 'Toggle Dark Mode', label: 'Settings', id: 'toggle-dark-mode', callback: (prompt) => { Zotero.Prefs.set('darkMode', !Zotero.Prefs.get('darkMode')); } } ]); ``` -------------------------------- ### Access PDF Reader and Annotations Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/summary.md Provides methods to get the active PDF reader instance and retrieve data for the currently selected annotation, including page number and text. ```typescript const reader = ztoolkit.Reader; // Get active reader const activeReader = await reader.getReader(); // Get selected annotation const annotation = reader.getSelectedAnnotationData(activeReader); if (annotation) { console.log(`Page ${annotation.pageLabel}: ${annotation.text}`); } ``` -------------------------------- ### Access and Manipulate Extra Fields Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/summary.md Provides utilities for getting, setting, and deleting custom extra fields associated with Zotero items. Supports appending or replacing field values. ```typescript const extra = ztoolkit.ExtraField; const item = Zotero.Items.get(123); // Get all fields const fields = extra.getExtraFields(item, 'enhanced'); // Get single field const value = extra.getExtraField(item, 'key'); // Set field (replace or append) await extra.setExtraField(item, 'key', 'value', { append: false }); // Delete field await extra.setExtraField(item, 'key', ''); ``` -------------------------------- ### show Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-helpers.md Displays the progress notification window to the user. Can optionally specify a close time. ```APIDOC ## show(closeTime) ### Description Displays the progress window. ### Parameters #### Path Parameters - **closeTime** (number) - Optional - Time in milliseconds after which the window will auto-close. ### Returns - ProgressWindowHelper - Returns `this` for chaining. ``` -------------------------------- ### Perform Copy Operation with Chained Additions Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-helpers.md Chain multiple add operations (text and HTML) and then execute the copy command. This example demonstrates adding both plain text and HTML before copying. ```typescript new ClipboardHelper() .addText("Hello", "text/plain") .addText("

Hello

", "text/html") .copy(); ``` -------------------------------- ### Initialize PromptManager Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-managers.md Instantiate the PromptManager to manage commands for the command palette. ```typescript const prompt = new PromptManager(); ``` -------------------------------- ### Get Zotero Global (Static) Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-basic-tool.md Access the Zotero global object directly using a static method, without needing an instance of BasicTool. This is useful for early initialization or utility functions. ```typescript const Zotero = BasicTool.getZotero(); ``` -------------------------------- ### createElement() (XUL) Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-ui-tool.md Creates a XUL element, commonly used for Zotero-specific UI components, with provided tag name and properties. ```APIDOC ## createElement() (XUL) ```typescript createElement(doc: Document, tagName: keyof XULElementTagNameMap, props?: XULElementProps): T ``` ### Description Create a XUL element (Zotero-specific UI element). ### Parameters - **doc** (Document) - Target document - **tagName** (string) - XUL tag name (`menuitem`, `hbox`, `vbox`, etc.) - **props** (XULElementProps) - Element properties and configuration ### Example ```typescript const menuitem = ui.createElement(document, 'menuitem', { namespace: 'xul', attributes: { label: 'Click Me!' } }); ``` ``` -------------------------------- ### Access and Modify Data with Proxy Object Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-helpers.md Use the `asObject()` method to get a Proxy object for direct property access. This allows for intuitive data manipulation similar to standard JavaScript objects. ```typescript const storage = prefs.asObject(); storage.myData = { name: "John", age: 30 }; console.log(storage.myData); // { name: "John", age: 30 } delete storage.myData; ``` -------------------------------- ### Initialize BasicTool with Custom Options Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/configuration.md Provide a custom configuration object to BasicTool during initialization. This allows full control over logging, API, debug, and listener settings. ```typescript // Option 3: Provide custom options const tool3 = new BasicTool({ log: { _type: "toolkitlog", disableConsole: false, disableZLog: false, prefix: "MyPlugin" }, api: { pluginID: "my-plugin@example.com" }, debug: { disableDebugBridgePassword: false, password: "" }, listeners: { callbacks: { onMainWindowLoad: new Set(), onMainWindowUnload: new Set(), onPluginUnload: new Set() } } }); ``` -------------------------------- ### Get Extra Fields (Enhanced Parser) Source: https://github.com/windingwind/zotero-plugin-toolkit/blob/main/_autodocs/api-reference-tools.md Retrieve extra fields using an enhanced parser that supports multiple string values per key. Non-standard lines are stored under the '__nonStandard__' key. ```typescript // Extra field content: // title: My Title // title: Alternative Title // author: John Doe // custom-field: value const fields = extra.getExtraFields(item, "enhanced"); console.log(fields.get('title')); // ['My Title', 'Alternative Title'] console.log(fields.get('author')); // ['John Doe'] ```