hazo_ihelp 2.0.1

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 (156) hide show
  1. package/config/hazo_ihelp_config.ini +9 -0
  2. package/config/hazo_ihelp_config.ini.sample +23 -0
  3. package/dist/api/create_config_handler.d.ts +27 -0
  4. package/dist/api/create_config_handler.d.ts.map +1 -0
  5. package/dist/api/create_config_handler.js +122 -0
  6. package/dist/api/create_config_handler.js.map +1 -0
  7. package/dist/api/create_ihelp_handler.d.ts +60 -0
  8. package/dist/api/create_ihelp_handler.d.ts.map +1 -0
  9. package/dist/api/create_ihelp_handler.js +378 -0
  10. package/dist/api/create_ihelp_handler.js.map +1 -0
  11. package/dist/api/image_upload_handler.d.ts +29 -0
  12. package/dist/api/image_upload_handler.d.ts.map +1 -0
  13. package/dist/api/image_upload_handler.js +149 -0
  14. package/dist/api/image_upload_handler.js.map +1 -0
  15. package/dist/api/index.d.ts +6 -0
  16. package/dist/api/index.d.ts.map +1 -0
  17. package/dist/api/index.js +4 -0
  18. package/dist/api/index.js.map +1 -0
  19. package/dist/components/editor/editor_collapsible_section.d.ts +11 -0
  20. package/dist/components/editor/editor_collapsible_section.d.ts.map +1 -0
  21. package/dist/components/editor/editor_collapsible_section.js +10 -0
  22. package/dist/components/editor/editor_collapsible_section.js.map +1 -0
  23. package/dist/components/editor/editor_context_keys_section.d.ts +13 -0
  24. package/dist/components/editor/editor_context_keys_section.d.ts.map +1 -0
  25. package/dist/components/editor/editor_context_keys_section.js +99 -0
  26. package/dist/components/editor/editor_context_keys_section.js.map +1 -0
  27. package/dist/components/editor/editor_form.d.ts +27 -0
  28. package/dist/components/editor/editor_form.d.ts.map +1 -0
  29. package/dist/components/editor/editor_form.js +25 -0
  30. package/dist/components/editor/editor_form.js.map +1 -0
  31. package/dist/components/editor/editor_import_export.d.ts +18 -0
  32. package/dist/components/editor/editor_import_export.d.ts.map +1 -0
  33. package/dist/components/editor/editor_import_export.js +117 -0
  34. package/dist/components/editor/editor_import_export.js.map +1 -0
  35. package/dist/components/editor/editor_tags_section.d.ts +10 -0
  36. package/dist/components/editor/editor_tags_section.d.ts.map +1 -0
  37. package/dist/components/editor/editor_tags_section.js +33 -0
  38. package/dist/components/editor/editor_tags_section.js.map +1 -0
  39. package/dist/components/editor/editor_topic_list.d.ts +14 -0
  40. package/dist/components/editor/editor_topic_list.d.ts.map +1 -0
  41. package/dist/components/editor/editor_topic_list.js +58 -0
  42. package/dist/components/editor/editor_topic_list.js.map +1 -0
  43. package/dist/components/editor/editor_topic_list_item.d.ts +10 -0
  44. package/dist/components/editor/editor_topic_list_item.d.ts.map +1 -0
  45. package/dist/components/editor/editor_topic_list_item.js +10 -0
  46. package/dist/components/editor/editor_topic_list_item.js.map +1 -0
  47. package/dist/components/ihelp_detail_panel.d.ts +16 -0
  48. package/dist/components/ihelp_detail_panel.d.ts.map +1 -0
  49. package/dist/components/ihelp_detail_panel.js +46 -0
  50. package/dist/components/ihelp_detail_panel.js.map +1 -0
  51. package/dist/components/ihelp_editor.d.ts +3 -0
  52. package/dist/components/ihelp_editor.d.ts.map +1 -0
  53. package/dist/components/ihelp_editor.js +169 -0
  54. package/dist/components/ihelp_editor.js.map +1 -0
  55. package/dist/components/ihelp_icon.d.ts +7 -0
  56. package/dist/components/ihelp_icon.d.ts.map +1 -0
  57. package/dist/components/ihelp_icon.js +14 -0
  58. package/dist/components/ihelp_icon.js.map +1 -0
  59. package/dist/components/ihelp_provider.d.ts +21 -0
  60. package/dist/components/ihelp_provider.d.ts.map +1 -0
  61. package/dist/components/ihelp_provider.js +83 -0
  62. package/dist/components/ihelp_provider.js.map +1 -0
  63. package/dist/components/ihelp_rich_editor.d.ts +15 -0
  64. package/dist/components/ihelp_rich_editor.d.ts.map +1 -0
  65. package/dist/components/ihelp_rich_editor.js +182 -0
  66. package/dist/components/ihelp_rich_editor.js.map +1 -0
  67. package/dist/components/ihelp_search_dialog.d.ts +3 -0
  68. package/dist/components/ihelp_search_dialog.d.ts.map +1 -0
  69. package/dist/components/ihelp_search_dialog.js +454 -0
  70. package/dist/components/ihelp_search_dialog.js.map +1 -0
  71. package/dist/components/index.d.ts +7 -0
  72. package/dist/components/index.d.ts.map +1 -0
  73. package/dist/components/index.js +7 -0
  74. package/dist/components/index.js.map +1 -0
  75. package/dist/components/resizable_image.d.ts +17 -0
  76. package/dist/components/resizable_image.d.ts.map +1 -0
  77. package/dist/components/resizable_image.js +170 -0
  78. package/dist/components/resizable_image.js.map +1 -0
  79. package/dist/components/ui/badge.d.ts +9 -0
  80. package/dist/components/ui/badge.d.ts.map +1 -0
  81. package/dist/components/ui/badge.js +17 -0
  82. package/dist/components/ui/badge.js.map +1 -0
  83. package/dist/components/ui/button.d.ts +10 -0
  84. package/dist/components/ui/button.d.ts.map +1 -0
  85. package/dist/components/ui/button.js +50 -0
  86. package/dist/components/ui/button.js.map +1 -0
  87. package/dist/components/ui/dialog.d.ts +20 -0
  88. package/dist/components/ui/dialog.d.ts.map +1 -0
  89. package/dist/components/ui/dialog.js +26 -0
  90. package/dist/components/ui/dialog.js.map +1 -0
  91. package/dist/components/ui/input.d.ts +6 -0
  92. package/dist/components/ui/input.d.ts.map +1 -0
  93. package/dist/components/ui/input.js +12 -0
  94. package/dist/components/ui/input.js.map +1 -0
  95. package/dist/components/ui/label.d.ts +6 -0
  96. package/dist/components/ui/label.d.ts.map +1 -0
  97. package/dist/components/ui/label.js +12 -0
  98. package/dist/components/ui/label.js.map +1 -0
  99. package/dist/components/ui/popover.d.ts +7 -0
  100. package/dist/components/ui/popover.d.ts.map +1 -0
  101. package/dist/components/ui/popover.js +13 -0
  102. package/dist/components/ui/popover.js.map +1 -0
  103. package/dist/components/ui/select.d.ts +14 -0
  104. package/dist/components/ui/select.d.ts.map +1 -0
  105. package/dist/components/ui/select.js +29 -0
  106. package/dist/components/ui/select.js.map +1 -0
  107. package/dist/components/ui/switch.d.ts +5 -0
  108. package/dist/components/ui/switch.d.ts.map +1 -0
  109. package/dist/components/ui/switch.js +11 -0
  110. package/dist/components/ui/switch.js.map +1 -0
  111. package/dist/components/ui/textarea.d.ts +6 -0
  112. package/dist/components/ui/textarea.d.ts.map +1 -0
  113. package/dist/components/ui/textarea.js +12 -0
  114. package/dist/components/ui/textarea.js.map +1 -0
  115. package/dist/config/parse_config.d.ts +10 -0
  116. package/dist/config/parse_config.d.ts.map +1 -0
  117. package/dist/config/parse_config.js +76 -0
  118. package/dist/config/parse_config.js.map +1 -0
  119. package/dist/hooks/index.d.ts +6 -0
  120. package/dist/hooks/index.d.ts.map +1 -0
  121. package/dist/hooks/index.js +5 -0
  122. package/dist/hooks/index.js.map +1 -0
  123. package/dist/hooks/use_ihelp.d.ts +3 -0
  124. package/dist/hooks/use_ihelp.d.ts.map +1 -0
  125. package/dist/hooks/use_ihelp.js +52 -0
  126. package/dist/hooks/use_ihelp.js.map +1 -0
  127. package/dist/hooks/use_ihelp_config.d.ts +19 -0
  128. package/dist/hooks/use_ihelp_config.d.ts.map +1 -0
  129. package/dist/hooks/use_ihelp_config.js +62 -0
  130. package/dist/hooks/use_ihelp_config.js.map +1 -0
  131. package/dist/hooks/use_ihelp_editor.d.ts +3 -0
  132. package/dist/hooks/use_ihelp_editor.d.ts.map +1 -0
  133. package/dist/hooks/use_ihelp_editor.js +93 -0
  134. package/dist/hooks/use_ihelp_editor.js.map +1 -0
  135. package/dist/hooks/use_ihelp_search.d.ts +3 -0
  136. package/dist/hooks/use_ihelp_search.d.ts.map +1 -0
  137. package/dist/hooks/use_ihelp_search.js +68 -0
  138. package/dist/hooks/use_ihelp_search.js.map +1 -0
  139. package/dist/index.client.d.ts +13 -0
  140. package/dist/index.client.d.ts.map +1 -0
  141. package/dist/index.client.js +15 -0
  142. package/dist/index.client.js.map +1 -0
  143. package/dist/index.d.ts +12 -0
  144. package/dist/index.d.ts.map +1 -0
  145. package/dist/index.js +12 -0
  146. package/dist/index.js.map +1 -0
  147. package/dist/types/index.d.ts +595 -0
  148. package/dist/types/index.d.ts.map +1 -0
  149. package/dist/types/index.js +8 -0
  150. package/dist/types/index.js.map +1 -0
  151. package/dist/utils/cn.d.ts +3 -0
  152. package/dist/utils/cn.d.ts.map +1 -0
  153. package/dist/utils/cn.js +6 -0
  154. package/dist/utils/cn.js.map +1 -0
  155. package/migrations/001_create_ihelp_tables.sql +58 -0
  156. package/package.json +108 -0
@@ -0,0 +1,76 @@
1
+ // SERVER-ONLY: This module imports Node.js built-ins (fs, path) and must
2
+ // never be imported in client-side code or browser bundles.
3
+ // Install the 'server-only' package and add `import 'server-only'` here
4
+ // once it is available in this project's dependencies.
5
+ import { readFileSync, existsSync } from 'fs';
6
+ import { resolve } from 'path';
7
+ // ---- Defaults ----
8
+ const DEFAULT_IMAGE_UPLOAD = {
9
+ max_file_size_mb: 5,
10
+ allowed_types: ['image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/svg+xml', 'image/avif'],
11
+ upload_dir: 'public/ihelp/images',
12
+ upload_url_prefix: '/ihelp/images',
13
+ resize_enabled: true,
14
+ resize_max_width: 1200,
15
+ resize_max_height: 1200,
16
+ resize_quality: 80,
17
+ };
18
+ function parseIni(text) {
19
+ const sections = {};
20
+ let current = '';
21
+ for (const raw of text.split('\n')) {
22
+ const line = raw.trim();
23
+ if (!line || line.startsWith(';') || line.startsWith('#'))
24
+ continue;
25
+ const sectionMatch = line.match(/^\[(.+)]$/);
26
+ if (sectionMatch) {
27
+ current = sectionMatch[1].trim();
28
+ sections[current] = sections[current] || {};
29
+ continue;
30
+ }
31
+ const eqIdx = line.indexOf('=');
32
+ if (eqIdx > 0 && current) {
33
+ const key = line.slice(0, eqIdx).trim();
34
+ const value = line.slice(eqIdx + 1).trim();
35
+ sections[current][key] = value;
36
+ }
37
+ }
38
+ return sections;
39
+ }
40
+ // ---- Config cache ----
41
+ let cachedConfig = null;
42
+ let cachedPath = null;
43
+ /**
44
+ * Parse the hazo_ihelp config file.
45
+ * Returns defaults when the file is absent.
46
+ * Caches result per config_path so the file is read once per process.
47
+ */
48
+ export function parseIhelpConfig(config_path) {
49
+ const resolved = resolve(config_path ?? 'config/hazo_ihelp_config.ini');
50
+ if (cachedConfig && cachedPath === resolved)
51
+ return cachedConfig;
52
+ if (!existsSync(resolved)) {
53
+ cachedConfig = { image_upload: { ...DEFAULT_IMAGE_UPLOAD } };
54
+ cachedPath = resolved;
55
+ return cachedConfig;
56
+ }
57
+ const text = readFileSync(resolved, 'utf-8');
58
+ const ini = parseIni(text);
59
+ const s = ini['image_upload'] || {};
60
+ const config = {
61
+ max_file_size_mb: s.max_file_size_mb ? Number(s.max_file_size_mb) : DEFAULT_IMAGE_UPLOAD.max_file_size_mb,
62
+ allowed_types: s.allowed_types
63
+ ? s.allowed_types.split(',').map((t) => t.trim()).filter(Boolean)
64
+ : DEFAULT_IMAGE_UPLOAD.allowed_types,
65
+ upload_dir: s.upload_dir || DEFAULT_IMAGE_UPLOAD.upload_dir,
66
+ upload_url_prefix: s.upload_url_prefix || DEFAULT_IMAGE_UPLOAD.upload_url_prefix,
67
+ resize_enabled: s.resize_enabled !== undefined ? s.resize_enabled === 'true' : DEFAULT_IMAGE_UPLOAD.resize_enabled,
68
+ resize_max_width: s.resize_max_width ? Number(s.resize_max_width) : DEFAULT_IMAGE_UPLOAD.resize_max_width,
69
+ resize_max_height: s.resize_max_height ? Number(s.resize_max_height) : DEFAULT_IMAGE_UPLOAD.resize_max_height,
70
+ resize_quality: s.resize_quality ? Number(s.resize_quality) : DEFAULT_IMAGE_UPLOAD.resize_quality,
71
+ };
72
+ cachedConfig = { image_upload: config };
73
+ cachedPath = resolved;
74
+ return cachedConfig;
75
+ }
76
+ //# sourceMappingURL=parse_config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse_config.js","sourceRoot":"","sources":["../../src/config/parse_config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export { use_ihelp } from './use_ihelp.js';
2
+ export { use_ihelp_search } from './use_ihelp_search.js';
3
+ export { use_ihelp_editor } from './use_ihelp_editor.js';
4
+ export { use_ihelp_config } from './use_ihelp_config.js';
5
+ export type { UseIhelpConfigResult } from './use_ihelp_config.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,YAAY,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { use_ihelp } from './use_ihelp.js';
2
+ export { use_ihelp_search } from './use_ihelp_search.js';
3
+ export { use_ihelp_editor } from './use_ihelp_editor.js';
4
+ export { use_ihelp_config } from './use_ihelp_config.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { UseIhelpResult } from '../types/index.js';
2
+ export declare function use_ihelp(context_key: string, api_base_url?: string, scope_id?: string | null): UseIhelpResult;
3
+ //# sourceMappingURL=use_ihelp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use_ihelp.d.ts","sourceRoot":"","sources":["../../src/hooks/use_ihelp.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAc,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEpE,wBAAgB,SAAS,CACvB,WAAW,EAAE,MAAM,EACnB,YAAY,GAAE,MAAqB,EACnC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GACvB,cAAc,CA2DhB"}
@@ -0,0 +1,52 @@
1
+ "use client";
2
+ import { useState, useEffect, useCallback, useRef } from 'react';
3
+ export function use_ihelp(context_key, api_base_url = '/api/ihelp', scope_id) {
4
+ const [topics, setTopics] = useState([]);
5
+ const [loading, setLoading] = useState(true);
6
+ const [error, setError] = useState(null);
7
+ // Cache results keyed by context_key + scope_id to avoid redundant fetches
8
+ const cache = useRef({});
9
+ const fetchTopics = useCallback(async () => {
10
+ const cache_key = `${context_key}::${scope_id ?? ''}`;
11
+ if (cache.current[cache_key]) {
12
+ setTopics(cache.current[cache_key]);
13
+ setLoading(false);
14
+ return;
15
+ }
16
+ setLoading(true);
17
+ setError(null);
18
+ try {
19
+ const params = new URLSearchParams({ context_key });
20
+ if (scope_id) {
21
+ params.set('scope_id', scope_id);
22
+ }
23
+ const response = await fetch(`${api_base_url}?${params.toString()}`);
24
+ if (!response.ok) {
25
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
26
+ }
27
+ const json = await response.json();
28
+ if (!json.success) {
29
+ throw new Error(json.error ?? 'Unknown error from API');
30
+ }
31
+ const fetched = json.data ?? [];
32
+ cache.current[cache_key] = fetched;
33
+ setTopics(fetched);
34
+ }
35
+ catch (err) {
36
+ setError(err instanceof Error ? err.message : String(err));
37
+ }
38
+ finally {
39
+ setLoading(false);
40
+ }
41
+ }, [context_key, api_base_url, scope_id]);
42
+ useEffect(() => {
43
+ fetchTopics();
44
+ }, [fetchTopics]);
45
+ const refetch = useCallback(() => {
46
+ const cache_key = `${context_key}::${scope_id ?? ''}`;
47
+ delete cache.current[cache_key];
48
+ fetchTopics();
49
+ }, [context_key, scope_id, fetchTopics]);
50
+ return { topics, loading, error, refetch };
51
+ }
52
+ //# sourceMappingURL=use_ihelp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use_ihelp.js","sourceRoot":"","sources":["../../src/hooks/use_ihelp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ export interface UseIhelpConfigResult<T = unknown> {
2
+ value: T | null;
3
+ loading: boolean;
4
+ error: string | null;
5
+ refetch: () => void;
6
+ save: (value: T) => Promise<void>;
7
+ }
8
+ /**
9
+ * Fetch and save a single config entry from the hazo_config table.
10
+ *
11
+ * For context keys usage:
12
+ * ```
13
+ * const { value: keys, save } = use_ihelp_config<ContextKeyOption[]>(
14
+ * 'context_keys', '/api/ihelp/config'
15
+ * );
16
+ * ```
17
+ */
18
+ export declare function use_ihelp_config<T = unknown>(config_key: string, api_base_url?: string, scope_id?: string | null): UseIhelpConfigResult<T>;
19
+ //# sourceMappingURL=use_ihelp_config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use_ihelp_config.d.ts","sourceRoot":"","sources":["../../src/hooks/use_ihelp_config.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,oBAAoB,CAAC,CAAC,GAAG,OAAO;IAC/C,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACnC;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,GAAG,OAAO,EAC1C,UAAU,EAAE,MAAM,EAClB,YAAY,GAAE,MAA4B,EAC1C,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GACvB,oBAAoB,CAAC,CAAC,CAAC,CAiDzB"}
@@ -0,0 +1,62 @@
1
+ "use client";
2
+ import { useState, useEffect, useCallback } from 'react';
3
+ /**
4
+ * Fetch and save a single config entry from the hazo_config table.
5
+ *
6
+ * For context keys usage:
7
+ * ```
8
+ * const { value: keys, save } = use_ihelp_config<ContextKeyOption[]>(
9
+ * 'context_keys', '/api/ihelp/config'
10
+ * );
11
+ * ```
12
+ */
13
+ export function use_ihelp_config(config_key, api_base_url = '/api/ihelp/config', scope_id) {
14
+ const [value, setValue] = useState(null);
15
+ const [loading, setLoading] = useState(true);
16
+ const [error, setError] = useState(null);
17
+ const fetchConfig = useCallback(async () => {
18
+ setLoading(true);
19
+ setError(null);
20
+ try {
21
+ const params = new URLSearchParams({ config_key });
22
+ if (scope_id)
23
+ params.set('scope_id', scope_id);
24
+ const res = await fetch(`${api_base_url}?${params.toString()}`);
25
+ if (!res.ok)
26
+ throw new Error(`HTTP ${res.status}: ${res.statusText}`);
27
+ const json = await res.json();
28
+ if (!json.success)
29
+ throw new Error(json.error ?? 'Unknown error');
30
+ setValue(json.data?.value ?? null);
31
+ }
32
+ catch (err) {
33
+ setError(err?.message || 'Failed to load config');
34
+ }
35
+ finally {
36
+ setLoading(false);
37
+ }
38
+ }, [config_key, api_base_url, scope_id]);
39
+ useEffect(() => { fetchConfig(); }, [fetchConfig]);
40
+ const save = useCallback(async (newValue) => {
41
+ setError(null);
42
+ try {
43
+ const res = await fetch(api_base_url, {
44
+ method: 'PUT',
45
+ headers: { 'Content-Type': 'application/json' },
46
+ body: JSON.stringify({ config_key, value: newValue, scope_id: scope_id ?? null }),
47
+ });
48
+ if (!res.ok)
49
+ throw new Error(`HTTP ${res.status}: ${res.statusText}`);
50
+ const json = await res.json();
51
+ if (!json.success)
52
+ throw new Error(json.error ?? 'Unknown error');
53
+ setValue(json.data?.value ?? newValue);
54
+ }
55
+ catch (err) {
56
+ setError(err?.message || 'Failed to save config');
57
+ throw err;
58
+ }
59
+ }, [config_key, api_base_url, scope_id]);
60
+ return { value, loading, error, refetch: fetchConfig, save };
61
+ }
62
+ //# sourceMappingURL=use_ihelp_config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use_ihelp_config.js","sourceRoot":"","sources":["../../src/hooks/use_ihelp_config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { UseIhelpEditorResult } from '../types/index.js';
2
+ export declare function use_ihelp_editor(api_base_url?: string, scope_id?: string | null): UseIhelpEditorResult;
3
+ //# sourceMappingURL=use_ihelp_editor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use_ihelp_editor.d.ts","sourceRoot":"","sources":["../../src/hooks/use_ihelp_editor.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAA+B,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAE3F,wBAAgB,gBAAgB,CAC9B,YAAY,GAAE,MAAqB,EACnC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GACvB,oBAAoB,CAyHtB"}
@@ -0,0 +1,93 @@
1
+ "use client";
2
+ import { useState, useEffect, useCallback } from 'react';
3
+ export function use_ihelp_editor(api_base_url = '/api/ihelp', scope_id) {
4
+ const [topics, setTopics] = useState([]);
5
+ const [loading, setLoading] = useState(true);
6
+ const [error, setError] = useState(null);
7
+ const fetchTopics = useCallback(async () => {
8
+ setLoading(true);
9
+ setError(null);
10
+ try {
11
+ const params = new URLSearchParams();
12
+ if (scope_id) {
13
+ params.set('scope_id', scope_id);
14
+ }
15
+ const url = params.toString()
16
+ ? `${api_base_url}?${params.toString()}`
17
+ : api_base_url;
18
+ const response = await fetch(url);
19
+ if (!response.ok) {
20
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
21
+ }
22
+ const json = await response.json();
23
+ if (!json.success) {
24
+ throw new Error(json.error ?? 'Unknown error from API');
25
+ }
26
+ setTopics(json.data ?? []);
27
+ }
28
+ catch (err) {
29
+ setError(err instanceof Error ? err.message : String(err));
30
+ }
31
+ finally {
32
+ setLoading(false);
33
+ }
34
+ }, [api_base_url, scope_id]);
35
+ useEffect(() => {
36
+ fetchTopics();
37
+ }, [fetchTopics]);
38
+ const create_topic = useCallback(async (input) => {
39
+ const response = await fetch(api_base_url, {
40
+ method: 'POST',
41
+ headers: { 'Content-Type': 'application/json' },
42
+ body: JSON.stringify(input),
43
+ });
44
+ if (!response.ok) {
45
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
46
+ }
47
+ const json = await response.json();
48
+ if (!json.success) {
49
+ throw new Error(json.error ?? 'Failed to create topic');
50
+ }
51
+ await fetchTopics();
52
+ return json.data;
53
+ }, [api_base_url, fetchTopics]);
54
+ const update_topic = useCallback(async (id, input) => {
55
+ const response = await fetch(`${api_base_url}/${id}`, {
56
+ method: 'PATCH',
57
+ headers: { 'Content-Type': 'application/json' },
58
+ body: JSON.stringify(input),
59
+ });
60
+ if (!response.ok) {
61
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
62
+ }
63
+ const json = await response.json();
64
+ if (!json.success) {
65
+ throw new Error(json.error ?? 'Failed to update topic');
66
+ }
67
+ await fetchTopics();
68
+ return json.data;
69
+ }, [api_base_url, fetchTopics]);
70
+ const delete_topic = useCallback(async (id) => {
71
+ const response = await fetch(`${api_base_url}/${id}`, {
72
+ method: 'DELETE',
73
+ });
74
+ if (!response.ok) {
75
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
76
+ }
77
+ const json = await response.json();
78
+ if (!json.success) {
79
+ throw new Error(json.error ?? 'Failed to delete topic');
80
+ }
81
+ await fetchTopics();
82
+ }, [api_base_url, fetchTopics]);
83
+ return {
84
+ topics,
85
+ loading,
86
+ error,
87
+ create_topic,
88
+ update_topic,
89
+ delete_topic,
90
+ refetch: fetchTopics,
91
+ };
92
+ }
93
+ //# sourceMappingURL=use_ihelp_editor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use_ihelp_editor.js","sourceRoot":"","sources":["../../src/hooks/use_ihelp_editor.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAGzD,MAAM,UAAU,gBAAgB,CAC9B,eAAuB,YAAY,EACnC,QAAwB;IAExB,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAe,EAAE,CAAC,CAAC;IACvD,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAU,IAAI,CAAC,CAAC;IACtD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAExD,MAAM,WAAW,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACzC,UAAU,CAAC,IAAI,CAAC,CAAC;QACjB,QAAQ,CAAC,IAAI,CAAC,CAAC;QAEf,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;YACrC,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;YACnC,CAAC;YAED,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,EAAE;gBAC3B,CAAC,CAAC,GAAG,YAAY,IAAI,MAAM,CAAC,QAAQ,EAAE,EAAE;gBACxC,CAAC,CAAC,YAAY,CAAC;YAEjB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;YAElC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CAAC,QAAQ,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;YACrE,CAAC;YAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YAEnC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gBAClB,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,wBAAwB,CAAC,CAAC;YAC1D,CAAC;YAED,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QAC7B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAC7D,CAAC;gBAAS,CAAC;YACT,UAAU,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC;IACH,CAAC,EAAE,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC;IAE7B,SAAS,CAAC,GAAG,EAAE;QACb,WAAW,EAAE,CAAC;IAChB,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;IAElB,MAAM,YAAY,GAAG,WAAW,CAC9B,KAAK,EAAE,KAAsB,EAAuB,EAAE;QACpD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,YAAY,EAAE;YACzC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;SAC5B,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,QAAQ,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;QACrE,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAEnC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,wBAAwB,CAAC,CAAC;QAC1D,CAAC;QAED,MAAM,WAAW,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC,IAAkB,CAAC;IACjC,CAAC,EACD,CAAC,YAAY,EAAE,WAAW,CAAC,CAC5B,CAAC;IAEF,MAAM,YAAY,GAAG,WAAW,CAC9B,KAAK,EAAE,EAAU,EAAE,KAA+B,EAAuB,EAAE;QACzE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,YAAY,IAAI,EAAE,EAAE,EAAE;YACpD,MAAM,EAAE,OAAO;YACf,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;SAC5B,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,QAAQ,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;QACrE,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAEnC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,wBAAwB,CAAC,CAAC;QAC1D,CAAC;QAED,MAAM,WAAW,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC,IAAkB,CAAC;IACjC,CAAC,EACD,CAAC,YAAY,EAAE,WAAW,CAAC,CAC5B,CAAC;IAEF,MAAM,YAAY,GAAG,WAAW,CAC9B,KAAK,EAAE,EAAU,EAAiB,EAAE;QAClC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,YAAY,IAAI,EAAE,EAAE,EAAE;YACpD,MAAM,EAAE,QAAQ;SACjB,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,QAAQ,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;QACrE,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAEnC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,wBAAwB,CAAC,CAAC;QAC1D,CAAC;QAED,MAAM,WAAW,EAAE,CAAC;IACtB,CAAC,EACD,CAAC,YAAY,EAAE,WAAW,CAAC,CAC5B,CAAC;IAEF,OAAO;QACL,MAAM;QACN,OAAO;QACP,KAAK;QACL,YAAY;QACZ,YAAY;QACZ,YAAY;QACZ,OAAO,EAAE,WAAW;KACrB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { UseIhelpSearchResult } from '../types/index.js';
2
+ export declare function use_ihelp_search(api_base_url?: string, scope_id?: string | null): UseIhelpSearchResult;
3
+ //# sourceMappingURL=use_ihelp_search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use_ihelp_search.d.ts","sourceRoot":"","sources":["../../src/hooks/use_ihelp_search.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAc,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAE1E,wBAAgB,gBAAgB,CAC9B,YAAY,GAAE,MAAqB,EACnC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GACvB,oBAAoB,CAgFtB"}
@@ -0,0 +1,68 @@
1
+ "use client";
2
+ import { useState, useEffect, useMemo } from 'react';
3
+ import Fuse from 'fuse.js';
4
+ export function use_ihelp_search(api_base_url = '/api/ihelp', scope_id) {
5
+ const [query, setQuery] = useState('');
6
+ const [all_topics, setAllTopics] = useState([]);
7
+ const [loading, setLoading] = useState(true);
8
+ const [error, setError] = useState(null);
9
+ useEffect(() => {
10
+ let cancelled = false;
11
+ async function fetchAll() {
12
+ setLoading(true);
13
+ setError(null);
14
+ try {
15
+ const params = new URLSearchParams();
16
+ if (scope_id) {
17
+ params.set('scope_id', scope_id);
18
+ }
19
+ const url = params.toString()
20
+ ? `${api_base_url}?${params.toString()}`
21
+ : api_base_url;
22
+ const response = await fetch(url);
23
+ if (!response.ok) {
24
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
25
+ }
26
+ const json = await response.json();
27
+ if (!json.success) {
28
+ throw new Error(json.error ?? 'Unknown error from API');
29
+ }
30
+ if (!cancelled) {
31
+ setAllTopics(json.data ?? []);
32
+ }
33
+ }
34
+ catch (err) {
35
+ if (!cancelled) {
36
+ setError(err instanceof Error ? err.message : String(err));
37
+ }
38
+ }
39
+ finally {
40
+ if (!cancelled) {
41
+ setLoading(false);
42
+ }
43
+ }
44
+ }
45
+ fetchAll();
46
+ return () => {
47
+ cancelled = true;
48
+ };
49
+ }, [api_base_url, scope_id]);
50
+ const fuse = useMemo(() => new Fuse(all_topics, {
51
+ threshold: 0.3,
52
+ keys: [
53
+ { name: 'title', weight: 2 },
54
+ { name: 'description', weight: 1.5 },
55
+ { name: 'tags.label', weight: 1 },
56
+ { name: 'content', weight: 0.5 },
57
+ ],
58
+ }), [all_topics]);
59
+ const results = useMemo(() => {
60
+ if (!query.trim()) {
61
+ return all_topics;
62
+ }
63
+ return fuse.search(query).map((r) => r.item);
64
+ }, [query, all_topics, fuse]);
65
+ const set_query = (q) => setQuery(q);
66
+ return { query, set_query, results, all_topics, loading, error };
67
+ }
68
+ //# sourceMappingURL=use_ihelp_search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use_ihelp_search.js","sourceRoot":"","sources":["../../src/hooks/use_ihelp_search.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * hazo_ihelp - Client-safe exports
3
+ *
4
+ * This is the default entry point for 'hazo_ihelp' imports.
5
+ * Contains only client-safe components, hooks, and types.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ export * from './components/index.js';
10
+ export * from './hooks/index.js';
11
+ export type { IhelpTopic, IhelpTag, IhelpContextMapping, IhelpTopicInput, IhelpTagInput, IhelpApiResponse, IhelpProviderProps, IhelpIconProps, IhelpSearchDialogProps, IhelpDetailPanelProps, IhelpEditorProps, IhelpNavState, IhelpTheme, IhelpLabels, UseIhelpResult, UseIhelpSearchResult, UseIhelpEditorResult, HazoConfigRow, ContextKeyOption, } from './types/index.js';
12
+ export { cn } from './utils/cn.js';
13
+ //# sourceMappingURL=index.client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.client.d.ts","sourceRoot":"","sources":["../src/index.client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,cAAc,uBAAuB,CAAC;AAGtC,cAAc,kBAAkB,CAAC;AAGjC,YAAY,EACV,UAAU,EACV,QAAQ,EACR,mBAAmB,EACnB,eAAe,EACf,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,sBAAsB,EACtB,qBAAqB,EACrB,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,WAAW,EACX,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACpB,aAAa,EACb,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,EAAE,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * hazo_ihelp - Client-safe exports
3
+ *
4
+ * This is the default entry point for 'hazo_ihelp' imports.
5
+ * Contains only client-safe components, hooks, and types.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ // Components
10
+ export * from './components/index.js';
11
+ // Hooks
12
+ export * from './hooks/index.js';
13
+ // Utils
14
+ export { cn } from './utils/cn.js';
15
+ //# sourceMappingURL=index.client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.client.js","sourceRoot":"","sources":["../src/index.client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,aAAa;AACb,cAAc,uBAAuB,CAAC;AAEtC,QAAQ;AACR,cAAc,kBAAkB,CAAC;AAyBjC,QAAQ;AACR,OAAO,EAAE,EAAE,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * hazo_ihelp - Contextual popup help system
3
+ *
4
+ * Main entry point exports server-side utilities.
5
+ * For client components, use 'hazo_ihelp' (which maps to index.client.ts)
6
+ * For API handlers, use 'hazo_ihelp/api'
7
+ *
8
+ * @packageDocumentation
9
+ */
10
+ export * from './index.client.js';
11
+ export type { CreateIhelpHandlerOptions } from './types/index.js';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,cAAc,mBAAmB,CAAC;AAGlC,YAAY,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ /**
2
+ * hazo_ihelp - Contextual popup help system
3
+ *
4
+ * Main entry point exports server-side utilities.
5
+ * For client components, use 'hazo_ihelp' (which maps to index.client.ts)
6
+ * For API handlers, use 'hazo_ihelp/api'
7
+ *
8
+ * @packageDocumentation
9
+ */
10
+ // Re-export everything from client
11
+ export * from './index.client.js';
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,mCAAmC;AACnC,cAAc,mBAAmB,CAAC"}