docusaurus-plugin-glossary 3.3.3 → 3.3.4

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.
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Shared type definitions for docusaurus-plugin-glossary.
3
+ *
4
+ * Single source of truth for the *declared* public data shapes. Both the plugin
5
+ * entry point (`src/index.ts`) and the remark plugin declaration
6
+ * (`src/remark/glossary-terms.d.ts`) consume these, so the declarations can't
7
+ * drift from each other.
8
+ *
9
+ * Note: the remark runtime (`src/remark/glossary-terms.js`) is plain JS with
10
+ * `checkJs: false`, so it is NOT type-checked against these shapes — keep it in
11
+ * sync by hand.
12
+ */
13
+ /** A single glossary entry. */
14
+ interface GlossaryTerm {
15
+ term: string;
16
+ definition: string;
17
+ abbreviation?: string;
18
+ relatedTerms?: string[];
19
+ id?: string;
20
+ autoLink?: boolean;
21
+ aliases?: string[];
22
+ caseSensitive?: boolean;
23
+ }
24
+ /** Shape of a glossary JSON file. */
25
+ interface GlossaryData {
26
+ title?: string;
27
+ description?: string;
28
+ terms: GlossaryTerm[];
29
+ }
30
+ /** Options accepted by the glossary plugin / preset. */
31
+ interface GlossaryPluginOptions {
32
+ glossaryPath?: string;
33
+ routePath?: string;
34
+ autoLinkTerms?: boolean;
35
+ /**
36
+ * When true, the first canonical occurrence of any term that has an `abbreviation` is
37
+ * rendered as "Long Form (Term)" instead of just "Term", enforcing the convention of
38
+ * introducing an acronym on first use. Subsequent occurrences in the same file render
39
+ * normally. Default: false.
40
+ */
41
+ expandAcronymsOnFirstUse?: boolean;
42
+ }
43
+ /** Options accepted by the `remark/glossary-terms` plugin. */
44
+ interface RemarkGlossaryTermsOptions {
45
+ terms?: GlossaryTerm[];
46
+ glossaryPath?: string | null;
47
+ routePath?: string;
48
+ siteDir?: string | null;
49
+ expandAcronymsOnFirstUse?: boolean;
50
+ }
51
+ /** The transformer returned by the remark plugin factory. */
52
+ type RemarkGlossaryTermsTransformer = (tree: unknown) => unknown;
53
+
54
+ export type { GlossaryPluginOptions as G, RemarkGlossaryTermsOptions as R, GlossaryData as a, GlossaryTerm as b, RemarkGlossaryTermsTransformer as c };
@@ -1,2 +1,46 @@
1
- export { GlossaryValidationError, ValidationError, ValidationResult, formatValidationErrors, validateGlossaryData } from './index.cjs';
2
- import '@docusaurus/types';
1
+ import { a as GlossaryData } from './types-B6LWPlBY.cjs';
2
+
3
+ interface ValidationError {
4
+ field: string;
5
+ message: string;
6
+ value?: unknown;
7
+ }
8
+ interface ValidationResult {
9
+ valid: boolean;
10
+ errors: ValidationError[];
11
+ data: GlossaryData;
12
+ }
13
+ /**
14
+ * Validates glossary data structure
15
+ *
16
+ * Ensures the glossary data conforms to the expected schema:
17
+ * - Must be an object with a "terms" array
18
+ * - Each term must have "term" (string) and "definition" (string)
19
+ * - Optional fields: abbreviation (string), relatedTerms (string[]), id (string)
20
+ *
21
+ * @param data - The data to validate
22
+ * @param options - Validation options
23
+ * @param options.throwOnError - If true, throws an error on validation failure (default: true)
24
+ * @returns Validation result with errors and sanitized data
25
+ * @throws Error if data is invalid and throwOnError is true
26
+ */
27
+ declare function validateGlossaryData(data: unknown, options?: {
28
+ throwOnError?: boolean;
29
+ }): ValidationResult;
30
+ /**
31
+ * Custom error class for glossary validation errors
32
+ * Provides detailed error messages for debugging
33
+ */
34
+ declare class GlossaryValidationError extends Error {
35
+ readonly errors: ValidationError[];
36
+ constructor(errors: ValidationError[]);
37
+ }
38
+ /**
39
+ * Formats validation errors into a readable string
40
+ *
41
+ * @param errors - Array of validation errors
42
+ * @returns Formatted error message
43
+ */
44
+ declare function formatValidationErrors(errors: ValidationError[]): string;
45
+
46
+ export { GlossaryValidationError, type ValidationError, type ValidationResult, formatValidationErrors, validateGlossaryData };
@@ -1,2 +1,46 @@
1
- export { GlossaryValidationError, ValidationError, ValidationResult, formatValidationErrors, validateGlossaryData } from './index.js';
2
- import '@docusaurus/types';
1
+ import { a as GlossaryData } from './types-B6LWPlBY.js';
2
+
3
+ interface ValidationError {
4
+ field: string;
5
+ message: string;
6
+ value?: unknown;
7
+ }
8
+ interface ValidationResult {
9
+ valid: boolean;
10
+ errors: ValidationError[];
11
+ data: GlossaryData;
12
+ }
13
+ /**
14
+ * Validates glossary data structure
15
+ *
16
+ * Ensures the glossary data conforms to the expected schema:
17
+ * - Must be an object with a "terms" array
18
+ * - Each term must have "term" (string) and "definition" (string)
19
+ * - Optional fields: abbreviation (string), relatedTerms (string[]), id (string)
20
+ *
21
+ * @param data - The data to validate
22
+ * @param options - Validation options
23
+ * @param options.throwOnError - If true, throws an error on validation failure (default: true)
24
+ * @returns Validation result with errors and sanitized data
25
+ * @throws Error if data is invalid and throwOnError is true
26
+ */
27
+ declare function validateGlossaryData(data: unknown, options?: {
28
+ throwOnError?: boolean;
29
+ }): ValidationResult;
30
+ /**
31
+ * Custom error class for glossary validation errors
32
+ * Provides detailed error messages for debugging
33
+ */
34
+ declare class GlossaryValidationError extends Error {
35
+ readonly errors: ValidationError[];
36
+ constructor(errors: ValidationError[]);
37
+ }
38
+ /**
39
+ * Formats validation errors into a readable string
40
+ *
41
+ * @param errors - Array of validation errors
42
+ * @returns Formatted error message
43
+ */
44
+ declare function formatValidationErrors(errors: ValidationError[]): string;
45
+
46
+ export { GlossaryValidationError, type ValidationError, type ValidationResult, formatValidationErrors, validateGlossaryData };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "docusaurus-plugin-glossary",
3
- "version": "3.3.3",
3
+ "version": "3.3.4",
4
4
  "description": "A Docusaurus plugin for creating and managing glossary terms with auto-generated pages and inline tooltips",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -8,19 +8,34 @@
8
8
  "types": "dist/index.d.ts",
9
9
  "exports": {
10
10
  ".": {
11
- "types": "./dist/index.d.ts",
12
- "import": "./dist/index.js",
13
- "require": "./dist/index.cjs"
11
+ "import": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ },
15
+ "require": {
16
+ "types": "./dist/index.d.cts",
17
+ "default": "./dist/index.cjs"
18
+ }
14
19
  },
15
20
  "./preset": {
16
- "types": "./dist/preset.d.ts",
17
- "import": "./dist/preset.js",
18
- "require": "./dist/preset.cjs"
21
+ "import": {
22
+ "types": "./dist/preset.d.ts",
23
+ "default": "./dist/preset.js"
24
+ },
25
+ "require": {
26
+ "types": "./dist/preset.d.cts",
27
+ "default": "./dist/preset.cjs"
28
+ }
19
29
  },
20
30
  "./remark/glossary-terms": {
21
- "types": "./dist/remark/glossary-terms.d.ts",
22
- "import": "./dist/remark/glossary-terms.js",
23
- "require": "./dist/remark/glossary-terms.cjs"
31
+ "import": {
32
+ "types": "./dist/remark/glossary-terms.d.ts",
33
+ "default": "./dist/remark/glossary-terms.js"
34
+ },
35
+ "require": {
36
+ "types": "./dist/remark/glossary-terms.d.cts",
37
+ "default": "./dist/remark/glossary-terms.cjs"
38
+ }
24
39
  }
25
40
  },
26
41
  "files": [
@@ -34,6 +49,7 @@
34
49
  "watch": "npm run dev",
35
50
  "clean": "rimraf dist",
36
51
  "typecheck": "tsc --noEmit",
52
+ "check:exports": "npm run build && attw --pack --profile node16 .",
37
53
  "test": "jest",
38
54
  "test:watch": "jest --watch",
39
55
  "test:coverage": "jest --coverage",
@@ -44,7 +60,7 @@
44
60
  "example:serve": "npm --prefix examples/docusaurus-v3 run serve",
45
61
  "example:clear": "npm --prefix examples/docusaurus-v3 run clear",
46
62
  "prepare": "husky",
47
- "prepublishOnly": "npm run build && npm test",
63
+ "prepublishOnly": "npm run build && npm test && npm run check:exports",
48
64
  "format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,css,md}\"",
49
65
  "format:check": "prettier --check \"**/*.{js,jsx,ts,tsx,json,css,md}\"",
50
66
  "lint": "eslint \"src/**/*.{js,jsx,ts,tsx}\" \"__tests__/**/*.js\"",
@@ -80,9 +96,10 @@
80
96
  "validate-peer-dependencies": "^2.2.0"
81
97
  },
82
98
  "engines": {
83
- "node": ">=18.0"
99
+ "node": ">=20.0"
84
100
  },
85
101
  "devDependencies": {
102
+ "@arethetypeswrong/cli": "^0.18.4",
86
103
  "@babel/preset-env": "^7.28.5",
87
104
  "@babel/preset-react": "^7.28.5",
88
105
  "@babel/preset-typescript": "^7.28.5",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["// @ts-ignore\nimport path from 'path';\n// @ts-ignore\nimport { fileURLToPath } from 'url';\nimport fs from 'fs-extra';\nimport type { LoadContext, Plugin } from '@docusaurus/types';\nimport validatePeerDependencies from 'validate-peer-dependencies';\nimport remarkGlossaryTerms from './remark/glossary-terms.js';\nimport { validateGlossaryData, GlossaryValidationError } from './validation.js';\n\n// Standard ES module directory resolution\nconst currentFilePath = fileURLToPath(import.meta.url);\nconst currentDir = path.dirname(currentFilePath);\n\n// Validate peer dependencies at module load time\nvalidatePeerDependencies(currentDir);\n\nexport interface GlossaryPluginOptions {\n glossaryPath?: string;\n routePath?: string;\n autoLinkTerms?: boolean;\n /**\n * When true, the first canonical occurrence of any term that has an `abbreviation` is\n * rendered as \"Long Form (Term)\" instead of just \"Term\", enforcing the convention of\n * introducing an acronym on first use. Subsequent occurrences in the same file render\n * normally. Default: false.\n */\n expandAcronymsOnFirstUse?: boolean;\n}\n\nexport interface GlossaryTerm {\n term: string;\n definition: string;\n abbreviation?: string;\n relatedTerms?: string[];\n id?: string;\n autoLink?: boolean;\n aliases?: string[];\n caseSensitive?: boolean;\n}\n\nexport interface GlossaryData {\n title?: string;\n description?: string;\n terms: GlossaryTerm[];\n}\n\n/**\n * Docusaurus Glossary Plugin\n *\n * A plugin that provides glossary functionality with:\n * - Glossary terms defined in a JSON file\n * - Auto-generated glossary page with term definitions\n * - GlossaryTerm component for inline definitions with interactive tooltips\n * - Automatic client-side initialization via getClientModules() (no manual imports needed)\n * - Optional automatic glossary term detection in markdown files via remark plugin\n *\n * ## Basic Usage (Manual Term Markup)\n *\n * Just install the plugin - the GlossaryTerm component is automatically available:\n * ```javascript\n * module.exports = {\n * plugins: [\n * ['docusaurus-plugin-glossary', {\n * glossaryPath: 'glossary/glossary.json',\n * routePath: '/glossary',\n * }],\n * ],\n * };\n * ```\n *\n * Then use `<GlossaryTerm>` in your MDX files without importing:\n * ```mdx\n * <GlossaryTerm term=\"API\">API</GlossaryTerm>\n * ```\n *\n * ## Advanced Usage (Automatic Term Detection)\n *\n * To automatically detect and link glossary terms in markdown, add the remark plugin:\n * ```javascript\n * const glossaryPlugin = require('docusaurus-plugin-glossary');\n *\n * module.exports = {\n * presets: [\n * ['@docusaurus/preset-classic', {\n * docs: {\n * remarkPlugins: [\n * glossaryPlugin.getRemarkPlugin({\n * glossaryPath: 'glossary/glossary.json',\n * routePath: '/glossary',\n * }, { siteDir: __dirname }),\n * ],\n * },\n * }],\n * ],\n * plugins: [\n * ['docusaurus-plugin-glossary', {\n * glossaryPath: 'glossary/glossary.json',\n * routePath: '/glossary',\n * }],\n * ],\n * };\n * ```\n *\n * @param context - Docusaurus context\n * @param options - Plugin options\n * @param options.glossaryPath - Path to glossary JSON file (default: 'glossary/glossary.json')\n * @param options.routePath - Route path for glossary page (default: '/glossary')\n * @param options.autoLinkTerms - Legacy option, kept for compatibility but no longer used (configure remark plugin manually instead)\n * @returns Plugin object\n */\nexport default function glossaryPlugin(\n context: LoadContext,\n options: GlossaryPluginOptions = {}\n): Plugin {\n const { glossaryPath = 'glossary/glossary.json', routePath = '/glossary' } = options;\n\n return {\n name: 'docusaurus-plugin-glossary',\n\n getClientModules() {\n return [path.resolve(currentDir, './client/index.js')];\n },\n\n async loadContent() {\n // Load glossary terms from JSON file\n const glossaryFilePath = path.resolve(context.siteDir, glossaryPath);\n\n if (await fs.pathExists(glossaryFilePath)) {\n try {\n const rawData = await fs.readJson(glossaryFilePath);\n\n // Validate glossary data structure\n const validationResult = validateGlossaryData(rawData, { throwOnError: false });\n\n if (!validationResult.valid) {\n console.warn(\n `[glossary-plugin] Glossary file has validation errors at ${glossaryFilePath}:`\n );\n validationResult.errors.forEach(err => {\n console.warn(` - [${err.field}] ${err.message}`);\n });\n console.warn('[glossary-plugin] Proceeding with valid terms only.');\n }\n\n return validationResult.data;\n } catch (error) {\n if (error instanceof GlossaryValidationError) {\n throw error;\n }\n // JSON parsing error\n throw new Error(\n `Failed to parse glossary file at ${glossaryFilePath}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n console.warn(`Glossary file not found at ${glossaryFilePath}. Using empty glossary.`);\n return { terms: [] };\n },\n\n async contentLoaded({ content, actions }) {\n const { createData, addRoute, setGlobalData } = actions;\n const glossaryContent = content as GlossaryData;\n\n // Create data file that can be imported by components\n const glossaryDataPath = await createData(\n 'glossary-data.json',\n JSON.stringify(glossaryContent)\n );\n\n // Create a data file for the remark plugin to access glossary terms\n await createData(\n 'remark-glossary-data.json',\n JSON.stringify({\n terms: glossaryContent.terms || [],\n routePath: routePath,\n })\n );\n\n // Add glossary page route\n addRoute({\n path: routePath,\n component: path.join(currentDir, 'components/GlossaryPage.js'),\n exact: true,\n modules: {\n glossaryData: glossaryDataPath,\n },\n });\n\n // Expose global data for runtime lookups (used by GlossaryTerm)\n setGlobalData({\n terms: glossaryContent.terms || [],\n routePath,\n });\n },\n\n getThemePath() {\n return path.resolve(currentDir, './theme');\n },\n\n getPathsToWatch() {\n return [path.resolve(context.siteDir, glossaryPath)];\n },\n\n async postBuild() {\n // You can add any post-build steps here if needed\n console.log('Glossary plugin: Build completed');\n },\n };\n}\n\n// Export remark plugin factory for use in markdown configuration\nexport const remarkPlugin = remarkGlossaryTerms;\n\n// Export cache clearing utility\nexport { clearGlossaryCache } from './remark/glossary-terms.js';\n\n// Export validation utilities\nexport {\n validateGlossaryData,\n GlossaryValidationError,\n formatValidationErrors,\n type ValidationError,\n type ValidationResult,\n} from './validation.js';\n\n/**\n * Helper function to get the configured remark plugin\n * This can be used in docusaurus.config.js markdown configuration\n *\n * @param pluginOptions - Plugin options from docusaurus.config.js\n * @param context - Context with siteDir\n * @returns Configured remark plugin\n */\nexport function getRemarkPlugin(\n pluginOptions: GlossaryPluginOptions,\n context?: { siteDir?: string }\n): [\n typeof remarkGlossaryTerms,\n {\n glossaryPath: string;\n routePath: string;\n siteDir?: string;\n expandAcronymsOnFirstUse: boolean;\n },\n] {\n const {\n glossaryPath = 'glossary/glossary.json',\n routePath = '/glossary',\n expandAcronymsOnFirstUse = false,\n } = pluginOptions;\n\n const siteDir = context?.siteDir;\n\n return [\n remarkGlossaryTerms,\n {\n glossaryPath,\n routePath,\n siteDir,\n expandAcronymsOnFirstUse,\n },\n ];\n}\n"],"mappings":";;;;;;;;;AACA,OAAO,UAAU;AAEjB,SAAS,qBAAqB;AAC9B,OAAO,QAAQ;AAEf,OAAO,8BAA8B;AAKrC,IAAM,kBAAkB,cAAc,YAAY,GAAG;AACrD,IAAM,aAAa,KAAK,QAAQ,eAAe;AAG/C,yBAAyB,UAAU;AAgGpB,SAAR,eACL,SACA,UAAiC,CAAC,GAC1B;AACR,QAAM,EAAE,eAAe,0BAA0B,YAAY,YAAY,IAAI;AAE7E,SAAO;AAAA,IACL,MAAM;AAAA,IAEN,mBAAmB;AACjB,aAAO,CAAC,KAAK,QAAQ,YAAY,mBAAmB,CAAC;AAAA,IACvD;AAAA,IAEA,MAAM,cAAc;AAElB,YAAM,mBAAmB,KAAK,QAAQ,QAAQ,SAAS,YAAY;AAEnE,UAAI,MAAM,GAAG,WAAW,gBAAgB,GAAG;AACzC,YAAI;AACF,gBAAM,UAAU,MAAM,GAAG,SAAS,gBAAgB;AAGlD,gBAAM,mBAAmB,qBAAqB,SAAS,EAAE,cAAc,MAAM,CAAC;AAE9E,cAAI,CAAC,iBAAiB,OAAO;AAC3B,oBAAQ;AAAA,cACN,4DAA4D,gBAAgB;AAAA,YAC9E;AACA,6BAAiB,OAAO,QAAQ,SAAO;AACrC,sBAAQ,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,OAAO,EAAE;AAAA,YAClD,CAAC;AACD,oBAAQ,KAAK,qDAAqD;AAAA,UACpE;AAEA,iBAAO,iBAAiB;AAAA,QAC1B,SAAS,OAAO;AACd,cAAI,iBAAiB,yBAAyB;AAC5C,kBAAM;AAAA,UACR;AAEA,gBAAM,IAAI;AAAA,YACR,oCAAoC,gBAAgB,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,UACjH;AAAA,QACF;AAAA,MACF;AAEA,cAAQ,KAAK,8BAA8B,gBAAgB,yBAAyB;AACpF,aAAO,EAAE,OAAO,CAAC,EAAE;AAAA,IACrB;AAAA,IAEA,MAAM,cAAc,EAAE,SAAS,QAAQ,GAAG;AACxC,YAAM,EAAE,YAAY,UAAU,cAAc,IAAI;AAChD,YAAM,kBAAkB;AAGxB,YAAM,mBAAmB,MAAM;AAAA,QAC7B;AAAA,QACA,KAAK,UAAU,eAAe;AAAA,MAChC;AAGA,YAAM;AAAA,QACJ;AAAA,QACA,KAAK,UAAU;AAAA,UACb,OAAO,gBAAgB,SAAS,CAAC;AAAA,UACjC;AAAA,QACF,CAAC;AAAA,MACH;AAGA,eAAS;AAAA,QACP,MAAM;AAAA,QACN,WAAW,KAAK,KAAK,YAAY,4BAA4B;AAAA,QAC7D,OAAO;AAAA,QACP,SAAS;AAAA,UACP,cAAc;AAAA,QAChB;AAAA,MACF,CAAC;AAGD,oBAAc;AAAA,QACZ,OAAO,gBAAgB,SAAS,CAAC;AAAA,QACjC;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IAEA,eAAe;AACb,aAAO,KAAK,QAAQ,YAAY,SAAS;AAAA,IAC3C;AAAA,IAEA,kBAAkB;AAChB,aAAO,CAAC,KAAK,QAAQ,QAAQ,SAAS,YAAY,CAAC;AAAA,IACrD;AAAA,IAEA,MAAM,YAAY;AAEhB,cAAQ,IAAI,kCAAkC;AAAA,IAChD;AAAA,EACF;AACF;AAGO,IAAM,eAAe;AAsBrB,SAAS,gBACd,eACA,SASA;AACA,QAAM;AAAA,IACJ,eAAe;AAAA,IACf,YAAY;AAAA,IACZ,2BAA2B;AAAA,EAC7B,IAAI;AAEJ,QAAM,UAAU,SAAS;AAEzB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;","names":[]}