@cqrs-ddd/mikro-orm 0.4.0 → 0.4.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 +3 -277
- package/dist/concurrency/optimistic-delete.d.ts +2 -2
- package/dist/concurrency/optimistic-delete.js +2 -2
- package/dist/concurrency/optimistic-update.d.ts +2 -2
- package/dist/concurrency/optimistic-update.js +2 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mapping/unix-timestamp.type.d.ts +5 -2
- package/dist/mapping/unix-timestamp.type.d.ts.map +1 -1
- package/dist/mapping/unix-timestamp.type.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -8,21 +8,7 @@ authoritative aggregate loading, version-conditioned writes, the persistence dia
|
|
|
8
8
|
that maps unique violations and transient failures, a revision-fenced cache stored in
|
|
9
9
|
the database, and the `EntitySchema` mapping of `RootEntity`.
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
on no framework: it works in a plain Node service and in a NestJS application.
|
|
13
|
-
|
|
14
|
-
## Contents
|
|
15
|
-
|
|
16
|
-
- [Installation](#installation)
|
|
17
|
-
- [Entity manager source](#entity-manager-source)
|
|
18
|
-
- [Multi-tenant store](#multi-tenant-store)
|
|
19
|
-
- [Loading aggregates](#loading-aggregates)
|
|
20
|
-
- [Version-conditioned writes](#version-conditioned-writes)
|
|
21
|
-
- [Persistence errors](#persistence-errors)
|
|
22
|
-
- [Mapping a root entity](#mapping-a-root-entity)
|
|
23
|
-
- [The database cache](#the-database-cache)
|
|
24
|
-
- [SQL identifiers](#sql-identifiers)
|
|
25
|
-
- [License](#license)
|
|
11
|
+
**Documentation:** [guide](https://aristoteliss.github.io/nestjs-pipeline/packages/cqrs-ddd/mikro-orm/) · [API reference](https://aristoteliss.github.io/nestjs-pipeline/api/cqrs-ddd/mikro-orm/) · [all packages](https://aristoteliss.github.io/nestjs-pipeline/)
|
|
26
12
|
|
|
27
13
|
## Installation
|
|
28
14
|
|
|
@@ -30,270 +16,10 @@ on no framework: it works in a plain Node service and in a NestJS application.
|
|
|
30
16
|
pnpm add @cqrs-ddd/mikro-orm @cqrs-ddd/core @mikro-orm/core
|
|
31
17
|
```
|
|
32
18
|
|
|
33
|
-
Requires Node.js 22.17 or later, as MikroORM 7 does. `@cqrs-ddd/core` `^0.4.
|
|
19
|
+
Requires Node.js 22.17 or later, as MikroORM 7 does. `@cqrs-ddd/core` `^0.4.2` and `@mikro-orm/core` `^7.2.1` are peer
|
|
34
20
|
dependencies; add the MikroORM driver you use, such as `@mikro-orm/postgresql`.
|
|
35
21
|
|
|
36
|
-
Published as an ES module; a CommonJS application loads it with `require()`. Coming from
|
|
37
|
-
0.3.x, see [Upgrading from 0.3.x](https://github.com/aristoteliss/nestjs-pipeline#upgrading-from-03x).
|
|
38
|
-
|
|
39
|
-
## Entity manager source
|
|
40
|
-
|
|
41
|
-
The adapters take an `IEntityManagerSource`, an object with an `em` property, and read
|
|
42
|
-
`em` on every operation. A multi-tenant store can therefore hand out the current
|
|
43
|
-
tenant's manager; a single-database setup can pass `{ em: orm.em.fork() }`.
|
|
44
|
-
|
|
45
|
-
## Multi-tenant store
|
|
46
|
-
|
|
47
|
-
`TenantStore` is that source for a multi-tenant application. `em` and `transactional()`
|
|
48
|
-
act on the active tenant, which `tenant()` supplies; `orm(tenant)` returns the initialized
|
|
49
|
-
ORM holding its data. Both throw when there is no tenant or it is unknown: the store never
|
|
50
|
-
falls back to one.
|
|
51
|
-
|
|
52
|
-
```typescript
|
|
53
|
-
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
54
|
-
import { setPersistenceDialect } from '@cqrs-ddd/core/persistence';
|
|
55
|
-
import { CacheEntrySchema, MikroOrmDialect, TenantStore } from '@cqrs-ddd/mikro-orm';
|
|
56
|
-
import { MikroORM } from '@mikro-orm/core';
|
|
57
|
-
|
|
58
|
-
const requestTenant = new AsyncLocalStorage<string>();
|
|
59
|
-
const orms = new Map<string, MikroORM>();
|
|
60
|
-
for (const tenant of ['tenant_a', 'tenant_b']) {
|
|
61
|
-
orms.set(tenant, await MikroORM.init({ ...tenantOptions(tenant), entities: [UserSchema, CacheEntrySchema] }));
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const store = new TenantStore({
|
|
65
|
-
tenant: () => {
|
|
66
|
-
const tenant = requestTenant.getStore();
|
|
67
|
-
if (!tenant) throw new Error('No tenant in scope.');
|
|
68
|
-
return tenant;
|
|
69
|
-
},
|
|
70
|
-
orm: (tenant) => {
|
|
71
|
-
const orm = orms.get(tenant);
|
|
72
|
-
if (!orm) throw new Error(`Unknown tenant ${tenant}.`);
|
|
73
|
-
return orm;
|
|
74
|
-
},
|
|
75
|
-
isolation: 'database', // one ORM and database per tenant; 'schema': one ORM, a schema per tenant
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
const [first] = orms.values();
|
|
79
|
-
if (first) setPersistenceDialect(new MikroOrmDialect(first));
|
|
80
|
-
|
|
81
|
-
await requestTenant.run('tenant_a', () => store.em.findOne(User, { id }));
|
|
82
|
-
await requestTenant.run('tenant_a', () =>
|
|
83
|
-
store.transactional((em) => em.nativeDelete(CacheEntry, { key })),
|
|
84
|
-
);
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
With `'schema'` isolation, `orm` returns the same ORM for every tenant and each manager is
|
|
88
|
-
forked with `schema: tenant`; validate the tenant against a known list before it reaches
|
|
89
|
-
the store, for example with `isSqlIdentifier`.
|
|
90
|
-
|
|
91
|
-
- `em` reuses the contextual manager (a MikroORM `RequestContext` or an active
|
|
92
|
-
transaction) only when it belongs to the tenant's ORM, configuration, driver and schema,
|
|
93
|
-
and no other tenant used it first. Otherwise it forks one, with the tenant's schema under
|
|
94
|
-
`'schema'` isolation.
|
|
95
|
-
- `transactional()` always runs on a fork of its own; a missing or unknown tenant rejects
|
|
96
|
-
it.
|
|
97
|
-
- The tenant of each manager it hands out is kept in a `WeakMap`: MikroORM objects are
|
|
98
|
-
never modified.
|
|
99
|
-
|
|
100
|
-
## Loading aggregates
|
|
101
|
-
|
|
102
|
-
A command that mutates an aggregate loads it through core's
|
|
103
|
-
`IWriteSideAggregateRepository<TEntity>.findById(id)`. `AggregateRepository` implements
|
|
104
|
-
it: `findById()` reads with `{ refresh: true }`, never touches the cache, rehydrates
|
|
105
|
-
through the `hydrateFn` you pass, and translates driver failures with
|
|
106
|
-
`mapPersistenceError`.
|
|
107
|
-
|
|
108
|
-
```typescript
|
|
109
|
-
import type { ICache } from '@cqrs-ddd/core/application';
|
|
110
|
-
import { cacheKey, PersistedWrite } from '@cqrs-ddd/core/persistence';
|
|
111
|
-
import { AggregateRepository, type IEntityManagerSource, optimisticUpdate } from '@cqrs-ddd/mikro-orm';
|
|
112
|
-
|
|
113
|
-
export class UpdateUserRepository extends AggregateRepository<UserSnapshot, User, UserSnapshot> {
|
|
114
|
-
constructor(cache: ICache<UserSnapshot>, store: IEntityManagerSource) {
|
|
115
|
-
super(cache, store, User, User.aggregateName, User.fromJSON);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
@PersistedWrite<User>({
|
|
119
|
-
cache: { setKey: (user) => cacheKey(User.aggregateName, { id: user.id }) },
|
|
120
|
-
})
|
|
121
|
-
async save(user: User): Promise<UserSnapshot> {
|
|
122
|
-
const snapshot = user.toJSON();
|
|
123
|
-
await optimisticUpdate(
|
|
124
|
-
this.store.em,
|
|
125
|
-
User,
|
|
126
|
-
user,
|
|
127
|
-
{ username: snapshot.username, updatedAt: snapshot.updatedAt },
|
|
128
|
-
'User',
|
|
129
|
-
);
|
|
130
|
-
return snapshot;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const users = new UpdateUserRepository(cache, store);
|
|
135
|
-
const user = await users.findById(id); // always the database row, never the cache
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
## Version-conditioned writes
|
|
139
|
-
|
|
140
|
-
`optimisticUpdate` and `optimisticDelete` write `WHERE id = ? AND version = expected`,
|
|
141
|
-
check the affected rows, and raise core's `EntityNotFoundException` or
|
|
142
|
-
`ConcurrencyConflictError`. They, and every write whose success triggers acknowledgment
|
|
143
|
-
or cache work, call `assertAutocommit(em, operation)` first: a write inside an outer
|
|
144
|
-
transaction is rejected before any statement runs, because its success would not mean
|
|
145
|
-
durable persistence.
|
|
146
|
-
|
|
147
|
-
```typescript
|
|
148
|
-
import { ConcurrencyConflictError } from '@cqrs-ddd/core/domain';
|
|
149
|
-
import { optimisticDelete, optimisticUpdate } from '@cqrs-ddd/mikro-orm';
|
|
150
|
-
|
|
151
|
-
// UPDATE users SET department = ?, updated_at = ?, version = <user.version>
|
|
152
|
-
// WHERE id = <user.id> AND version = <user.getExpectedVersion()>
|
|
153
|
-
await optimisticUpdate(store.em, User, user, { department: 'Research', updatedAt: user.updatedAt }, 'User');
|
|
154
|
-
|
|
155
|
-
try {
|
|
156
|
-
await optimisticDelete(store.em, User, staleUser, 'User');
|
|
157
|
-
} catch (error) {
|
|
158
|
-
if (error instanceof ConcurrencyConflictError) {
|
|
159
|
-
// error.expectedVersion is the version staleUser was loaded at; reload and retry
|
|
160
|
-
}
|
|
161
|
-
throw error;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
await store.em.transactional((em) => optimisticUpdate(em, User, user, fields, 'User')); // rejected
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
- `data` holds the columns to write; `version` is set from `entity.version`, so a caller
|
|
168
|
-
lists every other changed column, `updatedAt` included.
|
|
169
|
-
- No matching row: a refreshed read tells a missing row (`EntityNotFoundException`) from a
|
|
170
|
-
diverged version (`ConcurrencyConflictError`). More than one matching row throws an
|
|
171
|
-
`Error`.
|
|
172
|
-
- Neither function touches the cache, acknowledges the aggregate or publishes events;
|
|
173
|
-
`@PersistedWrite`, `@Cache` and `CommandBaseHandler` do that.
|
|
174
|
-
|
|
175
|
-
## Persistence errors
|
|
176
|
-
|
|
177
|
-
`MikroOrmDialect` implements core's `IPersistenceDialect`. Register it once the ORM is
|
|
178
|
-
initialized, and `@MapPersistenceErrors` / `@PersistedWrite` map unique violations by
|
|
179
|
-
entity property:
|
|
180
|
-
|
|
181
|
-
```typescript
|
|
182
|
-
import { setPersistenceDialect } from '@cqrs-ddd/core/persistence';
|
|
183
|
-
import { MikroOrmDialect } from '@cqrs-ddd/mikro-orm';
|
|
184
|
-
|
|
185
|
-
const orm = await MikroORM.init(options);
|
|
186
|
-
setPersistenceDialect(new MikroOrmDialect(orm));
|
|
187
|
-
|
|
188
|
-
// in a repository
|
|
189
|
-
@PersistedWrite<User>({ unique: { email: (user) => new UniqueEmailException(user) } })
|
|
190
|
-
async save(user: User): Promise<UserSnapshot> {
|
|
191
|
-
const snapshot = user.toJSON();
|
|
192
|
-
await optimisticUpdate(this.store.em, User, user, { email: snapshot.email }, 'User');
|
|
193
|
-
return snapshot;
|
|
194
|
-
}
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
A multi-property constraint is keyed by its declared name, passed as the constraint type:
|
|
198
|
-
|
|
199
|
-
```typescript
|
|
200
|
-
const ROLE_NAME = 'roles_tenant_name_unique';
|
|
201
|
-
// schema: uniques: [{ name: ROLE_NAME, properties: ['tenantId', 'name'] }]
|
|
202
|
-
|
|
203
|
-
@PersistedWrite<Role, typeof ROLE_NAME>({
|
|
204
|
-
unique: { [ROLE_NAME]: (role) => new DuplicateRoleNameException(role) },
|
|
205
|
-
})
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
It reads each entity's unique constraints from the ORM metadata: `unique: true` or
|
|
209
|
-
`unique: 'name'` on a property, and `uniques: [{ name?, properties }]` on the schema. A
|
|
210
|
-
single-property constraint is keyed by that property; a multi-property one by its
|
|
211
|
-
`name`, which it must declare. For a `UniqueConstraintViolationException`, PostgreSQL's
|
|
212
|
-
reported constraint name is matched against the declared name, or the naming strategy's
|
|
213
|
-
`indexName` when none is declared, and SQLite's reported `table.column` list against the
|
|
214
|
-
constraint's columns. Anything else yields no match and the original error is rethrown.
|
|
215
|
-
Construction fails when two constraints of one entity cover the same columns, because
|
|
216
|
-
SQLite could not tell them apart. Declare constraint names in the mapping, never in a
|
|
217
|
-
repository.
|
|
218
|
-
|
|
219
|
-
`mapPersistenceError(error, operation)` is the `otherwise` translator for transient
|
|
220
|
-
failures: `isTransientPersistenceError` recognizes retryable PostgreSQL SQLSTATEs
|
|
221
|
-
(`40001`, `40P01`, `55P03`, `57P01`–`57P03`, classes `08` and `53`), Node network errors,
|
|
222
|
-
`SQLITE_BUSY`/`SQLITE_LOCKED` and timeouts, through the `cause` chain, and wraps them in
|
|
223
|
-
core's `TransientOperationError`. Any other error is returned unchanged.
|
|
224
|
-
|
|
225
|
-
## Mapping a root entity
|
|
226
|
-
|
|
227
|
-
`rootEntityProperties(columns?)` and `versionProperty(column?)` give the `EntitySchema`
|
|
228
|
-
properties every `RootEntity` needs, with timestamps stored as epoch milliseconds
|
|
229
|
-
through `UnixTimestampType`. That type throws a `TypeError` for a value with no valid
|
|
230
|
-
time instead of storing `NaN`. The properties use `accessor: true`, so MikroORM reads
|
|
231
|
-
and writes them through the entity's getters and private setters, and queries use the
|
|
232
|
-
public names.
|
|
233
|
-
|
|
234
|
-
```typescript
|
|
235
|
-
export const UserSchema = new EntitySchema<User, AggregateRoot>({
|
|
236
|
-
class: User as any,
|
|
237
|
-
tableName: 'users',
|
|
238
|
-
properties: {
|
|
239
|
-
...rootEntityProperties(),
|
|
240
|
-
version: versionProperty(),
|
|
241
|
-
username: { type: 'string', length: 255, accessor: true },
|
|
242
|
-
department: { type: 'string', length: 255, nullable: true, accessor: true },
|
|
243
|
-
email: { type: 'string', length: 320, unique: true },
|
|
244
|
-
},
|
|
245
|
-
});
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
`rootEntityProperties({ createdAt: 'created', updatedAt: 'modified' })` renames the
|
|
249
|
-
columns; the defaults are `id`, `created_at` and `updated_at`.
|
|
250
|
-
|
|
251
|
-
Map a subclass's fields the same way. An entity written without version checks has no
|
|
252
|
-
version column; map its inherited `version` as `{ type: 'number', persist: false }`.
|
|
253
|
-
|
|
254
|
-
## The database cache
|
|
255
|
-
|
|
256
|
-
`MikroOrmCache(store, { defaultTtlMs?, logger? })` implements core's `IVersionedCache`
|
|
257
|
-
with one database row per key; every write is a compare-and-set in its own transaction.
|
|
258
|
-
`store` provides `em` and `transactional(work)`. Register `CacheEntrySchema` (or
|
|
259
|
-
`createCacheEntrySchema(table)`) with the ORM, and create the table in a migration with
|
|
260
|
-
`createCacheTableSql(table?)`, which covers PostgreSQL and SQLite.
|
|
261
|
-
|
|
262
|
-
```typescript
|
|
263
|
-
import { CACHE_TOKEN } from '@cqrs-ddd/core/persistence';
|
|
264
|
-
import { createCacheTableSql, MikroOrmCache } from '@cqrs-ddd/mikro-orm';
|
|
265
|
-
|
|
266
|
-
// once, in a migration
|
|
267
|
-
await orm.em.getConnection().execute(createCacheTableSql());
|
|
268
|
-
|
|
269
|
-
const cache = new MikroOrmCache<UserSnapshot>(store, {
|
|
270
|
-
defaultTtlMs: 5 * 60_000, // 0 never expires
|
|
271
|
-
logger: { warn: (message) => console.warn(message) },
|
|
272
|
-
});
|
|
273
|
-
const users = new UpdateUserRepository(cache, store);
|
|
274
|
-
const reads = new GetUserRepository(cache, store);
|
|
275
|
-
|
|
276
|
-
// NestJS
|
|
277
|
-
{
|
|
278
|
-
provide: CACHE_TOKEN,
|
|
279
|
-
useFactory: (store: TenantStore) => new MikroOrmCache(store, { logger: new Logger('MikroOrmCache') }),
|
|
280
|
-
inject: [STORE],
|
|
281
|
-
}
|
|
282
|
-
```
|
|
283
|
-
|
|
284
|
-
- `store.transactional(work)` must run `work` on a manager of its own, never the caller's
|
|
285
|
-
request or transaction manager; `TenantStore` does, and so does
|
|
286
|
-
`{ em: orm.em, transactional: (work) => orm.em.fork().transactional(work) }`.
|
|
287
|
-
- With a `TenantStore`, each tenant's cache rows live in that tenant's database or schema.
|
|
288
|
-
- Reads bypass the identity map, a reader never deletes an expired row, and a corrupted
|
|
289
|
-
payload throws instead of reading as a miss.
|
|
290
|
-
- `set` and `invalidate` throw when their compare-and-set cannot settle after 16 attempts.
|
|
291
|
-
|
|
292
|
-
## SQL identifiers
|
|
293
|
-
|
|
294
|
-
`isSqlIdentifier(name, { qualified? })` accepts an unquoted SQL identifier, optionally
|
|
295
|
-
schema-qualified. Use it before interpolating a name, such as a tenant schema, into SQL
|
|
296
|
-
text, where it cannot be passed as a parameter.
|
|
22
|
+
Published as an ES module; a CommonJS application loads it with `require()`. Coming from 0.3.x, see [Upgrading from 0.3.x](https://aristoteliss.github.io/nestjs-pipeline/upgrading/from-0-3/).
|
|
297
23
|
|
|
298
24
|
## License
|
|
299
25
|
|
|
@@ -11,8 +11,8 @@ import { type VersionedAggregate } from './conditioned-write.js';
|
|
|
11
11
|
* modified since the aggregate was loaded is not removed;
|
|
12
12
|
* - one affected row is success;
|
|
13
13
|
* - zero rows runs one refreshed diagnostic read: an absent row is
|
|
14
|
-
*
|
|
15
|
-
*
|
|
14
|
+
* `EntityNotFoundException`, a present row is
|
|
15
|
+
* `ConcurrencyConflictError`;
|
|
16
16
|
* - any other count is an invariant violation, since the filter includes a
|
|
17
17
|
* primary key.
|
|
18
18
|
*
|
|
@@ -12,8 +12,8 @@ import { expectOneRow } from './conditioned-write.js';
|
|
|
12
12
|
* modified since the aggregate was loaded is not removed;
|
|
13
13
|
* - one affected row is success;
|
|
14
14
|
* - zero rows runs one refreshed diagnostic read: an absent row is
|
|
15
|
-
*
|
|
16
|
-
*
|
|
15
|
+
* `EntityNotFoundException`, a present row is
|
|
16
|
+
* `ConcurrencyConflictError`;
|
|
17
17
|
* - any other count is an invariant violation, since the filter includes a
|
|
18
18
|
* primary key.
|
|
19
19
|
*
|
|
@@ -12,8 +12,8 @@ import { type VersionedAggregate } from './conditioned-write.js';
|
|
|
12
12
|
* - **Affected Row Verification**:
|
|
13
13
|
* - Exactly `1` row affected: Write succeeded; completes cleanly.
|
|
14
14
|
* - `0` rows affected: Performs a refreshed diagnostic read (`findOne` with `refresh: true`):
|
|
15
|
-
* - If the entity is absent, throws
|
|
16
|
-
* - If the entity is present, throws
|
|
15
|
+
* - If the entity is absent, throws `EntityNotFoundException`.
|
|
16
|
+
* - If the entity is present, throws `ConcurrencyConflictError`.
|
|
17
17
|
* - More than `1` row affected: Throws an `Error` indicating primary-key uniqueness invariant violation.
|
|
18
18
|
*
|
|
19
19
|
* > [!NOTE]
|
|
@@ -13,8 +13,8 @@ import { expectOneRow } from './conditioned-write.js';
|
|
|
13
13
|
* - **Affected Row Verification**:
|
|
14
14
|
* - Exactly `1` row affected: Write succeeded; completes cleanly.
|
|
15
15
|
* - `0` rows affected: Performs a refreshed diagnostic read (`findOne` with `refresh: true`):
|
|
16
|
-
* - If the entity is absent, throws
|
|
17
|
-
* - If the entity is present, throws
|
|
16
|
+
* - If the entity is absent, throws `EntityNotFoundException`.
|
|
17
|
+
* - If the entity is present, throws `ConcurrencyConflictError`.
|
|
18
18
|
* - More than `1` row affected: Throws an `Error` indicating primary-key uniqueness invariant violation.
|
|
19
19
|
*
|
|
20
20
|
* > [!NOTE]
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from './cache/cache-entry.js';
|
|
2
2
|
export * from './cache/mikro-orm.cache.js';
|
|
3
3
|
export * from './concurrency/assert-autocommit.js';
|
|
4
|
+
export type { VersionedAggregate } from './concurrency/conditioned-write.js';
|
|
4
5
|
export * from './concurrency/optimistic-delete.js';
|
|
5
6
|
export * from './concurrency/optimistic-update.js';
|
|
6
7
|
export * from './errors/mikro-orm.dialect.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oCAAoC,CAAC;AACnD,cAAc,oCAAoC,CAAC;AACnD,cAAc,oCAAoC,CAAC;AACnD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uCAAuC,CAAC;AACtD,cAAc,qCAAqC,CAAC;AACpD,cAAc,kCAAkC,CAAC;AACjD,cAAc,sCAAsC,CAAC;AACrD,cAAc,2BAA2B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oCAAoC,CAAC;AACnD,YAAY,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,cAAc,oCAAoC,CAAC;AACnD,cAAc,oCAAoC,CAAC;AACnD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uCAAuC,CAAC;AACtD,cAAc,qCAAqC,CAAC;AACpD,cAAc,kCAAkC,CAAC;AACjD,cAAc,sCAAsC,CAAC;AACrD,cAAc,2BAA2B,CAAC"}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oCAAoC,CAAC;AAEnD,cAAc,oCAAoC,CAAC;AACnD,cAAc,oCAAoC,CAAC;AACnD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uCAAuC,CAAC;AACtD,cAAc,qCAAqC,CAAC;AACpD,cAAc,kCAAkC,CAAC;AACjD,cAAc,sCAAsC,CAAC;AACrD,cAAc,2BAA2B,CAAC"}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { type EntityProperty, Platform, type TransformContext, Type } from '@mikro-orm/core';
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* A value {@link UnixTimestampType} reads as a time: a `Date`, epoch milliseconds as a
|
|
4
|
+
* number, a bigint or a numeric string, or a date string.
|
|
5
|
+
*/
|
|
6
|
+
export type Timestamp = Date | number | string | bigint;
|
|
3
7
|
/**
|
|
4
8
|
* MikroORM type that stores a `Date` as epoch milliseconds in a 64-bit `bigint`
|
|
5
9
|
* column.
|
|
@@ -13,5 +17,4 @@ export declare class UnixTimestampType extends Type<Date | null | undefined, num
|
|
|
13
17
|
convertToJSValue(value: Timestamp | null | undefined, _platform?: Platform, _context?: TransformContext): Date | null | undefined;
|
|
14
18
|
getColumnType(prop?: EntityProperty, platform?: Platform): string;
|
|
15
19
|
}
|
|
16
|
-
export {};
|
|
17
20
|
//# sourceMappingURL=unix-timestamp.type.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unix-timestamp.type.d.ts","sourceRoot":"","sources":["../../src/mapping/unix-timestamp.type.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,cAAc,EACnB,QAAQ,EACR,KAAK,gBAAgB,EACrB,IAAI,EACL,MAAM,iBAAiB,CAAC;AAEzB,
|
|
1
|
+
{"version":3,"file":"unix-timestamp.type.d.ts","sourceRoot":"","sources":["../../src/mapping/unix-timestamp.type.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,cAAc,EACnB,QAAQ,EACR,KAAK,gBAAgB,EACrB,IAAI,EACL,MAAM,iBAAiB,CAAC;AAEzB;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AA0BxD;;;;;;;GAOG;AACH,qBAAa,iBAAkB,SAAQ,IAAI,CACzC,IAAI,GAAG,IAAI,GAAG,SAAS,EACvB,MAAM,GAAG,IAAI,GAAG,SAAS,CAC1B;IACC,sBAAsB,CACpB,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,EACnC,SAAS,CAAC,EAAE,QAAQ,EACpB,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,MAAM,GAAG,IAAI,GAAG,SAAS,CAG3B;IAED,gBAAgB,CACd,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,EACnC,SAAS,CAAC,EAAE,QAAQ,EACpB,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,IAAI,GAAG,IAAI,GAAG,SAAS,CAIzB;IAED,aAAa,CACX,IAAI,GAAE,cAAqC,EAC3C,QAAQ,CAAC,EAAE,QAAQ,GAClB,MAAM,CAER;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unix-timestamp.type.js","sourceRoot":"","sources":["../../src/mapping/unix-timestamp.type.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,OAAO,EAIL,IAAI,GACL,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"unix-timestamp.type.js","sourceRoot":"","sources":["../../src/mapping/unix-timestamp.type.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,OAAO,EAIL,IAAI,GACL,MAAM,iBAAiB,CAAC;AAQzB;;;;;;GAMG;AACH,SAAS,mBAAmB,CAAC,KAAc;IACzC,IAAI,YAAY,GAAG,MAAM,CAAC,GAAG,CAAC;IAC9B,IAAI,KAAK,YAAY,IAAI;QAAE,YAAY,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;SACrD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,YAAY,GAAG,KAAK,CAAC;SACpD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;SAC5D,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC1D,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC9B,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IACrE,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,SAAS,CACjB,iCAAiC,OAAO,KAAK,UAAU,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,kBAAkB,CACvG,CAAC;IACJ,CAAC;IACD,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,OAAO,iBAAkB,SAAQ,IAGtC;IACC,sBAAsB,CACpB,KAAmC,EACnC,SAAoB,EACpB,QAA2B;QAE3B,IAAI,KAAK,IAAI,IAAI;YAAE,OAAO,KAAK,CAAC;QAChC,OAAO,mBAAmB,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IAED,gBAAgB,CACd,KAAmC,EACnC,SAAoB,EACpB,QAA2B;QAE3B,IAAI,KAAK,IAAI,IAAI;YAAE,OAAO,KAAK,CAAC;QAChC,MAAM,YAAY,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;QAChD,OAAO,KAAK,YAAY,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC;IAChE,CAAC;IAED,aAAa,CACX,IAAI,GAAmB,EAAoB,EAC3C,QAAmB;QAEnB,OAAO,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,2BAA2B,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC1E,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cqrs-ddd/mikro-orm",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "MikroORM persistence adapters for @cqrs-ddd/core: authoritative aggregate loading, version-conditioned writes, a revision-fenced cache and root-entity schema mapping.",
|
|
5
5
|
"author": "Aristotelis",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"url": "git+https://github.com/aristoteliss/nestjs-pipeline.git",
|
|
14
14
|
"directory": "packages/ddd-mikro-orm"
|
|
15
15
|
},
|
|
16
|
-
"homepage": "https://github.
|
|
16
|
+
"homepage": "https://aristoteliss.github.io/nestjs-pipeline/packages/cqrs-ddd/mikro-orm/",
|
|
17
17
|
"bugs": {
|
|
18
18
|
"url": "https://github.com/aristoteliss/nestjs-pipeline/issues"
|
|
19
19
|
},
|
|
@@ -45,14 +45,14 @@
|
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"@mikro-orm/core": "^7.2.1",
|
|
48
|
-
"@cqrs-ddd/core": "^0.4.
|
|
48
|
+
"@cqrs-ddd/core": "^0.4.2"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@mikro-orm/core": "^7.2.1",
|
|
52
52
|
"@vitest/coverage-v8": "^5.0.2",
|
|
53
53
|
"typescript": "^7.0.2",
|
|
54
54
|
"vitest": "^5.0.2",
|
|
55
|
-
"@cqrs-ddd/core": "^0.4.
|
|
55
|
+
"@cqrs-ddd/core": "^0.4.2"
|
|
56
56
|
},
|
|
57
57
|
"scripts": {
|
|
58
58
|
"build": "tsc -p tsconfig.build.json",
|