arkormx 2.10.2 → 2.11.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/dist/cli.mjs CHANGED
@@ -363,6 +363,419 @@ var PrimaryKeyGenerationPlanner = class {
363
363
  }
364
364
  };
365
365
 
366
+ //#endregion
367
+ //#region src/Expression.ts
368
+ /**
369
+ * A composable SQL expression. Instances are immutable — every operator returns a
370
+ * new expression — and are accepted by `select`, `where`, `groupBy`, `orderBy`,
371
+ * `having`, and the aggregate helpers. Adapters compile the underlying node tree.
372
+ */
373
+ var Expression = class Expression {
374
+ /**
375
+ * Type guard for values that came out of the expression builder.
376
+ */
377
+ static isExpression(value) {
378
+ return value instanceof Expression;
379
+ }
380
+ eq(value) {
381
+ return binary("=", this, coerceValue(value));
382
+ }
383
+ ne(value) {
384
+ return binary("!=", this, coerceValue(value));
385
+ }
386
+ gt(value) {
387
+ return binary(">", this, coerceValue(value));
388
+ }
389
+ gte(value) {
390
+ return binary(">=", this, coerceValue(value));
391
+ }
392
+ lt(value) {
393
+ return binary("<", this, coerceValue(value));
394
+ }
395
+ lte(value) {
396
+ return binary("<=", this, coerceValue(value));
397
+ }
398
+ like(value) {
399
+ return binary("like", this, coerceValue(value));
400
+ }
401
+ ilike(value) {
402
+ return binary("ilike", this, coerceValue(value));
403
+ }
404
+ notLike(value) {
405
+ return binary("not-like", this, coerceValue(value));
406
+ }
407
+ notIlike(value) {
408
+ return binary("not-ilike", this, coerceValue(value));
409
+ }
410
+ in(values) {
411
+ return new NodeExpression({
412
+ kind: "in",
413
+ operand: this.toExpressionNode(),
414
+ values: values.map((value) => coerceValue(value).toExpressionNode()),
415
+ not: false
416
+ });
417
+ }
418
+ notIn(values) {
419
+ return new NodeExpression({
420
+ kind: "in",
421
+ operand: this.toExpressionNode(),
422
+ values: values.map((value) => coerceValue(value).toExpressionNode()),
423
+ not: true
424
+ });
425
+ }
426
+ isNull() {
427
+ return new NodeExpression({
428
+ kind: "null-check",
429
+ operand: this.toExpressionNode(),
430
+ not: false
431
+ });
432
+ }
433
+ isNotNull() {
434
+ return new NodeExpression({
435
+ kind: "null-check",
436
+ operand: this.toExpressionNode(),
437
+ not: true
438
+ });
439
+ }
440
+ and(other) {
441
+ return binary("and", this, other);
442
+ }
443
+ or(other) {
444
+ return binary("or", this, other);
445
+ }
446
+ plus(value) {
447
+ return binary("+", this, coerceValue(value));
448
+ }
449
+ minus(value) {
450
+ return binary("-", this, coerceValue(value));
451
+ }
452
+ times(value) {
453
+ return binary("*", this, coerceValue(value));
454
+ }
455
+ dividedBy(value) {
456
+ return binary("/", this, coerceValue(value));
457
+ }
458
+ };
459
+ /**
460
+ * Concrete expression backed by a pre-built node.
461
+ */
462
+ var NodeExpression = class extends Expression {
463
+ constructor(node) {
464
+ super();
465
+ this.node = node;
466
+ }
467
+ toExpressionNode() {
468
+ return this.node;
469
+ }
470
+ };
471
+ /**
472
+ * Fluent `CASE … WHEN … THEN … ELSE … END` builder. Immutable.
473
+ */
474
+ var CaseExpression = class CaseExpression extends Expression {
475
+ constructor(branches, elseExpr) {
476
+ super();
477
+ this.branches = branches;
478
+ this.elseExpr = elseExpr;
479
+ }
480
+ when(condition, result) {
481
+ return new CaseExpression([...this.branches, {
482
+ when: condition,
483
+ then: coerceValue(result)
484
+ }], this.elseExpr);
485
+ }
486
+ else(result) {
487
+ return new CaseExpression(this.branches, coerceValue(result));
488
+ }
489
+ toExpressionNode() {
490
+ return {
491
+ kind: "case",
492
+ cases: this.branches.map((branch) => ({
493
+ when: branch.when.toExpressionNode(),
494
+ then: branch.then.toExpressionNode()
495
+ })),
496
+ else: this.elseExpr?.toExpressionNode()
497
+ };
498
+ }
499
+ };
500
+ /**
501
+ * JSON-path value extraction (`metadata ->> 'billType'`), with optional casts.
502
+ */
503
+ var JsonExpression = class JsonExpression extends Expression {
504
+ constructor(column, path, castTo) {
505
+ super();
506
+ this.column = column;
507
+ this.path = path;
508
+ this.castTo = castTo;
509
+ }
510
+ asText() {
511
+ return new JsonExpression(this.column, this.path, "text");
512
+ }
513
+ asNumber() {
514
+ return new JsonExpression(this.column, this.path, "number");
515
+ }
516
+ asBoolean() {
517
+ return new JsonExpression(this.column, this.path, "boolean");
518
+ }
519
+ toExpressionNode() {
520
+ return {
521
+ kind: "json",
522
+ column: this.column,
523
+ path: this.path,
524
+ cast: this.castTo
525
+ };
526
+ }
527
+ };
528
+ /**
529
+ * Aggregate expression (`sum`, `count`, `avg`, `min`, `max`) with optional filter.
530
+ */
531
+ var AggregateExpression = class AggregateExpression extends Expression {
532
+ constructor(fn, arg, options = {}) {
533
+ super();
534
+ this.fn = fn;
535
+ this.arg = arg;
536
+ this.options = options;
537
+ }
538
+ /**
539
+ * Restricts the aggregate to rows matching `predicate` (`FILTER (WHERE …)`).
540
+ */
541
+ filter(predicate) {
542
+ return new AggregateExpression(this.fn, this.arg, {
543
+ ...this.options,
544
+ filterExpr: predicate
545
+ });
546
+ }
547
+ distinct() {
548
+ return new AggregateExpression(this.fn, this.arg, {
549
+ ...this.options,
550
+ distinct: true
551
+ });
552
+ }
553
+ toExpressionNode() {
554
+ return {
555
+ kind: "aggregate",
556
+ fn: this.fn,
557
+ arg: this.arg?.toExpressionNode(),
558
+ distinct: this.options.distinct,
559
+ filter: this.options.filterExpr?.toExpressionNode()
560
+ };
561
+ }
562
+ };
563
+ const binary = (operator, left, right) => new NodeExpression({
564
+ kind: "binary",
565
+ operator,
566
+ left: left.toExpressionNode(),
567
+ right: right.toExpressionNode()
568
+ });
569
+ /**
570
+ * Coerces a raw value into a bound-literal expression; passes expressions through.
571
+ */
572
+ const coerceValue = (value) => {
573
+ if (value instanceof Expression) return value;
574
+ return new NodeExpression({
575
+ kind: "value",
576
+ value
577
+ });
578
+ };
579
+ /**
580
+ * Coerces a bare string into a column reference; passes expressions through.
581
+ */
582
+ const coerceColumn = (value) => {
583
+ if (value instanceof Expression) return value;
584
+ if (typeof value === "string") return col(value);
585
+ return coerceValue(value);
586
+ };
587
+ /**
588
+ * A typed column reference. Supports joined `table.column` syntax.
589
+ */
590
+ const col = (name) => new NodeExpression({
591
+ kind: "column",
592
+ name
593
+ });
594
+ /**
595
+ * A bound literal value (parameterized, never interpolated).
596
+ */
597
+ const val = (value) => new NodeExpression({
598
+ kind: "value",
599
+ value
600
+ });
601
+ /**
602
+ * Raw SQL escape hatch with positional `?` bindings.
603
+ */
604
+ const raw = (sql, bindings = []) => new NodeExpression({
605
+ kind: "raw",
606
+ sql,
607
+ bindings
608
+ });
609
+ /**
610
+ * Starts a `CASE WHEN condition THEN result` expression.
611
+ */
612
+ const caseWhen = (condition, result) => new CaseExpression([{
613
+ when: condition,
614
+ then: coerceValue(result)
615
+ }]);
616
+ /**
617
+ * `COALESCE(a, b, …)` — first non-null argument. Bare strings are columns.
618
+ */
619
+ const coalesce = (...args) => new NodeExpression({
620
+ kind: "function",
621
+ name: "coalesce",
622
+ args: args.map((arg) => coerceColumn(arg).toExpressionNode())
623
+ });
624
+ /**
625
+ * An arbitrary SQL function call. Bare-string arguments are treated as columns.
626
+ */
627
+ const fn = (name, ...args) => new NodeExpression({
628
+ kind: "function",
629
+ name,
630
+ args: args.map((arg) => coerceColumn(arg).toExpressionNode())
631
+ });
632
+ /**
633
+ * JSON value extraction: `json('metadata', 'billType')` => `metadata ->> 'billType'`.
634
+ */
635
+ const json = (column, ...path) => new JsonExpression(column, path.map(String));
636
+ /**
637
+ * `SUM(expr)`; a bare-string argument is treated as a column.
638
+ */
639
+ const sum = (arg) => new AggregateExpression("sum", coerceColumn(arg));
640
+ /**
641
+ * `AVG(expr)`; a bare-string argument is treated as a column.
642
+ */
643
+ const avg = (arg) => new AggregateExpression("avg", coerceColumn(arg));
644
+ /**
645
+ * `MIN(expr)`; a bare-string argument is treated as a column.
646
+ */
647
+ const min = (arg) => new AggregateExpression("min", coerceColumn(arg));
648
+ /**
649
+ * `MAX(expr)`; a bare-string argument is treated as a column.
650
+ */
651
+ const max = (arg) => new AggregateExpression("max", coerceColumn(arg));
652
+ /**
653
+ * `COUNT(expr)` — or `COUNT(*)` when called without an argument.
654
+ */
655
+ const count = (arg) => new AggregateExpression("count", arg === void 0 ? void 0 : coerceColumn(arg));
656
+ const EXPRESSION_OPERATORS = {
657
+ "=": "=",
658
+ "==": "=",
659
+ "!=": "!=",
660
+ "<>": "!=",
661
+ ">": ">",
662
+ ">=": ">=",
663
+ "<": "<",
664
+ "<=": "<=",
665
+ like: "like",
666
+ ilike: "ilike",
667
+ "not like": "not-like",
668
+ "not ilike": "not-ilike"
669
+ };
670
+ /**
671
+ * Builds a comparison predicate: `where('createdAt', '>=', boundary)`. Handy as an
672
+ * inline predicate for `caseWhen`, `having`, and aggregate `.filter(…)`.
673
+ */
674
+ const where = (column, operator, value) => {
675
+ const normalized = EXPRESSION_OPERATORS[operator];
676
+ if (!normalized) throw new Error(`Unsupported expression operator [${operator}].`);
677
+ return binary(normalized, col(column), coerceValue(value));
678
+ };
679
+ /**
680
+ * The expression-builder namespace passed to `static computed` factories, so a
681
+ * model can declare a virtual attribute as `category: (e) => e.coalesce(…)`.
682
+ */
683
+ const expressionBuilder = {
684
+ col,
685
+ val,
686
+ raw,
687
+ caseWhen,
688
+ coalesce,
689
+ fn,
690
+ json,
691
+ sum,
692
+ avg,
693
+ min,
694
+ max,
695
+ count,
696
+ where
697
+ };
698
+
699
+ //#endregion
700
+ //#region src/helpers/generated-column.ts
701
+ /**
702
+ * Resolves a generated-column expression into raw Postgres SQL. Generated columns
703
+ * cannot carry bind parameters (they must be immutable), so literal values are
704
+ * inlined and aggregates are rejected.
705
+ */
706
+ const resolveGeneratedExpression = (expression) => {
707
+ if (typeof expression === "string") return expression;
708
+ return expressionNodeToSql(expression(expressionBuilder).toExpressionNode());
709
+ };
710
+ const quoteIdentifier = (name) => name.split(".").map((part) => `"${part.replace(/"/g, "\"\"")}"`).join(".");
711
+ const quoteLiteral = (value) => {
712
+ if (value === null || value === void 0) return "null";
713
+ if (typeof value === "number" || typeof value === "bigint") return String(value);
714
+ if (typeof value === "boolean") return value ? "true" : "false";
715
+ if (value instanceof Date) return `'${value.toISOString()}'`;
716
+ return `'${String(value).replace(/'/g, "''")}'`;
717
+ };
718
+ const BINARY_OPERATORS = {
719
+ "=": "=",
720
+ "!=": "!=",
721
+ ">": ">",
722
+ ">=": ">=",
723
+ "<": "<",
724
+ "<=": "<=",
725
+ like: "like",
726
+ ilike: "ilike",
727
+ "not-like": "not like",
728
+ "not-ilike": "not ilike",
729
+ and: "and",
730
+ or: "or",
731
+ "+": "+",
732
+ "-": "-",
733
+ "*": "*",
734
+ "/": "/"
735
+ };
736
+ const FUNCTION_NAME = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
737
+ const jsonAccessorSql = (node) => {
738
+ const base = `${quoteIdentifier(node.column)}::jsonb`;
739
+ let accessor;
740
+ if (node.path.length === 0) accessor = base;
741
+ else if (node.path.length === 1) accessor = `(${base} ->> ${quoteLiteral(node.path[0])})`;
742
+ else accessor = `(${base} #>> '{${node.path.join(",")}}'::text[])`;
743
+ if (node.cast === "number") return `(${accessor})::numeric`;
744
+ if (node.cast === "boolean") return `(${accessor})::boolean`;
745
+ return accessor;
746
+ };
747
+ const expressionNodeToSql = (node) => {
748
+ switch (node.kind) {
749
+ case "column": return quoteIdentifier(node.name);
750
+ case "value": return quoteLiteral(node.value);
751
+ case "raw": return inlineRawSql(node.sql, node.bindings);
752
+ case "json": return jsonAccessorSql(node);
753
+ case "function":
754
+ if (!FUNCTION_NAME.test(node.name)) throw new ArkormException(`Unsupported SQL function name [${node.name}].`);
755
+ return `${node.name}(${node.args.map(expressionNodeToSql).join(", ")})`;
756
+ case "case": return `case ${node.cases.map((branch) => `when ${expressionNodeToSql(branch.when)} then ${expressionNodeToSql(branch.then)}`).join(" ")}${node.else ? ` else ${expressionNodeToSql(node.else)}` : ""} end`;
757
+ case "binary": {
758
+ const operator = BINARY_OPERATORS[node.operator];
759
+ return `(${expressionNodeToSql(node.left)} ${operator} ${expressionNodeToSql(node.right)})`;
760
+ }
761
+ case "in": {
762
+ const values = node.values.map(expressionNodeToSql).join(", ");
763
+ return `(${expressionNodeToSql(node.operand)} ${node.not ? "not in" : "in"} (${values}))`;
764
+ }
765
+ case "null-check": return `(${expressionNodeToSql(node.operand)} is ${node.not ? "not null" : "null"})`;
766
+ case "aggregate": throw new ArkormException("Aggregate expressions are not allowed in generated columns.");
767
+ default: throw new ArkormException(`Unsupported expression node [${node.kind}].`);
768
+ }
769
+ };
770
+ const inlineRawSql = (sql, bindings) => {
771
+ const segments = sql.split("?");
772
+ if (segments.length !== bindings.length + 1) throw new ArkormException("Raw expression bindings do not match the number of placeholders.");
773
+ return segments.reduce((accumulator, segment, index) => {
774
+ const binding = index < bindings.length ? quoteLiteral(bindings[index]) : "";
775
+ return accumulator + segment + binding;
776
+ }, "");
777
+ };
778
+
366
779
  //#endregion
367
780
  //#region src/database/TableBuilder.ts
368
781
  const PRISMA_ENUM_MEMBER_REGEX$1 = /^[A-Za-z][A-Za-z0-9_]*$/;
@@ -666,6 +1079,30 @@ var TableBuilder = class {
666
1079
  return this.column(name, "dateTime", options);
667
1080
  }
668
1081
  /**
1082
+ * Defines a database-computed column (`GENERATED ALWAYS AS (…) STORED`). The
1083
+ * expression may be a raw SQL string or an expression-builder factory, and must
1084
+ * be immutable and reference only the row's own columns. Combine with
1085
+ * {@link index} to index the generated value.
1086
+ *
1087
+ * @example
1088
+ * table.generated('category', "case when metadata->>'kind' = 'a' then 'x' else 'y' end", {
1089
+ * type: 'text',
1090
+ * })
1091
+ * table.generated('total', (e) => e.col('price').times(e.col('quantity')), { type: 'integer' })
1092
+ *
1093
+ * @param name The generated column name.
1094
+ * @param expression The SQL expression string, or a builder factory.
1095
+ * @param options Column type (default `text`), `stored` flag, and nullability.
1096
+ * @returns
1097
+ */
1098
+ generated(name, expression, options = {}) {
1099
+ return this.column(name, options.type ?? "text", {
1100
+ generatedExpression: resolveGeneratedExpression(expression),
1101
+ generatedStored: options.stored ?? true,
1102
+ nullable: options.nullable
1103
+ });
1104
+ }
1105
+ /**
669
1106
  * Defines colonns for a polymorphic relationship in the table.
670
1107
  *
671
1108
  * @param name The base name for the polymorphic relationship columns.
@@ -1001,6 +1438,8 @@ var TableBuilder = class {
1001
1438
  updatedAt: options.updatedAt,
1002
1439
  precision: options.precision,
1003
1440
  scale: options.scale,
1441
+ generatedExpression: options.generatedExpression,
1442
+ generatedStored: options.generatedStored,
1004
1443
  primaryKeyGeneration: options.primaryKeyGeneration
1005
1444
  });
1006
1445
  const column = this.columns[this.columns.length - 1];
@@ -1384,6 +1823,10 @@ const buildFieldLine = (column) => {
1384
1823
  const mapped = typeof column.map === "string" && column.map.trim().length > 0 ? ` @map("${column.map.replace(/"/g, "\\\"")}")` : "";
1385
1824
  const updatedAt = column.updatedAt ? " @updatedAt" : "";
1386
1825
  const nativeType = column.type === "decimal" ? ` @db.Decimal(${column.precision ?? 8}, ${column.scale ?? 2})` : "";
1826
+ if (column.generatedExpression) {
1827
+ const escaped = column.generatedExpression.replace(/\\/g, "\\\\").replace(/"/g, "\\\"");
1828
+ return ` ${column.name} ${scalar}${nullable}${unique} @default(dbgenerated("${escaped}"))${mapped}${nativeType}`;
1829
+ }
1387
1830
  const defaultValue = column.type === "enum" ? formatEnumDefaultValue(column.default) : column.primaryKeyGeneration?.prismaDefault ?? formatDefaultValue(column.default);
1388
1831
  const defaultSuffix = defaultValue ? ` ${defaultValue}` : "";
1389
1832
  return ` ${column.name} ${scalar}${nullable}${primary}${unique}${defaultSuffix}${updatedAt}${mapped}${nativeType}`;
@@ -2816,6 +3259,7 @@ var PrismaDatabaseAdapter = class PrismaDatabaseAdapter {
2816
3259
  rawWhere: false,
2817
3260
  distinct: false,
2818
3261
  groupBy: false,
3262
+ expressions: false,
2819
3263
  returning: false
2820
3264
  };
2821
3265
  }
@@ -2851,6 +3295,14 @@ var PrismaDatabaseAdapter = class PrismaDatabaseAdapter {
2851
3295
  }
2852
3296
  toQuerySelect(columns) {
2853
3297
  if (!columns || columns.length === 0) return void 0;
3298
+ const expressionColumn = columns.find((column) => column.expression);
3299
+ if (expressionColumn) throw new UnsupportedAdapterFeatureException("Expression select columns are not supported by the Prisma compatibility adapter; use a SQL-backed adapter.", {
3300
+ operation: "adapter.select",
3301
+ meta: {
3302
+ feature: "expressions",
3303
+ alias: expressionColumn.alias
3304
+ }
3305
+ });
2854
3306
  const rawColumn = columns.find((column) => column.raw);
2855
3307
  if (rawColumn) throw new UnsupportedAdapterFeatureException("Raw select expressions are not supported by the Prisma compatibility adapter; use a SQL-backed adapter or DB.raw().", {
2856
3308
  operation: "adapter.select",
@@ -2868,6 +3320,10 @@ var PrismaDatabaseAdapter = class PrismaDatabaseAdapter {
2868
3320
  }
2869
3321
  toQueryOrderBy(orderBy) {
2870
3322
  if (!orderBy || orderBy.length === 0) return void 0;
3323
+ if (orderBy.some((entry) => entry.expression)) throw new UnsupportedAdapterFeatureException("Order-by expressions are not supported by the Prisma compatibility adapter; use a SQL-backed adapter.", {
3324
+ operation: "adapter.select",
3325
+ meta: { feature: "expressions" }
3326
+ });
2871
3327
  return orderBy.map((entry) => ({ [entry.column]: entry.direction }));
2872
3328
  }
2873
3329
  toComparisonWhere(condition) {
@@ -4242,7 +4698,8 @@ var Migration = class {
4242
4698
  //#region src/cli/commands/MigrateCommand.ts
4243
4699
  /**
4244
4700
  * The MigrateCommand class implements the CLI command for applying migration
4245
- * classes to the Prisma schema and running the Prisma workflow.
4701
+ * classes to the database or Prisma schema and running the Prisma workflow when
4702
+ * using the Prisma compatibility driver.
4246
4703
  *
4247
4704
  * @author Legacy (3m1n3nc3)
4248
4705
  * @since 0.1.0
@@ -4253,22 +4710,22 @@ var MigrateCommand = class extends Command {
4253
4710
  this.signature = `migrate
4254
4711
  {name? : Migration class or file name}
4255
4712
  {--all : Run all migrations from the configured migrations directory}
4256
- {--deploy : Use prisma migrate deploy instead of migrate dev}
4257
- {--skip-generate : Skip prisma generate}
4713
+ {--deploy : Use prisma migrate deploy instead of migrate dev (Prisma compatibility driver only)}
4714
+ {--skip-generate : Skip prisma generate (Prisma compatibility driver only)}
4258
4715
  {--skip-migrate : Skip prisma migrate command}
4259
4716
  {--state-file= : Path to applied migration state file}
4260
- {--schema= : Explicit prisma schema path}
4261
- {--migration-name= : Name for prisma migrate dev}
4717
+ {--schema= : Explicit prisma schema path (Prisma compatibility driver only)}
4718
+ {--migration-name= : Name for prisma migrate dev (Prisma compatibility driver only)}
4262
4719
  {--create-database : Create the configured database without prompting}
4263
4720
  `;
4264
- this.description = "Apply migration classes to schema.prisma and run Prisma workflow";
4721
+ this.description = "Apply migration classes to the database or schema.prisma and run Prisma workflow when using the Prisma compatibility driver";
4265
4722
  }
4266
4723
  /**
4267
4724
  * Command handler for the migrate command.
4268
4725
  * This method is responsible for orchestrating the migration
4269
4726
  * process, including loading migration classes, applying them to
4270
- * the Prisma schema, and running the appropriate Prisma commands
4271
- * based on the provided options.
4727
+ * the the database or Prisma schema, and running the appropriate Prisma commands
4728
+ * when using the Prisma compatibility driver based on the provided options.
4272
4729
  *
4273
4730
  * @returns
4274
4731
  */
@@ -4477,10 +4934,10 @@ var MigrateFreshCommand = class extends Command {
4477
4934
  constructor(..._args) {
4478
4935
  super(..._args);
4479
4936
  this.signature = `migrate:fresh
4480
- {--skip-generate : Skip prisma generate}
4481
- {--skip-migrate : Skip prisma database sync}
4937
+ {--skip-generate : Skip prisma generate (Prisma compatibility driver only)}
4938
+ {--skip-migrate : Skip prisma database sync (Prisma compatibility driver only)}
4482
4939
  {--state-file= : Path to applied migration state file}
4483
- {--schema= : Explicit prisma schema path}
4940
+ {--schema= : Explicit prisma schema path (Prisma compatibility driver only)}
4484
4941
  {--create-database : Create the configured database without prompting}
4485
4942
  `;
4486
4943
  this.description = "Reset the database and rerun all migration classes";
@@ -4635,12 +5092,12 @@ var MigrateRollbackCommand = class extends Command {
4635
5092
  this.signature = `migrate:rollback
4636
5093
  {--step= : Number of latest applied migration classes to rollback}
4637
5094
  {--dry-run : Preview rollback targets without applying changes}
4638
- {--deploy : Use prisma migrate deploy instead of migrate dev}
4639
- {--skip-generate : Skip prisma generate}
4640
- {--skip-migrate : Skip prisma migrate command}
5095
+ {--deploy : Use prisma migrate deploy instead of migrate dev (Prisma compatibility driver only)}
5096
+ {--skip-generate : Skip prisma generate (Prisma compatibility driver only)}
5097
+ {--skip-migrate : Skip prisma migrate command (Prisma compatibility driver only)}
4641
5098
  {--state-file= : Path to applied migration state file}
4642
- {--schema= : Explicit prisma schema path}
4643
- {--migration-name= : Name for prisma migrate dev}
5099
+ {--schema= : Explicit prisma schema path (Prisma compatibility driver only)}
5100
+ {--migration-name= : Name for prisma migrate dev (Prisma compatibility driver only)}
4644
5101
  `;
4645
5102
  this.description = "Rollback migration classes from schema.prisma and run Prisma workflow";
4646
5103
  }
@@ -4655,7 +5112,7 @@ var MigrateRollbackCommand = class extends Command {
4655
5112
  const useDatabaseMigrations = supportsDatabaseMigrationExecution(adapter);
4656
5113
  const persistedFeatures = resolvePersistedMetadataFeatures(this.app.getConfig("features"));
4657
5114
  let appliedState = await readAppliedMigrationsStateFromStore(adapter, stateFilePath);
4658
- const stepOption = this.option("step");
5115
+ const stepOption = this.option("step", 1);
4659
5116
  const stepCount = stepOption == null ? void 0 : Number(stepOption);
4660
5117
  if (stepCount != null && (!Number.isFinite(stepCount) || stepCount <= 0 || !Number.isInteger(stepCount))) return void this.error("Error: --step must be a positive integer.");
4661
5118
  const targets = stepCount ? getLatestAppliedMigrations(appliedState, stepCount) : (() => {