db-model-router 1.0.9 → 1.0.11
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/.codegraph/config.json +143 -0
- package/CLAUDE.md +150 -0
- package/dbmr.schema.json +3 -0
- package/docs/dbmr-schema-spec.md +597 -393
- package/package.json +1 -1
- package/skill/SKILL.md +1 -1
- package/skill/references/dbmr-schema-spec.md +597 -0
- package/src/cli/commands/generate.js +6 -6
- package/src/cli/diff-engine.js +4 -4
- package/src/cli/generate-migration.js +4 -0
- package/src/cli/generate-route.js +3 -3
- package/src/schema/schema-validator.js +1 -1
- package/.env +0 -7
- package/db-manager/.dbmanager.sqlite +0 -0
- package/db-manager/.dbmanager.sqlite-shm +0 -0
- package/db-manager/.dbmanager.sqlite-wal +0 -0
- package/db-manager/demo/cockroachdb.env +0 -6
- package/db-manager/demo/demo.sqlite +0 -0
- package/db-manager/demo/dynamodb.env +0 -7
- package/db-manager/demo/mongodb.env +0 -4
- package/db-manager/demo/mssql.env +0 -6
- package/db-manager/demo/mysql.env +0 -6
- package/db-manager/demo/oracle.env +0 -6
- package/db-manager/demo/postgres.env +0 -6
- package/db-manager/demo/redis.env +0 -4
- package/db-manager/demo/seeds/cockroachdb.sql +0 -32
- package/db-manager/demo/seeds/mssql.sql +0 -32
- package/db-manager/demo/seeds/mysql.sql +0 -32
- package/db-manager/demo/seeds/oracle.sql +0 -43
- package/db-manager/demo/seeds/postgres.sql +0 -32
- package/db-manager/demo/seeds/sqlite3.sql +0 -32
- package/db-manager/demo/sqlite3.env +0 -2
- package/demo/.dockerignore +0 -7
- package/demo/.env.example +0 -15
- package/demo/Dockerfile +0 -20
- package/demo/app.js +0 -39
- package/demo/commons/add_migration.js +0 -43
- package/demo/commons/db.js +0 -17
- package/demo/commons/migrate.js +0 -68
- package/demo/commons/modules.js +0 -18
- package/demo/commons/password.js +0 -36
- package/demo/commons/security.js +0 -30
- package/demo/commons/session.js +0 -13
- package/demo/commons/webhook.js +0 -81
- package/demo/dbmr.schema.json +0 -338
- package/demo/middleware/authenticate.js +0 -14
- package/demo/middleware/hasPermission.js +0 -30
- package/demo/middleware/logger.js +0 -67
- package/demo/middleware/tenantIsolation.js +0 -19
- package/demo/migrations/20260510193736_create_migrations_table.sql +0 -6
- package/demo/migrations/20260510193737_create_saas_tables.sql +0 -69
- package/demo/migrations/20260510193737_create_tables.sql +0 -193
- package/demo/models/addresses.js +0 -24
- package/demo/models/cart_items.js +0 -20
- package/demo/models/carts.js +0 -18
- package/demo/models/categories.js +0 -22
- package/demo/models/coupons.js +0 -25
- package/demo/models/index.js +0 -43
- package/demo/models/order_items.js +0 -23
- package/demo/models/orders.js +0 -27
- package/demo/models/payments.js +0 -23
- package/demo/models/product_images.js +0 -20
- package/demo/models/product_reviews.js +0 -22
- package/demo/models/product_variants.js +0 -22
- package/demo/models/products.js +0 -32
- package/demo/models/role_permissions.js +0 -17
- package/demo/models/roles.js +0 -17
- package/demo/models/shipments.js +0 -21
- package/demo/models/tenants.js +0 -18
- package/demo/models/users.js +0 -23
- package/demo/models/webhook_logs.js +0 -22
- package/demo/models/webhooks.js +0 -19
- package/demo/models/wishlists.js +0 -17
- package/demo/openapi.json +0 -7000
- package/demo/package-lock.json +0 -3972
- package/demo/package.json +0 -46
- package/demo/routes/addresses/index.js +0 -10
- package/demo/routes/auth/index.js +0 -55
- package/demo/routes/carts/cart_items/index.js +0 -11
- package/demo/routes/carts/index.js +0 -14
- package/demo/routes/categories/index.js +0 -10
- package/demo/routes/coupons/index.js +0 -10
- package/demo/routes/docs.js +0 -18
- package/demo/routes/health.js +0 -35
- package/demo/routes/index.js +0 -40
- package/demo/routes/orders/index.js +0 -18
- package/demo/routes/orders/order_items/index.js +0 -11
- package/demo/routes/orders/payments/index.js +0 -11
- package/demo/routes/orders/shipments/index.js +0 -11
- package/demo/routes/products/index.js +0 -18
- package/demo/routes/products/product_images/index.js +0 -11
- package/demo/routes/products/product_reviews/index.js +0 -11
- package/demo/routes/products/product_variants/index.js +0 -11
- package/demo/routes/roles/index.js +0 -75
- package/demo/routes/roles/permissions/index.js +0 -47
- package/demo/routes/tenants/index.js +0 -45
- package/demo/routes/users/index.js +0 -45
- package/demo/routes/wishlists/index.js +0 -10
- package/demo/seeds/saas-seed.js +0 -329
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"include": [
|
|
4
|
+
"**/*.ts",
|
|
5
|
+
"**/*.tsx",
|
|
6
|
+
"**/*.js",
|
|
7
|
+
"**/*.jsx",
|
|
8
|
+
"**/*.py",
|
|
9
|
+
"**/*.go",
|
|
10
|
+
"**/*.rs",
|
|
11
|
+
"**/*.java",
|
|
12
|
+
"**/*.c",
|
|
13
|
+
"**/*.h",
|
|
14
|
+
"**/*.cpp",
|
|
15
|
+
"**/*.hpp",
|
|
16
|
+
"**/*.cc",
|
|
17
|
+
"**/*.cxx",
|
|
18
|
+
"**/*.cs",
|
|
19
|
+
"**/*.php",
|
|
20
|
+
"**/*.rb",
|
|
21
|
+
"**/*.swift",
|
|
22
|
+
"**/*.kt",
|
|
23
|
+
"**/*.kts",
|
|
24
|
+
"**/*.dart",
|
|
25
|
+
"**/*.svelte",
|
|
26
|
+
"**/*.vue",
|
|
27
|
+
"**/*.liquid",
|
|
28
|
+
"**/*.pas",
|
|
29
|
+
"**/*.dpr",
|
|
30
|
+
"**/*.dpk",
|
|
31
|
+
"**/*.lpr",
|
|
32
|
+
"**/*.dfm",
|
|
33
|
+
"**/*.fmx",
|
|
34
|
+
"**/*.scala",
|
|
35
|
+
"**/*.sc"
|
|
36
|
+
],
|
|
37
|
+
"exclude": [
|
|
38
|
+
"**/.git/**",
|
|
39
|
+
"**/node_modules/**",
|
|
40
|
+
"**/vendor/**",
|
|
41
|
+
"**/Pods/**",
|
|
42
|
+
"**/dist/**",
|
|
43
|
+
"**/build/**",
|
|
44
|
+
"**/out/**",
|
|
45
|
+
"**/bin/**",
|
|
46
|
+
"**/obj/**",
|
|
47
|
+
"**/target/**",
|
|
48
|
+
"**/*.min.js",
|
|
49
|
+
"**/*.bundle.js",
|
|
50
|
+
"**/.next/**",
|
|
51
|
+
"**/.nuxt/**",
|
|
52
|
+
"**/.svelte-kit/**",
|
|
53
|
+
"**/.output/**",
|
|
54
|
+
"**/.turbo/**",
|
|
55
|
+
"**/.cache/**",
|
|
56
|
+
"**/.parcel-cache/**",
|
|
57
|
+
"**/.vite/**",
|
|
58
|
+
"**/.astro/**",
|
|
59
|
+
"**/.docusaurus/**",
|
|
60
|
+
"**/.gatsby/**",
|
|
61
|
+
"**/.webpack/**",
|
|
62
|
+
"**/.nx/**",
|
|
63
|
+
"**/.yarn/cache/**",
|
|
64
|
+
"**/.pnpm-store/**",
|
|
65
|
+
"**/storybook-static/**",
|
|
66
|
+
"**/.expo/**",
|
|
67
|
+
"**/web-build/**",
|
|
68
|
+
"**/ios/Pods/**",
|
|
69
|
+
"**/ios/build/**",
|
|
70
|
+
"**/android/build/**",
|
|
71
|
+
"**/android/.gradle/**",
|
|
72
|
+
"**/__pycache__/**",
|
|
73
|
+
"**/.venv/**",
|
|
74
|
+
"**/venv/**",
|
|
75
|
+
"**/site-packages/**",
|
|
76
|
+
"**/dist-packages/**",
|
|
77
|
+
"**/.pytest_cache/**",
|
|
78
|
+
"**/.mypy_cache/**",
|
|
79
|
+
"**/.ruff_cache/**",
|
|
80
|
+
"**/.tox/**",
|
|
81
|
+
"**/.nox/**",
|
|
82
|
+
"**/*.egg-info/**",
|
|
83
|
+
"**/.eggs/**",
|
|
84
|
+
"**/go/pkg/mod/**",
|
|
85
|
+
"**/target/debug/**",
|
|
86
|
+
"**/target/release/**",
|
|
87
|
+
"**/.gradle/**",
|
|
88
|
+
"**/.m2/**",
|
|
89
|
+
"**/generated-sources/**",
|
|
90
|
+
"**/.kotlin/**",
|
|
91
|
+
"**/.dart_tool/**",
|
|
92
|
+
"**/.vs/**",
|
|
93
|
+
"**/.nuget/**",
|
|
94
|
+
"**/artifacts/**",
|
|
95
|
+
"**/publish/**",
|
|
96
|
+
"**/cmake-build-*/**",
|
|
97
|
+
"**/CMakeFiles/**",
|
|
98
|
+
"**/bazel-*/**",
|
|
99
|
+
"**/vcpkg_installed/**",
|
|
100
|
+
"**/.conan/**",
|
|
101
|
+
"**/Debug/**",
|
|
102
|
+
"**/Release/**",
|
|
103
|
+
"**/x64/**",
|
|
104
|
+
"**/.pio/**",
|
|
105
|
+
"**/release/**",
|
|
106
|
+
"**/*.app/**",
|
|
107
|
+
"**/*.asar",
|
|
108
|
+
"**/DerivedData/**",
|
|
109
|
+
"**/.build/**",
|
|
110
|
+
"**/.swiftpm/**",
|
|
111
|
+
"**/xcuserdata/**",
|
|
112
|
+
"**/Carthage/Build/**",
|
|
113
|
+
"**/SourcePackages/**",
|
|
114
|
+
"**/__history/**",
|
|
115
|
+
"**/__recovery/**",
|
|
116
|
+
"**/*.dcu",
|
|
117
|
+
"**/.composer/**",
|
|
118
|
+
"**/storage/framework/**",
|
|
119
|
+
"**/bootstrap/cache/**",
|
|
120
|
+
"**/.bundle/**",
|
|
121
|
+
"**/tmp/cache/**",
|
|
122
|
+
"**/public/assets/**",
|
|
123
|
+
"**/public/packs/**",
|
|
124
|
+
"**/.yardoc/**",
|
|
125
|
+
"**/coverage/**",
|
|
126
|
+
"**/htmlcov/**",
|
|
127
|
+
"**/.nyc_output/**",
|
|
128
|
+
"**/test-results/**",
|
|
129
|
+
"**/.coverage/**",
|
|
130
|
+
"**/.idea/**",
|
|
131
|
+
"**/logs/**",
|
|
132
|
+
"**/tmp/**",
|
|
133
|
+
"**/temp/**",
|
|
134
|
+
"**/_build/**",
|
|
135
|
+
"**/docs/_build/**",
|
|
136
|
+
"**/site/**"
|
|
137
|
+
],
|
|
138
|
+
"languages": [],
|
|
139
|
+
"frameworks": [],
|
|
140
|
+
"maxFileSize": 1048576,
|
|
141
|
+
"extractDocstrings": true,
|
|
142
|
+
"trackCallSites": true
|
|
143
|
+
}
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
`db-model-router` is a database-agnostic REST API generator for Node.js. It generates CRUD Express routes from a model schema and supports 9+ database adapters (mysql, postgres, sqlite3, mongodb, mssql, cockroachdb, oracle, redis, dynamodb). It also provides a schema-driven CLI that scaffolds projects, introspects live databases, and generates models/routes/tests/OpenAPI specs.
|
|
8
|
+
|
|
9
|
+
## Common Commands
|
|
10
|
+
|
|
11
|
+
| Command | Description |
|
|
12
|
+
|---------|-------------|
|
|
13
|
+
| `npm run dev` | Start the development server (`nodemon src/serve.js`) |
|
|
14
|
+
| `npm test` | Run tests with the default env (`env/.env.default`, targets MySQL) |
|
|
15
|
+
| `npm run test:sqlite3` | Run SQLite3 adapter tests |
|
|
16
|
+
| `npm run test:mysql` | Run MySQL adapter tests |
|
|
17
|
+
| `npm run test:postgres` | Run PostgreSQL adapter tests |
|
|
18
|
+
| `npm run test:mongodb` | Run MongoDB adapter tests |
|
|
19
|
+
| `npm run test:dynamodb` | Run DynamoDB adapter tests |
|
|
20
|
+
| `npm run test:redis` | Run Redis adapter tests |
|
|
21
|
+
| `npm run test:mssql` | Run MSSQL adapter tests |
|
|
22
|
+
| `npm run test:oracle` | Run Oracle adapter tests |
|
|
23
|
+
| `npm run test:cockroachdb` | Run CockroachDB adapter tests |
|
|
24
|
+
| `npm run test:kafka` | Run Kafka tests |
|
|
25
|
+
| `npm run test:properties` | Run property-based tests (fast-check) |
|
|
26
|
+
| `npm run test:command` | Run CLI command tests |
|
|
27
|
+
| `npm run test:all` | Run all adapter + property + function + command tests |
|
|
28
|
+
| `npm run demo:clear` | Clear the `demo/` directory |
|
|
29
|
+
| `npm run demo:create` | Populate the `demo/` directory with sample files |
|
|
30
|
+
|
|
31
|
+
**Running a single test file:**
|
|
32
|
+
```bash
|
|
33
|
+
# Example: run only the MySQL individual adapter tests
|
|
34
|
+
dotenv -e env/.env.mysql -- mocha test/adapters/mysql.individual.test.js --timeout 15000 --exit
|
|
35
|
+
|
|
36
|
+
# Example: run a single CLI command test
|
|
37
|
+
dotenv -e env/.env.default -- mocha test/commands/generate.test.js --timeout 30000 --exit
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**Running tests with a specific database:**
|
|
41
|
+
Tests load DB credentials from `env/.env.<adapter>`. Docker Compose provides local instances of all databases (see `docker-compose.yml`).
|
|
42
|
+
|
|
43
|
+
**Running a single test within a file:**
|
|
44
|
+
```bash
|
|
45
|
+
dotenv -e env/.env.sqlite3 -- mocha test/adapters/sqlite3.individual.test.js --grep "insert" --timeout 15000 --exit
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## High-Level Architecture
|
|
49
|
+
|
|
50
|
+
### Core Runtime (`src/`)
|
|
51
|
+
|
|
52
|
+
The library follows a **singleton adapter pattern**:
|
|
53
|
+
|
|
54
|
+
1. **`src/index.js`** — Main entry. Exports `init(adapterName)`, `db` (lazy singleton), `model`, `route`, `kafka`. Calling `init("postgres")` loads the corresponding adapter module into the `db` singleton.
|
|
55
|
+
2. **`src/commons/model.js`** — The `model(db, table, structure, pk, uniqueKeys, option)` factory returns an object with async methods: `insert`, `update`, `upsert`, `remove`, `byId`, `find`, `findOne`, `list`, `patch`. This is the **universal model API**; it is identical across all adapters.
|
|
56
|
+
3. **`src/commons/route.js`** — The `route(model, override)` factory returns an Express `Router` with 9 standard endpoints (GET/POST/PUT/PATCH/DELETE for `/:id` and `/`). `override` injects request-derived values into payloads (e.g., `{ user_id: "user.user_id" }`).
|
|
57
|
+
4. **`src/commons/validator.js`** — Input validation using `node-input-validator`, plus the filter parser that converts query-string operators (`!value`, `>value`, `%value%`, `in(a,b)`) into the internal filter array format.
|
|
58
|
+
5. **`src/commons/kafka.js`** — Optional Kafka producer. If `KAFKA_BROKER` is set, write operations in `model.js` call `produce(table, operation, data)` after successful DB commits.
|
|
59
|
+
6. **`src/commons/function.js`** — Shared utilities (`jsonSafeParse`, `jsonStringify`, `getType`, etc.).
|
|
60
|
+
|
|
61
|
+
### Adapter Interface (`src/<adapter>/db.js`)
|
|
62
|
+
|
|
63
|
+
Each adapter must implement a common interface. This is the **only** adapter-specific code:
|
|
64
|
+
|
|
65
|
+
- `connect(credentials)` — initialize connection/pool/client.
|
|
66
|
+
- `get(table, filter, sort, safeDelete)` → `{ data: [...], count: <number> }`
|
|
67
|
+
- `list(table, filter, sort, safeDelete, page, limit)` → `{ data: [...], count: <number> }`
|
|
68
|
+
- `insert(table, data, uniqueKeys)` → `{ id }` or `{ rows, message }`
|
|
69
|
+
- `upsert(table, data, uniqueKeys)` — insert-or-update, bulk-capable.
|
|
70
|
+
- `remove(table, filter, safeDelete)` — hard delete or soft delete.
|
|
71
|
+
- `where(filter, safeDelete)` — internal filter builder (returns `{ query, value }`).
|
|
72
|
+
- `sort_builder(sort)` — internal sort builder.
|
|
73
|
+
|
|
74
|
+
Adapters live in `src/mysql/db.js`, `src/postgres/db.js`, `src/mongodb/db.js`, etc. Non-SQL adapters (MongoDB, Redis, DynamoDB) implement the same interface but translate filters into their native query languages.
|
|
75
|
+
|
|
76
|
+
### Filter System
|
|
77
|
+
|
|
78
|
+
Filters are nested arrays: `[OR_groups[AND_conditions[column, operator, value]]]`.
|
|
79
|
+
|
|
80
|
+
Example:
|
|
81
|
+
```js
|
|
82
|
+
// (name = "Alice") OR (age > 30)
|
|
83
|
+
[[["name", "=", "Alice"]], [["age", ">", 30]]]
|
|
84
|
+
|
|
85
|
+
// (name = "Alice" AND age = 30)
|
|
86
|
+
[[["name", "=", "Alice"], ["age", "=", 30]]]
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Query parameters are auto-parsed by `validator.js` into this structure.
|
|
90
|
+
|
|
91
|
+
### Schema-Driven CLI (`src/cli/`)
|
|
92
|
+
|
|
93
|
+
The CLI is a unified entry point (`src/cli/main.js`) with subcommands:
|
|
94
|
+
|
|
95
|
+
- **`init`** — Scaffold a new project (optionally from `dbmr.schema.json`). Generates ESM project with Docker support, migrations, and optional Loki/Grafana logging.
|
|
96
|
+
- **`inspect`** — Introspect a live database and emit a `dbmr.schema.json` file.
|
|
97
|
+
- **`generate`** — Generate models, routes, tests, OpenAPI spec, migrations, and SaaS structure from a schema file.
|
|
98
|
+
- **`doctor`** — Validate schema, check peer dependencies, verify generated files are in sync.
|
|
99
|
+
- **`diff`** — Preview what `generate` would change without writing files.
|
|
100
|
+
- **`db-manager`** — Launch a built-in database management UI.
|
|
101
|
+
- **`help`** — Show detailed per-command help.
|
|
102
|
+
|
|
103
|
+
Key CLI modules:
|
|
104
|
+
- `src/cli/flags.js` — Universal flag parser (`--yes`, `--json`, `--dry-run`, `--no-install`, `--help`) and `OutputContext`.
|
|
105
|
+
- `src/schema/schema-parser.js` / `schema-validator.js` — Parse and validate `dbmr.schema.json`.
|
|
106
|
+
- `src/schema/schema-to-meta.js` — Convert parsed schema into `ModelMeta` objects consumed by generators.
|
|
107
|
+
- `src/cli/generate-model.js`, `generate-route.js`, `generate-openapi.js`, `generate-migration.js` — Code generators.
|
|
108
|
+
- `src/cli/generate-saas-structure.js` — Scaffolds multi-tenant SaaS tables (tenants, users, roles, role_permissions, webhooks, webhook_logs), middleware, and routes.
|
|
109
|
+
|
|
110
|
+
### SaaS Multi-Tenant Structure
|
|
111
|
+
|
|
112
|
+
When `generate` runs (unless `--saas-structure=false`), it injects a complete SaaS backend:
|
|
113
|
+
- Tables: `tenants`, `users`, `roles`, `role_permissions`, `webhooks`, `webhook_logs`
|
|
114
|
+
- Middleware: `authenticate`, `tenantIsolation`, `hasPermission`
|
|
115
|
+
- Routes: `/api/auth`, `/api/users`, `/api/tenants`, `/api/roles`
|
|
116
|
+
- Seeds: Super Admin user + Tenant Admin role template
|
|
117
|
+
|
|
118
|
+
**Important:** Do NOT add `users`, `tenants`, `roles`, or `role_permissions` to `dbmr.schema.json` — they are generated automatically.
|
|
119
|
+
|
|
120
|
+
### DB Manager (`db-manager/`)
|
|
121
|
+
|
|
122
|
+
A standalone Express dashboard for browsing tables, editing rows, running SQL queries, and exporting CSV. Launched via `db-model-router db-manager [--env .env] [--port 4000]`.
|
|
123
|
+
|
|
124
|
+
### Test Architecture
|
|
125
|
+
|
|
126
|
+
Tests use **Mocha** + **Supertest** + **assert**.
|
|
127
|
+
|
|
128
|
+
- `test/adapters/<adapter>.individual.test.js` — CRUD operations per adapter.
|
|
129
|
+
- `test/adapters/<adapter>.bulk.test.js` — Bulk insert/update/delete per adapter.
|
|
130
|
+
- `test/adapters/<adapter>.route.test.js` — HTTP route tests per adapter.
|
|
131
|
+
- `test/properties/*.property.test.js` — Property-based tests using `fast-check`.
|
|
132
|
+
- `test/commands/*.test.js` — CLI command tests.
|
|
133
|
+
- `test/integration/` — End-to-end integration tests (schema workflow, DB manager).
|
|
134
|
+
|
|
135
|
+
### Development Server
|
|
136
|
+
|
|
137
|
+
`src/serve.js` is a reference implementation. It:
|
|
138
|
+
1. Auto-detects `ultimate-express` then falls back to `express`.
|
|
139
|
+
2. Calls `init("mysql")` and `db.connect(...)` using `env/.env.default` credentials.
|
|
140
|
+
3. Defines a `test` model and mounts `/test` routes with a payload override for `user_id`.
|
|
141
|
+
|
|
142
|
+
When modifying core behavior, `serve.js` is useful for quick manual verification (`npm run dev`).
|
|
143
|
+
|
|
144
|
+
## Important Patterns
|
|
145
|
+
|
|
146
|
+
- **Peer dependencies:** All database drivers and Express variants are optional peer dependencies. The library throws a helpful `MODULE_NOT_FOUND` message telling the user exactly what to install.
|
|
147
|
+
- **Soft deletes:** Pass `{ safeDelete: "is_deleted" }` as the model option. The adapter's `get`/`list`/`remove` methods automatically filter on `safeDelete = 0` and `remove` becomes an UPDATE when `safeDelete` is set.
|
|
148
|
+
- **Timestamp handling:** `model.js` auto-strips `created_at` / `modified_at` variants from payloads before validation. Adapters do NOT need to handle this.
|
|
149
|
+
- **Bulk chunking:** SQL adapters chunk bulk inserts/updates at 999 rows per statement to stay within parameter limits.
|
|
150
|
+
- **JSON columns:** `object` type columns are stringified on insert/update and parsed on read via `jsonSafeParse` / `jsonStringify` in `function.js`.
|
package/dbmr.schema.json
CHANGED