hazo_connect 2.2.0 → 2.3.2

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 (46) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +563 -0
  3. package/dist/adapters/sqlite-adapter.d.ts.map +1 -1
  4. package/dist/adapters/sqlite-adapter.js +37 -2
  5. package/dist/adapters/sqlite-adapter.js.map +1 -1
  6. package/dist/factory.d.ts +1 -0
  7. package/dist/factory.d.ts.map +1 -1
  8. package/dist/factory.js +51 -9
  9. package/dist/factory.js.map +1 -1
  10. package/dist/nextjs/index.d.ts +2 -0
  11. package/dist/nextjs/index.d.ts.map +1 -1
  12. package/dist/nextjs/index.js +10 -1
  13. package/dist/nextjs/index.js.map +1 -1
  14. package/dist/nextjs/route-setup.d.ts +46 -0
  15. package/dist/nextjs/route-setup.d.ts.map +1 -0
  16. package/dist/nextjs/route-setup.js +141 -0
  17. package/dist/nextjs/route-setup.js.map +1 -0
  18. package/dist/nextjs/setup-helpers.d.ts +86 -0
  19. package/dist/nextjs/setup-helpers.d.ts.map +1 -0
  20. package/dist/nextjs/setup-helpers.js +174 -0
  21. package/dist/nextjs/setup-helpers.js.map +1 -0
  22. package/dist/server/index.d.ts +2 -1
  23. package/dist/server/index.d.ts.map +1 -1
  24. package/dist/server/index.js +7 -1
  25. package/dist/server/index.js.map +1 -1
  26. package/dist/sqlite/admin-service.d.ts +8 -0
  27. package/dist/sqlite/admin-service.d.ts.map +1 -1
  28. package/dist/sqlite/admin-service.js +39 -1
  29. package/dist/sqlite/admin-service.js.map +1 -1
  30. package/dist/utils/config-validator.d.ts +39 -0
  31. package/dist/utils/config-validator.d.ts.map +1 -0
  32. package/dist/utils/config-validator.js +78 -0
  33. package/dist/utils/config-validator.js.map +1 -0
  34. package/docs/examples/nextjs-admin-ui-setup.ts +199 -0
  35. package/docs/examples/nextjs-api-route.ts +205 -0
  36. package/docs/examples/nextjs-crud-service.ts +257 -0
  37. package/docs/examples/nextjs-server-component.tsx +123 -0
  38. package/docs/examples/nextjs-singleton-pattern.ts +166 -0
  39. package/docs/migration-guide.md +272 -0
  40. package/docs/nextjs-setup.md +471 -0
  41. package/docs/techdoc.md +824 -0
  42. package/docs/troubleshooting.md +442 -0
  43. package/docs/types.md +490 -0
  44. package/package.json +16 -4
  45. package/scripts/postinstall-setup.js +72 -0
  46. package/scripts/setup-routes.js +123 -0
@@ -0,0 +1,166 @@
1
+ /**
2
+ * Example: Singleton Pattern for hazo_connect in Next.js
3
+ *
4
+ * This example shows how to use a singleton pattern to share
5
+ * a single hazo_connect instance across multiple API routes.
6
+ */
7
+
8
+ // ============================================================================
9
+ // Step 1: Create singleton instance
10
+ // ============================================================================
11
+
12
+ // lib/hazo_connect.ts
13
+ import { getHazoConnectSingleton } from 'hazo_connect/nextjs/setup'
14
+ import type { HazoConnectAdapter } from 'hazo_connect/server'
15
+
16
+ /**
17
+ * Get the singleton hazo_connect adapter instance
18
+ *
19
+ * This instance is created on first call and reused for all subsequent calls.
20
+ * Thread-safe for Next.js serverless environment.
21
+ */
22
+ export const hazo: HazoConnectAdapter = getHazoConnectSingleton()
23
+
24
+ // ============================================================================
25
+ // Step 2: Use singleton in API routes
26
+ // ============================================================================
27
+
28
+ // app/api/users/route.ts
29
+ import { NextResponse } from 'next/server'
30
+ import { hazo } from '@/lib/hazo_connect'
31
+ import { QueryBuilder } from 'hazo_connect/server'
32
+
33
+ export async function GET() {
34
+ try {
35
+ // Use the shared singleton instance
36
+ const users = await hazo.query(
37
+ new QueryBuilder()
38
+ .from('users')
39
+ .select('*')
40
+ .order('name', 'asc')
41
+ )
42
+
43
+ return NextResponse.json({ data: users })
44
+ } catch (error) {
45
+ return NextResponse.json(
46
+ { error: error instanceof Error ? error.message : 'Unknown error' },
47
+ { status: 500 }
48
+ )
49
+ }
50
+ }
51
+
52
+ // app/api/posts/route.ts
53
+ import { NextResponse } from 'next/server'
54
+ import { hazo } from '@/lib/hazo_connect'
55
+ import { QueryBuilder } from 'hazo_connect/server'
56
+
57
+ export async function GET() {
58
+ try {
59
+ // Same singleton instance, different query
60
+ const posts = await hazo.query(
61
+ new QueryBuilder()
62
+ .from('posts')
63
+ .select('*')
64
+ .order('created_at', 'desc')
65
+ .limit(10)
66
+ )
67
+
68
+ return NextResponse.json({ data: posts })
69
+ } catch (error) {
70
+ return NextResponse.json(
71
+ { error: error instanceof Error ? error.message : 'Unknown error' },
72
+ { status: 500 }
73
+ )
74
+ }
75
+ }
76
+
77
+ // app/api/comments/route.ts
78
+ import { NextRequest, NextResponse } from 'next/server'
79
+ import { hazo } from '@/lib/hazo_connect'
80
+ import { QueryBuilder } from 'hazo_connect/server'
81
+
82
+ export async function GET(request: NextRequest) {
83
+ try {
84
+ const { searchParams } = new URL(request.url)
85
+ const postId = searchParams.get('post_id')
86
+
87
+ let builder = new QueryBuilder()
88
+ .from('comments')
89
+ .select('*')
90
+
91
+ if (postId) {
92
+ builder = builder.where('post_id', 'eq', postId)
93
+ }
94
+
95
+ // Same singleton instance, filtered query
96
+ const comments = await hazo.query(builder)
97
+
98
+ return NextResponse.json({ data: comments })
99
+ } catch (error) {
100
+ return NextResponse.json(
101
+ { error: error instanceof Error ? error.message : 'Unknown error' },
102
+ { status: 500 }
103
+ )
104
+ }
105
+ }
106
+
107
+ // ============================================================================
108
+ // Alternative: Manual Singleton Pattern
109
+ // ============================================================================
110
+
111
+ // lib/hazo_connect-manual.ts
112
+ import { createHazoConnect } from 'hazo_connect/server'
113
+ import type { HazoConnectAdapter } from 'hazo_connect/server'
114
+ import path from 'path'
115
+
116
+ let hazoInstance: HazoConnectAdapter | null = null
117
+
118
+ /**
119
+ * Get or create the singleton hazo_connect adapter instance
120
+ */
121
+ export function getHazoConnect(): HazoConnectAdapter {
122
+ if (!hazoInstance) {
123
+ hazoInstance = createHazoConnect({
124
+ type: 'sqlite',
125
+ sqlite: {
126
+ database_path: process.env.HAZO_CONNECT_SQLITE_PATH
127
+ ? path.resolve(process.env.HAZO_CONNECT_SQLITE_PATH)
128
+ : path.resolve(process.cwd(), 'database.sqlite'),
129
+ read_only: process.env.HAZO_CONNECT_SQLITE_READONLY === 'true'
130
+ },
131
+ enable_admin_ui: process.env.HAZO_CONNECT_ENABLE_ADMIN_UI === 'true'
132
+ })
133
+ }
134
+
135
+ return hazoInstance
136
+ }
137
+
138
+ /**
139
+ * Reset the singleton (useful for testing)
140
+ */
141
+ export function resetHazoConnect(): void {
142
+ hazoInstance = null
143
+ }
144
+
145
+ // Usage:
146
+ // import { getHazoConnect } from '@/lib/hazo_connect-manual'
147
+ // const hazo = getHazoConnect()
148
+
149
+ // ============================================================================
150
+ // Benefits of Singleton Pattern
151
+ // ============================================================================
152
+
153
+ /**
154
+ * Benefits:
155
+ *
156
+ * 1. Single database connection shared across all API routes
157
+ * 2. Reduced memory usage (one instance instead of many)
158
+ * 3. Faster response times (no connection overhead per request)
159
+ * 4. Thread-safe in Next.js serverless environment
160
+ * 5. Configuration is centralized in one place
161
+ *
162
+ * Note: The singleton is automatically created on first use and
163
+ * reused for all subsequent calls. If configuration changes,
164
+ * a new instance will be created automatically.
165
+ */
166
+
@@ -0,0 +1,272 @@
1
+ # Migration Guide for hazo_connect
2
+
3
+ This guide helps you migrate existing code to use the new server-side entry points and patterns.
4
+
5
+ ## Table of Contents
6
+
7
+ - [From Old Import Paths](#from-old-import-paths)
8
+ - [From Client-Side to Server-Side](#from-client-side-to-server-side)
9
+ - [From Direct Calls to API Routes](#from-direct-calls-to-api-routes)
10
+ - [Testing Considerations](#testing-considerations)
11
+
12
+ ## From Old Import Paths
13
+
14
+ ### Before (Old Import)
15
+
16
+ ```typescript
17
+ import { createHazoConnect, QueryBuilder } from 'hazo_connect'
18
+ ```
19
+
20
+ ### After (New Import)
21
+
22
+ ```typescript
23
+ // For server-side code (API routes, Server Components, Server Actions)
24
+ import { createHazoConnect, QueryBuilder } from 'hazo_connect/server'
25
+
26
+ // For types in client components
27
+ import type { HazoConnectConfig, HazoConnectAdapter } from 'hazo_connect'
28
+ import type { TableSummary } from 'hazo_connect/ui'
29
+ ```
30
+
31
+ ### Migration Steps
32
+
33
+ 1. **Find all imports** of `hazo_connect` in your codebase
34
+ 2. **Replace server-side imports** with `hazo_connect/server`
35
+ 3. **Replace type imports** in client components with `hazo_connect` or `hazo_connect/ui`
36
+ 4. **Update test files** to use `hazo_connect/server`
37
+
38
+ ## From Client-Side to Server-Side
39
+
40
+ ### Before (Client Component - Won't Work)
41
+
42
+ ```typescript
43
+ 'use client'
44
+
45
+ import { createHazoConnect } from 'hazo_connect' // ❌ Old import
46
+
47
+ export function MyComponent() {
48
+ const [data, setData] = useState([])
49
+
50
+ useEffect(() => {
51
+ const hazo = createHazoConnect({ ... })
52
+ hazo.query(...).then(setData)
53
+ }, [])
54
+
55
+ return <div>{/* render data */}</div>
56
+ }
57
+ ```
58
+
59
+ ### After (Client Component - Correct Pattern)
60
+
61
+ ```typescript
62
+ 'use client'
63
+
64
+ export function MyComponent() {
65
+ const [data, setData] = useState([])
66
+
67
+ useEffect(() => {
68
+ // Fetch from API route instead
69
+ fetch('/api/data')
70
+ .then(res => res.json())
71
+ .then(json => setData(json.data))
72
+ }, [])
73
+
74
+ return <div>{/* render data */}</div>
75
+ }
76
+ ```
77
+
78
+ ```typescript
79
+ // app/api/data/route.ts
80
+ import { createHazoConnect } from 'hazo_connect/server'
81
+ import { QueryBuilder } from 'hazo_connect/server'
82
+
83
+ export async function GET() {
84
+ const hazo = createHazoConnect({ ... })
85
+ const data = await hazo.query(new QueryBuilder().from('table'))
86
+ return NextResponse.json({ data })
87
+ }
88
+ ```
89
+
90
+ ## From Direct Calls to API Routes
91
+
92
+ ### Before (Direct Call in Server Component)
93
+
94
+ ```typescript
95
+ // app/users/page.tsx
96
+ import { createHazoConnect } from 'hazo_connect' // ❌ Old import
97
+
98
+ export default async function UsersPage() {
99
+ const hazo = createHazoConnect({ ... })
100
+ const users = await hazo.query(...)
101
+
102
+ return <div>{/* render users */}</div>
103
+ }
104
+ ```
105
+
106
+ ### After (Fetch from API Route)
107
+
108
+ ```typescript
109
+ // app/users/page.tsx
110
+ import { headers } from 'next/headers'
111
+
112
+ export default async function UsersPage() {
113
+ const headersList = await headers()
114
+ const host = headersList.get('host') || 'localhost:3000'
115
+
116
+ const response = await fetch(`http://${host}/api/users`, {
117
+ cache: 'no-store'
118
+ })
119
+ const { data: users } = await response.json()
120
+
121
+ return <div>{/* render users */}</div>
122
+ }
123
+ ```
124
+
125
+ ```typescript
126
+ // app/api/users/route.ts
127
+ import { createHazoConnect } from 'hazo_connect/server'
128
+ import { QueryBuilder } from 'hazo_connect/server'
129
+
130
+ export async function GET() {
131
+ const hazo = createHazoConnect({ ... })
132
+ const users = await hazo.query(new QueryBuilder().from('users'))
133
+ return NextResponse.json({ data: users })
134
+ }
135
+ ```
136
+
137
+ ## Testing Considerations
138
+
139
+ ### Unit Tests
140
+
141
+ Update test imports:
142
+
143
+ ```typescript
144
+ // Before
145
+ import { createHazoConnect } from 'hazo_connect'
146
+
147
+ // After
148
+ import { createHazoConnect } from 'hazo_connect/server'
149
+ ```
150
+
151
+ ### Integration Tests
152
+
153
+ No changes needed - integration tests already use relative imports:
154
+
155
+ ```typescript
156
+ // tests/integration/test.ts
157
+ import { createHazoConnect } from '../../src/lib/factory' // ✅ Still works
158
+ ```
159
+
160
+ ### Mocking in Tests
161
+
162
+ ```typescript
163
+ // tests/setup.ts
164
+ import { resetHazoConnectSingleton } from 'hazo_connect/nextjs/setup'
165
+
166
+ beforeEach(() => {
167
+ resetHazoConnectSingleton() // Reset singleton between tests
168
+ })
169
+ ```
170
+
171
+ ## Common Migration Patterns
172
+
173
+ ### Pattern 1: API Route Migration
174
+
175
+ **Before:**
176
+ ```typescript
177
+ // pages/api/users.ts (Pages Router)
178
+ import { createHazoConnect } from 'hazo_connect'
179
+
180
+ export default async function handler(req, res) {
181
+ const hazo = createHazoConnect({ ... })
182
+ const users = await hazo.query(...)
183
+ res.json({ data: users })
184
+ }
185
+ ```
186
+
187
+ **After:**
188
+ ```typescript
189
+ // app/api/users/route.ts (App Router)
190
+ import { createHazoConnect } from 'hazo_connect/server'
191
+ import { QueryBuilder } from 'hazo_connect/server'
192
+ import { NextResponse } from 'next/server'
193
+
194
+ export async function GET() {
195
+ const hazo = createHazoConnect({ ... })
196
+ const users = await hazo.query(new QueryBuilder().from('users'))
197
+ return NextResponse.json({ data: users })
198
+ }
199
+ ```
200
+
201
+ ### Pattern 2: Server Component Migration
202
+
203
+ **Before:**
204
+ ```typescript
205
+ // components/UsersList.tsx
206
+ import { createHazoConnect } from 'hazo_connect'
207
+
208
+ export async function UsersList() {
209
+ const hazo = createHazoConnect({ ... })
210
+ const users = await hazo.query(...)
211
+ return <ul>{/* render */}</ul>
212
+ }
213
+ ```
214
+
215
+ **After:**
216
+ ```typescript
217
+ // app/users/page.tsx
218
+ import { headers } from 'next/headers'
219
+
220
+ export default async function UsersPage() {
221
+ const headersList = await headers()
222
+ const host = headersList.get('host') || 'localhost:3000'
223
+ const response = await fetch(`http://${host}/api/users`, { cache: 'no-store' })
224
+ const { data: users } = await response.json()
225
+ return <ul>{/* render */}</ul>
226
+ }
227
+ ```
228
+
229
+ ### Pattern 3: Singleton Pattern Migration
230
+
231
+ **Before:**
232
+ ```typescript
233
+ // Multiple API routes each creating their own instance
234
+ // app/api/users/route.ts
235
+ const hazo = createHazoConnect({ ... })
236
+
237
+ // app/api/posts/route.ts
238
+ const hazo = createHazoConnect({ ... }) // New instance each time
239
+ ```
240
+
241
+ **After:**
242
+ ```typescript
243
+ // lib/hazo_connect.ts
244
+ import { getHazoConnectSingleton } from 'hazo_connect/nextjs/setup'
245
+ export const hazo = getHazoConnectSingleton()
246
+
247
+ // app/api/users/route.ts
248
+ import { hazo } from '@/lib/hazo_connect' // Shared instance
249
+
250
+ // app/api/posts/route.ts
251
+ import { hazo } from '@/lib/hazo_connect' // Same shared instance
252
+ ```
253
+
254
+ ## Checklist
255
+
256
+ When migrating:
257
+
258
+ - [ ] Update all imports from `hazo_connect` to `hazo_connect/server` for runtime code
259
+ - [ ] Update type imports in client components to `hazo_connect` or `hazo_connect/ui`
260
+ - [ ] Move direct `hazo_connect` calls from Server Components to API routes
261
+ - [ ] Update client components to fetch from API routes instead of calling `hazo_connect`
262
+ - [ ] Update test files to use `hazo_connect/server`
263
+ - [ ] Consider using singleton pattern for multiple API routes
264
+ - [ ] Update Next.js configuration (see [Next.js Setup Guide](./nextjs-setup.md))
265
+ - [ ] Test in development and production environments
266
+
267
+ ## Need Help?
268
+
269
+ - See [Troubleshooting Guide](./troubleshooting.md) for common issues
270
+ - See [Next.js Setup Guide](./nextjs-setup.md) for configuration
271
+ - See [Code Examples](./examples/) for working patterns
272
+