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,824 @@
1
+ # Hazo Connect - Technical Documentation
2
+
3
+ This document provides technical details about the internal architecture, file structure, services, key assumptions, and dependencies of the `hazo_connect` package. It is intended for developers maintaining or extending the codebase.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Overview](#overview)
8
+ - [Architecture](#architecture)
9
+ - [File Structure](#file-structure)
10
+ - [Entry Points](#entry-points)
11
+ - [Core Components](#core-components)
12
+ - [Factory](#factory)
13
+ - [Query Builder](#query-builder)
14
+ - [Adapters](#adapters)
15
+ - [Helpers](#helpers)
16
+ - [SQLite Subsystem](#sqlite-subsystem)
17
+ - [SQLite Adapter](#sqlite-adapter)
18
+ - [Query Translator](#query-translator)
19
+ - [Admin Service](#admin-service)
20
+ - [Next.js Integration](#nextjs-integration)
21
+ - [Utility Modules](#utility-modules)
22
+ - [Key Assumptions](#key-assumptions)
23
+ - [Dependencies](#dependencies)
24
+ - [Build Process](#build-process)
25
+ - [Testing Strategy](#testing-strategy)
26
+ - [Extension Points](#extension-points)
27
+
28
+ ---
29
+
30
+ ## Overview
31
+
32
+ `hazo_connect` is a database abstraction layer that provides a unified interface for interacting with different database backends. It follows the adapter pattern, where each database type (PostgREST, SQLite, Supabase, File) has its own adapter implementation that conforms to the `HazoConnectAdapter` interface.
33
+
34
+ ### Design Principles
35
+
36
+ 1. **Zero Dependencies in Core**: The core types and query builder have no external dependencies
37
+ 2. **Dependency Injection**: Logger and configuration are injected, not imported
38
+ 3. **Server-Side Only**: Runtime guards prevent client-side usage
39
+ 4. **Type Safety**: Full TypeScript support with strict typing
40
+ 5. **Adapter Pattern**: Each database type implements a common interface
41
+
42
+ ---
43
+
44
+ ## Architecture
45
+
46
+ ```
47
+ ┌─────────────────────────────────────────────────────────────────────────┐
48
+ │ Application Layer │
49
+ │ (Next.js API Routes, Server Components, Server Actions) │
50
+ └─────────────────────────────────────────────────────────────────────────┘
51
+
52
+
53
+ ┌─────────────────────────────────────────────────────────────────────────┐
54
+ │ Entry Points │
55
+ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
56
+ │ │ /server │ │ /nextjs │ │ /nextjs/ │ │ /ui │ │
57
+ │ │ (runtime) │ │ (helpers) │ │ setup │ │ (types) │ │
58
+ │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
59
+ └─────────────────────────────────────────────────────────────────────────┘
60
+
61
+
62
+ ┌─────────────────────────────────────────────────────────────────────────┐
63
+ │ Core Layer │
64
+ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
65
+ │ │ Factory │ │ Query Builder │ │ Helpers │ │
66
+ │ │ createHazoConnect│ │ QueryBuilder │ │ createCrudService│ │
67
+ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
68
+ └─────────────────────────────────────────────────────────────────────────┘
69
+
70
+
71
+ ┌─────────────────────────────────────────────────────────────────────────┐
72
+ │ Adapter Layer │
73
+ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
74
+ │ │ PostgrestAd │ │ SqliteAdapt │ │ SupabaseAd │ │ FileAdapt │ │
75
+ │ │ apter │ │ er │ │ apter │ │ er │ │
76
+ │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
77
+ │ │ │ │ │ │
78
+ │ └────────────────┴────────────────┴────────────────┘ │
79
+ │ extends BaseAdapter │
80
+ └─────────────────────────────────────────────────────────────────────────┘
81
+
82
+
83
+ ┌─────────────────────────────────────────────────────────────────────────┐
84
+ │ Database Layer │
85
+ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
86
+ │ │ PostgREST │ │ sql.js │ │ Supabase │ │ File System │ │
87
+ │ │ API │ │ (WASM) │ │ API │ │ │ │
88
+ │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
89
+ └─────────────────────────────────────────────────────────────────────────┘
90
+ ```
91
+
92
+ ---
93
+
94
+ ## File Structure
95
+
96
+ ```
97
+ src/lib/
98
+ ├── index.ts # Main entry point (types only)
99
+ ├── types.ts # Core TypeScript interfaces and types
100
+ ├── factory.ts # Factory function to create adapters
101
+ ├── query-builder.ts # Query builder with fluent API
102
+ ├── helpers.ts # CRUD service and query helpers
103
+ ├── README.md # Library documentation
104
+
105
+ ├── adapters/ # Database adapter implementations
106
+ │ ├── base-adapter.ts # Abstract base class for adapters
107
+ │ ├── postgrest-adapter.ts # PostgREST API adapter
108
+ │ ├── sqlite-adapter.ts # SQLite adapter (sql.js)
109
+ │ ├── supabase-adapter.ts # Supabase adapter (stub)
110
+ │ └── file-adapter.ts # File system adapter (stub)
111
+
112
+ ├── server/ # Server-only entry point
113
+ │ └── index.ts # Exports with 'use server' directive
114
+
115
+ ├── nextjs/ # Next.js-specific helpers
116
+ │ ├── index.ts # Main Next.js exports
117
+ │ ├── api-route-helpers.ts # API route handler utilities
118
+ │ ├── setup-helpers.ts # Environment-based setup, singleton
119
+ │ └── server-only.ts # Server-only guard utilities
120
+
121
+ ├── sqlite/ # SQLite-specific modules
122
+ │ ├── admin-service.ts # Admin UI service functions
123
+ │ └── query-translator.ts # QueryBuilder to SQL translator
124
+
125
+ ├── ui/ # UI-safe entry point
126
+ │ └── index.ts # Type-only exports for client components
127
+
128
+ ├── utils/ # Utility modules
129
+ │ ├── config-validator.ts # Configuration validation
130
+ │ ├── sqlite-utils.ts # SQLite helper functions
131
+ │ ├── wasm-resolver.ts # WASM file resolution
132
+ │ └── where-builder.ts # WHERE clause builder
133
+
134
+ └── __tests__/ # Unit tests
135
+ ├── factory.test.ts
136
+ ├── postgrest_adapter.test.ts
137
+ ├── query_builder.test.ts
138
+ └── sqlite_adapter.test.ts
139
+
140
+ app/ # Next.js app directory (Admin UI)
141
+ └── hazo_connect/
142
+ ├── api/sqlite/ # Admin API routes
143
+ │ ├── data/route.ts # CRUD operations
144
+ │ ├── schema/route.ts # Schema retrieval
145
+ │ └── tables/route.ts # Table listing
146
+ └── sqlite_admin/ # Admin UI pages
147
+ ├── page.tsx # Server component
148
+ └── sqlite-admin-client.tsx # Client component
149
+
150
+ docs/ # Documentation
151
+ ├── examples/ # Code examples
152
+ ├── migration-guide.md
153
+ ├── nextjs-setup.md
154
+ ├── troubleshooting.md
155
+ └── types.md
156
+
157
+ tests/ # Integration tests
158
+ └── integration/
159
+ ├── postgrest.integration.test.ts
160
+ ├── sqlite.integration.test.ts
161
+ └── sqlite-singleton.test.ts
162
+ ```
163
+
164
+ ---
165
+
166
+ ## Entry Points
167
+
168
+ ### `hazo_connect` (Main)
169
+
170
+ **File:** `src/lib/index.ts`
171
+
172
+ Exports types only. Safe for client-side imports.
173
+
174
+ ```typescript
175
+ export type { HazoConnectConfig, HazoConnectAdapter, Logger, ... }
176
+ ```
177
+
178
+ ### `hazo_connect/server`
179
+
180
+ **File:** `src/lib/server/index.ts`
181
+
182
+ Server-side runtime exports with `'use server'` directive.
183
+
184
+ ```typescript
185
+ export { createHazoConnect, QueryBuilder, createCrudService, ... }
186
+ export type { HazoConnectConfig, CrudService, ... }
187
+ ```
188
+
189
+ **Runtime Guard:** Throws error if imported in browser environment.
190
+
191
+ ### `hazo_connect/nextjs`
192
+
193
+ **File:** `src/lib/nextjs/index.ts`
194
+
195
+ Next.js-specific helpers for API routes.
196
+
197
+ ```typescript
198
+ export { createApiRouteHandler, getServerHazoConnect }
199
+ ```
200
+
201
+ ### `hazo_connect/nextjs/setup`
202
+
203
+ **File:** `src/lib/nextjs/setup-helpers.ts`
204
+
205
+ Environment-based configuration and singleton pattern.
206
+
207
+ ```typescript
208
+ export { createHazoConnectFromEnv, getHazoConnectSingleton }
209
+ ```
210
+
211
+ ### `hazo_connect/ui`
212
+
213
+ **File:** `src/lib/ui/index.ts`
214
+
215
+ UI-safe types for client components.
216
+
217
+ ```typescript
218
+ export type { TableSummary, TableSchema, SqliteFilterOperator, ... }
219
+ ```
220
+
221
+ ---
222
+
223
+ ## Core Components
224
+
225
+ ### Factory
226
+
227
+ **File:** `src/lib/factory.ts`
228
+
229
+ The `createHazoConnect` function is the main entry point for creating adapter instances.
230
+
231
+ **Responsibilities:**
232
+ - Parse and validate configuration
233
+ - Extract configuration from ConfigProvider if provided
234
+ - Resolve environment variables for paths and credentials
235
+ - Instantiate the appropriate adapter based on `type`
236
+ - Register SQLite adapters with admin service when `enable_admin_ui` is true
237
+
238
+ **Flow:**
239
+ ```
240
+ createHazoConnect(config)
241
+
242
+ ├─── Validate type
243
+
244
+ ├─── Extract config from ConfigProvider or direct config
245
+
246
+ ├─── Resolve environment variables (paths, API keys)
247
+
248
+ ├─── Switch on type:
249
+ │ ├─── 'postgrest' → new PostgrestAdapter(...)
250
+ │ ├─── 'sqlite' → new SqliteAdapter(...)
251
+ │ ├─── 'supabase' → new SupabaseAdapter(...)
252
+ │ └─── 'file' → new FileAdapter(...)
253
+
254
+ └─── If SQLite + enable_admin_ui → registerSqliteAdapter(adapter)
255
+ ```
256
+
257
+ ### Query Builder
258
+
259
+ **File:** `src/lib/query-builder.ts`
260
+
261
+ Fluent API for building database queries.
262
+
263
+ **State:**
264
+ - `_table`: Target table name
265
+ - `_selectFields`: Fields to select
266
+ - `_whereConditions`: WHERE conditions (AND)
267
+ - `_whereOrConditions`: OR condition groups
268
+ - `_orderBy`: ORDER BY clauses
269
+ - `_limitValue`: LIMIT value
270
+ - `_offsetValue`: OFFSET value
271
+ - `_joins`: JOIN clauses
272
+ - `_nestedSelects`: Nested select for PostgREST
273
+
274
+ **Methods:**
275
+ ```typescript
276
+ from(table: string): this
277
+ select(fields: string | string[]): this
278
+ where(field: string, operator: QueryOperator, value: any): this
279
+ whereIn(field: string, values: any[]): this
280
+ whereOr(conditions: Array<{...}>): this
281
+ order(field: string, direction: OrderDirection): this
282
+ limit(count: number): this
283
+ offset(count: number): this
284
+ join(table: string, on: string, type: JoinType): this
285
+ nestedSelect(table: string, fields: string[]): this
286
+ clone(): QueryBuilder
287
+ ```
288
+
289
+ ### Adapters
290
+
291
+ **Base Class:** `src/lib/adapters/base-adapter.ts`
292
+
293
+ Abstract base class providing common functionality:
294
+ - Configuration storage
295
+ - Logger integration
296
+ - Error handling utilities
297
+ - Query logging
298
+
299
+ **Interface:** `HazoConnectAdapter`
300
+ ```typescript
301
+ interface HazoConnectAdapter {
302
+ query(builder: QueryBuilder, method?: string, body?: any): Promise<any>
303
+ rawQuery(endpoint: string, options?: RequestInit): Promise<any>
304
+ getConfig(): Promise<any>
305
+ }
306
+ ```
307
+
308
+ #### PostgrestAdapter
309
+
310
+ **File:** `src/lib/adapters/postgrest-adapter.ts`
311
+
312
+ Translates QueryBuilder to PostgREST URL syntax and makes HTTP requests.
313
+
314
+ **URL Building:**
315
+ - `from('users')` → `/users`
316
+ - `where('id', 'eq', '123')` → `?id=eq.123`
317
+ - `select(['id', 'name'])` → `?select=id,name`
318
+ - `nestedSelect('posts', ['title'])` → `?select=*,posts(title)`
319
+
320
+ #### SqliteAdapter
321
+
322
+ **File:** `src/lib/adapters/sqlite-adapter.ts`
323
+
324
+ Uses sql.js (WebAssembly SQLite) for local database operations.
325
+
326
+ **Key Features:**
327
+ - In-memory and file-backed databases
328
+ - Read-only mode support
329
+ - Initial SQL execution for schema setup
330
+ - Automatic persistence after writes
331
+ - WASM file resolution
332
+
333
+ **Initialization Flow:**
334
+ ```
335
+ constructor()
336
+
337
+ ├─── normalizeConfig()
338
+
339
+ ├─── resolveWasmDirectory()
340
+
341
+ ├─── loadSqlJs() → Promise<SqlJsStatic>
342
+
343
+ └─── initializeDatabase() → Promise<SqlJsDatabase>
344
+
345
+ ├─── If file exists → Load from file
346
+
347
+ ├─── Else → Create new database
348
+ │ │
349
+ │ └─── Execute initial_sql if provided
350
+
351
+ └─── If database_path → Persist to file
352
+ ```
353
+
354
+ ### Helpers
355
+
356
+ **File:** `src/lib/helpers.ts`
357
+
358
+ #### createCrudService
359
+
360
+ Creates a CRUD service wrapper for a table:
361
+
362
+ ```typescript
363
+ function createCrudService<T>(
364
+ adapter: HazoConnectAdapter,
365
+ table: string,
366
+ options?: { primaryKeys?: string[]; logger?: Logger }
367
+ ): CrudService<T>
368
+ ```
369
+
370
+ **Methods:**
371
+ - `list()`: Get all records
372
+ - `findBy(criteria)`: Find by criteria
373
+ - `findOneBy(criteria)`: Find single record
374
+ - `findById(id)`: Find by primary key
375
+ - `insert(data)`: Insert record(s)
376
+ - `updateById(id, patch)`: Update by primary key
377
+ - `deleteById(id)`: Delete by primary key
378
+ - `query()`: Get executable query builder
379
+
380
+ #### attachExecute
381
+
382
+ Attaches `execute()` method to a QueryBuilder:
383
+
384
+ ```typescript
385
+ function attachExecute(
386
+ builder: QueryBuilder,
387
+ adapter: HazoConnectAdapter,
388
+ logger?: Logger
389
+ ): ExecutableQueryBuilder
390
+ ```
391
+
392
+ ---
393
+
394
+ ## SQLite Subsystem
395
+
396
+ ### SQLite Adapter
397
+
398
+ **File:** `src/lib/adapters/sqlite-adapter.ts`
399
+
400
+ **Query Execution Flow:**
401
+ ```
402
+ query(builder, method, body)
403
+
404
+ ├─── GET → executeSelect(builder)
405
+ │ │
406
+ │ └─── translateSelect(builder) → SQL + params
407
+ │ │
408
+ │ └─── executeStatements(database, [translation])
409
+
410
+ ├─── POST → executeInsert(builder, body)
411
+ │ │
412
+ │ └─── translateInsert(builder, payload) → SQL statements
413
+ │ │
414
+ │ └─── executeStatements() → persistDatabase()
415
+
416
+ ├─── PATCH/PUT → executeUpdate(builder, body)
417
+ │ │
418
+ │ └─── translateUpdate(builder, updates) → SQL
419
+ │ │
420
+ │ └─── executeStatements() → persistDatabase()
421
+
422
+ └─── DELETE → executeDelete(builder)
423
+
424
+ └─── translateDelete(builder) → SQL
425
+
426
+ └─── executeStatements() → persistDatabase()
427
+ ```
428
+
429
+ ### Query Translator
430
+
431
+ **File:** `src/lib/sqlite/query-translator.ts`
432
+
433
+ Translates QueryBuilder state to parameterized SQL statements.
434
+
435
+ **Functions:**
436
+ - `translateSelect(builder)`: SELECT query
437
+ - `translateInsert(builder, payload)`: INSERT statement(s)
438
+ - `translateUpdate(builder, updates)`: UPDATE statement
439
+ - `translateDelete(builder)`: DELETE statement
440
+
441
+ **SQL Generation:**
442
+ ```typescript
443
+ // QueryBuilder state
444
+ builder.from('users').where('status', 'eq', 'active').limit(10)
445
+
446
+ // Translated SQL
447
+ {
448
+ sql: 'SELECT * FROM "users" WHERE "status" = ? LIMIT 10',
449
+ params: ['active']
450
+ }
451
+ ```
452
+
453
+ ### Admin Service
454
+
455
+ **File:** `src/lib/sqlite/admin-service.ts`
456
+
457
+ Provides admin functionality for the SQLite Admin UI.
458
+
459
+ **Singleton Pattern:**
460
+ - `registeredAdapter`: Adapter registered by factory/singleton
461
+ - `cachedAdapter`: Fallback adapter from environment variables
462
+ - `adminUiEnabled`: Flag to enable/disable admin UI
463
+
464
+ **Functions:**
465
+ ```typescript
466
+ getSqliteAdminService(): SqliteAdminService
467
+ initializeAdminService(config): void
468
+ registerSqliteAdapter(adapter): void
469
+ clearRegisteredAdapter(): void // For testing
470
+ ```
471
+
472
+ **Service Methods:**
473
+ - `listTables()`: List all tables and views
474
+ - `getTableSchema(table)`: Get column and FK definitions
475
+ - `getTableData(table, options)`: Paginated data retrieval
476
+ - `insertRow(table, data)`: Insert single row
477
+ - `updateRows(table, criteria, data)`: Update matching rows
478
+ - `deleteRows(table, criteria)`: Delete matching rows
479
+
480
+ ---
481
+
482
+ ## Next.js Integration
483
+
484
+ ### Setup Helpers
485
+
486
+ **File:** `src/lib/nextjs/setup-helpers.ts`
487
+
488
+ #### createHazoConnectFromEnv
489
+
490
+ Creates adapter from environment variables:
491
+
492
+ ```typescript
493
+ function createHazoConnectFromEnv(options?: {
494
+ type?: 'sqlite' | 'postgrest' | 'supabase' | 'file'
495
+ sqlitePath?: string
496
+ readOnly?: boolean
497
+ enableAdminUi?: boolean
498
+ logger?: Logger
499
+ }): HazoConnectAdapter
500
+ ```
501
+
502
+ **Environment Variable Resolution:**
503
+ 1. Check option overrides
504
+ 2. Fall back to `HAZO_CONNECT_*` variables
505
+ 3. Fall back to legacy variable names
506
+ 4. Apply defaults
507
+
508
+ #### getHazoConnectSingleton
509
+
510
+ Creates/returns singleton adapter instance:
511
+
512
+ ```typescript
513
+ function getHazoConnectSingleton(options?: CreateHazoConnectFromEnvOptions): HazoConnectAdapter
514
+ ```
515
+
516
+ **Singleton Behavior:**
517
+ - Creates adapter on first call
518
+ - Returns cached instance on subsequent calls
519
+ - Recreates if configuration signature changes
520
+ - Registers SQLite adapter with admin service
521
+
522
+ ### API Route Helpers
523
+
524
+ **File:** `src/lib/nextjs/api-route-helpers.ts`
525
+
526
+ #### createApiRouteHandler
527
+
528
+ Wraps handler with automatic adapter initialization:
529
+
530
+ ```typescript
531
+ function createApiRouteHandler(
532
+ handler: (hazo: HazoConnectAdapter, request: NextRequest) => Promise<Response>,
533
+ options?: {
534
+ config?: ApiRouteHazoConfig
535
+ getConfig?: (request: NextRequest) => ApiRouteHazoConfig
536
+ logger?: Logger
537
+ }
538
+ ): (request: NextRequest) => Promise<Response>
539
+ ```
540
+
541
+ #### getServerHazoConnect
542
+
543
+ Creates adapter for manual use in API routes:
544
+
545
+ ```typescript
546
+ function getServerHazoConnect(config: ApiRouteHazoConfig, logger?: Logger): HazoConnectAdapter
547
+ ```
548
+
549
+ ---
550
+
551
+ ## Utility Modules
552
+
553
+ ### Config Validator
554
+
555
+ **File:** `src/lib/utils/config-validator.ts`
556
+
557
+ Validates Next.js configuration for SQLite compatibility.
558
+
559
+ ```typescript
560
+ function validateNextJsConfig(): ValidationResult
561
+ function getConfigurationTips(): string[]
562
+ ```
563
+
564
+ ### SQLite Utils
565
+
566
+ **File:** `src/lib/utils/sqlite-utils.ts`
567
+
568
+ Helper functions for SQLite operations:
569
+
570
+ ```typescript
571
+ function quoteIdentifier(name: string): string
572
+ function normalizeValue(value: unknown): unknown
573
+ function sanitizeTableName(table: string): string
574
+ function isPlainObject(value: unknown): boolean
575
+ ```
576
+
577
+ ### WASM Resolver
578
+
579
+ **File:** `src/lib/utils/wasm-resolver.ts`
580
+
581
+ Resolves sql-wasm.wasm file location:
582
+
583
+ ```typescript
584
+ function resolveWasmDirectory(config: SqliteAdapterOptions): string
585
+ function createSqlJsConfig(wasmDirectory: string): SqlJsConfig
586
+ ```
587
+
588
+ **Resolution Order:**
589
+ 1. Explicit `wasm_directory` in config
590
+ 2. `HAZO_CONNECT_SQLITE_WASM_DIR` environment variable
591
+ 3. Auto-detect from node_modules
592
+
593
+ ### Where Builder
594
+
595
+ **File:** `src/lib/utils/where-builder.ts`
596
+
597
+ Builds WHERE clauses from filter specifications:
598
+
599
+ ```typescript
600
+ function buildWhereClause(filters: SqliteWhereFilter[]): { clause: string; params: unknown[] }
601
+ function buildFiltersFromCriteria(criteria: Record<string, unknown>): SqliteWhereFilter[]
602
+ ```
603
+
604
+ ---
605
+
606
+ ## Key Assumptions
607
+
608
+ ### Database Assumptions
609
+
610
+ 1. **SQLite**: Uses sql.js (WebAssembly), not native SQLite bindings
611
+ 2. **PostgREST**: Assumes standard PostgREST API format
612
+ 3. **Primary Keys**: Defaults to `id` column if not specified
613
+ 4. **Table Names**: Must be valid SQL identifiers
614
+
615
+ ### Environment Assumptions
616
+
617
+ 1. **Server-Side Only**: All runtime code assumes Node.js environment
618
+ 2. **Next.js 14+**: Next.js helpers assume App Router
619
+ 3. **File System Access**: SQLite file persistence requires write access
620
+ 4. **WASM Support**: sql.js requires WebAssembly support
621
+
622
+ ### Configuration Assumptions
623
+
624
+ 1. **Environment Variables**: Loaded via dotenv from `.env.local`
625
+ 2. **Path Resolution**: Relative paths resolved from `process.cwd()`
626
+ 3. **Admin UI Disabled**: By default for security
627
+
628
+ ---
629
+
630
+ ## Dependencies
631
+
632
+ ### Production Dependencies
633
+
634
+ | Package | Version | Purpose |
635
+ |---------|---------|---------|
636
+ | `dotenv` | ^16.4.5 | Environment variable loading |
637
+ | `hazo_config` | ^1.3.0 | Configuration provider interface |
638
+ | `sql.js` | ^1.13.0 | WebAssembly SQLite implementation |
639
+
640
+ ### Peer Dependencies (Optional)
641
+
642
+ | Package | Version | Purpose |
643
+ |---------|---------|---------|
644
+ | `next` | >=14.0.0 | Next.js framework (Admin UI) |
645
+ | `react` | >=18.0.0 | React library (Admin UI) |
646
+ | `react-dom` | >=18.0.0 | React DOM (Admin UI) |
647
+ | `lucide-react` | ^0.553.0 | Icons (Admin UI) |
648
+ | `sonner` | ^2.0.7 | Toast notifications (Admin UI) |
649
+
650
+ ### Development Dependencies
651
+
652
+ - TypeScript 5.5+
653
+ - Jest 30+ for testing
654
+ - Next.js 14+ for development server
655
+ - Storybook for component development
656
+
657
+ ---
658
+
659
+ ## Build Process
660
+
661
+ ### Library Build
662
+
663
+ ```bash
664
+ npm run build:lib
665
+ ```
666
+
667
+ Uses `tsconfig.lib.json`:
668
+ - Compiles `src/lib/**/*.ts` to `dist/`
669
+ - Generates `.d.ts` type declarations
670
+ - Excludes tests and app directory
671
+
672
+ ### Next.js Build
673
+
674
+ ```bash
675
+ npm run build
676
+ ```
677
+
678
+ Builds the Next.js application including Admin UI.
679
+
680
+ ### Package Exports
681
+
682
+ Defined in `package.json`:
683
+
684
+ ```json
685
+ {
686
+ "exports": {
687
+ ".": { "types": "./dist/index.d.ts", "default": "./dist/index.js" },
688
+ "./server": { "types": "./dist/server/index.d.ts", "default": "./dist/server/index.js" },
689
+ "./nextjs": { "types": "./dist/nextjs/index.d.ts", "default": "./dist/nextjs/index.js" },
690
+ "./nextjs/setup": { "types": "./dist/nextjs/setup-helpers.d.ts", "default": "./dist/nextjs/setup-helpers.js" },
691
+ "./ui": { "types": "./dist/ui/index.d.ts", "default": "./dist/ui/index.js" }
692
+ }
693
+ }
694
+ ```
695
+
696
+ ---
697
+
698
+ ## Testing Strategy
699
+
700
+ ### Unit Tests
701
+
702
+ **Location:** `src/lib/__tests__/`
703
+
704
+ - `factory.test.ts`: Factory function tests
705
+ - `query_builder.test.ts`: QueryBuilder API tests
706
+ - `postgrest_adapter.test.ts`: PostgREST adapter tests
707
+ - `sqlite_adapter.test.ts`: SQLite adapter tests
708
+
709
+ ### Integration Tests
710
+
711
+ **Location:** `tests/integration/`
712
+
713
+ - `sqlite.integration.test.ts`: SQLite CRUD operations
714
+ - `sqlite-singleton.test.ts`: Singleton pattern and admin service
715
+ - `postgrest.integration.test.ts`: PostgREST API integration
716
+
717
+ ### Running Tests
718
+
719
+ ```bash
720
+ # All tests
721
+ npm test
722
+
723
+ # Watch mode
724
+ npm run test:watch
725
+
726
+ # Coverage
727
+ npm run test:coverage
728
+
729
+ # Integration only
730
+ npm run test:integration:sqlite
731
+ ```
732
+
733
+ ---
734
+
735
+ ## Extension Points
736
+
737
+ ### Adding a New Adapter
738
+
739
+ 1. Create adapter class extending `BaseAdapter`:
740
+
741
+ ```typescript
742
+ // src/lib/adapters/new-adapter.ts
743
+ export class NewAdapter extends BaseAdapter implements HazoConnectAdapter {
744
+ async query(builder: QueryBuilder, method?: string, body?: any): Promise<any> {
745
+ // Implementation
746
+ }
747
+
748
+ async rawQuery(endpoint: string, options?: RequestInit): Promise<any> {
749
+ // Implementation
750
+ }
751
+
752
+ async getConfig(): Promise<any> {
753
+ return { ...this.config }
754
+ }
755
+ }
756
+ ```
757
+
758
+ 2. Add to factory:
759
+
760
+ ```typescript
761
+ // src/lib/factory.ts
762
+ case 'new':
763
+ adapter = new NewAdapter(providerConfig, logger)
764
+ break
765
+ ```
766
+
767
+ 3. Update types:
768
+
769
+ ```typescript
770
+ // src/lib/types.ts
771
+ export type ConnectionType = 'postgrest' | 'supabase' | 'sqlite' | 'file' | 'new'
772
+ ```
773
+
774
+ 4. Export from server entry point:
775
+
776
+ ```typescript
777
+ // src/lib/server/index.ts
778
+ export { NewAdapter } from '../adapters/new-adapter'
779
+ ```
780
+
781
+ ### Adding New Query Operators
782
+
783
+ 1. Update types:
784
+
785
+ ```typescript
786
+ // src/lib/types.ts
787
+ export type QueryOperator = 'eq' | 'neq' | ... | 'new_operator'
788
+ ```
789
+
790
+ 2. Update query translator (for SQLite):
791
+
792
+ ```typescript
793
+ // src/lib/sqlite/query-translator.ts
794
+ function translateOperator(operator: QueryOperator, value: unknown): string {
795
+ switch (operator) {
796
+ case 'new_operator':
797
+ return 'NEW_SQL_SYNTAX ?'
798
+ // ...
799
+ }
800
+ }
801
+ ```
802
+
803
+ 3. Update PostgREST adapter (for PostgREST):
804
+
805
+ ```typescript
806
+ // src/lib/adapters/postgrest-adapter.ts
807
+ // Add operator to URL building logic
808
+ ```
809
+
810
+ ---
811
+
812
+ ## Version History
813
+
814
+ See [CHANGELOG.md](../CHANGELOG.md) for version history.
815
+
816
+ ---
817
+
818
+ ## Contributing
819
+
820
+ 1. Follow existing code style and conventions
821
+ 2. Add tests for new functionality
822
+ 3. Update documentation for API changes
823
+ 4. Run `npm run build:lib` and `npm test` before submitting
824
+