@edium/halifax 2.1.0 → 2.2.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/CHANGELOG.md +64 -1
- package/README.md +73 -17
- package/README_AUTH.md +38 -0
- package/README_AUTOCRUD.md +5 -5
- package/README_CLASSES.md +322 -0
- package/README_HOOKS.md +275 -0
- package/README_INTERFACES.md +601 -0
- package/README_OPENAPI.md +471 -0
- package/README_REPO_ADAPTERS.md +77 -0
- package/README_TYPES.md +114 -0
- package/dist/adapters/orm/drizzle/DrizzleAdapter.d.ts +128 -0
- package/dist/adapters/orm/drizzle/DrizzleAdapter.js +255 -0
- package/dist/adapters/orm/drizzle/astToDrizzle.d.ts +21 -0
- package/dist/adapters/orm/drizzle/astToDrizzle.js +121 -0
- package/dist/adapters/orm/drizzle/index.d.ts +4 -0
- package/dist/adapters/orm/drizzle/index.js +2 -0
- package/dist/adapters/orm/prisma/PrismaAdapter.d.ts +1 -1
- package/dist/adapters/orm/prisma/PrismaAdapter.js +24 -1
- package/dist/adapters/orm/prisma/astToPrisma.d.ts +1 -2
- package/dist/adapters/orm/prisma/astToPrisma.js +1 -3
- package/dist/adapters/orm/prisma/helpers.js +1 -1
- package/dist/adapters/orm/prisma/types.d.ts +11 -11
- package/dist/auth/AuthStrategy.d.ts +6 -189
- package/dist/auth/AuthStrategy.js +4 -220
- package/dist/auth/strategies/AllowAllAuthStrategy.d.ts +6 -0
- package/dist/auth/strategies/AllowAllAuthStrategy.js +6 -0
- package/dist/auth/strategies/ApiKeyAuthStrategy.d.ts +25 -0
- package/dist/auth/strategies/ApiKeyAuthStrategy.js +39 -0
- package/dist/auth/strategies/JwtClaimsAuthStrategy.d.ts +32 -0
- package/dist/auth/strategies/JwtClaimsAuthStrategy.js +52 -0
- package/dist/auth/strategies/PassportStrategies.d.ts +94 -0
- package/dist/auth/strategies/PassportStrategies.js +142 -0
- package/dist/auth/strategies/types.d.ts +70 -0
- package/dist/core/crudRouter.d.ts +11 -18
- package/dist/core/crudRouter.js +95 -390
- package/dist/core/fields.d.ts +8 -0
- package/dist/core/fields.js +14 -0
- package/dist/core/handlerUtils.d.ts +70 -0
- package/dist/core/handlerUtils.js +193 -0
- package/dist/core/handlers/create.d.ts +3 -0
- package/dist/core/handlers/create.js +26 -0
- package/dist/core/handlers/deleteMany.d.ts +3 -0
- package/dist/core/handlers/deleteMany.js +24 -0
- package/dist/core/handlers/deleteOne.d.ts +3 -0
- package/dist/core/handlers/deleteOne.js +19 -0
- package/dist/core/handlers/query.d.ts +3 -0
- package/dist/core/handlers/query.js +23 -0
- package/dist/core/handlers/readMany.d.ts +3 -0
- package/dist/core/handlers/readMany.js +18 -0
- package/dist/core/handlers/readOne.d.ts +3 -0
- package/dist/core/handlers/readOne.js +23 -0
- package/dist/core/handlers/updateMany.d.ts +3 -0
- package/dist/core/handlers/updateMany.js +34 -0
- package/dist/core/handlers/updateOne.d.ts +3 -0
- package/dist/core/handlers/updateOne.js +20 -0
- package/dist/core/handlers/upsertOne.d.ts +3 -0
- package/dist/core/handlers/upsertOne.js +20 -0
- package/dist/core/hooks.d.ts +217 -0
- package/dist/core/queryString.js +1 -1
- package/dist/core/types.d.ts +38 -29
- package/dist/core/validation.d.ts +1 -2
- package/dist/core/validation.js +1 -3
- package/dist/index.d.ts +3 -6
- package/dist/index.js +3 -6
- package/dist/openapi/generateDocsHtml.d.ts +1 -0
- package/dist/openapi/generateDocsHtml.js +47 -0
- package/dist/openapi/index.d.ts +3 -0
- package/dist/openapi/index.js +2 -0
- package/dist/openapi/specGenerator.d.ts +149 -0
- package/dist/openapi/specGenerator.js +770 -0
- package/package.json +38 -22
- package/dist/enums/SqlComparison.d.ts +0 -28
- package/dist/enums/SqlComparison.js +0 -29
- package/dist/enums/SqlOperator.d.ts +0 -5
- package/dist/enums/SqlOperator.js +0 -6
- package/dist/enums/SqlOrder.d.ts +0 -5
- package/dist/enums/SqlOrder.js +0 -6
- package/dist/interfaces/IQueryFilter.d.ts +0 -17
- package/dist/interfaces/IQueryOptions.d.ts +0 -20
- package/dist/interfaces/ISort.d.ts +0 -8
- package/dist/interfaces/ISort.js +0 -1
- /package/dist/{interfaces/IQueryFilter.js → auth/strategies/types.js} +0 -0
- /package/dist/{interfaces/IQueryOptions.js → core/hooks.js} +0 -0
|
@@ -0,0 +1,601 @@
|
|
|
1
|
+
# Interfaces — `@edium/halifax`
|
|
2
|
+
|
|
3
|
+
All publicly exported TypeScript interfaces, grouped by concern. Type aliases are in [README_TYPES.md](./README_TYPES.md); classes are in [README_CLASSES.md](./README_CLASSES.md).
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Resource definition
|
|
8
|
+
|
|
9
|
+
### `ResourceDefinition<TRecord, TCreate, TUpdate>`
|
|
10
|
+
|
|
11
|
+
Import: `@edium/halifax`
|
|
12
|
+
|
|
13
|
+
Full definition of a Halifax resource. Pass an array of these to `createExpressCrudRouter` / `registerCrudApi`.
|
|
14
|
+
|
|
15
|
+
| Property | Type | Required | Description |
|
|
16
|
+
| --------------------- | --------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
17
|
+
| `routePrefix` | `string` | yes | URL path segment (e.g. `'users'`, `'blog-posts'`). Defines the resource's public routes. |
|
|
18
|
+
| `repository` | `Repository<TRecord, TCreate, TUpdate>` | yes | The data adapter that handles reads and writes. |
|
|
19
|
+
| `name` | `string` | no | Human-readable name used in error messages. Defaults to title-cased `routePrefix` (`'blog-posts'` → `'Blog Posts'`). |
|
|
20
|
+
| `fields` | `FieldDefinition[]` | no\* | Field schema — controls filtering, sorting, selection, and write access. Optional when the repository exposes its own schema (Prisma/Drizzle); required otherwise. Merged by name over the repository's base schema when both are present. |
|
|
21
|
+
| `relations` | `RelationDefinition[]` | no | Relations exposed via `?include=`. Merged over the repository's relation schema by name. |
|
|
22
|
+
| `tenant` | `TenantResourceConfig \| false` | no | Tenant isolation for this resource. `false` explicitly opts out of an otherwise tenant-scoped API. |
|
|
23
|
+
| `permissions` | `CrudPermissions` | no | Per-action enables/disables. Merged over `defaultCrudPermissions` — list only the actions to disable. |
|
|
24
|
+
| `requiredPermissions` | `Partial<Record<CrudAction, string[]>>` | no | Permission strings per action checked by the auth strategy. |
|
|
25
|
+
| `defaultLimit` | `number` | no | Default page size when caller omits `?limit=`. Defaults to `DEFAULT_PAGE_LIMIT` (5000). `0` disables the default bound. |
|
|
26
|
+
| `maxLimit` | `number` | no | Hard cap on page size. Defaults to `MAX_PAGE_LIMIT` (5000). `0` removes the cap. |
|
|
27
|
+
| `maxFilterDepth` | `number` | no | Maximum nesting depth for `where` clause children. Defaults to 3. |
|
|
28
|
+
| `cache` | `ResourceCacheConfig \| false` | no | Per-resource cache TTL. `false` disables caching even when an API-wide default is set. |
|
|
29
|
+
| `envelope` | `string \| null` | no | Wraps every success response body under this key (e.g. `'data'`). Overrides the API-wide `envelope` option. |
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
### `FieldDefinition`
|
|
34
|
+
|
|
35
|
+
Import: `@edium/halifax`
|
|
36
|
+
|
|
37
|
+
Describes a single column exposed through the Halifax API. All flags default to `true` (permissive); set one to `false` to restrict. The primary key is automatically non-writable.
|
|
38
|
+
|
|
39
|
+
| Property | Type | Description |
|
|
40
|
+
| ------------ | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
41
|
+
| `name` | `string` | Column / property name. |
|
|
42
|
+
| `filterable` | `boolean` | When `false`, cannot be used in `?field=` query-string filters. |
|
|
43
|
+
| `sortable` | `boolean` | When `false`, cannot be used in `?order=` sort expressions. |
|
|
44
|
+
| `selectable` | `boolean` | When `false`, excluded from `?fields=` projections. |
|
|
45
|
+
| `writable` | `boolean` | When `false`, stripped from POST/PATCH/PUT bodies. Primary key defaults to `false`. |
|
|
46
|
+
| `type` | `FieldType` | OpenAPI scalar type. Auto-populated by Prisma/Drizzle adapters; set manually for custom repos. |
|
|
47
|
+
| `format` | `string` | OpenAPI format modifier (e.g. `'date-time'`, `'int64'`, `'binary'`). |
|
|
48
|
+
| `readRoles` | `string[]` | Roles or permissions required to read this field. Callers without a match have the field stripped from responses. Matched against `AuthContext.roles` and `AuthContext.permissions`. |
|
|
49
|
+
| `writeRoles` | `string[]` | Roles or permissions required to write this field. Callers without a match have the field silently dropped from write bodies. |
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
### `RelationDefinition`
|
|
54
|
+
|
|
55
|
+
Import: `@edium/halifax`
|
|
56
|
+
|
|
57
|
+
Declares a relation that callers may eager-load via `?include=`.
|
|
58
|
+
|
|
59
|
+
| Property | Type | Description |
|
|
60
|
+
| ------------ | --------- | ------------------------------------------------------------------------------------ |
|
|
61
|
+
| `name` | `string` | Relation name as defined on the Prisma/ORM model. |
|
|
62
|
+
| `includable` | `boolean` | When `false`, this relation cannot be requested via `?include=`. Defaults to `true`. |
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
### `CrudPermissions`
|
|
67
|
+
|
|
68
|
+
Import: `@edium/halifax`
|
|
69
|
+
|
|
70
|
+
Per-action toggles controlling which CRUD endpoints are registered for a resource. All actions default to `true`. List only the actions to disable.
|
|
71
|
+
|
|
72
|
+
| Property | Default | Route affected |
|
|
73
|
+
| ------------------------------- | ------- | ----------------------- |
|
|
74
|
+
| `allowCreate` | `true` | `POST /:resource` |
|
|
75
|
+
| `allowReadOne` | `true` | `GET /:resource/:id` |
|
|
76
|
+
| `allowReadMany` | `true` | `GET /:resource` |
|
|
77
|
+
| `allowReadManyWithQueryBuilder` | `true` | `POST /:resource/query` |
|
|
78
|
+
| `allowUpdateOne` | `true` | `PATCH /:resource/:id` |
|
|
79
|
+
| `allowUpdateMany` | `true` | `PATCH /:resource` |
|
|
80
|
+
| `allowUpsertOne` | `true` | `PUT /:resource/:id` |
|
|
81
|
+
| `allowDeleteOne` | `true` | `DELETE /:resource/:id` |
|
|
82
|
+
| `allowDeleteMany` | `true` | `DELETE /:resource` |
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
### `ResourceCacheConfig`
|
|
87
|
+
|
|
88
|
+
Import: `@edium/halifax`
|
|
89
|
+
|
|
90
|
+
Per-resource read-through cache configuration. Set on `ResourceDefinition.cache`.
|
|
91
|
+
|
|
92
|
+
| Property | Type | Description |
|
|
93
|
+
| ------------ | -------- | --------------------------------------------------------------------------------------- |
|
|
94
|
+
| `ttlSeconds` | `number` | Cache TTL in seconds. `0` means never expire (cache forever until a write invalidates). |
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
### `TenantResourceConfig`
|
|
99
|
+
|
|
100
|
+
Import: `@edium/halifax`
|
|
101
|
+
|
|
102
|
+
Declares that a resource is tenant-scoped. Set on `ResourceDefinition.tenant`.
|
|
103
|
+
|
|
104
|
+
| Property | Type | Description |
|
|
105
|
+
| -------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
106
|
+
| `field` | `string` | Column / property that stores the tenant key (e.g. `'companyId'`). Every read and write is confined to rows whose value on this field matches the caller's resolved tenant id. |
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## API options
|
|
111
|
+
|
|
112
|
+
### `CrudApiOptions`
|
|
113
|
+
|
|
114
|
+
Import: `@edium/halifax`
|
|
115
|
+
|
|
116
|
+
Options for `registerCrudApi` and all `create*CrudRouter` / `create*CrudPlugin` functions.
|
|
117
|
+
|
|
118
|
+
| Property | Type | Description |
|
|
119
|
+
| ------------------ | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
120
|
+
| `authStrategy` | `AuthStrategy` | Auth strategy for all routes. Defaults to `AllowAllAuthStrategy`. |
|
|
121
|
+
| `tenant` | `TenantOptions` | Multi-tenant isolation config. When omitted, no tenant scoping is applied. |
|
|
122
|
+
| `queryBuilderPath` | `string` | Path segment for the query-builder POST route (default: `'query'`). Must match `HalifaxClientOptions.queryBuilderPath` in `@edium/halifax-client`. |
|
|
123
|
+
| `envelope` | `string \| null` | Wraps every success response body under this key API-wide. Per-resource `ResourceDefinition.envelope` takes precedence. |
|
|
124
|
+
| `openapi` | `OpenApiOptions` | Enable OpenAPI 3.1 spec generation and Swagger UI. Omit to disable entirely. |
|
|
125
|
+
| `cache.store` | `CacheStore` | Backing cache store shared by all resources. Defaults to `InMemoryCacheStore`. |
|
|
126
|
+
| `cache.ttlSeconds` | `number` | Default TTL applied to resources with no per-resource cache config. `0` = never expire. |
|
|
127
|
+
| `cache.bustHeader` | `string` | Request header that force-refreshes the cache. Defaults to `'Cache-Control'` (busts on `no-cache`/`no-store`). |
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
### `OpenApiOptions`
|
|
132
|
+
|
|
133
|
+
Import: `@edium/halifax`
|
|
134
|
+
|
|
135
|
+
Configuration for OpenAPI 3.1 spec generation. Set on `CrudApiOptions.openapi`.
|
|
136
|
+
|
|
137
|
+
| Property | Type | Default | Description |
|
|
138
|
+
| ---------------- | ---------------------------------------------- | ------------------ | ------------------------------------------------------------------------------------------ |
|
|
139
|
+
| `enabled` | `boolean` | `true` | Set `false` to disable entirely — no routes registered, no spec generated. |
|
|
140
|
+
| `title` | `string` | `'Halifax API'` | API title shown in Swagger UI. |
|
|
141
|
+
| `version` | `string` | `'1.0.0'` | API version string. |
|
|
142
|
+
| `description` | `string` | — | Markdown description shown at the top of the docs. |
|
|
143
|
+
| `servers` | `Array<{ url: string; description?: string }>` | — | Server URLs listed in the spec. |
|
|
144
|
+
| `envelope` | `string \| null` | — | Mirrors `CrudApiOptions.envelope` for the spec — auto-propagated; only override if needed. |
|
|
145
|
+
| `specPath` | `string` | `'/openapi.json'` | Path for the raw spec, relative to the router mount point. |
|
|
146
|
+
| `docsPath` | `string` | `'/docs'` | Path for the Swagger UI page, relative to the router mount point. |
|
|
147
|
+
| `securityScheme` | `SecurityScheme` | Auto from strategy | Overrides the security scheme reported by the `authStrategy`. |
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Auth
|
|
152
|
+
|
|
153
|
+
### `AuthStrategy`
|
|
154
|
+
|
|
155
|
+
Import: `@edium/halifax`
|
|
156
|
+
|
|
157
|
+
Contract for pluggable authentication and authorization strategies. Implement this to create a custom strategy.
|
|
158
|
+
|
|
159
|
+
| Member | Signature | Required | Description |
|
|
160
|
+
| --------------- | ----------------------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
161
|
+
| `authenticate` | `(req: HttpRequest) => AuthContext \| Promise<AuthContext>` | yes | Authenticate the request. Throw `AuthenticationError` (→ 401) or `AuthorizationError` (→ 403) on failure. |
|
|
162
|
+
| `authorize` | `(params: AuthorizeParams) => boolean \| Promise<boolean>` | no | Gate each action against the auth context. When absent, Halifax checks `requiredPermissions` against `auth.roles`/`auth.permissions` directly. |
|
|
163
|
+
| `openApiScheme` | `() => SecurityScheme \| undefined` | no | Return the security scheme to document in the OpenAPI spec (wires up the Swagger UI "Authorize" button). |
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
### `AuthContext`
|
|
168
|
+
|
|
169
|
+
Import: `@edium/halifax`
|
|
170
|
+
|
|
171
|
+
Resolved user identity returned by `AuthStrategy.authenticate`.
|
|
172
|
+
|
|
173
|
+
| Property | Type | Description |
|
|
174
|
+
| ----------------- | ------------------------- | ----------------------------------------------------------------------------------------------------- |
|
|
175
|
+
| `isAuthenticated` | `boolean` | Always `true` for a successfully authenticated context. |
|
|
176
|
+
| `userId` | `string` | Unique identifier for the authenticated user. |
|
|
177
|
+
| `roles` | `string[]` | Role strings granted to the user. Checked against `requiredPermissions` and `readRoles`/`writeRoles`. |
|
|
178
|
+
| `permissions` | `string[]` | Explicit permission strings. Checked alongside `roles`. |
|
|
179
|
+
| `claims` | `Record<string, unknown>` | Raw claims from the token or session payload. |
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
### `AuthorizeParams`
|
|
184
|
+
|
|
185
|
+
Import: `@edium/halifax`
|
|
186
|
+
|
|
187
|
+
Passed to `AuthStrategy.authorize` on every request.
|
|
188
|
+
|
|
189
|
+
| Property | Type | Description |
|
|
190
|
+
| --------------------- | -------------------- | ------------------------------------------------------ |
|
|
191
|
+
| `auth` | `AuthContext` | The resolved authentication context. |
|
|
192
|
+
| `action` | `CrudAction` | The CRUD action being performed. |
|
|
193
|
+
| `resource` | `ResourceDefinition` | The resource being accessed. |
|
|
194
|
+
| `requiredPermissions` | `string[]` | Permissions required for this action on this resource. |
|
|
195
|
+
| `req` | `HttpRequest` | The incoming HTTP request. |
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
### `PassportJwtStrategyOptions`
|
|
200
|
+
|
|
201
|
+
Import: `@edium/halifax`
|
|
202
|
+
|
|
203
|
+
Options for `PassportJwtStrategy`.
|
|
204
|
+
|
|
205
|
+
| Property | Type | Default | Description |
|
|
206
|
+
| ---------- | -------------------------------- | -------------- | ------------------------------------------------------------------------------------------------------------- |
|
|
207
|
+
| `passport` | `PassportLike` | required | A Passport instance with a JWT strategy registered. |
|
|
208
|
+
| `strategy` | `string` | `'jwt'` | Name of the Passport strategy to invoke. |
|
|
209
|
+
| `mapUser` | `(user: unknown) => AuthContext` | Default mapper | Maps the raw Passport user payload to an `AuthContext`. Default reads `sub`/`id`, `roles`, and `permissions`. |
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
### `PassportLike`
|
|
214
|
+
|
|
215
|
+
Import: `@edium/halifax`
|
|
216
|
+
|
|
217
|
+
Minimal structural type for a Passport.js instance. Avoids a hard dependency on `passport`.
|
|
218
|
+
|
|
219
|
+
| Method | Signature | Description |
|
|
220
|
+
| -------------- | --------------------------------------------- | ------------------------------------------------- |
|
|
221
|
+
| `authenticate` | `(strategy, options, callback) => middleware` | Authenticates a request using the named strategy. |
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## Multi-tenancy
|
|
226
|
+
|
|
227
|
+
### `TenantOptions`
|
|
228
|
+
|
|
229
|
+
Import: `@edium/halifax`
|
|
230
|
+
|
|
231
|
+
Configures multi-tenant isolation API-wide. Set on `CrudApiOptions.tenant`.
|
|
232
|
+
|
|
233
|
+
| Property | Type | Default | Description |
|
|
234
|
+
| ----------- | ------------------------------------------------------------ | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
235
|
+
| `resolveId` | `(ctx: TenantResolveContext) => unknown \| Promise<unknown>` | required | Resolves the tenant key from the auth context and request. Must come from the token/session — never from client input. Return `null`/`undefined` when none applies. |
|
|
236
|
+
| `field` | `string` | `'tenantId'` | Default column name for auto-detection: resources with a field of this name are automatically scoped on it. |
|
|
237
|
+
| `strict` | `boolean` | `true` | When `true`, a tenant-scoped resource whose `resolveId` returns no value rejects with 403 rather than serving unscoped. |
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
### `TenantResolveContext`
|
|
242
|
+
|
|
243
|
+
Import: `@edium/halifax`
|
|
244
|
+
|
|
245
|
+
Passed to `TenantOptions.resolveId` on every request.
|
|
246
|
+
|
|
247
|
+
| Property | Type | Description |
|
|
248
|
+
| ---------- | -------------------- | ------------------------------------ |
|
|
249
|
+
| `auth` | `AuthContext` | The resolved authentication context. |
|
|
250
|
+
| `req` | `HttpRequest` | The incoming HTTP request. |
|
|
251
|
+
| `resource` | `ResourceDefinition` | The resource being accessed. |
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
### `TenantScope`
|
|
256
|
+
|
|
257
|
+
Import: `@edium/halifax`
|
|
258
|
+
|
|
259
|
+
A resolved tenant constraint for a single request. Produced by the router and passed to `Repository.withScope`.
|
|
260
|
+
|
|
261
|
+
| Property | Type | Description |
|
|
262
|
+
| -------- | --------- | ------------------------------------------------------- |
|
|
263
|
+
| `field` | `string` | Column that stores the tenant key (e.g. `'companyId'`). |
|
|
264
|
+
| `value` | `unknown` | The tenant key value the caller is bound to. |
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
## HTTP
|
|
269
|
+
|
|
270
|
+
### `HttpServer`
|
|
271
|
+
|
|
272
|
+
Import: `@edium/halifax`
|
|
273
|
+
|
|
274
|
+
Contract an HTTP server adapter must implement for Halifax to register routes. Implement this to add a new HTTP framework.
|
|
275
|
+
|
|
276
|
+
| Method | Signature | Description |
|
|
277
|
+
| --------------- | ----------------------------------------------------------------------- | ------------------------- |
|
|
278
|
+
| `registerRoute` | `(method: HttpMethod, path: string, handler: HttpRouteHandler) => void` | Register a route handler. |
|
|
279
|
+
| `start` | `(port: number, host?: string) => Promise<void> \| void` | Start listening. |
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
### `HttpRequest<TRaw>`
|
|
284
|
+
|
|
285
|
+
Import: `@edium/halifax`
|
|
286
|
+
|
|
287
|
+
Framework-agnostic representation of an incoming HTTP request, passed to all handlers and auth strategies.
|
|
288
|
+
|
|
289
|
+
| Property | Type | Description |
|
|
290
|
+
| --------- | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
|
|
291
|
+
| `method` | `string` | HTTP method (`'GET'`, `'POST'`, etc.). |
|
|
292
|
+
| `params` | `Record<string, string>` | Route parameters (e.g. `{ id: '42' }`). |
|
|
293
|
+
| `query` | `Record<string, unknown>` | Parsed query-string parameters. |
|
|
294
|
+
| `body` | `unknown` | Parsed request body. |
|
|
295
|
+
| `headers` | `Record<string, string \| string[] \| undefined>` | Request headers. |
|
|
296
|
+
| `raw` | `TRaw` | Underlying raw request object from the framework (e.g. Express `Request`). Used by `PassportSessionStrategy`. |
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
### `HttpResponse<TRaw>`
|
|
301
|
+
|
|
302
|
+
Import: `@edium/halifax`
|
|
303
|
+
|
|
304
|
+
Framework-agnostic representation of an outgoing HTTP response.
|
|
305
|
+
|
|
306
|
+
| Member | Signature | Description |
|
|
307
|
+
| ----------- | ---------------------------------------------- | -------------------------------------------------- |
|
|
308
|
+
| `status` | `(code: number) => HttpResponse` | Set the HTTP status code (chainable). |
|
|
309
|
+
| `json` | `(payload: unknown) => void \| Promise<void>` | Serialize and send the response as JSON. |
|
|
310
|
+
| `send` | `(payload?: unknown) => void \| Promise<void>` | Send a raw response body (optional). |
|
|
311
|
+
| `setHeader` | `(name: string, value: string) => void` | Set a response header (optional). |
|
|
312
|
+
| `raw` | `TRaw` | Underlying raw response object from the framework. |
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
### HTTP framework structural interfaces
|
|
317
|
+
|
|
318
|
+
These are duck-typed so Halifax has no hard dependencies on specific framework packages.
|
|
319
|
+
|
|
320
|
+
| Interface | Import path | Description |
|
|
321
|
+
| ------------------------ | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
|
322
|
+
| `ExpressAppLike` | `@edium/halifax` | Minimal structural type for an Express `Application`. Requires `use`, `get`, `post`, `put`, `patch`, `delete`, `all`, and `listen`. |
|
|
323
|
+
| `FastifyAppLike` | `@edium/halifax` | Minimal structural type for a Fastify instance. Requires `get`, `post`, `put`, `patch`, `delete`, `all`, and `listen`. |
|
|
324
|
+
| `HyperExpressAppLike` | `@edium/halifax` | Minimal structural type for a HyperExpress `Server`. Requires `use`, `get`, `post`, `put`, `patch`, `delete`, `any`, and `listen`. |
|
|
325
|
+
| `UltimateExpressAppLike` | `@edium/halifax` | Minimal structural type for an Ultimate Express `App`. Requires `use`, `get`, `post`, `put`, `patch`, `delete`, `all`, and `listen`. |
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
## Repository
|
|
330
|
+
|
|
331
|
+
### `Repository<TRecord, TCreate, TUpdate>`
|
|
332
|
+
|
|
333
|
+
Import: `@edium/halifax`
|
|
334
|
+
|
|
335
|
+
Core data-access contract. Implement this interface to create a custom repository adapter.
|
|
336
|
+
|
|
337
|
+
| Member | Type | Required | Description |
|
|
338
|
+
| -------------- | ----------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------- |
|
|
339
|
+
| `capabilities` | `Partial<RepositoryCapabilities>` | no | Declares which optional operations the adapter supports. |
|
|
340
|
+
| `fields` | `FieldDefinition[]` | no | Field schema exposed to Halifax. When present, `ResourceDefinition.fields` are merged over these as sparse overrides. |
|
|
341
|
+
| `relations` | `RelationDefinition[]` | no | Relations for `?include=`. |
|
|
342
|
+
| `idField` | `string` | no | Primary key field name. Defaults to `'id'`. |
|
|
343
|
+
| `getOne` | `(id, options?) => Promise<TRecord \| null>` | yes | Fetch a single record by primary key. |
|
|
344
|
+
| `getMany` | `(options?) => Promise<ListResult<TRecord>>` | yes | Fetch a paginated, filtered list. |
|
|
345
|
+
| `createOne` | `(data, options?) => Promise<TRecord>` | yes | Insert and return a single record. |
|
|
346
|
+
| `createMany` | `(data[], options?) => Promise<TRecord[]>` | yes | Insert multiple records. |
|
|
347
|
+
| `updateOne` | `(id, data) => Promise<TRecord \| null>` | yes | Partially update a record by primary key. |
|
|
348
|
+
| `deleteOne` | `(id) => Promise<boolean>` | yes | Delete a record by primary key. |
|
|
349
|
+
| `updateMany` | `(query, data) => Promise<UpdateManyResult<TRecord>>` | no | Bulk-update matching records (query AST). |
|
|
350
|
+
| `upsertOne` | `(id, data) => Promise<TRecord>` | no | Insert or replace a record by primary key. |
|
|
351
|
+
| `deleteMany` | `(query) => Promise<DeleteManyResult>` | no | Bulk-delete matching records (query AST). |
|
|
352
|
+
| `executeQuery` | `(query) => Promise<QueryResult<TRecord>>` | no | Execute a raw query-builder AST. |
|
|
353
|
+
| `withScope` | `(scope: TenantScope) => Repository<...>` | no | Return a scoped clone for tenant isolation. Must be implemented for tenant-scoped resources. |
|
|
354
|
+
|
|
355
|
+
---
|
|
356
|
+
|
|
357
|
+
### `RepositoryCapabilities`
|
|
358
|
+
|
|
359
|
+
Import: `@edium/halifax`
|
|
360
|
+
|
|
361
|
+
Flags declaring which optional operations a repository adapter supports.
|
|
362
|
+
|
|
363
|
+
| Property | Type | Description |
|
|
364
|
+
| -------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------ |
|
|
365
|
+
| `supportsIncludes` | `boolean` | When `false`, the router rejects any `?include=` request with 422 rather than silently ignoring it. |
|
|
366
|
+
| `supportsCreateManyReturn` | `boolean` | When `true`, `createMany` returns the created records. When `false`, it returns an empty array (bulk insert path). |
|
|
367
|
+
|
|
368
|
+
---
|
|
369
|
+
|
|
370
|
+
### `ListOptions`
|
|
371
|
+
|
|
372
|
+
Import: `@edium/halifax`
|
|
373
|
+
|
|
374
|
+
Options passed to `Repository.getMany`.
|
|
375
|
+
|
|
376
|
+
| Property | Type | Description |
|
|
377
|
+
| --------- | ------------------------------------------------------ | --------------------------------------------------------------------------------- |
|
|
378
|
+
| `fields` | `string[]` | Columns to return. Returns all columns when omitted. |
|
|
379
|
+
| `where` | `Record<string, unknown>` | Key–value pairs applied as equality filters (or `{ in: [...] }` for multi-value). |
|
|
380
|
+
| `limit` | `number` | Maximum number of records to return. |
|
|
381
|
+
| `offset` | `number` | Number of records to skip for pagination. |
|
|
382
|
+
| `orderBy` | `Array<{ field: string; direction: 'asc' \| 'desc' }>` | Sort expressions. |
|
|
383
|
+
| `include` | `string[]` | Relation names to eager-load. |
|
|
384
|
+
|
|
385
|
+
---
|
|
386
|
+
|
|
387
|
+
### `CreateOptions`
|
|
388
|
+
|
|
389
|
+
Import: `@edium/halifax`
|
|
390
|
+
|
|
391
|
+
Options passed to `Repository.createOne` and `Repository.createMany`.
|
|
392
|
+
|
|
393
|
+
| Property | Type | Description |
|
|
394
|
+
| ---------------- | -------- | -------------------------------------------------------------------------------- |
|
|
395
|
+
| `idempotencyKey` | `string` | When provided, the adapter may de-duplicate repeated requests with the same key. |
|
|
396
|
+
|
|
397
|
+
---
|
|
398
|
+
|
|
399
|
+
## Cache
|
|
400
|
+
|
|
401
|
+
### `CacheStore`
|
|
402
|
+
|
|
403
|
+
Import: `@edium/halifax`
|
|
404
|
+
|
|
405
|
+
Contract for pluggable cache backends. Implement this to use Redis, Memcached, or any other store.
|
|
406
|
+
|
|
407
|
+
| Method | Signature | Description |
|
|
408
|
+
| -------- | ---------------------------------------------------- | ---------------------------------------------------------------- |
|
|
409
|
+
| `get` | `(key: string) => Promise<unknown> \| unknown` | Read a cached value. Returns `undefined` when absent or expired. |
|
|
410
|
+
| `set` | `(key, value, ttlSeconds?) => Promise<void> \| void` | Write a value. `ttlSeconds` `0` or omitted means no expiry. |
|
|
411
|
+
| `delete` | `(key: string) => Promise<void> \| void` | Delete a cached value. |
|
|
412
|
+
|
|
413
|
+
---
|
|
414
|
+
|
|
415
|
+
### `CachingRepositoryOptions`
|
|
416
|
+
|
|
417
|
+
Import: `@edium/halifax`
|
|
418
|
+
|
|
419
|
+
Options for `createCachingRepository`.
|
|
420
|
+
|
|
421
|
+
| Property | Type | Description |
|
|
422
|
+
| ------------ | ------------ | --------------------------------------------------------------------------------------------------------------- |
|
|
423
|
+
| `store` | `CacheStore` | Backing cache store. |
|
|
424
|
+
| `ttlSeconds` | `number` | TTL for cached reads. `0` = never expire. |
|
|
425
|
+
| `namespace` | `string` | Key prefix unique to this (resource, tenant) pair — ensures tenant isolation in a shared cache. |
|
|
426
|
+
| `bust` | `boolean` | When `true`, bypass the cache for this request and overwrite the entry. Set from the cache-bust request header. |
|
|
427
|
+
|
|
428
|
+
---
|
|
429
|
+
|
|
430
|
+
### `RedisLikeClient`
|
|
431
|
+
|
|
432
|
+
Import: `@edium/halifax`
|
|
433
|
+
|
|
434
|
+
Minimal structural type for a Redis client. `RedisCacheStore` uses this interface so no specific Redis package is a hard dependency. `redis` v4's `get`, `set`, and `del` satisfy it directly.
|
|
435
|
+
|
|
436
|
+
| Method | Signature | Description |
|
|
437
|
+
| ------ | -------------------------------------------- | ---------------------------------------------- |
|
|
438
|
+
| `get` | `(key: string) => Promise<string \| null>` | Read a key. |
|
|
439
|
+
| `set` | `(key, value, options?) => Promise<unknown>` | Write a key. `options.EX` sets TTL in seconds. |
|
|
440
|
+
| `del` | `(key: string) => Promise<unknown>` | Delete a key. |
|
|
441
|
+
|
|
442
|
+
---
|
|
443
|
+
|
|
444
|
+
## Prisma adapter
|
|
445
|
+
|
|
446
|
+
### `PrismaDelegate`
|
|
447
|
+
|
|
448
|
+
Import: `@edium/halifax`
|
|
449
|
+
|
|
450
|
+
Minimal structural type for a Prisma model delegate (e.g. `prisma.user`, `prisma.post`). Avoids a hard dependency on `@prisma/client`.
|
|
451
|
+
|
|
452
|
+
Key methods required: `findUnique`, `findFirst`, `findMany`, `count`, `create`, `createMany`, `update`, `updateMany`, `upsert`, `delete`, `deleteMany`.
|
|
453
|
+
|
|
454
|
+
---
|
|
455
|
+
|
|
456
|
+
### `PrismaAdapterOptions`
|
|
457
|
+
|
|
458
|
+
Import: `@edium/halifax`
|
|
459
|
+
|
|
460
|
+
Options for the `PrismaAdapter` constructor.
|
|
461
|
+
|
|
462
|
+
| Property | Type | Default | Description |
|
|
463
|
+
| --------------- | ---------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
464
|
+
| `delegate` | `PrismaDelegate` | required | The Prisma model delegate (`prisma.post`, `prisma.user`, …). |
|
|
465
|
+
| `idField` | `string` | `'id'` | Primary key field name. |
|
|
466
|
+
| `returnCreated` | `boolean` | `false` | When `true`, `createMany` falls back to serial `createOne` calls and returns the records. Slower but useful when the created data is needed. |
|
|
467
|
+
| `model` | `ModelSchema` | — | Prisma DMMF model. When provided, the adapter exposes a derived `fields` schema for type-safe introspection and OpenAPI generation. Auto-provided by `createPrismaResources`. |
|
|
468
|
+
| `scope` | `TenantScope` | — | Tenant constraint. Set internally via `withScope` — do not pass directly. |
|
|
469
|
+
|
|
470
|
+
---
|
|
471
|
+
|
|
472
|
+
### `CreatePrismaResourcesOptions`
|
|
473
|
+
|
|
474
|
+
Import: `@edium/halifax`
|
|
475
|
+
|
|
476
|
+
Global options for `createPrismaResources`.
|
|
477
|
+
|
|
478
|
+
| Property | Type | Description |
|
|
479
|
+
| --------------- | -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
|
|
480
|
+
| `models` | `Record<string, ModelResourceOptions>` | Per-model overrides keyed by Prisma model name (PascalCase). |
|
|
481
|
+
| `permissions` | `CrudPermissions` | Default permissions applied to every generated resource. |
|
|
482
|
+
| `defaultLimit` | `number` | Default page size for all generated resources. |
|
|
483
|
+
| `maxLimit` | `number` | Hard page-size cap for all generated resources. |
|
|
484
|
+
| `idField` | `string` | Primary key field name for all generated resources. |
|
|
485
|
+
| `returnCreated` | `boolean` | When `true`, `createMany` returns created records on all generated resources. |
|
|
486
|
+
| `tenantField` | `string` | Column name for auto-tenant scoping. Resources that have a field with this name are automatically marked tenant-scoped. |
|
|
487
|
+
|
|
488
|
+
---
|
|
489
|
+
|
|
490
|
+
### `ModelResourceOptions`
|
|
491
|
+
|
|
492
|
+
Import: `@edium/halifax`
|
|
493
|
+
|
|
494
|
+
Per-model overrides within `CreatePrismaResourcesOptions.models`.
|
|
495
|
+
|
|
496
|
+
| Property | Type | Description |
|
|
497
|
+
| --------------------- | --------------------------------------- | -------------------------------------------------- |
|
|
498
|
+
| `exclude` | `boolean` | When `true`, this model is skipped entirely. |
|
|
499
|
+
| `tenant` | `TenantResourceConfig \| false` | Override or disable tenant scoping for this model. |
|
|
500
|
+
| `routePrefix` | `string` | Override the auto-derived URL prefix. |
|
|
501
|
+
| `permissions` | `CrudPermissions` | Override default CRUD permissions for this model. |
|
|
502
|
+
| `requiredPermissions` | `Partial<Record<CrudAction, string[]>>` | Per-action permission requirements. |
|
|
503
|
+
| `defaultLimit` | `number` | Default page size override. |
|
|
504
|
+
| `maxLimit` | `number` | Max page size override. |
|
|
505
|
+
| `maxFilterDepth` | `number` | Maximum WHERE clause nesting depth. |
|
|
506
|
+
|
|
507
|
+
---
|
|
508
|
+
|
|
509
|
+
### `ModelSchema`
|
|
510
|
+
|
|
511
|
+
Import: `@edium/halifax`
|
|
512
|
+
|
|
513
|
+
Minimal shape of a Prisma DMMF model — structurally compatible with `Prisma.DMMF.Model`. Used to derive the Halifax field schema from Prisma metadata.
|
|
514
|
+
|
|
515
|
+
| Property | Type | Description |
|
|
516
|
+
| -------- | ---------------- | ------------------------------------------------------------- |
|
|
517
|
+
| `name` | `string` | Prisma model name (PascalCase). |
|
|
518
|
+
| `dbName` | `string \| null` | Underlying database table name. `null` to use the model name. |
|
|
519
|
+
| `fields` | `ModelField[]` | Field definitions from the DMMF. |
|
|
520
|
+
|
|
521
|
+
---
|
|
522
|
+
|
|
523
|
+
### `ModelField`
|
|
524
|
+
|
|
525
|
+
Import: `@edium/halifax`
|
|
526
|
+
|
|
527
|
+
Minimal shape of a Prisma DMMF field — structurally compatible with `Prisma.DMMF.Field`.
|
|
528
|
+
|
|
529
|
+
| Property | Type | Description |
|
|
530
|
+
| ------------ | --------- | ------------------------------------------------------------------------------------------------------------- |
|
|
531
|
+
| `name` | `string` | Column / property name. |
|
|
532
|
+
| `kind` | `string` | Prisma field kind: `'scalar'`, `'object'` (relation), `'enum'`, `'unsupported'`. |
|
|
533
|
+
| `isId` | `boolean` | `true` when this field is the primary key. |
|
|
534
|
+
| `isReadOnly` | `boolean` | `true` for Prisma-managed fields (relation FKs, read-only scalars). |
|
|
535
|
+
| `hasDefault` | `boolean` | `true` when Prisma provides a default value. |
|
|
536
|
+
| `type` | `string` | Prisma scalar type name (`'String'`, `'Int'`, `'Boolean'`, `'DateTime'`, …). Used for OpenAPI type inference. |
|
|
537
|
+
|
|
538
|
+
---
|
|
539
|
+
|
|
540
|
+
## Drizzle adapter (`@edium/halifax/drizzle`)
|
|
541
|
+
|
|
542
|
+
### `DrizzleAdapterConfig`
|
|
543
|
+
|
|
544
|
+
Import: `@edium/halifax/drizzle`
|
|
545
|
+
|
|
546
|
+
Constructor config for `DrizzleAdapter`.
|
|
547
|
+
|
|
548
|
+
| Property | Type | Description |
|
|
549
|
+
| --------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
550
|
+
| `idField` | `string` | Primary key field name. Defaults to auto-detecting the first column with `.primaryKey()`. Set explicitly for composite keys or non-standard names. |
|
|
551
|
+
|
|
552
|
+
---
|
|
553
|
+
|
|
554
|
+
## Query AST
|
|
555
|
+
|
|
556
|
+
These interfaces are re-exported from `@edium/halifax-types`.
|
|
557
|
+
|
|
558
|
+
### `IQueryOptions`
|
|
559
|
+
|
|
560
|
+
Import: `@edium/halifax`
|
|
561
|
+
|
|
562
|
+
Full query AST sent to `POST /:resource/query`. Also accepted as the body by `updateMany` and `deleteMany`.
|
|
563
|
+
|
|
564
|
+
| Property | Type | Description |
|
|
565
|
+
| ---------- | ---------------- | -------------------------- |
|
|
566
|
+
| `where` | `IQueryFilter[]` | Filter conditions. |
|
|
567
|
+
| `orderBy` | `ISort[]` | Sort clauses. |
|
|
568
|
+
| `limit` | `number` | Maximum records to return. |
|
|
569
|
+
| `offset` | `number` | Records to skip. |
|
|
570
|
+
| `fields` | `string[]` | Field projection. |
|
|
571
|
+
| `distinct` | `string[]` | Columns to deduplicate on. |
|
|
572
|
+
|
|
573
|
+
---
|
|
574
|
+
|
|
575
|
+
### `IQueryFilter`
|
|
576
|
+
|
|
577
|
+
Import: `@edium/halifax`
|
|
578
|
+
|
|
579
|
+
A single filter node in a `where` array.
|
|
580
|
+
|
|
581
|
+
| Property | Type | Description |
|
|
582
|
+
| ------------ | ------------------------------ | ------------------------------------------------------------------------- |
|
|
583
|
+
| `field` | `string` | Column to filter on. |
|
|
584
|
+
| `comparison` | `SqlComparison \| string` | Comparison operator. |
|
|
585
|
+
| `value1` | `QueryScalar \| QueryScalar[]` | Primary value for the comparison. |
|
|
586
|
+
| `value2` | `string \| number` | Secondary value (used by `BETWEEN`). |
|
|
587
|
+
| `operator` | `SqlOperator` | Logical operator (`AND`/`OR`) joining this condition to the next sibling. |
|
|
588
|
+
| `children` | `IQueryFilter[]` | Nested sub-group of conditions for parenthesised AND/OR logic. |
|
|
589
|
+
|
|
590
|
+
---
|
|
591
|
+
|
|
592
|
+
### `ISort`
|
|
593
|
+
|
|
594
|
+
Import: `@edium/halifax`
|
|
595
|
+
|
|
596
|
+
A single sort clause in an `orderBy` array.
|
|
597
|
+
|
|
598
|
+
| Property | Type | Description |
|
|
599
|
+
| -------- | ---------- | --------------------------------- |
|
|
600
|
+
| `field` | `string` | Column to sort on. |
|
|
601
|
+
| `order` | `SqlOrder` | Sort direction (`ASC` or `DESC`). |
|