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.
- package/config/hazo_ihelp_config.ini +9 -0
- package/config/hazo_ihelp_config.ini.sample +23 -0
- package/dist/api/create_config_handler.d.ts +27 -0
- package/dist/api/create_config_handler.d.ts.map +1 -0
- package/dist/api/create_config_handler.js +122 -0
- package/dist/api/create_config_handler.js.map +1 -0
- package/dist/api/create_ihelp_handler.d.ts +60 -0
- package/dist/api/create_ihelp_handler.d.ts.map +1 -0
- package/dist/api/create_ihelp_handler.js +378 -0
- package/dist/api/create_ihelp_handler.js.map +1 -0
- package/dist/api/image_upload_handler.d.ts +29 -0
- package/dist/api/image_upload_handler.d.ts.map +1 -0
- package/dist/api/image_upload_handler.js +149 -0
- package/dist/api/image_upload_handler.js.map +1 -0
- package/dist/api/index.d.ts +6 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +4 -0
- package/dist/api/index.js.map +1 -0
- package/dist/components/editor/editor_collapsible_section.d.ts +11 -0
- package/dist/components/editor/editor_collapsible_section.d.ts.map +1 -0
- package/dist/components/editor/editor_collapsible_section.js +10 -0
- package/dist/components/editor/editor_collapsible_section.js.map +1 -0
- package/dist/components/editor/editor_context_keys_section.d.ts +13 -0
- package/dist/components/editor/editor_context_keys_section.d.ts.map +1 -0
- package/dist/components/editor/editor_context_keys_section.js +99 -0
- package/dist/components/editor/editor_context_keys_section.js.map +1 -0
- package/dist/components/editor/editor_form.d.ts +27 -0
- package/dist/components/editor/editor_form.d.ts.map +1 -0
- package/dist/components/editor/editor_form.js +25 -0
- package/dist/components/editor/editor_form.js.map +1 -0
- package/dist/components/editor/editor_import_export.d.ts +18 -0
- package/dist/components/editor/editor_import_export.d.ts.map +1 -0
- package/dist/components/editor/editor_import_export.js +117 -0
- package/dist/components/editor/editor_import_export.js.map +1 -0
- package/dist/components/editor/editor_tags_section.d.ts +10 -0
- package/dist/components/editor/editor_tags_section.d.ts.map +1 -0
- package/dist/components/editor/editor_tags_section.js +33 -0
- package/dist/components/editor/editor_tags_section.js.map +1 -0
- package/dist/components/editor/editor_topic_list.d.ts +14 -0
- package/dist/components/editor/editor_topic_list.d.ts.map +1 -0
- package/dist/components/editor/editor_topic_list.js +58 -0
- package/dist/components/editor/editor_topic_list.js.map +1 -0
- package/dist/components/editor/editor_topic_list_item.d.ts +10 -0
- package/dist/components/editor/editor_topic_list_item.d.ts.map +1 -0
- package/dist/components/editor/editor_topic_list_item.js +10 -0
- package/dist/components/editor/editor_topic_list_item.js.map +1 -0
- package/dist/components/ihelp_detail_panel.d.ts +16 -0
- package/dist/components/ihelp_detail_panel.d.ts.map +1 -0
- package/dist/components/ihelp_detail_panel.js +46 -0
- package/dist/components/ihelp_detail_panel.js.map +1 -0
- package/dist/components/ihelp_editor.d.ts +3 -0
- package/dist/components/ihelp_editor.d.ts.map +1 -0
- package/dist/components/ihelp_editor.js +169 -0
- package/dist/components/ihelp_editor.js.map +1 -0
- package/dist/components/ihelp_icon.d.ts +7 -0
- package/dist/components/ihelp_icon.d.ts.map +1 -0
- package/dist/components/ihelp_icon.js +14 -0
- package/dist/components/ihelp_icon.js.map +1 -0
- package/dist/components/ihelp_provider.d.ts +21 -0
- package/dist/components/ihelp_provider.d.ts.map +1 -0
- package/dist/components/ihelp_provider.js +83 -0
- package/dist/components/ihelp_provider.js.map +1 -0
- package/dist/components/ihelp_rich_editor.d.ts +15 -0
- package/dist/components/ihelp_rich_editor.d.ts.map +1 -0
- package/dist/components/ihelp_rich_editor.js +182 -0
- package/dist/components/ihelp_rich_editor.js.map +1 -0
- package/dist/components/ihelp_search_dialog.d.ts +3 -0
- package/dist/components/ihelp_search_dialog.d.ts.map +1 -0
- package/dist/components/ihelp_search_dialog.js +454 -0
- package/dist/components/ihelp_search_dialog.js.map +1 -0
- package/dist/components/index.d.ts +7 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +7 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/resizable_image.d.ts +17 -0
- package/dist/components/resizable_image.d.ts.map +1 -0
- package/dist/components/resizable_image.js +170 -0
- package/dist/components/resizable_image.js.map +1 -0
- package/dist/components/ui/badge.d.ts +9 -0
- package/dist/components/ui/badge.d.ts.map +1 -0
- package/dist/components/ui/badge.js +17 -0
- package/dist/components/ui/badge.js.map +1 -0
- package/dist/components/ui/button.d.ts +10 -0
- package/dist/components/ui/button.d.ts.map +1 -0
- package/dist/components/ui/button.js +50 -0
- package/dist/components/ui/button.js.map +1 -0
- package/dist/components/ui/dialog.d.ts +20 -0
- package/dist/components/ui/dialog.d.ts.map +1 -0
- package/dist/components/ui/dialog.js +26 -0
- package/dist/components/ui/dialog.js.map +1 -0
- package/dist/components/ui/input.d.ts +6 -0
- package/dist/components/ui/input.d.ts.map +1 -0
- package/dist/components/ui/input.js +12 -0
- package/dist/components/ui/input.js.map +1 -0
- package/dist/components/ui/label.d.ts +6 -0
- package/dist/components/ui/label.d.ts.map +1 -0
- package/dist/components/ui/label.js +12 -0
- package/dist/components/ui/label.js.map +1 -0
- package/dist/components/ui/popover.d.ts +7 -0
- package/dist/components/ui/popover.d.ts.map +1 -0
- package/dist/components/ui/popover.js +13 -0
- package/dist/components/ui/popover.js.map +1 -0
- package/dist/components/ui/select.d.ts +14 -0
- package/dist/components/ui/select.d.ts.map +1 -0
- package/dist/components/ui/select.js +29 -0
- package/dist/components/ui/select.js.map +1 -0
- package/dist/components/ui/switch.d.ts +5 -0
- package/dist/components/ui/switch.d.ts.map +1 -0
- package/dist/components/ui/switch.js +11 -0
- package/dist/components/ui/switch.js.map +1 -0
- package/dist/components/ui/textarea.d.ts +6 -0
- package/dist/components/ui/textarea.d.ts.map +1 -0
- package/dist/components/ui/textarea.js +12 -0
- package/dist/components/ui/textarea.js.map +1 -0
- package/dist/config/parse_config.d.ts +10 -0
- package/dist/config/parse_config.d.ts.map +1 -0
- package/dist/config/parse_config.js +76 -0
- package/dist/config/parse_config.js.map +1 -0
- package/dist/hooks/index.d.ts +6 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +5 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/use_ihelp.d.ts +3 -0
- package/dist/hooks/use_ihelp.d.ts.map +1 -0
- package/dist/hooks/use_ihelp.js +52 -0
- package/dist/hooks/use_ihelp.js.map +1 -0
- package/dist/hooks/use_ihelp_config.d.ts +19 -0
- package/dist/hooks/use_ihelp_config.d.ts.map +1 -0
- package/dist/hooks/use_ihelp_config.js +62 -0
- package/dist/hooks/use_ihelp_config.js.map +1 -0
- package/dist/hooks/use_ihelp_editor.d.ts +3 -0
- package/dist/hooks/use_ihelp_editor.d.ts.map +1 -0
- package/dist/hooks/use_ihelp_editor.js +93 -0
- package/dist/hooks/use_ihelp_editor.js.map +1 -0
- package/dist/hooks/use_ihelp_search.d.ts +3 -0
- package/dist/hooks/use_ihelp_search.d.ts.map +1 -0
- package/dist/hooks/use_ihelp_search.js +68 -0
- package/dist/hooks/use_ihelp_search.js.map +1 -0
- package/dist/index.client.d.ts +13 -0
- package/dist/index.client.d.ts.map +1 -0
- package/dist/index.client.js +15 -0
- package/dist/index.client.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/types/index.d.ts +595 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +8 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/cn.d.ts +3 -0
- package/dist/utils/cn.d.ts.map +1 -0
- package/dist/utils/cn.js +6 -0
- package/dist/utils/cn.js.map +1 -0
- package/migrations/001_create_ihelp_tables.sql +58 -0
- package/package.json +108 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
[image_upload]
|
|
2
|
+
max_file_size_mb = 5
|
|
3
|
+
allowed_types = image/jpeg, image/png, image/gif, image/webp, image/svg+xml, image/avif
|
|
4
|
+
upload_dir = test-app/public/ihelp/images
|
|
5
|
+
upload_url_prefix = /ihelp/images
|
|
6
|
+
resize_enabled = true
|
|
7
|
+
resize_max_width = 1200
|
|
8
|
+
resize_max_height = 1200
|
|
9
|
+
resize_quality = 80
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
; hazo_ihelp configuration
|
|
2
|
+
; Copy this file to config/hazo_ihelp_config.ini and adjust values.
|
|
3
|
+
|
|
4
|
+
[image_upload]
|
|
5
|
+
; Maximum file size in MB
|
|
6
|
+
max_file_size_mb = 5
|
|
7
|
+
|
|
8
|
+
; Allowed MIME types (comma-separated)
|
|
9
|
+
allowed_types = image/jpeg, image/png, image/gif, image/webp, image/svg+xml, image/avif
|
|
10
|
+
|
|
11
|
+
; Filesystem path where uploaded images are saved (relative to project root)
|
|
12
|
+
upload_dir = public/ihelp/images
|
|
13
|
+
|
|
14
|
+
; URL prefix returned in API responses (must match how upload_dir is served)
|
|
15
|
+
upload_url_prefix = /ihelp/images
|
|
16
|
+
|
|
17
|
+
; Resize images that exceed max dimensions (skips SVG)
|
|
18
|
+
resize_enabled = true
|
|
19
|
+
resize_max_width = 1200
|
|
20
|
+
resize_max_height = 1200
|
|
21
|
+
|
|
22
|
+
; JPEG/WebP quality (1-100)
|
|
23
|
+
resize_quality = 80
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config API Handler Factory
|
|
3
|
+
*
|
|
4
|
+
* Creates GET and PUT handlers for the hazo_config key-value table.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* // app/api/ihelp/config/route.ts
|
|
9
|
+
* import { createConfigHandler } from 'hazo_ihelp/api';
|
|
10
|
+
* import { getHazoConnect } from '../../../lib/db';
|
|
11
|
+
*
|
|
12
|
+
* export const dynamic = 'force-dynamic';
|
|
13
|
+
* const handler = createConfigHandler({ getHazoConnect: () => getHazoConnect() });
|
|
14
|
+
* export const GET = handler.GET;
|
|
15
|
+
* export const PUT = handler.PUT;
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
19
|
+
import type { IhelpApiResponse } from '../types/index.js';
|
|
20
|
+
export interface CreateConfigHandlerOptions {
|
|
21
|
+
getHazoConnect: () => Promise<any> | any;
|
|
22
|
+
}
|
|
23
|
+
export declare function createConfigHandler(options: CreateConfigHandlerOptions): {
|
|
24
|
+
GET: (request: NextRequest) => Promise<NextResponse<IhelpApiResponse>>;
|
|
25
|
+
PUT: (request: NextRequest) => Promise<NextResponse<IhelpApiResponse>>;
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=create_config_handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create_config_handler.d.ts","sourceRoot":"","sources":["../../src/api/create_config_handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAExD,OAAO,KAAK,EAAiB,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAgBzE,MAAM,WAAW,0BAA0B;IACzC,cAAc,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;CAC1C;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,0BAA0B;mBAIzC,WAAW,KAAG,OAAO,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC;mBAyCrD,WAAW,KAAG,OAAO,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC;EAyDlF"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config API Handler Factory
|
|
3
|
+
*
|
|
4
|
+
* Creates GET and PUT handlers for the hazo_config key-value table.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* // app/api/ihelp/config/route.ts
|
|
9
|
+
* import { createConfigHandler } from 'hazo_ihelp/api';
|
|
10
|
+
* import { getHazoConnect } from '../../../lib/db';
|
|
11
|
+
*
|
|
12
|
+
* export const dynamic = 'force-dynamic';
|
|
13
|
+
* const handler = createConfigHandler({ getHazoConnect: () => getHazoConnect() });
|
|
14
|
+
* export const GET = handler.GET;
|
|
15
|
+
* export const PUT = handler.PUT;
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
import { NextResponse } from 'next/server';
|
|
19
|
+
import { createCrudService } from 'hazo_connect/server';
|
|
20
|
+
function generateUUID() {
|
|
21
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
|
22
|
+
const r = (Math.random() * 16) | 0;
|
|
23
|
+
const v = c === 'x' ? r : (r & 0x3) | 0x8;
|
|
24
|
+
return v.toString(16);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
function errResponse(error, status) {
|
|
28
|
+
return NextResponse.json({ success: false, error }, { status });
|
|
29
|
+
}
|
|
30
|
+
export function createConfigHandler(options) {
|
|
31
|
+
const { getHazoConnect } = options;
|
|
32
|
+
// GET ?config_key=context_keys&scope_id=...
|
|
33
|
+
async function GET(request) {
|
|
34
|
+
try {
|
|
35
|
+
const adapter = await getHazoConnect();
|
|
36
|
+
const configService = createCrudService(adapter, 'hazo_config');
|
|
37
|
+
const url = new URL(request.url);
|
|
38
|
+
const config_key = url.searchParams.get('config_key');
|
|
39
|
+
const scope_id = url.searchParams.get('scope_id') || null;
|
|
40
|
+
if (!config_key) {
|
|
41
|
+
return errResponse('config_key query parameter is required', 400);
|
|
42
|
+
}
|
|
43
|
+
// Try scoped first, then fall back to global (scope_id = null)
|
|
44
|
+
let rows = await configService.findBy({ config_key, scope_id });
|
|
45
|
+
if (rows.length === 0 && scope_id) {
|
|
46
|
+
rows = await configService.findBy({ config_key, scope_id: null });
|
|
47
|
+
}
|
|
48
|
+
if (rows.length === 0) {
|
|
49
|
+
return NextResponse.json({ success: true, data: null });
|
|
50
|
+
}
|
|
51
|
+
const row = rows[0];
|
|
52
|
+
let parsed;
|
|
53
|
+
try {
|
|
54
|
+
parsed = JSON.parse(row.config_value);
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
parsed = row.config_value;
|
|
58
|
+
}
|
|
59
|
+
return NextResponse.json({
|
|
60
|
+
success: true,
|
|
61
|
+
data: { id: row.id, config_key: row.config_key, value: parsed, scope_id: row.scope_id },
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
return errResponse(err?.message || 'Failed to fetch config', 500);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// PUT — upsert config entry
|
|
69
|
+
async function PUT(request) {
|
|
70
|
+
try {
|
|
71
|
+
const adapter = await getHazoConnect();
|
|
72
|
+
const configService = createCrudService(adapter, 'hazo_config');
|
|
73
|
+
const body = await request.json();
|
|
74
|
+
const { config_key, value, scope_id = null } = body;
|
|
75
|
+
if (!config_key) {
|
|
76
|
+
return errResponse('config_key is required', 400);
|
|
77
|
+
}
|
|
78
|
+
if (value === undefined) {
|
|
79
|
+
return errResponse('value is required', 400);
|
|
80
|
+
}
|
|
81
|
+
const config_value = typeof value === 'string' ? value : JSON.stringify(value);
|
|
82
|
+
const now = new Date().toISOString();
|
|
83
|
+
// Find existing row for this key+scope
|
|
84
|
+
const existing = await configService.findBy({ config_key, scope_id });
|
|
85
|
+
let row;
|
|
86
|
+
if (existing.length > 0) {
|
|
87
|
+
const updated = await configService.updateById(existing[0].id, {
|
|
88
|
+
config_value,
|
|
89
|
+
changed_at: now,
|
|
90
|
+
});
|
|
91
|
+
row = Array.isArray(updated) ? updated[0] : updated;
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
const inserted = await configService.insert({
|
|
95
|
+
id: generateUUID(),
|
|
96
|
+
config_key,
|
|
97
|
+
config_value,
|
|
98
|
+
scope_id,
|
|
99
|
+
created_at: now,
|
|
100
|
+
changed_at: null,
|
|
101
|
+
});
|
|
102
|
+
row = Array.isArray(inserted) ? inserted[0] : inserted;
|
|
103
|
+
}
|
|
104
|
+
let parsed;
|
|
105
|
+
try {
|
|
106
|
+
parsed = JSON.parse(row.config_value);
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
parsed = row.config_value;
|
|
110
|
+
}
|
|
111
|
+
return NextResponse.json({
|
|
112
|
+
success: true,
|
|
113
|
+
data: { id: row.id, config_key: row.config_key, value: parsed, scope_id: row.scope_id },
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
return errResponse(err?.message || 'Failed to save config', 500);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return { GET, PUT };
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=create_config_handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create_config_handler.js","sourceRoot":"","sources":["../../src/api/create_config_handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* iHelp API Handler Factory
|
|
3
|
+
*
|
|
4
|
+
* Creates GET, POST, PATCH, and DELETE handlers for ihelp topic endpoints.
|
|
5
|
+
* These handlers should be used in a Next.js API route.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* // app/api/ihelp/topics/route.ts
|
|
10
|
+
* import { createIhelpHandler } from 'hazo_ihelp/api';
|
|
11
|
+
* import { getHazoConnectSingleton } from 'hazo_connect/nextjs/setup';
|
|
12
|
+
*
|
|
13
|
+
* export const dynamic = 'force-dynamic';
|
|
14
|
+
*
|
|
15
|
+
* const { GET, POST } = createIhelpHandler({
|
|
16
|
+
* getHazoConnect: () => getHazoConnectSingleton(),
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* export { GET, POST };
|
|
20
|
+
*
|
|
21
|
+
* // app/api/ihelp/topics/[id]/route.ts
|
|
22
|
+
* import { createIhelpHandler } from 'hazo_ihelp/api';
|
|
23
|
+
* import { getHazoConnectSingleton } from 'hazo_connect/nextjs/setup';
|
|
24
|
+
*
|
|
25
|
+
* export const dynamic = 'force-dynamic';
|
|
26
|
+
*
|
|
27
|
+
* const { PATCH, DELETE } = createIhelpHandler({
|
|
28
|
+
* getHazoConnect: () => getHazoConnectSingleton(),
|
|
29
|
+
* });
|
|
30
|
+
*
|
|
31
|
+
* export { PATCH, DELETE };
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
35
|
+
import type { CreateIhelpHandlerOptions, IhelpApiResponse, IhelpTopic } from '../types/index.js';
|
|
36
|
+
/**
|
|
37
|
+
* Creates GET, POST, PATCH, and DELETE handlers for ihelp topics.
|
|
38
|
+
*
|
|
39
|
+
* @param options - Configuration options
|
|
40
|
+
* @returns Object with GET, POST, PATCH, and DELETE handlers
|
|
41
|
+
*/
|
|
42
|
+
export declare function createIhelpHandler(options: CreateIhelpHandlerOptions): {
|
|
43
|
+
GET: (request: NextRequest) => Promise<NextResponse<IhelpApiResponse<IhelpTopic | IhelpTopic[]>>>;
|
|
44
|
+
POST: (request: NextRequest) => Promise<NextResponse<IhelpApiResponse<IhelpTopic>>>;
|
|
45
|
+
PATCH: (request: NextRequest, context?: {
|
|
46
|
+
params: Promise<{
|
|
47
|
+
id?: string;
|
|
48
|
+
}> | {
|
|
49
|
+
id?: string;
|
|
50
|
+
};
|
|
51
|
+
}) => Promise<NextResponse<IhelpApiResponse<IhelpTopic>>>;
|
|
52
|
+
DELETE: (request: NextRequest, context?: {
|
|
53
|
+
params: Promise<{
|
|
54
|
+
id?: string;
|
|
55
|
+
}> | {
|
|
56
|
+
id?: string;
|
|
57
|
+
};
|
|
58
|
+
}) => Promise<NextResponse<IhelpApiResponse<null>>>;
|
|
59
|
+
};
|
|
60
|
+
//# sourceMappingURL=create_ihelp_handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create_ihelp_handler.d.ts","sourceRoot":"","sources":["../../src/api/create_ihelp_handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAExD,OAAO,KAAK,EACV,yBAAyB,EACzB,gBAAgB,EAChB,UAAU,EAIX,MAAM,mBAAmB,CAAC;AA2C3B;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,yBAAyB;mBA0CxD,WAAW,KACnB,OAAO,CAAC,YAAY,CAAC,gBAAgB,CAAC,UAAU,GAAG,UAAU,EAAE,CAAC,CAAC,CAAC;oBAsG1D,WAAW,KACnB,OAAO,CAAC,YAAY,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAAC;qBAoF3C,WAAW,YACV;QAAE,MAAM,EAAE,OAAO,CAAC;YAAE,EAAE,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,GAAG;YAAE,EAAE,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,KAC/D,OAAO,CAAC,YAAY,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAAC;sBA0G3C,WAAW,YACV;QAAE,MAAM,EAAE,OAAO,CAAC;YAAE,EAAE,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,GAAG;YAAE,EAAE,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,KAC/D,OAAO,CAAC,YAAY,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC;EAmCjD"}
|
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* iHelp API Handler Factory
|
|
3
|
+
*
|
|
4
|
+
* Creates GET, POST, PATCH, and DELETE handlers for ihelp topic endpoints.
|
|
5
|
+
* These handlers should be used in a Next.js API route.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* // app/api/ihelp/topics/route.ts
|
|
10
|
+
* import { createIhelpHandler } from 'hazo_ihelp/api';
|
|
11
|
+
* import { getHazoConnectSingleton } from 'hazo_connect/nextjs/setup';
|
|
12
|
+
*
|
|
13
|
+
* export const dynamic = 'force-dynamic';
|
|
14
|
+
*
|
|
15
|
+
* const { GET, POST } = createIhelpHandler({
|
|
16
|
+
* getHazoConnect: () => getHazoConnectSingleton(),
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* export { GET, POST };
|
|
20
|
+
*
|
|
21
|
+
* // app/api/ihelp/topics/[id]/route.ts
|
|
22
|
+
* import { createIhelpHandler } from 'hazo_ihelp/api';
|
|
23
|
+
* import { getHazoConnectSingleton } from 'hazo_connect/nextjs/setup';
|
|
24
|
+
*
|
|
25
|
+
* export const dynamic = 'force-dynamic';
|
|
26
|
+
*
|
|
27
|
+
* const { PATCH, DELETE } = createIhelpHandler({
|
|
28
|
+
* getHazoConnect: () => getHazoConnectSingleton(),
|
|
29
|
+
* });
|
|
30
|
+
*
|
|
31
|
+
* export { PATCH, DELETE };
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
import { NextResponse } from 'next/server';
|
|
35
|
+
import { createCrudService } from 'hazo_connect/server';
|
|
36
|
+
// ============================================================================
|
|
37
|
+
// Helper Functions
|
|
38
|
+
// ============================================================================
|
|
39
|
+
/** Generate a UUID v4 */
|
|
40
|
+
function generateUUID() {
|
|
41
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
|
42
|
+
const r = (Math.random() * 16) | 0;
|
|
43
|
+
const v = c === 'x' ? r : (r & 0x3) | 0x8;
|
|
44
|
+
return v.toString(16);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
/** No-op logger */
|
|
48
|
+
const noopLogger = {
|
|
49
|
+
error: () => { },
|
|
50
|
+
warn: () => { },
|
|
51
|
+
info: () => { },
|
|
52
|
+
debug: () => { },
|
|
53
|
+
};
|
|
54
|
+
/** Create a standardized error response */
|
|
55
|
+
function createErrorResponse(error, status) {
|
|
56
|
+
return NextResponse.json({ success: false, error }, { status });
|
|
57
|
+
}
|
|
58
|
+
// ============================================================================
|
|
59
|
+
// Handler Factory
|
|
60
|
+
// ============================================================================
|
|
61
|
+
/**
|
|
62
|
+
* Creates GET, POST, PATCH, and DELETE handlers for ihelp topics.
|
|
63
|
+
*
|
|
64
|
+
* @param options - Configuration options
|
|
65
|
+
* @returns Object with GET, POST, PATCH, and DELETE handlers
|
|
66
|
+
*/
|
|
67
|
+
export function createIhelpHandler(options) {
|
|
68
|
+
const { getHazoConnect, getLogger } = options;
|
|
69
|
+
const logger = getLogger?.() || noopLogger;
|
|
70
|
+
// ---------------------------------------------------------------------------
|
|
71
|
+
// Internal helper: assemble a full IhelpTopic with joined tags & context_keys
|
|
72
|
+
// ---------------------------------------------------------------------------
|
|
73
|
+
async function assembleTopicWithJoins(topicRow, adapter) {
|
|
74
|
+
const tagsService = createCrudService(adapter, 'ihelp_tags');
|
|
75
|
+
const contextMapService = createCrudService(adapter, 'ihelp_context_map');
|
|
76
|
+
const [tags, contextMappings] = await Promise.all([
|
|
77
|
+
tagsService.findBy({ topic_id: topicRow.id }),
|
|
78
|
+
contextMapService.findBy({ topic_id: topicRow.id }),
|
|
79
|
+
]);
|
|
80
|
+
return {
|
|
81
|
+
...topicRow,
|
|
82
|
+
tags,
|
|
83
|
+
context_keys: contextMappings.map((m) => m.context_key),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
// ---------------------------------------------------------------------------
|
|
87
|
+
// GET handler — list topics (with optional filters) or fetch single topic
|
|
88
|
+
// ---------------------------------------------------------------------------
|
|
89
|
+
/**
|
|
90
|
+
* GET handler
|
|
91
|
+
*
|
|
92
|
+
* Query params:
|
|
93
|
+
* - id — fetch a single topic by UUID
|
|
94
|
+
* - context_key — return topics mapped to this context key
|
|
95
|
+
* - scope_id — filter to globally-visible + scope-specific topics
|
|
96
|
+
* - category — filter by category label
|
|
97
|
+
* - search — ilike filter on title and description
|
|
98
|
+
*/
|
|
99
|
+
async function GET(request) {
|
|
100
|
+
try {
|
|
101
|
+
const searchParams = request.nextUrl.searchParams;
|
|
102
|
+
const id = searchParams.get('id');
|
|
103
|
+
const context_key = searchParams.get('context_key');
|
|
104
|
+
const scope_id = searchParams.get('scope_id');
|
|
105
|
+
const category = searchParams.get('category');
|
|
106
|
+
const search = searchParams.get('search');
|
|
107
|
+
logger.debug('[hazo_ihelp] GET request', { id, context_key, scope_id, category, search });
|
|
108
|
+
const adapter = await getHazoConnect();
|
|
109
|
+
const topicsService = createCrudService(adapter, 'ihelp_topics');
|
|
110
|
+
// ---- Single topic fetch ----
|
|
111
|
+
if (id) {
|
|
112
|
+
const topic = await topicsService.findById(id);
|
|
113
|
+
if (!topic) {
|
|
114
|
+
return createErrorResponse('Topic not found', 404);
|
|
115
|
+
}
|
|
116
|
+
const assembled = await assembleTopicWithJoins(topic, adapter);
|
|
117
|
+
return NextResponse.json({ success: true, data: assembled });
|
|
118
|
+
}
|
|
119
|
+
// ---- Context key lookup ----
|
|
120
|
+
if (context_key) {
|
|
121
|
+
const contextMapService = createCrudService(adapter, 'ihelp_context_map');
|
|
122
|
+
const mappings = await contextMapService.findBy({ context_key });
|
|
123
|
+
if (!mappings.length) {
|
|
124
|
+
return NextResponse.json({ success: true, data: [] });
|
|
125
|
+
}
|
|
126
|
+
// Sort by priority ascending, then fetch matching topics
|
|
127
|
+
const sortedMappings = mappings.sort((a, b) => a.priority - b.priority);
|
|
128
|
+
const topicIds = sortedMappings.map((m) => m.topic_id);
|
|
129
|
+
const allTopics = [];
|
|
130
|
+
for (const topicId of topicIds) {
|
|
131
|
+
const topic = await topicsService.findById(topicId);
|
|
132
|
+
if (topic) {
|
|
133
|
+
const assembled = await assembleTopicWithJoins(topic, adapter);
|
|
134
|
+
allTopics.push(assembled);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return NextResponse.json({ success: true, data: allTopics });
|
|
138
|
+
}
|
|
139
|
+
// ---- List with optional filters ----
|
|
140
|
+
const rows = await topicsService.list((qb) => {
|
|
141
|
+
let q = qb;
|
|
142
|
+
if (scope_id) {
|
|
143
|
+
// Topics where scope_id IS NULL or matches the given value
|
|
144
|
+
q = q.whereOr([
|
|
145
|
+
{ field: 'scope_id', operator: 'is', value: null },
|
|
146
|
+
{ field: 'scope_id', operator: 'eq', value: scope_id },
|
|
147
|
+
]);
|
|
148
|
+
}
|
|
149
|
+
if (category) {
|
|
150
|
+
q = q.where('category', 'eq', category);
|
|
151
|
+
}
|
|
152
|
+
if (search) {
|
|
153
|
+
// ilike search on title and description
|
|
154
|
+
q = q.whereOr([
|
|
155
|
+
{ field: 'title', operator: 'ilike', value: `%${search}%` },
|
|
156
|
+
{ field: 'description', operator: 'ilike', value: `%${search}%` },
|
|
157
|
+
]);
|
|
158
|
+
}
|
|
159
|
+
return q;
|
|
160
|
+
});
|
|
161
|
+
const assembled = await Promise.all(rows.map((row) => assembleTopicWithJoins(row, adapter)));
|
|
162
|
+
return NextResponse.json({ success: true, data: assembled });
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
logger.error('[hazo_ihelp] GET error', {
|
|
166
|
+
error: error instanceof Error ? error.message : String(error),
|
|
167
|
+
});
|
|
168
|
+
return createErrorResponse('Failed to fetch topics', 500);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// ---------------------------------------------------------------------------
|
|
172
|
+
// POST handler — create a new topic
|
|
173
|
+
// ---------------------------------------------------------------------------
|
|
174
|
+
/**
|
|
175
|
+
* POST handler
|
|
176
|
+
*
|
|
177
|
+
* Body: IhelpTopicInput
|
|
178
|
+
*/
|
|
179
|
+
async function POST(request) {
|
|
180
|
+
try {
|
|
181
|
+
const body = (await request.json());
|
|
182
|
+
if (!body.title) {
|
|
183
|
+
return createErrorResponse('title is required', 400);
|
|
184
|
+
}
|
|
185
|
+
logger.debug('[hazo_ihelp] POST request', { title: body.title });
|
|
186
|
+
const adapter = await getHazoConnect();
|
|
187
|
+
const topicsService = createCrudService(adapter, 'ihelp_topics');
|
|
188
|
+
const tagsService = createCrudService(adapter, 'ihelp_tags');
|
|
189
|
+
const contextMapService = createCrudService(adapter, 'ihelp_context_map');
|
|
190
|
+
const topicId = generateUUID();
|
|
191
|
+
const now = new Date().toISOString();
|
|
192
|
+
// Insert topic
|
|
193
|
+
const inserted = await topicsService.insert({
|
|
194
|
+
id: topicId,
|
|
195
|
+
parent_id: body.parent_id ?? null,
|
|
196
|
+
scope_id: body.scope_id ?? null,
|
|
197
|
+
category: body.category ?? '',
|
|
198
|
+
title: body.title,
|
|
199
|
+
description: body.description ?? null,
|
|
200
|
+
content: body.content ?? null,
|
|
201
|
+
icon: body.icon ?? null,
|
|
202
|
+
sort_order: body.sort_order ?? 0,
|
|
203
|
+
is_published: body.is_published ?? false,
|
|
204
|
+
created_at: now,
|
|
205
|
+
changed_at: null,
|
|
206
|
+
});
|
|
207
|
+
const topicRow = Array.isArray(inserted) ? inserted[0] : inserted;
|
|
208
|
+
// Insert tags if provided
|
|
209
|
+
if (body.tags && body.tags.length > 0) {
|
|
210
|
+
const tagRows = body.tags.map((tag) => ({
|
|
211
|
+
id: generateUUID(),
|
|
212
|
+
topic_id: topicId,
|
|
213
|
+
label: tag.label,
|
|
214
|
+
variant: tag.variant ?? 'default',
|
|
215
|
+
icon: tag.icon ?? null,
|
|
216
|
+
}));
|
|
217
|
+
await tagsService.insert(tagRows);
|
|
218
|
+
}
|
|
219
|
+
// Insert context_keys if provided
|
|
220
|
+
if (body.context_keys && body.context_keys.length > 0) {
|
|
221
|
+
const mapRows = body.context_keys.map((key, index) => ({
|
|
222
|
+
id: generateUUID(),
|
|
223
|
+
topic_id: topicId,
|
|
224
|
+
context_key: key,
|
|
225
|
+
priority: index,
|
|
226
|
+
}));
|
|
227
|
+
await contextMapService.insert(mapRows);
|
|
228
|
+
}
|
|
229
|
+
const assembled = await assembleTopicWithJoins(topicRow, adapter);
|
|
230
|
+
return NextResponse.json({ success: true, data: assembled }, { status: 201 });
|
|
231
|
+
}
|
|
232
|
+
catch (error) {
|
|
233
|
+
logger.error('[hazo_ihelp] POST error', {
|
|
234
|
+
error: error instanceof Error ? error.message : String(error),
|
|
235
|
+
});
|
|
236
|
+
return createErrorResponse('Failed to create topic', 500);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
// ---------------------------------------------------------------------------
|
|
240
|
+
// PATCH handler — update an existing topic
|
|
241
|
+
// ---------------------------------------------------------------------------
|
|
242
|
+
/**
|
|
243
|
+
* PATCH handler
|
|
244
|
+
*
|
|
245
|
+
* Expects `id` as a URL search param or route segment param.
|
|
246
|
+
* Body: Partial<IhelpTopicInput>
|
|
247
|
+
*/
|
|
248
|
+
async function PATCH(request, context) {
|
|
249
|
+
try {
|
|
250
|
+
// Resolve id from params or query string
|
|
251
|
+
let id;
|
|
252
|
+
if (context?.params) {
|
|
253
|
+
const resolved = context.params instanceof Promise
|
|
254
|
+
? await context.params
|
|
255
|
+
: context.params;
|
|
256
|
+
id = resolved.id;
|
|
257
|
+
}
|
|
258
|
+
if (!id) {
|
|
259
|
+
id = request.nextUrl.searchParams.get('id') ?? undefined;
|
|
260
|
+
}
|
|
261
|
+
if (!id) {
|
|
262
|
+
return createErrorResponse('id is required', 400);
|
|
263
|
+
}
|
|
264
|
+
const body = (await request.json());
|
|
265
|
+
logger.debug('[hazo_ihelp] PATCH request', { id });
|
|
266
|
+
const adapter = await getHazoConnect();
|
|
267
|
+
const topicsService = createCrudService(adapter, 'ihelp_topics');
|
|
268
|
+
const tagsService = createCrudService(adapter, 'ihelp_tags');
|
|
269
|
+
const contextMapService = createCrudService(adapter, 'ihelp_context_map');
|
|
270
|
+
// Build the patch payload (exclude relation fields)
|
|
271
|
+
const patch = { changed_at: new Date().toISOString() };
|
|
272
|
+
if (body.parent_id !== undefined)
|
|
273
|
+
patch.parent_id = body.parent_id;
|
|
274
|
+
if (body.scope_id !== undefined)
|
|
275
|
+
patch.scope_id = body.scope_id;
|
|
276
|
+
if (body.category !== undefined)
|
|
277
|
+
patch.category = body.category;
|
|
278
|
+
if (body.title !== undefined)
|
|
279
|
+
patch.title = body.title;
|
|
280
|
+
if (body.description !== undefined)
|
|
281
|
+
patch.description = body.description;
|
|
282
|
+
if (body.content !== undefined)
|
|
283
|
+
patch.content = body.content;
|
|
284
|
+
if (body.icon !== undefined)
|
|
285
|
+
patch.icon = body.icon;
|
|
286
|
+
if (body.sort_order !== undefined)
|
|
287
|
+
patch.sort_order = body.sort_order;
|
|
288
|
+
if (body.is_published !== undefined)
|
|
289
|
+
patch.is_published = body.is_published;
|
|
290
|
+
const updated = await topicsService.updateById(id, patch);
|
|
291
|
+
if (!updated || updated.length === 0) {
|
|
292
|
+
return createErrorResponse('Topic not found', 404);
|
|
293
|
+
}
|
|
294
|
+
const topicRow = updated[0];
|
|
295
|
+
// Replace tags if provided
|
|
296
|
+
if (body.tags !== undefined) {
|
|
297
|
+
// Delete existing tags one-by-one (deleteById targets the primary key)
|
|
298
|
+
const existingTags = await tagsService.findBy({ topic_id: id });
|
|
299
|
+
for (const tag of existingTags) {
|
|
300
|
+
await tagsService.deleteById(tag.id);
|
|
301
|
+
}
|
|
302
|
+
if (body.tags.length > 0) {
|
|
303
|
+
const tagRows = body.tags.map((tag) => ({
|
|
304
|
+
id: generateUUID(),
|
|
305
|
+
topic_id: id,
|
|
306
|
+
label: tag.label,
|
|
307
|
+
variant: tag.variant ?? 'default',
|
|
308
|
+
icon: tag.icon ?? null,
|
|
309
|
+
}));
|
|
310
|
+
await tagsService.insert(tagRows);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
// Replace context_keys if provided
|
|
314
|
+
if (body.context_keys !== undefined) {
|
|
315
|
+
const existingMappings = await contextMapService.findBy({ topic_id: id });
|
|
316
|
+
for (const mapping of existingMappings) {
|
|
317
|
+
await contextMapService.deleteById(mapping.id);
|
|
318
|
+
}
|
|
319
|
+
if (body.context_keys.length > 0) {
|
|
320
|
+
const mapRows = body.context_keys.map((key, index) => ({
|
|
321
|
+
id: generateUUID(),
|
|
322
|
+
topic_id: id,
|
|
323
|
+
context_key: key,
|
|
324
|
+
priority: index,
|
|
325
|
+
}));
|
|
326
|
+
await contextMapService.insert(mapRows);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
const assembled = await assembleTopicWithJoins(topicRow, adapter);
|
|
330
|
+
return NextResponse.json({ success: true, data: assembled });
|
|
331
|
+
}
|
|
332
|
+
catch (error) {
|
|
333
|
+
logger.error('[hazo_ihelp] PATCH error', {
|
|
334
|
+
error: error instanceof Error ? error.message : String(error),
|
|
335
|
+
});
|
|
336
|
+
return createErrorResponse('Failed to update topic', 500);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
// ---------------------------------------------------------------------------
|
|
340
|
+
// DELETE handler — remove a topic (CASCADE handles tags & context_map)
|
|
341
|
+
// ---------------------------------------------------------------------------
|
|
342
|
+
/**
|
|
343
|
+
* DELETE handler
|
|
344
|
+
*
|
|
345
|
+
* Expects `id` as a URL search param or route segment param.
|
|
346
|
+
*/
|
|
347
|
+
async function DELETE(request, context) {
|
|
348
|
+
try {
|
|
349
|
+
// Resolve id from params or query string
|
|
350
|
+
let id;
|
|
351
|
+
if (context?.params) {
|
|
352
|
+
const resolved = context.params instanceof Promise
|
|
353
|
+
? await context.params
|
|
354
|
+
: context.params;
|
|
355
|
+
id = resolved.id;
|
|
356
|
+
}
|
|
357
|
+
if (!id) {
|
|
358
|
+
id = request.nextUrl.searchParams.get('id') ?? undefined;
|
|
359
|
+
}
|
|
360
|
+
if (!id) {
|
|
361
|
+
return createErrorResponse('id is required', 400);
|
|
362
|
+
}
|
|
363
|
+
logger.debug('[hazo_ihelp] DELETE request', { id });
|
|
364
|
+
const adapter = await getHazoConnect();
|
|
365
|
+
const topicsService = createCrudService(adapter, 'ihelp_topics');
|
|
366
|
+
await topicsService.deleteById(id);
|
|
367
|
+
return NextResponse.json({ success: true, data: null });
|
|
368
|
+
}
|
|
369
|
+
catch (error) {
|
|
370
|
+
logger.error('[hazo_ihelp] DELETE error', {
|
|
371
|
+
error: error instanceof Error ? error.message : String(error),
|
|
372
|
+
});
|
|
373
|
+
return createErrorResponse('Failed to delete topic', 500);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
return { GET, POST, PATCH, DELETE };
|
|
377
|
+
}
|
|
378
|
+
//# sourceMappingURL=create_ihelp_handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create_ihelp_handler.js","sourceRoot":"","sources":["../../src/api/create_ihelp_handler.ts"],"names":[],"mappings":"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"}
|