@nest-batch/typeorm 0.2.1 → 0.2.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.ko.md +55 -0
- package/README.md +27 -230
- package/package.json +5 -4
package/README.ko.md
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# @nest-batch/typeorm
|
|
2
|
+
|
|
3
|
+
`@nest-batch/core`용 TypeORM persistence adapter입니다.
|
|
4
|
+
|
|
5
|
+
English: [README.md](./README.md)
|
|
6
|
+
|
|
7
|
+
## 설치
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pnpm add @nest-batch/core @nest-batch/typeorm typeorm
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Nest 애플리케이션에서 `@nestjs/typeorm`을 사용한다면 기존 `TypeOrmModule.forRoot`
|
|
14
|
+
구성을 그대로 소유하면 됩니다.
|
|
15
|
+
|
|
16
|
+
## Public Import
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
import {
|
|
20
|
+
BATCH_META_ENTITIES,
|
|
21
|
+
TypeOrmAdapter,
|
|
22
|
+
TypeOrmJobRepository,
|
|
23
|
+
TypeOrmTransactionManager,
|
|
24
|
+
batchMetaEntities,
|
|
25
|
+
} from '@nest-batch/typeorm';
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Wiring
|
|
29
|
+
|
|
30
|
+
host-owned TypeORM data source에 batch metadata entity를 등록합니다.
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
import { TypeOrmModule } from '@nestjs/typeorm';
|
|
34
|
+
import { InProcessAdapter, NestBatchModule } from '@nest-batch/core';
|
|
35
|
+
import { BATCH_META_ENTITIES, TypeOrmAdapter } from '@nest-batch/typeorm';
|
|
36
|
+
|
|
37
|
+
@Module({
|
|
38
|
+
imports: [
|
|
39
|
+
TypeOrmModule.forRoot({
|
|
40
|
+
type: 'postgres',
|
|
41
|
+
entities: [ProductEntity, ...BATCH_META_ENTITIES],
|
|
42
|
+
url: process.env.DATABASE_URL,
|
|
43
|
+
}),
|
|
44
|
+
NestBatchModule.forRoot({
|
|
45
|
+
adapters: {
|
|
46
|
+
persistence: TypeOrmAdapter.forRoot(),
|
|
47
|
+
transport: InProcessAdapter.forRoot(),
|
|
48
|
+
},
|
|
49
|
+
}),
|
|
50
|
+
],
|
|
51
|
+
})
|
|
52
|
+
export class AppModule {}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
metadata entity를 추가한 뒤 application repository에서 migration을 생성하세요.
|
package/README.md
CHANGED
|
@@ -1,259 +1,56 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @nest-batch/typeorm
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
the same five active batch meta-tables that
|
|
5
|
-
`@nest-batch/mikro-orm` ships, expressed as TypeORM 1.0 entities plus
|
|
6
|
-
an exported entity tuple. It exposes `TypeOrmJobRepository` and
|
|
7
|
-
`TypeOrmTransactionManager` and runs the shared core contract suite
|
|
8
|
-
against a real TypeORM `DataSource`.
|
|
3
|
+
TypeORM persistence adapter for `@nest-batch/core`.
|
|
9
4
|
|
|
10
|
-
|
|
11
|
-
direction is strict and one-way:
|
|
12
|
-
|
|
13
|
-
```
|
|
14
|
-
@nest-batch/typeorm ──▶ @nest-batch/core
|
|
15
|
-
│
|
|
16
|
-
└──────▶ typeorm (peer, ^1.0.0)
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
`@nest-batch/core` does not know this package exists. The boundary is
|
|
20
|
-
enforced by a core test that fails the build if any `typeorm` import
|
|
21
|
-
shows up in core.
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## TypeORM 1.0.0-only policy
|
|
26
|
-
|
|
27
|
-
This adapter targets **TypeORM 1.0.0 only**. The peer range is
|
|
28
|
-
`typeorm: ^1.0.0` and intentionally excludes `0.3.x`.
|
|
29
|
-
|
|
30
|
-
Why 1.0.0 and not 0.3? Two reasons:
|
|
31
|
-
|
|
32
|
-
1. The `Connection` → `DataSource` rename. TypeORM 1.0.0 finished the
|
|
33
|
-
rename that 0.3 started; the API now exposes `DataSource`,
|
|
34
|
-
`DataSourceOptions`, and `DataSource.transaction()` instead of
|
|
35
|
-
`Connection`, `ConnectionOptions`, and `Connection.transaction()`.
|
|
36
|
-
Maintaining 0.3 support would mean running the full codebase
|
|
37
|
-
through `Connection → DataSource` shims, which is a waste of
|
|
38
|
-
effort when 0.3 is on a separate support track.
|
|
39
|
-
2. The entity surface. A few decorators and metadata helpers moved
|
|
40
|
-
between 0.3 and 1.0. Supporting both means conditional entity
|
|
41
|
-
definitions, which is a smell.
|
|
42
|
-
|
|
43
|
-
The peer range is `^1.0.0`, so any 1.x release works. The boundary
|
|
44
|
-
test in core and a dedicated peer-range test in this package
|
|
45
|
-
together ensure 0.3 does not silently sneak back in.
|
|
46
|
-
|
|
47
|
-
If you're on TypeORM 0.3, stay on the previous
|
|
48
|
-
`@nest-batch/nest-batch` package (pre-rename) or upgrade TypeORM
|
|
49
|
-
first. There's no compatibility shim in this release.
|
|
50
|
-
|
|
51
|
-
---
|
|
5
|
+
Korean: [README.ko.md](./README.ko.md)
|
|
52
6
|
|
|
53
7
|
## Install
|
|
54
8
|
|
|
55
9
|
```bash
|
|
56
|
-
pnpm add @nest-batch/typeorm
|
|
10
|
+
pnpm add @nest-batch/core @nest-batch/typeorm typeorm
|
|
57
11
|
```
|
|
58
12
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
| Package | Range |
|
|
62
|
-
| ------------------ | ------------- |
|
|
63
|
-
| `@nest-batch/core` | `workspace:*` |
|
|
64
|
-
| `typeorm` | `^1.0.0` |
|
|
65
|
-
|
|
66
|
-
`typeorm` is a hard peer (declared in `peerDependencies` with
|
|
67
|
-
`optional: false`). The `package.json` also lists it as a
|
|
68
|
-
`devDependency` so the package's own test suite can resolve it
|
|
69
|
-
without the host.
|
|
70
|
-
|
|
71
|
-
---
|
|
72
|
-
|
|
73
|
-
## Schema ownership
|
|
74
|
-
|
|
75
|
-
This package owns the same five active batch meta tables as
|
|
76
|
-
`@nest-batch/mikro-orm`:
|
|
13
|
+
If your Nest application uses `@nestjs/typeorm`, keep using your normal
|
|
14
|
+
`TypeOrmModule.forRoot` configuration.
|
|
77
15
|
|
|
78
|
-
|
|
79
|
-
| ------------------------------ | ---------------------------------------------------------------------------------- |
|
|
80
|
-
| `batch_job_instance` | One row per logical job (unique on `job_name`+`job_key`). |
|
|
81
|
-
| `batch_job_execution` | One row per job run. Holds status, start/end, exit code/message. |
|
|
82
|
-
| `batch_step_execution` | One row per step run. Holds step status, exit code/message, last-chunk checkpoint. |
|
|
83
|
-
| `batch_job_execution_context` | JSON checkpoint + execution context (job-scoped). |
|
|
84
|
-
| `batch_step_execution_context` | JSON checkpoint + execution context (step-scoped). |
|
|
16
|
+
## Public Imports
|
|
85
17
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
> host owns the `TypeOrmModule.forRoot()` call), spreading
|
|
96
|
-
> `batchMetaEntities` into your own `entities` array is the only
|
|
97
|
-
> way the meta tables are registered with TypeORM's metadata
|
|
98
|
-
> system. Forgetting the spread means `Repository<Entity>` lookups
|
|
99
|
-
> for the meta tables fail silently and the repository throws at
|
|
100
|
-
> first call.
|
|
101
|
-
|
|
102
|
-
> The entities declare portable logical column types because the
|
|
103
|
-
> same contract is exercised against fast SQLite tests and real
|
|
104
|
-
> PostgreSQL/MySQL driver shells. Host-owned migrations may map
|
|
105
|
-
> those logical columns to dialect-specific types such as
|
|
106
|
-
> `timestamptz` or `datetime(6)`.
|
|
107
|
-
|
|
108
|
-
---
|
|
18
|
+
```ts
|
|
19
|
+
import {
|
|
20
|
+
BATCH_META_ENTITIES,
|
|
21
|
+
TypeOrmAdapter,
|
|
22
|
+
TypeOrmJobRepository,
|
|
23
|
+
TypeOrmTransactionManager,
|
|
24
|
+
batchMetaEntities,
|
|
25
|
+
} from '@nest-batch/typeorm';
|
|
26
|
+
```
|
|
109
27
|
|
|
110
28
|
## Wiring
|
|
111
29
|
|
|
112
|
-
|
|
113
|
-
owned `TypeOrmModule.forRoot()` call (which builds the
|
|
114
|
-
`DataSource` and registers the meta entities) and a
|
|
115
|
-
`TypeOrmAdapter.forRoot()` carrier passed to
|
|
116
|
-
`NestBatchModule.forRoot({ adapters: { persistence, ... } })`.
|
|
117
|
-
|
|
118
|
-
### Bring-your-own `DataSource` (recommended)
|
|
119
|
-
|
|
120
|
-
If your app already uses `@nestjs/typeorm` (the typical case for a
|
|
121
|
-
Nest app with user-domain entities), call
|
|
122
|
-
`TypeOrmModule.forRoot()` yourself, spread `batchMetaEntities()`
|
|
123
|
-
into its `entities` array, and pass the adapter's no-arg
|
|
124
|
-
`TypeOrmAdapter.forRoot()` to `NestBatchModule.forRoot()` under
|
|
125
|
-
`adapters.persistence`:
|
|
30
|
+
Register the batch metadata entities in your host-owned TypeORM data source.
|
|
126
31
|
|
|
127
32
|
```ts
|
|
128
|
-
import { Module } from '@nestjs/common';
|
|
129
33
|
import { TypeOrmModule } from '@nestjs/typeorm';
|
|
130
|
-
import { NestBatchModule } from '@nest-batch/core';
|
|
131
|
-
import {
|
|
132
|
-
import { ProductEntity } from './entities/product.entity';
|
|
34
|
+
import { InProcessAdapter, NestBatchModule } from '@nest-batch/core';
|
|
35
|
+
import { BATCH_META_ENTITIES, TypeOrmAdapter } from '@nest-batch/typeorm';
|
|
133
36
|
|
|
134
37
|
@Module({
|
|
135
38
|
imports: [
|
|
136
39
|
TypeOrmModule.forRoot({
|
|
137
40
|
type: 'postgres',
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
username: 'demo',
|
|
141
|
-
password: 'demo',
|
|
142
|
-
database: 'nest_batch_demo',
|
|
143
|
-
entities: [ProductEntity, ...batchMetaEntities()],
|
|
144
|
-
migrations: [
|
|
145
|
-
/* your app-owned migrations */
|
|
146
|
-
],
|
|
147
|
-
migrationsRun: true,
|
|
41
|
+
entities: [ProductEntity, ...BATCH_META_ENTITIES],
|
|
42
|
+
url: process.env.DATABASE_URL,
|
|
148
43
|
}),
|
|
149
44
|
NestBatchModule.forRoot({
|
|
150
|
-
adapters: {
|
|
45
|
+
adapters: {
|
|
46
|
+
persistence: TypeOrmAdapter.forRoot(),
|
|
47
|
+
transport: InProcessAdapter.forRoot(),
|
|
48
|
+
},
|
|
151
49
|
}),
|
|
152
50
|
],
|
|
153
51
|
})
|
|
154
52
|
export class AppModule {}
|
|
155
53
|
```
|
|
156
54
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
declares its own provider and export surface. The
|
|
160
|
-
`JOB_REPOSITORY_TOKEN` and `TRANSACTION_MANAGER_TOKEN` bindings are
|
|
161
|
-
registered globally by the adapter, so you do **not** list
|
|
162
|
-
`TypeOrmJobRepository` / `TypeOrmTransactionManager` in the
|
|
163
|
-
`providers` array — they're already wired.
|
|
164
|
-
|
|
165
|
-
> **Warning:** The adapter does **not** call `TypeOrmModule.forRoot()`
|
|
166
|
-
> and does **not** create a `DataSource`. If you forget the
|
|
167
|
-
> `TypeOrmModule.forRoot()` import, the app boots cleanly and the
|
|
168
|
-
> batch module compiles, but the repository throws at first call
|
|
169
|
-
> because `Repository<Entity>` resolution has nothing to bind to.
|
|
170
|
-
> The two pieces are decoupled by design — the adapter is a
|
|
171
|
-
> binding-only carrier, and the connection is the host's.
|
|
172
|
-
|
|
173
|
-
> **Note:** `@nestjs/typeorm` defaults to `isGlobal: true`, which
|
|
174
|
-
> is what the adapter assumes. Setting `isGlobal: false` breaks
|
|
175
|
-
> `EntityManager` injection inside the adapter's own module: the
|
|
176
|
-
> `DataSource` is registered on the host's `TypeOrmModule.forRoot()`
|
|
177
|
-
> but the adapter module is `global: true`, so the `EntityManager`
|
|
178
|
-
> token it needs is not exported across the boundary. Leave it at
|
|
179
|
-
> the default unless you've wired an alternative.
|
|
180
|
-
|
|
181
|
-
`forRootAsync` is the right call when the connection comes from a
|
|
182
|
-
config service or a secret manager. Pass the standard `useFactory`
|
|
183
|
-
plus `inject` list to `TypeOrmModule.forRootAsync()` and keep
|
|
184
|
-
`TypeOrmAdapter.forRoot()` unchanged — the adapter doesn't care
|
|
185
|
-
how the `DataSource` is built.
|
|
186
|
-
|
|
187
|
-
### DataSource, not Connection
|
|
188
|
-
|
|
189
|
-
TypeORM 1.0.0 calls it `DataSource`. The old `Connection` type is
|
|
190
|
-
gone, and so is `getConnection()` / `getRepository()` on the
|
|
191
|
-
connection. Every example in this README uses `DataSource`. If
|
|
192
|
-
you're migrating from a 0.3 codebase, the rename touches every
|
|
193
|
-
test file, every import, and every import path — there is no
|
|
194
|
-
`@typeorm/0.3-compat` shim.
|
|
195
|
-
|
|
196
|
-
The `TypeOrmTransactionManager` accepts a `DataSource` and uses
|
|
197
|
-
`dataSource.transaction()` to start a real DB transaction. The
|
|
198
|
-
callback receives a transactional `EntityManager`; use that one,
|
|
199
|
-
not a globally-injected one, so all reads and writes are part of
|
|
200
|
-
the same transaction.
|
|
201
|
-
|
|
202
|
-
---
|
|
203
|
-
|
|
204
|
-
## DB-first semantics
|
|
205
|
-
|
|
206
|
-
The repository is the durable source of truth for execution state.
|
|
207
|
-
Same model as the MikroORM adapter, same invariants:
|
|
208
|
-
|
|
209
|
-
1. **The DB is canonical.** A BullMQ job is a correlation stamp, not
|
|
210
|
-
a state row. The `JobExecution` row carries the actual
|
|
211
|
-
`status`, `startTime`, `endTime`, `exitCode`, and `exitMessage`.
|
|
212
|
-
2. **Atomic launches are enforced by the row lock.** The
|
|
213
|
-
`createExecutionAtomic` flow uses a transactional
|
|
214
|
-
`SELECT ... FOR UPDATE SKIP LOCKED` (on PostgreSQL) to serialize
|
|
215
|
-
concurrent launches. Two callers racing to launch the same
|
|
216
|
-
`jobName + jobKey` get one winner; the loser sees a thrown
|
|
217
|
-
`JobExecutionAlreadyRunningError`.
|
|
218
|
-
3. **Restart and checkpoint go through the DB.** `findLatestStepExecution`
|
|
219
|
-
returns the most recent `StepExecution` for `(jobExecutionId, stepName)`
|
|
220
|
-
regardless of status, so the executor can load the
|
|
221
|
-
last-committed chunk index from
|
|
222
|
-
`batch_step_execution_context` and resume from there.
|
|
223
|
-
|
|
224
|
-
The contract suite is the same one `@nest-batch/mikro-orm` runs. If
|
|
225
|
-
you change the repository or transaction manager, run the suite to
|
|
226
|
-
confirm you haven't broken the contract.
|
|
227
|
-
|
|
228
|
-
---
|
|
229
|
-
|
|
230
|
-
## What is NOT in this package
|
|
231
|
-
|
|
232
|
-
- A TypeORM 0.3 adapter. Use 1.0.0 or stay on the previous package.
|
|
233
|
-
- A Drizzle adapter. Drizzle is explicitly excluded from this
|
|
234
|
-
release. See `MIGRATION.md`.
|
|
235
|
-
- A MikroORM adapter. Use `@nest-batch/mikro-orm` if you want
|
|
236
|
-
MikroORM 6; the two packages expose the same six-table schema.
|
|
237
|
-
- A transport. Use `@nest-batch/bullmq` to wire BullMQ as the
|
|
238
|
-
execution strategy; the transport layer reads the same
|
|
239
|
-
`JobExecution` rows.
|
|
240
|
-
- An admin UI, metrics, tracing, webhook, or job visualization
|
|
241
|
-
surface. Out of scope for the whole `@nest-batch/*` family.
|
|
242
|
-
|
|
243
|
-
---
|
|
244
|
-
|
|
245
|
-
## Scripts
|
|
246
|
-
|
|
247
|
-
```bash
|
|
248
|
-
pnpm --filter @nest-batch/typeorm build # SWC transpile + tsc declarations
|
|
249
|
-
pnpm --filter @nest-batch/typeorm test # vitest run (uses better-sqlite3 by default)
|
|
250
|
-
pnpm --filter @nest-batch/typeorm test:watch # vitest watch
|
|
251
|
-
pnpm --filter @nest-batch/typeorm typecheck # tsc --noEmit
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
The contract suite runs against an in-memory SQLite database by
|
|
255
|
-
default. The test driver is `better-sqlite3` because it gives
|
|
256
|
-
sub-millisecond setup and teardown, and the contract tests are
|
|
257
|
-
database-agnostic enough to not need a full PostgreSQL harness.
|
|
258
|
-
For an end-to-end Postgres run, point the suite at your own
|
|
259
|
-
`DataSource` via the documented test harness hook.
|
|
55
|
+
Generate migrations in the application repository after adding the metadata
|
|
56
|
+
entities.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nest-batch/typeorm",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "TypeORM 1.0.0 adapter SLOT for @nest-batch/core — JobRepository and TransactionManager interface shape, paired with @nest-batch/postgresql (Postgres driver) or @nest-batch/mysql (MySQL driver).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "easdkr",
|
|
@@ -25,7 +25,8 @@
|
|
|
25
25
|
"files": [
|
|
26
26
|
"dist/src",
|
|
27
27
|
"src",
|
|
28
|
-
"README.md"
|
|
28
|
+
"README.md",
|
|
29
|
+
"README.ko.md"
|
|
29
30
|
],
|
|
30
31
|
"publishConfig": {
|
|
31
32
|
"access": "public"
|
|
@@ -33,7 +34,7 @@
|
|
|
33
34
|
"peerDependencies": {
|
|
34
35
|
"@nestjs/common": "^10 || ^11",
|
|
35
36
|
"typeorm": "^1.0.0",
|
|
36
|
-
"@nest-batch/core": "^0.2.
|
|
37
|
+
"@nest-batch/core": "^0.2.4"
|
|
37
38
|
},
|
|
38
39
|
"peerDependenciesMeta": {
|
|
39
40
|
"typeorm": {
|
|
@@ -58,7 +59,7 @@
|
|
|
58
59
|
"typescript": "^5.5.0",
|
|
59
60
|
"unplugin-swc": "^1.5.0",
|
|
60
61
|
"vitest": "^2.0.0",
|
|
61
|
-
"@nest-batch/core": "0.2.
|
|
62
|
+
"@nest-batch/core": "0.2.4"
|
|
62
63
|
},
|
|
63
64
|
"scripts": {
|
|
64
65
|
"build": "swc src -d dist --config-file ../../.swcrc && tsc --emitDeclarationOnly -p tsconfig.build.json",
|