@prisma-next/target-mongo 0.4.0-dev.9 → 0.4.1

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.
@@ -1,76 +1,77 @@
1
1
  import { MongoSchemaCollection, MongoSchemaIndex } from "@prisma-next/mongo-schema-ir";
2
- import { CollModOptions, CreateCollectionOptions, CreateIndexOptions, MongoIndexKey } from "@prisma-next/mongo-query-ast/control";
3
- import { MigrationOperationClass } from "@prisma-next/framework-components/control";
2
+ import { CollModOptions, CreateCollectionOptions, CreateIndexOptions, MongoIndexKey, MongoMigrationPlanOperation } from "@prisma-next/mongo-query-ast/control";
3
+ import { ImportRequirement, TsExpression } from "@prisma-next/ts-render";
4
+ import { MigrationOperationClass, OpFactoryCall } from "@prisma-next/framework-components/control";
4
5
 
5
6
  //#region src/core/op-factory-call.d.ts
7
+
6
8
  interface CollModMeta {
7
9
  readonly id?: string;
8
10
  readonly label?: string;
9
11
  readonly operationClass?: MigrationOperationClass;
10
12
  }
11
- interface OpFactoryCallVisitor<R> {
12
- createIndex(call: CreateIndexCall): R;
13
- dropIndex(call: DropIndexCall): R;
14
- createCollection(call: CreateCollectionCall): R;
15
- dropCollection(call: DropCollectionCall): R;
16
- collMod(call: CollModCall): R;
17
- }
18
- declare abstract class OpFactoryCallNode {
19
- abstract readonly factory: string;
13
+ declare abstract class OpFactoryCallNode extends TsExpression implements OpFactoryCall {
14
+ abstract readonly factoryName: string;
20
15
  abstract readonly operationClass: MigrationOperationClass;
21
16
  abstract readonly label: string;
22
- abstract accept<R>(visitor: OpFactoryCallVisitor<R>): R;
17
+ abstract toOp(): MongoMigrationPlanOperation;
18
+ importRequirements(): readonly ImportRequirement[];
23
19
  protected freeze(): void;
24
20
  }
25
21
  declare class CreateIndexCall extends OpFactoryCallNode {
26
- readonly factory: "createIndex";
22
+ readonly factoryName: "createIndex";
27
23
  readonly operationClass: "additive";
28
24
  readonly collection: string;
29
25
  readonly keys: ReadonlyArray<MongoIndexKey>;
30
26
  readonly options: CreateIndexOptions | undefined;
31
27
  readonly label: string;
32
28
  constructor(collection: string, keys: ReadonlyArray<MongoIndexKey>, options?: CreateIndexOptions);
33
- accept<R>(visitor: OpFactoryCallVisitor<R>): R;
29
+ toOp(): MongoMigrationPlanOperation;
30
+ renderTypeScript(): string;
34
31
  }
35
32
  declare class DropIndexCall extends OpFactoryCallNode {
36
- readonly factory: "dropIndex";
33
+ readonly factoryName: "dropIndex";
37
34
  readonly operationClass: "destructive";
38
35
  readonly collection: string;
39
36
  readonly keys: ReadonlyArray<MongoIndexKey>;
40
37
  readonly label: string;
41
38
  constructor(collection: string, keys: ReadonlyArray<MongoIndexKey>);
42
- accept<R>(visitor: OpFactoryCallVisitor<R>): R;
39
+ toOp(): MongoMigrationPlanOperation;
40
+ renderTypeScript(): string;
43
41
  }
44
42
  declare class CreateCollectionCall extends OpFactoryCallNode {
45
- readonly factory: "createCollection";
43
+ readonly factoryName: "createCollection";
46
44
  readonly operationClass: "additive";
47
45
  readonly collection: string;
48
46
  readonly options: CreateCollectionOptions | undefined;
49
47
  readonly label: string;
50
48
  constructor(collection: string, options?: CreateCollectionOptions);
51
- accept<R>(visitor: OpFactoryCallVisitor<R>): R;
49
+ toOp(): MongoMigrationPlanOperation;
50
+ renderTypeScript(): string;
52
51
  }
53
52
  declare class DropCollectionCall extends OpFactoryCallNode {
54
- readonly factory: "dropCollection";
53
+ readonly factoryName: "dropCollection";
55
54
  readonly operationClass: "destructive";
56
55
  readonly collection: string;
57
56
  readonly label: string;
58
57
  constructor(collection: string);
59
- accept<R>(visitor: OpFactoryCallVisitor<R>): R;
58
+ toOp(): MongoMigrationPlanOperation;
59
+ renderTypeScript(): string;
60
60
  }
61
61
  declare class CollModCall extends OpFactoryCallNode {
62
- readonly factory: "collMod";
62
+ readonly factoryName: "collMod";
63
63
  readonly collection: string;
64
64
  readonly options: CollModOptions;
65
65
  readonly meta: CollModMeta | undefined;
66
66
  readonly operationClass: MigrationOperationClass;
67
67
  readonly label: string;
68
68
  constructor(collection: string, options: CollModOptions, meta?: CollModMeta);
69
- accept<R>(visitor: OpFactoryCallVisitor<R>): R;
69
+ toOp(): MongoMigrationPlanOperation;
70
+ renderTypeScript(): string;
70
71
  }
71
- type OpFactoryCall = CreateIndexCall | DropIndexCall | CreateCollectionCall | DropCollectionCall | CollModCall;
72
+ type OpFactoryCall$1 = CreateIndexCall | DropIndexCall | CreateCollectionCall | DropCollectionCall | CollModCall;
72
73
  declare function schemaIndexToCreateIndexOptions(index: MongoSchemaIndex): CreateIndexOptions;
73
74
  declare function schemaCollectionToCreateCollectionOptions(coll: MongoSchemaCollection): CreateCollectionOptions | undefined;
74
75
  //#endregion
75
- export { DropCollectionCall as a, OpFactoryCallVisitor as c, CreateIndexCall as i, schemaCollectionToCreateCollectionOptions as l, CollModMeta as n, DropIndexCall as o, CreateCollectionCall as r, OpFactoryCall as s, CollModCall as t, schemaIndexToCreateIndexOptions as u };
76
- //# sourceMappingURL=op-factory-call-CfPGebEH.d.mts.map
76
+ export { DropCollectionCall as a, schemaCollectionToCreateCollectionOptions as c, CreateIndexCall as i, schemaIndexToCreateIndexOptions as l, CollModMeta as n, DropIndexCall as o, CreateCollectionCall as r, OpFactoryCall$1 as s, CollModCall as t };
77
+ //# sourceMappingURL=op-factory-call-BjNAcPSF.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"op-factory-call-BjNAcPSF.d.mts","names":[],"sources":["../src/core/op-factory-call.ts"],"sourcesContent":[],"mappings":";;;;;;;AAwEqC,UA3BpB,WAAA,CA2BoB;EAAiB,SAAA,EAAA,CAAA,EAAA,MAAA;EAgCzC,SAAA,KAAA,CAAA,EAAc,MAAA;EAII,SAAA,cAAA,CAAA,EA5DH,uBA4DG;;uBAvDhB,iBAAA,SAA0B,YAAA,YAAwB,aA0DX,CAAA;EAAd,kBAAA,WAAA,EAAA,MAAA;EAQ9B,kBAAA,cAAA,EAhE0B,uBAgE1B;EAfyB,kBAAA,KAAA,EAAA,MAAA;EAAiB,SAAA,IAAA,CAAA,CAAA,EA/CjC,2BA+CiC;EAwBvC,kBAAA,CAAA,CAAA,EAAA,SArEoB,iBAqEC,EAAA;EAId,UAAA,MAAA,CAAA,CAAA,EAAA,IAAA;;AAWV,cAvEG,eAAA,SAAwB,iBAAA,CAuE3B;EAfgC,SAAA,WAAA,EAAA,aAAA;EAAiB,SAAA,cAAA,EAAA,UAAA;EA0B9C,SAAA,UAAA,EAAmB,MAAA;EAsBnB,SAAA,IAAA,EApGI,aAoGQ,CApGM,aAoGN,CAAA;EAGL,SAAA,OAAA,EAtGA,kBAsGA,GAAA,SAAA;EACH,SAAA,KAAA,EAAA,MAAA;EACU,WAAA,CAAA,UAAA,EAAA,MAAA,EAAA,IAAA,EAnGjB,aAmGiB,CAnGH,aAmGG,CAAA,EAAA,OAAA,CAAA,EAlGb,kBAkGa;EAGgB,IAAA,CAAA,CAAA,EA3FjC,2BA2FiC;EAAuB,gBAAA,CAAA,CAAA,EAAA,MAAA;;AARjC,cAxEpB,aAAA,SAAsB,iBAAA,CAwEF;EAAiB,SAAA,WAAA,EAAA,WAAA;EA6BtC,SAAA,cAAa,EAAA,aAAA;EACrB,SAAA,UAAA,EAAA,MAAA;EACA,SAAA,IAAA,EAnGa,aAmGb,CAnG2B,aAmG3B,CAAA;EACA,SAAA,KAAA,EAAA,MAAA;EACA,WAAA,CAAA,UAAA,EAAA,MAAA,EAAA,IAAA,EAlGoC,aAkGpC,CAlGkD,aAkGlD,CAAA;EACA,IAAA,CAAA,CAAA,EA3FM,2BA2FN;EAAW,gBAAA,CAAA,CAAA,EAAA,MAAA;AAEf;AAcgB,cAlGH,oBAAA,SAA6B,iBAAA,CAmGlC;;;;oBA/FY;;4CAGwB;UAQlC;;;cAWG,kBAAA,SAA2B,iBAAA;;;;;;UAa9B;;;cASG,WAAA,SAAoB,iBAAA;;;oBAGb;iBACH;2BACU;;2CAGgB,uBAAuB;UAUxD;;;KAWE,eAAA,GACR,kBACA,gBACA,uBACA,qBACA;iBAEY,+BAAA,QAAuC,mBAAmB;iBAc1D,yCAAA,OACR,wBACL"}
package/package.json CHANGED
@@ -1,22 +1,23 @@
1
1
  {
2
2
  "name": "@prisma-next/target-mongo",
3
- "version": "0.4.0-dev.9",
3
+ "version": "0.4.1",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "description": "MongoDB target pack for Prisma Next",
7
7
  "dependencies": {
8
8
  "arktype": "^2.1.29",
9
9
  "mongodb": "^6.16.0",
10
- "@prisma-next/contract": "0.4.0-dev.9",
11
- "@prisma-next/migration-tools": "0.4.0-dev.9",
12
- "@prisma-next/errors": "0.4.0-dev.9",
13
- "@prisma-next/mongo-contract": "0.4.0-dev.9",
14
- "@prisma-next/mongo-lowering": "0.4.0-dev.9",
15
- "@prisma-next/mongo-schema-ir": "0.4.0-dev.9",
16
- "@prisma-next/framework-components": "0.4.0-dev.9",
17
- "@prisma-next/mongo-query-ast": "0.4.0-dev.9",
18
- "@prisma-next/utils": "0.4.0-dev.9",
19
- "@prisma-next/mongo-value": "0.4.0-dev.9"
10
+ "@prisma-next/contract": "0.4.1",
11
+ "@prisma-next/migration-tools": "0.4.1",
12
+ "@prisma-next/framework-components": "0.4.1",
13
+ "@prisma-next/errors": "0.4.1",
14
+ "@prisma-next/ts-render": "0.4.1",
15
+ "@prisma-next/mongo-lowering": "0.4.1",
16
+ "@prisma-next/mongo-contract": "0.4.1",
17
+ "@prisma-next/mongo-query-ast": "0.4.1",
18
+ "@prisma-next/utils": "0.4.1",
19
+ "@prisma-next/mongo-schema-ir": "0.4.1",
20
+ "@prisma-next/mongo-value": "0.4.1"
20
21
  },
21
22
  "devDependencies": {
22
23
  "mongodb-memory-server": "10.4.3",
@@ -25,8 +26,8 @@
25
26
  "typescript": "5.9.3",
26
27
  "vitest": "4.0.17",
27
28
  "@prisma-next/test-utils": "0.0.1",
28
- "@prisma-next/tsdown": "0.0.0",
29
- "@prisma-next/tsconfig": "0.0.0"
29
+ "@prisma-next/tsconfig": "0.0.0",
30
+ "@prisma-next/tsdown": "0.0.0"
30
31
  },
31
32
  "files": [
32
33
  "dist",
@@ -243,12 +243,11 @@ export class MongoMigrationPlanner implements MigrationPlanner<'mongo', 'mongo'>
243
243
  /**
244
244
  * Produce an empty `migration.ts` authoring surface for `migration new`.
245
245
  *
246
- * Mongo is a class-flow target, so the "empty migration" is a
247
- * `PlannerProducedMongoMigration` with no operations; `renderTypeScript()`
248
- * emits a stub class with the correct `from`/`to` metadata that the user
249
- * then fills in with operations. The contract path on the context is
250
- * unused — Mongo's emitted source does not import from the generated
251
- * contract `.d.ts`.
246
+ * The "empty migration" is a `PlannerProducedMongoMigration` with no
247
+ * operations; `renderTypeScript()` emits a stub class with the correct
248
+ * `from`/`to` metadata that the user then fills in with operations. The
249
+ * contract path on the context is unused Mongo's emitted source does
250
+ * not import from the generated contract `.d.ts`.
252
251
  */
253
252
  emptyMigration(context: MigrationScaffoldContext): MigrationPlanWithAuthoringSurface {
254
253
  return new PlannerProducedMongoMigration([], {
@@ -1,9 +1,32 @@
1
- import type { MigrationOperationClass } from '@prisma-next/framework-components/control';
1
+ /**
2
+ * Mongo migration IR: one concrete `*Call` class per pure factory under
3
+ * `migration-factories.ts`, plus a shared `OpFactoryCallNode` abstract
4
+ * base. Every call class carries the literal arguments its backing
5
+ * factory would receive, computes a human-readable `label` in its
6
+ * constructor, and implements two polymorphic hooks:
7
+ *
8
+ * - `toOp()` — converts the IR node to a runtime
9
+ * `MongoMigrationPlanOperation` by delegating to the matching pure
10
+ * factory in `migration-factories.ts`.
11
+ * - `renderTypeScript()` / `importRequirements()` — inherited from
12
+ * `TsExpression`. Used by `renderCallsToTypeScript` to emit the call
13
+ * as a TypeScript expression inside the scaffolded `migration.ts`.
14
+ *
15
+ * The abstract base and all concrete classes are package-private.
16
+ * External consumers see only the framework-level `OpFactoryCall`
17
+ * interface and the `OpFactoryCall` union.
18
+ */
19
+
20
+ import type {
21
+ OpFactoryCall as FrameworkOpFactoryCall,
22
+ MigrationOperationClass,
23
+ } from '@prisma-next/framework-components/control';
2
24
  import type {
3
25
  CollModOptions,
4
26
  CreateCollectionOptions,
5
27
  CreateIndexOptions,
6
28
  MongoIndexKey,
29
+ MongoMigrationPlanOperation,
7
30
  } from '@prisma-next/mongo-query-ast/control';
8
31
  import type {
9
32
  MongoSchemaCollection,
@@ -11,6 +34,14 @@ import type {
11
34
  MongoSchemaIndex,
12
35
  MongoSchemaValidator,
13
36
  } from '@prisma-next/mongo-schema-ir';
37
+ import { type ImportRequirement, jsonToTsSource, TsExpression } from '@prisma-next/ts-render';
38
+ import {
39
+ collMod,
40
+ createCollection,
41
+ createIndex,
42
+ dropCollection,
43
+ dropIndex,
44
+ } from './migration-factories';
14
45
 
15
46
  export interface CollModMeta {
16
47
  readonly id?: string;
@@ -18,19 +49,17 @@ export interface CollModMeta {
18
49
  readonly operationClass?: MigrationOperationClass;
19
50
  }
20
51
 
21
- export interface OpFactoryCallVisitor<R> {
22
- createIndex(call: CreateIndexCall): R;
23
- dropIndex(call: DropIndexCall): R;
24
- createCollection(call: CreateCollectionCall): R;
25
- dropCollection(call: DropCollectionCall): R;
26
- collMod(call: CollModCall): R;
27
- }
52
+ const TARGET_MIGRATION_MODULE = '@prisma-next/target-mongo/migration';
28
53
 
29
- abstract class OpFactoryCallNode {
30
- abstract readonly factory: string;
54
+ abstract class OpFactoryCallNode extends TsExpression implements FrameworkOpFactoryCall {
55
+ abstract readonly factoryName: string;
31
56
  abstract readonly operationClass: MigrationOperationClass;
32
57
  abstract readonly label: string;
33
- abstract accept<R>(visitor: OpFactoryCallVisitor<R>): R;
58
+ abstract toOp(): MongoMigrationPlanOperation;
59
+
60
+ importRequirements(): readonly ImportRequirement[] {
61
+ return [{ moduleSpecifier: TARGET_MIGRATION_MODULE, symbol: this.factoryName }];
62
+ }
34
63
 
35
64
  protected freeze(): void {
36
65
  Object.freeze(this);
@@ -42,7 +71,7 @@ function formatKeys(keys: ReadonlyArray<MongoIndexKey>): string {
42
71
  }
43
72
 
44
73
  export class CreateIndexCall extends OpFactoryCallNode {
45
- readonly factory = 'createIndex' as const;
74
+ readonly factoryName = 'createIndex' as const;
46
75
  readonly operationClass = 'additive' as const;
47
76
  readonly collection: string;
48
77
  readonly keys: ReadonlyArray<MongoIndexKey>;
@@ -62,13 +91,19 @@ export class CreateIndexCall extends OpFactoryCallNode {
62
91
  this.freeze();
63
92
  }
64
93
 
65
- accept<R>(visitor: OpFactoryCallVisitor<R>): R {
66
- return visitor.createIndex(this);
94
+ toOp(): MongoMigrationPlanOperation {
95
+ return createIndex(this.collection, this.keys, this.options);
96
+ }
97
+
98
+ renderTypeScript(): string {
99
+ return this.options
100
+ ? `createIndex(${jsonToTsSource(this.collection)}, ${jsonToTsSource(this.keys)}, ${jsonToTsSource(this.options)})`
101
+ : `createIndex(${jsonToTsSource(this.collection)}, ${jsonToTsSource(this.keys)})`;
67
102
  }
68
103
  }
69
104
 
70
105
  export class DropIndexCall extends OpFactoryCallNode {
71
- readonly factory = 'dropIndex' as const;
106
+ readonly factoryName = 'dropIndex' as const;
72
107
  readonly operationClass = 'destructive' as const;
73
108
  readonly collection: string;
74
109
  readonly keys: ReadonlyArray<MongoIndexKey>;
@@ -82,13 +117,17 @@ export class DropIndexCall extends OpFactoryCallNode {
82
117
  this.freeze();
83
118
  }
84
119
 
85
- accept<R>(visitor: OpFactoryCallVisitor<R>): R {
86
- return visitor.dropIndex(this);
120
+ toOp(): MongoMigrationPlanOperation {
121
+ return dropIndex(this.collection, this.keys);
122
+ }
123
+
124
+ renderTypeScript(): string {
125
+ return `dropIndex(${jsonToTsSource(this.collection)}, ${jsonToTsSource(this.keys)})`;
87
126
  }
88
127
  }
89
128
 
90
129
  export class CreateCollectionCall extends OpFactoryCallNode {
91
- readonly factory = 'createCollection' as const;
130
+ readonly factoryName = 'createCollection' as const;
92
131
  readonly operationClass = 'additive' as const;
93
132
  readonly collection: string;
94
133
  readonly options: CreateCollectionOptions | undefined;
@@ -102,13 +141,19 @@ export class CreateCollectionCall extends OpFactoryCallNode {
102
141
  this.freeze();
103
142
  }
104
143
 
105
- accept<R>(visitor: OpFactoryCallVisitor<R>): R {
106
- return visitor.createCollection(this);
144
+ toOp(): MongoMigrationPlanOperation {
145
+ return createCollection(this.collection, this.options);
146
+ }
147
+
148
+ renderTypeScript(): string {
149
+ return this.options
150
+ ? `createCollection(${jsonToTsSource(this.collection)}, ${jsonToTsSource(this.options)})`
151
+ : `createCollection(${jsonToTsSource(this.collection)})`;
107
152
  }
108
153
  }
109
154
 
110
155
  export class DropCollectionCall extends OpFactoryCallNode {
111
- readonly factory = 'dropCollection' as const;
156
+ readonly factoryName = 'dropCollection' as const;
112
157
  readonly operationClass = 'destructive' as const;
113
158
  readonly collection: string;
114
159
  readonly label: string;
@@ -120,13 +165,17 @@ export class DropCollectionCall extends OpFactoryCallNode {
120
165
  this.freeze();
121
166
  }
122
167
 
123
- accept<R>(visitor: OpFactoryCallVisitor<R>): R {
124
- return visitor.dropCollection(this);
168
+ toOp(): MongoMigrationPlanOperation {
169
+ return dropCollection(this.collection);
170
+ }
171
+
172
+ renderTypeScript(): string {
173
+ return `dropCollection(${jsonToTsSource(this.collection)})`;
125
174
  }
126
175
  }
127
176
 
128
177
  export class CollModCall extends OpFactoryCallNode {
129
- readonly factory = 'collMod' as const;
178
+ readonly factoryName = 'collMod' as const;
130
179
  readonly collection: string;
131
180
  readonly options: CollModOptions;
132
181
  readonly meta: CollModMeta | undefined;
@@ -143,8 +192,14 @@ export class CollModCall extends OpFactoryCallNode {
143
192
  this.freeze();
144
193
  }
145
194
 
146
- accept<R>(visitor: OpFactoryCallVisitor<R>): R {
147
- return visitor.collMod(this);
195
+ toOp(): MongoMigrationPlanOperation {
196
+ return collMod(this.collection, this.options, this.meta);
197
+ }
198
+
199
+ renderTypeScript(): string {
200
+ return this.meta
201
+ ? `collMod(${jsonToTsSource(this.collection)}, ${jsonToTsSource(this.options)}, ${jsonToTsSource(this.meta)})`
202
+ : `collMod(${jsonToTsSource(this.collection)}, ${jsonToTsSource(this.options)})`;
148
203
  }
149
204
  }
150
205
 
@@ -1,39 +1,6 @@
1
1
  import type { MongoMigrationPlanOperation } from '@prisma-next/mongo-query-ast/control';
2
- import {
3
- collMod,
4
- createCollection,
5
- createIndex,
6
- dropCollection,
7
- dropIndex,
8
- } from './migration-factories';
9
- import type {
10
- CollModCall,
11
- CreateCollectionCall,
12
- CreateIndexCall,
13
- DropCollectionCall,
14
- DropIndexCall,
15
- OpFactoryCall,
16
- OpFactoryCallVisitor,
17
- } from './op-factory-call';
18
-
19
- const renderVisitor: OpFactoryCallVisitor<MongoMigrationPlanOperation> = {
20
- createIndex(call: CreateIndexCall) {
21
- return createIndex(call.collection, call.keys, call.options);
22
- },
23
- dropIndex(call: DropIndexCall) {
24
- return dropIndex(call.collection, call.keys);
25
- },
26
- createCollection(call: CreateCollectionCall) {
27
- return createCollection(call.collection, call.options);
28
- },
29
- dropCollection(call: DropCollectionCall) {
30
- return dropCollection(call.collection);
31
- },
32
- collMod(call: CollModCall) {
33
- return collMod(call.collection, call.options, call.meta);
34
- },
35
- };
2
+ import type { OpFactoryCall } from './op-factory-call';
36
3
 
37
4
  export function renderOps(calls: ReadonlyArray<OpFactoryCall>): MongoMigrationPlanOperation[] {
38
- return calls.map((call) => call.accept(renderVisitor));
5
+ return calls.map((call) => call.toOp());
39
6
  }
@@ -1,13 +1,6 @@
1
1
  import { detectScaffoldRuntime, shebangLineFor } from '@prisma-next/migration-tools/migration-ts';
2
- import type {
3
- CollModCall,
4
- CreateCollectionCall,
5
- CreateIndexCall,
6
- DropCollectionCall,
7
- DropIndexCall,
8
- OpFactoryCall,
9
- OpFactoryCallVisitor,
10
- } from './op-factory-call';
2
+ import { type ImportRequirement, jsonToTsSource, renderImports } from '@prisma-next/ts-render';
3
+ import type { OpFactoryCall } from './op-factory-call';
11
4
 
12
5
  export interface RenderMigrationMeta {
13
6
  readonly from: string;
@@ -16,22 +9,34 @@ export interface RenderMigrationMeta {
16
9
  readonly labels?: readonly string[];
17
10
  }
18
11
 
12
+ const BASE_IMPORT: ImportRequirement = {
13
+ moduleSpecifier: '@prisma-next/family-mongo/migration',
14
+ symbol: 'Migration',
15
+ };
16
+
19
17
  /**
20
- * Render a list of Mongo `OpFactoryCall`s as a class-flow `migration.ts`
18
+ * Render a list of Mongo `OpFactoryCall`s as a `migration.ts`
21
19
  * source string. The result is shebanged, extends the user-facing
22
20
  * `Migration` (i.e. `MongoMigration`) from `@prisma-next/family-mongo`, and
23
21
  * implements the abstract `operations` and `describe` members. `meta` is
24
22
  * always rendered — `describe()` is part of the `Migration` contract, so
25
23
  * even an empty stub must satisfy it; callers pass empty strings for a
26
24
  * migration-new scaffold.
25
+ *
26
+ * The walk is polymorphic: each call node contributes its own
27
+ * `renderTypeScript()` expression and declares its own
28
+ * `importRequirements()`. The top-level renderer aggregates imports
29
+ * across all nodes and emits one `import { … } from "…"` line per module.
30
+ * The `Migration` import from `@prisma-next/family-mongo/migration` is
31
+ * always emitted — it's driven by `meta` (the rendered scaffold always
32
+ * extends `Migration`), not by any node.
27
33
  */
28
34
  export function renderCallsToTypeScript(
29
35
  calls: ReadonlyArray<OpFactoryCall>,
30
36
  meta: RenderMigrationMeta,
31
37
  ): string {
32
- const factoryNames = collectFactoryNames(calls);
33
- const imports = buildImports(factoryNames);
34
- const operationsBody = calls.map((c) => c.accept(renderCallVisitor)).join(',\n');
38
+ const imports = buildImports(calls);
39
+ const operationsBody = calls.map((c) => c.renderTypeScript()).join(',\n');
35
40
 
36
41
  return [
37
42
  shebangLineFor(detectScaffoldRuntime()),
@@ -52,20 +57,14 @@ export function renderCallsToTypeScript(
52
57
  ].join('\n');
53
58
  }
54
59
 
55
- function collectFactoryNames(calls: ReadonlyArray<OpFactoryCall>): string[] {
56
- const names = new Set<string>();
60
+ function buildImports(calls: ReadonlyArray<OpFactoryCall>): string {
61
+ const requirements: ImportRequirement[] = [BASE_IMPORT];
57
62
  for (const call of calls) {
58
- names.add(call.factory);
63
+ for (const req of call.importRequirements()) {
64
+ requirements.push(req);
65
+ }
59
66
  }
60
- return [...names].sort();
61
- }
62
-
63
- function buildImports(factoryNames: string[]): string {
64
- const lines = ["import { Migration } from '@prisma-next/family-mongo/migration';"];
65
- if (factoryNames.length > 0) {
66
- lines.push(`import { ${factoryNames.join(', ')} } from '@prisma-next/target-mongo/migration';`);
67
- }
68
- return lines.join('\n');
67
+ return renderImports(requirements);
69
68
  }
70
69
 
71
70
  function buildDescribeMethod(meta: RenderMigrationMeta): string {
@@ -78,7 +77,7 @@ function buildDescribeMethod(meta: RenderMigrationMeta): string {
78
77
  lines.push(` kind: ${JSON.stringify(meta.kind)},`);
79
78
  }
80
79
  if (meta.labels && meta.labels.length > 0) {
81
- lines.push(` labels: ${renderLiteral(meta.labels)},`);
80
+ lines.push(` labels: ${jsonToTsSource(meta.labels)},`);
82
81
  }
83
82
  lines.push(' };');
84
83
  lines.push(' }');
@@ -86,58 +85,6 @@ function buildDescribeMethod(meta: RenderMigrationMeta): string {
86
85
  return lines.join('\n');
87
86
  }
88
87
 
89
- const renderCallVisitor: OpFactoryCallVisitor<string> = {
90
- createIndex(call: CreateIndexCall) {
91
- return call.options
92
- ? `createIndex(${renderLiteral(call.collection)}, ${renderLiteral(call.keys)}, ${renderLiteral(call.options)})`
93
- : `createIndex(${renderLiteral(call.collection)}, ${renderLiteral(call.keys)})`;
94
- },
95
- dropIndex(call: DropIndexCall) {
96
- return `dropIndex(${renderLiteral(call.collection)}, ${renderLiteral(call.keys)})`;
97
- },
98
- createCollection(call: CreateCollectionCall) {
99
- return call.options
100
- ? `createCollection(${renderLiteral(call.collection)}, ${renderLiteral(call.options)})`
101
- : `createCollection(${renderLiteral(call.collection)})`;
102
- },
103
- dropCollection(call: DropCollectionCall) {
104
- return `dropCollection(${renderLiteral(call.collection)})`;
105
- },
106
- collMod(call: CollModCall) {
107
- return call.meta
108
- ? `collMod(${renderLiteral(call.collection)}, ${renderLiteral(call.options)}, ${renderLiteral(call.meta)})`
109
- : `collMod(${renderLiteral(call.collection)}, ${renderLiteral(call.options)})`;
110
- },
111
- };
112
-
113
- function renderLiteral(value: unknown): string {
114
- if (value === undefined) return 'undefined';
115
- if (value === null) return 'null';
116
- if (typeof value === 'string') return JSON.stringify(value);
117
- if (typeof value === 'number' || typeof value === 'boolean') return String(value);
118
- if (Array.isArray(value)) {
119
- if (value.length === 0) return '[]';
120
- const items = value.map((v) => renderLiteral(v));
121
- const singleLine = `[${items.join(', ')}]`;
122
- if (singleLine.length <= 80) return singleLine;
123
- return `[\n${items.map((i) => ` ${i}`).join(',\n')},\n]`;
124
- }
125
- if (typeof value === 'object') {
126
- const entries = Object.entries(value).filter(([, v]) => v !== undefined);
127
- if (entries.length === 0) return '{}';
128
- const items = entries.map(([k, v]) => `${renderKey(k)}: ${renderLiteral(v)}`);
129
- const singleLine = `{ ${items.join(', ')} }`;
130
- if (singleLine.length <= 80) return singleLine;
131
- return `{\n${items.map((i) => ` ${i}`).join(',\n')},\n}`;
132
- }
133
- return String(value);
134
- }
135
-
136
- function renderKey(key: string): string {
137
- if (key === '__proto__') return JSON.stringify(key);
138
- return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? key : JSON.stringify(key);
139
- }
140
-
141
88
  function indent(text: string, spaces: number): string {
142
89
  const pad = ' '.repeat(spaces);
143
90
  return text
@@ -11,7 +11,7 @@ export type { PlanCallsResult } from '../core/mongo-planner';
11
11
  export { MongoMigrationPlanner } from '../core/mongo-planner';
12
12
  export type { MarkerOperations, MongoRunnerDependencies } from '../core/mongo-runner';
13
13
  export { MongoMigrationRunner } from '../core/mongo-runner';
14
- export type { CollModMeta, OpFactoryCall, OpFactoryCallVisitor } from '../core/op-factory-call';
14
+ export type { CollModMeta, OpFactoryCall } from '../core/op-factory-call';
15
15
  export {
16
16
  CollModCall,
17
17
  CreateCollectionCall,
@@ -1 +0,0 @@
1
- {"version":3,"file":"op-factory-call-CfPGebEH.d.mts","names":[],"sources":["../src/core/op-factory-call.ts"],"sourcesContent":[],"mappings":"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"}