@prisma-next/target-mongo 0.4.0-dev.9 → 0.5.0-dev.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.
package/README.md CHANGED
@@ -33,6 +33,7 @@ const contract = defineContract({
33
33
  ### Migration authoring
34
34
 
35
35
  ```typescript
36
+ import { MigrationCLI } from '@prisma-next/cli/migration-cli';
36
37
  import { Migration } from '@prisma-next/family-mongo/migration';
37
38
  import { createIndex, createCollection } from '@prisma-next/target-mongo/migration';
38
39
 
@@ -49,7 +50,7 @@ class UsersMigration extends Migration {
49
50
  }
50
51
 
51
52
  export default UsersMigration;
52
- Migration.run(import.meta.url, UsersMigration)
53
+ MigrationCLI.run(import.meta.url, UsersMigration);
53
54
  ```
54
55
 
55
56
  Run `tsx migration.ts` to produce `ops.json` and `migration.json` (when `describe()` is implemented). Use `--dry-run` to preview without writing.
@@ -1,4 +1,4 @@
1
- import { a as DropCollectionCall, c as OpFactoryCallVisitor, i as CreateIndexCall, l as schemaCollectionToCreateCollectionOptions, n as CollModMeta, o as DropIndexCall, r as CreateCollectionCall, s as OpFactoryCall, t as CollModCall, u as schemaIndexToCreateIndexOptions } from "./op-factory-call-CfPGebEH.mjs";
1
+ import { a as DropCollectionCall, c as schemaCollectionToCreateCollectionOptions, i as CreateIndexCall, l as schemaIndexToCreateIndexOptions, n as CollModMeta, o as DropIndexCall, r as CreateCollectionCall, s as OpFactoryCall, t as CollModCall } from "./op-factory-call-BjNAcPSF.mjs";
2
2
  import { MongoSchemaIR } from "@prisma-next/mongo-schema-ir";
3
3
  import { MongoQueryPlan } from "@prisma-next/mongo-query-ast/execution";
4
4
  import { AnyMongoMigrationOperation, MongoAndExpr, MongoDdlCommandVisitor, MongoExistsExpr, MongoExprFilter, MongoFieldFilter, MongoFilterExpr, MongoFilterVisitor, MongoInspectionCommandVisitor, MongoMigrationPlanOperation, MongoNotExpr, MongoOrExpr } from "@prisma-next/mongo-query-ast/control";
@@ -74,12 +74,11 @@ declare class MongoMigrationPlanner implements MigrationPlanner<'mongo', 'mongo'
74
74
  /**
75
75
  * Produce an empty `migration.ts` authoring surface for `migration new`.
76
76
  *
77
- * Mongo is a class-flow target, so the "empty migration" is a
78
- * `PlannerProducedMongoMigration` with no operations; `renderTypeScript()`
79
- * emits a stub class with the correct `from`/`to` metadata that the user
80
- * then fills in with operations. The contract path on the context is
81
- * unused — Mongo's emitted source does not import from the generated
82
- * contract `.d.ts`.
77
+ * The "empty migration" is a `PlannerProducedMongoMigration` with no
78
+ * operations; `renderTypeScript()` emits a stub class with the correct
79
+ * `from`/`to` metadata that the user then fills in with operations. The
80
+ * contract path on the context is unused Mongo's emitted source does
81
+ * not import from the generated contract `.d.ts`.
83
82
  */
84
83
  emptyMigration(context: MigrationScaffoldContext): MigrationPlanWithAuthoringSurface;
85
84
  }
@@ -168,15 +167,23 @@ interface RenderMigrationMeta {
168
167
  readonly labels?: readonly string[];
169
168
  }
170
169
  /**
171
- * Render a list of Mongo `OpFactoryCall`s as a class-flow `migration.ts`
170
+ * Render a list of Mongo `OpFactoryCall`s as a `migration.ts`
172
171
  * source string. The result is shebanged, extends the user-facing
173
172
  * `Migration` (i.e. `MongoMigration`) from `@prisma-next/family-mongo`, and
174
173
  * implements the abstract `operations` and `describe` members. `meta` is
175
174
  * always rendered — `describe()` is part of the `Migration` contract, so
176
175
  * even an empty stub must satisfy it; callers pass empty strings for a
177
176
  * migration-new scaffold.
177
+ *
178
+ * The walk is polymorphic: each call node contributes its own
179
+ * `renderTypeScript()` expression and declares its own
180
+ * `importRequirements()`. The top-level renderer aggregates imports
181
+ * across all nodes and emits one `import { … } from "…"` line per module.
182
+ * The `Migration` and `MigrationCLI` imports are always emitted — they're
183
+ * structural to the rendered scaffold (extends `Migration`, calls
184
+ * `MigrationCLI.run`), not driven by any node.
178
185
  */
179
186
  declare function renderCallsToTypeScript(calls: ReadonlyArray<OpFactoryCall>, meta: RenderMigrationMeta): string;
180
187
  //#endregion
181
- export { CollModCall, type CollModMeta, CreateCollectionCall, CreateIndexCall, DropCollectionCall, DropIndexCall, FilterEvaluator, type MarkerOperations, MongoMigrationPlanner, MongoMigrationRunner, type MongoRunnerDependencies, type OpFactoryCall, type OpFactoryCallVisitor, type PlanCallsResult, PlannerProducedMongoMigration, type RenderMigrationMeta, contractToMongoSchemaIR, deserializeMongoOp, deserializeMongoOps, formatMongoOperations, initMarker, readMarker, renderCallsToTypeScript, renderOps, schemaCollectionToCreateCollectionOptions, schemaIndexToCreateIndexOptions, serializeMongoOps, updateMarker, writeLedgerEntry };
188
+ export { CollModCall, type CollModMeta, CreateCollectionCall, CreateIndexCall, DropCollectionCall, DropIndexCall, FilterEvaluator, type MarkerOperations, MongoMigrationPlanner, MongoMigrationRunner, type MongoRunnerDependencies, type OpFactoryCall, type PlanCallsResult, PlannerProducedMongoMigration, type RenderMigrationMeta, contractToMongoSchemaIR, deserializeMongoOp, deserializeMongoOps, formatMongoOperations, initMarker, readMarker, renderCallsToTypeScript, renderOps, schemaCollectionToCreateCollectionOptions, schemaIndexToCreateIndexOptions, serializeMongoOps, updateMarker, writeLedgerEntry };
182
189
  //# sourceMappingURL=control.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"control.d.mts","names":[],"sources":["../src/core/contract-to-schema.ts","../src/core/ddl-formatter.ts","../src/core/filter-evaluator.ts","../src/core/marker-ledger.ts","../src/core/mongo-ops-serializer.ts","../src/core/mongo-planner.ts","../src/core/mongo-runner.ts","../src/core/planner-produced-migration.ts","../src/core/render-ops.ts","../src/core/render-typescript.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;iBAoDgB,uBAAA,WAAkC,uBAAuB;;;iBC6CzD,qBAAA,sBAA2C;;;cC/C9C,eAAA,YAA2B;;mBAGrB,sBAAsB;cAK3B;YAKF;WAID;YAIC;eAIG;cAKD;;;;iBCjDQ,UAAA,KAAe,KAAK,QAAQ;iBAgB5B,UAAA,KAChB;;;IAEH;iBAcmB,YAAA,KAChB;;;IAGH;iBAiBmB,gBAAA,KAChB;;EHlCU,SAAA,IAAA,EAAA,MAAA;;IGoCb;;;iBC8ea,kBAAA,iBAAmC;iBAOnC,mBAAA,4BAA+C;iBAI/C,iBAAA,eAAgC;;;KC7epC,eAAA;;kBACoC;;;sBACI;;cAEvC,qBAAA,YAAiC;;;ILpD9B,SAAA,MAAA,EAAA,OAAuB;qBKwDlB;kCACa,cAAc;MAC1C;EJbU,IAAA,CAAA,OAAA,EAAA;;;qBIiIK;IHhLR,SAAA,QAAgB,EAAA,MAAA;IAGV,SAAA,mBAAA,EG+Ke,aH/Kf,CG+K6B,8BH/K7B,CAAA,OAAA,EAAA,OAAA,CAAA,CAAA;EAAsB,CAAA,CAAA,EGgLnC,sBHhLmC;EAK3B;;;;;;;;;;0BGkMY,2BAA2B;AF7NrD;;;UGMiB,gBAAA;gBACD,QAAQ;;;;MAIlB;;;INUU,SAAA,WAAA,EAAuB,MAAA;MMNlC;;;ILmDW,SAAA,IAAA,EAAA,MAAqB;;MK9C/B;;AJDO,UIII,uBAAA,CJJY;EAGV,SAAA,eAAA,EIES,sBJFT,CIEgC,OJFhC,CAAA,IAAA,CAAA,CAAA;EAAsB,SAAA,kBAAA,EIGV,6BJHU,CIGoB,OJHpB,CIG4B,MJH5B,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,CAAA,CAAA;EAK3B,SAAA,OAAA,EIDM,YJCN;EAKF,SAAA,MAAA,EILO,WJKP;EAID,SAAA,SAAA,EIRW,gBJQX;;AAQI,cIDF,oBAAA,CJCE;EAKD,iBAAA,IAAA;EA9B0B,WAAA,CAAA,IAAA,EIyBH,uBJzBG;EAAkB,OAAA,CAAA,OAAA,EAAA;mBI4BvC;;qBAEE;IHjDC,SAAU,SAAA,CAAA,EAAA;MAAK,gBAAA,EAAA,EAAA,EGmDT,sBHnDS,CAAA,EAAA,IAAA;MAAa,mBAAA,EAAA,EAAA,EGoDnB,sBHpDmB,CAAA,EAAA,IAAA;IAAR,CAAA;IAAO,SAAA,eAAA,CAAA,EGsDlB,8BHtDkB;IAgB3B,SAAU,mBAG7B,EGoC+B,aHpCxB,CGoCsC,8BHpCtC,CAAA,OAAA,EAAA,OAAA,CAAA,CAAA;EAcY,CAAA,CAAA,EGuBhB,OHvBgB,CGuBR,qBHnBX,CAAA;EAiBmB,QAAA,oBAAgB;;;;ECiftB,QAAA,0BAAmC;EAOnC,QAAA,yBAAmB;AAInC;;;;;;;;;;;;AJ7hBA;;;;AC6CA;;;cMzEa,6BAAA,SACH,UAAU,uCACP;ELwBA,iBAAA,KAAgB;EAGV,iBAAA,IAAA;EAAsB,SAAA,QAAA,EAAA,OAAA;EAK3B,WAAA,CAAA,KAAA,EAAA,SK3BuB,aL2BvB,EAAA,EAAA,IAAA,EK1Ba,aL0Bb;EAKF,IAAA,UAAA,CAAA,CAAA,EAAA,SK1B0B,0BL0B1B,EAAA;EAID,QAAA,CAAA,CAAA,EK1BY,aL0BZ;EAIC,gBAAA,CAAA,CAAA,EAAA,MAAA;;;;iBMnCI,SAAA,QAAiB,cAAc,iBAAiB;;;UCzB/C,mBAAA;;;;;;;;;;;;ATyCjB;;;iBSzBgB,uBAAA,QACP,cAAc,sBACf"}
1
+ {"version":3,"file":"control.d.mts","names":[],"sources":["../src/core/contract-to-schema.ts","../src/core/ddl-formatter.ts","../src/core/filter-evaluator.ts","../src/core/marker-ledger.ts","../src/core/mongo-ops-serializer.ts","../src/core/mongo-planner.ts","../src/core/mongo-runner.ts","../src/core/planner-produced-migration.ts","../src/core/render-ops.ts","../src/core/render-typescript.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;iBAoDgB,uBAAA,WAAkC,uBAAuB;;;iBC6CzD,qBAAA,sBAA2C;;;cC/C9C,eAAA,YAA2B;;mBAGrB,sBAAsB;cAK3B;YAKF;WAID;YAIC;eAIG;cAKD;;;;iBCjDQ,UAAA,KAAe,KAAK,QAAQ;iBAgB5B,UAAA,KAChB;;;IAEH;iBAcmB,YAAA,KAChB;;;IAGH;iBAiBmB,gBAAA,KAChB;;EHlCU,SAAA,IAAA,EAAA,MAAA;;IGoCb;;;iBC8ea,kBAAA,iBAAmC;iBAOnC,mBAAA,4BAA+C;iBAI/C,iBAAA,eAAgC;;;KC7epC,eAAA;;kBACoC;;;sBACI;;cAEvC,qBAAA,YAAiC;;;ILpD9B,SAAA,MAAA,EAAA,OAAuB;qBKwDlB;kCACa,cAAc;MAC1C;EJbU,IAAA,CAAA,OAAA,EAAA;;;qBIiIK;IHhLR,SAAA,QAAgB,EAAA,MAAA;IAGV,SAAA,mBAAA,EG+Ke,aH/Kf,CG+K6B,8BH/K7B,CAAA,OAAA,EAAA,OAAA,CAAA,CAAA;EAAsB,CAAA,CAAA,EGgLnC,sBHhLmC;EAK3B;;;;;;;;;0BGiMY,2BAA2B;;;;UCtNpC,gBAAA;gBACD,QAAQ;;;;MAIlB;;;INUU,SAAA,WAAA,EAAuB,MAAA;MMNlC;;;ILmDW,SAAA,IAAA,EAAA,MAAqB;;MK9C/B;;AJDO,UIII,uBAAA,CJJY;EAGV,SAAA,eAAA,EIES,sBJFT,CIEgC,OJFhC,CAAA,IAAA,CAAA,CAAA;EAAsB,SAAA,kBAAA,EIGV,6BJHU,CIGoB,OJHpB,CIG4B,MJH5B,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,CAAA,CAAA;EAK3B,SAAA,OAAA,EIDM,YJCN;EAKF,SAAA,MAAA,EILO,WJKP;EAID,SAAA,SAAA,EIRW,gBJQX;;AAQI,cIDF,oBAAA,CJCE;EAKD,iBAAA,IAAA;EA9B0B,WAAA,CAAA,IAAA,EIyBH,uBJzBG;EAAkB,OAAA,CAAA,OAAA,EAAA;mBI4BvC;;qBAEE;IHjDC,SAAU,SAAA,CAAA,EAAA;MAAK,gBAAA,EAAA,EAAA,EGmDT,sBHnDS,CAAA,EAAA,IAAA;MAAa,mBAAA,EAAA,EAAA,EGoDnB,sBHpDmB,CAAA,EAAA,IAAA;IAAR,CAAA;IAAO,SAAA,eAAA,CAAA,EGsDlB,8BHtDkB;IAgB3B,SAAU,mBAG7B,EGoC+B,aHpCxB,CGoCsC,8BHpCtC,CAAA,OAAA,EAAA,OAAA,CAAA,CAAA;EAcY,CAAA,CAAA,EGuBhB,OHvBgB,CGuBR,qBHnBX,CAAA;EAiBmB,QAAA,oBAAgB;;;;ECiftB,QAAA,0BAAmC;EAOnC,QAAA,yBAAmB;AAInC;;;;;;;;;;;;AJ7hBA;;;;AC6CA;;;cMzEa,6BAAA,SACH,UAAU,uCACP;ELwBA,iBAAA,KAAgB;EAGV,iBAAA,IAAA;EAAsB,SAAA,QAAA,EAAA,OAAA;EAK3B,WAAA,CAAA,KAAA,EAAA,SK3BuB,aL2BvB,EAAA,EAAA,IAAA,EK1Ba,aL0Bb;EAKF,IAAA,UAAA,CAAA,CAAA,EAAA,SK1B0B,0BL0B1B,EAAA;EAID,QAAA,CAAA,CAAA,EK1BY,aL0BZ;EAIC,gBAAA,CAAA,CAAA,EAAA,MAAA;;;;iBMpEI,SAAA,QAAiB,cAAc,iBAAiB;;;UCC/C,mBAAA;;;;;;;;;;;;ATgDjB;;;;AC6CA;;;;AC/CA;;;AAQc,iBOTE,uBAAA,CPSF,KAAA,EORL,aPQK,CORS,aPQT,CAAA,EAAA,IAAA,EOPN,mBPOM,CAAA,EAAA,MAAA"}
package/dist/control.mjs CHANGED
@@ -4,6 +4,7 @@ import { AggregateCommand, MongoAddFieldsStage, MongoLimitStage, MongoLookupStag
4
4
  import { CollModCommand, CreateCollectionCommand, CreateIndexCommand, DropCollectionCommand, DropIndexCommand, ListCollectionsCommand, ListIndexesCommand, MongoAndExpr, MongoExistsExpr, MongoFieldFilter, MongoNotExpr, MongoOrExpr } from "@prisma-next/mongo-query-ast/control";
5
5
  import { ifDefined } from "@prisma-next/utils/defined";
6
6
  import { type } from "arktype";
7
+ import { TsExpression, jsonToTsSource, renderImports } from "@prisma-next/ts-render";
7
8
  import { Migration } from "@prisma-next/migration-tools/migration";
8
9
  import { detectScaffoldRuntime, shebangLineFor } from "@prisma-next/migration-tools/migration-ts";
9
10
  import { errorRunnerFailed } from "@prisma-next/errors/execution";
@@ -665,7 +666,14 @@ function serializeMongoOps(ops) {
665
666
 
666
667
  //#endregion
667
668
  //#region src/core/op-factory-call.ts
668
- var OpFactoryCallNode = class {
669
+ const TARGET_MIGRATION_MODULE = "@prisma-next/target-mongo/migration";
670
+ var OpFactoryCallNode = class extends TsExpression {
671
+ importRequirements() {
672
+ return [{
673
+ moduleSpecifier: TARGET_MIGRATION_MODULE,
674
+ symbol: this.factoryName
675
+ }];
676
+ }
669
677
  freeze() {
670
678
  Object.freeze(this);
671
679
  }
@@ -674,7 +682,7 @@ function formatKeys(keys) {
674
682
  return keys.map((k) => `${k.field}:${k.direction}`).join(", ");
675
683
  }
676
684
  var CreateIndexCall = class extends OpFactoryCallNode {
677
- factory = "createIndex";
685
+ factoryName = "createIndex";
678
686
  operationClass = "additive";
679
687
  collection;
680
688
  keys;
@@ -688,12 +696,15 @@ var CreateIndexCall = class extends OpFactoryCallNode {
688
696
  this.label = `Create index on ${collection} (${formatKeys(keys)})`;
689
697
  this.freeze();
690
698
  }
691
- accept(visitor) {
692
- return visitor.createIndex(this);
699
+ toOp() {
700
+ return createIndex(this.collection, this.keys, this.options);
701
+ }
702
+ renderTypeScript() {
703
+ return this.options ? `createIndex(${jsonToTsSource(this.collection)}, ${jsonToTsSource(this.keys)}, ${jsonToTsSource(this.options)})` : `createIndex(${jsonToTsSource(this.collection)}, ${jsonToTsSource(this.keys)})`;
693
704
  }
694
705
  };
695
706
  var DropIndexCall = class extends OpFactoryCallNode {
696
- factory = "dropIndex";
707
+ factoryName = "dropIndex";
697
708
  operationClass = "destructive";
698
709
  collection;
699
710
  keys;
@@ -705,12 +716,15 @@ var DropIndexCall = class extends OpFactoryCallNode {
705
716
  this.label = `Drop index on ${collection} (${formatKeys(keys)})`;
706
717
  this.freeze();
707
718
  }
708
- accept(visitor) {
709
- return visitor.dropIndex(this);
719
+ toOp() {
720
+ return dropIndex(this.collection, this.keys);
721
+ }
722
+ renderTypeScript() {
723
+ return `dropIndex(${jsonToTsSource(this.collection)}, ${jsonToTsSource(this.keys)})`;
710
724
  }
711
725
  };
712
726
  var CreateCollectionCall = class extends OpFactoryCallNode {
713
- factory = "createCollection";
727
+ factoryName = "createCollection";
714
728
  operationClass = "additive";
715
729
  collection;
716
730
  options;
@@ -722,12 +736,15 @@ var CreateCollectionCall = class extends OpFactoryCallNode {
722
736
  this.label = `Create collection ${collection}`;
723
737
  this.freeze();
724
738
  }
725
- accept(visitor) {
726
- return visitor.createCollection(this);
739
+ toOp() {
740
+ return createCollection(this.collection, this.options);
741
+ }
742
+ renderTypeScript() {
743
+ return this.options ? `createCollection(${jsonToTsSource(this.collection)}, ${jsonToTsSource(this.options)})` : `createCollection(${jsonToTsSource(this.collection)})`;
727
744
  }
728
745
  };
729
746
  var DropCollectionCall = class extends OpFactoryCallNode {
730
- factory = "dropCollection";
747
+ factoryName = "dropCollection";
731
748
  operationClass = "destructive";
732
749
  collection;
733
750
  label;
@@ -737,12 +754,15 @@ var DropCollectionCall = class extends OpFactoryCallNode {
737
754
  this.label = `Drop collection ${collection}`;
738
755
  this.freeze();
739
756
  }
740
- accept(visitor) {
741
- return visitor.dropCollection(this);
757
+ toOp() {
758
+ return dropCollection(this.collection);
759
+ }
760
+ renderTypeScript() {
761
+ return `dropCollection(${jsonToTsSource(this.collection)})`;
742
762
  }
743
763
  };
744
764
  var CollModCall = class extends OpFactoryCallNode {
745
- factory = "collMod";
765
+ factoryName = "collMod";
746
766
  collection;
747
767
  options;
748
768
  meta;
@@ -757,8 +777,11 @@ var CollModCall = class extends OpFactoryCallNode {
757
777
  this.label = meta?.label ?? `Modify collection ${collection}`;
758
778
  this.freeze();
759
779
  }
760
- accept(visitor) {
761
- return visitor.collMod(this);
780
+ toOp() {
781
+ return collMod(this.collection, this.options, this.meta);
782
+ }
783
+ renderTypeScript() {
784
+ return this.meta ? `collMod(${jsonToTsSource(this.collection)}, ${jsonToTsSource(this.options)}, ${jsonToTsSource(this.meta)})` : `collMod(${jsonToTsSource(this.collection)}, ${jsonToTsSource(this.options)})`;
762
785
  }
763
786
  };
764
787
  function schemaIndexToCreateIndexOptions(index) {
@@ -798,41 +821,55 @@ function schemaCollectionToCreateCollectionOptions(coll) {
798
821
 
799
822
  //#endregion
800
823
  //#region src/core/render-ops.ts
801
- const renderVisitor = {
802
- createIndex(call) {
803
- return createIndex(call.collection, call.keys, call.options);
804
- },
805
- dropIndex(call) {
806
- return dropIndex(call.collection, call.keys);
807
- },
808
- createCollection(call) {
809
- return createCollection(call.collection, call.options);
810
- },
811
- dropCollection(call) {
812
- return dropCollection(call.collection);
813
- },
814
- collMod(call) {
815
- return collMod(call.collection, call.options, call.meta);
816
- }
817
- };
818
824
  function renderOps(calls) {
819
- return calls.map((call) => call.accept(renderVisitor));
825
+ return calls.map((call) => call.toOp());
820
826
  }
821
827
 
822
828
  //#endregion
823
829
  //#region src/core/render-typescript.ts
824
830
  /**
825
- * Render a list of Mongo `OpFactoryCall`s as a class-flow `migration.ts`
831
+ * Always-present base imports for the rendered scaffold:
832
+ *
833
+ * - `Migration` from `@prisma-next/family-mongo/migration` — the
834
+ * user-facing Mongo `Migration` base; subclasses don't need to
835
+ * redeclare `targetId` or thread family/target generics.
836
+ * - `MigrationCLI` from `@prisma-next/cli/migration-cli` — the
837
+ * migration-file CLI entrypoint that loads `prisma-next.config.ts`,
838
+ * assembles a `ControlStack`, and instantiates the migration class.
839
+ * The migration file owns this dependency directly: pulling CLI
840
+ * machinery in at script run time is acceptable because the script's
841
+ * whole purpose is to be invoked from the project that owns the
842
+ * config. (Mirrors the postgres facade pattern; pulling `MigrationCLI`
843
+ * into `@prisma-next/family-mongo/migration` so a Mongo migration only
844
+ * needs one import is tracked separately as a follow-up.)
845
+ */
846
+ const BASE_IMPORTS = [{
847
+ moduleSpecifier: "@prisma-next/family-mongo/migration",
848
+ symbol: "Migration"
849
+ }, {
850
+ moduleSpecifier: "@prisma-next/cli/migration-cli",
851
+ symbol: "MigrationCLI"
852
+ }];
853
+ /**
854
+ * Render a list of Mongo `OpFactoryCall`s as a `migration.ts`
826
855
  * source string. The result is shebanged, extends the user-facing
827
856
  * `Migration` (i.e. `MongoMigration`) from `@prisma-next/family-mongo`, and
828
857
  * implements the abstract `operations` and `describe` members. `meta` is
829
858
  * always rendered — `describe()` is part of the `Migration` contract, so
830
859
  * even an empty stub must satisfy it; callers pass empty strings for a
831
860
  * migration-new scaffold.
861
+ *
862
+ * The walk is polymorphic: each call node contributes its own
863
+ * `renderTypeScript()` expression and declares its own
864
+ * `importRequirements()`. The top-level renderer aggregates imports
865
+ * across all nodes and emits one `import { … } from "…"` line per module.
866
+ * The `Migration` and `MigrationCLI` imports are always emitted — they're
867
+ * structural to the rendered scaffold (extends `Migration`, calls
868
+ * `MigrationCLI.run`), not driven by any node.
832
869
  */
833
870
  function renderCallsToTypeScript(calls, meta) {
834
- const imports = buildImports(collectFactoryNames(calls));
835
- const operationsBody = calls.map((c) => c.accept(renderCallVisitor)).join(",\n");
871
+ const imports = buildImports(calls);
872
+ const operationsBody = calls.map((c) => c.renderTypeScript()).join(",\n");
836
873
  return [
837
874
  shebangLineFor(detectScaffoldRuntime()),
838
875
  imports,
@@ -847,19 +884,14 @@ function renderCallsToTypeScript(calls, meta) {
847
884
  "}",
848
885
  "",
849
886
  "export default M;",
850
- "Migration.run(import.meta.url, M);",
887
+ "MigrationCLI.run(import.meta.url, M);",
851
888
  ""
852
889
  ].join("\n");
853
890
  }
854
- function collectFactoryNames(calls) {
855
- const names = /* @__PURE__ */ new Set();
856
- for (const call of calls) names.add(call.factory);
857
- return [...names].sort();
858
- }
859
- function buildImports(factoryNames) {
860
- const lines = ["import { Migration } from '@prisma-next/family-mongo/migration';"];
861
- if (factoryNames.length > 0) lines.push(`import { ${factoryNames.join(", ")} } from '@prisma-next/target-mongo/migration';`);
862
- return lines.join("\n");
891
+ function buildImports(calls) {
892
+ const requirements = [...BASE_IMPORTS];
893
+ for (const call of calls) for (const req of call.importRequirements()) requirements.push(req);
894
+ return renderImports(requirements);
863
895
  }
864
896
  function buildDescribeMethod(meta) {
865
897
  const lines = [];
@@ -868,55 +900,12 @@ function buildDescribeMethod(meta) {
868
900
  lines.push(` from: ${JSON.stringify(meta.from)},`);
869
901
  lines.push(` to: ${JSON.stringify(meta.to)},`);
870
902
  if (meta.kind) lines.push(` kind: ${JSON.stringify(meta.kind)},`);
871
- if (meta.labels && meta.labels.length > 0) lines.push(` labels: ${renderLiteral(meta.labels)},`);
903
+ if (meta.labels && meta.labels.length > 0) lines.push(` labels: ${jsonToTsSource(meta.labels)},`);
872
904
  lines.push(" };");
873
905
  lines.push(" }");
874
906
  lines.push("");
875
907
  return lines.join("\n");
876
908
  }
877
- const renderCallVisitor = {
878
- createIndex(call) {
879
- return call.options ? `createIndex(${renderLiteral(call.collection)}, ${renderLiteral(call.keys)}, ${renderLiteral(call.options)})` : `createIndex(${renderLiteral(call.collection)}, ${renderLiteral(call.keys)})`;
880
- },
881
- dropIndex(call) {
882
- return `dropIndex(${renderLiteral(call.collection)}, ${renderLiteral(call.keys)})`;
883
- },
884
- createCollection(call) {
885
- return call.options ? `createCollection(${renderLiteral(call.collection)}, ${renderLiteral(call.options)})` : `createCollection(${renderLiteral(call.collection)})`;
886
- },
887
- dropCollection(call) {
888
- return `dropCollection(${renderLiteral(call.collection)})`;
889
- },
890
- collMod(call) {
891
- return call.meta ? `collMod(${renderLiteral(call.collection)}, ${renderLiteral(call.options)}, ${renderLiteral(call.meta)})` : `collMod(${renderLiteral(call.collection)}, ${renderLiteral(call.options)})`;
892
- }
893
- };
894
- function renderLiteral(value) {
895
- if (value === void 0) return "undefined";
896
- if (value === null) return "null";
897
- if (typeof value === "string") return JSON.stringify(value);
898
- if (typeof value === "number" || typeof value === "boolean") return String(value);
899
- if (Array.isArray(value)) {
900
- if (value.length === 0) return "[]";
901
- const items = value.map((v) => renderLiteral(v));
902
- const singleLine = `[${items.join(", ")}]`;
903
- if (singleLine.length <= 80) return singleLine;
904
- return `[\n${items.map((i) => ` ${i}`).join(",\n")},\n]`;
905
- }
906
- if (typeof value === "object") {
907
- const entries = Object.entries(value).filter(([, v]) => v !== void 0);
908
- if (entries.length === 0) return "{}";
909
- const items = entries.map(([k, v]) => `${renderKey(k)}: ${renderLiteral(v)}`);
910
- const singleLine = `{ ${items.join(", ")} }`;
911
- if (singleLine.length <= 80) return singleLine;
912
- return `{\n${items.map((i) => ` ${i}`).join(",\n")},\n}`;
913
- }
914
- return String(value);
915
- }
916
- function renderKey(key) {
917
- if (key === "__proto__") return JSON.stringify(key);
918
- return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? key : JSON.stringify(key);
919
- }
920
909
  function indent(text, spaces) {
921
910
  const pad = " ".repeat(spaces);
922
911
  return text.split("\n").map((line) => line.trim() ? `${pad}${line}` : line).join("\n");
@@ -1087,12 +1076,11 @@ var MongoMigrationPlanner = class {
1087
1076
  /**
1088
1077
  * Produce an empty `migration.ts` authoring surface for `migration new`.
1089
1078
  *
1090
- * Mongo is a class-flow target, so the "empty migration" is a
1091
- * `PlannerProducedMongoMigration` with no operations; `renderTypeScript()`
1092
- * emits a stub class with the correct `from`/`to` metadata that the user
1093
- * then fills in with operations. The contract path on the context is
1094
- * unused — Mongo's emitted source does not import from the generated
1095
- * contract `.d.ts`.
1079
+ * The "empty migration" is a `PlannerProducedMongoMigration` with no
1080
+ * operations; `renderTypeScript()` emits a stub class with the correct
1081
+ * `from`/`to` metadata that the user then fills in with operations. The
1082
+ * contract path on the context is unused Mongo's emitted source does
1083
+ * not import from the generated contract `.d.ts`.
1096
1084
  */
1097
1085
  emptyMigration(context) {
1098
1086
  return new PlannerProducedMongoMigration([], {