neoorm 0.8.1 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -5
- package/dist/bin/neoorm.d.ts +1 -1
- package/dist/bin/neoorm.d.ts.map +1 -1
- package/dist/bin/neoorm.js +131 -57
- package/dist/bin/neoorm.js.map +1 -1
- package/dist/codegen/diff-manifest.d.ts.map +1 -1
- package/dist/codegen/diff-manifest.js +106 -4
- package/dist/codegen/diff-manifest.js.map +1 -1
- package/dist/codegen/generate-summary.d.ts +1 -0
- package/dist/codegen/generate-summary.d.ts.map +1 -1
- package/dist/codegen/generate-summary.js +3 -0
- package/dist/codegen/generate-summary.js.map +1 -1
- package/dist/codegen/generate.d.ts +7 -1
- package/dist/codegen/generate.d.ts.map +1 -1
- package/dist/codegen/generate.js +53 -20
- package/dist/codegen/generate.js.map +1 -1
- package/dist/codegen/schema-to-manifest.d.ts.map +1 -1
- package/dist/codegen/schema-to-manifest.js +302 -22
- package/dist/codegen/schema-to-manifest.js.map +1 -1
- package/dist/codegen/validation/emit-elysia.d.ts +4 -0
- package/dist/codegen/validation/emit-elysia.d.ts.map +1 -0
- package/dist/codegen/validation/emit-elysia.js +304 -0
- package/dist/codegen/validation/emit-elysia.js.map +1 -0
- package/dist/codegen/validation/types.d.ts +1 -1
- package/dist/codegen/validation/types.js +1 -1
- package/dist/config.d.ts +2 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +3 -1
- package/dist/config.js.map +1 -1
- package/dist/datasource-provider.d.ts +5 -1
- package/dist/datasource-provider.d.ts.map +1 -1
- package/dist/datasource-provider.js +21 -2
- package/dist/datasource-provider.js.map +1 -1
- package/dist/dialect/column-kind-support.d.ts +9 -0
- package/dist/dialect/column-kind-support.d.ts.map +1 -0
- package/dist/dialect/column-kind-support.js +25 -0
- package/dist/dialect/column-kind-support.js.map +1 -0
- package/dist/dialect/fk.d.ts +30 -1
- package/dist/dialect/fk.d.ts.map +1 -1
- package/dist/dialect/fk.js +113 -0
- package/dist/dialect/fk.js.map +1 -1
- package/dist/dialect/index.d.ts +5 -1
- package/dist/dialect/index.d.ts.map +1 -1
- package/dist/dialect/index.js +4 -0
- package/dist/dialect/index.js.map +1 -1
- package/dist/dialect/mariadb.d.ts +4 -0
- package/dist/dialect/mariadb.d.ts.map +1 -0
- package/dist/dialect/mariadb.js +15 -0
- package/dist/dialect/mariadb.js.map +1 -0
- package/dist/dialect/mariadb.test.d.ts +2 -0
- package/dist/dialect/mariadb.test.d.ts.map +1 -0
- package/dist/dialect/mariadb.test.js +151 -0
- package/dist/dialect/mariadb.test.js.map +1 -0
- package/dist/dialect/mysql-family.d.ts +14 -0
- package/dist/dialect/mysql-family.d.ts.map +1 -0
- package/dist/dialect/mysql-family.js +453 -0
- package/dist/dialect/mysql-family.js.map +1 -0
- package/dist/dialect/mysql.d.ts +6 -0
- package/dist/dialect/mysql.d.ts.map +1 -0
- package/dist/dialect/mysql.js +16 -0
- package/dist/dialect/mysql.js.map +1 -0
- package/dist/dialect/mysql.test.d.ts +2 -0
- package/dist/dialect/mysql.test.d.ts.map +1 -0
- package/dist/dialect/mysql.test.js +211 -0
- package/dist/dialect/mysql.test.js.map +1 -0
- package/dist/dialect/placeholders.d.ts +7 -0
- package/dist/dialect/placeholders.d.ts.map +1 -0
- package/dist/dialect/placeholders.js +18 -0
- package/dist/dialect/placeholders.js.map +1 -0
- package/dist/dialect/postgres.d.ts.map +1 -1
- package/dist/dialect/postgres.js +55 -27
- package/dist/dialect/postgres.js.map +1 -1
- package/dist/dialect/resolve.d.ts +13 -0
- package/dist/dialect/resolve.d.ts.map +1 -0
- package/dist/dialect/resolve.js +66 -0
- package/dist/dialect/resolve.js.map +1 -0
- package/dist/dialect/shared.d.ts +8 -1
- package/dist/dialect/shared.d.ts.map +1 -1
- package/dist/dialect/shared.js +37 -0
- package/dist/dialect/shared.js.map +1 -1
- package/dist/dialect/sqlite.d.ts.map +1 -1
- package/dist/dialect/sqlite.js +50 -18
- package/dist/dialect/sqlite.js.map +1 -1
- package/dist/dialect/sqlite.test.js +43 -1
- package/dist/dialect/sqlite.test.js.map +1 -1
- package/dist/dialect/types.d.ts +46 -3
- package/dist/dialect/types.d.ts.map +1 -1
- package/dist/docs/pages.d.ts.map +1 -1
- package/dist/docs/pages.js +3 -0
- package/dist/docs/pages.js.map +1 -1
- package/dist/docs/render.js +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/init/scaffold.d.ts +2 -1
- package/dist/init/scaffold.d.ts.map +1 -1
- package/dist/init/scaffold.js.map +1 -1
- package/dist/init/templates.d.ts +3 -2
- package/dist/init/templates.d.ts.map +1 -1
- package/dist/init/templates.js +19 -10
- package/dist/init/templates.js.map +1 -1
- package/dist/introspect/group-fks.d.ts +24 -0
- package/dist/introspect/group-fks.d.ts.map +1 -0
- package/dist/introspect/group-fks.js +48 -0
- package/dist/introspect/group-fks.js.map +1 -0
- package/dist/introspect/mysql/to-manifest.d.ts +4 -0
- package/dist/introspect/mysql/to-manifest.d.ts.map +1 -0
- package/dist/introspect/mysql/to-manifest.js +317 -0
- package/dist/introspect/mysql/to-manifest.js.map +1 -0
- package/dist/introspect/pull.d.ts +1 -0
- package/dist/introspect/pull.d.ts.map +1 -1
- package/dist/introspect/pull.js +179 -6
- package/dist/introspect/pull.js.map +1 -1
- package/dist/introspect/queries.d.ts +10 -1
- package/dist/introspect/queries.d.ts.map +1 -1
- package/dist/introspect/queries.js +41 -11
- package/dist/introspect/queries.js.map +1 -1
- package/dist/introspect/sqlite/to-manifest.d.ts.map +1 -1
- package/dist/introspect/sqlite/to-manifest.js +99 -26
- package/dist/introspect/sqlite/to-manifest.js.map +1 -1
- package/dist/introspect/to-manifest.d.ts.map +1 -1
- package/dist/introspect/to-manifest.js +145 -26
- package/dist/introspect/to-manifest.js.map +1 -1
- package/dist/migrate/dev-lock.d.ts +15 -0
- package/dist/migrate/dev-lock.d.ts.map +1 -0
- package/dist/migrate/dev-lock.js +101 -0
- package/dist/migrate/dev-lock.js.map +1 -0
- package/dist/migrate/runner.d.ts.map +1 -1
- package/dist/migrate/runner.js +143 -51
- package/dist/migrate/runner.js.map +1 -1
- package/dist/plugins/builtin.d.ts +42 -0
- package/dist/plugins/builtin.d.ts.map +1 -1
- package/dist/plugins/builtin.js +276 -8
- package/dist/plugins/builtin.js.map +1 -1
- package/dist/plugins/json/operators.d.ts.map +1 -1
- package/dist/plugins/json/operators.js +69 -3
- package/dist/plugins/json/operators.js.map +1 -1
- package/dist/plugins/postgis/operators.d.ts.map +1 -1
- package/dist/plugins/postgis/operators.js +15 -3
- package/dist/plugins/postgis/operators.js.map +1 -1
- package/dist/runtime/client.d.ts +31 -4
- package/dist/runtime/client.d.ts.map +1 -1
- package/dist/runtime/client.js +129 -4
- package/dist/runtime/client.js.map +1 -1
- package/dist/runtime/driver.d.ts +2 -0
- package/dist/runtime/driver.d.ts.map +1 -1
- package/dist/runtime/driver.js +12 -0
- package/dist/runtime/driver.js.map +1 -1
- package/dist/runtime/executor.d.ts +1 -0
- package/dist/runtime/executor.d.ts.map +1 -1
- package/dist/runtime/executor.js +7 -1
- package/dist/runtime/executor.js.map +1 -1
- package/dist/runtime/mariadb-driver.d.ts +25 -0
- package/dist/runtime/mariadb-driver.d.ts.map +1 -0
- package/dist/runtime/mariadb-driver.js +103 -0
- package/dist/runtime/mariadb-driver.js.map +1 -0
- package/dist/runtime/mysql-driver.d.ts +25 -0
- package/dist/runtime/mysql-driver.d.ts.map +1 -0
- package/dist/runtime/mysql-driver.js +101 -0
- package/dist/runtime/mysql-driver.js.map +1 -0
- package/dist/runtime/mysql-error.d.ts +15 -0
- package/dist/runtime/mysql-error.d.ts.map +1 -0
- package/dist/runtime/mysql-error.js +119 -0
- package/dist/runtime/mysql-error.js.map +1 -0
- package/dist/runtime/mysql-family-pool.d.ts +50 -0
- package/dist/runtime/mysql-family-pool.d.ts.map +1 -0
- package/dist/runtime/mysql-family-pool.js +52 -0
- package/dist/runtime/mysql-family-pool.js.map +1 -0
- package/dist/runtime/mysql-family-pool.test.d.ts +2 -0
- package/dist/runtime/mysql-family-pool.test.d.ts.map +1 -0
- package/dist/runtime/mysql-family-pool.test.js +169 -0
- package/dist/runtime/mysql-family-pool.test.js.map +1 -0
- package/dist/runtime/mysql-placeholders.d.ts +18 -0
- package/dist/runtime/mysql-placeholders.d.ts.map +1 -0
- package/dist/runtime/mysql-placeholders.js +133 -0
- package/dist/runtime/mysql-placeholders.js.map +1 -0
- package/dist/runtime/mysql-placeholders.test.d.ts +2 -0
- package/dist/runtime/mysql-placeholders.test.d.ts.map +1 -0
- package/dist/runtime/mysql-placeholders.test.js +33 -0
- package/dist/runtime/mysql-placeholders.test.js.map +1 -0
- package/dist/runtime/query/compile-aggregate.d.ts +1 -1
- package/dist/runtime/query/compile-aggregate.d.ts.map +1 -1
- package/dist/runtime/query/compile-aggregate.js +25 -22
- package/dist/runtime/query/compile-aggregate.js.map +1 -1
- package/dist/runtime/query/compile-where.d.ts +9 -9
- package/dist/runtime/query/compile-where.d.ts.map +1 -1
- package/dist/runtime/query/compile-where.js +87 -66
- package/dist/runtime/query/compile-where.js.map +1 -1
- package/dist/runtime/query/compile-write.d.ts +9 -9
- package/dist/runtime/query/compile-write.d.ts.map +1 -1
- package/dist/runtime/query/compile-write.js +77 -63
- package/dist/runtime/query/compile-write.js.map +1 -1
- package/dist/runtime/query/count.d.ts.map +1 -1
- package/dist/runtime/query/count.js +4 -1
- package/dist/runtime/query/count.js.map +1 -1
- package/dist/runtime/query/create.d.ts.map +1 -1
- package/dist/runtime/query/create.js +38 -12
- package/dist/runtime/query/create.js.map +1 -1
- package/dist/runtime/query/cursor.d.ts +1 -1
- package/dist/runtime/query/cursor.d.ts.map +1 -1
- package/dist/runtime/query/cursor.js +6 -7
- package/dist/runtime/query/cursor.js.map +1 -1
- package/dist/runtime/query/delete.d.ts.map +1 -1
- package/dist/runtime/query/delete.js +41 -15
- package/dist/runtime/query/delete.js.map +1 -1
- package/dist/runtime/query/execute.d.ts +1 -0
- package/dist/runtime/query/execute.d.ts.map +1 -1
- package/dist/runtime/query/execute.js +23 -8
- package/dist/runtime/query/execute.js.map +1 -1
- package/dist/runtime/query/find-or-create.d.ts +1 -1
- package/dist/runtime/query/find-or-create.d.ts.map +1 -1
- package/dist/runtime/query/find-or-create.js +16 -8
- package/dist/runtime/query/find-or-create.js.map +1 -1
- package/dist/runtime/query/find.d.ts +2 -0
- package/dist/runtime/query/find.d.ts.map +1 -1
- package/dist/runtime/query/find.js +108 -62
- package/dist/runtime/query/find.js.map +1 -1
- package/dist/runtime/query/mutation-returning.d.ts +10 -0
- package/dist/runtime/query/mutation-returning.d.ts.map +1 -0
- package/dist/runtime/query/mutation-returning.js +85 -0
- package/dist/runtime/query/mutation-returning.js.map +1 -0
- package/dist/runtime/query/paginate.d.ts.map +1 -1
- package/dist/runtime/query/paginate.js +3 -3
- package/dist/runtime/query/paginate.js.map +1 -1
- package/dist/runtime/query/relation-join.d.ts +5 -0
- package/dist/runtime/query/relation-join.d.ts.map +1 -0
- package/dist/runtime/query/relation-join.js +26 -0
- package/dist/runtime/query/relation-join.js.map +1 -0
- package/dist/runtime/query/relation-planner.d.ts +1 -1
- package/dist/runtime/query/relation-planner.d.ts.map +1 -1
- package/dist/runtime/query/relation-planner.js +69 -55
- package/dist/runtime/query/relation-planner.js.map +1 -1
- package/dist/runtime/query/relation-writes.d.ts +2 -2
- package/dist/runtime/query/relation-writes.d.ts.map +1 -1
- package/dist/runtime/query/relation-writes.js +257 -98
- package/dist/runtime/query/relation-writes.js.map +1 -1
- package/dist/runtime/query/table-index.d.ts.map +1 -1
- package/dist/runtime/query/table-index.js +16 -9
- package/dist/runtime/query/table-index.js.map +1 -1
- package/dist/runtime/query/unique.d.ts +3 -0
- package/dist/runtime/query/unique.d.ts.map +1 -1
- package/dist/runtime/query/unique.js +26 -6
- package/dist/runtime/query/unique.js.map +1 -1
- package/dist/runtime/query/unique.test.js +110 -7
- package/dist/runtime/query/unique.test.js.map +1 -1
- package/dist/runtime/query/update.d.ts.map +1 -1
- package/dist/runtime/query/update.js +89 -23
- package/dist/runtime/query/update.js.map +1 -1
- package/dist/runtime/query/updated-at.js +2 -2
- package/dist/runtime/query/updated-at.js.map +1 -1
- package/dist/runtime/query/upsert.d.ts.map +1 -1
- package/dist/runtime/query/upsert.js +29 -5
- package/dist/runtime/query/upsert.js.map +1 -1
- package/dist/runtime/transaction.d.ts +1 -0
- package/dist/runtime/transaction.d.ts.map +1 -1
- package/dist/runtime/transaction.js +8 -0
- package/dist/runtime/transaction.js.map +1 -1
- package/dist/runtime/types.d.ts +10 -2
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/schema/column-constraints.d.ts +1 -1
- package/dist/schema/column-constraints.d.ts.map +1 -1
- package/dist/schema/column-constraints.js +6 -3
- package/dist/schema/column-constraints.js.map +1 -1
- package/dist/schema/column.d.ts +2 -2
- package/dist/schema/column.d.ts.map +1 -1
- package/dist/schema/column.js +1 -1
- package/dist/schema/column.js.map +1 -1
- package/dist/schema/index.d.ts +4 -4
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +2 -2
- package/dist/schema/index.js.map +1 -1
- package/dist/schema/nested-relation-types.d.ts +10 -9
- package/dist/schema/nested-relation-types.d.ts.map +1 -1
- package/dist/schema/relation-types.d.ts +73 -12
- package/dist/schema/relation-types.d.ts.map +1 -1
- package/dist/schema/relation.d.ts +11 -1
- package/dist/schema/relation.d.ts.map +1 -1
- package/dist/schema/relation.js +6 -0
- package/dist/schema/relation.js.map +1 -1
- package/dist/schema/table.d.ts +74 -11
- package/dist/schema/table.d.ts.map +1 -1
- package/dist/schema/table.js +93 -7
- package/dist/schema/table.js.map +1 -1
- package/dist/schema/types.d.ts +1 -1
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/sql/builder.d.ts +13 -3
- package/dist/sql/builder.d.ts.map +1 -1
- package/dist/sql/builder.js +155 -5
- package/dist/sql/builder.js.map +1 -1
- package/dist/sql/index.d.ts +1 -0
- package/dist/sql/index.d.ts.map +1 -1
- package/dist/sql/index.js.map +1 -1
- package/dist/sql/qualify-tables.d.ts +15 -0
- package/dist/sql/qualify-tables.d.ts.map +1 -0
- package/dist/sql/qualify-tables.js +206 -0
- package/dist/sql/qualify-tables.js.map +1 -0
- package/dist/sql/template.d.ts +5 -0
- package/dist/sql/template.d.ts.map +1 -1
- package/dist/sql/template.js +23 -3
- package/dist/sql/template.js.map +1 -1
- package/docs/cli.md +4 -4
- package/docs/configuration.md +7 -6
- package/docs/elysia.md +131 -0
- package/docs/errors.md +1 -1
- package/docs/examples.md +4 -2
- package/docs/getting-started.md +6 -4
- package/docs/mariadb.md +149 -0
- package/docs/migrations.md +5 -3
- package/docs/mysql.md +134 -0
- package/docs/plugins.md +1 -1
- package/docs/queries.md +14 -11
- package/docs/relations.md +19 -4
- package/docs/schema.md +73 -10
- package/docs/sqlite.md +6 -2
- package/docs/typebox.md +4 -4
- package/docs/zod.md +2 -2
- package/package.json +18 -2
package/docs/relations.md
CHANGED
|
@@ -6,13 +6,13 @@
|
|
|
6
6
|
|
|
7
7
|
| Relation kind | Operations |
|
|
8
8
|
|---------------|------------|
|
|
9
|
-
| **To-one** (outgoing FK) | `connect`, `create`, `disconnect` (nullable FK only) |
|
|
9
|
+
| **To-one** (outgoing FK) | `connect`, `connectOrCreate`, `create`, `disconnect` (nullable FK only) |
|
|
10
10
|
| **One-to-many** (inverse) | `create`, `connect`, `disconnect`, `set`, `delete` |
|
|
11
11
|
| **Many-to-many** | `connect`, `connectOrCreate`, `disconnect`, `set`, `delete` |
|
|
12
12
|
|
|
13
|
-
`connect`, `set`, `disconnect`, and `delete` identify related rows by the **target table's
|
|
13
|
+
`connect`, `set`, `disconnect`, and `delete` identify related rows by the **target table's primary key**: `{ id: ... }` or `{ userId: ... }` for a scalar PK, or an object with **every** PK column for a composite key. A single-column `fk()` still stores one referenced value; a composite `foreignKey()` extra assigns **each** local column from the matching target field (never a concatenated PK string).
|
|
14
14
|
|
|
15
|
-
A relation field must be a **pure write bag**: every key is one of those operations. Mixing a write op with extra fields (`{ create: { name: "A" }, foo: 1 }`), passing a scalar, or passing `{}` throws `invalid_nested_write` — the parent row is not written.
|
|
15
|
+
A relation field must be a **pure write bag**: every key is one of those operations. Mixing a write op with extra fields (`{ create: { name: "A" }, foo: 1 }`), passing a scalar, or passing `{}` throws `invalid_nested_write` — the parent row is not written. To-one `connectOrCreate` cannot be mixed with `connect` or `create`.
|
|
16
16
|
|
|
17
17
|
## Examples
|
|
18
18
|
|
|
@@ -21,7 +21,22 @@ A relation field must be a **pure write bag**: every key is one of those operati
|
|
|
21
21
|
```ts
|
|
22
22
|
await db.posts.update({
|
|
23
23
|
where: { id: postId },
|
|
24
|
-
data: {
|
|
24
|
+
data: {
|
|
25
|
+
author: { connect: { id: userId } },
|
|
26
|
+
// or create the author if missing:
|
|
27
|
+
// author: { connectOrCreate: { where: { email }, create: { email, password } } },
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Composite primary key:
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
await db.orders.update({
|
|
36
|
+
where: { id: orderId },
|
|
37
|
+
data: {
|
|
38
|
+
lines: { connect: [{ tenantId: "acme", lineNo: 1 }] },
|
|
39
|
+
},
|
|
25
40
|
});
|
|
26
41
|
```
|
|
27
42
|
|
package/docs/schema.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Schema DSL
|
|
2
2
|
|
|
3
|
-
NeoOrm **0.8.0** uses accessor-based identity: schema keys, `fk("users")`, `many("tags")`, and `through: "postTags"` all refer to **accessors**, not raw SQL names. `schemaToManifest` resolves accessors to SQL before migrations and the typed client are generated.
|
|
3
|
+
NeoOrm **0.8.0** and later uses accessor-based identity: schema keys, `fk("users")`, `many("tags")`, and `through: "postTags"` all refer to **accessors**, not raw SQL names. `schemaToManifest` resolves accessors to SQL before migrations and the typed client are generated.
|
|
4
4
|
|
|
5
5
|
## Tables and accessors
|
|
6
6
|
|
|
@@ -48,10 +48,21 @@ Column field names use camelCase in TypeScript. By default SQL column names are
|
|
|
48
48
|
| `decimal()` / `numeric()` | `NUMERIC` | `string \| null` | Use strings to avoid float loss |
|
|
49
49
|
| `enumType(["a", "b"])` | mode-dependent | union literals | See [Enum columns](#enum-columns) |
|
|
50
50
|
| `bytea()` | `BYTEA` | `Buffer \| null` | |
|
|
51
|
-
| `textArray()` / `intArray()` | arrays | arrays \| null | |
|
|
51
|
+
| `textArray()` / `intArray()` | arrays | arrays \| null | JSON on SQLite/MySQL |
|
|
52
|
+
| `uuidArray()` | `UUID[]` | `string[] \| null` | JSON on SQLite/MySQL |
|
|
53
|
+
| `enumArray(["a", "b"])` | `TEXT[]` or `name[]` | union arrays \| null | Same enum storage mode as `enumType`; JSON on SQLite/MySQL |
|
|
54
|
+
| `real()` / `float()` | `REAL` | `number \| null` | 32-bit. Prisma `Float` is `double()`. MySQL `FLOAT`, SQLite `REAL` |
|
|
55
|
+
| `double()` | `DOUBLE PRECISION` | `number \| null` | MySQL `DOUBLE`, SQLite `REAL` |
|
|
56
|
+
| `date()` | `DATE` | `string \| null` | `YYYY-MM-DD`, not `Date`. SQLite `TEXT`, MySQL `DATE` |
|
|
57
|
+
| `time()` | `TIME` | `string \| null` | SQLite `TEXT`, MySQL `TIME` |
|
|
58
|
+
| `interval()` | `INTERVAL` | `string \| null` | SQLite `TEXT`; rejected on MySQL/MariaDB |
|
|
59
|
+
| `inet()` / `cidr()` | `INET` / `CIDR` | `string \| null` | SQLite `TEXT`; rejected on MySQL/MariaDB |
|
|
60
|
+
| `xml()` | `XML` | `string \| null` | MySQL `LONGTEXT`, SQLite `TEXT` |
|
|
61
|
+
| `money()` | `MONEY` | `string \| null` | MySQL `DECIMAL(19,4)`, SQLite `TEXT` |
|
|
62
|
+
| `int4Range()` / `int8Range()` / `numRange()` / `tsRange()` / `tstzRange()` / `dateRange()` | matching PG ranges | `string \| null` | PostgreSQL only (rejected on SQLite and MySQL/MariaDB) |
|
|
52
63
|
| `citext()` | `CITEXT` | `string \| null` | Requires `citext` extension |
|
|
53
64
|
|
|
54
|
-
All column builders support `.notNull()`, `.unique()`, `.default(value)`, `.primary()`, `.map(name)`, `.hidden()`, `.index()`, and `.check("sql expression")`. Text columns add `.maxLength()`, `.minLength()`, `.notEmpty()`, `.email()`, and `.url()`. Numeric columns (`int`, `bigint`, `serial`, `decimal`) add `.min()`, `.max()`, and `.positive()`.
|
|
65
|
+
All column builders support `.notNull()`, `.unique()`, `.default(value)`, `.primary()`, `.map(name)`, `.hidden()`, `.index()`, and `.check("sql expression")`. Text columns add `.maxLength()`, `.minLength()`, `.notEmpty()`, `.email()`, and `.url()`. Numeric columns (`int`, `bigint`, `serial`, `decimal`, `real`, `double`) add `.min()`, `.max()`, and `.positive()`.
|
|
55
66
|
|
|
56
67
|
`.hidden()` marks a column as sensitive. It is omitted from default query output on the root table and on nested `with` includes. Pass `includeHidden: true` when the app needs the value (for example password verification on login). Use `.strip()` to remove any remaining sensitive fields before JSON responses.
|
|
57
68
|
|
|
@@ -100,7 +111,9 @@ Fluent modifiers (no options bag):
|
|
|
100
111
|
|--------|--------|
|
|
101
112
|
| `.as("author")` | override relation name on this table (default: strip `Id` from column name) |
|
|
102
113
|
| `.inverse("articles")` | override relation name on the target table (rare — see defaults below) |
|
|
103
|
-
| `.onDelete("cascade" \| "restrict" \| "set null" \| "no action")` | FK
|
|
114
|
+
| `.onDelete("cascade" \| "restrict" \| "set null" \| "no action")` | FK `ON DELETE` |
|
|
115
|
+
| `.onUpdate("cascade" \| "restrict" \| "set null" \| "no action")` | FK `ON UPDATE` |
|
|
116
|
+
| `.deferrable("immediate" \| "deferred")` | `DEFERRABLE` (Postgres and SQLite; rejected on MySQL/MariaDB) |
|
|
104
117
|
| `.notNull()` | `NOT NULL` |
|
|
105
118
|
| `.unique()` | `UNIQUE` — unique FKs infer a **singular** inverse (`profiles.userId` → `users.profile`) |
|
|
106
119
|
| `.primary()` | part of composite PK |
|
|
@@ -123,6 +136,39 @@ postTags: table("post_tags", {
|
|
|
123
136
|
|
|
124
137
|
Multiple `.primary()` columns infer a composite key. `primaryKey(t.colA, t.colB)` in extras is optional when you want to name the key without marking every column.
|
|
125
138
|
|
|
139
|
+
### Composite foreign keys
|
|
140
|
+
|
|
141
|
+
Use table extras `foreignKey()` when several local columns form one constraint (and one relation). Do not also mark those columns `fk()`.
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
orders: table(
|
|
145
|
+
{
|
|
146
|
+
id: id(),
|
|
147
|
+
tenantId: text().notNull(),
|
|
148
|
+
userId: text().notNull(),
|
|
149
|
+
},
|
|
150
|
+
(t) => [
|
|
151
|
+
foreignKey(t.tenantId, t.userId)
|
|
152
|
+
.references("users", "tenantId", "id")
|
|
153
|
+
.as("user")
|
|
154
|
+
.inverse("orders")
|
|
155
|
+
.onDelete("cascade")
|
|
156
|
+
.onUpdate("cascade"),
|
|
157
|
+
],
|
|
158
|
+
),
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
The target column list must match a primary key or unique index. `.as()` and `.inverse()` are required. Connect still uses the target table's full primary key:
|
|
162
|
+
|
|
163
|
+
```ts
|
|
164
|
+
await db.orders.create({
|
|
165
|
+
data: {
|
|
166
|
+
tenantId: "acme",
|
|
167
|
+
user: { connect: { tenantId: "acme", id: userId } },
|
|
168
|
+
},
|
|
169
|
+
});
|
|
170
|
+
```
|
|
171
|
+
|
|
126
172
|
### Self-relations
|
|
127
173
|
|
|
128
174
|
```ts
|
|
@@ -148,7 +194,7 @@ export const schema = defineSchema({
|
|
|
148
194
|
|
|
149
195
|
## Column checks
|
|
150
196
|
|
|
151
|
-
Use `.check("sql expression")` for custom CHECK constraints, or the typed helpers below. Helpers compile to database CHECK constraints (and `VARCHAR(n)` for text length on Postgres). They are not runtime validators by themselves. With [`generate.zod`](zod.md)
|
|
197
|
+
Use `.check("sql expression")` for custom CHECK constraints, or the typed helpers below. Helpers compile to database CHECK constraints (and `VARCHAR(n)` for text length on Postgres). They are not runtime validators by themselves. With [`generate.zod`](zod.md), [`generate.typebox`](typebox.md), or [`generate.elysia`](elysia.md), the same helpers are copied into generated validation schemas at your API boundary.
|
|
152
198
|
|
|
153
199
|
### Typed constraint helpers
|
|
154
200
|
|
|
@@ -172,7 +218,7 @@ views: int().notNull().min(0)
|
|
|
172
218
|
price: decimal({ precision: 10, scale: 2 }).notNull().positive()
|
|
173
219
|
```
|
|
174
220
|
|
|
175
|
-
`.email()` and `.url()` are validation-only: they do not emit a SQL CHECK. With [`generate.zod`](zod.md)
|
|
221
|
+
`.email()` and `.url()` are validation-only: they do not emit a SQL CHECK. With [`generate.zod`](zod.md), [`generate.typebox`](typebox.md), or [`generate.elysia`](elysia.md), columns named `email` or ending in `Email` (`contactEmail`) become email-format strings, and columns named `url` or ending in `Url` (`avatarUrl`) become URL-format strings. You can also mark any `text` / `citext` column with `.email()` or `.url()`. Foreign keys follow the **referenced** column (`authorEmail` pointing at a uuid PK stays a uuid).
|
|
176
222
|
|
|
177
223
|
`citext` length helpers use CHECK only (no `VARCHAR`). NULL still bypasses CHECK — pair `.notEmpty()` with `.notNull()` to reject empty strings.
|
|
178
224
|
|
|
@@ -200,7 +246,24 @@ posts: table(
|
|
|
200
246
|
),
|
|
201
247
|
```
|
|
202
248
|
|
|
203
|
-
Helpers: `unique(...cols)`, `index(...cols)`, `primaryKey(...cols)`. `unique()` and `index()`
|
|
249
|
+
Helpers: `unique(...cols)`, `index(...cols)`, `primaryKey(...cols)`, `expr("sql")`. `unique()` and `index()` support `.using()`, `.ops()`, and `.where()` for partial indexes.
|
|
250
|
+
|
|
251
|
+
### Index methods and expressions
|
|
252
|
+
|
|
253
|
+
```ts
|
|
254
|
+
(t) => [
|
|
255
|
+
index(t.tags).using("gin"),
|
|
256
|
+
index(t.metadata).using("gin").ops("jsonb_path_ops"),
|
|
257
|
+
index(t.location).using("gist"),
|
|
258
|
+
index(t.createdAt).using("brin"),
|
|
259
|
+
unique(expr("lower(email)")),
|
|
260
|
+
index(t.authorId, expr("date_trunc('day', created_at)")),
|
|
261
|
+
],
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Default method is btree (`USING btree` is omitted in SQL). Postgres also emits `gin`, `gist`, `brin`, and `hash`. SQLite allows expression keys and partial `WHERE`, but not those access methods. MySQL/MariaDB allow `USING HASH` and functional `(expr)` keys; they reject GIN/GiST/BRIN and partial `WHERE`.
|
|
265
|
+
|
|
266
|
+
`unique()` cannot use `gin` / `gist` / `brin`. Expression unique indexes are not `findUnique` / `upsert` targets.
|
|
204
267
|
|
|
205
268
|
### Partial indexes
|
|
206
269
|
|
|
@@ -211,7 +274,7 @@ Helpers: `unique(...cols)`, `index(...cols)`, `primaryKey(...cols)`. `unique()`
|
|
|
211
274
|
],
|
|
212
275
|
```
|
|
213
276
|
|
|
214
|
-
Equality map of column refs → values; compiled to `WHERE "published" = true` (or `= 1` on SQLite). Partial uniques emit as `CREATE UNIQUE INDEX ... WHERE ...`, not table-level `UNIQUE (...)`. They are
|
|
277
|
+
Equality map of column refs → values; compiled to `WHERE "published" = true` (or `= 1` on SQLite). Partial uniques emit as `CREATE UNIQUE INDEX ... WHERE ...`, not table-level `UNIQUE (...)`. They are valid `findUnique` / `upsert` / `findOrCreate` targets: `where` uses the indexed columns, and the index predicate is applied automatically (`AND` on lookups, `ON CONFLICT (…) WHERE …` on Postgres and SQLite).
|
|
215
278
|
|
|
216
279
|
## Many-to-many
|
|
217
280
|
|
|
@@ -282,7 +345,7 @@ status: enumType(["draft", "published", "archived"])
|
|
|
282
345
|
.default("draft"),
|
|
283
346
|
```
|
|
284
347
|
|
|
285
|
-
`datasource.enum` in config: `check` (default), `union`, or `native` (PostgreSQL
|
|
348
|
+
`datasource.enum` in config: `check` (default), `union`, or `native` (PostgreSQL `CREATE TYPE` / MySQL and MariaDB column `ENUM`).
|
|
286
349
|
|
|
287
350
|
## PostgreSQL extensions
|
|
288
351
|
|
|
@@ -297,4 +360,4 @@ Column type plugins still register required extensions automatically.
|
|
|
297
360
|
|
|
298
361
|
## SQLite type mapping
|
|
299
362
|
|
|
300
|
-
Same DSL; see [SQLite](sqlite.md) for storage types and limitations.
|
|
363
|
+
Same DSL; see [SQLite](sqlite.md), [MySQL](mysql.md), and [MariaDB](mariadb.md) for storage types and limitations.
|
package/docs/sqlite.md
CHANGED
|
@@ -103,9 +103,11 @@ bunx neoorm migrate reset --force
|
|
|
103
103
|
|
|
104
104
|
| Schema builder | SQLite storage |
|
|
105
105
|
|----------------|----------------|
|
|
106
|
-
| `id`, `text`, `uuid`, `json`, `jsonb`, `decimal`, `textArray`, `intArray`, `citext`, `enumType` | `TEXT` |
|
|
106
|
+
| `id`, `text`, `uuid`, `json`, `jsonb`, `decimal`, `textArray`, `intArray`, `uuidArray`, `enumArray`, `citext`, `enumType`, `date`, `time`, `interval`, `inet`, `cidr`, `xml`, `money` | `TEXT` |
|
|
107
107
|
| `int`, `serial` | `INTEGER` |
|
|
108
|
+
| `real`, `double` | `REAL` |
|
|
108
109
|
| `bigint` | `TEXT` |
|
|
110
|
+
| `int4Range` … `dateRange` | rejected at schema compile |
|
|
109
111
|
| `serial().primary()` | `INTEGER PRIMARY KEY AUTOINCREMENT` |
|
|
110
112
|
| `bool` | `BOOLEAN` (stored as 0/1) |
|
|
111
113
|
| `timestamp` | `TEXT` (ISO-8601) |
|
|
@@ -118,9 +120,11 @@ bunx neoorm migrate reset --force
|
|
|
118
120
|
|
|
119
121
|
| Feature | PostgreSQL | SQLite |
|
|
120
122
|
|---------|-----------|--------|
|
|
121
|
-
| `distinct` (`DISTINCT ON`) | supported |
|
|
123
|
+
| `distinct` (`DISTINCT ON`) | supported | `ROW_NUMBER()` per distinct columns (same `orderBy` prefix rule) |
|
|
124
|
+
| `search` | POSIX `~` / `~*` | JavaScript `RegExp` via `REGEXP` / `regexp_i` |
|
|
122
125
|
| `datasource.schema` | multi-schema | not applicable |
|
|
123
126
|
| `enum: "native"` | `CREATE TYPE ... AS ENUM` | not applicable (TEXT + CHECK) |
|
|
127
|
+
| range types | supported | rejected at schema compile |
|
|
124
128
|
| transaction options (`readOnly`, `isolationLevel`) | `BEGIN READ ONLY` / `ISOLATION LEVEL` | `readOnly` → `PRAGMA query_only`; `RepeatableRead`/`Serializable` → `BEGIN IMMEDIATE`; other isolation → `BEGIN` |
|
|
125
129
|
| JSON operators | `@>`, `?`, `#>` | `json_patch` / `json_each` / `json_extract` |
|
|
126
130
|
|
package/docs/typebox.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# TypeBox schemas
|
|
2
2
|
|
|
3
|
-
`neoorm generate` can print Select, Create, and Update **scalar** TypeBox schemas next to the typed client. Codegen maps your schema to a validator-neutral IR first; TypeBox is
|
|
3
|
+
`neoorm generate` can print Select, Create, and Update **scalar** TypeBox schemas next to the typed client. Codegen maps your schema to a validator-neutral IR first; TypeBox 1.x is one printer (alongside [Zod](zod.md) and [Elysia `t`](elysia.md)).
|
|
4
4
|
|
|
5
5
|
Generated schemas match the TypeScript shapes of row / insert / update scalars — not nested relation writes (`connect`, `create`, `set`). Those stay TypeScript-only.
|
|
6
6
|
|
|
7
|
-
Schemas target **TypeBox 1.x** (`typebox` on npm), not `@sinclair/typebox` 0.x.
|
|
7
|
+
Schemas target **TypeBox 1.x** (`typebox` on npm), not `@sinclair/typebox` 0.x. For Elysia 1.x route `body:`, use [`generate.elysia`](elysia.md) instead.
|
|
8
8
|
|
|
9
9
|
## Enable
|
|
10
10
|
|
|
@@ -40,7 +40,7 @@ Disable `generate.typebox` and generate again to remove `typebox.ts`.
|
|
|
40
40
|
|
|
41
41
|
`typebox` is an optional peer of NeoOrm. The generated file imports `typebox` directly; NeoOrm does not bundle it. If `generate.typebox` is on and `typebox` is not installed, `neoorm generate` still writes `typebox.ts` and prints a warning (`bun add typebox`).
|
|
42
42
|
|
|
43
|
-
You can enable Zod and
|
|
43
|
+
You can enable Zod, TypeBox, and Elysia together. When Zod is on, `client.ts` keeps Zod as a flat `export *` and namespaces TypeBox and Elysia (`export * as typebox` / `export * as elysia`). TypeBox + Elysia without Zod keeps TypeBox flat and namespaces Elysia. Import TypeBox from `./typebox.js` (or `typebox.UserCreateSchema` from the client) when it is namespaced. For Elysia 1.x `body:`, use [`generate.elysia`](elysia.md).
|
|
44
44
|
|
|
45
45
|
## Usage
|
|
46
46
|
|
|
@@ -115,7 +115,7 @@ Typed schema helpers map into TypeBox:
|
|
|
115
115
|
| `timestamp()` | `Date` or ISO datetime string → `Date` (`Type.Codec` + `Value.Decode`) |
|
|
116
116
|
| `bytea()` | `Type.Refine` + `Buffer.isBuffer` |
|
|
117
117
|
|
|
118
|
-
Raw `.check("sql")` is not mapped. With `generate.typebox: true` (or `generate.zod
|
|
118
|
+
Raw `.check("sql")` is not mapped. With `generate.typebox: true` (or `generate.zod` / `generate.elysia`), codegen reads inline `json()` / `jsonb()` type arguments from `schema.ts` and maps object literals to `Type.Object`, `Record<K,V>` to `Type.Record`, and primitives to the matching TypeBox types. Type aliases and imported types are not resolved yet — use an inline type or `.schema()` for those.
|
|
119
119
|
|
|
120
120
|
```ts
|
|
121
121
|
metadata: jsonb<{ featured: boolean; category?: string }>(),
|
package/docs/zod.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Zod schemas
|
|
2
2
|
|
|
3
|
-
`neoorm generate` can print Select, Create, and Update **scalar** Zod schemas next to the typed client. Codegen maps your schema to a validator-neutral IR first; Zod
|
|
3
|
+
`neoorm generate` can print Select, Create, and Update **scalar** Zod schemas next to the typed client. Codegen maps your schema to a validator-neutral IR first; Zod, [TypeBox](typebox.md), and [Elysia `t`](elysia.md) are the printers shipped today.
|
|
4
4
|
|
|
5
5
|
Generated schemas match the TypeScript shapes of row / insert / update scalars — not nested relation writes (`connect`, `create`, `set`). Those stay TypeScript-only.
|
|
6
6
|
|
|
@@ -104,7 +104,7 @@ Typed schema helpers map into Zod:
|
|
|
104
104
|
| `json()` / `jsonb()` with `.schema()` validation IR | same as IR (`z.object`, nested `z.record`, …); wins over generics |
|
|
105
105
|
| `timestamp()` | `Date` or ISO datetime string → `Date` |
|
|
106
106
|
|
|
107
|
-
Raw `.check("sql")` is not mapped. With `generate.zod: true` or `generate.
|
|
107
|
+
Raw `.check("sql")` is not mapped. With `generate.zod: true`, `generate.typebox: true`, or `generate.elysia: true`, codegen reads inline `json()` / `jsonb()` type arguments from `schema.ts` and maps object literals to `z.object`, `Record<K,V>` to `z.record`, and primitives to the matching Zod types. Type aliases and imported types are not resolved yet — use an inline type or `.schema()` for those.
|
|
108
108
|
|
|
109
109
|
```ts
|
|
110
110
|
metadata: jsonb<{ featured: boolean; category?: string }>(),
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "neoorm",
|
|
3
|
-
"version": "0.8.
|
|
4
|
-
"description": "TypeScript-first PostgreSQL and
|
|
3
|
+
"version": "0.8.2",
|
|
4
|
+
"description": "TypeScript-first PostgreSQL, SQLite, MySQL, and MariaDB ORM with schema DSL, codegen, and typed relations",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -67,6 +67,8 @@
|
|
|
67
67
|
"postgresql",
|
|
68
68
|
"postgres",
|
|
69
69
|
"sqlite",
|
|
70
|
+
"mysql",
|
|
71
|
+
"mariadb",
|
|
70
72
|
"typescript",
|
|
71
73
|
"schema",
|
|
72
74
|
"codegen",
|
|
@@ -88,16 +90,30 @@
|
|
|
88
90
|
"@biomejs/biome": "2.5.2",
|
|
89
91
|
"@types/node": "^26.1.0",
|
|
90
92
|
"@types/pg": "^8.20.0",
|
|
93
|
+
"mysql2": "^3.15.3",
|
|
94
|
+
"mariadb": "^3.4.5",
|
|
91
95
|
"typebox": "^1.3.31",
|
|
92
96
|
"typescript": "^7.0.2",
|
|
93
97
|
"vitest": "^4.1.9",
|
|
94
98
|
"zod": "^4.1.5"
|
|
95
99
|
},
|
|
96
100
|
"peerDependencies": {
|
|
101
|
+
"elysia": ">=1.2.0",
|
|
102
|
+
"mysql2": ">=3.0.0",
|
|
103
|
+
"mariadb": ">=3.0.0",
|
|
97
104
|
"typebox": "^1.0.0",
|
|
98
105
|
"zod": "^4.0.0"
|
|
99
106
|
},
|
|
100
107
|
"peerDependenciesMeta": {
|
|
108
|
+
"elysia": {
|
|
109
|
+
"optional": true
|
|
110
|
+
},
|
|
111
|
+
"mysql2": {
|
|
112
|
+
"optional": true
|
|
113
|
+
},
|
|
114
|
+
"mariadb": {
|
|
115
|
+
"optional": true
|
|
116
|
+
},
|
|
101
117
|
"typebox": {
|
|
102
118
|
"optional": true
|
|
103
119
|
},
|