@joakimbugge/typeorm-seeder 0.2.0 → 0.4.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/README.md CHANGED
@@ -1,276 +1,308 @@
1
- # @joakimbugge/typeorm-seeder
2
-
3
- Decorator-based entity seeding for TypeORM. Annotate your entity properties with `@Seed()`, then create or persist fully populated entity graphs with a single function call — including relations, embedded types, and circular guards. Organise complex seeding scenarios into `@Seeder` classes with declared dependencies that are automatically ordered and executed for you.
4
-
5
- ---
6
-
7
- ## Installation
8
-
9
- ```bash
10
- npm install @joakimbugge/typeorm-seeder
11
- ```
12
-
13
- `typeorm` and `reflect-metadata` are peer dependencies and must be installed alongside it.
14
-
15
- ```bash
16
- npm install typeorm reflect-metadata
17
- ```
18
-
19
- Your `tsconfig.json` must have decorator support enabled:
20
-
21
- ```json
22
- {
23
- "compilerOptions": {
24
- "experimentalDecorators": true,
25
- "emitDecoratorMetadata": true
26
- }
27
- }
28
- ```
29
-
30
- ---
31
-
32
- ## Decorating entities
33
-
34
- Use `@Seed()` on any entity property to describe how it should be populated. Plain column properties (scalars) take a factory function; relation properties take the bare decorator (or a `count` option for collections).
35
-
36
- ```ts
37
- import { Entity, PrimaryGeneratedColumn, Column, OneToMany, ManyToOne } from 'typeorm'
38
- import { faker } from '@faker-js/faker'
39
- import { Seed } from '@joakimbugge/typeorm-seeder'
40
-
41
- @Entity()
42
- class Author {
43
- @PrimaryGeneratedColumn()
44
- id!: number
45
-
46
- @Seed(() => faker.person.fullName())
47
- @Column()
48
- name!: string
49
-
50
- @Seed({ count: 3 })
51
- @OneToMany(() => Book, (b) => b.author)
52
- books!: Book[]
53
- }
54
-
55
- @Entity()
56
- class Book {
57
- @PrimaryGeneratedColumn()
58
- id!: number
59
-
60
- @Seed(() => faker.lorem.words(4))
61
- @Column()
62
- title!: string
63
-
64
- @Seed()
65
- @ManyToOne(() => Author, (a) => a.books)
66
- author!: Author
67
- }
68
- ```
69
-
70
- > [!IMPORTANT]
71
- > **How circular relations are handled**
72
- >
73
- > When seeding `Author`, its `books` are seeded too. Each `Book` has an `author` relation back to `Author` — but seeding that would loop back to `Author`, which would seed more books, and so on forever.
74
- >
75
- > @joakimbugge/typeorm-seeder breaks the cycle at the point where a type would re-enter itself. In the example above, `book.author` is left `undefined` when seeding from `Author`. Seeding a `Book` directly works fine and does populate `book.author` — the cycle only cuts when a type is already being seeded higher up in the same chain.
76
-
77
- ---
78
-
79
- ## Seeding entities
80
-
81
- Call `seed(EntityClass)` to get a builder with four methods: `create`, `createMany`, `save`, and `saveMany`.
82
-
83
- ```ts
84
- import { seed } from '@joakimbugge/typeorm-seeder'
85
- ```
86
-
87
- ### Saving
88
-
89
- `save()` and `saveMany()` create instances and write them to the database in one step. Pass a `DataSource` in the options.
90
-
91
- ```ts
92
- const author = await seed(Author).save({ dataSource })
93
- // author.id → assigned by the database
94
- // author.books → 3 persisted Book instances
95
-
96
- const authors = await seed(Author).saveMany(5, { dataSource })
97
- // [Author, Author, Author, Author, Author] — each with their own books
98
- ```
99
-
100
- ### Without saving
101
-
102
- `create()` and `createMany()` build entity instances without touching the database. Useful for unit tests or for preparing entities before passing them to your own persistence logic.
103
-
104
- ```ts
105
- const author = await seed(Author).create()
106
- // Plain Author instance — no id, fully populated relations
107
-
108
- const books = await seed(Book).createMany(10)
109
- // [Book, Book, …] — each with its own seeded Author
110
- ```
111
-
112
- ### Multiple entity types at once
113
-
114
- Pass an array of entity classes to seed one of each:
115
-
116
- ```ts
117
- const [author, book] = await seed([Author, Book]).create()
118
- const [author, book] = await seed([Author, Book]).save({ dataSource })
119
- ```
120
-
121
- Relation seeding is **disabled by default** in this form — each entity is created independently, so there is no overlap between the `Author` you asked for and the `Author` that would have been auto-created inside `Book`. Pass `relations: true` to override:
122
-
123
- ```ts
124
- const [author, book] = await seed([Author, Book]).save({ dataSource, relations: true })
125
- // author.books → seeded | book.author → seeded (independently)
126
- ```
127
-
128
- `createMany` and `saveMany` return an array per class:
129
-
130
- ```ts
131
- const [authors, books] = await seed([Author, Book]).createMany(3)
132
- // authors → [Author, Author, Author]
133
- // books → [Book, Book, Book]
134
- ```
135
-
136
- ### Skipping relations
137
-
138
- Pass `relations: false` to create a flat entity with no relation properties set — useful when you want to wire relations yourself:
139
-
140
- ```ts
141
- const author = await seed(Author).create({ relations: false })
142
- // author.books → undefined
143
-
144
- const book = await seed(Book).save({ dataSource, relations: false })
145
- // book.author → null in the database
146
- ```
147
-
148
- ### Passing a DataSource to factories
149
-
150
- If a factory needs to query the database, the `dataSource` you provide in options is forwarded to every factory via `SeedContext`:
151
-
152
- ```ts
153
- @Seed(async ({ dataSource }) => {
154
- const existing = await dataSource!.getRepository(Role).findOneBy({ name: 'admin' })
155
- return existing!
156
- })
157
- @ManyToOne(() => Role)
158
- role!: Role
159
- ```
160
-
161
- ---
162
-
163
- ## Seeder suites
164
-
165
- For production seeding scripts or structured test fixtures, organise your seeding logic into `@Seeder` classes. Declare dependencies between seeders and let the library figure out the execution order.
166
-
167
- ```ts
168
- import { Seeder, runSeeders, seed } from '@joakimbugge/typeorm-seeder'
169
- import type { SeederInterface, SeedContext } from '@joakimbugge/typeorm-seeder'
170
-
171
- @Seeder()
172
- class UserSeeder implements SeederInterface {
173
- async run(ctx: SeedContext) {
174
- await seed(User).saveMany(10, { ...ctx, dataSource: ctx.dataSource! })
175
- }
176
- }
177
-
178
- @Seeder({ dependencies: [UserSeeder] })
179
- class PostSeeder implements SeederInterface {
180
- async run(ctx: SeedContext) {
181
- await seed(Post).saveMany(50, { ...ctx, dataSource: ctx.dataSource! })
182
- }
183
- }
184
-
185
- // Run from your seed script or test setup:
186
- await runSeeders([PostSeeder], { dataSource })
187
- // UserSeeder runs first, then PostSeeder
188
- ```
189
-
190
- `runSeeders` accepts the root seeders you want to execute. It collects all transitive dependencies, topologically sorts them, and runs each once in the correct order. Passing the same seeder as both a root and a dependency of another root is safe — it will only run once.
191
-
192
- Circular dependencies between seeders are detected at runtime and throw an error naming the seeders involved.
193
-
194
- ---
195
-
196
- ## API reference
197
-
198
- ### `@Seed(factory?, options?)`
199
-
200
- Property decorator. Marks a property for automatic seeding.
201
-
202
- | Signature | Behaviour |
203
- |---|---|
204
- | `@Seed(factory)` | Calls `factory(context)` and assigns the result |
205
- | `@Seed(factory, options)` | Same, with additional options |
206
- | `@Seed(options)` | Relation seed with options (e.g. `count`) |
207
- | `@Seed()` | Bare relation seed — auto-creates one related entity |
208
-
209
- **`SeedOptions`**
210
-
211
- | Property | Type | Description |
212
- |---|---|---|
213
- | `count` | `number` | Number of related entities to create. Only applies to `one-to-many` and `many-to-many` relations. |
214
-
215
- ---
216
-
217
- ### `seed(EntityClass)`
218
-
219
- Returns a builder for creating and persisting seed entities.
220
-
221
- ```ts
222
- seed(Author).create(context?): Promise<Author>
223
- seed(Author).createMany(count, context?): Promise<Author[]>
224
- seed(Author).save(options): Promise<Author>
225
- seed(Author).saveMany(count, options): Promise<Author[]>
226
- ```
227
-
228
- The array form returns a tuple of instances (or arrays of instances for `createMany`/`saveMany`):
229
-
230
- ```ts
231
- seed([Author, Book]).create(context?): Promise<[Author, Book]>
232
- seed([Author, Book]).createMany(count, context?): Promise<[Author[], Book[]]>
233
- seed([Author, Book]).save(options): Promise<[Author, Book]>
234
- seed([Author, Book]).saveMany(count, options): Promise<[Author[], Book[]]>
235
- ```
236
-
237
- ---
238
-
239
- ### `@Seeder(options?)`
240
-
241
- Class decorator. Registers a class as a seeder and declares its dependencies.
242
-
243
- **`SeederOptions`**
244
-
245
- | Property | Type | Description |
246
- |---|---|---|
247
- | `dependencies` | `SeederInterface[]` | Seeders that must run before this one. |
248
-
249
- ---
250
-
251
- ### `runSeeders(seeders, context?)`
252
-
253
- Topologically sorts and runs the given seeders plus all their transitive dependencies.
254
-
255
- ```ts
256
- runSeeders([PostSeeder], { dataSource }): Promise<void>
257
- ```
258
-
259
- Throws if a circular dependency is detected.
260
-
261
- ---
262
-
263
- ### `SeedContext`
264
-
265
- Passed to factory functions and `SeederInterface.run()`.
266
-
267
- | Property | Type | Description |
268
- |---|---|---|
269
- | `dataSource` | `DataSource?` | Active TypeORM data source. |
270
- | `relations` | `boolean?` | Set to `false` to skip relation seeding. Defaults to `true`. |
271
-
272
- ---
273
-
274
- ## License
275
-
276
- MIT
1
+ # @joakimbugge/typeorm-seeder
2
+
3
+ Decorator-based entity seeding for TypeORM. Annotate your entity properties with `@Seed()`, then create or persist fully populated entity graphs with a single function call — including relations, embedded types, and circular guards. Organise complex seeding scenarios into `@Seeder` classes with declared dependencies that are automatically ordered and executed for you.
4
+
5
+ ---
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install @joakimbugge/typeorm-seeder
11
+ ```
12
+
13
+ `typeorm` and `reflect-metadata` are peer dependencies and must be installed alongside it.
14
+
15
+ ```bash
16
+ npm install typeorm reflect-metadata
17
+ ```
18
+
19
+ Your `tsconfig.json` must have decorator support enabled:
20
+
21
+ ```json
22
+ {
23
+ "compilerOptions": {
24
+ "experimentalDecorators": true,
25
+ "emitDecoratorMetadata": true
26
+ }
27
+ }
28
+ ```
29
+
30
+ ---
31
+
32
+ ## Decorating entities
33
+
34
+ Use `@Seed()` on any entity property to describe how it should be populated. Plain column properties (scalars) take a factory function; relation properties take the bare decorator (or a `count` option for collections).
35
+
36
+ ```ts
37
+ import { Entity, PrimaryGeneratedColumn, Column, OneToMany, ManyToOne } from 'typeorm'
38
+ import { faker } from '@faker-js/faker'
39
+ import { Seed } from '@joakimbugge/typeorm-seeder'
40
+
41
+ @Entity()
42
+ class Author {
43
+ @PrimaryGeneratedColumn()
44
+ id!: number
45
+
46
+ @Seed(() => faker.person.fullName())
47
+ @Column()
48
+ name!: string
49
+
50
+ @Seed({ count: 3 })
51
+ @OneToMany(() => Book, (b) => b.author)
52
+ books!: Book[]
53
+ }
54
+
55
+ @Entity()
56
+ class Book {
57
+ @PrimaryGeneratedColumn()
58
+ id!: number
59
+
60
+ @Seed(() => faker.lorem.words(4))
61
+ @Column()
62
+ title!: string
63
+
64
+ @Seed()
65
+ @ManyToOne(() => Author, (a) => a.books)
66
+ author!: Author
67
+ }
68
+ ```
69
+
70
+ > [!IMPORTANT]
71
+ > **How circular relations are handled**
72
+ >
73
+ > When seeding `Author`, its `books` are seeded too. Each `Book` has an `author` relation back to `Author` — but seeding that would loop back to `Author`, which would seed more books, and so on forever.
74
+ >
75
+ > @joakimbugge/typeorm-seeder breaks the cycle at the point where a type would re-enter itself. In the example above, `book.author` is left `undefined` when seeding from `Author`. Seeding a `Book` directly works fine and does populate `book.author` — the cycle only cuts when a type is already being seeded higher up in the same chain.
76
+
77
+ ---
78
+
79
+ ## Seeding entities
80
+
81
+ Call `seed(EntityClass)` to get a builder with four methods: `create`, `createMany`, `save`, and `saveMany`.
82
+
83
+ ```ts
84
+ import { seed } from '@joakimbugge/typeorm-seeder'
85
+ ```
86
+
87
+ ### Saving
88
+
89
+ `save()` and `saveMany()` create instances and write them to the database in one step. Pass a `DataSource` in the options.
90
+
91
+ ```ts
92
+ const author = await seed(Author).save({ dataSource })
93
+ // author.id → assigned by the database
94
+ // author.books → 3 persisted Book instances
95
+
96
+ const authors = await seed(Author).saveMany(5, { dataSource })
97
+ // [Author, Author, Author, Author, Author] — each with their own books
98
+ ```
99
+
100
+ ### Without saving
101
+
102
+ `create()` and `createMany()` build entity instances without touching the database. Useful for unit tests or for preparing entities before passing them to your own persistence logic.
103
+
104
+ ```ts
105
+ const author = await seed(Author).create()
106
+ // Plain Author instance — no id, fully populated relations
107
+
108
+ const books = await seed(Book).createMany(10)
109
+ // [Book, Book, …] — each with its own seeded Author
110
+ ```
111
+
112
+ ### Multiple entity types at once
113
+
114
+ Pass an array of entity classes to seed one of each:
115
+
116
+ ```ts
117
+ const [author, book] = await seed([Author, Book]).create()
118
+ const [author, book] = await seed([Author, Book]).save({ dataSource })
119
+ ```
120
+
121
+ Relation seeding is **disabled by default** in this form — each entity is created independently, so there is no overlap between the `Author` you asked for and the `Author` that would have been auto-created inside `Book`. Pass `relations: true` to override:
122
+
123
+ ```ts
124
+ const [author, book] = await seed([Author, Book]).save({ dataSource, relations: true })
125
+ // author.books → seeded | book.author → seeded (independently)
126
+ ```
127
+
128
+ `createMany` and `saveMany` return an array per class:
129
+
130
+ ```ts
131
+ const [authors, books] = await seed([Author, Book]).createMany(3)
132
+ // authors → [Author, Author, Author]
133
+ // books → [Book, Book, Book]
134
+ ```
135
+
136
+ ### Skipping relations
137
+
138
+ Pass `relations: false` to create a flat entity with no relation properties set — useful when you want to wire relations yourself:
139
+
140
+ ```ts
141
+ const author = await seed(Author).create({ relations: false })
142
+ // author.books → undefined
143
+
144
+ const book = await seed(Book).save({ dataSource, relations: false })
145
+ // book.author → null in the database
146
+ ```
147
+
148
+ ### Passing a DataSource to factories
149
+
150
+ If a factory needs to query the database, the `dataSource` you provide in options is forwarded to every factory via `SeedContext`:
151
+
152
+ ```ts
153
+ @Seed(async ({ dataSource }) => {
154
+ const existing = await dataSource!.getRepository(Role).findOneBy({ name: 'admin' })
155
+ return existing!
156
+ })
157
+ @ManyToOne(() => Role)
158
+ role!: Role
159
+ ```
160
+
161
+ ---
162
+
163
+ ## Seeder suites
164
+
165
+ For production seeding scripts or structured test fixtures, organise your seeding logic into `@Seeder` classes. Declare dependencies between seeders and let the library figure out the execution order.
166
+
167
+ ```ts
168
+ import { Seeder, runSeeders, seed } from '@joakimbugge/typeorm-seeder'
169
+ import type { SeederInterface, SeedContext } from '@joakimbugge/typeorm-seeder'
170
+
171
+ @Seeder()
172
+ class UserSeeder implements SeederInterface {
173
+ async run(ctx: SeedContext) {
174
+ await seed(User).saveMany(10, { ...ctx, dataSource: ctx.dataSource! })
175
+ }
176
+ }
177
+
178
+ @Seeder({ dependencies: [UserSeeder] })
179
+ class PostSeeder implements SeederInterface {
180
+ async run(ctx: SeedContext) {
181
+ await seed(Post).saveMany(50, { ...ctx, dataSource: ctx.dataSource! })
182
+ }
183
+ }
184
+
185
+ // Run from your seed script or test setup:
186
+ await runSeeders([PostSeeder], { dataSource })
187
+ // UserSeeder runs first, then PostSeeder
188
+ ```
189
+
190
+ `runSeeders` accepts the root seeders you want to execute. It collects all transitive dependencies, topologically sorts them, and runs each once in the correct order. Passing the same seeder as both a root and a dependency of another root is safe — it will only run once.
191
+
192
+ Circular dependencies between seeders are detected at runtime and throw an error naming the seeders involved.
193
+
194
+ ---
195
+
196
+ ## Running seed scripts
197
+
198
+ When running a seed script directly with Node.js, `reflect-metadata` must be the very first import — before any entity is loaded. TypeORM's decorators depend on it being in place when the class is evaluated.
199
+
200
+ ```ts
201
+ import 'reflect-metadata'
202
+ import { seed } from '@joakimbugge/typeorm-seeder'
203
+ import { User } from './entities/User.js'
204
+
205
+ await seed(User).save({ dataSource })
206
+ ```
207
+
208
+ ### TypeScript execution
209
+
210
+ [tsx](https://github.com/privatenumber/tsx) is a popular choice for running TypeScript directly, but it uses esbuild under the hood which does not support `emitDecoratorMetadata`. This causes TypeORM to fail when inferring column types. Use [ts-node](https://github.com/TypeStrong/ts-node) instead.
211
+
212
+ **ESM projects** (`"type": "module"` or `"module": "nodenext"` in tsconfig):
213
+
214
+ ```bash
215
+ node --no-warnings --loader ts-node/esm src/seed.ts
216
+ ```
217
+
218
+ `--no-warnings` suppresses two noisy but harmless warnings emitted by ts-node itself: one about `--loader` being experimental (Node.js may eventually replace it with `register()`), and one about ts-node internally using a deprecated `fs.Stats` constructor.
219
+
220
+ **CommonJS projects:**
221
+
222
+ ```bash
223
+ npx ts-node src/seed.ts
224
+ ```
225
+
226
+ ---
227
+
228
+ ## API reference
229
+
230
+ ### `@Seed(factory?, options?)`
231
+
232
+ Property decorator. Marks a property for automatic seeding.
233
+
234
+ | Signature | Behaviour |
235
+ |---|---|
236
+ | `@Seed(factory)` | Calls `factory(context)` and assigns the result |
237
+ | `@Seed(factory, options)` | Same, with additional options |
238
+ | `@Seed(options)` | Relation seed with options (e.g. `count`) |
239
+ | `@Seed()` | Bare relation seed — auto-creates one related entity |
240
+
241
+ **`SeedOptions`**
242
+
243
+ | Property | Type | Description |
244
+ |---|---|---|
245
+ | `count` | `number` | Number of related entities to create. Only applies to `one-to-many` and `many-to-many` relations. |
246
+
247
+ ---
248
+
249
+ ### `seed(EntityClass)`
250
+
251
+ Returns a builder for creating and persisting seed entities.
252
+
253
+ ```ts
254
+ seed(Author).create(context?): Promise<Author>
255
+ seed(Author).createMany(count, context?): Promise<Author[]>
256
+ seed(Author).save(options): Promise<Author>
257
+ seed(Author).saveMany(count, options): Promise<Author[]>
258
+ ```
259
+
260
+ The array form returns a tuple of instances (or arrays of instances for `createMany`/`saveMany`):
261
+
262
+ ```ts
263
+ seed([Author, Book]).create(context?): Promise<[Author, Book]>
264
+ seed([Author, Book]).createMany(count, context?): Promise<[Author[], Book[]]>
265
+ seed([Author, Book]).save(options): Promise<[Author, Book]>
266
+ seed([Author, Book]).saveMany(count, options): Promise<[Author[], Book[]]>
267
+ ```
268
+
269
+ ---
270
+
271
+ ### `@Seeder(options?)`
272
+
273
+ Class decorator. Registers a class as a seeder and declares its dependencies.
274
+
275
+ **`SeederOptions`**
276
+
277
+ | Property | Type | Description |
278
+ |---|---|---|
279
+ | `dependencies` | `SeederInterface[]` | Seeders that must run before this one. |
280
+
281
+ ---
282
+
283
+ ### `runSeeders(seeders, context?)`
284
+
285
+ Topologically sorts and runs the given seeders plus all their transitive dependencies.
286
+
287
+ ```ts
288
+ runSeeders([PostSeeder], { dataSource }): Promise<void>
289
+ ```
290
+
291
+ Throws if a circular dependency is detected.
292
+
293
+ ---
294
+
295
+ ### `SeedContext`
296
+
297
+ Passed to factory functions and `SeederInterface.run()`.
298
+
299
+ | Property | Type | Description |
300
+ |---|---|---|
301
+ | `dataSource` | `DataSource?` | Active TypeORM data source. |
302
+ | `relations` | `boolean?` | Set to `false` to skip relation seeding. Defaults to `true`. |
303
+
304
+ ---
305
+
306
+ ## License
307
+
308
+ MIT
package/dist/index.cjs CHANGED
@@ -257,8 +257,25 @@ function topoSort(roots) {
257
257
  throw err;
258
258
  }
259
259
  }
260
- async function runSeeders(seeders, context = {}) {
261
- for (const SeederClass of topoSort(seeders)) await new SeederClass().run(context);
260
+ async function runSeeders(seeders, options = {}) {
261
+ const { logging = true, onBefore, onAfter, onError, skip, ...context } = options;
262
+ for (const SeederClass of topoSort(seeders)) {
263
+ if (await skip?.(SeederClass)) continue;
264
+ if (logging) console.log(`[${SeederClass.name}] Starting...`);
265
+ await onBefore?.(SeederClass);
266
+ const start = Date.now();
267
+ try {
268
+ await new SeederClass().run(context);
269
+ } catch (err) {
270
+ const durationMs = Date.now() - start;
271
+ if (logging) console.error(`[${SeederClass.name}] Failed after ${durationMs}ms`);
272
+ await onError?.(SeederClass, err);
273
+ throw err;
274
+ }
275
+ const durationMs = Date.now() - start;
276
+ if (logging) console.log(`[${SeederClass.name}] Done in ${durationMs}ms`);
277
+ await onAfter?.(SeederClass, durationMs);
278
+ }
262
279
  }
263
280
  //#endregion
264
281
  exports.Seed = Seed;
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["registry","DepGraph"],"sources":["../src/seed/registry.ts","../src/seed/decorator.ts","../src/seed/creator.ts","../src/seed/persist.ts","../src/seed/builder.ts","../src/seeder/registry.ts","../src/seeder/decorator.ts","../src/seeder/runner.ts"],"sourcesContent":["import type { DataSource } from 'typeorm';\n\n/** An entity instance — any class-based object managed by TypeORM. */\nexport type EntityInstance = object;\n\n/** A constructor that produces an entity instance. */\nexport type EntityConstructor<T extends EntityInstance = EntityInstance> = new () => T;\n\nexport interface SeedContext {\n dataSource?: DataSource;\n /**\n * Set to `false` to skip automatic relation seeding. Scalar and embedded\n * properties are still seeded; only relation properties decorated with a\n * bare `@Seed()` are skipped. Useful when you want to create flat entities\n * and wire relations yourself.\n *\n * @default true\n */\n relations?: boolean;\n}\n\n/** Factory callback passed to @Seed. Receives the seeder context, which may include a DataSource. */\nexport type SeedFactory<T = unknown> = (context: SeedContext) => T | Promise<T>;\n\n/** Options passed to @Seed. */\nexport interface SeedOptions {\n /**\n * Number of related entities to create. Only meaningful on one-to-many and\n * many-to-many relation properties. Ignored on scalar and single-entity relations.\n */\n count?: number;\n}\n\nexport interface SeedEntry {\n propertyKey: string | symbol;\n /** Undefined when @Seed is used without a factory (i.e. bare relation seed). */\n factory: SeedFactory | undefined;\n options: SeedOptions;\n}\n\nexport type MapToInstances<T extends readonly EntityConstructor[]> = {\n [K in keyof T]: T[K] extends EntityConstructor<infer I> ? I : never;\n};\n\nexport type MapToInstanceArrays<T extends readonly EntityConstructor[]> = {\n [K in keyof T]: T[K] extends EntityConstructor<infer I> ? I[] : never;\n};\n\n// Keyed by the entity class constructor.\nconst registry = new Map<Function, SeedEntry[]>();\n\nexport function registerSeed(target: Function, entry: SeedEntry): void {\n const entries = registry.get(target) ?? [];\n\n entries.push(entry);\n registry.set(target, entries);\n}\n\n/**\n * Returns all seed entries for the given class, including those inherited from\n * parent classes. Parent entries come first, preserving declaration order.\n */\nexport function getSeeds(target: Function): SeedEntry[] {\n const entries: SeedEntry[] = [];\n let current: Function = target;\n\n while (current && current !== Function.prototype) {\n const own = registry.get(current);\n\n if (own) {\n entries.unshift(...own);\n }\n\n current = Object.getPrototypeOf(current) as Function;\n }\n\n return entries;\n}\n","import { registerSeed } from './registry.js';\nimport type { SeedFactory, SeedOptions } from './registry.js';\n\n/** Mark a relation property for auto-seeding (creates one related entity). */\nexport function Seed(): PropertyDecorator;\n/** Mark a relation property for auto-seeding with options (e.g. count for one-to-many). */\nexport function Seed(options: SeedOptions): PropertyDecorator;\n/** Mark a scalar property with a factory callback. */\nexport function Seed(factory: SeedFactory): PropertyDecorator;\n/** Mark a scalar property with a factory callback and options. */\nexport function Seed(factory: SeedFactory, options: SeedOptions): PropertyDecorator;\nexport function Seed(\n factoryOrOptions?: SeedFactory | SeedOptions,\n options?: SeedOptions,\n): PropertyDecorator {\n const factory = typeof factoryOrOptions === 'function' ? factoryOrOptions : undefined;\n const opts: SeedOptions =\n (typeof factoryOrOptions === 'object' ? factoryOrOptions : options) ?? {};\n\n return (target, propertyKey) => {\n registerSeed(target.constructor as Function, { propertyKey, factory, options: opts });\n };\n}\n","import { getMetadataArgsStorage } from 'typeorm';\nimport { getSeeds } from './registry.js';\nimport type {\n EntityConstructor,\n EntityInstance,\n MapToInstanceArrays,\n MapToInstances,\n SeedContext,\n} from './registry.js';\n\nexport interface CreateManySeedOptions extends SeedContext {\n count: number;\n}\n\n// Internal extension of SeedContext — never exposed in the public API.\ninterface InternalContext extends SeedContext {\n _ancestors: Set<Function>;\n}\n\nfunction getAncestors(context: SeedContext): Set<Function> {\n return (context as InternalContext)._ancestors ?? new Set();\n}\n\nfunction withAncestor(context: SeedContext, cls: Function): InternalContext {\n const ancestors = getAncestors(context);\n\n return { ...context, _ancestors: new Set([...ancestors, cls]) };\n}\n\nfunction getClassHierarchy(target: Function): Function[] {\n const hierarchy: Function[] = [];\n let current: Function = target;\n\n while (current && current !== Function.prototype) {\n hierarchy.push(current);\n current = Object.getPrototypeOf(current) as Function;\n }\n\n return hierarchy;\n}\n\nasync function createOneSeed<T extends EntityInstance>(\n EntityClass: EntityConstructor<T>,\n context: SeedContext,\n): Promise<T> {\n const instance = new EntityClass();\n const ancestors = getAncestors(context);\n const childContext = withAncestor(context, EntityClass);\n const storage = getMetadataArgsStorage();\n const relations = storage.filterRelations(getClassHierarchy(EntityClass));\n const seededProperties = new Set<string | symbol>();\n const record = instance as Record<string | symbol, unknown>;\n\n // Step 1: Run @Seed entries that have an explicit factory.\n for (const { propertyKey, factory } of getSeeds(EntityClass)) {\n if (!factory) {\n continue;\n }\n\n record[propertyKey] = await factory(context);\n seededProperties.add(propertyKey);\n }\n\n // Step 2: Auto-seed TypeORM embedded properties not already covered by Step 1.\n for (const embedded of storage.filterEmbeddeds(EntityClass)) {\n if (seededProperties.has(embedded.propertyName)) {\n continue;\n }\n\n const EmbeddedClass = embedded.type() as EntityConstructor;\n\n if (getSeeds(EmbeddedClass).length > 0) {\n record[embedded.propertyName] = await createOneSeed(EmbeddedClass, context);\n seededProperties.add(embedded.propertyName);\n }\n }\n\n // Step 3: Auto-seed @Seed entries without a factory (relation seeds).\n // Uses the ancestor guard to cut circular chains: if the related class is\n // already being seeded higher up in this call chain, the property is left\n // undefined rather than triggering infinite recursion.\n // Skipped entirely when context.relations === false.\n if (context.relations === false) {\n return instance;\n }\n\n for (const { propertyKey, factory, options } of getSeeds(EntityClass)) {\n if (factory || seededProperties.has(propertyKey)) {\n continue;\n }\n\n const relation = relations.find((r) => r.propertyName === String(propertyKey));\n\n if (!relation || typeof relation.type !== 'function') {\n continue;\n }\n\n const RelatedClass = (relation.type as () => Function)() as EntityConstructor;\n\n if (ancestors.has(RelatedClass)) {\n continue;\n }\n\n const isArray =\n relation.relationType === 'one-to-many' || relation.relationType === 'many-to-many';\n\n if (isArray) {\n record[propertyKey] = await createManySeed(RelatedClass, {\n count: options.count ?? 1,\n ...childContext,\n });\n } else {\n record[propertyKey] = await createOneSeed(RelatedClass, childContext);\n }\n\n seededProperties.add(propertyKey);\n }\n\n return instance;\n}\n\nexport async function createSeed<T extends EntityInstance>(\n EntityClass: EntityConstructor<T>,\n context?: SeedContext,\n): Promise<T>;\nexport async function createSeed<T extends readonly EntityConstructor[]>(\n EntityClasses: [...T],\n context?: SeedContext,\n): Promise<MapToInstances<T>>;\nexport async function createSeed<T extends EntityInstance>(\n classOrClasses: EntityConstructor<T> | readonly EntityConstructor[],\n context: SeedContext = {},\n): Promise<T | EntityInstance[]> {\n if (Array.isArray(classOrClasses)) {\n const effectiveContext: SeedContext = { relations: false, ...context };\n\n return (await Promise.all(\n (classOrClasses as EntityConstructor[]).map((cls) => createOneSeed(cls, effectiveContext)),\n )) as EntityInstance[];\n }\n\n const [entity] = await createManySeed(classOrClasses as EntityConstructor<T>, {\n count: 1,\n ...context,\n });\n\n return entity!;\n}\n\nexport async function createManySeed<T extends EntityInstance>(\n EntityClass: EntityConstructor<T>,\n options: CreateManySeedOptions,\n): Promise<T[]>;\nexport async function createManySeed<T extends readonly EntityConstructor[]>(\n EntityClasses: [...T],\n options: CreateManySeedOptions,\n): Promise<MapToInstanceArrays<T>>;\nexport async function createManySeed<T extends EntityInstance>(\n classOrClasses: EntityConstructor<T> | readonly EntityConstructor[],\n { count, ...context }: CreateManySeedOptions,\n): Promise<T[] | EntityInstance[][]> {\n if (Array.isArray(classOrClasses)) {\n const effectiveContext: SeedContext = { relations: false, ...context };\n\n return (await Promise.all(\n (classOrClasses as EntityConstructor[]).map((cls) =>\n Promise.all(Array.from({ length: count }, () => createOneSeed(cls, effectiveContext))),\n ),\n )) as EntityInstance[][];\n }\n\n return await Promise.all(\n Array.from({ length: count }, () =>\n createOneSeed(classOrClasses as EntityConstructor<T>, context),\n ),\n );\n}\n","import { type DataSource } from 'typeorm';\n\nimport { createManySeed } from './creator.js';\nimport type {\n EntityConstructor,\n EntityInstance,\n MapToInstanceArrays,\n MapToInstances,\n SeedContext,\n} from './registry.js';\n\nexport interface SaveSeedOptions extends SeedContext {\n dataSource: DataSource;\n}\n\nexport interface SaveManySeedOptions extends SaveSeedOptions {\n count: number;\n}\n\ntype RelationMetadata = DataSource extends { getMetadata(...args: never[]): infer M }\n ? M extends { relations: Array<infer R> }\n ? R\n : never\n : never;\n\ninterface CascadeState {\n relation: RelationMetadata;\n original: boolean;\n}\n\nfunction collectEntityClasses(entity: EntityInstance, visited = new Set<Function>()): Function[] {\n const EntityClass = entity.constructor as Function;\n\n if (visited.has(EntityClass)) {\n return [];\n }\n\n visited.add(EntityClass);\n\n const classes: Function[] = [EntityClass];\n\n for (const value of Object.values(entity)) {\n if (Array.isArray(value)) {\n for (const item of value) {\n if (item && typeof item === 'object' && item.constructor !== Object) {\n classes.push(...collectEntityClasses(item, visited));\n }\n }\n } else if (value && typeof value === 'object' && value.constructor !== Object) {\n classes.push(...collectEntityClasses(value as EntityInstance, visited));\n }\n }\n\n return classes;\n}\n\nfunction enableCascadeInsert(EntityClass: Function, dataSource: DataSource): CascadeState[] {\n const states: CascadeState[] = [];\n\n try {\n const relations = dataSource.getMetadata(EntityClass).relations;\n\n for (const relation of relations) {\n states.push({ relation, original: relation.isCascadeInsert });\n relation.isCascadeInsert = true;\n }\n } catch {\n // Class is not registered as an entity with this DataSource (e.g. embedded class).\n }\n\n return states;\n}\n\nfunction restoreCascade(states: CascadeState[]): void {\n for (const { relation, original } of states) {\n relation.isCascadeInsert = original;\n }\n}\n\n/**\n * Creates and persists a seed entity and all its seeded relations.\n * Delegates to {@link saveManySeed} with `count: 1` and unwraps the result.\n */\nexport async function saveSeed<T extends EntityInstance>(\n EntityClass: EntityConstructor<T>,\n options: SaveSeedOptions,\n): Promise<T>;\n/**\n * Creates and persists one instance of each entity class in the array.\n * Relation seeding is disabled by default; pass `relations: true` to override.\n */\nexport async function saveSeed<T extends readonly EntityConstructor[]>(\n EntityClasses: [...T],\n options: SaveSeedOptions,\n): Promise<MapToInstances<T>>;\nexport async function saveSeed<T extends EntityInstance>(\n classOrClasses: EntityConstructor<T> | readonly EntityConstructor[],\n options: SaveSeedOptions,\n): Promise<T | EntityInstance[]> {\n if (Array.isArray(classOrClasses)) {\n const effectiveOptions = { relations: false, ...options, count: 1 };\n\n return (await Promise.all(\n (classOrClasses as EntityConstructor[]).map((cls) =>\n saveManySeed(cls, effectiveOptions).then(([entity]) => entity!),\n ),\n )) as EntityInstance[];\n }\n\n const [entity] = await saveManySeed(classOrClasses as EntityConstructor<T>, {\n ...options,\n count: 1,\n });\n\n return entity!;\n}\n\n/**\n * Creates and persists multiple seed entities of the same class.\n * Applies the same logic as {@link saveSeed} for each entity.\n */\nexport async function saveManySeed<T extends EntityInstance>(\n EntityClass: EntityConstructor<T>,\n options: SaveManySeedOptions,\n): Promise<T[]>;\n/**\n * Creates and persists multiple instances of each entity class in the array.\n * Relation seeding is disabled by default; pass `relations: true` to override.\n */\nexport async function saveManySeed<T extends readonly EntityConstructor[]>(\n EntityClasses: [...T],\n options: SaveManySeedOptions,\n): Promise<MapToInstanceArrays<T>>;\nexport async function saveManySeed<T extends EntityInstance>(\n classOrClasses: EntityConstructor<T> | readonly EntityConstructor[],\n options: SaveManySeedOptions,\n): Promise<T[] | EntityInstance[][]> {\n if (Array.isArray(classOrClasses)) {\n const effectiveOptions = { relations: false, ...options };\n\n return (await Promise.all(\n (classOrClasses as EntityConstructor[]).map((cls) => saveManySeedOne(cls, effectiveOptions)),\n )) as EntityInstance[][];\n }\n\n return await saveManySeedOne(classOrClasses as EntityConstructor<T>, options);\n}\n\nasync function saveManySeedOne<T extends EntityInstance>(\n EntityClass: EntityConstructor<T>,\n options: SaveManySeedOptions,\n): Promise<T[]> {\n const { count, dataSource } = options;\n\n if (count === 0) {\n return [];\n }\n\n const entities = await createManySeed(EntityClass, options);\n\n const visited = new Set<Function>();\n const states = entities\n .flatMap((entity) => collectEntityClasses(entity, visited))\n .flatMap((cls) => enableCascadeInsert(cls, dataSource));\n\n try {\n return (await dataSource.getRepository(EntityClass).save(entities)) as T[];\n } finally {\n restoreCascade(states);\n }\n}\n","import { createManySeed, createSeed } from './creator.js';\nimport { saveManySeed, saveSeed } from './persist.js';\nimport type {\n EntityConstructor,\n EntityInstance,\n MapToInstanceArrays,\n MapToInstances,\n SeedContext,\n} from './registry.js';\nimport type { SaveSeedOptions } from './persist.js';\n\ninterface SingleSeed<T extends EntityInstance> {\n /** Creates a single instance in memory without persisting. */\n create(context?: SeedContext): Promise<T>;\n /** Creates and persists a single instance. */\n save(options: SaveSeedOptions): Promise<T>;\n /** Creates multiple instances in memory without persisting. */\n createMany(count: number, context?: SeedContext): Promise<T[]>;\n /** Creates and persists multiple instances. */\n saveMany(count: number, options: SaveSeedOptions): Promise<T[]>;\n}\n\ninterface MultiSeed<T extends readonly EntityConstructor[]> {\n /** Creates one instance of each class in memory without persisting. */\n create(context?: SeedContext): Promise<MapToInstances<T>>;\n /** Creates and persists one instance of each class. */\n save(options: SaveSeedOptions): Promise<MapToInstances<T>>;\n /** Creates `count` instances of each class in memory without persisting. */\n createMany(count: number, context?: SeedContext): Promise<MapToInstanceArrays<T>>;\n /** Creates and persists `count` instances of each class. */\n saveMany(count: number, options: SaveSeedOptions): Promise<MapToInstanceArrays<T>>;\n}\n\nexport function seed<T extends EntityInstance>(EntityClass: EntityConstructor<T>): SingleSeed<T>;\nexport function seed<T extends readonly EntityConstructor[]>(EntityClasses: [...T]): MultiSeed<T>;\nexport function seed<T extends EntityInstance>(\n classOrClasses: EntityConstructor<T> | readonly EntityConstructor[],\n): SingleSeed<T> | MultiSeed<readonly EntityConstructor[]> {\n if (Array.isArray(classOrClasses)) {\n const classes = classOrClasses as readonly EntityConstructor[];\n\n return {\n create: (context?: SeedContext) =>\n createSeed(classes as [...typeof classes], context) as Promise<\n MapToInstances<typeof classes>\n >,\n save: (options: SaveSeedOptions) =>\n saveSeed(classes as [...typeof classes], options) as Promise<\n MapToInstances<typeof classes>\n >,\n createMany: (count: number, context?: SeedContext) =>\n createManySeed(classes as [...typeof classes], { count, ...context }) as Promise<\n MapToInstanceArrays<typeof classes>\n >,\n saveMany: (count: number, options: SaveSeedOptions) =>\n saveManySeed(classes as [...typeof classes], { count, ...options }) as Promise<\n MapToInstanceArrays<typeof classes>\n >,\n };\n }\n\n const EntityClass = classOrClasses as EntityConstructor<T>;\n\n return {\n create: (context?: SeedContext) => createSeed(EntityClass, context),\n save: (options: SaveSeedOptions) => saveSeed(EntityClass, options),\n createMany: (count: number, context?: SeedContext) =>\n createManySeed(EntityClass, { count, ...context }),\n saveMany: (count: number, options: SaveSeedOptions) =>\n saveManySeed(EntityClass, { count, ...options }),\n };\n}\n","interface SeederMeta {\n dependencies: Function[];\n}\n\nconst registry = new WeakMap<Function, SeederMeta>();\n\nexport function registerSeeder(target: Function, meta: SeederMeta): void {\n registry.set(target, meta);\n}\n\nexport function getSeederMeta(target: Function): SeederMeta | undefined {\n return registry.get(target);\n}\n","import { registerSeeder } from './registry.js';\nimport type { SeedContext } from '../seed/registry.js';\n\nexport interface SeederInterface {\n run(context: SeedContext): Promise<void>;\n}\n\nexport interface SeederOptions {\n dependencies?: (new () => SeederInterface)[];\n}\n\nexport function Seeder(options: SeederOptions = {}): ClassDecorator {\n return (target) => {\n registerSeeder(target, { dependencies: options.dependencies ?? [] });\n };\n}\n","import { DepGraph } from 'dependency-graph';\nimport { getSeederMeta } from './registry.js';\nimport type { SeederInterface } from './decorator.js';\nimport type { SeedContext } from '../seed/registry.js';\n\ntype SeederCtor = new () => SeederInterface;\n\nfunction topoSort(roots: SeederCtor[]): SeederCtor[] {\n const graph = new DepGraph<SeederCtor>();\n const byName = new Map<string, SeederCtor>();\n\n // Collect all nodes transitively via BFS and register them in the graph.\n const visited = new Set<SeederCtor>();\n const queue: SeederCtor[] = [...roots];\n\n while (queue.length > 0) {\n const node = queue.shift()!;\n\n if (visited.has(node)) {\n continue;\n }\n\n visited.add(node);\n graph.addNode(node.name, node);\n byName.set(node.name, node);\n\n for (const dep of (getSeederMeta(node)?.dependencies ?? []) as SeederCtor[]) {\n queue.push(dep);\n }\n }\n\n // Wire up the dependency edges.\n for (const node of visited) {\n for (const dep of (getSeederMeta(node)?.dependencies ?? []) as SeederCtor[]) {\n graph.addDependency(node.name, dep.name);\n }\n }\n\n try {\n return graph.overallOrder().map((name) => byName.get(name)!);\n } catch (err) {\n if (err && typeof err === 'object' && 'cyclePath' in err) {\n const path = (err as { cyclePath: string[] }).cyclePath.join(' → ');\n throw new Error(`Circular dependency detected among seeders: ${path}`);\n }\n\n throw err;\n }\n}\n\nexport async function runSeeders(seeders: SeederCtor[], context: SeedContext = {}): Promise<void> {\n for (const SeederClass of topoSort(seeders)) {\n await new SeederClass().run(context);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["registry","DepGraph"],"sources":["../src/seed/registry.ts","../src/seed/decorator.ts","../src/seed/creator.ts","../src/seed/persist.ts","../src/seed/builder.ts","../src/seeder/registry.ts","../src/seeder/decorator.ts","../src/seeder/runner.ts"],"sourcesContent":["import type { DataSource } from 'typeorm';\n\n/** An entity instance — any class-based object managed by TypeORM. */\nexport type EntityInstance = object;\n\n/** A constructor that produces an entity instance. */\nexport type EntityConstructor<T extends EntityInstance = EntityInstance> = new () => T;\n\nexport interface SeedContext {\n dataSource?: DataSource;\n /**\n * Set to `false` to skip automatic relation seeding. Scalar and embedded\n * properties are still seeded; only relation properties decorated with a\n * bare `@Seed()` are skipped. Useful when you want to create flat entities\n * and wire relations yourself.\n *\n * @default true\n */\n relations?: boolean;\n}\n\n/** Factory callback passed to @Seed. Receives the seeder context, which may include a DataSource. */\nexport type SeedFactory<T = unknown> = (context: SeedContext) => T | Promise<T>;\n\n/** Options passed to @Seed. */\nexport interface SeedOptions {\n /**\n * Number of related entities to create. Only meaningful on one-to-many and\n * many-to-many relation properties. Ignored on scalar and single-entity relations.\n */\n count?: number;\n}\n\nexport interface SeedEntry {\n propertyKey: string | symbol;\n /** Undefined when @Seed is used without a factory (i.e. bare relation seed). */\n factory: SeedFactory | undefined;\n options: SeedOptions;\n}\n\nexport type MapToInstances<T extends readonly EntityConstructor[]> = {\n [K in keyof T]: T[K] extends EntityConstructor<infer I> ? I : never;\n};\n\nexport type MapToInstanceArrays<T extends readonly EntityConstructor[]> = {\n [K in keyof T]: T[K] extends EntityConstructor<infer I> ? I[] : never;\n};\n\n// Keyed by the entity class constructor.\nconst registry = new Map<Function, SeedEntry[]>();\n\nexport function registerSeed(target: Function, entry: SeedEntry): void {\n const entries = registry.get(target) ?? [];\n\n entries.push(entry);\n registry.set(target, entries);\n}\n\n/**\n * Returns all seed entries for the given class, including those inherited from\n * parent classes. Parent entries come first, preserving declaration order.\n */\nexport function getSeeds(target: Function): SeedEntry[] {\n const entries: SeedEntry[] = [];\n let current: Function = target;\n\n while (current && current !== Function.prototype) {\n const own = registry.get(current);\n\n if (own) {\n entries.unshift(...own);\n }\n\n current = Object.getPrototypeOf(current) as Function;\n }\n\n return entries;\n}\n","import { registerSeed } from './registry.js';\nimport type { SeedFactory, SeedOptions } from './registry.js';\n\n/** Mark a relation property for auto-seeding (creates one related entity). */\nexport function Seed(): PropertyDecorator;\n/** Mark a relation property for auto-seeding with options (e.g. count for one-to-many). */\nexport function Seed(options: SeedOptions): PropertyDecorator;\n/** Mark a scalar property with a factory callback. */\nexport function Seed(factory: SeedFactory): PropertyDecorator;\n/** Mark a scalar property with a factory callback and options. */\nexport function Seed(factory: SeedFactory, options: SeedOptions): PropertyDecorator;\nexport function Seed(\n factoryOrOptions?: SeedFactory | SeedOptions,\n options?: SeedOptions,\n): PropertyDecorator {\n const factory = typeof factoryOrOptions === 'function' ? factoryOrOptions : undefined;\n const opts: SeedOptions =\n (typeof factoryOrOptions === 'object' ? factoryOrOptions : options) ?? {};\n\n return (target, propertyKey) => {\n registerSeed(target.constructor as Function, { propertyKey, factory, options: opts });\n };\n}\n","import { getMetadataArgsStorage } from 'typeorm';\nimport { getSeeds } from './registry.js';\nimport type {\n EntityConstructor,\n EntityInstance,\n MapToInstanceArrays,\n MapToInstances,\n SeedContext,\n} from './registry.js';\n\nexport interface CreateManySeedOptions extends SeedContext {\n count: number;\n}\n\n// Internal extension of SeedContext — never exposed in the public API.\ninterface InternalContext extends SeedContext {\n _ancestors: Set<Function>;\n}\n\nfunction getAncestors(context: SeedContext): Set<Function> {\n return (context as InternalContext)._ancestors ?? new Set();\n}\n\nfunction withAncestor(context: SeedContext, cls: Function): InternalContext {\n const ancestors = getAncestors(context);\n\n return { ...context, _ancestors: new Set([...ancestors, cls]) };\n}\n\nfunction getClassHierarchy(target: Function): Function[] {\n const hierarchy: Function[] = [];\n let current: Function = target;\n\n while (current && current !== Function.prototype) {\n hierarchy.push(current);\n current = Object.getPrototypeOf(current) as Function;\n }\n\n return hierarchy;\n}\n\nasync function createOneSeed<T extends EntityInstance>(\n EntityClass: EntityConstructor<T>,\n context: SeedContext,\n): Promise<T> {\n const instance = new EntityClass();\n const ancestors = getAncestors(context);\n const childContext = withAncestor(context, EntityClass);\n const storage = getMetadataArgsStorage();\n const relations = storage.filterRelations(getClassHierarchy(EntityClass));\n const seededProperties = new Set<string | symbol>();\n const record = instance as Record<string | symbol, unknown>;\n\n // Step 1: Run @Seed entries that have an explicit factory.\n for (const { propertyKey, factory } of getSeeds(EntityClass)) {\n if (!factory) {\n continue;\n }\n\n record[propertyKey] = await factory(context);\n seededProperties.add(propertyKey);\n }\n\n // Step 2: Auto-seed TypeORM embedded properties not already covered by Step 1.\n for (const embedded of storage.filterEmbeddeds(EntityClass)) {\n if (seededProperties.has(embedded.propertyName)) {\n continue;\n }\n\n const EmbeddedClass = embedded.type() as EntityConstructor;\n\n if (getSeeds(EmbeddedClass).length > 0) {\n record[embedded.propertyName] = await createOneSeed(EmbeddedClass, context);\n seededProperties.add(embedded.propertyName);\n }\n }\n\n // Step 3: Auto-seed @Seed entries without a factory (relation seeds).\n // Uses the ancestor guard to cut circular chains: if the related class is\n // already being seeded higher up in this call chain, the property is left\n // undefined rather than triggering infinite recursion.\n // Skipped entirely when context.relations === false.\n if (context.relations === false) {\n return instance;\n }\n\n for (const { propertyKey, factory, options } of getSeeds(EntityClass)) {\n if (factory || seededProperties.has(propertyKey)) {\n continue;\n }\n\n const relation = relations.find((r) => r.propertyName === String(propertyKey));\n\n if (!relation || typeof relation.type !== 'function') {\n continue;\n }\n\n const RelatedClass = (relation.type as () => Function)() as EntityConstructor;\n\n if (ancestors.has(RelatedClass)) {\n continue;\n }\n\n const isArray =\n relation.relationType === 'one-to-many' || relation.relationType === 'many-to-many';\n\n if (isArray) {\n record[propertyKey] = await createManySeed(RelatedClass, {\n count: options.count ?? 1,\n ...childContext,\n });\n } else {\n record[propertyKey] = await createOneSeed(RelatedClass, childContext);\n }\n\n seededProperties.add(propertyKey);\n }\n\n return instance;\n}\n\nexport async function createSeed<T extends EntityInstance>(\n EntityClass: EntityConstructor<T>,\n context?: SeedContext,\n): Promise<T>;\nexport async function createSeed<T extends readonly EntityConstructor[]>(\n EntityClasses: [...T],\n context?: SeedContext,\n): Promise<MapToInstances<T>>;\nexport async function createSeed<T extends EntityInstance>(\n classOrClasses: EntityConstructor<T> | readonly EntityConstructor[],\n context: SeedContext = {},\n): Promise<T | EntityInstance[]> {\n if (Array.isArray(classOrClasses)) {\n const effectiveContext: SeedContext = { relations: false, ...context };\n\n return (await Promise.all(\n (classOrClasses as EntityConstructor[]).map((cls) => createOneSeed(cls, effectiveContext)),\n )) as EntityInstance[];\n }\n\n const [entity] = await createManySeed(classOrClasses as EntityConstructor<T>, {\n count: 1,\n ...context,\n });\n\n return entity!;\n}\n\nexport async function createManySeed<T extends EntityInstance>(\n EntityClass: EntityConstructor<T>,\n options: CreateManySeedOptions,\n): Promise<T[]>;\nexport async function createManySeed<T extends readonly EntityConstructor[]>(\n EntityClasses: [...T],\n options: CreateManySeedOptions,\n): Promise<MapToInstanceArrays<T>>;\nexport async function createManySeed<T extends EntityInstance>(\n classOrClasses: EntityConstructor<T> | readonly EntityConstructor[],\n { count, ...context }: CreateManySeedOptions,\n): Promise<T[] | EntityInstance[][]> {\n if (Array.isArray(classOrClasses)) {\n const effectiveContext: SeedContext = { relations: false, ...context };\n\n return (await Promise.all(\n (classOrClasses as EntityConstructor[]).map((cls) =>\n Promise.all(Array.from({ length: count }, () => createOneSeed(cls, effectiveContext))),\n ),\n )) as EntityInstance[][];\n }\n\n return await Promise.all(\n Array.from({ length: count }, () =>\n createOneSeed(classOrClasses as EntityConstructor<T>, context),\n ),\n );\n}\n","import { type DataSource } from 'typeorm';\n\nimport { createManySeed } from './creator.js';\nimport type {\n EntityConstructor,\n EntityInstance,\n MapToInstanceArrays,\n MapToInstances,\n SeedContext,\n} from './registry.js';\n\nexport interface SaveSeedOptions extends SeedContext {\n dataSource: DataSource;\n}\n\nexport interface SaveManySeedOptions extends SaveSeedOptions {\n count: number;\n}\n\ntype RelationMetadata = DataSource extends { getMetadata(...args: never[]): infer M }\n ? M extends { relations: Array<infer R> }\n ? R\n : never\n : never;\n\ninterface CascadeState {\n relation: RelationMetadata;\n original: boolean;\n}\n\nfunction collectEntityClasses(entity: EntityInstance, visited = new Set<Function>()): Function[] {\n const EntityClass = entity.constructor as Function;\n\n if (visited.has(EntityClass)) {\n return [];\n }\n\n visited.add(EntityClass);\n\n const classes: Function[] = [EntityClass];\n\n for (const value of Object.values(entity)) {\n if (Array.isArray(value)) {\n for (const item of value) {\n if (item && typeof item === 'object' && item.constructor !== Object) {\n classes.push(...collectEntityClasses(item, visited));\n }\n }\n } else if (value && typeof value === 'object' && value.constructor !== Object) {\n classes.push(...collectEntityClasses(value as EntityInstance, visited));\n }\n }\n\n return classes;\n}\n\nfunction enableCascadeInsert(EntityClass: Function, dataSource: DataSource): CascadeState[] {\n const states: CascadeState[] = [];\n\n try {\n const relations = dataSource.getMetadata(EntityClass).relations;\n\n for (const relation of relations) {\n states.push({ relation, original: relation.isCascadeInsert });\n relation.isCascadeInsert = true;\n }\n } catch {\n // Class is not registered as an entity with this DataSource (e.g. embedded class).\n }\n\n return states;\n}\n\nfunction restoreCascade(states: CascadeState[]): void {\n for (const { relation, original } of states) {\n relation.isCascadeInsert = original;\n }\n}\n\n/**\n * Creates and persists a seed entity and all its seeded relations.\n * Delegates to {@link saveManySeed} with `count: 1` and unwraps the result.\n */\nexport async function saveSeed<T extends EntityInstance>(\n EntityClass: EntityConstructor<T>,\n options: SaveSeedOptions,\n): Promise<T>;\n/**\n * Creates and persists one instance of each entity class in the array.\n * Relation seeding is disabled by default; pass `relations: true` to override.\n */\nexport async function saveSeed<T extends readonly EntityConstructor[]>(\n EntityClasses: [...T],\n options: SaveSeedOptions,\n): Promise<MapToInstances<T>>;\nexport async function saveSeed<T extends EntityInstance>(\n classOrClasses: EntityConstructor<T> | readonly EntityConstructor[],\n options: SaveSeedOptions,\n): Promise<T | EntityInstance[]> {\n if (Array.isArray(classOrClasses)) {\n const effectiveOptions = { relations: false, ...options, count: 1 };\n\n return (await Promise.all(\n (classOrClasses as EntityConstructor[]).map((cls) =>\n saveManySeed(cls, effectiveOptions).then(([entity]) => entity!),\n ),\n )) as EntityInstance[];\n }\n\n const [entity] = await saveManySeed(classOrClasses as EntityConstructor<T>, {\n ...options,\n count: 1,\n });\n\n return entity!;\n}\n\n/**\n * Creates and persists multiple seed entities of the same class.\n * Applies the same logic as {@link saveSeed} for each entity.\n */\nexport async function saveManySeed<T extends EntityInstance>(\n EntityClass: EntityConstructor<T>,\n options: SaveManySeedOptions,\n): Promise<T[]>;\n/**\n * Creates and persists multiple instances of each entity class in the array.\n * Relation seeding is disabled by default; pass `relations: true` to override.\n */\nexport async function saveManySeed<T extends readonly EntityConstructor[]>(\n EntityClasses: [...T],\n options: SaveManySeedOptions,\n): Promise<MapToInstanceArrays<T>>;\nexport async function saveManySeed<T extends EntityInstance>(\n classOrClasses: EntityConstructor<T> | readonly EntityConstructor[],\n options: SaveManySeedOptions,\n): Promise<T[] | EntityInstance[][]> {\n if (Array.isArray(classOrClasses)) {\n const effectiveOptions = { relations: false, ...options };\n\n return (await Promise.all(\n (classOrClasses as EntityConstructor[]).map((cls) => saveManySeedOne(cls, effectiveOptions)),\n )) as EntityInstance[][];\n }\n\n return await saveManySeedOne(classOrClasses as EntityConstructor<T>, options);\n}\n\nasync function saveManySeedOne<T extends EntityInstance>(\n EntityClass: EntityConstructor<T>,\n options: SaveManySeedOptions,\n): Promise<T[]> {\n const { count, dataSource } = options;\n\n if (count === 0) {\n return [];\n }\n\n const entities = await createManySeed(EntityClass, options);\n\n const visited = new Set<Function>();\n const states = entities\n .flatMap((entity) => collectEntityClasses(entity, visited))\n .flatMap((cls) => enableCascadeInsert(cls, dataSource));\n\n try {\n return (await dataSource.getRepository(EntityClass).save(entities)) as T[];\n } finally {\n restoreCascade(states);\n }\n}\n","import { createManySeed, createSeed } from './creator.js';\nimport { saveManySeed, saveSeed } from './persist.js';\nimport type {\n EntityConstructor,\n EntityInstance,\n MapToInstanceArrays,\n MapToInstances,\n SeedContext,\n} from './registry.js';\nimport type { SaveSeedOptions } from './persist.js';\n\ninterface SingleSeed<T extends EntityInstance> {\n /** Creates a single instance in memory without persisting. */\n create(context?: SeedContext): Promise<T>;\n /** Creates and persists a single instance. */\n save(options: SaveSeedOptions): Promise<T>;\n /** Creates multiple instances in memory without persisting. */\n createMany(count: number, context?: SeedContext): Promise<T[]>;\n /** Creates and persists multiple instances. */\n saveMany(count: number, options: SaveSeedOptions): Promise<T[]>;\n}\n\ninterface MultiSeed<T extends readonly EntityConstructor[]> {\n /** Creates one instance of each class in memory without persisting. */\n create(context?: SeedContext): Promise<MapToInstances<T>>;\n /** Creates and persists one instance of each class. */\n save(options: SaveSeedOptions): Promise<MapToInstances<T>>;\n /** Creates `count` instances of each class in memory without persisting. */\n createMany(count: number, context?: SeedContext): Promise<MapToInstanceArrays<T>>;\n /** Creates and persists `count` instances of each class. */\n saveMany(count: number, options: SaveSeedOptions): Promise<MapToInstanceArrays<T>>;\n}\n\nexport function seed<T extends EntityInstance>(EntityClass: EntityConstructor<T>): SingleSeed<T>;\nexport function seed<T extends readonly EntityConstructor[]>(EntityClasses: [...T]): MultiSeed<T>;\nexport function seed<T extends EntityInstance>(\n classOrClasses: EntityConstructor<T> | readonly EntityConstructor[],\n): SingleSeed<T> | MultiSeed<readonly EntityConstructor[]> {\n if (Array.isArray(classOrClasses)) {\n const classes = classOrClasses as readonly EntityConstructor[];\n\n return {\n create: (context?: SeedContext) =>\n createSeed(classes as [...typeof classes], context) as Promise<\n MapToInstances<typeof classes>\n >,\n save: (options: SaveSeedOptions) =>\n saveSeed(classes as [...typeof classes], options) as Promise<\n MapToInstances<typeof classes>\n >,\n createMany: (count: number, context?: SeedContext) =>\n createManySeed(classes as [...typeof classes], { count, ...context }) as Promise<\n MapToInstanceArrays<typeof classes>\n >,\n saveMany: (count: number, options: SaveSeedOptions) =>\n saveManySeed(classes as [...typeof classes], { count, ...options }) as Promise<\n MapToInstanceArrays<typeof classes>\n >,\n };\n }\n\n const EntityClass = classOrClasses as EntityConstructor<T>;\n\n return {\n create: (context?: SeedContext) => createSeed(EntityClass, context),\n save: (options: SaveSeedOptions) => saveSeed(EntityClass, options),\n createMany: (count: number, context?: SeedContext) =>\n createManySeed(EntityClass, { count, ...context }),\n saveMany: (count: number, options: SaveSeedOptions) =>\n saveManySeed(EntityClass, { count, ...options }),\n };\n}\n","interface SeederMeta {\n dependencies: Function[];\n}\n\nconst registry = new WeakMap<Function, SeederMeta>();\n\nexport function registerSeeder(target: Function, meta: SeederMeta): void {\n registry.set(target, meta);\n}\n\nexport function getSeederMeta(target: Function): SeederMeta | undefined {\n return registry.get(target);\n}\n","import { registerSeeder } from './registry.js';\nimport type { SeedContext } from '../seed/registry.js';\n\nexport interface SeederInterface {\n run(context: SeedContext): Promise<void>;\n}\n\nexport interface SeederOptions {\n dependencies?: (new () => SeederInterface)[];\n}\n\nexport function Seeder(options: SeederOptions = {}): ClassDecorator {\n return (target) => {\n registerSeeder(target, { dependencies: options.dependencies ?? [] });\n };\n}\n","import { DepGraph } from 'dependency-graph';\nimport { getSeederMeta } from './registry.js';\nimport type { SeederInterface } from './decorator.js';\nimport type { SeedContext } from '../seed/registry.js';\n\nexport type SeederCtor = new () => SeederInterface;\n\nexport interface RunSeedersOptions extends SeedContext {\n /**\n * Enable console logging for each seeder. Set to `false` to silence output,\n * e.g. when using callbacks to handle logging yourself.\n *\n * @default true\n */\n logging?: boolean;\n /** Called before each seeder runs, in execution order. */\n onBefore?: (seeder: SeederCtor) => void | Promise<void>;\n /** Called after each seeder completes successfully, with the time it took in milliseconds. */\n onAfter?: (seeder: SeederCtor, durationMs: number) => void | Promise<void>;\n /** Called when a seeder throws. The error is re-thrown after this callback returns. */\n onError?: (seeder: SeederCtor, error: unknown) => void | Promise<void>;\n /** Called for each seeder before it runs. Return `true` to skip it entirely. */\n skip?: (seeder: SeederCtor) => boolean | Promise<boolean>;\n}\n\nfunction topoSort(roots: SeederCtor[]): SeederCtor[] {\n const graph = new DepGraph<SeederCtor>();\n const byName = new Map<string, SeederCtor>();\n\n // Collect all nodes transitively via BFS and register them in the graph.\n const visited = new Set<SeederCtor>();\n const queue: SeederCtor[] = [...roots];\n\n while (queue.length > 0) {\n const node = queue.shift()!;\n\n if (visited.has(node)) {\n continue;\n }\n\n visited.add(node);\n graph.addNode(node.name, node);\n byName.set(node.name, node);\n\n for (const dep of (getSeederMeta(node)?.dependencies ?? []) as SeederCtor[]) {\n queue.push(dep);\n }\n }\n\n // Wire up the dependency edges.\n for (const node of visited) {\n for (const dep of (getSeederMeta(node)?.dependencies ?? []) as SeederCtor[]) {\n graph.addDependency(node.name, dep.name);\n }\n }\n\n try {\n return graph.overallOrder().map((name) => byName.get(name)!);\n } catch (err) {\n if (err && typeof err === 'object' && 'cyclePath' in err) {\n const path = (err as { cyclePath: string[] }).cyclePath.join(' → ');\n throw new Error(`Circular dependency detected among seeders: ${path}`);\n }\n\n throw err;\n }\n}\n\nexport async function runSeeders(\n seeders: SeederCtor[],\n options: RunSeedersOptions = {},\n): Promise<void> {\n const { logging = true, onBefore, onAfter, onError, skip, ...context } = options;\n\n for (const SeederClass of topoSort(seeders)) {\n if (await skip?.(SeederClass)) {\n continue;\n }\n\n if (logging) {\n console.log(`[${SeederClass.name}] Starting...`);\n }\n\n await onBefore?.(SeederClass);\n\n const start = Date.now();\n\n try {\n await new SeederClass().run(context);\n } catch (err) {\n const durationMs = Date.now() - start;\n\n if (logging) {\n console.error(`[${SeederClass.name}] Failed after ${durationMs}ms`);\n }\n\n await onError?.(SeederClass, err);\n throw err;\n }\n\n const durationMs = Date.now() - start;\n\n if (logging) {\n console.log(`[${SeederClass.name}] Done in ${durationMs}ms`);\n }\n\n await onAfter?.(SeederClass, durationMs);\n }\n}\n"],"mappings":"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"}
package/dist/index.d.cts CHANGED
@@ -118,7 +118,24 @@ declare function Seeder(options?: SeederOptions): ClassDecorator;
118
118
  //#endregion
119
119
  //#region src/seeder/runner.d.ts
120
120
  type SeederCtor = new () => SeederInterface;
121
- declare function runSeeders(seeders: SeederCtor[], context?: SeedContext): Promise<void>;
121
+ interface RunSeedersOptions extends SeedContext {
122
+ /**
123
+ * Enable console logging for each seeder. Set to `false` to silence output,
124
+ * e.g. when using callbacks to handle logging yourself.
125
+ *
126
+ * @default true
127
+ */
128
+ logging?: boolean;
129
+ /** Called before each seeder runs, in execution order. */
130
+ onBefore?: (seeder: SeederCtor) => void | Promise<void>;
131
+ /** Called after each seeder completes successfully, with the time it took in milliseconds. */
132
+ onAfter?: (seeder: SeederCtor, durationMs: number) => void | Promise<void>;
133
+ /** Called when a seeder throws. The error is re-thrown after this callback returns. */
134
+ onError?: (seeder: SeederCtor, error: unknown) => void | Promise<void>;
135
+ /** Called for each seeder before it runs. Return `true` to skip it entirely. */
136
+ skip?: (seeder: SeederCtor) => boolean | Promise<boolean>;
137
+ }
138
+ declare function runSeeders(seeders: SeederCtor[], options?: RunSeedersOptions): Promise<void>;
122
139
  //#endregion
123
- export { type CreateManySeedOptions, type EntityConstructor, type EntityInstance, type SaveManySeedOptions, type SaveSeedOptions, Seed, type SeedContext, type SeedEntry, type SeedFactory, type SeedOptions, Seeder, type SeederInterface, type SeederOptions, createManySeed, createSeed, runSeeders, saveManySeed, saveSeed, seed };
140
+ export { type CreateManySeedOptions, type EntityConstructor, type EntityInstance, type RunSeedersOptions, type SaveManySeedOptions, type SaveSeedOptions, Seed, type SeedContext, type SeedEntry, type SeedFactory, type SeedOptions, Seeder, type SeederCtor, type SeederInterface, type SeederOptions, createManySeed, createSeed, runSeeders, saveManySeed, saveSeed, seed };
124
141
  //# sourceMappingURL=index.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/seed/registry.ts","../src/seed/decorator.ts","../src/seed/persist.ts","../src/seed/builder.ts","../src/seed/creator.ts","../src/seeder/decorator.ts","../src/seeder/runner.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/seed/registry.ts","../src/seed/decorator.ts","../src/seed/persist.ts","../src/seed/builder.ts","../src/seed/creator.ts","../src/seeder/decorator.ts","../src/seeder/runner.ts"],"mappings":"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"}
package/dist/index.d.mts CHANGED
@@ -118,7 +118,24 @@ declare function Seeder(options?: SeederOptions): ClassDecorator;
118
118
  //#endregion
119
119
  //#region src/seeder/runner.d.ts
120
120
  type SeederCtor = new () => SeederInterface;
121
- declare function runSeeders(seeders: SeederCtor[], context?: SeedContext): Promise<void>;
121
+ interface RunSeedersOptions extends SeedContext {
122
+ /**
123
+ * Enable console logging for each seeder. Set to `false` to silence output,
124
+ * e.g. when using callbacks to handle logging yourself.
125
+ *
126
+ * @default true
127
+ */
128
+ logging?: boolean;
129
+ /** Called before each seeder runs, in execution order. */
130
+ onBefore?: (seeder: SeederCtor) => void | Promise<void>;
131
+ /** Called after each seeder completes successfully, with the time it took in milliseconds. */
132
+ onAfter?: (seeder: SeederCtor, durationMs: number) => void | Promise<void>;
133
+ /** Called when a seeder throws. The error is re-thrown after this callback returns. */
134
+ onError?: (seeder: SeederCtor, error: unknown) => void | Promise<void>;
135
+ /** Called for each seeder before it runs. Return `true` to skip it entirely. */
136
+ skip?: (seeder: SeederCtor) => boolean | Promise<boolean>;
137
+ }
138
+ declare function runSeeders(seeders: SeederCtor[], options?: RunSeedersOptions): Promise<void>;
122
139
  //#endregion
123
- export { type CreateManySeedOptions, type EntityConstructor, type EntityInstance, type SaveManySeedOptions, type SaveSeedOptions, Seed, type SeedContext, type SeedEntry, type SeedFactory, type SeedOptions, Seeder, type SeederInterface, type SeederOptions, createManySeed, createSeed, runSeeders, saveManySeed, saveSeed, seed };
140
+ export { type CreateManySeedOptions, type EntityConstructor, type EntityInstance, type RunSeedersOptions, type SaveManySeedOptions, type SaveSeedOptions, Seed, type SeedContext, type SeedEntry, type SeedFactory, type SeedOptions, Seeder, type SeederCtor, type SeederInterface, type SeederOptions, createManySeed, createSeed, runSeeders, saveManySeed, saveSeed, seed };
124
141
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/seed/registry.ts","../src/seed/decorator.ts","../src/seed/persist.ts","../src/seed/builder.ts","../src/seed/creator.ts","../src/seeder/decorator.ts","../src/seeder/runner.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/seed/registry.ts","../src/seed/decorator.ts","../src/seed/persist.ts","../src/seed/builder.ts","../src/seed/creator.ts","../src/seeder/decorator.ts","../src/seeder/runner.ts"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -256,8 +256,25 @@ function topoSort(roots) {
256
256
  throw err;
257
257
  }
258
258
  }
259
- async function runSeeders(seeders, context = {}) {
260
- for (const SeederClass of topoSort(seeders)) await new SeederClass().run(context);
259
+ async function runSeeders(seeders, options = {}) {
260
+ const { logging = true, onBefore, onAfter, onError, skip, ...context } = options;
261
+ for (const SeederClass of topoSort(seeders)) {
262
+ if (await skip?.(SeederClass)) continue;
263
+ if (logging) console.log(`[${SeederClass.name}] Starting...`);
264
+ await onBefore?.(SeederClass);
265
+ const start = Date.now();
266
+ try {
267
+ await new SeederClass().run(context);
268
+ } catch (err) {
269
+ const durationMs = Date.now() - start;
270
+ if (logging) console.error(`[${SeederClass.name}] Failed after ${durationMs}ms`);
271
+ await onError?.(SeederClass, err);
272
+ throw err;
273
+ }
274
+ const durationMs = Date.now() - start;
275
+ if (logging) console.log(`[${SeederClass.name}] Done in ${durationMs}ms`);
276
+ await onAfter?.(SeederClass, durationMs);
277
+ }
261
278
  }
262
279
  //#endregion
263
280
  export { Seed, Seeder, createManySeed, createSeed, runSeeders, saveManySeed, saveSeed, seed };
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["registry"],"sources":["../src/seed/registry.ts","../src/seed/decorator.ts","../src/seed/creator.ts","../src/seed/persist.ts","../src/seed/builder.ts","../src/seeder/registry.ts","../src/seeder/decorator.ts","../src/seeder/runner.ts"],"sourcesContent":["import type { DataSource } from 'typeorm';\n\n/** An entity instance — any class-based object managed by TypeORM. */\nexport type EntityInstance = object;\n\n/** A constructor that produces an entity instance. */\nexport type EntityConstructor<T extends EntityInstance = EntityInstance> = new () => T;\n\nexport interface SeedContext {\n dataSource?: DataSource;\n /**\n * Set to `false` to skip automatic relation seeding. Scalar and embedded\n * properties are still seeded; only relation properties decorated with a\n * bare `@Seed()` are skipped. Useful when you want to create flat entities\n * and wire relations yourself.\n *\n * @default true\n */\n relations?: boolean;\n}\n\n/** Factory callback passed to @Seed. Receives the seeder context, which may include a DataSource. */\nexport type SeedFactory<T = unknown> = (context: SeedContext) => T | Promise<T>;\n\n/** Options passed to @Seed. */\nexport interface SeedOptions {\n /**\n * Number of related entities to create. Only meaningful on one-to-many and\n * many-to-many relation properties. Ignored on scalar and single-entity relations.\n */\n count?: number;\n}\n\nexport interface SeedEntry {\n propertyKey: string | symbol;\n /** Undefined when @Seed is used without a factory (i.e. bare relation seed). */\n factory: SeedFactory | undefined;\n options: SeedOptions;\n}\n\nexport type MapToInstances<T extends readonly EntityConstructor[]> = {\n [K in keyof T]: T[K] extends EntityConstructor<infer I> ? I : never;\n};\n\nexport type MapToInstanceArrays<T extends readonly EntityConstructor[]> = {\n [K in keyof T]: T[K] extends EntityConstructor<infer I> ? I[] : never;\n};\n\n// Keyed by the entity class constructor.\nconst registry = new Map<Function, SeedEntry[]>();\n\nexport function registerSeed(target: Function, entry: SeedEntry): void {\n const entries = registry.get(target) ?? [];\n\n entries.push(entry);\n registry.set(target, entries);\n}\n\n/**\n * Returns all seed entries for the given class, including those inherited from\n * parent classes. Parent entries come first, preserving declaration order.\n */\nexport function getSeeds(target: Function): SeedEntry[] {\n const entries: SeedEntry[] = [];\n let current: Function = target;\n\n while (current && current !== Function.prototype) {\n const own = registry.get(current);\n\n if (own) {\n entries.unshift(...own);\n }\n\n current = Object.getPrototypeOf(current) as Function;\n }\n\n return entries;\n}\n","import { registerSeed } from './registry.js';\nimport type { SeedFactory, SeedOptions } from './registry.js';\n\n/** Mark a relation property for auto-seeding (creates one related entity). */\nexport function Seed(): PropertyDecorator;\n/** Mark a relation property for auto-seeding with options (e.g. count for one-to-many). */\nexport function Seed(options: SeedOptions): PropertyDecorator;\n/** Mark a scalar property with a factory callback. */\nexport function Seed(factory: SeedFactory): PropertyDecorator;\n/** Mark a scalar property with a factory callback and options. */\nexport function Seed(factory: SeedFactory, options: SeedOptions): PropertyDecorator;\nexport function Seed(\n factoryOrOptions?: SeedFactory | SeedOptions,\n options?: SeedOptions,\n): PropertyDecorator {\n const factory = typeof factoryOrOptions === 'function' ? factoryOrOptions : undefined;\n const opts: SeedOptions =\n (typeof factoryOrOptions === 'object' ? factoryOrOptions : options) ?? {};\n\n return (target, propertyKey) => {\n registerSeed(target.constructor as Function, { propertyKey, factory, options: opts });\n };\n}\n","import { getMetadataArgsStorage } from 'typeorm';\nimport { getSeeds } from './registry.js';\nimport type {\n EntityConstructor,\n EntityInstance,\n MapToInstanceArrays,\n MapToInstances,\n SeedContext,\n} from './registry.js';\n\nexport interface CreateManySeedOptions extends SeedContext {\n count: number;\n}\n\n// Internal extension of SeedContext — never exposed in the public API.\ninterface InternalContext extends SeedContext {\n _ancestors: Set<Function>;\n}\n\nfunction getAncestors(context: SeedContext): Set<Function> {\n return (context as InternalContext)._ancestors ?? new Set();\n}\n\nfunction withAncestor(context: SeedContext, cls: Function): InternalContext {\n const ancestors = getAncestors(context);\n\n return { ...context, _ancestors: new Set([...ancestors, cls]) };\n}\n\nfunction getClassHierarchy(target: Function): Function[] {\n const hierarchy: Function[] = [];\n let current: Function = target;\n\n while (current && current !== Function.prototype) {\n hierarchy.push(current);\n current = Object.getPrototypeOf(current) as Function;\n }\n\n return hierarchy;\n}\n\nasync function createOneSeed<T extends EntityInstance>(\n EntityClass: EntityConstructor<T>,\n context: SeedContext,\n): Promise<T> {\n const instance = new EntityClass();\n const ancestors = getAncestors(context);\n const childContext = withAncestor(context, EntityClass);\n const storage = getMetadataArgsStorage();\n const relations = storage.filterRelations(getClassHierarchy(EntityClass));\n const seededProperties = new Set<string | symbol>();\n const record = instance as Record<string | symbol, unknown>;\n\n // Step 1: Run @Seed entries that have an explicit factory.\n for (const { propertyKey, factory } of getSeeds(EntityClass)) {\n if (!factory) {\n continue;\n }\n\n record[propertyKey] = await factory(context);\n seededProperties.add(propertyKey);\n }\n\n // Step 2: Auto-seed TypeORM embedded properties not already covered by Step 1.\n for (const embedded of storage.filterEmbeddeds(EntityClass)) {\n if (seededProperties.has(embedded.propertyName)) {\n continue;\n }\n\n const EmbeddedClass = embedded.type() as EntityConstructor;\n\n if (getSeeds(EmbeddedClass).length > 0) {\n record[embedded.propertyName] = await createOneSeed(EmbeddedClass, context);\n seededProperties.add(embedded.propertyName);\n }\n }\n\n // Step 3: Auto-seed @Seed entries without a factory (relation seeds).\n // Uses the ancestor guard to cut circular chains: if the related class is\n // already being seeded higher up in this call chain, the property is left\n // undefined rather than triggering infinite recursion.\n // Skipped entirely when context.relations === false.\n if (context.relations === false) {\n return instance;\n }\n\n for (const { propertyKey, factory, options } of getSeeds(EntityClass)) {\n if (factory || seededProperties.has(propertyKey)) {\n continue;\n }\n\n const relation = relations.find((r) => r.propertyName === String(propertyKey));\n\n if (!relation || typeof relation.type !== 'function') {\n continue;\n }\n\n const RelatedClass = (relation.type as () => Function)() as EntityConstructor;\n\n if (ancestors.has(RelatedClass)) {\n continue;\n }\n\n const isArray =\n relation.relationType === 'one-to-many' || relation.relationType === 'many-to-many';\n\n if (isArray) {\n record[propertyKey] = await createManySeed(RelatedClass, {\n count: options.count ?? 1,\n ...childContext,\n });\n } else {\n record[propertyKey] = await createOneSeed(RelatedClass, childContext);\n }\n\n seededProperties.add(propertyKey);\n }\n\n return instance;\n}\n\nexport async function createSeed<T extends EntityInstance>(\n EntityClass: EntityConstructor<T>,\n context?: SeedContext,\n): Promise<T>;\nexport async function createSeed<T extends readonly EntityConstructor[]>(\n EntityClasses: [...T],\n context?: SeedContext,\n): Promise<MapToInstances<T>>;\nexport async function createSeed<T extends EntityInstance>(\n classOrClasses: EntityConstructor<T> | readonly EntityConstructor[],\n context: SeedContext = {},\n): Promise<T | EntityInstance[]> {\n if (Array.isArray(classOrClasses)) {\n const effectiveContext: SeedContext = { relations: false, ...context };\n\n return (await Promise.all(\n (classOrClasses as EntityConstructor[]).map((cls) => createOneSeed(cls, effectiveContext)),\n )) as EntityInstance[];\n }\n\n const [entity] = await createManySeed(classOrClasses as EntityConstructor<T>, {\n count: 1,\n ...context,\n });\n\n return entity!;\n}\n\nexport async function createManySeed<T extends EntityInstance>(\n EntityClass: EntityConstructor<T>,\n options: CreateManySeedOptions,\n): Promise<T[]>;\nexport async function createManySeed<T extends readonly EntityConstructor[]>(\n EntityClasses: [...T],\n options: CreateManySeedOptions,\n): Promise<MapToInstanceArrays<T>>;\nexport async function createManySeed<T extends EntityInstance>(\n classOrClasses: EntityConstructor<T> | readonly EntityConstructor[],\n { count, ...context }: CreateManySeedOptions,\n): Promise<T[] | EntityInstance[][]> {\n if (Array.isArray(classOrClasses)) {\n const effectiveContext: SeedContext = { relations: false, ...context };\n\n return (await Promise.all(\n (classOrClasses as EntityConstructor[]).map((cls) =>\n Promise.all(Array.from({ length: count }, () => createOneSeed(cls, effectiveContext))),\n ),\n )) as EntityInstance[][];\n }\n\n return await Promise.all(\n Array.from({ length: count }, () =>\n createOneSeed(classOrClasses as EntityConstructor<T>, context),\n ),\n );\n}\n","import { type DataSource } from 'typeorm';\n\nimport { createManySeed } from './creator.js';\nimport type {\n EntityConstructor,\n EntityInstance,\n MapToInstanceArrays,\n MapToInstances,\n SeedContext,\n} from './registry.js';\n\nexport interface SaveSeedOptions extends SeedContext {\n dataSource: DataSource;\n}\n\nexport interface SaveManySeedOptions extends SaveSeedOptions {\n count: number;\n}\n\ntype RelationMetadata = DataSource extends { getMetadata(...args: never[]): infer M }\n ? M extends { relations: Array<infer R> }\n ? R\n : never\n : never;\n\ninterface CascadeState {\n relation: RelationMetadata;\n original: boolean;\n}\n\nfunction collectEntityClasses(entity: EntityInstance, visited = new Set<Function>()): Function[] {\n const EntityClass = entity.constructor as Function;\n\n if (visited.has(EntityClass)) {\n return [];\n }\n\n visited.add(EntityClass);\n\n const classes: Function[] = [EntityClass];\n\n for (const value of Object.values(entity)) {\n if (Array.isArray(value)) {\n for (const item of value) {\n if (item && typeof item === 'object' && item.constructor !== Object) {\n classes.push(...collectEntityClasses(item, visited));\n }\n }\n } else if (value && typeof value === 'object' && value.constructor !== Object) {\n classes.push(...collectEntityClasses(value as EntityInstance, visited));\n }\n }\n\n return classes;\n}\n\nfunction enableCascadeInsert(EntityClass: Function, dataSource: DataSource): CascadeState[] {\n const states: CascadeState[] = [];\n\n try {\n const relations = dataSource.getMetadata(EntityClass).relations;\n\n for (const relation of relations) {\n states.push({ relation, original: relation.isCascadeInsert });\n relation.isCascadeInsert = true;\n }\n } catch {\n // Class is not registered as an entity with this DataSource (e.g. embedded class).\n }\n\n return states;\n}\n\nfunction restoreCascade(states: CascadeState[]): void {\n for (const { relation, original } of states) {\n relation.isCascadeInsert = original;\n }\n}\n\n/**\n * Creates and persists a seed entity and all its seeded relations.\n * Delegates to {@link saveManySeed} with `count: 1` and unwraps the result.\n */\nexport async function saveSeed<T extends EntityInstance>(\n EntityClass: EntityConstructor<T>,\n options: SaveSeedOptions,\n): Promise<T>;\n/**\n * Creates and persists one instance of each entity class in the array.\n * Relation seeding is disabled by default; pass `relations: true` to override.\n */\nexport async function saveSeed<T extends readonly EntityConstructor[]>(\n EntityClasses: [...T],\n options: SaveSeedOptions,\n): Promise<MapToInstances<T>>;\nexport async function saveSeed<T extends EntityInstance>(\n classOrClasses: EntityConstructor<T> | readonly EntityConstructor[],\n options: SaveSeedOptions,\n): Promise<T | EntityInstance[]> {\n if (Array.isArray(classOrClasses)) {\n const effectiveOptions = { relations: false, ...options, count: 1 };\n\n return (await Promise.all(\n (classOrClasses as EntityConstructor[]).map((cls) =>\n saveManySeed(cls, effectiveOptions).then(([entity]) => entity!),\n ),\n )) as EntityInstance[];\n }\n\n const [entity] = await saveManySeed(classOrClasses as EntityConstructor<T>, {\n ...options,\n count: 1,\n });\n\n return entity!;\n}\n\n/**\n * Creates and persists multiple seed entities of the same class.\n * Applies the same logic as {@link saveSeed} for each entity.\n */\nexport async function saveManySeed<T extends EntityInstance>(\n EntityClass: EntityConstructor<T>,\n options: SaveManySeedOptions,\n): Promise<T[]>;\n/**\n * Creates and persists multiple instances of each entity class in the array.\n * Relation seeding is disabled by default; pass `relations: true` to override.\n */\nexport async function saveManySeed<T extends readonly EntityConstructor[]>(\n EntityClasses: [...T],\n options: SaveManySeedOptions,\n): Promise<MapToInstanceArrays<T>>;\nexport async function saveManySeed<T extends EntityInstance>(\n classOrClasses: EntityConstructor<T> | readonly EntityConstructor[],\n options: SaveManySeedOptions,\n): Promise<T[] | EntityInstance[][]> {\n if (Array.isArray(classOrClasses)) {\n const effectiveOptions = { relations: false, ...options };\n\n return (await Promise.all(\n (classOrClasses as EntityConstructor[]).map((cls) => saveManySeedOne(cls, effectiveOptions)),\n )) as EntityInstance[][];\n }\n\n return await saveManySeedOne(classOrClasses as EntityConstructor<T>, options);\n}\n\nasync function saveManySeedOne<T extends EntityInstance>(\n EntityClass: EntityConstructor<T>,\n options: SaveManySeedOptions,\n): Promise<T[]> {\n const { count, dataSource } = options;\n\n if (count === 0) {\n return [];\n }\n\n const entities = await createManySeed(EntityClass, options);\n\n const visited = new Set<Function>();\n const states = entities\n .flatMap((entity) => collectEntityClasses(entity, visited))\n .flatMap((cls) => enableCascadeInsert(cls, dataSource));\n\n try {\n return (await dataSource.getRepository(EntityClass).save(entities)) as T[];\n } finally {\n restoreCascade(states);\n }\n}\n","import { createManySeed, createSeed } from './creator.js';\nimport { saveManySeed, saveSeed } from './persist.js';\nimport type {\n EntityConstructor,\n EntityInstance,\n MapToInstanceArrays,\n MapToInstances,\n SeedContext,\n} from './registry.js';\nimport type { SaveSeedOptions } from './persist.js';\n\ninterface SingleSeed<T extends EntityInstance> {\n /** Creates a single instance in memory without persisting. */\n create(context?: SeedContext): Promise<T>;\n /** Creates and persists a single instance. */\n save(options: SaveSeedOptions): Promise<T>;\n /** Creates multiple instances in memory without persisting. */\n createMany(count: number, context?: SeedContext): Promise<T[]>;\n /** Creates and persists multiple instances. */\n saveMany(count: number, options: SaveSeedOptions): Promise<T[]>;\n}\n\ninterface MultiSeed<T extends readonly EntityConstructor[]> {\n /** Creates one instance of each class in memory without persisting. */\n create(context?: SeedContext): Promise<MapToInstances<T>>;\n /** Creates and persists one instance of each class. */\n save(options: SaveSeedOptions): Promise<MapToInstances<T>>;\n /** Creates `count` instances of each class in memory without persisting. */\n createMany(count: number, context?: SeedContext): Promise<MapToInstanceArrays<T>>;\n /** Creates and persists `count` instances of each class. */\n saveMany(count: number, options: SaveSeedOptions): Promise<MapToInstanceArrays<T>>;\n}\n\nexport function seed<T extends EntityInstance>(EntityClass: EntityConstructor<T>): SingleSeed<T>;\nexport function seed<T extends readonly EntityConstructor[]>(EntityClasses: [...T]): MultiSeed<T>;\nexport function seed<T extends EntityInstance>(\n classOrClasses: EntityConstructor<T> | readonly EntityConstructor[],\n): SingleSeed<T> | MultiSeed<readonly EntityConstructor[]> {\n if (Array.isArray(classOrClasses)) {\n const classes = classOrClasses as readonly EntityConstructor[];\n\n return {\n create: (context?: SeedContext) =>\n createSeed(classes as [...typeof classes], context) as Promise<\n MapToInstances<typeof classes>\n >,\n save: (options: SaveSeedOptions) =>\n saveSeed(classes as [...typeof classes], options) as Promise<\n MapToInstances<typeof classes>\n >,\n createMany: (count: number, context?: SeedContext) =>\n createManySeed(classes as [...typeof classes], { count, ...context }) as Promise<\n MapToInstanceArrays<typeof classes>\n >,\n saveMany: (count: number, options: SaveSeedOptions) =>\n saveManySeed(classes as [...typeof classes], { count, ...options }) as Promise<\n MapToInstanceArrays<typeof classes>\n >,\n };\n }\n\n const EntityClass = classOrClasses as EntityConstructor<T>;\n\n return {\n create: (context?: SeedContext) => createSeed(EntityClass, context),\n save: (options: SaveSeedOptions) => saveSeed(EntityClass, options),\n createMany: (count: number, context?: SeedContext) =>\n createManySeed(EntityClass, { count, ...context }),\n saveMany: (count: number, options: SaveSeedOptions) =>\n saveManySeed(EntityClass, { count, ...options }),\n };\n}\n","interface SeederMeta {\n dependencies: Function[];\n}\n\nconst registry = new WeakMap<Function, SeederMeta>();\n\nexport function registerSeeder(target: Function, meta: SeederMeta): void {\n registry.set(target, meta);\n}\n\nexport function getSeederMeta(target: Function): SeederMeta | undefined {\n return registry.get(target);\n}\n","import { registerSeeder } from './registry.js';\nimport type { SeedContext } from '../seed/registry.js';\n\nexport interface SeederInterface {\n run(context: SeedContext): Promise<void>;\n}\n\nexport interface SeederOptions {\n dependencies?: (new () => SeederInterface)[];\n}\n\nexport function Seeder(options: SeederOptions = {}): ClassDecorator {\n return (target) => {\n registerSeeder(target, { dependencies: options.dependencies ?? [] });\n };\n}\n","import { DepGraph } from 'dependency-graph';\nimport { getSeederMeta } from './registry.js';\nimport type { SeederInterface } from './decorator.js';\nimport type { SeedContext } from '../seed/registry.js';\n\ntype SeederCtor = new () => SeederInterface;\n\nfunction topoSort(roots: SeederCtor[]): SeederCtor[] {\n const graph = new DepGraph<SeederCtor>();\n const byName = new Map<string, SeederCtor>();\n\n // Collect all nodes transitively via BFS and register them in the graph.\n const visited = new Set<SeederCtor>();\n const queue: SeederCtor[] = [...roots];\n\n while (queue.length > 0) {\n const node = queue.shift()!;\n\n if (visited.has(node)) {\n continue;\n }\n\n visited.add(node);\n graph.addNode(node.name, node);\n byName.set(node.name, node);\n\n for (const dep of (getSeederMeta(node)?.dependencies ?? []) as SeederCtor[]) {\n queue.push(dep);\n }\n }\n\n // Wire up the dependency edges.\n for (const node of visited) {\n for (const dep of (getSeederMeta(node)?.dependencies ?? []) as SeederCtor[]) {\n graph.addDependency(node.name, dep.name);\n }\n }\n\n try {\n return graph.overallOrder().map((name) => byName.get(name)!);\n } catch (err) {\n if (err && typeof err === 'object' && 'cyclePath' in err) {\n const path = (err as { cyclePath: string[] }).cyclePath.join(' → ');\n throw new Error(`Circular dependency detected among seeders: ${path}`);\n }\n\n throw err;\n }\n}\n\nexport async function runSeeders(seeders: SeederCtor[], context: SeedContext = {}): Promise<void> {\n for (const SeederClass of topoSort(seeders)) {\n await new SeederClass().run(context);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["registry"],"sources":["../src/seed/registry.ts","../src/seed/decorator.ts","../src/seed/creator.ts","../src/seed/persist.ts","../src/seed/builder.ts","../src/seeder/registry.ts","../src/seeder/decorator.ts","../src/seeder/runner.ts"],"sourcesContent":["import type { DataSource } from 'typeorm';\n\n/** An entity instance — any class-based object managed by TypeORM. */\nexport type EntityInstance = object;\n\n/** A constructor that produces an entity instance. */\nexport type EntityConstructor<T extends EntityInstance = EntityInstance> = new () => T;\n\nexport interface SeedContext {\n dataSource?: DataSource;\n /**\n * Set to `false` to skip automatic relation seeding. Scalar and embedded\n * properties are still seeded; only relation properties decorated with a\n * bare `@Seed()` are skipped. Useful when you want to create flat entities\n * and wire relations yourself.\n *\n * @default true\n */\n relations?: boolean;\n}\n\n/** Factory callback passed to @Seed. Receives the seeder context, which may include a DataSource. */\nexport type SeedFactory<T = unknown> = (context: SeedContext) => T | Promise<T>;\n\n/** Options passed to @Seed. */\nexport interface SeedOptions {\n /**\n * Number of related entities to create. Only meaningful on one-to-many and\n * many-to-many relation properties. Ignored on scalar and single-entity relations.\n */\n count?: number;\n}\n\nexport interface SeedEntry {\n propertyKey: string | symbol;\n /** Undefined when @Seed is used without a factory (i.e. bare relation seed). */\n factory: SeedFactory | undefined;\n options: SeedOptions;\n}\n\nexport type MapToInstances<T extends readonly EntityConstructor[]> = {\n [K in keyof T]: T[K] extends EntityConstructor<infer I> ? I : never;\n};\n\nexport type MapToInstanceArrays<T extends readonly EntityConstructor[]> = {\n [K in keyof T]: T[K] extends EntityConstructor<infer I> ? I[] : never;\n};\n\n// Keyed by the entity class constructor.\nconst registry = new Map<Function, SeedEntry[]>();\n\nexport function registerSeed(target: Function, entry: SeedEntry): void {\n const entries = registry.get(target) ?? [];\n\n entries.push(entry);\n registry.set(target, entries);\n}\n\n/**\n * Returns all seed entries for the given class, including those inherited from\n * parent classes. Parent entries come first, preserving declaration order.\n */\nexport function getSeeds(target: Function): SeedEntry[] {\n const entries: SeedEntry[] = [];\n let current: Function = target;\n\n while (current && current !== Function.prototype) {\n const own = registry.get(current);\n\n if (own) {\n entries.unshift(...own);\n }\n\n current = Object.getPrototypeOf(current) as Function;\n }\n\n return entries;\n}\n","import { registerSeed } from './registry.js';\nimport type { SeedFactory, SeedOptions } from './registry.js';\n\n/** Mark a relation property for auto-seeding (creates one related entity). */\nexport function Seed(): PropertyDecorator;\n/** Mark a relation property for auto-seeding with options (e.g. count for one-to-many). */\nexport function Seed(options: SeedOptions): PropertyDecorator;\n/** Mark a scalar property with a factory callback. */\nexport function Seed(factory: SeedFactory): PropertyDecorator;\n/** Mark a scalar property with a factory callback and options. */\nexport function Seed(factory: SeedFactory, options: SeedOptions): PropertyDecorator;\nexport function Seed(\n factoryOrOptions?: SeedFactory | SeedOptions,\n options?: SeedOptions,\n): PropertyDecorator {\n const factory = typeof factoryOrOptions === 'function' ? factoryOrOptions : undefined;\n const opts: SeedOptions =\n (typeof factoryOrOptions === 'object' ? factoryOrOptions : options) ?? {};\n\n return (target, propertyKey) => {\n registerSeed(target.constructor as Function, { propertyKey, factory, options: opts });\n };\n}\n","import { getMetadataArgsStorage } from 'typeorm';\nimport { getSeeds } from './registry.js';\nimport type {\n EntityConstructor,\n EntityInstance,\n MapToInstanceArrays,\n MapToInstances,\n SeedContext,\n} from './registry.js';\n\nexport interface CreateManySeedOptions extends SeedContext {\n count: number;\n}\n\n// Internal extension of SeedContext — never exposed in the public API.\ninterface InternalContext extends SeedContext {\n _ancestors: Set<Function>;\n}\n\nfunction getAncestors(context: SeedContext): Set<Function> {\n return (context as InternalContext)._ancestors ?? new Set();\n}\n\nfunction withAncestor(context: SeedContext, cls: Function): InternalContext {\n const ancestors = getAncestors(context);\n\n return { ...context, _ancestors: new Set([...ancestors, cls]) };\n}\n\nfunction getClassHierarchy(target: Function): Function[] {\n const hierarchy: Function[] = [];\n let current: Function = target;\n\n while (current && current !== Function.prototype) {\n hierarchy.push(current);\n current = Object.getPrototypeOf(current) as Function;\n }\n\n return hierarchy;\n}\n\nasync function createOneSeed<T extends EntityInstance>(\n EntityClass: EntityConstructor<T>,\n context: SeedContext,\n): Promise<T> {\n const instance = new EntityClass();\n const ancestors = getAncestors(context);\n const childContext = withAncestor(context, EntityClass);\n const storage = getMetadataArgsStorage();\n const relations = storage.filterRelations(getClassHierarchy(EntityClass));\n const seededProperties = new Set<string | symbol>();\n const record = instance as Record<string | symbol, unknown>;\n\n // Step 1: Run @Seed entries that have an explicit factory.\n for (const { propertyKey, factory } of getSeeds(EntityClass)) {\n if (!factory) {\n continue;\n }\n\n record[propertyKey] = await factory(context);\n seededProperties.add(propertyKey);\n }\n\n // Step 2: Auto-seed TypeORM embedded properties not already covered by Step 1.\n for (const embedded of storage.filterEmbeddeds(EntityClass)) {\n if (seededProperties.has(embedded.propertyName)) {\n continue;\n }\n\n const EmbeddedClass = embedded.type() as EntityConstructor;\n\n if (getSeeds(EmbeddedClass).length > 0) {\n record[embedded.propertyName] = await createOneSeed(EmbeddedClass, context);\n seededProperties.add(embedded.propertyName);\n }\n }\n\n // Step 3: Auto-seed @Seed entries without a factory (relation seeds).\n // Uses the ancestor guard to cut circular chains: if the related class is\n // already being seeded higher up in this call chain, the property is left\n // undefined rather than triggering infinite recursion.\n // Skipped entirely when context.relations === false.\n if (context.relations === false) {\n return instance;\n }\n\n for (const { propertyKey, factory, options } of getSeeds(EntityClass)) {\n if (factory || seededProperties.has(propertyKey)) {\n continue;\n }\n\n const relation = relations.find((r) => r.propertyName === String(propertyKey));\n\n if (!relation || typeof relation.type !== 'function') {\n continue;\n }\n\n const RelatedClass = (relation.type as () => Function)() as EntityConstructor;\n\n if (ancestors.has(RelatedClass)) {\n continue;\n }\n\n const isArray =\n relation.relationType === 'one-to-many' || relation.relationType === 'many-to-many';\n\n if (isArray) {\n record[propertyKey] = await createManySeed(RelatedClass, {\n count: options.count ?? 1,\n ...childContext,\n });\n } else {\n record[propertyKey] = await createOneSeed(RelatedClass, childContext);\n }\n\n seededProperties.add(propertyKey);\n }\n\n return instance;\n}\n\nexport async function createSeed<T extends EntityInstance>(\n EntityClass: EntityConstructor<T>,\n context?: SeedContext,\n): Promise<T>;\nexport async function createSeed<T extends readonly EntityConstructor[]>(\n EntityClasses: [...T],\n context?: SeedContext,\n): Promise<MapToInstances<T>>;\nexport async function createSeed<T extends EntityInstance>(\n classOrClasses: EntityConstructor<T> | readonly EntityConstructor[],\n context: SeedContext = {},\n): Promise<T | EntityInstance[]> {\n if (Array.isArray(classOrClasses)) {\n const effectiveContext: SeedContext = { relations: false, ...context };\n\n return (await Promise.all(\n (classOrClasses as EntityConstructor[]).map((cls) => createOneSeed(cls, effectiveContext)),\n )) as EntityInstance[];\n }\n\n const [entity] = await createManySeed(classOrClasses as EntityConstructor<T>, {\n count: 1,\n ...context,\n });\n\n return entity!;\n}\n\nexport async function createManySeed<T extends EntityInstance>(\n EntityClass: EntityConstructor<T>,\n options: CreateManySeedOptions,\n): Promise<T[]>;\nexport async function createManySeed<T extends readonly EntityConstructor[]>(\n EntityClasses: [...T],\n options: CreateManySeedOptions,\n): Promise<MapToInstanceArrays<T>>;\nexport async function createManySeed<T extends EntityInstance>(\n classOrClasses: EntityConstructor<T> | readonly EntityConstructor[],\n { count, ...context }: CreateManySeedOptions,\n): Promise<T[] | EntityInstance[][]> {\n if (Array.isArray(classOrClasses)) {\n const effectiveContext: SeedContext = { relations: false, ...context };\n\n return (await Promise.all(\n (classOrClasses as EntityConstructor[]).map((cls) =>\n Promise.all(Array.from({ length: count }, () => createOneSeed(cls, effectiveContext))),\n ),\n )) as EntityInstance[][];\n }\n\n return await Promise.all(\n Array.from({ length: count }, () =>\n createOneSeed(classOrClasses as EntityConstructor<T>, context),\n ),\n );\n}\n","import { type DataSource } from 'typeorm';\n\nimport { createManySeed } from './creator.js';\nimport type {\n EntityConstructor,\n EntityInstance,\n MapToInstanceArrays,\n MapToInstances,\n SeedContext,\n} from './registry.js';\n\nexport interface SaveSeedOptions extends SeedContext {\n dataSource: DataSource;\n}\n\nexport interface SaveManySeedOptions extends SaveSeedOptions {\n count: number;\n}\n\ntype RelationMetadata = DataSource extends { getMetadata(...args: never[]): infer M }\n ? M extends { relations: Array<infer R> }\n ? R\n : never\n : never;\n\ninterface CascadeState {\n relation: RelationMetadata;\n original: boolean;\n}\n\nfunction collectEntityClasses(entity: EntityInstance, visited = new Set<Function>()): Function[] {\n const EntityClass = entity.constructor as Function;\n\n if (visited.has(EntityClass)) {\n return [];\n }\n\n visited.add(EntityClass);\n\n const classes: Function[] = [EntityClass];\n\n for (const value of Object.values(entity)) {\n if (Array.isArray(value)) {\n for (const item of value) {\n if (item && typeof item === 'object' && item.constructor !== Object) {\n classes.push(...collectEntityClasses(item, visited));\n }\n }\n } else if (value && typeof value === 'object' && value.constructor !== Object) {\n classes.push(...collectEntityClasses(value as EntityInstance, visited));\n }\n }\n\n return classes;\n}\n\nfunction enableCascadeInsert(EntityClass: Function, dataSource: DataSource): CascadeState[] {\n const states: CascadeState[] = [];\n\n try {\n const relations = dataSource.getMetadata(EntityClass).relations;\n\n for (const relation of relations) {\n states.push({ relation, original: relation.isCascadeInsert });\n relation.isCascadeInsert = true;\n }\n } catch {\n // Class is not registered as an entity with this DataSource (e.g. embedded class).\n }\n\n return states;\n}\n\nfunction restoreCascade(states: CascadeState[]): void {\n for (const { relation, original } of states) {\n relation.isCascadeInsert = original;\n }\n}\n\n/**\n * Creates and persists a seed entity and all its seeded relations.\n * Delegates to {@link saveManySeed} with `count: 1` and unwraps the result.\n */\nexport async function saveSeed<T extends EntityInstance>(\n EntityClass: EntityConstructor<T>,\n options: SaveSeedOptions,\n): Promise<T>;\n/**\n * Creates and persists one instance of each entity class in the array.\n * Relation seeding is disabled by default; pass `relations: true` to override.\n */\nexport async function saveSeed<T extends readonly EntityConstructor[]>(\n EntityClasses: [...T],\n options: SaveSeedOptions,\n): Promise<MapToInstances<T>>;\nexport async function saveSeed<T extends EntityInstance>(\n classOrClasses: EntityConstructor<T> | readonly EntityConstructor[],\n options: SaveSeedOptions,\n): Promise<T | EntityInstance[]> {\n if (Array.isArray(classOrClasses)) {\n const effectiveOptions = { relations: false, ...options, count: 1 };\n\n return (await Promise.all(\n (classOrClasses as EntityConstructor[]).map((cls) =>\n saveManySeed(cls, effectiveOptions).then(([entity]) => entity!),\n ),\n )) as EntityInstance[];\n }\n\n const [entity] = await saveManySeed(classOrClasses as EntityConstructor<T>, {\n ...options,\n count: 1,\n });\n\n return entity!;\n}\n\n/**\n * Creates and persists multiple seed entities of the same class.\n * Applies the same logic as {@link saveSeed} for each entity.\n */\nexport async function saveManySeed<T extends EntityInstance>(\n EntityClass: EntityConstructor<T>,\n options: SaveManySeedOptions,\n): Promise<T[]>;\n/**\n * Creates and persists multiple instances of each entity class in the array.\n * Relation seeding is disabled by default; pass `relations: true` to override.\n */\nexport async function saveManySeed<T extends readonly EntityConstructor[]>(\n EntityClasses: [...T],\n options: SaveManySeedOptions,\n): Promise<MapToInstanceArrays<T>>;\nexport async function saveManySeed<T extends EntityInstance>(\n classOrClasses: EntityConstructor<T> | readonly EntityConstructor[],\n options: SaveManySeedOptions,\n): Promise<T[] | EntityInstance[][]> {\n if (Array.isArray(classOrClasses)) {\n const effectiveOptions = { relations: false, ...options };\n\n return (await Promise.all(\n (classOrClasses as EntityConstructor[]).map((cls) => saveManySeedOne(cls, effectiveOptions)),\n )) as EntityInstance[][];\n }\n\n return await saveManySeedOne(classOrClasses as EntityConstructor<T>, options);\n}\n\nasync function saveManySeedOne<T extends EntityInstance>(\n EntityClass: EntityConstructor<T>,\n options: SaveManySeedOptions,\n): Promise<T[]> {\n const { count, dataSource } = options;\n\n if (count === 0) {\n return [];\n }\n\n const entities = await createManySeed(EntityClass, options);\n\n const visited = new Set<Function>();\n const states = entities\n .flatMap((entity) => collectEntityClasses(entity, visited))\n .flatMap((cls) => enableCascadeInsert(cls, dataSource));\n\n try {\n return (await dataSource.getRepository(EntityClass).save(entities)) as T[];\n } finally {\n restoreCascade(states);\n }\n}\n","import { createManySeed, createSeed } from './creator.js';\nimport { saveManySeed, saveSeed } from './persist.js';\nimport type {\n EntityConstructor,\n EntityInstance,\n MapToInstanceArrays,\n MapToInstances,\n SeedContext,\n} from './registry.js';\nimport type { SaveSeedOptions } from './persist.js';\n\ninterface SingleSeed<T extends EntityInstance> {\n /** Creates a single instance in memory without persisting. */\n create(context?: SeedContext): Promise<T>;\n /** Creates and persists a single instance. */\n save(options: SaveSeedOptions): Promise<T>;\n /** Creates multiple instances in memory without persisting. */\n createMany(count: number, context?: SeedContext): Promise<T[]>;\n /** Creates and persists multiple instances. */\n saveMany(count: number, options: SaveSeedOptions): Promise<T[]>;\n}\n\ninterface MultiSeed<T extends readonly EntityConstructor[]> {\n /** Creates one instance of each class in memory without persisting. */\n create(context?: SeedContext): Promise<MapToInstances<T>>;\n /** Creates and persists one instance of each class. */\n save(options: SaveSeedOptions): Promise<MapToInstances<T>>;\n /** Creates `count` instances of each class in memory without persisting. */\n createMany(count: number, context?: SeedContext): Promise<MapToInstanceArrays<T>>;\n /** Creates and persists `count` instances of each class. */\n saveMany(count: number, options: SaveSeedOptions): Promise<MapToInstanceArrays<T>>;\n}\n\nexport function seed<T extends EntityInstance>(EntityClass: EntityConstructor<T>): SingleSeed<T>;\nexport function seed<T extends readonly EntityConstructor[]>(EntityClasses: [...T]): MultiSeed<T>;\nexport function seed<T extends EntityInstance>(\n classOrClasses: EntityConstructor<T> | readonly EntityConstructor[],\n): SingleSeed<T> | MultiSeed<readonly EntityConstructor[]> {\n if (Array.isArray(classOrClasses)) {\n const classes = classOrClasses as readonly EntityConstructor[];\n\n return {\n create: (context?: SeedContext) =>\n createSeed(classes as [...typeof classes], context) as Promise<\n MapToInstances<typeof classes>\n >,\n save: (options: SaveSeedOptions) =>\n saveSeed(classes as [...typeof classes], options) as Promise<\n MapToInstances<typeof classes>\n >,\n createMany: (count: number, context?: SeedContext) =>\n createManySeed(classes as [...typeof classes], { count, ...context }) as Promise<\n MapToInstanceArrays<typeof classes>\n >,\n saveMany: (count: number, options: SaveSeedOptions) =>\n saveManySeed(classes as [...typeof classes], { count, ...options }) as Promise<\n MapToInstanceArrays<typeof classes>\n >,\n };\n }\n\n const EntityClass = classOrClasses as EntityConstructor<T>;\n\n return {\n create: (context?: SeedContext) => createSeed(EntityClass, context),\n save: (options: SaveSeedOptions) => saveSeed(EntityClass, options),\n createMany: (count: number, context?: SeedContext) =>\n createManySeed(EntityClass, { count, ...context }),\n saveMany: (count: number, options: SaveSeedOptions) =>\n saveManySeed(EntityClass, { count, ...options }),\n };\n}\n","interface SeederMeta {\n dependencies: Function[];\n}\n\nconst registry = new WeakMap<Function, SeederMeta>();\n\nexport function registerSeeder(target: Function, meta: SeederMeta): void {\n registry.set(target, meta);\n}\n\nexport function getSeederMeta(target: Function): SeederMeta | undefined {\n return registry.get(target);\n}\n","import { registerSeeder } from './registry.js';\nimport type { SeedContext } from '../seed/registry.js';\n\nexport interface SeederInterface {\n run(context: SeedContext): Promise<void>;\n}\n\nexport interface SeederOptions {\n dependencies?: (new () => SeederInterface)[];\n}\n\nexport function Seeder(options: SeederOptions = {}): ClassDecorator {\n return (target) => {\n registerSeeder(target, { dependencies: options.dependencies ?? [] });\n };\n}\n","import { DepGraph } from 'dependency-graph';\nimport { getSeederMeta } from './registry.js';\nimport type { SeederInterface } from './decorator.js';\nimport type { SeedContext } from '../seed/registry.js';\n\nexport type SeederCtor = new () => SeederInterface;\n\nexport interface RunSeedersOptions extends SeedContext {\n /**\n * Enable console logging for each seeder. Set to `false` to silence output,\n * e.g. when using callbacks to handle logging yourself.\n *\n * @default true\n */\n logging?: boolean;\n /** Called before each seeder runs, in execution order. */\n onBefore?: (seeder: SeederCtor) => void | Promise<void>;\n /** Called after each seeder completes successfully, with the time it took in milliseconds. */\n onAfter?: (seeder: SeederCtor, durationMs: number) => void | Promise<void>;\n /** Called when a seeder throws. The error is re-thrown after this callback returns. */\n onError?: (seeder: SeederCtor, error: unknown) => void | Promise<void>;\n /** Called for each seeder before it runs. Return `true` to skip it entirely. */\n skip?: (seeder: SeederCtor) => boolean | Promise<boolean>;\n}\n\nfunction topoSort(roots: SeederCtor[]): SeederCtor[] {\n const graph = new DepGraph<SeederCtor>();\n const byName = new Map<string, SeederCtor>();\n\n // Collect all nodes transitively via BFS and register them in the graph.\n const visited = new Set<SeederCtor>();\n const queue: SeederCtor[] = [...roots];\n\n while (queue.length > 0) {\n const node = queue.shift()!;\n\n if (visited.has(node)) {\n continue;\n }\n\n visited.add(node);\n graph.addNode(node.name, node);\n byName.set(node.name, node);\n\n for (const dep of (getSeederMeta(node)?.dependencies ?? []) as SeederCtor[]) {\n queue.push(dep);\n }\n }\n\n // Wire up the dependency edges.\n for (const node of visited) {\n for (const dep of (getSeederMeta(node)?.dependencies ?? []) as SeederCtor[]) {\n graph.addDependency(node.name, dep.name);\n }\n }\n\n try {\n return graph.overallOrder().map((name) => byName.get(name)!);\n } catch (err) {\n if (err && typeof err === 'object' && 'cyclePath' in err) {\n const path = (err as { cyclePath: string[] }).cyclePath.join(' → ');\n throw new Error(`Circular dependency detected among seeders: ${path}`);\n }\n\n throw err;\n }\n}\n\nexport async function runSeeders(\n seeders: SeederCtor[],\n options: RunSeedersOptions = {},\n): Promise<void> {\n const { logging = true, onBefore, onAfter, onError, skip, ...context } = options;\n\n for (const SeederClass of topoSort(seeders)) {\n if (await skip?.(SeederClass)) {\n continue;\n }\n\n if (logging) {\n console.log(`[${SeederClass.name}] Starting...`);\n }\n\n await onBefore?.(SeederClass);\n\n const start = Date.now();\n\n try {\n await new SeederClass().run(context);\n } catch (err) {\n const durationMs = Date.now() - start;\n\n if (logging) {\n console.error(`[${SeederClass.name}] Failed after ${durationMs}ms`);\n }\n\n await onError?.(SeederClass, err);\n throw err;\n }\n\n const durationMs = Date.now() - start;\n\n if (logging) {\n console.log(`[${SeederClass.name}] Done in ${durationMs}ms`);\n }\n\n await onAfter?.(SeederClass, durationMs);\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,74 +1,67 @@
1
- {
2
- "name": "@joakimbugge/typeorm-seeder",
3
- "version": "0.2.0",
4
- "description": "Decorator-based seeder library for TypeORM",
5
- "repository": {
6
- "type": "git",
7
- "url": "git+https://github.com/joakimbugge/to-seeder.git"
8
- },
9
- "homepage": "https://github.com/joakimbugge/to-seeder#readme",
10
- "bugs": "https://github.com/joakimbugge/to-seeder/issues",
11
- "type": "module",
12
- "main": "./dist/index.cjs",
13
- "module": "./dist/index.mjs",
14
- "types": "./dist/index.d.mts",
15
- "exports": {
16
- ".": {
17
- "import": {
18
- "types": "./dist/index.d.mts",
19
- "default": "./dist/index.mjs"
20
- },
21
- "require": {
22
- "types": "./dist/index.d.cts",
23
- "default": "./dist/index.cjs"
24
- }
25
- }
26
- },
27
- "files": [
28
- "dist"
29
- ],
30
- "scripts": {
31
- "build": "tsdown",
32
- "prepublishOnly": "npm run build",
33
- "dev": "tsdown --watch",
34
- "typecheck": "tsc --noEmit",
35
- "test": "vitest",
36
- "test:run": "vitest run",
37
- "lint": "oxlint src tests",
38
- "lint:fix": "oxlint --fix src tests",
39
- "fmt": "oxfmt src tests",
40
- "fmt:check": "oxfmt --check src tests"
41
- },
42
- "keywords": [
43
- "typeorm",
44
- "seeder",
45
- "decorator",
46
- "database",
47
- "seed"
48
- ],
49
- "license": "MIT",
50
- "engines": {
51
- "node": ">=16.13.0"
52
- },
53
- "peerDependencies": {
54
- "reflect-metadata": ">=0.1.0",
55
- "typeorm": ">=0.3.0"
56
- },
57
- "devDependencies": {
58
- "@faker-js/faker": "^10.4.0",
59
- "@types/better-sqlite3": "^7.6.13",
60
- "better-sqlite3": "^12.8.0",
61
- "lefthook": "^2.1.4",
62
- "oxfmt": "^0.42.0",
63
- "oxlint": "^1.57.0",
64
- "reflect-metadata": "^0.2.2",
65
- "tsdown": "^0.21.4",
66
- "tsx": "^4.21.0",
67
- "typeorm": "1.0.0-beta.1",
68
- "typescript": "^5.9.3",
69
- "vitest": "^4.1.1"
70
- },
71
- "dependencies": {
72
- "dependency-graph": "^1.0.0"
73
- }
74
- }
1
+ {
2
+ "name": "@joakimbugge/typeorm-seeder",
3
+ "version": "0.4.0",
4
+ "description": "Decorator-based seeder library for TypeORM",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/joakimbugge/to-seeder.git"
8
+ },
9
+ "homepage": "https://github.com/joakimbugge/to-seeder#readme",
10
+ "bugs": "https://github.com/joakimbugge/to-seeder/issues",
11
+ "type": "module",
12
+ "main": "./dist/index.cjs",
13
+ "module": "./dist/index.mjs",
14
+ "types": "./dist/index.d.mts",
15
+ "exports": {
16
+ ".": {
17
+ "import": {
18
+ "types": "./dist/index.d.mts",
19
+ "default": "./dist/index.mjs"
20
+ },
21
+ "require": {
22
+ "types": "./dist/index.d.cts",
23
+ "default": "./dist/index.cjs"
24
+ }
25
+ }
26
+ },
27
+ "files": [
28
+ "dist"
29
+ ],
30
+ "scripts": {
31
+ "build": "tsdown",
32
+ "prepublishOnly": "pnpm run build",
33
+ "dev": "tsdown --watch",
34
+ "typecheck": "tsc --noEmit",
35
+ "test": "vitest",
36
+ "test:run": "vitest run",
37
+ "lint": "oxlint src tests",
38
+ "lint:fix": "oxlint --fix src tests",
39
+ "fmt": "oxfmt src tests",
40
+ "fmt:check": "oxfmt --check src tests"
41
+ },
42
+ "keywords": [
43
+ "typeorm",
44
+ "seeder",
45
+ "decorator",
46
+ "database",
47
+ "seed"
48
+ ],
49
+ "license": "MIT",
50
+ "engines": {
51
+ "node": ">=16.13.0"
52
+ },
53
+ "peerDependencies": {
54
+ "reflect-metadata": ">=0.1.0",
55
+ "typeorm": ">=0.3.0"
56
+ },
57
+ "devDependencies": {
58
+ "@faker-js/faker": "^10.4.0",
59
+ "@types/better-sqlite3": "^7.6.13",
60
+ "better-sqlite3": "^12.8.0",
61
+ "reflect-metadata": "^0.2.2",
62
+ "typeorm": "1.0.0-beta.1"
63
+ },
64
+ "dependencies": {
65
+ "dependency-graph": "^1.0.0"
66
+ }
67
+ }