neoorm 0.8.0 → 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 +13 -6
- package/dist/bin/neoorm.d.ts +1 -1
- package/dist/bin/neoorm.d.ts.map +1 -1
- package/dist/bin/neoorm.js +148 -75
- 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 +5 -1
- package/dist/codegen/generate-summary.d.ts.map +1 -1
- package/dist/codegen/generate-summary.js +10 -1
- package/dist/codegen/generate-summary.js.map +1 -1
- package/dist/codegen/generate.d.ts +24 -4
- package/dist/codegen/generate.d.ts.map +1 -1
- package/dist/codegen/generate.js +150 -13
- package/dist/codegen/generate.js.map +1 -1
- package/dist/codegen/manifest-relations.d.ts +2 -0
- package/dist/codegen/manifest-relations.d.ts.map +1 -1
- package/dist/codegen/manifest-relations.js +2 -1
- package/dist/codegen/manifest-relations.js.map +1 -1
- package/dist/codegen/schema-to-manifest.d.ts +1 -1
- package/dist/codegen/schema-to-manifest.d.ts.map +1 -1
- package/dist/codegen/schema-to-manifest.js +349 -29
- 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/emit-typebox.d.ts +4 -0
- package/dist/codegen/validation/emit-typebox.d.ts.map +1 -0
- package/dist/codegen/validation/emit-typebox.js +360 -0
- package/dist/codegen/validation/emit-typebox.js.map +1 -0
- package/dist/codegen/validation/emit-zod.d.ts +4 -0
- package/dist/codegen/validation/emit-zod.d.ts.map +1 -0
- package/dist/codegen/validation/emit-zod.js +288 -0
- package/dist/codegen/validation/emit-zod.js.map +1 -0
- package/dist/codegen/validation/from-manifest.d.ts +5 -0
- package/dist/codegen/validation/from-manifest.d.ts.map +1 -0
- package/dist/codegen/validation/from-manifest.js +284 -0
- package/dist/codegen/validation/from-manifest.js.map +1 -0
- package/dist/codegen/validation/infer.d.ts +47 -0
- package/dist/codegen/validation/infer.d.ts.map +1 -0
- package/dist/codegen/validation/infer.js +2 -0
- package/dist/codegen/validation/infer.js.map +1 -0
- package/dist/codegen/validation/json-generic-types.d.ts +7 -0
- package/dist/codegen/validation/json-generic-types.d.ts.map +1 -0
- package/dist/codegen/validation/json-generic-types.js +295 -0
- package/dist/codegen/validation/json-generic-types.js.map +1 -0
- package/dist/codegen/validation/types.d.ts +84 -0
- package/dist/codegen/validation/types.d.ts.map +1 -0
- package/dist/codegen/validation/types.js +6 -0
- package/dist/codegen/validation/types.js.map +1 -0
- package/dist/config.d.ts +8 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +30 -0
- 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 +6 -1
- package/dist/dialect/index.d.ts.map +1 -1
- package/dist/dialect/index.js +5 -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 +2 -1
- package/dist/dialect/postgres.d.ts.map +1 -1
- package/dist/dialect/postgres.js +93 -30
- 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 +60 -3
- package/dist/dialect/types.d.ts.map +1 -1
- package/dist/docs/pages.d.ts.map +1 -1
- package/dist/docs/pages.js +5 -0
- package/dist/docs/pages.js.map +1 -1
- package/dist/docs/render.js +1 -1
- package/dist/index.d.ts +6 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -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 -9
- 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 +186 -9
- package/dist/introspect/pull.js.map +1 -1
- package/dist/introspect/queries.d.ts +11 -1
- package/dist/introspect/queries.d.ts.map +1 -1
- package/dist/introspect/queries.js +43 -12
- 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 +154 -28
- 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 +62 -12
- package/dist/plugins/builtin.d.ts.map +1 -1
- package/dist/plugins/builtin.js +378 -30
- package/dist/plugins/builtin.js.map +1 -1
- package/dist/plugins/index.d.ts +1 -0
- package/dist/plugins/index.d.ts.map +1 -1
- package/dist/plugins/index.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/columns.d.ts.map +1 -1
- package/dist/plugins/postgis/columns.js +52 -0
- package/dist/plugins/postgis/columns.js.map +1 -1
- package/dist/plugins/postgis/columns.test.js +13 -0
- package/dist/plugins/postgis/columns.test.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/plugins/types.d.ts +3 -0
- package/dist/plugins/types.d.ts.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 +131 -6
- 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/error-hints.d.ts.map +1 -1
- package/dist/runtime/error-hints.js +37 -10
- package/dist/runtime/error-hints.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/aggregate.d.ts.map +1 -1
- package/dist/runtime/query/aggregate.js +3 -3
- package/dist/runtime/query/aggregate.js.map +1 -1
- 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 +33 -28
- 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 +108 -76
- 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 +116 -68
- package/dist/runtime/query/find.js.map +1 -1
- package/dist/runtime/query/group-by.d.ts.map +1 -1
- package/dist/runtime/query/group-by.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/projection.d.ts.map +1 -1
- package/dist/runtime/query/projection.js +1 -1
- package/dist/runtime/query/projection.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 +72 -58
- 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 +272 -116
- package/dist/runtime/query/relation-writes.js.map +1 -1
- package/dist/runtime/query/table-index.d.ts +1 -1
- package/dist/runtime/query/table-index.d.ts.map +1 -1
- package/dist/runtime/query/table-index.js +17 -10
- 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/sqlite-open.js +1 -1
- package/dist/runtime/sqlite-open.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 +26 -0
- package/dist/schema/column-constraints.d.ts.map +1 -0
- package/dist/schema/column-constraints.js +143 -0
- package/dist/schema/column-constraints.js.map +1 -0
- package/dist/schema/column.d.ts +92 -3
- package/dist/schema/column.d.ts.map +1 -1
- package/dist/schema/column.js +17 -11
- package/dist/schema/column.js.map +1 -1
- package/dist/schema/index.d.ts +9 -6
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +8 -2
- package/dist/schema/index.js.map +1 -1
- package/dist/schema/json-column.d.ts +9 -0
- package/dist/schema/json-column.d.ts.map +1 -0
- package/dist/schema/json-column.js +11 -0
- package/dist/schema/json-column.js.map +1 -0
- package/dist/schema/many-to-many.d.ts +1 -1
- package/dist/schema/many-to-many.d.ts.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 +80 -19
- 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 +7 -6
- 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/dist/utils/load-ts.d.ts +2 -1
- package/dist/utils/load-ts.d.ts.map +1 -1
- package/dist/utils/load-ts.js +13 -1
- package/dist/utils/load-ts.js.map +1 -1
- package/docs/cli.md +4 -4
- package/docs/configuration.md +12 -5
- package/docs/elysia.md +131 -0
- package/docs/errors.md +1 -1
- package/docs/examples.md +4 -2
- package/docs/getting-started.md +28 -2
- package/docs/mariadb.md +149 -0
- package/docs/migrations.md +5 -3
- package/docs/mysql.md +134 -0
- package/docs/plugins.md +2 -0
- package/docs/queries.md +14 -11
- package/docs/relations.md +19 -4
- package/docs/schema.md +100 -9
- package/docs/sqlite.md +14 -2
- package/docs/typebox.md +139 -0
- package/docs/zod.md +128 -0
- package/package.json +33 -3
package/docs/configuration.md
CHANGED
|
@@ -26,10 +26,17 @@ CLI commands load `.env` from the project directory before evaluating this file,
|
|
|
26
26
|
|-----|------|---------|-------------|
|
|
27
27
|
| `schema` | `string` | required | Path to the schema file |
|
|
28
28
|
| `out` | `string` | required | Output directory for generated files |
|
|
29
|
-
| `datasource.provider` | `"postgresql" \| "postgres" \| "sqlite"` | required | Database provider. `"postgres"` is an alias of `"postgresql"`. |
|
|
30
|
-
| `datasource.url` | `string` | required | Connection string (PostgreSQL) or database file path / `:memory:` (SQLite) |
|
|
31
|
-
| `datasource.schema` | `string` | `"public"` | PostgreSQL schema for migrations and queries (SQLite: not applicable) |
|
|
29
|
+
| `datasource.provider` | `"postgresql" \| "postgres" \| "sqlite" \| "mysql" \| "mariadb"` | required | Database provider. `"postgres"` is an alias of `"postgresql"`. |
|
|
30
|
+
| `datasource.url` | `string` | required | Connection string (PostgreSQL / MySQL / MariaDB) or database file path / `:memory:` (SQLite) |
|
|
31
|
+
| `datasource.schema` | `string` | `"public"` | PostgreSQL schema for migrations and queries (SQLite, MySQL, and MariaDB: not applicable) |
|
|
32
32
|
| `datasource.enum` | `"check" \| "union" \| "native"` | `"check"` | How to store enum columns |
|
|
33
|
+
| `generate.zod` | `boolean` | `false` | Emit Select/Create/Update Zod schemas to `out/zod.ts`. See [Zod schemas](zod.md). |
|
|
34
|
+
| `generate.typebox` | `boolean` | `false` | Emit Select/Create/Update TypeBox schemas to `out/typebox.ts`. See [TypeBox schemas](typebox.md). |
|
|
35
|
+
| `generate.elysia` | `boolean` | `false` | Emit Select/Create/Update Elysia `t` schemas to `out/elysia.ts`. See [Elysia schemas](elysia.md). |
|
|
36
|
+
|
|
37
|
+
### Validation emit
|
|
38
|
+
|
|
39
|
+
Set `generate.zod` to write `out/zod.ts`, `generate.typebox` to write `out/typebox.ts`, and/or `generate.elysia` to write `out/elysia.ts` on `neoorm generate` / `neoorm migrate dev`. Install `zod` (`^4`), `typebox` (`^1`), and/or `elysia` (`>=1.2`) in the app. If a printer is enabled and its peer is missing, generate still writes the file and warns. Codegen uses a library-agnostic IR; Zod, TypeBox 1.x, and Elysia `t` are the shipped printers. See [Zod schemas](zod.md), [TypeBox schemas](typebox.md), and [Elysia schemas](elysia.md).
|
|
33
40
|
|
|
34
41
|
### SQLite
|
|
35
42
|
|
|
@@ -42,7 +49,7 @@ datasource: {
|
|
|
42
49
|
},
|
|
43
50
|
```
|
|
44
51
|
|
|
45
|
-
`datasource.schema` and `datasource.enum: "native"`
|
|
52
|
+
`datasource.schema` is PostgreSQL-only (ignored on SQLite, MySQL, and MariaDB). `datasource.enum: "native"` is PostgreSQL `CREATE TYPE` or MySQL/MariaDB column `ENUM`. See [SQLite](sqlite.md), [MySQL](mysql.md), and [MariaDB](mariadb.md).
|
|
46
53
|
|
|
47
54
|
### Enum modes
|
|
48
55
|
|
|
@@ -50,4 +57,4 @@ datasource: {
|
|
|
50
57
|
|------|-----|----------------|
|
|
51
58
|
| `check` (default) | `TEXT` + `CHECK (...)` | yes |
|
|
52
59
|
| `union` | `TEXT` | no (TypeScript union only) |
|
|
53
|
-
| `native` | Postgres `CREATE TYPE ... AS ENUM`
|
|
60
|
+
| `native` | Postgres `CREATE TYPE ... AS ENUM` or MySQL/MariaDB column `ENUM` | yes |
|
package/docs/elysia.md
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# Elysia schemas
|
|
2
|
+
|
|
3
|
+
`neoorm generate` can print Select, Create, and Update **scalar** Elysia `t` schemas next to the typed client. Codegen maps your schema to a validator-neutral IR first; this printer emits `import { t } from "elysia"` so the objects drop into route `body:` / `query:` the same way as hand-written `t.Object({ title: t.String() })`.
|
|
4
|
+
|
|
5
|
+
Generated schemas match the TypeScript shapes of row / insert / update scalars — not nested relation writes (`connect`, `create`, `set`). Those stay TypeScript-only.
|
|
6
|
+
|
|
7
|
+
This is the printer to use with **Elysia 1.x**. [TypeBox 1.x](typebox.md) (`import Type from "typebox"`) is a different package and will not type-check as Elysia `body:`.
|
|
8
|
+
|
|
9
|
+
## Enable
|
|
10
|
+
|
|
11
|
+
Install Elysia in the app, then opt in:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
bun add elysia
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
// neoorm.config.ts
|
|
19
|
+
import { defineConfig } from "neoorm";
|
|
20
|
+
|
|
21
|
+
export default defineConfig({
|
|
22
|
+
schema: "./schema.ts",
|
|
23
|
+
out: "./neoorm",
|
|
24
|
+
datasource: {
|
|
25
|
+
provider: "postgresql",
|
|
26
|
+
url: process.env.DATABASE_URL!,
|
|
27
|
+
},
|
|
28
|
+
generate: {
|
|
29
|
+
elysia: true,
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Re-run `neoorm generate` (or `neoorm migrate dev`). Output:
|
|
35
|
+
|
|
36
|
+
- `out/elysia.ts` — generated schemas
|
|
37
|
+
- `out/client.ts` re-exports them
|
|
38
|
+
|
|
39
|
+
Disable `generate.elysia` and generate again to remove `elysia.ts`.
|
|
40
|
+
|
|
41
|
+
`elysia` is an optional peer of NeoOrm. The generated file imports `elysia` directly; NeoOrm does not bundle it. If `generate.elysia` is on and `elysia` is not installed, `neoorm generate` still writes `elysia.ts` and prints a warning (`bun add elysia`).
|
|
42
|
+
|
|
43
|
+
When Zod or TypeBox 1.x is also enabled, `client.ts` keeps those as documented and re-exports Elysia as `export * as elysia from "./elysia.js"` so names do not collide. Import from `./elysia.js` (or `elysia.UserCreateSchema`) in that case.
|
|
44
|
+
|
|
45
|
+
## Usage
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
import { Elysia } from "elysia";
|
|
49
|
+
import { db, UserCreateSchema, UserUpdateSchema } from "./neoorm/client.js";
|
|
50
|
+
|
|
51
|
+
new Elysia()
|
|
52
|
+
.post("/users", ({ body }) => db.users.create({ data: body }), {
|
|
53
|
+
body: UserCreateSchema,
|
|
54
|
+
})
|
|
55
|
+
.patch("/users/:id", ({ params, body }) =>
|
|
56
|
+
db.users.update({
|
|
57
|
+
where: { id: params.id },
|
|
58
|
+
data: body,
|
|
59
|
+
}), {
|
|
60
|
+
body: UserUpdateSchema,
|
|
61
|
+
},
|
|
62
|
+
)
|
|
63
|
+
.listen(3000);
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Elysia validates `body` against the `t.Object` schema. `t.Date()` accepts ISO-8601 strings, `Date` values, and epoch numbers, and decodes to `Date`.
|
|
67
|
+
|
|
68
|
+
Per table (accessor `users` → model `User`):
|
|
69
|
+
|
|
70
|
+
| Export | Shape |
|
|
71
|
+
|--------|--------|
|
|
72
|
+
| `UserSchema` / `UserSelect` | Select row (default query output: no `.hidden()`, includes `timestamps()`) |
|
|
73
|
+
| `UserCreateSchema` / `UserCreate` | Insert scalars (no primary / serial / `timestamps()`; defaults optional; includes `.hidden()`) |
|
|
74
|
+
| `UserUpdateSchema` / `UserUpdate` | Update scalars (no primary / `timestamps()`; all optional; includes `.hidden()`) |
|
|
75
|
+
|
|
76
|
+
`UserSelect` / `UserCreate` / `UserUpdate` are `typeof Schema.static` aliases. They are named that way so they do not collide with the model type `User` from `models.ts`. Hoisted enums also get a type (`PostStatus` from `PostStatusSchema`).
|
|
77
|
+
|
|
78
|
+
`schemas.users.select` / `.create` / `.update` are the same objects.
|
|
79
|
+
|
|
80
|
+
`.hidden()` columns (for example `password`) are omitted from select schemas so they match default query results. They stay on create and update so login/register and password-change payloads can still be parsed. Use `includeHidden: true` on the query when the app needs those fields internally.
|
|
81
|
+
|
|
82
|
+
`createdAt` and `updatedAt` from `timestamps()` (and any `timestamp().defaultNow()` / `.updatedAt()` column) are ORM-managed. They appear on select schemas only — create and update parsers reject them so API clients cannot stamp those fields. A plain `timestamp()` without `defaultNow` stays on create/update.
|
|
83
|
+
|
|
84
|
+
Create with `author: { connect: { id } }` is not in `PostCreateSchema`. Pass the FK scalar (`authorId`) or keep nested writes in TypeScript.
|
|
85
|
+
|
|
86
|
+
## Junction (M2M) tables
|
|
87
|
+
|
|
88
|
+
Many-to-many through tables (auto `posts_tags` from `tags: many("tags")`, or an explicit `through` table) are not ordinary entities. Both FK columns are usually the composite primary key, so a naive Create/Update export would be `t.Object({})`.
|
|
89
|
+
|
|
90
|
+
Codegen treats them as **link** tables:
|
|
91
|
+
|
|
92
|
+
| Export | Shape |
|
|
93
|
+
|--------|--------|
|
|
94
|
+
| `{Model}Schema` / `{Model}Select` | Junction row (both FK ids, plus extras like `priority`) |
|
|
95
|
+
| `{Model}LinkCreateSchema` / `{Model}LinkCreate` | Both FK ids required; extra create-allowed columns |
|
|
96
|
+
| `{Model}CreateSchema` / `{Model}Create` | Alias of `LinkCreateSchema` |
|
|
97
|
+
| `{Model}UpdateSchema` | Extra scalar columns only. **Omitted** when the junction has no updatable fields |
|
|
98
|
+
|
|
99
|
+
Generated comments point at nested writes on the parent (`db.posts.update({ data: { tags: { connect: [{ id }] } } })`). Direct `db.posts_tags.create` is rarely needed. `schemas.posts_tags` has `select` and `create`; `update` is present only when the through table has extra columns.
|
|
100
|
+
|
|
101
|
+
Prefer validating parent payloads in TypeScript (`tags: { connect, set, … }`). Junction Elysia schemas are for the rare case you insert a link row yourself.
|
|
102
|
+
|
|
103
|
+
## Types and constraints
|
|
104
|
+
|
|
105
|
+
`t.BigInt()` and `Buffer` still match generated models, not JSON. Wrap those fields if the payload is a JSON number/string.
|
|
106
|
+
|
|
107
|
+
Typed schema helpers map into Elysia `t`:
|
|
108
|
+
|
|
109
|
+
| Schema | Elysia |
|
|
110
|
+
|--------|--------|
|
|
111
|
+
| `.minLength()` / `.maxLength()` / `.notEmpty()` | `t.String({ minLength, maxLength })` |
|
|
112
|
+
| `email` / `*Email` column names, or `.email()` on `text` / `citext` | `t.String({ format: "email" })` |
|
|
113
|
+
| `url` / `*Url` column names, or `.url()` on `text` / `citext` | `t.String({ format: "uri" })` |
|
|
114
|
+
| `.min()` / `.max()` / `.positive()` on int/serial | `t.Integer({ minimum, maximum, exclusiveMinimum: 0 })` |
|
|
115
|
+
| same helpers on `bigint` | `t.BigInt({ minimum, maximum, exclusiveMinimum: 0n })` |
|
|
116
|
+
| same helpers on `decimal()` | `t.Transform(t.String()).Decode(...)` |
|
|
117
|
+
| `enumType([...])` | hoisted `t.UnionEnum` |
|
|
118
|
+
| `json()` / `jsonb()` with no type arg | `t.Record(t.String(), t.Unknown())` |
|
|
119
|
+
| `jsonb<Record<string, unknown>>()` | `t.Record(t.String(), t.Unknown())` |
|
|
120
|
+
| `jsonb<{ featured: boolean }>()` (inline object type) | `t.Object({ featured: t.Boolean(), … })` |
|
|
121
|
+
| `json()` / `jsonb()` with `.schema()` validation IR | same as IR (`t.Object`, nested `t.Record`, …); wins over generics |
|
|
122
|
+
| `timestamp()` | `t.Date()` (ISO string / Date / epoch → `Date`) |
|
|
123
|
+
| `bytea()` | `t.Transform(t.Any())` + `Buffer.isBuffer` |
|
|
124
|
+
| nullable / optional | `t.Nullable` / `t.Optional` |
|
|
125
|
+
|
|
126
|
+
Raw `.check("sql")` is not mapped. With `generate.elysia: true` (or Zod/TypeBox), codegen reads inline `json()` / `jsonb()` type arguments from `schema.ts`. Type aliases and imported types are not resolved yet — use an inline type or `.schema()` for those.
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
metadata: jsonb<{ featured: boolean; category?: string }>(),
|
|
130
|
+
// → metadata: t.Nullable(t.Object({ featured: t.Boolean(), category: t.Optional(t.String()) }))
|
|
131
|
+
```
|
package/docs/errors.md
CHANGED
|
@@ -48,7 +48,7 @@ Type guards (`isUniqueViolation`, `isQueryCompileError`, `isNeoOrmError`, …) a
|
|
|
48
48
|
|
|
49
49
|
## Query error codes
|
|
50
50
|
|
|
51
|
-
Codes are **dialect-agnostic** — the same `unique_violation` code is used for PostgreSQL and
|
|
51
|
+
Codes are **dialect-agnostic** — the same `unique_violation` code is used for PostgreSQL, SQLite, MySQL, and MariaDB.
|
|
52
52
|
|
|
53
53
|
| Code | Subclass | Typical HTTP | When |
|
|
54
54
|
|------|----------|--------------|------|
|
package/docs/examples.md
CHANGED
|
@@ -369,7 +369,7 @@ await db.$transaction(async (tx) => {
|
|
|
369
369
|
|
|
370
370
|
## Raw SQL
|
|
371
371
|
|
|
372
|
-
Use `db.sql` when you need full SQL control. It uses the same compiler as `neoorm/sql` (`sql`, `sqlId`, nested fragments). `sqlBuilder`
|
|
372
|
+
Use `db.sql` when you need full SQL control. It uses the same compiler as `neoorm/sql` (`sql`, `sqlId`, nested fragments). `sqlBuilder` covers select/join/where/group/order/limit with bound params — interpolate `.compile()` into `db.sql` for HAVING or other raw tails.
|
|
373
373
|
|
|
374
374
|
```ts
|
|
375
375
|
import { sql, sqlBuilder, sqlId } from "neoorm/sql";
|
|
@@ -391,7 +391,9 @@ const grouped = sqlBuilder
|
|
|
391
391
|
.selectFrom("users")
|
|
392
392
|
.leftJoin("posts", "posts.author_id", "users.id")
|
|
393
393
|
.select(["users.id", "users.email"])
|
|
394
|
+
.where("users.email", "=", email)
|
|
394
395
|
.groupBy("users.id", "users.email")
|
|
396
|
+
.limit(10)
|
|
395
397
|
.compile();
|
|
396
398
|
const dashboard = await db.sql`${grouped} HAVING count(posts.id) > ${0}`;
|
|
397
399
|
```
|
|
@@ -459,7 +461,7 @@ const db = createNeoOrmClient(manifest, {
|
|
|
459
461
|
});
|
|
460
462
|
```
|
|
461
463
|
|
|
462
|
-
See [SQLite](sqlite.md) for type mapping and limitations.
|
|
464
|
+
See [SQLite](sqlite.md), [MySQL](mysql.md), and [MariaDB](mariadb.md) for type mapping and limitations.
|
|
463
465
|
|
|
464
466
|
Log compiled SQL:
|
|
465
467
|
|
package/docs/getting-started.md
CHANGED
|
@@ -89,6 +89,32 @@ export default defineConfig({
|
|
|
89
89
|
bunx neoorm generate
|
|
90
90
|
```
|
|
91
91
|
|
|
92
|
+
To emit Zod, TypeBox, or Elysia Select/Create/Update schemas, install the library and set `generate.zod` / `generate.typebox` / `generate.elysia` in config:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
bun add zod
|
|
96
|
+
bun add typebox
|
|
97
|
+
bun add elysia
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
export default defineConfig({
|
|
102
|
+
schema: "./schema.ts",
|
|
103
|
+
out: "./neoorm",
|
|
104
|
+
datasource: {
|
|
105
|
+
provider: "postgresql",
|
|
106
|
+
url: process.env.DATABASE_URL!,
|
|
107
|
+
},
|
|
108
|
+
generate: {
|
|
109
|
+
zod: true,
|
|
110
|
+
typebox: true,
|
|
111
|
+
elysia: true,
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
`neoorm generate` / `neoorm migrate dev` then writes `out/zod.ts`, `out/typebox.ts`, and/or `out/elysia.ts` (re-exported from `out/client.ts`). See [Zod schemas](zod.md), [TypeBox schemas](typebox.md), and [Elysia schemas](elysia.md). `neoorm init` leaves this commented in `neoorm.config.ts`.
|
|
117
|
+
|
|
92
118
|
## SQLite
|
|
93
119
|
|
|
94
120
|
Set `provider: "sqlite"` and `url` to a file path or `:memory:`:
|
|
@@ -110,7 +136,7 @@ const db = createNeoOrmClient(manifest, {
|
|
|
110
136
|
});
|
|
111
137
|
```
|
|
112
138
|
|
|
113
|
-
See [SQLite](sqlite.md).
|
|
139
|
+
See [SQLite](sqlite.md), [MySQL](mysql.md), and [MariaDB](mariadb.md).
|
|
114
140
|
|
|
115
141
|
## Tenant-specific schemas
|
|
116
142
|
|
|
@@ -121,7 +147,7 @@ const tenantDb = createNeoOrmClient(manifest, {
|
|
|
121
147
|
});
|
|
122
148
|
```
|
|
123
149
|
|
|
124
|
-
Raw `db.sql` uses the same compiler as `neoorm/sql`. `db.sql` / `db.execute`
|
|
150
|
+
Raw `db.sql` uses the same compiler as `neoorm/sql`. With PostgreSQL `schema: "tenant_acme"`, `db.sql` / `db.execute` qualify unqualified table names from your manifest (`FROM users` → `"tenant_acme"."users"`). `db.sqlId("users")` is schema-qualified; column `sqlId`s are not. Explicit `schema.table` refs are left alone.
|
|
125
151
|
|
|
126
152
|
Reuse an existing `pg` pool with `createNeoOrmClientFromPool(manifest, pool)`, or an existing SQLite handle with `createNeoOrmClientFromSqlite(manifest, database)`. `$disconnect()` does not close a borrowed pool or database — close it yourself when every consumer is done.
|
|
127
153
|
|
package/docs/mariadb.md
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# MariaDB
|
|
2
|
+
|
|
3
|
+
MariaDB 10.11 LTS is a first-class dialect via the optional official `mariadb` connector. Schema DSL, codegen, migrations, and the query client work the same way as PostgreSQL, with the storage and SQL differences below.
|
|
4
|
+
|
|
5
|
+
MariaDB versions below 10.11, GIS, Galera, and MaxScale specifics are out of scope. MySQL 8 uses a **separate** dialect and the `mysql2` driver — see [MySQL](mysql.md).
|
|
6
|
+
|
|
7
|
+
## Requirements
|
|
8
|
+
|
|
9
|
+
Install the driver next to NeoOrm:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
bun add neoorm mariadb
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
If `mariadb` is missing, creating a client throws: `mariadb is not installed. Run: bun add mariadb`.
|
|
16
|
+
|
|
17
|
+
## Configuration
|
|
18
|
+
|
|
19
|
+
Set `provider: "mariadb"` and a MariaDB 10.11 connection URL:
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
// neoorm.config.ts
|
|
23
|
+
import { defineConfig } from "neoorm";
|
|
24
|
+
|
|
25
|
+
export default defineConfig({
|
|
26
|
+
schema: "./schema.ts",
|
|
27
|
+
out: "./neoorm",
|
|
28
|
+
datasource: {
|
|
29
|
+
provider: "mariadb",
|
|
30
|
+
url: process.env.DATABASE_URL ?? "mariadb://root@localhost:3306/myapp",
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
`datasource.schema` is ignored (the database comes from the URL). `datasource.enum: "native"` is allowed and emits column `ENUM('a','b')` — there is no `CREATE TYPE`.
|
|
36
|
+
|
|
37
|
+
## Runtime client
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
import { createNeoOrmClient } from "neoorm";
|
|
41
|
+
import { manifest } from "./neoorm/manifest.js";
|
|
42
|
+
|
|
43
|
+
const db = createNeoOrmClient(manifest, {
|
|
44
|
+
provider: "mariadb",
|
|
45
|
+
connectionString: process.env.MARIADB_URL,
|
|
46
|
+
});
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Wrap an existing `mariadb` pool with `createNeoOrmClientFromMariadb(manifest, pool)`. `$disconnect()` does not call `pool.end()` in that case — you own the pool.
|
|
50
|
+
|
|
51
|
+
Data queries use connector `execute()` (prepared statements, `prepareCacheLength` 256). Transaction control stays on `query()`. Pools you wrap without `execute` fall back to `query()`.
|
|
52
|
+
|
|
53
|
+
Owned pools from `createNeoOrmClient` accept the same `pool` object as PostgreSQL for shared fields (`max`, idle timeout, keep-alive). Default `max` is 10. Pipelining is enabled (commands are still awaited in order). PostgreSQL-only keys such as `statement_timeout` are ignored.
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
const db = createNeoOrmClient(manifest, {
|
|
57
|
+
provider: "mariadb",
|
|
58
|
+
connectionString: process.env.MARIADB_URL,
|
|
59
|
+
pool: {
|
|
60
|
+
max: 10,
|
|
61
|
+
idleTimeoutMillis: 10_000,
|
|
62
|
+
keepAlive: true,
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Standalone `neoorm/sql` (`sqlId`) stays ANSI-quoted (`"users"`). Use `db.sql` with `db.sqlId("users")` so identifiers are backticks on MariaDB.
|
|
68
|
+
|
|
69
|
+
`mariadbDialect` is exported from `neoorm` for `dbPush`, migrate helpers, and custom executor wiring.
|
|
70
|
+
|
|
71
|
+
## CLI
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
bunx neoorm init --provider mariadb
|
|
75
|
+
bunx neoorm migrate deploy
|
|
76
|
+
bunx neoorm db push
|
|
77
|
+
bunx neoorm db pull
|
|
78
|
+
bunx neoorm migrate status
|
|
79
|
+
bunx neoorm migrate reset --force
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
- Deploy lock is `GET_LOCK('neoorm.migrate.<db>', timeout)` / `RELEASE_LOCK` on the deploy transaction.
|
|
83
|
+
- `migrate reset` sets `FOREIGN_KEY_CHECKS=0`, drops all tables in the current database, then re-enables checks and re-applies migrations.
|
|
84
|
+
- `db pull` introspects `information_schema`. MariaDB `JSON` columns are often `LONGTEXT` plus a `json_valid()` CHECK; NeoOrm maps those back to `jsonb()`.
|
|
85
|
+
|
|
86
|
+
## Type mapping
|
|
87
|
+
|
|
88
|
+
| Schema builder | MariaDB storage |
|
|
89
|
+
|----------------|-----------------|
|
|
90
|
+
| `id()`, unique/PK `text` | `VARCHAR(191)` (InnoDB index prefix; `TEXT` cannot be a unique key) |
|
|
91
|
+
| `text()` otherwise | `TEXT`, or `VARCHAR(n)` with `.maxLength()` |
|
|
92
|
+
| `uuid()` | `CHAR(36)` |
|
|
93
|
+
| `bool()` | `TINYINT(1)` |
|
|
94
|
+
| `int()` | `INT` |
|
|
95
|
+
| `bigint()` | `BIGINT` |
|
|
96
|
+
| `real()` / `float()` | `FLOAT` |
|
|
97
|
+
| `double()` | `DOUBLE` |
|
|
98
|
+
| `serial()` | `INT NOT NULL AUTO_INCREMENT` |
|
|
99
|
+
| `timestamp()` | `DATETIME(6)` + `CURRENT_TIMESTAMP(6)` |
|
|
100
|
+
| `date()` | `DATE` |
|
|
101
|
+
| `time()` | `TIME` |
|
|
102
|
+
| `json()` / `jsonb()` | `JSON` (LONGTEXT + `json_valid()` CHECK under the hood) |
|
|
103
|
+
| `decimal()` | `DECIMAL(p,s)` |
|
|
104
|
+
| `money()` | `DECIMAL(19,4)` |
|
|
105
|
+
| `xml()` | `LONGTEXT` |
|
|
106
|
+
| `bytea()` | `BLOB` |
|
|
107
|
+
| arrays / `citext()` | `JSON` / `VARCHAR` + `utf8mb4_uca1400_ai_ci` |
|
|
108
|
+
| `interval()`, `inet()`, `cidr()`, ranges | rejected at schema compile |
|
|
109
|
+
| `enum: "check"` | `VARCHAR` + `CHECK` |
|
|
110
|
+
| `enum: "native"` | column `ENUM('a','b')` |
|
|
111
|
+
|
|
112
|
+
## Differences from MySQL 8
|
|
113
|
+
|
|
114
|
+
| Feature | MySQL 8 | MariaDB 10.11 |
|
|
115
|
+
|---------|---------|----------------|
|
|
116
|
+
| Driver | `mysql2` | official `mariadb` package |
|
|
117
|
+
| `upsert` | `INSERT … AS new ON DUPLICATE KEY UPDATE` | `ON DUPLICATE KEY UPDATE col = VALUES(col)` |
|
|
118
|
+
| `search` | `REGEXP_LIKE` | `col REGEXP $n` (`(?i)` for insensitive) |
|
|
119
|
+
| `citext` collation | `utf8mb4_0900_ai_ci` | `utf8mb4_uca1400_ai_ci` |
|
|
120
|
+
| CHECK drop | `DROP CHECK` | `DROP CONSTRAINT` |
|
|
121
|
+
| CHECK errno | 3819 | 4025 (`ER_CONSTRAINT_FAILED`) |
|
|
122
|
+
| JSON storage | native JSON | JSON as LONGTEXT + `json_valid()` |
|
|
123
|
+
| `RETURNING` | none | INSERT/DELETE RETURNING exist, but UPDATE does not; NeoOrm uses follow-up `SELECT` for all writes |
|
|
124
|
+
|
|
125
|
+
## Differences from PostgreSQL
|
|
126
|
+
|
|
127
|
+
| Feature | PostgreSQL | MariaDB |
|
|
128
|
+
|---------|------------|---------|
|
|
129
|
+
| Identifier quoting | `"users"` | `` `users` `` |
|
|
130
|
+
| `RETURNING` | native | follow-up `SELECT` (or `insertId` for serial) |
|
|
131
|
+
| `upsert` | `ON CONFLICT … DO UPDATE` | `ON DUPLICATE KEY UPDATE` + `VALUES(col)` |
|
|
132
|
+
| `skipDuplicates` | `ON CONFLICT DO NOTHING` | `INSERT IGNORE` |
|
|
133
|
+
| `findOrCreate` | `xmax = 0` | SELECT → INSERT → retry on unique violation |
|
|
134
|
+
| `in` / `notIn` | array bind | `JSON_TABLE` |
|
|
135
|
+
| `search` | POSIX `~` | `REGEXP` |
|
|
136
|
+
| `ilike` | `ILIKE` | `LOWER(col) LIKE LOWER(?)` |
|
|
137
|
+
| JSON operators | `@>`, `?`, `#>` | `JSON_CONTAINS` / `JSON_EXTRACT` / `JSON_CONTAINS_PATH` |
|
|
138
|
+
| Nested includes | `json_agg … FILTER` | JOIN `JSON_ARRAYAGG` when possible; otherwise batched `IN` queries (no `LATERAL`) |
|
|
139
|
+
| `distinct` (`DISTINCT ON`) | supported | throws |
|
|
140
|
+
| Partial indexes `index({ where })` | supported | rejected at schema compile |
|
|
141
|
+
| PostGIS | supported | rejected |
|
|
142
|
+
| `interval` / `inet` / `cidr` / range types | supported | rejected at schema compile |
|
|
143
|
+
| `datasource.schema` | multi-schema | ignored (URL database) |
|
|
144
|
+
|
|
145
|
+
MariaDB has no `LATERAL`, so correlated `JSON_ARRAYAGG` derived tables (the MySQL 8 / Postgres inline has-many subquery) cannot see outer columns such as `` `users`.`id` ``. Those includes are loaded with a follow-up `WHERE fk IN (…)` query instead.
|
|
146
|
+
|
|
147
|
+
`createManyAndReturn` for serial primary keys uses `LAST_INSERT_ID()` plus row count inside a transaction and assumes consecutive autoincrement values.
|
|
148
|
+
|
|
149
|
+
Everything else — relations, nested writes, cursor pagination, aggregates, `groupBy`, savepoint-based nested transactions — behaves the same as on PostgreSQL.
|
package/docs/migrations.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
| `neoorm migrate deploy` | Apply pending migrations |
|
|
11
11
|
| `neoorm migrate status` | List applied vs pending migrations |
|
|
12
12
|
| `neoorm migrate down [--steps N]` | Roll back the last N applied migrations (default 1) |
|
|
13
|
-
| `neoorm migrate reset --force` | Drop the `public` schema (PostgreSQL) or all tables (SQLite) and re-apply migrations (local dev) |
|
|
13
|
+
| `neoorm migrate reset --force` | Drop the `public` schema (PostgreSQL) or all tables (SQLite / MySQL / MariaDB) and re-apply migrations (local dev) |
|
|
14
14
|
| `neoorm db push` | Push the current `schema.ts` to the database (no migration file) |
|
|
15
15
|
| `neoorm db pull` | Introspect the database into a schema file |
|
|
16
16
|
|
|
@@ -38,7 +38,9 @@ neoorm generate --accept-data-loss
|
|
|
38
38
|
| Dialect | Lock |
|
|
39
39
|
|---------|------|
|
|
40
40
|
| PostgreSQL | `pg_advisory_xact_lock` on the deploy transaction |
|
|
41
|
-
| SQLite | `BEGIN IMMEDIATE` around the whole deploy |
|
|
41
|
+
| SQLite | `BEGIN IMMEDIATE` around the whole deploy (after `PRAGMA foreign_keys = OFF`) |
|
|
42
|
+
| MySQL | `GET_LOCK('neoorm.migrate.<db>', timeout)` / `RELEASE_LOCK` on the deploy connection |
|
|
43
|
+
| MariaDB | `GET_LOCK('neoorm.migrate.<db>', timeout)` / `RELEASE_LOCK` on the deploy connection |
|
|
42
44
|
|
|
43
45
|
The ledger table `_neoorm_migrations` stores `name` and `checksum`. Editing an already-applied `migration.sql` is rejected (`migration_guard`) — restore the original file or add a new migration. Pending migrations in one deploy run apply in that locked transaction; if a later statement fails, none of that run's new ledger rows remain.
|
|
44
46
|
|
|
@@ -56,7 +58,7 @@ Shows applied migrations (with timestamps), pending folders on disk, and warning
|
|
|
56
58
|
neoorm migrate reset --force
|
|
57
59
|
```
|
|
58
60
|
|
|
59
|
-
Drops the `public` schema (PostgreSQL) or all tables (SQLite) and re-applies all migrations from disk. Requires `--force`. Use `--skip-apply` to only drop without re-applying.
|
|
61
|
+
Drops the `public` schema (PostgreSQL) or all tables (SQLite, MySQL, and MariaDB) and re-applies all migrations from disk. Requires `--force`. Use `--skip-apply` to only drop without re-applying.
|
|
60
62
|
|
|
61
63
|
PostgreSQL reset recreates the schema owned by the connecting role. It does not `GRANT ALL ON SCHEMA … TO PUBLIC`.
|
|
62
64
|
|
package/docs/mysql.md
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# MySQL
|
|
2
|
+
|
|
3
|
+
MySQL 8.0+ is a first-class dialect via the optional `mysql2` driver. Schema DSL, codegen, migrations, and the query client work against MySQL the same way they do against PostgreSQL, with the storage and SQL differences below.
|
|
4
|
+
|
|
5
|
+
PlanetScale, MySQL 5.7, and GIS/PostGIS are out of scope.
|
|
6
|
+
|
|
7
|
+
## Requirements
|
|
8
|
+
|
|
9
|
+
Install the driver next to NeoOrm:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
bun add neoorm mysql2
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
If `mysql2` is missing, creating a client throws: `mysql2 is not installed. Run: bun add mysql2`.
|
|
16
|
+
|
|
17
|
+
## Configuration
|
|
18
|
+
|
|
19
|
+
Set `provider: "mysql"` and a MySQL 8 connection URL:
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
// neoorm.config.ts
|
|
23
|
+
import { defineConfig } from "neoorm";
|
|
24
|
+
|
|
25
|
+
export default defineConfig({
|
|
26
|
+
schema: "./schema.ts",
|
|
27
|
+
out: "./neoorm",
|
|
28
|
+
datasource: {
|
|
29
|
+
provider: "mysql",
|
|
30
|
+
url: process.env.DATABASE_URL ?? "mysql://root@localhost:3306/myapp",
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
`datasource.schema` is ignored (the database comes from the URL). `datasource.enum: "native"` is allowed and emits column `ENUM('a','b')` — there is no `CREATE TYPE`.
|
|
36
|
+
|
|
37
|
+
## Runtime client
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
import { createNeoOrmClient } from "neoorm";
|
|
41
|
+
import { manifest } from "./neoorm/manifest.js";
|
|
42
|
+
|
|
43
|
+
const db = createNeoOrmClient(manifest, {
|
|
44
|
+
provider: "mysql",
|
|
45
|
+
connectionString: process.env.MYSQL_URL,
|
|
46
|
+
});
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Wrap an existing `mysql2/promise` pool with `createNeoOrmClientFromMysql(manifest, pool)`. `$disconnect()` does not call `pool.end()` in that case — you own the pool.
|
|
50
|
+
|
|
51
|
+
Data queries use mysql2 `execute()` (binary prepared statements, cached per connection). Transaction control (`START TRANSACTION`, `COMMIT`, `SAVEPOINT`) stays on `query()`. Pools you wrap without `execute` fall back to `query()`.
|
|
52
|
+
|
|
53
|
+
Owned pools from `createNeoOrmClient` accept the same `pool` object as PostgreSQL for shared fields (`max`, idle timeout, keep-alive). Default `max` is 10 (`connectionLimit`). PostgreSQL-only keys such as `statement_timeout` are ignored.
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
const db = createNeoOrmClient(manifest, {
|
|
57
|
+
provider: "mysql",
|
|
58
|
+
connectionString: process.env.MYSQL_URL,
|
|
59
|
+
pool: {
|
|
60
|
+
max: 10,
|
|
61
|
+
idleTimeoutMillis: 10_000,
|
|
62
|
+
keepAlive: true,
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Standalone `neoorm/sql` (`sqlId`) stays ANSI-quoted (`"users"`). Use `db.sql` with `db.sqlId("users")` so identifiers are backticks on MySQL.
|
|
68
|
+
|
|
69
|
+
`mysqlDialect` is exported from `neoorm` for `dbPush`, migrate helpers, and custom executor wiring.
|
|
70
|
+
|
|
71
|
+
## CLI
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
bunx neoorm init --provider mysql
|
|
75
|
+
bunx neoorm migrate deploy
|
|
76
|
+
bunx neoorm db push
|
|
77
|
+
bunx neoorm db pull
|
|
78
|
+
bunx neoorm migrate status
|
|
79
|
+
bunx neoorm migrate reset --force
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
- Deploy lock is `GET_LOCK('neoorm.migrate.<db>', timeout)` / `RELEASE_LOCK` on the deploy transaction.
|
|
83
|
+
- `migrate reset` sets `FOREIGN_KEY_CHECKS=0`, drops all tables in the current database, then re-enables checks and re-applies migrations.
|
|
84
|
+
- `db pull` introspects `information_schema` back into a schema file.
|
|
85
|
+
|
|
86
|
+
## Type mapping
|
|
87
|
+
|
|
88
|
+
| Schema builder | MySQL storage |
|
|
89
|
+
|----------------|---------------|
|
|
90
|
+
| `id()`, unique/PK `text` | `VARCHAR(191)` (InnoDB index prefix; `TEXT` cannot be a unique key) |
|
|
91
|
+
| `text()` otherwise | `TEXT`, or `VARCHAR(n)` with `.maxLength()` |
|
|
92
|
+
| `uuid()` | `CHAR(36)` |
|
|
93
|
+
| `bool()` | `TINYINT(1)` |
|
|
94
|
+
| `int()` | `INT` |
|
|
95
|
+
| `bigint()` | `BIGINT` |
|
|
96
|
+
| `real()` / `float()` | `FLOAT` |
|
|
97
|
+
| `double()` | `DOUBLE` |
|
|
98
|
+
| `serial()` | `INT NOT NULL AUTO_INCREMENT` |
|
|
99
|
+
| `timestamp()` | `DATETIME(6)` + `CURRENT_TIMESTAMP(6)` |
|
|
100
|
+
| `date()` | `DATE` |
|
|
101
|
+
| `time()` | `TIME` |
|
|
102
|
+
| `json()` / `jsonb()` | `JSON` |
|
|
103
|
+
| `decimal()` | `DECIMAL(p,s)` |
|
|
104
|
+
| `money()` | `DECIMAL(19,4)` |
|
|
105
|
+
| `xml()` | `LONGTEXT` |
|
|
106
|
+
| `bytea()` | `BLOB` |
|
|
107
|
+
| arrays / `citext()` | `JSON` / `VARCHAR` + `utf8mb4_0900_ai_ci` |
|
|
108
|
+
| `interval()`, `inet()`, `cidr()`, ranges | rejected at schema compile |
|
|
109
|
+
| `enum: "check"` | `VARCHAR` + `CHECK` (8.0.16+) |
|
|
110
|
+
| `enum: "native"` | column `ENUM('a','b')` |
|
|
111
|
+
|
|
112
|
+
## Differences from PostgreSQL
|
|
113
|
+
|
|
114
|
+
| Feature | PostgreSQL | MySQL |
|
|
115
|
+
|---------|------------|--------|
|
|
116
|
+
| Identifier quoting | `"users"` | `` `users` `` |
|
|
117
|
+
| `RETURNING` | native | follow-up `SELECT` (or `insertId` for serial) |
|
|
118
|
+
| `upsert` | `ON CONFLICT … DO UPDATE` | `INSERT … AS new ON DUPLICATE KEY UPDATE` |
|
|
119
|
+
| `skipDuplicates` | `ON CONFLICT DO NOTHING` | `INSERT IGNORE` |
|
|
120
|
+
| `findOrCreate` | `xmax = 0` | SELECT → INSERT → retry on unique violation |
|
|
121
|
+
| `in` / `notIn` | array bind | `JSON_TABLE` |
|
|
122
|
+
| `search` | POSIX `~` | `REGEXP_LIKE` |
|
|
123
|
+
| `ilike` | `ILIKE` | `LOWER(col) LIKE LOWER(?)` |
|
|
124
|
+
| JSON operators | `@>`, `?`, `#>` | `JSON_CONTAINS` / `JSON_EXTRACT` / `JSON_CONTAINS_PATH` |
|
|
125
|
+
| Nested includes | `json_agg … FILTER` | `JSON_ARRAYAGG(CASE WHEN …)` |
|
|
126
|
+
| `distinct` (`DISTINCT ON`) | supported | throws |
|
|
127
|
+
| Partial indexes `index({ where })` | supported | rejected at schema compile |
|
|
128
|
+
| PostGIS | supported | rejected |
|
|
129
|
+
| `interval` / `inet` / `cidr` / range types | supported | rejected at schema compile |
|
|
130
|
+
| `datasource.schema` | multi-schema | ignored (URL database) |
|
|
131
|
+
|
|
132
|
+
`createManyAndReturn` for serial primary keys uses `LAST_INSERT_ID()` plus row count inside a transaction and assumes consecutive autoincrement values.
|
|
133
|
+
|
|
134
|
+
Everything else — relations, nested writes, cursor pagination, aggregates, `groupBy`, savepoint-based nested transactions — behaves the same as on PostgreSQL.
|
package/docs/plugins.md
CHANGED
|
@@ -48,6 +48,8 @@ users: table({
|
|
|
48
48
|
|
|
49
49
|
See the plugin registry source for `ColumnTypePlugin` and `NeoOrmPlugin` interfaces.
|
|
50
50
|
|
|
51
|
+
Column types may implement `columnValidation(col)` returning a validator-neutral IR node (`{ kind: "string" }`, `{ kind: "enum", values }`, GeoJSON `object` / `union`, and so on). Zod, TypeBox, and Elysia codegen print that IR. Omit the hook to fall back to `unknown`.
|
|
52
|
+
|
|
51
53
|
To type `where` operators, augment `PluginColumnWhereOperators` on `neoorm/schema` with your column kind:
|
|
52
54
|
|
|
53
55
|
```ts
|