hazo_ihelp 2.0.9 → 2.1.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.
- package/SETUP_CHECKLIST.md +131 -0
- package/config/hazo_ihelp_config.ini.sample +41 -8
- package/db_setup_postgres.sql +52 -0
- package/db_setup_sqlite.sql +25 -0
- package/dist/api/create_config_handler.d.ts +2 -0
- package/dist/api/create_config_handler.d.ts.map +1 -1
- package/dist/api/create_config_handler.js +117 -81
- package/dist/api/create_config_handler.js.map +1 -1
- package/dist/api/create_ihelp_handler.d.ts +4 -12
- package/dist/api/create_ihelp_handler.d.ts.map +1 -1
- package/dist/api/create_ihelp_handler.js +251 -226
- package/dist/api/create_ihelp_handler.js.map +1 -1
- package/dist/api/image_upload_handler.d.ts.map +1 -1
- package/dist/api/image_upload_handler.js +114 -80
- package/dist/api/image_upload_handler.js.map +1 -1
- package/dist/components/editor/editor_collapsible_section.js +1 -1
- package/dist/components/editor/editor_collapsible_section.js.map +1 -1
- package/dist/components/editor/editor_form.js +1 -1
- package/dist/components/editor/editor_form.js.map +1 -1
- package/dist/components/editor/editor_topic_list_item.js +1 -1
- package/dist/components/editor/editor_topic_list_item.js.map +1 -1
- package/dist/components/hover_help_icon.d.ts +39 -0
- package/dist/components/hover_help_icon.d.ts.map +1 -0
- package/dist/components/hover_help_icon.js +29 -0
- package/dist/components/hover_help_icon.js.map +1 -0
- package/dist/components/ihelp_detail_panel.js +1 -1
- package/dist/components/ihelp_detail_panel.js.map +1 -1
- package/dist/components/ihelp_editor.js +1 -1
- package/dist/components/ihelp_editor.js.map +1 -1
- package/dist/components/ihelp_icon.js +1 -1
- package/dist/components/ihelp_icon.js.map +1 -1
- package/dist/components/ihelp_provider.d.ts.map +1 -1
- package/dist/components/ihelp_provider.js +6 -1
- package/dist/components/ihelp_provider.js.map +1 -1
- package/dist/components/ihelp_rich_editor.js +1 -1
- package/dist/components/ihelp_rich_editor.js.map +1 -1
- package/dist/components/ihelp_search_dialog.js +1 -1
- package/dist/components/ihelp_search_dialog.js.map +1 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +1 -0
- package/dist/components/index.js.map +1 -1
- package/dist/components/ui/badge.js +1 -1
- package/dist/components/ui/badge.js.map +1 -1
- package/dist/components/ui/button.js +1 -1
- package/dist/components/ui/button.js.map +1 -1
- package/dist/components/ui/dialog.js +1 -1
- package/dist/components/ui/dialog.js.map +1 -1
- package/dist/components/ui/input.js +1 -1
- package/dist/components/ui/input.js.map +1 -1
- package/dist/components/ui/label.js +1 -1
- package/dist/components/ui/label.js.map +1 -1
- package/dist/components/ui/popover.js +1 -1
- package/dist/components/ui/popover.js.map +1 -1
- package/dist/components/ui/select.js +1 -1
- package/dist/components/ui/select.js.map +1 -1
- package/dist/components/ui/switch.js +1 -1
- package/dist/components/ui/switch.js.map +1 -1
- package/dist/components/ui/textarea.js +1 -1
- package/dist/components/ui/textarea.js.map +1 -1
- package/dist/index.client.d.ts +1 -1
- package/dist/index.client.d.ts.map +1 -1
- package/dist/index.client.js +1 -1
- package/dist/index.client.js.map +1 -1
- package/dist/lib/config/hazo_ihelp_config.d.ts +106 -0
- package/dist/lib/config/hazo_ihelp_config.d.ts.map +1 -0
- package/dist/lib/config/hazo_ihelp_config.js +66 -0
- package/dist/lib/config/hazo_ihelp_config.js.map +1 -0
- package/dist/utils/logger.d.ts +25 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +42 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +65 -22
- package/config/hazo_ihelp_config.ini +0 -9
- package/dist/utils/cn.d.ts +0 -3
- package/dist/utils/cn.d.ts.map +0 -1
- package/dist/utils/cn.js +0 -6
- package/dist/utils/cn.js.map +0 -1
- package/migrations/001_create_ihelp_tables.sql +0 -109
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# hazo_ihelp — Setup Checklist
|
|
2
|
+
|
|
3
|
+
Step-by-step guide for adding hazo_ihelp to a consuming Next.js app.
|
|
4
|
+
|
|
5
|
+
## 1. Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install hazo_ihelp hazo_core hazo_ui hazo_connect
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
`hazo_core` and `hazo_ui` are required peer deps. `hazo_connect` is the
|
|
12
|
+
database adapter used by the API handlers (mark as a peer dep, mark
|
|
13
|
+
optional only if you bring your own adapter implementing the same shape).
|
|
14
|
+
|
|
15
|
+
For image-upload support, optionally install `sharp` for server-side
|
|
16
|
+
resizing (the handler degrades gracefully without it):
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install sharp
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## 2. Configure
|
|
23
|
+
|
|
24
|
+
Copy the sample INI into your app:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
mkdir -p config
|
|
28
|
+
cp node_modules/hazo_ihelp/config/hazo_ihelp_config.ini.sample config/hazo_ihelp_config.ini
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Adjust `upload_dir`, `upload_url_prefix`, and the size / MIME limits to
|
|
32
|
+
match your hosting setup. Any value can also be overridden via env vars
|
|
33
|
+
(`HAZO_IHELP_IMAGE_UPLOAD_MAX_FILE_SIZE_MB=10`) or layered with a
|
|
34
|
+
per-environment overlay file (`hazo_ihelp_config.<HAZO_ENV>.ini`).
|
|
35
|
+
|
|
36
|
+
## 3. Run the schema setup
|
|
37
|
+
|
|
38
|
+
Pick the file that matches your database and run it once:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
psql "$DATABASE_URL" -f node_modules/hazo_ihelp/db_setup_postgres.sql
|
|
42
|
+
# or
|
|
43
|
+
sqlite3 path/to/app.sqlite < node_modules/hazo_ihelp/db_setup_sqlite.sql
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The script is idempotent — safe to re-run. The PostgreSQL version ends
|
|
47
|
+
with `SELECT pg_notify('pgrst', 'reload schema');` so PostgREST picks
|
|
48
|
+
up the new tables without a restart.
|
|
49
|
+
|
|
50
|
+
The shared `hazo_config` table is created by the `hazo_config` package's
|
|
51
|
+
own setup script — make sure it's been run too.
|
|
52
|
+
|
|
53
|
+
## 4. Mount the API routes
|
|
54
|
+
|
|
55
|
+
Three routes are needed (paths shown match the defaults the hooks use):
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
// app/api/ihelp/topics/route.ts
|
|
59
|
+
import { createIhelpHandler } from 'hazo_ihelp/api';
|
|
60
|
+
import { getHazoConnectSingleton } from 'hazo_connect/nextjs/setup';
|
|
61
|
+
export const dynamic = 'force-dynamic';
|
|
62
|
+
const { GET, POST } = createIhelpHandler({
|
|
63
|
+
getHazoConnect: () => getHazoConnectSingleton(),
|
|
64
|
+
});
|
|
65
|
+
export { GET, POST };
|
|
66
|
+
|
|
67
|
+
// app/api/ihelp/topics/[id]/route.ts
|
|
68
|
+
import { createIhelpHandler } from 'hazo_ihelp/api';
|
|
69
|
+
import { getHazoConnectSingleton } from 'hazo_connect/nextjs/setup';
|
|
70
|
+
export const dynamic = 'force-dynamic';
|
|
71
|
+
const { PATCH, DELETE } = createIhelpHandler({
|
|
72
|
+
getHazoConnect: () => getHazoConnectSingleton(),
|
|
73
|
+
});
|
|
74
|
+
export { PATCH, DELETE };
|
|
75
|
+
|
|
76
|
+
// app/api/ihelp/config/route.ts
|
|
77
|
+
import { createConfigHandler } from 'hazo_ihelp/api';
|
|
78
|
+
import { getHazoConnectSingleton } from 'hazo_connect/nextjs/setup';
|
|
79
|
+
export const dynamic = 'force-dynamic';
|
|
80
|
+
const handler = createConfigHandler({
|
|
81
|
+
getHazoConnect: () => getHazoConnectSingleton(),
|
|
82
|
+
});
|
|
83
|
+
export const GET = handler.GET;
|
|
84
|
+
export const PUT = handler.PUT;
|
|
85
|
+
|
|
86
|
+
// app/api/ihelp/upload/route.ts
|
|
87
|
+
import { createImageUploadHandler } from 'hazo_ihelp/api';
|
|
88
|
+
export const runtime = 'nodejs';
|
|
89
|
+
const { POST } = createImageUploadHandler();
|
|
90
|
+
export { POST };
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## 5. Wrap the React tree
|
|
94
|
+
|
|
95
|
+
```tsx
|
|
96
|
+
import { IhelpProvider } from 'hazo_ihelp';
|
|
97
|
+
|
|
98
|
+
export default function RootLayout({ children }) {
|
|
99
|
+
return (
|
|
100
|
+
<html><body>
|
|
101
|
+
<IhelpProvider scope_id={current_org_id}>
|
|
102
|
+
{children}
|
|
103
|
+
</IhelpProvider>
|
|
104
|
+
</body></html>
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## 6. Drop in triggers near the UI they explain
|
|
110
|
+
|
|
111
|
+
```tsx
|
|
112
|
+
import { IhelpIcon } from 'hazo_ihelp';
|
|
113
|
+
|
|
114
|
+
<label>
|
|
115
|
+
Work-from-home deduction <IhelpIcon context_key="deductions.work_from_home" />
|
|
116
|
+
</label>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## 7. Author topics
|
|
120
|
+
|
|
121
|
+
Either through the bundled `<IhelpEditor>` admin surface or by POSTing
|
|
122
|
+
to `/api/ihelp/topics` directly. Topics are unpublished by default —
|
|
123
|
+
set `is_published: true` once they're ready for end users.
|
|
124
|
+
|
|
125
|
+
## 8. (Optional) Verify
|
|
126
|
+
|
|
127
|
+
- [ ] `npm run build` — package builds clean
|
|
128
|
+
- [ ] Open `/your/page/with/<IhelpIcon>` in dev — clicking opens the search dialog
|
|
129
|
+
- [ ] Press Cmd/Ctrl+K — search dialog toggles
|
|
130
|
+
- [ ] POST a topic with a `context_key` you used → the icon resolves to it
|
|
131
|
+
- [ ] Check server logs for `topic.created` events tagged with `correlationId`
|
|
@@ -1,23 +1,56 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
# hazo_ihelp Configuration File
|
|
2
|
+
# This file controls runtime behaviour of hazo_ihelp.
|
|
3
|
+
# All values are commented out by default - uncomment and modify as needed.
|
|
4
|
+
#
|
|
5
|
+
# Per hazo workspace standard S7, values may also be overridden via env vars:
|
|
6
|
+
# HAZO_IHELP_<SECTION>_<KEY>=value
|
|
7
|
+
# e.g. HAZO_IHELP_IMAGE_UPLOAD_MAX_FILE_SIZE_MB=10
|
|
8
|
+
#
|
|
9
|
+
# Per D-019, a per-environment overlay file at config/hazo_ihelp_config.<HAZO_ENV>.ini
|
|
10
|
+
# is layered on top of this base file when HAZO_ENV is set.
|
|
3
11
|
|
|
12
|
+
# =============================================================================
|
|
13
|
+
# [general] - Workspace-standard general configuration
|
|
14
|
+
# =============================================================================
|
|
15
|
+
[general]
|
|
16
|
+
|
|
17
|
+
# Deployment environment label. Falls back to NODE_ENV, then 'development'.
|
|
18
|
+
# env = production
|
|
19
|
+
|
|
20
|
+
# Default base URL for ihelp API requests on the server side.
|
|
21
|
+
# api_base_url = /api/ihelp
|
|
22
|
+
|
|
23
|
+
# =============================================================================
|
|
24
|
+
# [log.overrides] - Per-namespace log level overrides (workspace standard)
|
|
25
|
+
# Format: <namespace> = trace|debug|info|warn|error
|
|
26
|
+
# =============================================================================
|
|
27
|
+
[log.overrides]
|
|
28
|
+
|
|
29
|
+
# hazo_ihelp = info
|
|
30
|
+
# hazo_ihelp/topics = warn
|
|
31
|
+
# hazo_ihelp/upload = debug
|
|
32
|
+
|
|
33
|
+
# =============================================================================
|
|
34
|
+
# [image_upload] - Image upload handler defaults
|
|
35
|
+
# =============================================================================
|
|
4
36
|
[image_upload]
|
|
5
|
-
|
|
37
|
+
|
|
38
|
+
# Maximum file size in MB
|
|
6
39
|
max_file_size_mb = 5
|
|
7
40
|
|
|
8
|
-
|
|
41
|
+
# Allowed MIME types (comma-separated)
|
|
9
42
|
allowed_types = image/jpeg, image/png, image/gif, image/webp, image/svg+xml, image/avif
|
|
10
43
|
|
|
11
|
-
|
|
44
|
+
# Filesystem path where uploaded images are saved (relative to project root)
|
|
12
45
|
upload_dir = public/ihelp/images
|
|
13
46
|
|
|
14
|
-
|
|
47
|
+
# URL prefix returned in API responses (must match how upload_dir is served)
|
|
15
48
|
upload_url_prefix = /ihelp/images
|
|
16
49
|
|
|
17
|
-
|
|
50
|
+
# Resize images that exceed max dimensions (skips SVG)
|
|
18
51
|
resize_enabled = true
|
|
19
52
|
resize_max_width = 1200
|
|
20
53
|
resize_max_height = 1200
|
|
21
54
|
|
|
22
|
-
|
|
55
|
+
# JPEG/WebP quality (1-100)
|
|
23
56
|
resize_quality = 80
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
-- hazo_ihelp — PostgreSQL setup
|
|
2
|
+
-- Idempotent — safe to re-run. PostgreSQL uses native UUID, JSONB,
|
|
3
|
+
-- BOOLEAN, and TIMESTAMPTZ types.
|
|
4
|
+
--
|
|
5
|
+
-- Requires extension:
|
|
6
|
+
-- CREATE EXTENSION IF NOT EXISTS "pgcrypto"; -- for gen_random_uuid()
|
|
7
|
+
|
|
8
|
+
-- =============================================================================
|
|
9
|
+
-- hazo_ihelp_topics
|
|
10
|
+
-- =============================================================================
|
|
11
|
+
CREATE TABLE IF NOT EXISTS hazo_ihelp_topics (
|
|
12
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
13
|
+
parent_id UUID REFERENCES hazo_ihelp_topics(id) ON DELETE SET NULL,
|
|
14
|
+
scope_id UUID, -- NULL = global, UUID = org-specific
|
|
15
|
+
category TEXT NOT NULL DEFAULT 'General',
|
|
16
|
+
title TEXT NOT NULL,
|
|
17
|
+
description TEXT, -- short summary for search cards
|
|
18
|
+
content TEXT, -- rich HTML from Tiptap editor
|
|
19
|
+
icon TEXT, -- Lucide icon name
|
|
20
|
+
sort_order INTEGER NOT NULL DEFAULT 0,
|
|
21
|
+
is_published BOOLEAN NOT NULL DEFAULT TRUE,
|
|
22
|
+
tags JSONB NOT NULL DEFAULT '[]', -- [{label, variant, icon}]
|
|
23
|
+
contexts JSONB NOT NULL DEFAULT '[]', -- [{key, priority}]
|
|
24
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
25
|
+
changed_at TIMESTAMPTZ
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
CREATE INDEX IF NOT EXISTS idx_hazo_ihelp_topics_scope ON hazo_ihelp_topics(scope_id);
|
|
29
|
+
CREATE INDEX IF NOT EXISTS idx_hazo_ihelp_topics_parent ON hazo_ihelp_topics(parent_id);
|
|
30
|
+
CREATE INDEX IF NOT EXISTS idx_hazo_ihelp_topics_tags ON hazo_ihelp_topics USING GIN (tags);
|
|
31
|
+
CREATE INDEX IF NOT EXISTS idx_hazo_ihelp_topics_contexts ON hazo_ihelp_topics USING GIN (contexts);
|
|
32
|
+
|
|
33
|
+
-- =============================================================================
|
|
34
|
+
-- JSON column shapes
|
|
35
|
+
-- =============================================================================
|
|
36
|
+
-- tags: [{ "label": "Receipt Required", "variant": "warning", "icon": "AlertTriangle" }]
|
|
37
|
+
-- contexts: [{ "key": "deductions.work_from_home", "priority": 0 }]
|
|
38
|
+
|
|
39
|
+
-- =============================================================================
|
|
40
|
+
-- Example queries
|
|
41
|
+
-- =============================================================================
|
|
42
|
+
-- -- Find topics mapped to a context key, priority-ordered:
|
|
43
|
+
-- SELECT * FROM hazo_ihelp_topics
|
|
44
|
+
-- WHERE contexts @> '[{"key": "deductions.work_from_home"}]'
|
|
45
|
+
-- ORDER BY (SELECT MIN((ctx->>'priority')::int)
|
|
46
|
+
-- FROM jsonb_array_elements(contexts) ctx
|
|
47
|
+
-- WHERE ctx->>'key' = 'deductions.work_from_home');
|
|
48
|
+
--
|
|
49
|
+
-- -- Find topics with a specific tag label:
|
|
50
|
+
-- SELECT * FROM hazo_ihelp_topics WHERE tags @> '[{"label": "Pre-filled"}]';
|
|
51
|
+
|
|
52
|
+
SELECT pg_notify('pgrst', 'reload schema');
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
-- hazo_ihelp — SQLite setup
|
|
2
|
+
-- Idempotent — safe to re-run. SQLite stores UUIDs as TEXT and JSON as TEXT.
|
|
3
|
+
-- No native UUID, JSONB, BOOLEAN, or TIMESTAMPTZ types — see the PostgreSQL
|
|
4
|
+
-- companion file at db_setup_postgres.sql for the equivalent native typing.
|
|
5
|
+
|
|
6
|
+
CREATE TABLE IF NOT EXISTS hazo_ihelp_topics (
|
|
7
|
+
id TEXT PRIMARY KEY, -- UUID as text
|
|
8
|
+
parent_id TEXT, -- UUID ref → hazo_ihelp_topics(id)
|
|
9
|
+
scope_id TEXT, -- UUID, NULL = global
|
|
10
|
+
category TEXT NOT NULL DEFAULT 'General',
|
|
11
|
+
title TEXT NOT NULL,
|
|
12
|
+
description TEXT,
|
|
13
|
+
content TEXT, -- rich HTML from Tiptap editor
|
|
14
|
+
icon TEXT, -- Lucide icon name
|
|
15
|
+
sort_order INTEGER NOT NULL DEFAULT 0,
|
|
16
|
+
is_published INTEGER NOT NULL DEFAULT 1, -- SQLite boolean (0/1)
|
|
17
|
+
tags TEXT NOT NULL DEFAULT '[]', -- JSON array: [{label, variant, icon}]
|
|
18
|
+
contexts TEXT NOT NULL DEFAULT '[]', -- JSON array: [{key, priority}]
|
|
19
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
20
|
+
changed_at TEXT,
|
|
21
|
+
FOREIGN KEY (parent_id) REFERENCES hazo_ihelp_topics(id) ON DELETE SET NULL
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
CREATE INDEX IF NOT EXISTS idx_hazo_ihelp_topics_scope ON hazo_ihelp_topics(scope_id);
|
|
25
|
+
CREATE INDEX IF NOT EXISTS idx_hazo_ihelp_topics_parent ON hazo_ihelp_topics(parent_id);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create_config_handler.d.ts","sourceRoot":"","sources":["../../src/api/create_config_handler.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"create_config_handler.d.ts","sourceRoot":"","sources":["../../src/api/create_config_handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAUxD,OAAO,KAAK,EAAiB,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AA0BzE,MAAM,WAAW,0BAA0B;IACzC,cAAc,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;CAC1C;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,0BAA0B;mBAKzC,WAAW,KAAG,OAAO,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC;mBAiDrD,WAAW,KAAG,OAAO,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC;EAwElF"}
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
* Config API Handler Factory
|
|
3
3
|
*
|
|
4
4
|
* Creates GET and PUT handlers for the hazo_config key-value table.
|
|
5
|
+
* Each handler wraps its body in hazo_core's `withContext` so correlation
|
|
6
|
+
* IDs flow through every downstream call.
|
|
5
7
|
*
|
|
6
8
|
* @example
|
|
7
9
|
* ```typescript
|
|
@@ -17,105 +19,139 @@
|
|
|
17
19
|
*/
|
|
18
20
|
import { NextResponse } from 'next/server';
|
|
19
21
|
import { createCrudService } from 'hazo_connect/server';
|
|
22
|
+
import { HazoError, HazoValidationError, generateRequestId, getCorrelationId, withContext, } from 'hazo_core';
|
|
23
|
+
import { get_logger } from '../utils/logger.js';
|
|
20
24
|
function generateUUID() {
|
|
21
|
-
return
|
|
22
|
-
const r = (Math.random() * 16) | 0;
|
|
23
|
-
const v = c === 'x' ? r : (r & 0x3) | 0x8;
|
|
24
|
-
return v.toString(16);
|
|
25
|
-
});
|
|
25
|
+
return generateRequestId().slice(4);
|
|
26
26
|
}
|
|
27
27
|
function errResponse(error, status) {
|
|
28
28
|
return NextResponse.json({ success: false, error }, { status });
|
|
29
29
|
}
|
|
30
|
+
function handleError(logger, event, error) {
|
|
31
|
+
if (HazoError.is(error)) {
|
|
32
|
+
const status = error.httpStatus ?? 500;
|
|
33
|
+
if (status >= 500) {
|
|
34
|
+
logger.error(event, { code: error.code, message: error.message, context: error.context });
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
logger.warn(event, { code: error.code, message: error.message });
|
|
38
|
+
}
|
|
39
|
+
return errResponse(error.message, status);
|
|
40
|
+
}
|
|
41
|
+
logger.error(event, { error: error instanceof Error ? error.message : String(error) });
|
|
42
|
+
return errResponse(error instanceof Error ? error.message : 'Internal server error', 500);
|
|
43
|
+
}
|
|
30
44
|
export function createConfigHandler(options) {
|
|
31
45
|
const { getHazoConnect } = options;
|
|
46
|
+
const logger = get_logger();
|
|
32
47
|
// GET ?config_key=context_keys&scope_id=...
|
|
33
48
|
async function GET(request) {
|
|
34
|
-
|
|
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;
|
|
49
|
+
return withContext({ correlationId: getCorrelationId() ?? generateRequestId() }, async () => {
|
|
53
50
|
try {
|
|
54
|
-
|
|
51
|
+
const adapter = await getHazoConnect();
|
|
52
|
+
const configService = createCrudService(adapter, 'hazo_config');
|
|
53
|
+
const url = new URL(request.url);
|
|
54
|
+
const config_key = url.searchParams.get('config_key');
|
|
55
|
+
const scope_id = url.searchParams.get('scope_id') || null;
|
|
56
|
+
if (!config_key) {
|
|
57
|
+
throw new HazoValidationError({
|
|
58
|
+
code: 'HAZO_IHELP_VALIDATION_ERROR',
|
|
59
|
+
pkg: 'hazo_ihelp',
|
|
60
|
+
message: 'config_key query parameter is required',
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
logger.debug('config.get.request', { config_key, scope_id });
|
|
64
|
+
// Try scoped first, then fall back to global (scope_id = null)
|
|
65
|
+
let rows = await configService.findBy({ config_key, scope_id });
|
|
66
|
+
if (rows.length === 0 && scope_id) {
|
|
67
|
+
rows = await configService.findBy({ config_key, scope_id: null });
|
|
68
|
+
}
|
|
69
|
+
if (rows.length === 0) {
|
|
70
|
+
return NextResponse.json({ success: true, data: null });
|
|
71
|
+
}
|
|
72
|
+
const row = rows[0];
|
|
73
|
+
let parsed;
|
|
74
|
+
try {
|
|
75
|
+
parsed = JSON.parse(row.config_value);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
parsed = row.config_value;
|
|
79
|
+
}
|
|
80
|
+
return NextResponse.json({
|
|
81
|
+
success: true,
|
|
82
|
+
data: { id: row.id, config_key: row.config_key, value: parsed, scope_id: row.scope_id },
|
|
83
|
+
});
|
|
55
84
|
}
|
|
56
|
-
catch {
|
|
57
|
-
|
|
85
|
+
catch (err) {
|
|
86
|
+
return handleError(logger, 'config.get.failed', err);
|
|
58
87
|
}
|
|
59
|
-
|
|
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
|
-
}
|
|
88
|
+
});
|
|
67
89
|
}
|
|
68
90
|
// PUT — upsert config entry
|
|
69
91
|
async function PUT(request) {
|
|
70
|
-
|
|
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;
|
|
92
|
+
return withContext({ correlationId: getCorrelationId() ?? generateRequestId() }, async () => {
|
|
105
93
|
try {
|
|
106
|
-
|
|
94
|
+
const adapter = await getHazoConnect();
|
|
95
|
+
const configService = createCrudService(adapter, 'hazo_config');
|
|
96
|
+
const body = await request.json();
|
|
97
|
+
const { config_key, value, scope_id = null } = body;
|
|
98
|
+
if (!config_key) {
|
|
99
|
+
throw new HazoValidationError({
|
|
100
|
+
code: 'HAZO_IHELP_VALIDATION_ERROR',
|
|
101
|
+
pkg: 'hazo_ihelp',
|
|
102
|
+
message: 'config_key is required',
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
if (value === undefined) {
|
|
106
|
+
throw new HazoValidationError({
|
|
107
|
+
code: 'HAZO_IHELP_VALIDATION_ERROR',
|
|
108
|
+
pkg: 'hazo_ihelp',
|
|
109
|
+
message: 'value is required',
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
const config_value = typeof value === 'string' ? value : JSON.stringify(value);
|
|
113
|
+
const now = new Date().toISOString();
|
|
114
|
+
// Find existing row for this key+scope
|
|
115
|
+
const existing = await configService.findBy({ config_key, scope_id });
|
|
116
|
+
let row;
|
|
117
|
+
let action;
|
|
118
|
+
if (existing.length > 0) {
|
|
119
|
+
const updated = await configService.updateById(existing[0].id, {
|
|
120
|
+
config_value,
|
|
121
|
+
changed_at: now,
|
|
122
|
+
});
|
|
123
|
+
row = Array.isArray(updated) ? updated[0] : updated;
|
|
124
|
+
action = 'updated';
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
const inserted = await configService.insert({
|
|
128
|
+
id: generateUUID(),
|
|
129
|
+
config_key,
|
|
130
|
+
config_value,
|
|
131
|
+
scope_id,
|
|
132
|
+
created_at: now,
|
|
133
|
+
changed_at: null,
|
|
134
|
+
});
|
|
135
|
+
row = Array.isArray(inserted) ? inserted[0] : inserted;
|
|
136
|
+
action = 'created';
|
|
137
|
+
}
|
|
138
|
+
logger.info(`config.${action}`, { config_key, scope_id, config_id: row.id });
|
|
139
|
+
let parsed;
|
|
140
|
+
try {
|
|
141
|
+
parsed = JSON.parse(row.config_value);
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
parsed = row.config_value;
|
|
145
|
+
}
|
|
146
|
+
return NextResponse.json({
|
|
147
|
+
success: true,
|
|
148
|
+
data: { id: row.id, config_key: row.config_key, value: parsed, scope_id: row.scope_id },
|
|
149
|
+
});
|
|
107
150
|
}
|
|
108
|
-
catch {
|
|
109
|
-
|
|
151
|
+
catch (err) {
|
|
152
|
+
return handleError(logger, 'config.put.failed', err);
|
|
110
153
|
}
|
|
111
|
-
|
|
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
|
-
}
|
|
154
|
+
});
|
|
119
155
|
}
|
|
120
156
|
return { GET, PUT };
|
|
121
157
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create_config_handler.js","sourceRoot":"","sources":["../../src/api/create_config_handler.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"create_config_handler.js","sourceRoot":"","sources":["../../src/api/create_config_handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAe,YAAY,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EACL,SAAS,EACT,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,EAChB,WAAW,GACZ,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,UAAU,EAAe,MAAM,oBAAoB,CAAC;AAG7D,SAAS,YAAY;IACnB,OAAO,iBAAiB,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACtC,CAAC;AAED,SAAS,WAAW,CAAC,KAAa,EAAE,MAAc;IAChD,OAAO,YAAY,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAsB,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;AACtF,CAAC;AAED,SAAS,WAAW,CAAC,MAAc,EAAE,KAAa,EAAE,KAAc;IAChE,IAAI,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,IAAI,GAAG,CAAC;QACvC,IAAI,MAAM,IAAI,GAAG,EAAE,CAAC;YAClB,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAC5F,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACnE,CAAC;QACD,OAAO,WAAW,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC5C,CAAC;IACD,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACvF,OAAO,WAAW,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;AAC5F,CAAC;AAQD,MAAM,UAAU,mBAAmB,CAAC,OAAmC;IACrE,MAAM,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC;IACnC,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAE5B,4CAA4C;IAC5C,KAAK,UAAU,GAAG,CAAC,OAAoB;QACrC,OAAO,WAAW,CAAC,EAAE,aAAa,EAAE,gBAAgB,EAAE,IAAI,iBAAiB,EAAE,EAAE,EAAE,KAAK,IAAI,EAAE;YAC1F,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,cAAc,EAAE,CAAC;gBACvC,MAAM,aAAa,GAAG,iBAAiB,CAAkB,OAAc,EAAE,aAAa,CAAC,CAAC;gBAExF,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;gBACjC,MAAM,UAAU,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;gBACtD,MAAM,QAAQ,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC;gBAE1D,IAAI,CAAC,UAAU,EAAE,CAAC;oBAChB,MAAM,IAAI,mBAAmB,CAAC;wBAC5B,IAAI,EAAE,6BAA6B;wBACnC,GAAG,EAAE,YAAY;wBACjB,OAAO,EAAE,wCAAwC;qBAClD,CAAC,CAAC;gBACL,CAAC;gBAED,MAAM,CAAC,KAAK,CAAC,oBAAoB,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC;gBAE7D,+DAA+D;gBAC/D,IAAI,IAAI,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC;gBAChE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,QAAQ,EAAE,CAAC;oBAClC,IAAI,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;gBACpE,CAAC;gBAED,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACtB,OAAO,YAAY,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAsB,CAAC,CAAC;gBAC9E,CAAC;gBAED,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;gBACpB,IAAI,MAAe,CAAC;gBACpB,IAAI,CAAC;oBACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;gBACxC,CAAC;gBAAC,MAAM,CAAC;oBACP,MAAM,GAAG,GAAG,CAAC,YAAY,CAAC;gBAC5B,CAAC;gBAED,OAAO,YAAY,CAAC,IAAI,CAAC;oBACvB,OAAO,EAAE,IAAI;oBACb,IAAI,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE;iBACpE,CAAC,CAAC;YACzB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,WAAW,CAAC,MAAM,EAAE,mBAAmB,EAAE,GAAG,CAAC,CAAC;YACvD,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,4BAA4B;IAC5B,KAAK,UAAU,GAAG,CAAC,OAAoB;QACrC,OAAO,WAAW,CAAC,EAAE,aAAa,EAAE,gBAAgB,EAAE,IAAI,iBAAiB,EAAE,EAAE,EAAE,KAAK,IAAI,EAAE;YAC1F,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,cAAc,EAAE,CAAC;gBACvC,MAAM,aAAa,GAAG,iBAAiB,CAAkB,OAAc,EAAE,aAAa,CAAC,CAAC;gBAExF,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;gBAClC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC;gBAEpD,IAAI,CAAC,UAAU,EAAE,CAAC;oBAChB,MAAM,IAAI,mBAAmB,CAAC;wBAC5B,IAAI,EAAE,6BAA6B;wBACnC,GAAG,EAAE,YAAY;wBACjB,OAAO,EAAE,wBAAwB;qBAClC,CAAC,CAAC;gBACL,CAAC;gBACD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;oBACxB,MAAM,IAAI,mBAAmB,CAAC;wBAC5B,IAAI,EAAE,6BAA6B;wBACnC,GAAG,EAAE,YAAY;wBACjB,OAAO,EAAE,mBAAmB;qBAC7B,CAAC,CAAC;gBACL,CAAC;gBAED,MAAM,YAAY,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;gBAC/E,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;gBAErC,uCAAuC;gBACvC,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC;gBAEtE,IAAI,GAAoB,CAAC;gBACzB,IAAI,MAA6B,CAAC;gBAClC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACxB,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE;wBAC7D,YAAY;wBACZ,UAAU,EAAE,GAAG;qBACT,CAAC,CAAC;oBACV,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;oBACpD,MAAM,GAAG,SAAS,CAAC;gBACrB,CAAC;qBAAM,CAAC;oBACN,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC;wBAC1C,EAAE,EAAE,YAAY,EAAE;wBAClB,UAAU;wBACV,YAAY;wBACZ,QAAQ;wBACR,UAAU,EAAE,GAAG;wBACf,UAAU,EAAE,IAAI;qBACV,CAAC,CAAC;oBACV,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;oBACvD,MAAM,GAAG,SAAS,CAAC;gBACrB,CAAC;gBAED,MAAM,CAAC,IAAI,CAAC,UAAU,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;gBAE7E,IAAI,MAAe,CAAC;gBACpB,IAAI,CAAC;oBACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;gBACxC,CAAC;gBAAC,MAAM,CAAC;oBACP,MAAM,GAAG,GAAG,CAAC,YAAY,CAAC;gBAC5B,CAAC;gBAED,OAAO,YAAY,CAAC,IAAI,CAAC;oBACvB,OAAO,EAAE,IAAI;oBACb,IAAI,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE;iBACpE,CAAC,CAAC;YACzB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,WAAW,CAAC,MAAM,EAAE,mBAAmB,EAAE,GAAG,CAAC,CAAC;YACvD,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AACtB,CAAC"}
|
|
@@ -5,6 +5,10 @@
|
|
|
5
5
|
* Tags and context mappings are stored as JSON columns directly on the
|
|
6
6
|
* topics table — no separate join tables required.
|
|
7
7
|
*
|
|
8
|
+
* Every handler wraps its body with hazo_core's `withContext` so the
|
|
9
|
+
* correlation ID flows through every nested log call and downstream
|
|
10
|
+
* `fetchWithRequestId` outbound request.
|
|
11
|
+
*
|
|
8
12
|
* @example
|
|
9
13
|
* ```typescript
|
|
10
14
|
* // app/api/ihelp/topics/route.ts
|
|
@@ -18,18 +22,6 @@
|
|
|
18
22
|
* });
|
|
19
23
|
*
|
|
20
24
|
* export { GET, POST };
|
|
21
|
-
*
|
|
22
|
-
* // app/api/ihelp/topics/[id]/route.ts
|
|
23
|
-
* import { createIhelpHandler } from 'hazo_ihelp/api';
|
|
24
|
-
* import { getHazoConnectSingleton } from 'hazo_connect/nextjs/setup';
|
|
25
|
-
*
|
|
26
|
-
* export const dynamic = 'force-dynamic';
|
|
27
|
-
*
|
|
28
|
-
* const { PATCH, DELETE } = createIhelpHandler({
|
|
29
|
-
* getHazoConnect: () => getHazoConnectSingleton(),
|
|
30
|
-
* });
|
|
31
|
-
*
|
|
32
|
-
* export { PATCH, DELETE };
|
|
33
25
|
* ```
|
|
34
26
|
*/
|
|
35
27
|
import { NextRequest, NextResponse } from 'next/server';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create_ihelp_handler.d.ts","sourceRoot":"","sources":["../../src/api/create_ihelp_handler.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"create_ihelp_handler.d.ts","sourceRoot":"","sources":["../../src/api/create_ihelp_handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAWxD,OAAO,KAAK,EACV,yBAAyB,EACzB,gBAAgB,EAChB,UAAU,EAIX,MAAM,mBAAmB,CAAC;AA+D3B;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,yBAAyB;mBAuCxD,WAAW,KACnB,OAAO,CAAC,YAAY,CAAC,gBAAgB,CAAC,UAAU,GAAG,UAAU,EAAE,CAAC,CAAC,CAAC;oBAoG1D,WAAW,KACnB,OAAO,CAAC,YAAY,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAAC;qBAuF3C,WAAW,WACX;QAAE,MAAM,EAAE,OAAO,CAAC;YAAE,EAAE,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,KAC5C,OAAO,CAAC,YAAY,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAAC;sBA2F3C,WAAW,WACX;QAAE,MAAM,EAAE,OAAO,CAAC;YAAE,EAAE,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,KAC5C,OAAO,CAAC,YAAY,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC;EAkCjD"}
|