fastify-auto-sqlapi 0.0.4 → 0.1.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/AGENTS.md +15 -2
- package/AGENTS_BACKEND.md +160 -32
- package/AGENTS_FRONTEND.md +220 -49
- package/README.md +147 -27
- package/dist/bin/generate-schema.js +12 -29
- package/dist/bin/generate-tables.js +10 -33
- package/dist/bin/utils.d.ts +29 -1
- package/dist/bin/utils.d.ts.map +1 -1
- package/dist/bin/utils.js +71 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/lib/cli/load-dependency.d.ts +8 -0
- package/dist/lib/cli/load-dependency.d.ts.map +1 -0
- package/dist/lib/cli/load-dependency.js +21 -0
- package/dist/lib/cli/mysql-introspect.d.ts.map +1 -1
- package/dist/lib/cli/mysql-introspect.js +2 -11
- package/dist/lib/cli/pg-introspect.d.ts.map +1 -1
- package/dist/lib/cli/pg-introspect.js +2 -17
- package/dist/lib/cli/schema-codegen.d.ts +1 -1
- package/dist/lib/cli/schema-codegen.d.ts.map +1 -1
- package/dist/lib/cli/schema-codegen.js +11 -4
- package/dist/lib/cli/tables-codegen.d.ts.map +1 -1
- package/dist/lib/cli/tables-codegen.js +4 -3
- package/dist/lib/db.d.ts +1 -0
- package/dist/lib/db.d.ts.map +1 -1
- package/dist/lib/db.js +33 -49
- package/dist/lib/dialect.d.ts +17 -0
- package/dist/lib/dialect.d.ts.map +1 -1
- package/dist/lib/dialect.js +32 -0
- package/dist/lib/engine/bulk/bulk-upsert.d.ts.map +1 -1
- package/dist/lib/engine/bulk/bulk-upsert.js +26 -50
- package/dist/lib/engine/rest/delete.d.ts.map +1 -1
- package/dist/lib/engine/rest/delete.js +5 -10
- package/dist/lib/engine/rest/get.d.ts.map +1 -1
- package/dist/lib/engine/rest/get.js +4 -6
- package/dist/lib/engine/rest/insert.d.ts.map +1 -1
- package/dist/lib/engine/rest/insert.js +20 -39
- package/dist/lib/engine/rest/update.d.ts.map +1 -1
- package/dist/lib/engine/rest/update.js +35 -67
- package/dist/lib/engine/search/search.d.ts.map +1 -1
- package/dist/lib/engine/search/search.js +650 -130
- package/dist/lib/engine/write-helpers.d.ts +39 -2
- package/dist/lib/engine/write-helpers.d.ts.map +1 -1
- package/dist/lib/engine/write-helpers.js +58 -15
- package/dist/lib/errors.d.ts +11 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +12 -0
- package/dist/lib/naming.d.ts +11 -2
- package/dist/lib/naming.d.ts.map +1 -1
- package/dist/lib/naming.js +33 -5
- package/dist/lib/schema/bulk-upsert.d.ts.map +1 -1
- package/dist/lib/schema/bulk-upsert.js +9 -25
- package/dist/lib/schema/helpers.d.ts +28 -1
- package/dist/lib/schema/helpers.d.ts.map +1 -1
- package/dist/lib/schema/helpers.js +38 -0
- package/dist/lib/schema/insert.d.ts.map +1 -1
- package/dist/lib/schema/insert.js +9 -19
- package/dist/lib/schema/search.d.ts.map +1 -1
- package/dist/lib/schema/search.js +147 -53
- package/dist/lib/schema/update.d.ts.map +1 -1
- package/dist/lib/schema/update.js +9 -25
- package/dist/lib/sql-api.d.ts +6 -6
- package/dist/lib/sql-api.d.ts.map +1 -1
- package/dist/lib/sql-api.js +8 -8
- package/dist/lib/table-helpers.d.ts +6 -1
- package/dist/lib/table-helpers.d.ts.map +1 -1
- package/dist/lib/table-helpers.js +51 -3
- package/dist/lib/tenant.d.ts +23 -0
- package/dist/lib/tenant.d.ts.map +1 -1
- package/dist/lib/tenant.js +57 -9
- package/dist/routes/auto/bulk-delete.routes.d.ts.map +1 -1
- package/dist/routes/auto/bulk-delete.routes.js +17 -23
- package/dist/routes/auto/bulk-upsert.routes.d.ts.map +1 -1
- package/dist/routes/auto/bulk-upsert.routes.js +16 -22
- package/dist/routes/auto/delete.routes.d.ts.map +1 -1
- package/dist/routes/auto/delete.routes.js +18 -24
- package/dist/routes/auto/get.routes.d.ts.map +1 -1
- package/dist/routes/auto/get.routes.js +16 -23
- package/dist/routes/auto/insert.routes.d.ts.map +1 -1
- package/dist/routes/auto/insert.routes.js +19 -26
- package/dist/routes/auto/route-helpers.d.ts +27 -2
- package/dist/routes/auto/route-helpers.d.ts.map +1 -1
- package/dist/routes/auto/route-helpers.js +39 -1
- package/dist/routes/auto/search.routes.d.ts.map +1 -1
- package/dist/routes/auto/search.routes.js +47 -47
- package/dist/routes/auto/update.routes.d.ts.map +1 -1
- package/dist/routes/auto/update.routes.js +20 -27
- package/dist/types/cli.d.ts +22 -0
- package/dist/types/cli.d.ts.map +1 -0
- package/dist/types/cli.js +1 -0
- package/dist/types/computed.d.ts +29 -0
- package/dist/types/computed.d.ts.map +1 -0
- package/dist/types/computed.js +1 -0
- package/dist/types/conditions.d.ts +16 -0
- package/dist/types/conditions.d.ts.map +1 -0
- package/dist/types/conditions.js +1 -0
- package/dist/types/db.d.ts +22 -0
- package/dist/types/db.d.ts.map +1 -0
- package/dist/types/db.js +1 -0
- package/dist/types/dml.d.ts +64 -0
- package/dist/types/dml.d.ts.map +1 -0
- package/dist/types/dml.js +1 -0
- package/dist/types/join.d.ts +44 -0
- package/dist/types/join.d.ts.map +1 -0
- package/dist/types/join.js +1 -0
- package/dist/types/plugin.d.ts +20 -0
- package/dist/types/plugin.d.ts.map +1 -0
- package/dist/types/plugin.js +1 -0
- package/dist/types/schema.d.ts +10 -0
- package/dist/types/schema.d.ts.map +1 -0
- package/dist/types/schema.js +1 -0
- package/dist/types/search.d.ts +45 -0
- package/dist/types/search.d.ts.map +1 -0
- package/dist/types/search.js +1 -0
- package/dist/types/table.d.ts +52 -0
- package/dist/types/table.d.ts.map +1 -0
- package/dist/types/table.js +7 -0
- package/dist/types/tenant.d.ts +19 -0
- package/dist/types/tenant.d.ts.map +1 -0
- package/dist/types/tenant.js +1 -0
- package/dist/types/validation.d.ts +21 -0
- package/dist/types/validation.d.ts.map +1 -0
- package/dist/types/validation.js +1 -0
- package/dist/types.d.ts +12 -258
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +12 -7
- package/package.json +8 -5
package/README.md
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
# fastify-auto-sqlapi
|
|
2
2
|
|
|
3
|
-
Automatic CRUD API generation from PostgreSQL tables for [Fastify](https://fastify.dev/). No ORM, no magic — just raw SQL
|
|
3
|
+
Automatic CRUD API generation from PostgreSQL, MySQL, and MariaDB tables for [Fastify](https://fastify.dev/). No ORM, no magic — just raw SQL, with TypeBox validation and Swagger docs out of the box.
|
|
4
4
|
|
|
5
|
-
Point it at your database, and get a full REST API with search, pagination, joins, bulk operations, multi-tenant isolation, and hooks.
|
|
5
|
+
Point it at your database, and get a full REST API with search, advanced conditions, pagination, joins, aggregations, bulk operations, multi-tenant isolation, validation, and hooks.
|
|
6
6
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
9
9
|
- **Zero boilerplate** — define your tables, get 7 endpoints each
|
|
10
10
|
- **No ORM** — raw SQL via `pg` + parameterized queries
|
|
11
11
|
- **TypeBox validation** — request/response schemas auto-generated from your DB
|
|
12
|
-
- **
|
|
12
|
+
- **Joins** — four explicit families (`joinMustExist`, `joinMultiple`, `joinGroup`, `joinLeft`) with alias support
|
|
13
|
+
- **Computed fields** — declare virtual fields as SQL expressions in `defineTable`; usable like schema fields in filters/orderBy/conditions, and opt-in projected in the response via `selectComputed`. Covers JSON extraction, derived columns, dialect-aware date bucketing
|
|
13
14
|
- **Bulk operations** — batch insert/upsert/delete in single queries
|
|
14
15
|
- **Multi-tenant** — automatic row-level isolation, zero code in handlers
|
|
15
16
|
- **Validation** — structured field-level validation with cross-entity support
|
|
@@ -17,6 +18,8 @@ Point it at your database, and get a full REST API with search, pagination, join
|
|
|
17
18
|
- **Swagger UI** — optional, auto-configured from your schemas
|
|
18
19
|
- **Composable** — register all routes or pick only what you need
|
|
19
20
|
|
|
21
|
+
> ⚠️ **Migrating from a previous version?** The join API was redesigned. See **[BREAKING_CHANGES.md](./BREAKING_CHANGES.md)** for the full migration guide.
|
|
22
|
+
|
|
20
23
|
## Quick Start
|
|
21
24
|
|
|
22
25
|
### 1. Install
|
|
@@ -143,12 +146,16 @@ const TableCustomer = defineTable({
|
|
|
143
146
|
excludeFromCreation: ['id'], // omit from INSERT (e.g. auto-increment)
|
|
144
147
|
distinctResults: true, // SELECT DISTINCT
|
|
145
148
|
|
|
146
|
-
// Relations
|
|
149
|
+
// Relations — alias defaults to joinSchema.tableName. Override with `{ alias: '...' }`
|
|
150
|
+
// when you join the same table twice (e.g. `createdBy`/`updatedBy`) or want a friendlier
|
|
151
|
+
// name. Set `unique: true` for N:1 (parent) relations to enable `joinLeft`.
|
|
147
152
|
allowedReadJoins: [
|
|
148
|
-
buildRelation(SchemaCustomer, 'id', SchemaOrder, 'customerId'),
|
|
153
|
+
buildRelation(SchemaCustomer, 'id', SchemaOrder, 'customerId'), // alias = 'order'
|
|
154
|
+
buildRelation(SchemaSession, 'userId', SchemaUser, 'id', { unique: true }), // alias = 'user', N:1
|
|
155
|
+
buildRelation(SchemaSession, 'updatedBy', SchemaUser, 'id', { alias: 'updater', unique: true }),
|
|
149
156
|
],
|
|
150
157
|
allowedWriteJoins: [
|
|
151
|
-
buildRelation(SchemaCustomer, 'id', SchemaOrder, 'customerId'),
|
|
158
|
+
buildRelation(SchemaCustomer, 'id', SchemaOrder, 'customerId'), // alias = 'order'
|
|
152
159
|
],
|
|
153
160
|
|
|
154
161
|
// Upsert (ON CONFLICT)
|
|
@@ -176,10 +183,10 @@ const TableCustomer = defineTable({
|
|
|
176
183
|
return [];
|
|
177
184
|
},
|
|
178
185
|
|
|
179
|
-
// Hooks (runs after validation)
|
|
180
|
-
beforeInsert: async (db, req, record) => { /*
|
|
181
|
-
beforeUpdate: async (db, req, fields) => { /*
|
|
182
|
-
afterInsert: async (db, req, record, secondaryRecords) => { /*
|
|
186
|
+
// Hooks (runs after validation) — all receive camelCase records (schema field names)
|
|
187
|
+
beforeInsert: async (db, req, record) => { /* camelCase; mutations propagate to INSERT */ },
|
|
188
|
+
beforeUpdate: async (db, req, fields) => { /* camelCase; PK included for reference, excluded from UPDATE SET */ },
|
|
189
|
+
afterInsert: async (db, req, record, secondaryRecords) => { /* camelCase; input merged with generated PK */ },
|
|
183
190
|
|
|
184
191
|
// Auth (per-table)
|
|
185
192
|
onRequests: [
|
|
@@ -219,37 +226,89 @@ const TableCustomer = defineTable({
|
|
|
219
226
|
```typescript
|
|
220
227
|
await app.register(fastifyAutoSqlApi, {
|
|
221
228
|
DbTables: dbTables, // Required — your table definitions
|
|
229
|
+
dialect: 'postgres', // Optional — 'postgres' | 'mysql' | 'mariadb' (default: 'postgres')
|
|
222
230
|
prefix: '/api', // Optional — URL prefix for all routes
|
|
223
231
|
swagger: true, // Optional — enable Swagger UI (or pass SwaggerOptions)
|
|
224
232
|
onRequests: [authMiddleware], // Optional — global hooks applied to every route
|
|
225
233
|
getTenantId: (req) => id, // Optional — multi-tenant function
|
|
234
|
+
debug: true, // Optional — log all SQL queries and params
|
|
226
235
|
});
|
|
227
236
|
```
|
|
228
237
|
|
|
229
238
|
| Option | Type | Required | Description |
|
|
230
239
|
|--------|------|----------|-------------|
|
|
231
240
|
| `DbTables` | `Record<string, ITable>` | Yes | Table configurations |
|
|
241
|
+
| `dialect` | `'postgres' \| 'mysql' \| 'mariadb'` | No | DB dialect (default: `'postgres'`) |
|
|
232
242
|
| `prefix` | `string` | No | URL prefix (e.g. `/api`) |
|
|
233
243
|
| `swagger` | `boolean \| SwaggerOptions` | No | Enable Swagger UI |
|
|
234
244
|
| `onRequests` | `Function[]` | No | Global auth/middleware hooks |
|
|
235
245
|
| `getTenantId` | `(req) => id \| null` | No | Tenant resolver for multi-tenant |
|
|
246
|
+
| `debug` | `boolean` | No | Log all SQL queries to console |
|
|
247
|
+
|
|
248
|
+
For MySQL/MariaDB, register `mysql2/promise` pool instead of `@fastify/postgres` and pass `dialect: 'mysql'` or `'mariadb'`.
|
|
236
249
|
|
|
237
250
|
## API Reference
|
|
238
251
|
|
|
239
252
|
### POST /search/{table}
|
|
240
253
|
|
|
241
|
-
Search with filters, pagination, ordering, joins, and aggregations.
|
|
254
|
+
Search with filters, advanced conditions, pagination, ordering, joins, and aggregations.
|
|
242
255
|
|
|
243
256
|
**Request body** (all fields optional):
|
|
244
257
|
|
|
245
258
|
```json
|
|
246
259
|
{
|
|
247
260
|
"filters": { "name": "Mario" },
|
|
248
|
-
"
|
|
249
|
-
|
|
261
|
+
"conditions": [
|
|
262
|
+
{ "field": "total", "method": "isGreater", "params": [100] },
|
|
263
|
+
{ "field": "createdAt", "method": "isBetween", "params": ["2024-01-01", "2024-12-31"] }
|
|
264
|
+
],
|
|
265
|
+
"joinMustExist": {
|
|
266
|
+
"orders": {
|
|
267
|
+
"filters": { "status": "completed" },
|
|
268
|
+
"conditions": [{ "field": "total", "method": "isGreater", "params": [50] }]
|
|
269
|
+
}
|
|
270
|
+
},
|
|
271
|
+
"joinMultiple": {
|
|
272
|
+
"orders": {
|
|
273
|
+
"filters": { "status": "completed" },
|
|
274
|
+
"selection": "id,total,status"
|
|
275
|
+
}
|
|
276
|
+
},
|
|
277
|
+
"joinGroup": {
|
|
278
|
+
"orders": {
|
|
279
|
+
"aggregations": {
|
|
280
|
+
"by": "status",
|
|
281
|
+
"sum": ["total"],
|
|
282
|
+
"min": ["total"],
|
|
283
|
+
"max": ["total"],
|
|
284
|
+
"avg": ["total"],
|
|
285
|
+
"count": ["id"],
|
|
286
|
+
"distinctCount": ["status"]
|
|
287
|
+
},
|
|
288
|
+
"filters": { "status": "completed" }
|
|
289
|
+
}
|
|
290
|
+
},
|
|
291
|
+
"joinLeft": {
|
|
292
|
+
"creator": { "selection": "id,name,email" }
|
|
293
|
+
}
|
|
250
294
|
}
|
|
251
295
|
```
|
|
252
296
|
|
|
297
|
+
- **`filters`** — equality-based, flat key/value. Supports schema fields + `extraFilters`.
|
|
298
|
+
- **`conditions`** — array of `{ field, method, params }`. Methods: `isEqual`, `isNotEqual`, `isGreater`, `isGreaterOrEqual`, `isLess`, `isLessOrEqual`, `isLike`, `isILike`, `isIn`, `isNotIn`, `isBetween`, `isNotBetween`, `isNull`, `isNotNull`.
|
|
299
|
+
- **`joinMustExist`** — EXISTS-based filter: "main rows where at least one related row matches". Accepts `{ filters, conditions }` (both optional). Aliases must come from `allowedReadJoins` declarations with `unique: false`.
|
|
300
|
+
- **`joinMultiple`** — fetches related child rows in a side query. Accepts `{ filters, conditions, selection }`. Same `unique: false` aliases.
|
|
301
|
+
- **`joinGroup`** — aggregations on the related table. Supports `sum`, `min`, `max`, `avg`, `count`, `distinctCount`, and optional `by` for GROUP BY (a schema field name or a computed-field name declared on the join table — e.g. for date bucketing declare a computed using `db.dateTrunc('month', qiCol('orderDate'))`). Accepts `{ filters, conditions }`. Same `unique: false` aliases.
|
|
302
|
+
- **`joinLeft`** — embeds an N:1 parent. Real `LEFT JOIN` is added on demand (only when the request has `filters`/`conditions` on the parent or uses 2-parti `orderBy` on this alias). Aliases must be declared with `unique: true`. Accepts `{ filters, conditions, selection }`.
|
|
303
|
+
|
|
304
|
+
**Dot-notation in `orderBy` and `conditions`**:
|
|
305
|
+
|
|
306
|
+
| Form | Source | Example |
|
|
307
|
+
|------|--------|---------|
|
|
308
|
+
| `<field>` | main schema | `orderBy=name ASC` |
|
|
309
|
+
| `<alias>.<field>` | `joinLeft` aliases (`unique: true`) | `orderBy=creator.name ASC` |
|
|
310
|
+
| `<alias>.<fn>.<field>` | `joinGroup` aliases declared in the same body | `orderBy=orders.sum.total DESC`, or `conditions: [{ field: 'orders.count.id', method: 'isGreaterOrEqual', params: [4] }]` |
|
|
311
|
+
|
|
253
312
|
**Querystring** (optional): `orderBy`, `page`, `itemsPerPage`, `computeMin`, `computeMax`, `computeSum`, `computeAvg`
|
|
254
313
|
|
|
255
314
|
**Response:**
|
|
@@ -258,12 +317,25 @@ Search with filters, pagination, ordering, joins, and aggregations.
|
|
|
258
317
|
{
|
|
259
318
|
"table": "customer",
|
|
260
319
|
"main": [{ "id": 1, "name": "Mario", "email": "m@test.it" }],
|
|
261
|
-
"
|
|
262
|
-
"
|
|
320
|
+
"joinLeft": { "creator": [{ "id": 7, "name": "Alice", "email": "a@x.it" }] },
|
|
321
|
+
"joinMultiple": { "orders": [{ "id": 10, "customerId": 1, "total": 50 }] },
|
|
322
|
+
"joinGroup": {
|
|
323
|
+
"orders": {
|
|
324
|
+
"sum": { "total": 300 },
|
|
325
|
+
"count": { "id": 2 },
|
|
326
|
+
"rows": [{ "by": "completed", "sum_total": 300, "count_id": 2 }]
|
|
327
|
+
}
|
|
328
|
+
},
|
|
329
|
+
"pagination": {
|
|
330
|
+
"total": 25,
|
|
331
|
+
"pages": 3,
|
|
332
|
+
"computed": { "min": { "id": 1 }, "max": { "id": 100 } },
|
|
333
|
+
"paginator": { "page": 1, "itemsPerPage": 20 }
|
|
334
|
+
}
|
|
263
335
|
}
|
|
264
336
|
```
|
|
265
337
|
|
|
266
|
-
`
|
|
338
|
+
`joinLeft`, `joinMultiple`, `joinGroup`, and `pagination` appear only when requested. A simple `{}` body returns `{ table, main }`. `pagination.computed` appears only if `computeMin`/`computeMax`/`computeSum`/`computeAvg` are used.
|
|
267
339
|
|
|
268
340
|
### GET /rest/{table}/:id
|
|
269
341
|
|
|
@@ -277,12 +349,12 @@ Returns `{ main: { ... } }` or 404.
|
|
|
277
349
|
{
|
|
278
350
|
"main": { "name": "Mario", "email": "m@test.it" },
|
|
279
351
|
"secondaries": {
|
|
280
|
-
"
|
|
352
|
+
"orders": [{ "total": 50, "status": "pending" }]
|
|
281
353
|
}
|
|
282
354
|
}
|
|
283
355
|
```
|
|
284
356
|
|
|
285
|
-
`secondaries`
|
|
357
|
+
`secondaries` keys are the **alias** declared in `allowedWriteJoins`. FK fields are auto-filled from the inserted main record.
|
|
286
358
|
|
|
287
359
|
**Response (201):** `{ main: { ... }, secondaries: { ... } }`
|
|
288
360
|
|
|
@@ -293,8 +365,8 @@ Returns `{ main: { ... } }` or 404.
|
|
|
293
365
|
```json
|
|
294
366
|
{
|
|
295
367
|
"main": { "id": 1, "name": "Updated Name" },
|
|
296
|
-
"secondaries": { "
|
|
297
|
-
"deletions":
|
|
368
|
+
"secondaries": { "orders": [{ "total": 75 }] },
|
|
369
|
+
"deletions": { "orders": [{ "id": 10 }] }
|
|
298
370
|
}
|
|
299
371
|
```
|
|
300
372
|
|
|
@@ -312,6 +384,24 @@ Returns the deleted record or 404.
|
|
|
312
384
|
|
|
313
385
|
**Body:** Array of objects with the PK field, e.g. `[{ "id": 1 }, { "id": 2 }]`. Executes as a single `DELETE WHERE pk IN (...)`.
|
|
314
386
|
|
|
387
|
+
### Validation errors (400)
|
|
388
|
+
|
|
389
|
+
Both schema-level (TypeBox/Ajv) and custom (`validate` / `validateBulk`) errors use the same response shape:
|
|
390
|
+
|
|
391
|
+
```json
|
|
392
|
+
{
|
|
393
|
+
"statusCode": 400,
|
|
394
|
+
"error": "Bad Request",
|
|
395
|
+
"message": "Validation failed",
|
|
396
|
+
"fields": [
|
|
397
|
+
{ "path": "main.email", "code": "format", "message": "must match format \"email\"" },
|
|
398
|
+
{ "path": "name", "code": "required", "message": "is required" }
|
|
399
|
+
]
|
|
400
|
+
}
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
Custom validators return tuples `[field, code]` or `[field, code, message]` — `message` defaults to `code` if omitted. `validateBulk` replaces per-item `validate` in bulk-upsert requests.
|
|
404
|
+
|
|
315
405
|
## Multi-Tenant
|
|
316
406
|
|
|
317
407
|
Automatic row-level isolation on all CRUD operations. Configure once, no code in handlers.
|
|
@@ -405,9 +495,11 @@ await app.register(async (instance) => {
|
|
|
405
495
|
|
|
406
496
|
## Conventions
|
|
407
497
|
|
|
408
|
-
- **camelCase in API,
|
|
409
|
-
- **
|
|
410
|
-
- **
|
|
498
|
+
- **camelCase everywhere in the API** — requests, responses, `validate`, and all hooks (`beforeInsert`, `beforeUpdate`, `afterInsert`) use schema field names
|
|
499
|
+
- **Conversion to DB column format is automatic** via `colMap` — supports both snake_case and camelCase DB columns (e.g. betterauth-style)
|
|
500
|
+
- **Aliases identify joins** — declared in `buildRelation({ alias })`, used as keys in request/response/`secondaries`/dotted notation
|
|
501
|
+
- **`joinMustExist` / `joinMultiple` / `joinGroup`** are 1:N (child→main) and use side queries / EXISTS / correlated subqueries — no row duplication
|
|
502
|
+
- **`joinLeft`** is N:1 (parent→main) and adds a real `LEFT JOIN` on demand (only when filtering/ordering by parent)
|
|
411
503
|
- **All response fields are Optional** — response schemas use `Type.Partial` since `RETURNING *` may return any subset
|
|
412
504
|
|
|
413
505
|
## Re-exports
|
|
@@ -417,23 +509,51 @@ The package re-exports commonly needed utilities so you don't need to install th
|
|
|
417
509
|
```typescript
|
|
418
510
|
import {
|
|
419
511
|
Type, // from @sinclair/typebox
|
|
512
|
+
type Static, // from @sinclair/typebox
|
|
420
513
|
ConditionBuilder, // from node-condition-builder
|
|
421
514
|
Expression, // from node-condition-builder
|
|
422
|
-
|
|
515
|
+
|
|
516
|
+
// Table configuration
|
|
423
517
|
defineTable,
|
|
424
518
|
exportTableInfo,
|
|
425
519
|
buildRelation,
|
|
426
520
|
buildUpsertRule,
|
|
427
521
|
buildUpsertRules,
|
|
522
|
+
|
|
523
|
+
// DB layer
|
|
524
|
+
QueryClient, // raw SQL query helper
|
|
525
|
+
createQueryClient, // factory with dialect string
|
|
526
|
+
pgQueryable, // pg pool adapter
|
|
527
|
+
mysqlQueryable, // mysql2 pool adapter
|
|
528
|
+
|
|
529
|
+
// Programmatic high-level API
|
|
530
|
+
createSqlApi, // standalone SqlApi (for scripts/tests)
|
|
531
|
+
setupSwagger, // manual Swagger registration
|
|
532
|
+
} from 'fastify-auto-sqlapi';
|
|
533
|
+
|
|
534
|
+
import type {
|
|
535
|
+
ValidationError, // [field, code] | [field, code, message]
|
|
536
|
+
ValidatorFn,
|
|
537
|
+
BulkValidatorFn,
|
|
538
|
+
JoinDefinition,
|
|
539
|
+
JoinRefFilter,
|
|
540
|
+
JoinFetchRequest,
|
|
541
|
+
JoinGroupRequest,
|
|
542
|
+
SearchCondition,
|
|
543
|
+
ConditionMethod,
|
|
428
544
|
} from 'fastify-auto-sqlapi';
|
|
429
545
|
```
|
|
430
546
|
|
|
547
|
+
After registering the plugin, `app.sqlApi` is decorated on the Fastify instance and exposes `search`, `get`, `insert`, `update`, `delete`, `bulkUpsert`, `bulkDelete` for custom routes — same code path as the auto-generated endpoints.
|
|
548
|
+
|
|
431
549
|
## Requirements
|
|
432
550
|
|
|
433
551
|
- Node.js >= 18
|
|
434
|
-
-
|
|
435
|
-
-
|
|
436
|
-
- `@fastify/postgres`
|
|
552
|
+
- Fastify >= 4 (peer dependency)
|
|
553
|
+
- One of:
|
|
554
|
+
- **PostgreSQL** + `pg` + `@fastify/postgres`
|
|
555
|
+
- **MySQL** / **MariaDB** + `mysql2`
|
|
556
|
+
- Optional: `@fastify/swagger` + `@fastify/swagger-ui` for Swagger UI
|
|
437
557
|
|
|
438
558
|
## License
|
|
439
559
|
|
|
@@ -5,28 +5,15 @@ import { loadConfig } from '../lib/cli/config.js';
|
|
|
5
5
|
import { buildConnectionString, introspectTables } from '../lib/cli/pg-introspect.js';
|
|
6
6
|
import { buildMysqlConnectionConfig, introspectMysqlTables } from '../lib/cli/mysql-introspect.js';
|
|
7
7
|
import { buildTableMap, generateSchemaFile } from '../lib/cli/schema-codegen.js';
|
|
8
|
-
import { loadEnvFile, CONSOLE_COLORS, display, displayAsTableRow,
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
result.output = args[++i];
|
|
16
|
-
}
|
|
17
|
-
else if (args[i] === '--tables' && i + 1 < args.length) {
|
|
18
|
-
result.tables = args[++i].split(',').map((t) => t.trim()).filter(Boolean);
|
|
19
|
-
}
|
|
20
|
-
else if (args[i] === '--dialect' && i + 1 < args.length) {
|
|
21
|
-
result.dialect = args[++i];
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
return result;
|
|
25
|
-
}
|
|
26
|
-
async function main() {
|
|
27
|
-
display('++++++ fastify-auto-sqlapi: generating schemas ++++++', CONSOLE_COLORS.yellow);
|
|
28
|
-
const cliArgs = parseCliArgs();
|
|
8
|
+
import { loadEnvFile, CONSOLE_COLORS, display, displayAsTableRow, parseArgs, runCli } from './utils.js';
|
|
9
|
+
await runCli('fastify-auto-sqlapi: generating schemas', async () => {
|
|
10
|
+
const cliArgs = parseArgs({
|
|
11
|
+
output: { type: 'value' },
|
|
12
|
+
tables: { type: 'list' },
|
|
13
|
+
dialect: { type: 'value' },
|
|
14
|
+
});
|
|
29
15
|
const config = await loadConfig();
|
|
16
|
+
loadEnvFile(config.envFile);
|
|
30
17
|
const dialect = (cliArgs.dialect || config.dialect || 'postgres');
|
|
31
18
|
const schema = config.schema || (dialect === 'postgres' ? 'public' : config.schema || 'public');
|
|
32
19
|
const outputDir = path.resolve(process.cwd(), cliArgs.output || config.outputDir);
|
|
@@ -51,7 +38,7 @@ async function main() {
|
|
|
51
38
|
const tableMap = buildTableMap(rows);
|
|
52
39
|
// Filter tables if --tables flag is provided
|
|
53
40
|
const tableNames = cliArgs.tables;
|
|
54
|
-
if (tableNames) {
|
|
41
|
+
if (tableNames.length) {
|
|
55
42
|
for (const schemaName of Object.keys(tableMap)) {
|
|
56
43
|
if (!tableNames.includes(tableMap[schemaName].name)) {
|
|
57
44
|
delete tableMap[schemaName];
|
|
@@ -67,10 +54,10 @@ async function main() {
|
|
|
67
54
|
let untouched = 0;
|
|
68
55
|
const generatedFiles = new Set();
|
|
69
56
|
for (const schemaName of Object.keys(tableMap)) {
|
|
70
|
-
const { name: tableName, fields } = tableMap[schemaName];
|
|
57
|
+
const { name: tableName, fields, colMap } = tableMap[schemaName];
|
|
71
58
|
const filename = path.join(schemasDir, `${schemaName}.ts`);
|
|
72
59
|
generatedFiles.add(`${schemaName}.ts`);
|
|
73
|
-
const content = generateSchemaFile(schemaName, tableName, fields);
|
|
60
|
+
const content = generateSchemaFile(schemaName, tableName, fields, colMap);
|
|
74
61
|
let status = 'created';
|
|
75
62
|
let color = CONSOLE_COLORS.green;
|
|
76
63
|
if (fs.existsSync(filename)) {
|
|
@@ -94,7 +81,7 @@ async function main() {
|
|
|
94
81
|
}
|
|
95
82
|
}
|
|
96
83
|
// Remove orphan Schema*.ts files (only when generating all tables)
|
|
97
|
-
if (!tableNames) {
|
|
84
|
+
if (!tableNames.length) {
|
|
98
85
|
const existingFiles = fs.readdirSync(schemasDir);
|
|
99
86
|
for (const file of existingFiles) {
|
|
100
87
|
if (file.startsWith('Schema') && file.endsWith('.ts') && !generatedFiles.has(file)) {
|
|
@@ -115,8 +102,4 @@ async function main() {
|
|
|
115
102
|
if (!somethingTouched) {
|
|
116
103
|
display('All schemas are already up to date.', CONSOLE_COLORS.magenta);
|
|
117
104
|
}
|
|
118
|
-
}
|
|
119
|
-
main().catch((e) => {
|
|
120
|
-
error(`Error: ${e.message}`);
|
|
121
|
-
process.exit(1);
|
|
122
105
|
});
|
|
@@ -3,8 +3,7 @@ import * as fs from 'node:fs';
|
|
|
3
3
|
import * as path from 'node:path';
|
|
4
4
|
import { loadConfig } from '../lib/cli/config.js';
|
|
5
5
|
import { parseSchemaFile, generateSingleTableFile, generateDbTablesIndex } from '../lib/cli/tables-codegen.js';
|
|
6
|
-
import { loadEnvFile, CONSOLE_COLORS, display, displayAsTableRow, error } from './utils.js';
|
|
7
|
-
loadEnvFile();
|
|
6
|
+
import { loadEnvFile, CONSOLE_COLORS, display, displayAsTableRow, error, parseArgs, runCli } from './utils.js';
|
|
8
7
|
function printHelp() {
|
|
9
8
|
console.log('');
|
|
10
9
|
display('Usage:', CONSOLE_COLORS.yellow);
|
|
@@ -23,39 +22,21 @@ function printHelp() {
|
|
|
23
22
|
display('Table*.ts files are only created if they do not already exist.', CONSOLE_COLORS.magenta);
|
|
24
23
|
display('dbTables.ts is always regenerated to include all schemas.', CONSOLE_COLORS.magenta);
|
|
25
24
|
}
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
else if (args[i] === '--all') {
|
|
34
|
-
result.all = true;
|
|
35
|
-
}
|
|
36
|
-
else if (!args[i].startsWith('--')) {
|
|
37
|
-
// Split by comma to support both "a b" and "a,b" and "a, b"
|
|
38
|
-
for (const part of args[i].split(',')) {
|
|
39
|
-
const trimmed = part.trim();
|
|
40
|
-
if (trimmed)
|
|
41
|
-
result.tables.push(trimmed);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
return result;
|
|
46
|
-
}
|
|
47
|
-
async function main() {
|
|
48
|
-
const cliArgs = parseCliArgs();
|
|
25
|
+
await runCli('fastify-auto-sqlapi: generating tables template', async () => {
|
|
26
|
+
const cliArgs = parseArgs({
|
|
27
|
+
output: { type: 'value' },
|
|
28
|
+
all: { type: 'flag' },
|
|
29
|
+
tables: { type: 'list' },
|
|
30
|
+
});
|
|
49
31
|
if (!cliArgs.all && cliArgs.tables.length === 0) {
|
|
50
|
-
display('++++++ fastify-auto-sqlapi: generate tables template ++++++', CONSOLE_COLORS.yellow);
|
|
51
32
|
printHelp();
|
|
52
33
|
process.exit(1);
|
|
53
34
|
}
|
|
54
|
-
display('++++++ fastify-auto-sqlapi: generating tables template ++++++', CONSOLE_COLORS.yellow);
|
|
55
35
|
const config = await loadConfig();
|
|
36
|
+
loadEnvFile(config.envFile);
|
|
56
37
|
const outputDir = path.resolve(process.cwd(), cliArgs.output || config.outputDir);
|
|
57
|
-
const schemasDir = outputDir;
|
|
58
|
-
const tablesDir = outputDir;
|
|
38
|
+
const schemasDir = path.join(outputDir, 'schemas');
|
|
39
|
+
const tablesDir = path.join(outputDir, 'tables');
|
|
59
40
|
if (!fs.existsSync(schemasDir)) {
|
|
60
41
|
error(`Schemas directory not found: ${schemasDir}`);
|
|
61
42
|
display('Run sqlapi-generate-schema first.', CONSOLE_COLORS.magenta);
|
|
@@ -128,8 +109,4 @@ async function main() {
|
|
|
128
109
|
}
|
|
129
110
|
console.log('');
|
|
130
111
|
display('Edit the generated Table*.ts files to customize your table configuration.', CONSOLE_COLORS.magenta);
|
|
131
|
-
}
|
|
132
|
-
main().catch((e) => {
|
|
133
|
-
error(`Error: ${e.message}`);
|
|
134
|
-
process.exit(1);
|
|
135
112
|
});
|
package/dist/bin/utils.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Load .env file from cwd if it exists.
|
|
3
3
|
* Does not override already-set environment variables.
|
|
4
4
|
*/
|
|
5
|
-
export declare function loadEnvFile(): void;
|
|
5
|
+
export declare function loadEnvFile(envFile?: string): void;
|
|
6
6
|
export declare const CONSOLE_COLORS: {
|
|
7
7
|
readonly black: 30;
|
|
8
8
|
readonly gray: 90;
|
|
@@ -15,4 +15,32 @@ export declare const CONSOLE_COLORS: {
|
|
|
15
15
|
export declare function displayAsTableRow(pref: string, value: string, distance: number, color?: number): void;
|
|
16
16
|
export declare function display(text: string, color?: number): void;
|
|
17
17
|
export declare function error(text: string): void;
|
|
18
|
+
type ArgSpec = {
|
|
19
|
+
type: 'value';
|
|
20
|
+
} | {
|
|
21
|
+
type: 'flag';
|
|
22
|
+
} | {
|
|
23
|
+
type: 'list';
|
|
24
|
+
};
|
|
25
|
+
type ArgValue<S extends ArgSpec> = S['type'] extends 'flag' ? boolean : S['type'] extends 'list' ? string[] : string | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* Tiny declarative argv parser for the bundled CLIs.
|
|
28
|
+
* - `value` → recognized as `--name X`, last value wins
|
|
29
|
+
* - `flag` → recognized as `--name`, default false
|
|
30
|
+
* - `list` → comma-separated `--name a,b,c`; can also accept positional comma-/space- separated tokens
|
|
31
|
+
*
|
|
32
|
+
* Positional tokens (non-`--`) are accumulated into `positional`. List specs auto-merge those tokens
|
|
33
|
+
* (split on ',') into the list as well, supporting both "a b" and "a,b" CLI shapes.
|
|
34
|
+
*/
|
|
35
|
+
export declare function parseArgs<S extends Record<string, ArgSpec>>(spec: S, argv?: string[]): {
|
|
36
|
+
[K in keyof S]: ArgValue<S[K]>;
|
|
37
|
+
} & {
|
|
38
|
+
positional: string[];
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* CLI entry-point wrapper: prints a header, awaits `fn`, and turns thrown errors into a red message
|
|
42
|
+
* with a non-zero exit code (without aborting the process synchronously, so unfinished stdout flushes).
|
|
43
|
+
*/
|
|
44
|
+
export declare function runCli(name: string, fn: () => Promise<void>): Promise<void>;
|
|
45
|
+
export {};
|
|
18
46
|
//# sourceMappingURL=utils.d.ts.map
|
package/dist/bin/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/bin/utils.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,WAAW,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/bin/utils.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAqBlD;AAED,eAAO,MAAM,cAAc;;;;;;;;CAQjB,CAAC;AAEX,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,KAAK,GAAE,MAAU,GAChB,IAAI,CAQN;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,GAAE,MAAU,GAAG,IAAI,CAE7D;AAED,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAExC;AAED,KAAK,OAAO,GACR;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAErB,KAAK,QAAQ,CAAC,CAAC,SAAS,OAAO,IAC7B,CAAC,CAAC,MAAM,CAAC,SAAS,MAAM,GAAG,OAAO,GAClC,CAAC,CAAC,MAAM,CAAC,SAAS,MAAM,GAAG,MAAM,EAAE,GACnC,MAAM,GAAG,SAAS,CAAC;AAErB;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACzD,IAAI,EAAE,CAAC,EACP,IAAI,WAAwB,GAC3B;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,GAAG;IAAE,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,CAyC/D;AAED;;;GAGG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAQjF"}
|
package/dist/bin/utils.js
CHANGED
|
@@ -4,8 +4,8 @@ import { resolve } from 'node:path';
|
|
|
4
4
|
* Load .env file from cwd if it exists.
|
|
5
5
|
* Does not override already-set environment variables.
|
|
6
6
|
*/
|
|
7
|
-
export function loadEnvFile() {
|
|
8
|
-
const envPath = resolve(process.cwd(), '.env');
|
|
7
|
+
export function loadEnvFile(envFile) {
|
|
8
|
+
const envPath = resolve(process.cwd(), envFile || '.env');
|
|
9
9
|
if (!existsSync(envPath))
|
|
10
10
|
return;
|
|
11
11
|
const content = readFileSync(envPath, 'utf-8');
|
|
@@ -52,3 +52,72 @@ export function display(text, color = 0) {
|
|
|
52
52
|
export function error(text) {
|
|
53
53
|
display(text, CONSOLE_COLORS.red);
|
|
54
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* Tiny declarative argv parser for the bundled CLIs.
|
|
57
|
+
* - `value` → recognized as `--name X`, last value wins
|
|
58
|
+
* - `flag` → recognized as `--name`, default false
|
|
59
|
+
* - `list` → comma-separated `--name a,b,c`; can also accept positional comma-/space- separated tokens
|
|
60
|
+
*
|
|
61
|
+
* Positional tokens (non-`--`) are accumulated into `positional`. List specs auto-merge those tokens
|
|
62
|
+
* (split on ',') into the list as well, supporting both "a b" and "a,b" CLI shapes.
|
|
63
|
+
*/
|
|
64
|
+
export function parseArgs(spec, argv = process.argv.slice(2)) {
|
|
65
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
66
|
+
const out = { positional: [] };
|
|
67
|
+
for (const [name, def] of Object.entries(spec)) {
|
|
68
|
+
out[name] = def.type === 'flag' ? false : def.type === 'list' ? [] : undefined;
|
|
69
|
+
}
|
|
70
|
+
for (let i = 0; i < argv.length; i++) {
|
|
71
|
+
const token = argv[i];
|
|
72
|
+
if (token.startsWith('--')) {
|
|
73
|
+
const name = token.slice(2);
|
|
74
|
+
const def = spec[name];
|
|
75
|
+
if (!def)
|
|
76
|
+
continue;
|
|
77
|
+
if (def.type === 'flag') {
|
|
78
|
+
out[name] = true;
|
|
79
|
+
}
|
|
80
|
+
else if (def.type === 'value' && i + 1 < argv.length) {
|
|
81
|
+
out[name] = argv[++i];
|
|
82
|
+
}
|
|
83
|
+
else if (def.type === 'list' && i + 1 < argv.length) {
|
|
84
|
+
const next = argv[++i];
|
|
85
|
+
for (const part of next.split(',')) {
|
|
86
|
+
const t = part.trim();
|
|
87
|
+
if (t)
|
|
88
|
+
out[name].push(t);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
out.positional.push(token);
|
|
94
|
+
// Auto-distribute positional values into the (single) list spec, if any
|
|
95
|
+
for (const [n, def] of Object.entries(spec)) {
|
|
96
|
+
if (def.type === 'list') {
|
|
97
|
+
for (const part of token.split(',')) {
|
|
98
|
+
const t = part.trim();
|
|
99
|
+
if (t)
|
|
100
|
+
out[n].push(t);
|
|
101
|
+
}
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
108
|
+
return out;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* CLI entry-point wrapper: prints a header, awaits `fn`, and turns thrown errors into a red message
|
|
112
|
+
* with a non-zero exit code (without aborting the process synchronously, so unfinished stdout flushes).
|
|
113
|
+
*/
|
|
114
|
+
export async function runCli(name, fn) {
|
|
115
|
+
display(`++++++ ${name} ++++++`, CONSOLE_COLORS.yellow);
|
|
116
|
+
try {
|
|
117
|
+
await fn();
|
|
118
|
+
}
|
|
119
|
+
catch (e) {
|
|
120
|
+
error(`Error: ${e.message ?? String(e)}`);
|
|
121
|
+
process.exitCode = 1;
|
|
122
|
+
}
|
|
123
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -30,5 +30,5 @@ export { BulkDeleteTableBody, BulkDeleteTableResponse } from './lib/schema/bulk-
|
|
|
30
30
|
export { default as bulkDeleteRoutes } from './routes/auto/bulk-delete.routes.js';
|
|
31
31
|
export { Type, type Static } from '@sinclair/typebox';
|
|
32
32
|
export { ConditionBuilder, Expression } from 'node-condition-builder';
|
|
33
|
-
export type { SqlApiConfig, ColumnInfo, TableMap, Queryable, SqlResult, DbRecord, DbRecordValue, SelectOptions, SchemaDefinition, JoinDefinition, ITable, DbTables, SqlApiPluginOptions, SwaggerOptions, SearchParams, SearchResult, Paginator, PaginationResult, TableFilterFn, ExtendedConditionFn, FilterRecord, AggregationRequest, JoinGroupRequest, GetParams, GetResult, DeleteParams, DeleteResult, InsertParams, InsertResult, BulkUpsertItem, BulkUpsertParams, BulkUpsertResult, BulkDeleteParams, BulkDeleteResult, ConditionMethod, SearchCondition, UpdateParams, UpdateResult, TenantId, TenantScope, TenantScopeDirect, TenantScopeIndirect, TenantContext, ValidationError, ValidatorFn, BulkValidatorItem, BulkValidatorFn, } from './types.js';
|
|
33
|
+
export type { SqlApiConfig, ColumnInfo, TableMap, Queryable, SqlResult, DbRecord, DbRecordValue, SelectOptions, SchemaDefinition, JoinDefinition, ITable, DbTables, SqlApiPluginOptions, SwaggerOptions, SearchParams, SearchResult, Paginator, PaginationResult, TableFilterFn, ExtendedConditionFn, FilterRecord, AggregationRequest, JoinGroupRequest, ComputedFieldFn, ComputedFieldContext, ComputedFieldExpr, GetParams, GetResult, DeleteParams, DeleteResult, InsertParams, InsertResult, BulkUpsertItem, BulkUpsertParams, BulkUpsertResult, BulkDeleteParams, BulkDeleteResult, ConditionMethod, SearchCondition, UpdateParams, UpdateResult, TenantId, TenantScope, TenantScopeDirect, TenantScopeIndirect, TenantContext, ValidationError, ValidatorFn, BulkValidatorItem, BulkValidatorFn, } from './types.js';
|
|
34
34
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Load an optional peer dependency by trying the consumer's CWD first
|
|
3
|
+
* (so it works when installed via `npm install`/`npm link`), then falling
|
|
4
|
+
* back to the plugin's own `node_modules` (so it works in the plugin's own tests).
|
|
5
|
+
* Throws a friendly error if neither succeeds.
|
|
6
|
+
*/
|
|
7
|
+
export declare function loadOptionalDependency<T = unknown>(modulePath: string, installHint: string): T;
|
|
8
|
+
//# sourceMappingURL=load-dependency.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-dependency.d.ts","sourceRoot":"","sources":["../../../src/lib/cli/load-dependency.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,GAAG,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,CAAC,CAW9F"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
/**
|
|
3
|
+
* Load an optional peer dependency by trying the consumer's CWD first
|
|
4
|
+
* (so it works when installed via `npm install`/`npm link`), then falling
|
|
5
|
+
* back to the plugin's own `node_modules` (so it works in the plugin's own tests).
|
|
6
|
+
* Throws a friendly error if neither succeeds.
|
|
7
|
+
*/
|
|
8
|
+
export function loadOptionalDependency(modulePath, installHint) {
|
|
9
|
+
try {
|
|
10
|
+
return createRequire(process.cwd() + '/noop.js')(modulePath);
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
/* fall through to local require */
|
|
14
|
+
}
|
|
15
|
+
try {
|
|
16
|
+
return createRequire(import.meta.url)(modulePath);
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
throw new Error(`${modulePath} is required. Install it with: ${installHint}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mysql-introspect.d.ts","sourceRoot":"","sources":["../../../src/lib/cli/mysql-introspect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,wBAAgB,0BAA0B,IAAI;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAmBA;AAkDD,wBAAsB,qBAAqB,CACzC,gBAAgB,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,EAClG,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,UAAU,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"mysql-introspect.d.ts","sourceRoot":"","sources":["../../../src/lib/cli/mysql-introspect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,wBAAgB,0BAA0B,IAAI;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAmBA;AAkDD,wBAAsB,qBAAqB,CACzC,gBAAgB,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,EAClG,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,UAAU,EAAE,CAAC,CAyBvB"}
|