docusaurus-plugin-glossary 3.1.0 → 3.3.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.
Files changed (51) hide show
  1. package/README.md +5 -0
  2. package/dist/chunk-22LFZL7L.js +109 -0
  3. package/dist/chunk-22LFZL7L.js.map +1 -0
  4. package/dist/chunk-7Z37JEHW.js +257 -0
  5. package/dist/chunk-7Z37JEHW.js.map +1 -0
  6. package/dist/chunk-WYKSBP3X.js +331 -0
  7. package/dist/chunk-WYKSBP3X.js.map +1 -0
  8. package/dist/client/index.cjs +55 -0
  9. package/dist/client/index.cjs.map +1 -0
  10. package/dist/client/index.js +10 -21
  11. package/dist/client/index.js.map +1 -0
  12. package/dist/components/GlossaryPage.cjs +131 -0
  13. package/dist/components/GlossaryPage.cjs.map +1 -0
  14. package/dist/components/GlossaryPage.js +75 -113
  15. package/dist/components/GlossaryPage.js.map +1 -0
  16. package/dist/index.cjs +724 -0
  17. package/dist/index.cjs.map +1 -0
  18. package/dist/index.d.cts +176 -0
  19. package/dist/index.d.ts +85 -11
  20. package/dist/index.js +23 -173
  21. package/dist/index.js.map +1 -0
  22. package/dist/preset.cjs +775 -0
  23. package/dist/preset.cjs.map +1 -0
  24. package/dist/preset.d.cts +98 -0
  25. package/dist/preset.d.ts +8 -7
  26. package/dist/preset.js +79 -143
  27. package/dist/preset.js.map +1 -0
  28. package/dist/remark/glossary-terms.cjs +365 -0
  29. package/dist/remark/glossary-terms.cjs.map +1 -0
  30. package/dist/remark/glossary-terms.js +9 -440
  31. package/dist/remark/glossary-terms.js.map +1 -0
  32. package/dist/{theme/GlossaryTerm/styles.module.css → styles.module-QQW7ISLV.module.css} +2 -4
  33. package/dist/theme/GlossaryTerm/index.cjs +138 -0
  34. package/dist/theme/GlossaryTerm/index.cjs.map +1 -0
  35. package/dist/theme/GlossaryTerm/index.js +56 -90
  36. package/dist/theme/GlossaryTerm/index.js.map +1 -0
  37. package/dist/validation.cjs +283 -0
  38. package/dist/validation.cjs.map +1 -0
  39. package/dist/validation.d.cts +2 -0
  40. package/dist/validation.d.ts +2 -44
  41. package/dist/validation.js +11 -256
  42. package/dist/validation.js.map +1 -0
  43. package/package.json +27 -32
  44. package/dist/components/GlossaryPage.test.js +0 -205
  45. package/dist/index.d.ts.map +0 -1
  46. package/dist/preset.d.ts.map +0 -1
  47. package/dist/remark/glossary-terms.d.ts +0 -28
  48. package/dist/remark/glossary-terms.d.ts.map +0 -1
  49. package/dist/theme/GlossaryTerm/index.test.js +0 -143
  50. package/dist/validation.d.ts.map +0 -1
  51. /package/dist/{components/GlossaryPage.module.css → GlossaryPage.module-M4DEUP4X.module.css} +0 -0
@@ -1,141 +1,107 @@
1
- import React, { useMemo, useState, useRef, useEffect, useCallback } from 'react';
2
- import { usePluginData } from '@docusaurus/useGlobalData';
3
- import styles from './styles.module.css';
4
-
5
- /**
6
- * GlossaryTerm component - displays an inline term with tooltip
7
- *
8
- * Usage:
9
- * import GlossaryTerm from '@theme/GlossaryTerm';
10
- *
11
- * <GlossaryTerm term="API" definition="Application Programming Interface" />
12
- * or
13
- * <GlossaryTerm term="API">custom display text</GlossaryTerm>
14
- *
15
- * @param {object} props
16
- * @param {string} props.term - The glossary term
17
- * @param {string} props.definition - The definition to show in tooltip
18
- * @param {string} props.routePath - Route path to glossary page (default: '/glossary')
19
- * @param {React.ReactNode} props.children - Optional custom display text
20
- */
21
- export default function GlossaryTerm({ term, definition, routePath = '/glossary', children }) {
1
+ // src/theme/GlossaryTerm/index.js
2
+ import React, { useMemo, useState, useRef, useEffect, useCallback } from "react";
3
+ import { usePluginData } from "@docusaurus/useGlobalData";
4
+ import styles from "../../styles.module-QQW7ISLV.module.css";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ function GlossaryTerm({ term, definition, routePath = "/glossary", children }) {
22
7
  const [showTooltip, setShowTooltip] = useState(false);
23
8
  const [tooltipStyle, setTooltipStyle] = useState(null);
24
- const [placement, setPlacement] = useState('top'); // 'top' | 'bottom'
9
+ const [placement, setPlacement] = useState("top");
25
10
  const wrapperRef = useRef(null);
26
11
  const tooltipRef = useRef(null);
27
-
28
12
  const updatePosition = useCallback(() => {
29
13
  if (!wrapperRef.current || !tooltipRef.current) return;
30
14
  const wrapperRect = wrapperRef.current.getBoundingClientRect();
31
15
  const tooltipRect = tooltipRef.current.getBoundingClientRect();
32
-
33
16
  const viewportWidth = window.innerWidth;
34
17
  const viewportHeight = window.innerHeight;
35
-
36
- const preferredGap = 8; // px
37
-
38
- // Decide top vs bottom based on available space
18
+ const preferredGap = 8;
39
19
  const hasSpaceAbove = wrapperRect.top >= tooltipRect.height + preferredGap;
40
20
  const hasSpaceBelow = viewportHeight - wrapperRect.bottom >= tooltipRect.height + preferredGap;
41
- const nextPlacement = hasSpaceAbove || !hasSpaceBelow ? 'top' : 'bottom';
42
-
21
+ const nextPlacement = hasSpaceAbove || !hasSpaceBelow ? "top" : "bottom";
43
22
  let top;
44
- if (nextPlacement === 'top') {
23
+ if (nextPlacement === "top") {
45
24
  top = wrapperRect.top - tooltipRect.height - preferredGap;
46
25
  } else {
47
26
  top = wrapperRect.bottom + preferredGap;
48
27
  }
49
-
50
- // Center horizontally on the wrapper, then clamp within viewport with margin
51
28
  const horizontalMargin = 8;
52
29
  let left = wrapperRect.left + wrapperRect.width / 2 - tooltipRect.width / 2;
53
30
  left = Math.max(
54
31
  horizontalMargin,
55
32
  Math.min(left, viewportWidth - tooltipRect.width - horizontalMargin)
56
33
  );
57
-
58
34
  setPlacement(nextPlacement);
59
35
  setTooltipStyle({ top: Math.max(4, top), left });
60
36
  }, []);
61
-
62
37
  useEffect(() => {
63
38
  if (!showTooltip) return;
64
-
65
- // Use double requestAnimationFrame to ensure DOM is fully rendered and layout is complete
66
- // This ensures tooltipRef.current is available and has proper dimensions
67
39
  let rafId2;
68
40
  const rafId1 = requestAnimationFrame(() => {
69
41
  rafId2 = requestAnimationFrame(() => {
70
42
  updatePosition();
71
43
  });
72
44
  });
73
-
74
45
  const onScroll = () => updatePosition();
75
46
  const onResize = () => updatePosition();
76
- window.addEventListener('scroll', onScroll, true);
77
- window.addEventListener('resize', onResize);
47
+ window.addEventListener("scroll", onScroll, true);
48
+ window.addEventListener("resize", onResize);
78
49
  return () => {
79
50
  cancelAnimationFrame(rafId1);
80
51
  if (rafId2) cancelAnimationFrame(rafId2);
81
- window.removeEventListener('scroll', onScroll, true);
82
- window.removeEventListener('resize', onResize);
52
+ window.removeEventListener("scroll", onScroll, true);
53
+ window.removeEventListener("resize", onResize);
83
54
  };
84
55
  }, [showTooltip, updatePosition]);
85
-
86
- // Pull definition/route from plugin global data if not provided
87
- const pluginData = usePluginData('docusaurus-plugin-glossary');
56
+ const pluginData = usePluginData("docusaurus-plugin-glossary");
88
57
  const effectiveDefinition = useMemo(() => {
89
- if (definition && typeof definition === 'string' && definition.length > 0) {
58
+ if (definition && typeof definition === "string" && definition.length > 0) {
90
59
  return definition;
91
60
  }
92
- const terms = (pluginData && pluginData.terms) || [];
61
+ const terms = pluginData && pluginData.terms || [];
93
62
  const found = terms.find(
94
- t => typeof t.term === 'string' && t.term.toLowerCase() === String(term).toLowerCase()
63
+ (t) => typeof t.term === "string" && t.term.toLowerCase() === String(term).toLowerCase()
95
64
  );
96
- return found && found.definition ? found.definition : undefined;
65
+ return found && found.definition ? found.definition : void 0;
97
66
  }, [definition, pluginData, term]);
98
-
99
67
  const effectiveRoutePath = useMemo(() => {
100
- if (routePath && typeof routePath === 'string' && routePath.length > 0) return routePath;
101
- return (pluginData && pluginData.routePath) || '/glossary';
68
+ if (routePath && typeof routePath === "string" && routePath.length > 0) return routePath;
69
+ return pluginData && pluginData.routePath || "/glossary";
102
70
  }, [pluginData, routePath]);
103
-
104
71
  const displayText = children || term;
105
- const termId = term.toLowerCase().replace(/\s+/g, '-');
106
-
107
- return (
108
- <span ref={wrapperRef} className={styles.glossaryTermWrapper}>
109
- <a
110
- href={`${effectiveRoutePath}#${termId}`}
111
- className={styles.glossaryTerm}
112
- onMouseEnter={() => setShowTooltip(true)}
113
- onMouseLeave={() => setShowTooltip(false)}
114
- onFocus={() => setShowTooltip(true)}
115
- onBlur={() => setShowTooltip(false)}
116
- aria-describedby={`tooltip-${termId}`}
117
- >
118
- {displayText}
119
- </a>
120
- {effectiveDefinition && (
121
- <span
122
- ref={tooltipRef}
123
- id={`tooltip-${termId}`}
124
- className={
125
- `${styles.tooltip} ${showTooltip ? styles.tooltipVisible : ''} ` +
126
- `${placement === 'top' ? styles.tooltipTop : styles.tooltipBottom} ` +
127
- `${styles.tooltipFloating}`
128
- }
129
- role="tooltip"
130
- style={
131
- showTooltip && tooltipStyle
132
- ? { top: `${tooltipStyle.top}px`, left: `${tooltipStyle.left}px` }
133
- : undefined
134
- }
135
- >
136
- <strong>{term}</strong> {effectiveDefinition}
137
- </span>
138
- )}
139
- </span>
140
- );
72
+ const termId = term.toLowerCase().replace(/\s+/g, "-");
73
+ return /* @__PURE__ */ jsxs("span", { ref: wrapperRef, className: styles.glossaryTermWrapper, children: [
74
+ /* @__PURE__ */ jsx(
75
+ "a",
76
+ {
77
+ href: `${effectiveRoutePath}#${termId}`,
78
+ className: styles.glossaryTerm,
79
+ onMouseEnter: () => setShowTooltip(true),
80
+ onMouseLeave: () => setShowTooltip(false),
81
+ onFocus: () => setShowTooltip(true),
82
+ onBlur: () => setShowTooltip(false),
83
+ "aria-describedby": `tooltip-${termId}`,
84
+ children: displayText
85
+ }
86
+ ),
87
+ effectiveDefinition && /* @__PURE__ */ jsxs(
88
+ "span",
89
+ {
90
+ ref: tooltipRef,
91
+ id: `tooltip-${termId}`,
92
+ className: `${styles.tooltip} ${showTooltip ? styles.tooltipVisible : ""} ${placement === "top" ? styles.tooltipTop : styles.tooltipBottom} ${styles.tooltipFloating}`,
93
+ role: "tooltip",
94
+ style: showTooltip && tooltipStyle ? { top: `${tooltipStyle.top}px`, left: `${tooltipStyle.left}px` } : void 0,
95
+ children: [
96
+ /* @__PURE__ */ jsx("strong", { children: term }),
97
+ " ",
98
+ effectiveDefinition
99
+ ]
100
+ }
101
+ )
102
+ ] });
141
103
  }
104
+ export {
105
+ GlossaryTerm as default
106
+ };
107
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/theme/GlossaryTerm/index.js"],"sourcesContent":["import React, { useMemo, useState, useRef, useEffect, useCallback } from 'react';\nimport { usePluginData } from '@docusaurus/useGlobalData';\nimport styles from './styles.module.css';\n\n/**\n * GlossaryTerm component - displays an inline term with tooltip\n *\n * Usage:\n * import GlossaryTerm from '@theme/GlossaryTerm';\n *\n * <GlossaryTerm term=\"API\" definition=\"Application Programming Interface\" />\n * or\n * <GlossaryTerm term=\"API\">custom display text</GlossaryTerm>\n *\n * @param {object} props\n * @param {string} props.term - The glossary term\n * @param {string} props.definition - The definition to show in tooltip\n * @param {string} props.routePath - Route path to glossary page (default: '/glossary')\n * @param {React.ReactNode} props.children - Optional custom display text\n */\nexport default function GlossaryTerm({ term, definition, routePath = '/glossary', children }) {\n const [showTooltip, setShowTooltip] = useState(false);\n const [tooltipStyle, setTooltipStyle] = useState(null);\n const [placement, setPlacement] = useState('top'); // 'top' | 'bottom'\n const wrapperRef = useRef(null);\n const tooltipRef = useRef(null);\n\n const updatePosition = useCallback(() => {\n if (!wrapperRef.current || !tooltipRef.current) return;\n const wrapperRect = wrapperRef.current.getBoundingClientRect();\n const tooltipRect = tooltipRef.current.getBoundingClientRect();\n\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n\n const preferredGap = 8; // px\n\n // Decide top vs bottom based on available space\n const hasSpaceAbove = wrapperRect.top >= tooltipRect.height + preferredGap;\n const hasSpaceBelow = viewportHeight - wrapperRect.bottom >= tooltipRect.height + preferredGap;\n const nextPlacement = hasSpaceAbove || !hasSpaceBelow ? 'top' : 'bottom';\n\n let top;\n if (nextPlacement === 'top') {\n top = wrapperRect.top - tooltipRect.height - preferredGap;\n } else {\n top = wrapperRect.bottom + preferredGap;\n }\n\n // Center horizontally on the wrapper, then clamp within viewport with margin\n const horizontalMargin = 8;\n let left = wrapperRect.left + wrapperRect.width / 2 - tooltipRect.width / 2;\n left = Math.max(\n horizontalMargin,\n Math.min(left, viewportWidth - tooltipRect.width - horizontalMargin)\n );\n\n setPlacement(nextPlacement);\n setTooltipStyle({ top: Math.max(4, top), left });\n }, []);\n\n useEffect(() => {\n if (!showTooltip) return;\n\n // Use double requestAnimationFrame to ensure DOM is fully rendered and layout is complete\n // This ensures tooltipRef.current is available and has proper dimensions\n let rafId2;\n const rafId1 = requestAnimationFrame(() => {\n rafId2 = requestAnimationFrame(() => {\n updatePosition();\n });\n });\n\n const onScroll = () => updatePosition();\n const onResize = () => updatePosition();\n window.addEventListener('scroll', onScroll, true);\n window.addEventListener('resize', onResize);\n return () => {\n cancelAnimationFrame(rafId1);\n if (rafId2) cancelAnimationFrame(rafId2);\n window.removeEventListener('scroll', onScroll, true);\n window.removeEventListener('resize', onResize);\n };\n }, [showTooltip, updatePosition]);\n\n // Pull definition/route from plugin global data if not provided\n const pluginData = usePluginData('docusaurus-plugin-glossary');\n const effectiveDefinition = useMemo(() => {\n if (definition && typeof definition === 'string' && definition.length > 0) {\n return definition;\n }\n const terms = (pluginData && pluginData.terms) || [];\n const found = terms.find(\n t => typeof t.term === 'string' && t.term.toLowerCase() === String(term).toLowerCase()\n );\n return found && found.definition ? found.definition : undefined;\n }, [definition, pluginData, term]);\n\n const effectiveRoutePath = useMemo(() => {\n if (routePath && typeof routePath === 'string' && routePath.length > 0) return routePath;\n return (pluginData && pluginData.routePath) || '/glossary';\n }, [pluginData, routePath]);\n\n const displayText = children || term;\n const termId = term.toLowerCase().replace(/\\s+/g, '-');\n\n return (\n <span ref={wrapperRef} className={styles.glossaryTermWrapper}>\n <a\n href={`${effectiveRoutePath}#${termId}`}\n className={styles.glossaryTerm}\n onMouseEnter={() => setShowTooltip(true)}\n onMouseLeave={() => setShowTooltip(false)}\n onFocus={() => setShowTooltip(true)}\n onBlur={() => setShowTooltip(false)}\n aria-describedby={`tooltip-${termId}`}\n >\n {displayText}\n </a>\n {effectiveDefinition && (\n <span\n ref={tooltipRef}\n id={`tooltip-${termId}`}\n className={\n `${styles.tooltip} ${showTooltip ? styles.tooltipVisible : ''} ` +\n `${placement === 'top' ? styles.tooltipTop : styles.tooltipBottom} ` +\n `${styles.tooltipFloating}`\n }\n role=\"tooltip\"\n style={\n showTooltip && tooltipStyle\n ? { top: `${tooltipStyle.top}px`, left: `${tooltipStyle.left}px` }\n : undefined\n }\n >\n <strong>{term}</strong> {effectiveDefinition}\n </span>\n )}\n </span>\n );\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,283 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/validation.ts
21
+ var validation_exports = {};
22
+ __export(validation_exports, {
23
+ GlossaryValidationError: () => GlossaryValidationError,
24
+ formatValidationErrors: () => formatValidationErrors,
25
+ validateGlossaryData: () => validateGlossaryData
26
+ });
27
+ module.exports = __toCommonJS(validation_exports);
28
+ function validateTerm(term, index) {
29
+ const errors = [];
30
+ const prefix = `terms[${index}]`;
31
+ if (term === null || term === void 0) {
32
+ errors.push({
33
+ field: prefix,
34
+ message: "Term cannot be null or undefined",
35
+ value: term
36
+ });
37
+ return errors;
38
+ }
39
+ if (typeof term !== "object") {
40
+ errors.push({
41
+ field: prefix,
42
+ message: `Term must be an object, got ${typeof term}`,
43
+ value: term
44
+ });
45
+ return errors;
46
+ }
47
+ const termObj = term;
48
+ if (!("term" in termObj)) {
49
+ errors.push({
50
+ field: `${prefix}.term`,
51
+ message: 'Missing required field "term"'
52
+ });
53
+ } else if (typeof termObj.term !== "string") {
54
+ errors.push({
55
+ field: `${prefix}.term`,
56
+ message: `Field "term" must be a string, got ${typeof termObj.term}`,
57
+ value: termObj.term
58
+ });
59
+ } else if (termObj.term.trim() === "") {
60
+ errors.push({
61
+ field: `${prefix}.term`,
62
+ message: 'Field "term" cannot be empty',
63
+ value: termObj.term
64
+ });
65
+ }
66
+ if (!("definition" in termObj)) {
67
+ errors.push({
68
+ field: `${prefix}.definition`,
69
+ message: 'Missing required field "definition"'
70
+ });
71
+ } else if (typeof termObj.definition !== "string") {
72
+ errors.push({
73
+ field: `${prefix}.definition`,
74
+ message: `Field "definition" must be a string, got ${typeof termObj.definition}`,
75
+ value: termObj.definition
76
+ });
77
+ }
78
+ if ("abbreviation" in termObj && termObj.abbreviation !== void 0) {
79
+ if (typeof termObj.abbreviation !== "string") {
80
+ errors.push({
81
+ field: `${prefix}.abbreviation`,
82
+ message: `Field "abbreviation" must be a string, got ${typeof termObj.abbreviation}`,
83
+ value: termObj.abbreviation
84
+ });
85
+ }
86
+ }
87
+ if ("relatedTerms" in termObj && termObj.relatedTerms !== void 0) {
88
+ if (!Array.isArray(termObj.relatedTerms)) {
89
+ errors.push({
90
+ field: `${prefix}.relatedTerms`,
91
+ message: `Field "relatedTerms" must be an array, got ${typeof termObj.relatedTerms}`,
92
+ value: termObj.relatedTerms
93
+ });
94
+ } else {
95
+ termObj.relatedTerms.forEach((relatedTerm, relatedIndex) => {
96
+ if (typeof relatedTerm !== "string") {
97
+ errors.push({
98
+ field: `${prefix}.relatedTerms[${relatedIndex}]`,
99
+ message: `Related term must be a string, got ${typeof relatedTerm}`,
100
+ value: relatedTerm
101
+ });
102
+ }
103
+ });
104
+ }
105
+ }
106
+ if ("id" in termObj && termObj.id !== void 0) {
107
+ if (typeof termObj.id !== "string") {
108
+ errors.push({
109
+ field: `${prefix}.id`,
110
+ message: `Field "id" must be a string, got ${typeof termObj.id}`,
111
+ value: termObj.id
112
+ });
113
+ }
114
+ }
115
+ if ("autoLink" in termObj && termObj.autoLink !== void 0) {
116
+ if (typeof termObj.autoLink !== "boolean") {
117
+ errors.push({
118
+ field: `${prefix}.autoLink`,
119
+ message: `Field "autoLink" must be a boolean, got ${typeof termObj.autoLink}`,
120
+ value: termObj.autoLink
121
+ });
122
+ }
123
+ }
124
+ if ("aliases" in termObj && termObj.aliases !== void 0) {
125
+ if (!Array.isArray(termObj.aliases)) {
126
+ errors.push({
127
+ field: `${prefix}.aliases`,
128
+ message: `Field "aliases" must be an array, got ${typeof termObj.aliases}`,
129
+ value: termObj.aliases
130
+ });
131
+ } else {
132
+ termObj.aliases.forEach((alias, aliasIndex) => {
133
+ if (typeof alias !== "string") {
134
+ errors.push({
135
+ field: `${prefix}.aliases[${aliasIndex}]`,
136
+ message: `Alias must be a string, got ${typeof alias}`,
137
+ value: alias
138
+ });
139
+ } else if (alias.trim() === "") {
140
+ errors.push({
141
+ field: `${prefix}.aliases[${aliasIndex}]`,
142
+ message: "Alias cannot be empty",
143
+ value: alias
144
+ });
145
+ }
146
+ });
147
+ }
148
+ }
149
+ return errors;
150
+ }
151
+ function validateGlossaryData(data, options = {}) {
152
+ const { throwOnError = true } = options;
153
+ const errors = [];
154
+ if (data === null || data === void 0) {
155
+ errors.push({
156
+ field: "root",
157
+ message: "Glossary data cannot be null or undefined",
158
+ value: data
159
+ });
160
+ if (throwOnError && errors.length > 0) {
161
+ throw new GlossaryValidationError(errors);
162
+ }
163
+ return { valid: false, errors, data: { terms: [] } };
164
+ }
165
+ if (typeof data !== "object") {
166
+ errors.push({
167
+ field: "root",
168
+ message: `Glossary data must be an object, got ${typeof data}`,
169
+ value: data
170
+ });
171
+ if (throwOnError && errors.length > 0) {
172
+ throw new GlossaryValidationError(errors);
173
+ }
174
+ return { valid: false, errors, data: { terms: [] } };
175
+ }
176
+ const glossaryData = data;
177
+ if ("title" in glossaryData && typeof glossaryData.title !== "string") {
178
+ errors.push({
179
+ field: "title",
180
+ message: "The title property in the GlossaryData must be a string."
181
+ });
182
+ if (throwOnError && errors.length > 0) {
183
+ throw new GlossaryValidationError(errors);
184
+ }
185
+ }
186
+ const validTitle = glossaryData.title;
187
+ if ("description" in glossaryData && typeof glossaryData.description !== "string") {
188
+ errors.push({
189
+ field: "description",
190
+ message: "The description property in the GlossaryData must be a string."
191
+ });
192
+ if (throwOnError && errors.length > 0) {
193
+ throw new GlossaryValidationError(errors);
194
+ }
195
+ }
196
+ const validDescription = glossaryData.description;
197
+ if (!("terms" in glossaryData)) {
198
+ errors.push({
199
+ field: "terms",
200
+ message: 'Glossary data must contain a "terms" array'
201
+ });
202
+ if (throwOnError && errors.length > 0) {
203
+ throw new GlossaryValidationError(errors);
204
+ }
205
+ return { valid: false, errors, data: { terms: [] } };
206
+ }
207
+ if (!Array.isArray(glossaryData.terms)) {
208
+ errors.push({
209
+ field: "terms",
210
+ message: `Field "terms" must be an array, got ${typeof glossaryData.terms}`,
211
+ value: glossaryData.terms
212
+ });
213
+ if (throwOnError && errors.length > 0) {
214
+ throw new GlossaryValidationError(errors);
215
+ }
216
+ return { valid: false, errors, data: { terms: [] } };
217
+ }
218
+ const validTerms = [];
219
+ glossaryData.terms.forEach((term, index) => {
220
+ const termErrors = validateTerm(term, index);
221
+ if (termErrors.length > 0) {
222
+ errors.push(...termErrors);
223
+ } else {
224
+ validTerms.push(term);
225
+ }
226
+ });
227
+ const termNames = /* @__PURE__ */ new Map();
228
+ validTerms.forEach((term, index) => {
229
+ const lowerName = term.term.toLowerCase();
230
+ if (termNames.has(lowerName)) {
231
+ errors.push({
232
+ field: `terms[${index}].term`,
233
+ message: `Duplicate term "${term.term}" (first occurrence at index ${termNames.get(lowerName)})`,
234
+ value: term.term
235
+ });
236
+ } else {
237
+ termNames.set(lowerName, index);
238
+ }
239
+ });
240
+ if (throwOnError && errors.length > 0) {
241
+ throw new GlossaryValidationError(errors);
242
+ }
243
+ return {
244
+ valid: errors.length === 0,
245
+ errors,
246
+ data: { title: validTitle, description: validDescription, terms: validTerms }
247
+ };
248
+ }
249
+ var GlossaryValidationError = class _GlossaryValidationError extends Error {
250
+ constructor(errors) {
251
+ const message = formatValidationErrors(errors);
252
+ super(message);
253
+ this.name = "GlossaryValidationError";
254
+ this.errors = errors;
255
+ if (Error.captureStackTrace) {
256
+ Error.captureStackTrace(this, _GlossaryValidationError);
257
+ }
258
+ }
259
+ };
260
+ function formatValidationErrors(errors) {
261
+ if (errors.length === 0) {
262
+ return "No validation errors";
263
+ }
264
+ const header = `Glossary validation failed with ${errors.length} error${errors.length > 1 ? "s" : ""}:`;
265
+ const errorList = errors.map((err, index) => {
266
+ let msg = ` ${index + 1}. [${err.field}] ${err.message}`;
267
+ if (err.value !== void 0) {
268
+ const valueStr = typeof err.value === "object" ? JSON.stringify(err.value) : String(err.value);
269
+ const truncated = valueStr.length > 50 ? valueStr.substring(0, 50) + "..." : valueStr;
270
+ msg += ` (got: ${truncated})`;
271
+ }
272
+ return msg;
273
+ }).join("\n");
274
+ return `${header}
275
+ ${errorList}`;
276
+ }
277
+ // Annotate the CommonJS export names for ESM import in node:
278
+ 0 && (module.exports = {
279
+ GlossaryValidationError,
280
+ formatValidationErrors,
281
+ validateGlossaryData
282
+ });
283
+ //# sourceMappingURL=validation.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/validation.ts"],"sourcesContent":["import type { GlossaryData, GlossaryTerm } from './index.js';\n\nexport interface ValidationError {\n field: string;\n message: string;\n value?: unknown;\n}\n\nexport interface ValidationResult {\n valid: boolean;\n errors: ValidationError[];\n data: GlossaryData;\n}\n\n/**\n * Validates a single glossary term object\n *\n * @param term - The term object to validate\n * @param index - The index in the terms array (for error messages)\n * @returns Array of validation errors (empty if valid)\n */\nfunction validateTerm(term: unknown, index: number): ValidationError[] {\n const errors: ValidationError[] = [];\n const prefix = `terms[${index}]`;\n\n if (term === null || term === undefined) {\n errors.push({\n field: prefix,\n message: 'Term cannot be null or undefined',\n value: term,\n });\n return errors;\n }\n\n if (typeof term !== 'object') {\n errors.push({\n field: prefix,\n message: `Term must be an object, got ${typeof term}`,\n value: term,\n });\n return errors;\n }\n\n const termObj = term as Record<string, unknown>;\n\n // Required: term (string)\n if (!('term' in termObj)) {\n errors.push({\n field: `${prefix}.term`,\n message: 'Missing required field \"term\"',\n });\n } else if (typeof termObj.term !== 'string') {\n errors.push({\n field: `${prefix}.term`,\n message: `Field \"term\" must be a string, got ${typeof termObj.term}`,\n value: termObj.term,\n });\n } else if (termObj.term.trim() === '') {\n errors.push({\n field: `${prefix}.term`,\n message: 'Field \"term\" cannot be empty',\n value: termObj.term,\n });\n }\n\n // Required: definition (string)\n if (!('definition' in termObj)) {\n errors.push({\n field: `${prefix}.definition`,\n message: 'Missing required field \"definition\"',\n });\n } else if (typeof termObj.definition !== 'string') {\n errors.push({\n field: `${prefix}.definition`,\n message: `Field \"definition\" must be a string, got ${typeof termObj.definition}`,\n value: termObj.definition,\n });\n }\n\n // Optional: abbreviation (string)\n if ('abbreviation' in termObj && termObj.abbreviation !== undefined) {\n if (typeof termObj.abbreviation !== 'string') {\n errors.push({\n field: `${prefix}.abbreviation`,\n message: `Field \"abbreviation\" must be a string, got ${typeof termObj.abbreviation}`,\n value: termObj.abbreviation,\n });\n }\n }\n\n // Optional: relatedTerms (string[])\n if ('relatedTerms' in termObj && termObj.relatedTerms !== undefined) {\n if (!Array.isArray(termObj.relatedTerms)) {\n errors.push({\n field: `${prefix}.relatedTerms`,\n message: `Field \"relatedTerms\" must be an array, got ${typeof termObj.relatedTerms}`,\n value: termObj.relatedTerms,\n });\n } else {\n termObj.relatedTerms.forEach((relatedTerm, relatedIndex) => {\n if (typeof relatedTerm !== 'string') {\n errors.push({\n field: `${prefix}.relatedTerms[${relatedIndex}]`,\n message: `Related term must be a string, got ${typeof relatedTerm}`,\n value: relatedTerm,\n });\n }\n });\n }\n }\n\n // Optional: id (string)\n if ('id' in termObj && termObj.id !== undefined) {\n if (typeof termObj.id !== 'string') {\n errors.push({\n field: `${prefix}.id`,\n message: `Field \"id\" must be a string, got ${typeof termObj.id}`,\n value: termObj.id,\n });\n }\n }\n\n // Optional: autoLink (boolean)\n if ('autoLink' in termObj && termObj.autoLink !== undefined) {\n if (typeof termObj.autoLink !== 'boolean') {\n errors.push({\n field: `${prefix}.autoLink`,\n message: `Field \"autoLink\" must be a boolean, got ${typeof termObj.autoLink}`,\n value: termObj.autoLink,\n });\n }\n }\n\n // Optional: aliases (string[])\n if ('aliases' in termObj && termObj.aliases !== undefined) {\n if (!Array.isArray(termObj.aliases)) {\n errors.push({\n field: `${prefix}.aliases`,\n message: `Field \"aliases\" must be an array, got ${typeof termObj.aliases}`,\n value: termObj.aliases,\n });\n } else {\n termObj.aliases.forEach((alias, aliasIndex) => {\n if (typeof alias !== 'string') {\n errors.push({\n field: `${prefix}.aliases[${aliasIndex}]`,\n message: `Alias must be a string, got ${typeof alias}`,\n value: alias,\n });\n } else if (alias.trim() === '') {\n errors.push({\n field: `${prefix}.aliases[${aliasIndex}]`,\n message: 'Alias cannot be empty',\n value: alias,\n });\n }\n });\n }\n }\n\n return errors;\n}\n\n/**\n * Validates glossary data structure\n *\n * Ensures the glossary data conforms to the expected schema:\n * - Must be an object with a \"terms\" array\n * - Each term must have \"term\" (string) and \"definition\" (string)\n * - Optional fields: abbreviation (string), relatedTerms (string[]), id (string)\n *\n * @param data - The data to validate\n * @param options - Validation options\n * @param options.throwOnError - If true, throws an error on validation failure (default: true)\n * @returns Validation result with errors and sanitized data\n * @throws Error if data is invalid and throwOnError is true\n */\nexport function validateGlossaryData(\n data: unknown,\n options: { throwOnError?: boolean } = {}\n): ValidationResult {\n const { throwOnError = true } = options;\n const errors: ValidationError[] = [];\n\n // Check if data is null or undefined\n if (data === null || data === undefined) {\n errors.push({\n field: 'root',\n message: 'Glossary data cannot be null or undefined',\n value: data,\n });\n\n if (throwOnError && errors.length > 0) {\n throw new GlossaryValidationError(errors);\n }\n\n return { valid: false, errors, data: { terms: [] } };\n }\n\n // Check if data is an object\n if (typeof data !== 'object') {\n errors.push({\n field: 'root',\n message: `Glossary data must be an object, got ${typeof data}`,\n value: data,\n });\n\n if (throwOnError && errors.length > 0) {\n throw new GlossaryValidationError(errors);\n }\n\n return { valid: false, errors, data: { terms: [] } };\n }\n\n const glossaryData = data as Record<string, unknown>;\n\n //Check for title\n if ('title' in glossaryData && typeof glossaryData.title !== 'string') {\n errors.push({\n field: 'title',\n message: 'The title property in the GlossaryData must be a string.',\n });\n\n if (throwOnError && errors.length > 0) {\n throw new GlossaryValidationError(errors);\n }\n }\n const validTitle = glossaryData.title as string;\n\n if ('description' in glossaryData && typeof glossaryData.description !== 'string') {\n errors.push({\n field: 'description',\n message: 'The description property in the GlossaryData must be a string.',\n });\n\n if (throwOnError && errors.length > 0) {\n throw new GlossaryValidationError(errors);\n }\n }\n\n const validDescription = glossaryData.description as string;\n\n if (!('terms' in glossaryData)) {\n // Check for terms array\n errors.push({\n field: 'terms',\n message: 'Glossary data must contain a \"terms\" array',\n });\n\n if (throwOnError && errors.length > 0) {\n throw new GlossaryValidationError(errors);\n }\n\n return { valid: false, errors, data: { terms: [] } };\n }\n\n if (!Array.isArray(glossaryData.terms)) {\n errors.push({\n field: 'terms',\n message: `Field \"terms\" must be an array, got ${typeof glossaryData.terms}`,\n value: glossaryData.terms,\n });\n\n if (throwOnError && errors.length > 0) {\n throw new GlossaryValidationError(errors);\n }\n\n return { valid: false, errors, data: { terms: [] } };\n }\n\n // Validate each term\n const validTerms: GlossaryTerm[] = [];\n glossaryData.terms.forEach((term, index) => {\n const termErrors = validateTerm(term, index);\n if (termErrors.length > 0) {\n errors.push(...termErrors);\n } else {\n // Term is valid, add to valid terms\n validTerms.push(term as GlossaryTerm);\n }\n });\n\n // Check for duplicate terms\n const termNames = new Map<string, number>();\n validTerms.forEach((term, index) => {\n const lowerName = term.term.toLowerCase();\n if (termNames.has(lowerName)) {\n errors.push({\n field: `terms[${index}].term`,\n message: `Duplicate term \"${term.term}\" (first occurrence at index ${termNames.get(lowerName)})`,\n value: term.term,\n });\n } else {\n termNames.set(lowerName, index);\n }\n });\n\n if (throwOnError && errors.length > 0) {\n throw new GlossaryValidationError(errors);\n }\n\n return {\n valid: errors.length === 0,\n errors,\n data: { title: validTitle, description: validDescription, terms: validTerms },\n };\n}\n\n/**\n * Custom error class for glossary validation errors\n * Provides detailed error messages for debugging\n */\nexport class GlossaryValidationError extends Error {\n public readonly errors: ValidationError[];\n\n constructor(errors: ValidationError[]) {\n const message = formatValidationErrors(errors);\n super(message);\n this.name = 'GlossaryValidationError';\n this.errors = errors;\n\n // Maintains proper stack trace for where error was thrown (V8 engines)\n // @ts-ignore\n if (Error.captureStackTrace) {\n // @ts-ignore\n Error.captureStackTrace(this, GlossaryValidationError);\n }\n }\n}\n\n/**\n * Formats validation errors into a readable string\n *\n * @param errors - Array of validation errors\n * @returns Formatted error message\n */\nexport function formatValidationErrors(errors: ValidationError[]): string {\n if (errors.length === 0) {\n return 'No validation errors';\n }\n\n const header = `Glossary validation failed with ${errors.length} error${errors.length > 1 ? 's' : ''}:`;\n const errorList = errors\n .map((err, index) => {\n let msg = ` ${index + 1}. [${err.field}] ${err.message}`;\n if (err.value !== undefined) {\n const valueStr =\n typeof err.value === 'object' ? JSON.stringify(err.value) : String(err.value);\n // Truncate long values\n const truncated = valueStr.length > 50 ? valueStr.substring(0, 50) + '...' : valueStr;\n msg += ` (got: ${truncated})`;\n }\n return msg;\n })\n .join('\\n');\n\n return `${header}\\n${errorList}`;\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,2 @@
1
+ export { GlossaryValidationError, ValidationError, ValidationResult, formatValidationErrors, validateGlossaryData } from './index.cjs';
2
+ import '@docusaurus/types';
@@ -1,44 +1,2 @@
1
- import type { GlossaryData } from './index.js';
2
- export interface ValidationError {
3
- field: string;
4
- message: string;
5
- value?: unknown;
6
- }
7
- export interface ValidationResult {
8
- valid: boolean;
9
- errors: ValidationError[];
10
- data: GlossaryData;
11
- }
12
- /**
13
- * Validates glossary data structure
14
- *
15
- * Ensures the glossary data conforms to the expected schema:
16
- * - Must be an object with a "terms" array
17
- * - Each term must have "term" (string) and "definition" (string)
18
- * - Optional fields: abbreviation (string), relatedTerms (string[]), id (string)
19
- *
20
- * @param data - The data to validate
21
- * @param options - Validation options
22
- * @param options.throwOnError - If true, throws an error on validation failure (default: true)
23
- * @returns Validation result with errors and sanitized data
24
- * @throws Error if data is invalid and throwOnError is true
25
- */
26
- export declare function validateGlossaryData(data: unknown, options?: {
27
- throwOnError?: boolean;
28
- }): ValidationResult;
29
- /**
30
- * Custom error class for glossary validation errors
31
- * Provides detailed error messages for debugging
32
- */
33
- export declare class GlossaryValidationError extends Error {
34
- readonly errors: ValidationError[];
35
- constructor(errors: ValidationError[]);
36
- }
37
- /**
38
- * Formats validation errors into a readable string
39
- *
40
- * @param errors - Array of validation errors
41
- * @returns Formatted error message
42
- */
43
- export declare function formatValidationErrors(errors: ValidationError[]): string;
44
- //# sourceMappingURL=validation.d.ts.map
1
+ export { GlossaryValidationError, ValidationError, ValidationResult, formatValidationErrors, validateGlossaryData } from './index.js';
2
+ import '@docusaurus/types';