@remix-run/data-table 0.4.0 → 0.5.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
@@ -11,7 +11,7 @@ Typed relational query toolkit for JavaScript runtimes.
11
11
  - **Relation-First Queries**: `hasMany`, `hasOne`, `belongsTo`, `hasManyThrough`, and nested eager loading
12
12
  - **Safe Scoped Writes**: `update`/`delete` with `orderBy`/`limit` run safely in a transaction
13
13
  - **First-Class Migrations**: Plain SQL `up.sql`/`down.sql` files with a journaling runner and dry-run planning
14
- - **Database Lifecycle Commands**: Wipe, migrate, inspect, seed, and reset through `remix db`
14
+ - **Database Lifecycle Commands**: Wipe, migrate, rollback, inspect, seed, and reset through `remix db`
15
15
  - **Raw SQL Escape Hatch**: Execute SQL directly with `db.exec(sql\`...\`)`
16
16
 
17
17
  `data-table` gives you two complementary APIs:
@@ -409,7 +409,7 @@ environment variable at command runtime, and paths are resolved relative to `rem
409
409
 
410
410
  ```jsonc
411
411
  {
412
- "$schema": "https://remix.run/schemas/remix.json",
412
+ "$schema": "./node_modules/remix/schema/remix.json",
413
413
  "db": {
414
414
  "adapter": {
415
415
  "type": "postgres",
@@ -433,12 +433,16 @@ Run lifecycle commands through the Remix CLI:
433
433
  remix db status
434
434
  remix db migrate
435
435
  remix db migrate --to 20260301113000_add_user_status
436
+ remix db rollback
437
+ remix db rollback --step 2
438
+ remix db rollback --to 20260301113000_add_user_status
439
+ remix db rollback --dry-run
436
440
  remix db seed
437
- remix db reset
438
- remix db wipe
441
+ remix db reset --force
442
+ remix db wipe --force
439
443
  ```
440
444
 
441
- `--to` accepts a bare migration id (`20260301113000`) or the full directory name (`20260301113000_add_user_status`).
445
+ `rollback` reverts the most recently applied migration by default. Bound it with either `--step <count>` or `--to <migration>`, which reverts through the target migration inclusively. Migration targets accept a bare migration id (`20260301113000`) or the full directory name (`20260301113000_add_user_status`). Use `--dry-run` to report what would be reverted without changing the database.
442
446
 
443
447
  `remix db status` reports applied migrations whose files are no longer present as `missing`. If the journal table does not exist, it reports every migration as pending without creating the table. Forward migration runs stop before executing SQL when an applied journal entry is missing from the current migration set. Rollbacks skip those orphaned journal entries so migrations that are still present can be reverted.
444
448
 
@@ -473,6 +477,15 @@ for (let script of plan.sql) console.log(script)
473
477
 
474
478
  `to` and `step` are mutually exclusive. Omit `journalTable` to use `data_table_migrations`.
475
479
 
480
+ Hosts that embed the database CLI can invoke the same rollback behavior through `runRemixDb()`:
481
+
482
+ ```ts
483
+ import { runRemixDb } from 'remix/data-table/cli'
484
+
485
+ await runRemixDb({ command: 'rollback', db, migrations })
486
+ await runRemixDb({ command: 'rollback', db, migrations, step: 2, dryRun: true })
487
+ ```
488
+
476
489
  Database drivers with migration locking run the complete migration and journal lifecycle through the
477
490
  connection that owns the lock. This keeps advisory locks correctly paired when the driver uses a
478
491
  connection pool, including pools configured with a single connection.
package/dist/cli.d.ts CHANGED
@@ -4,6 +4,28 @@ interface DatabaseCommandOptions {
4
4
  /** Database instance used by the command. */
5
5
  db: Database;
6
6
  }
7
+ type RollbackBoundOptions = {
8
+ /**
9
+ * Reverts back through this migration, inclusive. Accepts a bare
10
+ * migration id or the full `id_name` directory form.
11
+ */
12
+ to: string;
13
+ step?: never;
14
+ } | {
15
+ to?: never;
16
+ /** Reverts this many migrations. Defaults to `1`. */
17
+ step?: number;
18
+ };
19
+ type RollbackCommandOptions = DatabaseCommandOptions & RollbackBoundOptions & {
20
+ /** Reverts applied migrations, newest first. */
21
+ command: 'rollback';
22
+ /** Migrations to revert. */
23
+ migrations: Migrations;
24
+ /** Reports what would be reverted without running it. */
25
+ dryRun?: boolean;
26
+ /** Migration journal table. */
27
+ journalTable?: string;
28
+ };
7
29
  /** Structured invocation options accepted by {@link runRemixDb}. */
8
30
  export type RunRemixDbOptions = (DatabaseCommandOptions & {
9
31
  /** Applies pending migrations. */
@@ -17,7 +39,7 @@ export type RunRemixDbOptions = (DatabaseCommandOptions & {
17
39
  to?: string;
18
40
  /** Migration journal table. */
19
41
  journalTable?: string;
20
- }) | (DatabaseCommandOptions & {
42
+ }) | RollbackCommandOptions | (DatabaseCommandOptions & {
21
43
  /** Wipes, migrates, and optionally seeds the database. */
22
44
  command: 'reset';
23
45
  /** Migrations to apply after wiping the database. */
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAA;AAE3D,UAAU,sBAAsB;IAC9B,6CAA6C;IAC7C,EAAE,EAAE,QAAQ,CAAA;CACb;AAED,oEAAoE;AACpE,MAAM,MAAM,iBAAiB,GACzB,CAAC,sBAAsB,GAAG;IACxB,kCAAkC;IAClC,OAAO,EAAE,SAAS,CAAA;IAClB,2BAA2B;IAC3B,UAAU,EAAE,UAAU,CAAA;IACtB;;;OAGG;IACH,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,+BAA+B;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAC,GACF,CAAC,sBAAsB,GAAG;IACxB,0DAA0D;IAC1D,OAAO,EAAE,OAAO,CAAA;IAChB,qDAAqD;IACrD,UAAU,EAAE,UAAU,CAAA;IACtB,yDAAyD;IACzD,IAAI,CAAC,EAAE,IAAI,CAAA;IACX,+BAA+B;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAC,GACF,CAAC,sBAAsB,GAAG;IACxB,4CAA4C;IAC5C,OAAO,EAAE,MAAM,CAAA;IACf,6CAA6C;IAC7C,IAAI,EAAE,IAAI,CAAA;CACX,CAAC,GACF,CAAC,sBAAsB,GAAG;IACxB,8CAA8C;IAC9C,OAAO,EAAE,QAAQ,CAAA;IACjB,6BAA6B;IAC7B,UAAU,EAAE,UAAU,CAAA;IACtB,+BAA+B;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAC,GACF,CAAC,sBAAsB,GAAG;IACxB,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAA;CAChB,CAAC,CAAA;AAEN;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CA4D5E"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAA;AAE3D,UAAU,sBAAsB;IAC9B,6CAA6C;IAC7C,EAAE,EAAE,QAAQ,CAAA;CACb;AAED,KAAK,oBAAoB,GACrB;IACE;;;OAGG;IACH,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,CAAC,EAAE,KAAK,CAAA;CACb,GACD;IACE,EAAE,CAAC,EAAE,KAAK,CAAA;IACV,qDAAqD;IACrD,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,CAAA;AAEL,KAAK,sBAAsB,GAAG,sBAAsB,GAClD,oBAAoB,GAAG;IACrB,gDAAgD;IAChD,OAAO,EAAE,UAAU,CAAA;IACnB,4BAA4B;IAC5B,UAAU,EAAE,UAAU,CAAA;IACtB,yDAAyD;IACzD,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,+BAA+B;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAEH,oEAAoE;AACpE,MAAM,MAAM,iBAAiB,GACzB,CAAC,sBAAsB,GAAG;IACxB,kCAAkC;IAClC,OAAO,EAAE,SAAS,CAAA;IAClB,2BAA2B;IAC3B,UAAU,EAAE,UAAU,CAAA;IACtB;;;OAGG;IACH,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,+BAA+B;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAC,GACF,sBAAsB,GACtB,CAAC,sBAAsB,GAAG;IACxB,0DAA0D;IAC1D,OAAO,EAAE,OAAO,CAAA;IAChB,qDAAqD;IACrD,UAAU,EAAE,UAAU,CAAA;IACtB,yDAAyD;IACzD,IAAI,CAAC,EAAE,IAAI,CAAA;IACX,+BAA+B;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAC,GACF,CAAC,sBAAsB,GAAG;IACxB,4CAA4C;IAC5C,OAAO,EAAE,MAAM,CAAA;IACf,6CAA6C;IAC7C,IAAI,EAAE,IAAI,CAAA;CACX,CAAC,GACF,CAAC,sBAAsB,GAAG;IACxB,8CAA8C;IAC9C,OAAO,EAAE,QAAQ,CAAA;IACjB,6BAA6B;IAC7B,UAAU,EAAE,UAAU,CAAA;IACtB,+BAA+B;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAC,GACF,CAAC,sBAAsB,GAAG;IACxB,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAA;CAChB,CAAC,CAAA;AAEN;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CA2F5E"}
package/dist/cli.js CHANGED
@@ -19,6 +19,31 @@ export async function runRemixDb(options) {
19
19
  }
20
20
  return 0;
21
21
  }
22
+ if (options.command === 'rollback') {
23
+ if (options.to !== undefined && options.step !== undefined) {
24
+ throw new Error('Cannot combine "to" and "step" migration options in the same run');
25
+ }
26
+ let result = options.to === undefined
27
+ ? await options.db.migrate(options.migrations, {
28
+ direction: 'down',
29
+ step: options.step ?? 1,
30
+ dryRun: options.dryRun,
31
+ journalTable: options.journalTable,
32
+ })
33
+ : await options.db.migrate(options.migrations, {
34
+ direction: 'down',
35
+ to: options.to,
36
+ dryRun: options.dryRun,
37
+ journalTable: options.journalTable,
38
+ });
39
+ if (result.reverted.length === 0) {
40
+ console.log('no migrations to revert');
41
+ }
42
+ for (let entry of result.reverted) {
43
+ console.log((options.dryRun ? 'would revert ' : 'reverted ') + entry.id + '_' + entry.name);
44
+ }
45
+ return 0;
46
+ }
22
47
  if (options.command === 'reset') {
23
48
  await options.db.reset({
24
49
  migrations: options.migrations,
@@ -15,7 +15,7 @@ function assertMigrationOperationOptions(options) {
15
15
  }
16
16
  }
17
17
  function resolveTargetOption(migrations, to) {
18
- if (!to) {
18
+ if (to === undefined) {
19
19
  return undefined;
20
20
  }
21
21
  // Accept either a bare migration id or the full `id_name` directory form and
@@ -42,6 +42,7 @@ export type WhereObject<column extends string = string> = Partial<Record<column,
42
42
  * User-facing where input accepted by `query.where()` and relation modifiers.
43
43
  */
44
44
  export type WhereInput<column extends string = string> = Predicate<column> | WhereObject<column>;
45
+ type WhereInputColumn<input extends WhereInput> = input extends Predicate<infer column> ? column : keyof input & string;
45
46
  /**
46
47
  * Builds an equality predicate.
47
48
  */
@@ -121,17 +122,17 @@ export declare function isNull<column extends string | ColumnReferenceLike>(colu
121
122
  */
122
123
  export declare function notNull<column extends string | ColumnReferenceLike>(column: column): Predicate<PredicateColumn<column>>;
123
124
  /**
124
- * Combines predicates with logical `AND`.
125
- * @param predicates Child predicates.
125
+ * Combines where inputs with logical `AND`.
126
+ * @param inputs Child predicates or object shorthand filters.
126
127
  * @returns A logical `and` predicate.
127
128
  */
128
- export declare function and<column extends string>(...predicates: Predicate<column>[]): Predicate<column>;
129
+ export declare function and<inputs extends WhereInput[]>(...inputs: inputs): Predicate<WhereInputColumn<inputs[number]>>;
129
130
  /**
130
- * Combines predicates with logical `OR`.
131
- * @param predicates Child predicates.
131
+ * Combines where inputs with logical `OR`.
132
+ * @param inputs Child predicates or object shorthand filters.
132
133
  * @returns A logical `or` predicate.
133
134
  */
134
- export declare function or<column extends string>(...predicates: Predicate<column>[]): Predicate<column>;
135
+ export declare function or<inputs extends WhereInput[]>(...inputs: inputs): Predicate<WhereInputColumn<inputs[number]>>;
135
136
  /**
136
137
  * Returns `true` when a value is a normalized predicate object.
137
138
  * @param value Value to inspect.
@@ -1 +1 @@
1
- {"version":3,"file":"operators.d.ts","sourceRoot":"","sources":["../../src/lib/operators.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"operators.d.ts","sourceRoot":"","sources":["../../src/lib/operators.ts"],"names":[],"mappings":"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"}
@@ -109,22 +109,26 @@ export function notNull(column) {
109
109
  return { type: 'null', operator: 'notNull', column: resolvePredicateColumn(column) };
110
110
  }
111
111
  /**
112
- * Combines predicates with logical `AND`.
113
- * @param predicates Child predicates.
112
+ * Combines where inputs with logical `AND`.
113
+ * @param inputs Child predicates or object shorthand filters.
114
114
  * @returns A logical `and` predicate.
115
115
  */
116
- export function and(...predicates) {
117
- let filtered = predicates.filter(Boolean);
118
- return { type: 'logical', operator: 'and', predicates: filtered };
116
+ export function and(...inputs) {
117
+ let predicates = inputs
118
+ .filter(Boolean)
119
+ .map((input) => normalizeWhereInput(input));
120
+ return { type: 'logical', operator: 'and', predicates };
119
121
  }
120
122
  /**
121
- * Combines predicates with logical `OR`.
122
- * @param predicates Child predicates.
123
+ * Combines where inputs with logical `OR`.
124
+ * @param inputs Child predicates or object shorthand filters.
123
125
  * @returns A logical `or` predicate.
124
126
  */
125
- export function or(...predicates) {
126
- let filtered = predicates.filter(Boolean);
127
- return { type: 'logical', operator: 'or', predicates: filtered };
127
+ export function or(...inputs) {
128
+ let predicates = inputs
129
+ .filter(Boolean)
130
+ .map((input) => normalizeWhereInput(input));
131
+ return { type: 'logical', operator: 'or', predicates };
128
132
  }
129
133
  /**
130
134
  * Returns `true` when a value is a normalized predicate object.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remix-run/data-table",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "A typed, relational query toolkit for JavaScript",
5
5
  "author": "Michael Jackson <mjijackson@gmail.com>",
6
6
  "license": "MIT",
@@ -49,8 +49,8 @@
49
49
  "devDependencies": {
50
50
  "@types/node": "^24.6.0",
51
51
  "typescript": "^7.0.2",
52
- "@remix-run/assert": "0.3.0",
53
- "@remix-run/test": "0.6.0"
52
+ "@remix-run/test": "0.6.0",
53
+ "@remix-run/assert": "0.3.0"
54
54
  },
55
55
  "dependencies": {},
56
56
  "keywords": [
package/src/cli.ts CHANGED
@@ -6,6 +6,33 @@ interface DatabaseCommandOptions {
6
6
  db: Database
7
7
  }
8
8
 
9
+ type RollbackBoundOptions =
10
+ | {
11
+ /**
12
+ * Reverts back through this migration, inclusive. Accepts a bare
13
+ * migration id or the full `id_name` directory form.
14
+ */
15
+ to: string
16
+ step?: never
17
+ }
18
+ | {
19
+ to?: never
20
+ /** Reverts this many migrations. Defaults to `1`. */
21
+ step?: number
22
+ }
23
+
24
+ type RollbackCommandOptions = DatabaseCommandOptions &
25
+ RollbackBoundOptions & {
26
+ /** Reverts applied migrations, newest first. */
27
+ command: 'rollback'
28
+ /** Migrations to revert. */
29
+ migrations: Migrations
30
+ /** Reports what would be reverted without running it. */
31
+ dryRun?: boolean
32
+ /** Migration journal table. */
33
+ journalTable?: string
34
+ }
35
+
9
36
  /** Structured invocation options accepted by {@link runRemixDb}. */
10
37
  export type RunRemixDbOptions =
11
38
  | (DatabaseCommandOptions & {
@@ -21,6 +48,7 @@ export type RunRemixDbOptions =
21
48
  /** Migration journal table. */
22
49
  journalTable?: string
23
50
  })
51
+ | RollbackCommandOptions
24
52
  | (DatabaseCommandOptions & {
25
53
  /** Wipes, migrates, and optionally seeds the database. */
26
54
  command: 'reset'
@@ -76,6 +104,37 @@ export async function runRemixDb(options: RunRemixDbOptions): Promise<number> {
76
104
  return 0
77
105
  }
78
106
 
107
+ if (options.command === 'rollback') {
108
+ if (options.to !== undefined && options.step !== undefined) {
109
+ throw new Error('Cannot combine "to" and "step" migration options in the same run')
110
+ }
111
+
112
+ let result =
113
+ options.to === undefined
114
+ ? await options.db.migrate(options.migrations, {
115
+ direction: 'down',
116
+ step: options.step ?? 1,
117
+ dryRun: options.dryRun,
118
+ journalTable: options.journalTable,
119
+ })
120
+ : await options.db.migrate(options.migrations, {
121
+ direction: 'down',
122
+ to: options.to,
123
+ dryRun: options.dryRun,
124
+ journalTable: options.journalTable,
125
+ })
126
+
127
+ if (result.reverted.length === 0) {
128
+ console.log('no migrations to revert')
129
+ }
130
+
131
+ for (let entry of result.reverted) {
132
+ console.log((options.dryRun ? 'would revert ' : 'reverted ') + entry.id + '_' + entry.name)
133
+ }
134
+
135
+ return 0
136
+ }
137
+
79
138
  if (options.command === 'reset') {
80
139
  await options.db.reset({
81
140
  migrations: options.migrations,
@@ -63,7 +63,7 @@ function resolveTargetOption(
63
63
  migrations: MigrationDescriptor[],
64
64
  to: string | undefined,
65
65
  ): string | undefined {
66
- if (!to) {
66
+ if (to === undefined) {
67
67
  return undefined
68
68
  }
69
69
 
@@ -66,6 +66,9 @@ export type WhereObject<column extends string = string> = Partial<Record<column,
66
66
  */
67
67
  export type WhereInput<column extends string = string> = Predicate<column> | WhereObject<column>
68
68
 
69
+ type WhereInputColumn<input extends WhereInput> =
70
+ input extends Predicate<infer column> ? column : keyof input & string
71
+
69
72
  /**
70
73
  * Builds an equality predicate.
71
74
  */
@@ -293,23 +296,33 @@ export function notNull<column extends string | ColumnReferenceLike>(
293
296
  }
294
297
 
295
298
  /**
296
- * Combines predicates with logical `AND`.
297
- * @param predicates Child predicates.
299
+ * Combines where inputs with logical `AND`.
300
+ * @param inputs Child predicates or object shorthand filters.
298
301
  * @returns A logical `and` predicate.
299
302
  */
300
- export function and<column extends string>(...predicates: Predicate<column>[]): Predicate<column> {
301
- let filtered = predicates.filter(Boolean)
302
- return { type: 'logical', operator: 'and', predicates: filtered }
303
+ export function and<inputs extends WhereInput[]>(
304
+ ...inputs: inputs
305
+ ): Predicate<WhereInputColumn<inputs[number]>> {
306
+ type column = WhereInputColumn<inputs[number]>
307
+ let predicates = inputs
308
+ .filter(Boolean)
309
+ .map((input) => normalizeWhereInput(input) as Predicate<column>)
310
+ return { type: 'logical', operator: 'and', predicates }
303
311
  }
304
312
 
305
313
  /**
306
- * Combines predicates with logical `OR`.
307
- * @param predicates Child predicates.
314
+ * Combines where inputs with logical `OR`.
315
+ * @param inputs Child predicates or object shorthand filters.
308
316
  * @returns A logical `or` predicate.
309
317
  */
310
- export function or<column extends string>(...predicates: Predicate<column>[]): Predicate<column> {
311
- let filtered = predicates.filter(Boolean)
312
- return { type: 'logical', operator: 'or', predicates: filtered }
318
+ export function or<inputs extends WhereInput[]>(
319
+ ...inputs: inputs
320
+ ): Predicate<WhereInputColumn<inputs[number]>> {
321
+ type column = WhereInputColumn<inputs[number]>
322
+ let predicates = inputs
323
+ .filter(Boolean)
324
+ .map((input) => normalizeWhereInput(input) as Predicate<column>)
325
+ return { type: 'logical', operator: 'or', predicates }
313
326
  }
314
327
 
315
328
  /**