@mikro-orm/pglite 7.0.18-dev.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 Martin Adámek
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,10 @@
1
+ import { PGliteDialect } from 'kysely';
2
+ import { AbstractSqlConnection, type Dictionary } from '@mikro-orm/sql';
3
+ /** PostgreSQL-in-WASM database connection using `@electric-sql/pglite`. */
4
+ export declare class PgliteConnection extends AbstractSqlConnection {
5
+ #private;
6
+ createKyselyDialect(overrides: Dictionary): PGliteDialect;
7
+ close(force?: boolean): Promise<void>;
8
+ /** PGlite supports multi-statement scripts via `exec()`, which is what schema dumps need. */
9
+ executeDump(source: string): Promise<void>;
10
+ }
@@ -0,0 +1,77 @@
1
+ import { PGlite } from '@electric-sql/pglite';
2
+ import { PGliteDialect } from 'kysely';
3
+ import array from 'postgres-array';
4
+ import { AbstractSqlConnection, createPostgreSqlTypeParsers } from '@mikro-orm/sql';
5
+ const isInMemoryDataDir = (dataDir) => !dataDir || dataDir === 'memory://' || dataDir.startsWith('memory:');
6
+ /** PostgreSQL-in-WASM database connection using `@electric-sql/pglite`. */
7
+ export class PgliteConnection extends AbstractSqlConnection {
8
+ // Stored as a Promise so `createKyselyDialect` can stay synchronous (else
9
+ // `getClient()` would throw "Current driver requires async initialization")
10
+ // while `executeDump` and the kysely dialect both `await` the same instance.
11
+ #pglite;
12
+ #neuterClose = false;
13
+ #ownsPglite = true;
14
+ createKyselyDialect(overrides) {
15
+ const onCreateConnection = this.options.onCreateConnection ?? this.config.get('onCreateConnection');
16
+ const options = (overrides ?? {});
17
+ const { pglite: userPglite, ...pgliteOptions } = options;
18
+ const dataDir = options.dataDir ?? this.config.get('dbName');
19
+ const parsers = { ...createPostgreSqlTypeParsers(s => array.parse(s)), ...options.parsers };
20
+ this.#ownsPglite = !userPglite;
21
+ // Skip `pglite.close()` (called by kysely's `PGliteDriver.destroy()`) when:
22
+ // - the user owns the instance (closing it is their responsibility), or
23
+ // - we hold an in-memory DB whose data would otherwise be lost on
24
+ // reconnect (e.g. test harnesses that drive `orm.close()` + `orm.connect()`).
25
+ // For file/IDB-backed instances we let kysely close so file handles / IDB
26
+ // connections are released; we drop our cached promise in `close()` below
27
+ // so the next dialect-construction rebuilds the PGlite instance.
28
+ this.#neuterClose = !this.#ownsPglite || isInMemoryDataDir(dataDir);
29
+ if (!this.#pglite) {
30
+ if (userPglite) {
31
+ this.#pglite = typeof userPglite === 'function' ? Promise.resolve(userPglite()) : Promise.resolve(userPglite);
32
+ }
33
+ else {
34
+ this.#pglite = PGlite.create({ ...pgliteOptions, dataDir, parsers });
35
+ }
36
+ }
37
+ if (this.#neuterClose) {
38
+ // Hand kysely a delegating wrapper rather than mutating the underlying
39
+ // instance — proxies can't pierce PGlite's private fields, and patching
40
+ // `close` directly would orphan a user-supplied PGlite (its real `close`
41
+ // would stay neutered after `orm.close()`). Each method call hits the
42
+ // original `p`, so `#private` fields stay reachable.
43
+ const sharedPglitePromise = this.#pglite.then(p => ({
44
+ query: p.query.bind(p),
45
+ transaction: p.transaction.bind(p),
46
+ close: () => Promise.resolve(),
47
+ get closed() {
48
+ return p.closed;
49
+ },
50
+ get ready() {
51
+ return p.ready;
52
+ },
53
+ // `waitReady` is a stable Promise on the underlying instance — capture it
54
+ // directly so coverage doesn't hinge on `kysely` actually awaiting it (which
55
+ // only happens in the WASM-not-yet-loaded transient window).
56
+ waitReady: p.waitReady,
57
+ }));
58
+ return new PGliteDialect({ pglite: () => sharedPglitePromise, onCreateConnection });
59
+ }
60
+ return new PGliteDialect({ pglite: () => this.#pglite, onCreateConnection });
61
+ }
62
+ async close(force) {
63
+ await super.close(force);
64
+ // Persistent backings (file/IDB) we own get really closed by kysely — drop
65
+ // the cached promise so a subsequent reconnect rebuilds a fresh instance
66
+ // (which then re-reads the persisted data from disk / IDB).
67
+ if (this.#ownsPglite && !this.#neuterClose) {
68
+ this.#pglite = undefined;
69
+ }
70
+ }
71
+ /** PGlite supports multi-statement scripts via `exec()`, which is what schema dumps need. */
72
+ async executeDump(source) {
73
+ await this.ensureConnection();
74
+ const pglite = await this.#pglite;
75
+ await pglite.exec(source);
76
+ }
77
+ }
@@ -0,0 +1,12 @@
1
+ import { type Configuration, type Constructor, EntityManagerType } from '@mikro-orm/core';
2
+ import { AbstractSqlDriver, BasePostgreSqlEntityManager } from '@mikro-orm/sql';
3
+ import { PgliteConnection } from './PgliteConnection.js';
4
+ import { PgliteMikroORM } from './PgliteMikroORM.js';
5
+ /** Database driver for PGlite (PostgreSQL in WASM). */
6
+ export declare class PgliteDriver extends AbstractSqlDriver<PgliteConnection> {
7
+ [EntityManagerType]: BasePostgreSqlEntityManager<this>;
8
+ constructor(config: Configuration);
9
+ createEntityManager(useContext?: boolean): this[typeof EntityManagerType];
10
+ /** @inheritDoc */
11
+ getORMClass(): Constructor<PgliteMikroORM>;
12
+ }
@@ -0,0 +1,20 @@
1
+ import { EntityManagerType } from '@mikro-orm/core';
2
+ import { AbstractSqlDriver, BasePostgreSqlEntityManager } from '@mikro-orm/sql';
3
+ import { PgliteConnection } from './PgliteConnection.js';
4
+ import { PglitePlatform } from './PglitePlatform.js';
5
+ import { PgliteMikroORM } from './PgliteMikroORM.js';
6
+ /** Database driver for PGlite (PostgreSQL in WASM). */
7
+ export class PgliteDriver extends AbstractSqlDriver {
8
+ [EntityManagerType];
9
+ constructor(config) {
10
+ super(config, new PglitePlatform(), PgliteConnection, ['kysely', '@electric-sql/pglite']);
11
+ }
12
+ createEntityManager(useContext) {
13
+ const EntityManagerClass = this.config.get('entityManager', BasePostgreSqlEntityManager);
14
+ return new EntityManagerClass(this.config, this, this.metadata, useContext);
15
+ }
16
+ /** @inheritDoc */
17
+ getORMClass() {
18
+ return PgliteMikroORM;
19
+ }
20
+ }
@@ -0,0 +1,20 @@
1
+ import { type AnyEntity, type EntityClass, type EntitySchema, type MikroORM, type Options, type IDatabaseDriver, type EntityManager, type EntityManagerType } from '@mikro-orm/core';
2
+ import { SqlMikroORM, type BasePostgreSqlEntityManager } from '@mikro-orm/sql';
3
+ import { PgliteDriver } from './PgliteDriver.js';
4
+ /** Configuration options for the PGlite driver. */
5
+ export type PgliteOptions<EM extends BasePostgreSqlEntityManager<PgliteDriver> = BasePostgreSqlEntityManager<PgliteDriver>, Entities extends readonly (string | EntityClass<AnyEntity> | EntitySchema)[] = (string | EntityClass<AnyEntity> | EntitySchema)[]> = Partial<Options<PgliteDriver, EM, Entities>>;
6
+ /** Creates a type-safe configuration object for the PGlite driver. */
7
+ export declare function definePgliteConfig<EM extends BasePostgreSqlEntityManager<PgliteDriver> = BasePostgreSqlEntityManager<PgliteDriver>, Entities extends readonly (string | EntityClass<AnyEntity> | EntitySchema)[] = (string | EntityClass<AnyEntity> | EntitySchema)[]>(options: PgliteOptions<EM, Entities>): PgliteOptions<EM, Entities>;
8
+ /**
9
+ * @inheritDoc
10
+ */
11
+ export declare class PgliteMikroORM<EM extends BasePostgreSqlEntityManager<PgliteDriver> = BasePostgreSqlEntityManager<PgliteDriver>, Entities extends readonly (string | EntityClass<AnyEntity> | EntitySchema)[] = (string | EntityClass<AnyEntity> | EntitySchema)[]> extends SqlMikroORM<PgliteDriver, EM, Entities> {
12
+ /**
13
+ * @inheritDoc
14
+ */
15
+ static init<D extends IDatabaseDriver = PgliteDriver, EM extends EntityManager<D> = D[typeof EntityManagerType] & EntityManager<D>, Entities extends readonly (string | EntityClass<AnyEntity> | EntitySchema)[] = (string | EntityClass<AnyEntity> | EntitySchema)[]>(options: Partial<Options<D, EM, Entities>>): Promise<MikroORM<D, EM, Entities>>;
16
+ /**
17
+ * @inheritDoc
18
+ */
19
+ constructor(options: Partial<Options<PgliteDriver, EM, Entities>>);
20
+ }
@@ -0,0 +1,26 @@
1
+ import { defineConfig, } from '@mikro-orm/core';
2
+ import { SqlMikroORM } from '@mikro-orm/sql';
3
+ import { PgliteDriver } from './PgliteDriver.js';
4
+ /** Creates a type-safe configuration object for the PGlite driver. */
5
+ export function definePgliteConfig(options) {
6
+ // PGlite defaults to in-memory storage; satisfy MikroORM's `dbName` validation
7
+ // without forcing every user to spell it out.
8
+ return defineConfig({ driver: PgliteDriver, dbName: 'memory://', ...options });
9
+ }
10
+ /**
11
+ * @inheritDoc
12
+ */
13
+ export class PgliteMikroORM extends SqlMikroORM {
14
+ /**
15
+ * @inheritDoc
16
+ */
17
+ static async init(options) {
18
+ return super.init(definePgliteConfig(options));
19
+ }
20
+ /**
21
+ * @inheritDoc
22
+ */
23
+ constructor(options) {
24
+ super(definePgliteConfig(options));
25
+ }
26
+ }
@@ -0,0 +1,16 @@
1
+ import { type IPostgresInterval } from 'postgres-interval';
2
+ import { BasePostgreSqlPlatform } from '@mikro-orm/sql';
3
+ import { PgliteSchemaHelper } from './PgliteSchemaHelper.js';
4
+ /** Platform implementation for PGlite (PostgreSQL in WASM, single-database). */
5
+ export declare class PglitePlatform extends BasePostgreSqlPlatform {
6
+ protected readonly schemaHelper: PgliteSchemaHelper;
7
+ /** PGlite uses the extended query protocol — one statement per `query()` call. */
8
+ supportsMultipleStatements(): boolean;
9
+ convertIntervalToJSValue(value: string): unknown;
10
+ convertIntervalToDatabaseValue(value: IPostgresInterval): unknown;
11
+ unmarshallArray(value: string): string[];
12
+ /**
13
+ * @inheritDoc
14
+ */
15
+ parseDate(value: string | number): Date;
16
+ }
@@ -0,0 +1,45 @@
1
+ import array from 'postgres-array';
2
+ import parseDate from 'postgres-date';
3
+ import PostgresInterval from 'postgres-interval';
4
+ import { BasePostgreSqlPlatform, Utils } from '@mikro-orm/sql';
5
+ import { PgliteSchemaHelper } from './PgliteSchemaHelper.js';
6
+ /** Platform implementation for PGlite (PostgreSQL in WASM, single-database). */
7
+ export class PglitePlatform extends BasePostgreSqlPlatform {
8
+ schemaHelper = new PgliteSchemaHelper(this);
9
+ /** PGlite uses the extended query protocol — one statement per `query()` call. */
10
+ supportsMultipleStatements() {
11
+ return false;
12
+ }
13
+ convertIntervalToJSValue(value) {
14
+ return PostgresInterval(value);
15
+ }
16
+ convertIntervalToDatabaseValue(value) {
17
+ if (Utils.isObject(value) && 'toPostgres' in value && typeof value.toPostgres === 'function') {
18
+ return value.toPostgres();
19
+ }
20
+ return value;
21
+ }
22
+ unmarshallArray(value) {
23
+ return array.parse(value);
24
+ }
25
+ /**
26
+ * @inheritDoc
27
+ */
28
+ parseDate(value) {
29
+ // postgres-date returns `null` for a JS ISO string which has the `T` separator
30
+ if (typeof value === 'string' && value.charAt(10) === 'T') {
31
+ return new Date(value);
32
+ }
33
+ /* v8 ignore next */
34
+ if (typeof value === 'number') {
35
+ return new Date(value);
36
+ }
37
+ // @ts-ignore fix wrong type resolution during build
38
+ const parsed = parseDate(value);
39
+ /* v8 ignore next */
40
+ if (parsed === null) {
41
+ return value;
42
+ }
43
+ return parsed;
44
+ }
45
+ }
@@ -0,0 +1,12 @@
1
+ import type { Connection } from '@mikro-orm/core';
2
+ import { PostgreSqlSchemaHelper } from '@mikro-orm/sql';
3
+ /**
4
+ * PGlite is a single-database engine — there is no management catalog and no
5
+ * `CREATE DATABASE`. Override the relevant lifecycle hooks to no-ops.
6
+ */
7
+ export declare class PgliteSchemaHelper extends PostgreSqlSchemaHelper {
8
+ getManagementDbName(): string;
9
+ getCreateDatabaseSQL(): string;
10
+ getDropDatabaseSQL(): string;
11
+ databaseExists(_connection: Connection, _name: string): Promise<boolean>;
12
+ }
@@ -0,0 +1,19 @@
1
+ import { PostgreSqlSchemaHelper } from '@mikro-orm/sql';
2
+ /**
3
+ * PGlite is a single-database engine — there is no management catalog and no
4
+ * `CREATE DATABASE`. Override the relevant lifecycle hooks to no-ops.
5
+ */
6
+ export class PgliteSchemaHelper extends PostgreSqlSchemaHelper {
7
+ getManagementDbName() {
8
+ return '';
9
+ }
10
+ getCreateDatabaseSQL() {
11
+ return '';
12
+ }
13
+ getDropDatabaseSQL() {
14
+ return '';
15
+ }
16
+ async databaseExists(_connection, _name) {
17
+ return true;
18
+ }
19
+ }
package/README.md ADDED
@@ -0,0 +1,226 @@
1
+ <h1 align="center">
2
+ <a href="https://mikro-orm.io"><img src="https://raw.githubusercontent.com/mikro-orm/mikro-orm/master/docs/static/img/logo-readme.svg?sanitize=true" alt="MikroORM" /></a>
3
+ </h1>
4
+
5
+ TypeScript ORM for Node.js based on Data Mapper, [Unit of Work](https://mikro-orm.io/docs/unit-of-work/) and [Identity Map](https://mikro-orm.io/docs/identity-map/) patterns. Supports MongoDB, MySQL, MariaDB, PostgreSQL (including CockroachDB and PGlite), SQLite (including libSQL), MSSQL and Oracle databases.
6
+
7
+ > Heavily inspired by [Doctrine](https://www.doctrine-project.org/) and [Hibernate](https://hibernate.org/).
8
+
9
+ [![NPM version](https://img.shields.io/npm/v/@mikro-orm/core.svg)](https://npmx.dev/package/@mikro-orm/core)
10
+ [![NPM dev version](https://img.shields.io/npm/v/@mikro-orm/core/next.svg)](https://npmx.dev/package/@mikro-orm/core)
11
+ [![Chat on discord](https://img.shields.io/discord/1214904142443839538?label=discord&color=blue)](https://discord.gg/w8bjxFHS7X)
12
+ [![Downloads](https://img.shields.io/npm/dm/@mikro-orm/core.svg)](https://npmx.dev/package/@mikro-orm/core)
13
+ [![Coverage Status](https://img.shields.io/coveralls/mikro-orm/mikro-orm.svg)](https://coveralls.io/r/mikro-orm/mikro-orm?branch=master)
14
+ [![Build Status](https://github.com/mikro-orm/mikro-orm/workflows/tests/badge.svg?branch=master)](https://github.com/mikro-orm/mikro-orm/actions?workflow=tests)
15
+
16
+ ## Quick Start
17
+
18
+ Install a driver package for your database:
19
+
20
+ ```sh
21
+ npm install @mikro-orm/postgresql # PostgreSQL
22
+ npm install @mikro-orm/pglite # PGlite (embedded PostgreSQL in WASM)
23
+ npm install @mikro-orm/mysql # MySQL
24
+ npm install @mikro-orm/mariadb # MariaDB
25
+ npm install @mikro-orm/sqlite # SQLite
26
+ npm install @mikro-orm/libsql # libSQL / Turso
27
+ npm install @mikro-orm/mongodb # MongoDB
28
+ npm install @mikro-orm/mssql # MS SQL Server
29
+ npm install @mikro-orm/oracledb # Oracle
30
+ ```
31
+
32
+ > If you use additional packages like `@mikro-orm/cli`, `@mikro-orm/migrations`, or `@mikro-orm/entity-generator`, install `@mikro-orm/core` explicitly as well. See the [quick start guide](https://mikro-orm.io/docs/quick-start) for details.
33
+
34
+ ### Define Entities
35
+
36
+ The recommended way to define entities is using [`defineEntity`](https://mikro-orm.io/docs/define-entity) with `setClass`:
37
+
38
+ ```typescript
39
+ import { defineEntity, p, MikroORM } from '@mikro-orm/postgresql';
40
+
41
+ const AuthorSchema = defineEntity({
42
+ name: 'Author',
43
+ properties: {
44
+ id: p.integer().primary(),
45
+ name: p.string(),
46
+ email: p.string(),
47
+ born: p.datetime().nullable(),
48
+ books: () => p.oneToMany(Book).mappedBy('author'),
49
+ },
50
+ });
51
+
52
+ export class Author extends AuthorSchema.class {}
53
+ AuthorSchema.setClass(Author);
54
+
55
+ const BookSchema = defineEntity({
56
+ name: 'Book',
57
+ properties: {
58
+ id: p.integer().primary(),
59
+ title: p.string(),
60
+ author: () => p.manyToOne(Author).inversedBy('books'),
61
+ },
62
+ });
63
+
64
+ export class Book extends BookSchema.class {}
65
+ BookSchema.setClass(Book);
66
+ ```
67
+
68
+ You can also define entities using [decorators](https://mikro-orm.io/docs/using-decorators) or [`EntitySchema`](https://mikro-orm.io/docs/define-entity#entityschema-low-level-api). See the [defining entities guide](https://mikro-orm.io/docs/defining-entities) for all options.
69
+
70
+ ### Initialize and Use
71
+
72
+ ```typescript
73
+ import { MikroORM, RequestContext } from '@mikro-orm/postgresql';
74
+
75
+ const orm = await MikroORM.init({
76
+ entities: [Author, Book],
77
+ dbName: 'my-db',
78
+ });
79
+
80
+ // Create new entities
81
+ const author = orm.em.create(Author, {
82
+ name: 'Jon Snow',
83
+ email: 'snow@wall.st',
84
+ });
85
+ const book = orm.em.create(Book, {
86
+ title: 'My Life on The Wall',
87
+ author,
88
+ });
89
+
90
+ // Flush persists all tracked changes in a single transaction
91
+ await orm.em.flush();
92
+ ```
93
+
94
+ ### Querying
95
+
96
+ ```typescript
97
+ // Find with relations
98
+ const authors = await orm.em.findAll(Author, {
99
+ populate: ['books'],
100
+ orderBy: { name: 'asc' },
101
+ });
102
+
103
+ // Type-safe QueryBuilder
104
+ const qb = orm.em.createQueryBuilder(Author);
105
+ const result = await qb
106
+ .select('*')
107
+ .where({ books: { title: { $like: '%Wall%' } } })
108
+ .getResult();
109
+ ```
110
+
111
+ ### Request Context
112
+
113
+ In web applications, use `RequestContext` to isolate the identity map per request:
114
+
115
+ ```typescript
116
+ const app = express();
117
+
118
+ app.use((req, res, next) => {
119
+ RequestContext.create(orm.em, next);
120
+ });
121
+ ```
122
+
123
+ More info about `RequestContext` is described [here](https://mikro-orm.io/docs/identity-map/#request-context).
124
+
125
+ ## Unit of Work
126
+
127
+ > Unit of Work maintains a list of objects (_entities_) affected by a business transaction
128
+ > and coordinates the writing out of changes. [(Martin Fowler)](https://www.martinfowler.com/eaaCatalog/unitOfWork.html)
129
+
130
+ When you call `em.flush()`, all computed changes are queried inside a database transaction. This means you can control transaction boundaries simply by making changes to your entities and calling `flush()` when ready.
131
+
132
+ ```typescript
133
+ const author = await em.findOneOrFail(Author, 1, {
134
+ populate: ['books'],
135
+ });
136
+ author.name = 'Jon Snow II';
137
+ author.books.getItems().forEach(book => book.title += ' (2nd ed.)');
138
+ author.books.add(orm.em.create(Book, { title: 'New Book', author }));
139
+
140
+ // Flush computes change sets and executes them in a single transaction
141
+ await em.flush();
142
+ ```
143
+
144
+ The above flush will execute:
145
+
146
+ ```sql
147
+ begin;
148
+ update "author" set "name" = 'Jon Snow II' where "id" = 1;
149
+ update "book"
150
+ set "title" = case
151
+ when ("id" = 1) then 'My Life on The Wall (2nd ed.)'
152
+ when ("id" = 2) then 'Another Book (2nd ed.)'
153
+ else "title" end
154
+ where "id" in (1, 2);
155
+ insert into "book" ("title", "author_id") values ('New Book', 1);
156
+ commit;
157
+ ```
158
+
159
+ ## Core Features
160
+
161
+ - [Clean and Simple Entity Definition](https://mikro-orm.io/docs/defining-entities) — decorators, `EntitySchema`, or `defineEntity`
162
+ - [Identity Map](https://mikro-orm.io/docs/identity-map) and [Unit of Work](https://mikro-orm.io/docs/unit-of-work) — automatic change tracking
163
+ - [Entity References](https://mikro-orm.io/docs/entity-references) and [Collections](https://mikro-orm.io/docs/collections)
164
+ - [QueryBuilder](https://mikro-orm.io/docs/query-builder) and [Kysely Integration](https://mikro-orm.io/docs/kysely)
165
+ - [Transactions](https://mikro-orm.io/docs/transactions) and [Cascading](https://mikro-orm.io/docs/cascading)
166
+ - [Populating Relations](https://mikro-orm.io/docs/populating-relations) and [Loading Strategies](https://mikro-orm.io/docs/loading-strategies)
167
+ - [Filters](https://mikro-orm.io/docs/filters) and [Lifecycle Hooks](https://mikro-orm.io/docs/events#hooks)
168
+ - [Schema Generator](https://mikro-orm.io/docs/schema-generator) and [Migrations](https://mikro-orm.io/docs/migrations)
169
+ - [Entity Generator](https://mikro-orm.io/docs/entity-generator) and [Seeding](https://mikro-orm.io/docs/seeding)
170
+ - [Embeddables](https://mikro-orm.io/docs/embeddables), [Custom Types](https://mikro-orm.io/docs/custom-types), and [Serialization](https://mikro-orm.io/docs/serializing)
171
+ - [Composite and Foreign Keys as Primary Key](https://mikro-orm.io/docs/composite-keys)
172
+ - [Entity Constructors](https://mikro-orm.io/docs/entity-constructors) and [Property Validation](https://mikro-orm.io/docs/property-validation)
173
+ - [Modelling Relationships](https://mikro-orm.io/docs/relationships) and [Vanilla JS Support](https://mikro-orm.io/docs/usage-with-js)
174
+
175
+ ## Documentation
176
+
177
+ MikroORM documentation, included in this repo in the root directory, is built with [Docusaurus](https://docusaurus.io) and publicly hosted on GitHub Pages at https://mikro-orm.io.
178
+
179
+ There is also auto-generated [CHANGELOG.md](CHANGELOG.md) file based on commit messages (via `semantic-release`).
180
+
181
+ ## Example Integrations
182
+
183
+ You can find example integrations for some popular frameworks in the [`mikro-orm-examples` repository](https://github.com/mikro-orm/mikro-orm-examples):
184
+
185
+ ### TypeScript Examples
186
+
187
+ - [Express + MongoDB](https://github.com/mikro-orm/express-ts-example-app)
188
+ - [Nest + MySQL](https://github.com/mikro-orm/nestjs-example-app)
189
+ - [RealWorld example app (Nest + MySQL)](https://github.com/mikro-orm/nestjs-realworld-example-app)
190
+ - [Koa + SQLite](https://github.com/mikro-orm/koa-ts-example-app)
191
+ - [GraphQL + PostgreSQL](https://github.com/driescroons/mikro-orm-graphql-example)
192
+ - [Inversify + PostgreSQL](https://github.com/PodaruDragos/inversify-example-app)
193
+ - [NextJS + MySQL](https://github.com/jonahallibone/mikro-orm-nextjs)
194
+ - [Accounts.js REST and GraphQL authentication + SQLite](https://github.com/darkbasic/mikro-orm-accounts-example)
195
+ - [Nest + Shopify + PostgreSQL + GraphQL](https://github.com/Cloudshelf/Shopify_CSConnector)
196
+ - [Elysia.js + libSQL + Bun](https://github.com/mikro-orm/elysia-bun-example-app)
197
+ - [Electron.js + PostgreSQL](https://github.com/adnanlah/electron-mikro-orm-example-app)
198
+
199
+ ### JavaScript Examples
200
+
201
+ - [Express + SQLite](https://github.com/mikro-orm/express-js-example-app)
202
+
203
+ ## Contributing
204
+
205
+ Contributions, issues and feature requests are welcome. Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on the process for submitting pull requests to us.
206
+
207
+ ## Authors
208
+
209
+ **Martin Adámek**
210
+
211
+ - Twitter: [@B4nan](https://twitter.com/B4nan)
212
+ - Github: [@b4nan](https://github.com/b4nan)
213
+
214
+ See also the list of contributors who [participated](https://github.com/mikro-orm/mikro-orm/contributors) in this project.
215
+
216
+ ## Show Your Support
217
+
218
+ Please star this repository if this project helped you!
219
+
220
+ > If you'd like to support my open-source work, consider sponsoring me directly at [github.com/sponsors/b4nan](https://github.com/sponsors/b4nan).
221
+
222
+ ## License
223
+
224
+ Copyright © 2018-present [Martin Adámek](https://github.com/b4nan).
225
+
226
+ This project is licensed under the MIT License - see the [LICENSE file](LICENSE) for details.
package/index.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ export * from '@mikro-orm/sql';
2
+ export * from './PgliteConnection.js';
3
+ export * from './PgliteDriver.js';
4
+ export * from './PglitePlatform.js';
5
+ export * from './PgliteSchemaHelper.js';
6
+ export { PgliteMikroORM as MikroORM, type PgliteOptions as Options, definePgliteConfig as defineConfig, } from './PgliteMikroORM.js';
7
+ export { raw } from './raw.js';
package/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export * from '@mikro-orm/sql';
2
+ export * from './PgliteConnection.js';
3
+ export * from './PgliteDriver.js';
4
+ export * from './PglitePlatform.js';
5
+ export * from './PgliteSchemaHelper.js';
6
+ export { PgliteMikroORM as MikroORM, definePgliteConfig as defineConfig, } from './PgliteMikroORM.js';
7
+ export { raw } from './raw.js';
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "@mikro-orm/pglite",
3
+ "version": "7.0.18-dev.0",
4
+ "description": "TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.",
5
+ "keywords": [
6
+ "data-mapper",
7
+ "ddd",
8
+ "entity",
9
+ "identity-map",
10
+ "javascript",
11
+ "js",
12
+ "mariadb",
13
+ "mikro-orm",
14
+ "mongo",
15
+ "mongodb",
16
+ "mysql",
17
+ "orm",
18
+ "pglite",
19
+ "postgresql",
20
+ "sqlite",
21
+ "sqlite3",
22
+ "ts",
23
+ "typescript",
24
+ "unit-of-work"
25
+ ],
26
+ "homepage": "https://mikro-orm.io",
27
+ "bugs": {
28
+ "url": "https://github.com/mikro-orm/mikro-orm/issues"
29
+ },
30
+ "license": "MIT",
31
+ "author": "Martin Adámek",
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "git+ssh://git@github.com/mikro-orm/mikro-orm.git"
35
+ },
36
+ "type": "module",
37
+ "exports": {
38
+ "./package.json": "./package.json",
39
+ ".": "./index.js"
40
+ },
41
+ "publishConfig": {
42
+ "access": "public"
43
+ },
44
+ "scripts": {
45
+ "build": "yarn compile && yarn copy",
46
+ "clean": "yarn run -T rimraf ./dist ./tsconfig.build.tsbuildinfo",
47
+ "compile": "yarn run -T tsc -p tsconfig.build.json",
48
+ "copy": "node ../../scripts/copy.mjs"
49
+ },
50
+ "dependencies": {
51
+ "@electric-sql/pglite": "0.4.4",
52
+ "@mikro-orm/sql": "7.0.18-dev.0",
53
+ "kysely": "0.29.2",
54
+ "postgres-array": "3.0.4",
55
+ "postgres-date": "2.1.0",
56
+ "postgres-interval": "4.0.2"
57
+ },
58
+ "devDependencies": {
59
+ "@mikro-orm/core": "^7.0.17"
60
+ },
61
+ "peerDependencies": {
62
+ "@mikro-orm/core": "7.0.18-dev.0"
63
+ },
64
+ "engines": {
65
+ "node": ">= 22.17.0"
66
+ }
67
+ }
package/raw.d.ts ADDED
@@ -0,0 +1,67 @@
1
+ import { type AnyString, type Dictionary, type EntityKey, type RawQueryFragment } from '@mikro-orm/sql';
2
+ import type { SelectQueryBuilder as KyselySelectQueryBuilder } from 'kysely';
3
+ /** @internal Type for QueryBuilder instances passed to raw() - uses toRaw to distinguish from Kysely QueryBuilder */
4
+ type QueryBuilderLike = {
5
+ toQuery(): {
6
+ sql: string;
7
+ params: readonly unknown[];
8
+ };
9
+ toRaw(): RawQueryFragment;
10
+ };
11
+ /**
12
+ * Creates raw SQL query fragment that can be assigned to a property or part of a filter. This fragment is represented
13
+ * by `RawQueryFragment` class instance that can be serialized to a string, so it can be used both as an object value
14
+ * and key. When serialized, the fragment key gets cached and only such cached key will be recognized by the ORM.
15
+ * This adds a runtime safety to the raw query fragments.
16
+ *
17
+ * > **`raw()` helper is required since v6 to use a raw fragment in your query, both through EntityManager and QueryBuilder.**
18
+ *
19
+ * ```ts
20
+ * // as a value
21
+ * await em.find(User, { time: raw('now()') });
22
+ *
23
+ * // as a key
24
+ * await em.find(User, { [raw('lower(name)')]: name.toLowerCase() });
25
+ *
26
+ * // value can be empty array
27
+ * await em.find(User, { [raw('(select 1 = 1)')]: [] });
28
+ * ```
29
+ *
30
+ * The `raw` helper supports several signatures, you can pass in a callback that receives the current property alias:
31
+ *
32
+ * ```ts
33
+ * await em.find(User, { [raw(alias => `lower(${alias}.name)`)]: name.toLowerCase() });
34
+ * ```
35
+ *
36
+ * You can also use the `sql` tagged template function, which works the same, but supports only the simple string signature:
37
+ *
38
+ * ```ts
39
+ * await em.find(User, { [sql`lower(name)`]: name.toLowerCase() });
40
+ * ```
41
+ *
42
+ * When using inside filters, you might have to use a callback signature to create new raw instance for every filter usage.
43
+ *
44
+ * ```ts
45
+ * @Filter({ name: 'long', cond: () => ({ [raw('length(perex)')]: { $gt: 10000 } }) })
46
+ * ```
47
+ *
48
+ * The `raw` helper can be used within indexes and uniques to write database-agnostic SQL expressions. In that case, you can use `'??'` to tag your database identifiers (table name, column names, index name, ...) inside your expression, and pass those identifiers as a second parameter to the `raw` helper. Internally, those will automatically be quoted according to the database in use:
49
+ *
50
+ * ```ts
51
+ * // On postgres, will produce: create index "index custom_idx_on_name" on "library.author" ("country")
52
+ * // On mysql, will produce: create index `index custom_idx_on_name` on `library.author` (`country`)
53
+ * @Index({ name: 'custom_idx_on_name', expression: (table, columns) => raw(`create index ?? on ?? (??)`, ['custom_idx_on_name', table, columns.name]) })
54
+ * @Entity({ schema: 'library' })
55
+ * export class Author { ... }
56
+ * ```
57
+ *
58
+ * You can also use the `quote` tag function to write database-agnostic SQL expressions. The end-result is the same as using the `raw` function regarding database identifiers quoting, only to have a more elegant expression syntax:
59
+ *
60
+ * ```ts
61
+ * @Index({ name: 'custom_idx_on_name', expression: (table, columns) => quote`create index ${'custom_idx_on_name'} on ${table} (${columns.name})` })
62
+ * @Entity({ schema: 'library' })
63
+ * export class Author { ... }
64
+ * ```
65
+ */
66
+ export declare function raw<R = RawQueryFragment & symbol, T extends object = any>(sql: QueryBuilderLike | KyselySelectQueryBuilder<any, any, any> | EntityKey<T> | EntityKey<T>[] | AnyString | ((alias: string) => string) | RawQueryFragment, params?: readonly unknown[] | Dictionary<unknown>): R;
67
+ export {};
package/raw.js ADDED
@@ -0,0 +1,64 @@
1
+ import { raw as raw_, Utils, } from '@mikro-orm/sql';
2
+ /**
3
+ * Creates raw SQL query fragment that can be assigned to a property or part of a filter. This fragment is represented
4
+ * by `RawQueryFragment` class instance that can be serialized to a string, so it can be used both as an object value
5
+ * and key. When serialized, the fragment key gets cached and only such cached key will be recognized by the ORM.
6
+ * This adds a runtime safety to the raw query fragments.
7
+ *
8
+ * > **`raw()` helper is required since v6 to use a raw fragment in your query, both through EntityManager and QueryBuilder.**
9
+ *
10
+ * ```ts
11
+ * // as a value
12
+ * await em.find(User, { time: raw('now()') });
13
+ *
14
+ * // as a key
15
+ * await em.find(User, { [raw('lower(name)')]: name.toLowerCase() });
16
+ *
17
+ * // value can be empty array
18
+ * await em.find(User, { [raw('(select 1 = 1)')]: [] });
19
+ * ```
20
+ *
21
+ * The `raw` helper supports several signatures, you can pass in a callback that receives the current property alias:
22
+ *
23
+ * ```ts
24
+ * await em.find(User, { [raw(alias => `lower(${alias}.name)`)]: name.toLowerCase() });
25
+ * ```
26
+ *
27
+ * You can also use the `sql` tagged template function, which works the same, but supports only the simple string signature:
28
+ *
29
+ * ```ts
30
+ * await em.find(User, { [sql`lower(name)`]: name.toLowerCase() });
31
+ * ```
32
+ *
33
+ * When using inside filters, you might have to use a callback signature to create new raw instance for every filter usage.
34
+ *
35
+ * ```ts
36
+ * @Filter({ name: 'long', cond: () => ({ [raw('length(perex)')]: { $gt: 10000 } }) })
37
+ * ```
38
+ *
39
+ * The `raw` helper can be used within indexes and uniques to write database-agnostic SQL expressions. In that case, you can use `'??'` to tag your database identifiers (table name, column names, index name, ...) inside your expression, and pass those identifiers as a second parameter to the `raw` helper. Internally, those will automatically be quoted according to the database in use:
40
+ *
41
+ * ```ts
42
+ * // On postgres, will produce: create index "index custom_idx_on_name" on "library.author" ("country")
43
+ * // On mysql, will produce: create index `index custom_idx_on_name` on `library.author` (`country`)
44
+ * @Index({ name: 'custom_idx_on_name', expression: (table, columns) => raw(`create index ?? on ?? (??)`, ['custom_idx_on_name', table, columns.name]) })
45
+ * @Entity({ schema: 'library' })
46
+ * export class Author { ... }
47
+ * ```
48
+ *
49
+ * You can also use the `quote` tag function to write database-agnostic SQL expressions. The end-result is the same as using the `raw` function regarding database identifiers quoting, only to have a more elegant expression syntax:
50
+ *
51
+ * ```ts
52
+ * @Index({ name: 'custom_idx_on_name', expression: (table, columns) => quote`create index ${'custom_idx_on_name'} on ${table} (${columns.name})` })
53
+ * @Entity({ schema: 'library' })
54
+ * export class Author { ... }
55
+ * ```
56
+ */
57
+ export function raw(sql, params) {
58
+ if (Utils.isObject(sql) && 'compile' in sql) {
59
+ const query = sql.compile();
60
+ const processed = query.sql.replaceAll(/\$\d+/g, '?');
61
+ return raw_(processed, query.parameters);
62
+ }
63
+ return raw_(sql, params);
64
+ }