@remix-run/cli 0.5.0 → 0.7.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.
Files changed (55) hide show
  1. package/README.md +52 -3
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +1 -0
  5. package/dist/lib/cli-context.d.ts.map +1 -1
  6. package/dist/lib/cli-context.js +5 -2
  7. package/dist/lib/cli.d.ts +1 -1
  8. package/dist/lib/cli.js +5 -1
  9. package/dist/lib/commands/assets.d.ts +4 -0
  10. package/dist/lib/commands/assets.d.ts.map +1 -0
  11. package/dist/lib/commands/assets.js +90 -0
  12. package/dist/lib/commands/db.d.ts.map +1 -1
  13. package/dist/lib/commands/db.js +63 -5
  14. package/dist/lib/commands/help.d.ts.map +1 -1
  15. package/dist/lib/commands/help.js +7 -0
  16. package/dist/lib/completion.d.ts.map +1 -1
  17. package/dist/lib/completion.js +25 -1
  18. package/dist/lib/database-command.d.ts +5 -1
  19. package/dist/lib/database-command.d.ts.map +1 -1
  20. package/dist/lib/database-command.js +1 -0
  21. package/dist/lib/errors.d.ts +6 -0
  22. package/dist/lib/errors.d.ts.map +1 -1
  23. package/dist/lib/errors.js +10 -0
  24. package/dist/lib/remix-config.d.ts +22 -0
  25. package/dist/lib/remix-config.d.ts.map +1 -1
  26. package/dist/lib/remix-config.js +80 -4
  27. package/package.json +6 -5
  28. package/schema/remix.json +49 -1
  29. package/src/index.ts +10 -0
  30. package/src/lib/cli-context.ts +10 -2
  31. package/src/lib/cli.ts +6 -1
  32. package/src/lib/commands/assets.ts +109 -0
  33. package/src/lib/commands/db.ts +75 -5
  34. package/src/lib/commands/help.ts +8 -0
  35. package/src/lib/completion.ts +41 -1
  36. package/src/lib/database-command.ts +6 -1
  37. package/src/lib/errors.ts +11 -0
  38. package/src/lib/remix-config.ts +128 -4
  39. package/template/.agents/skills/remix/SKILL.md +7 -5
  40. package/template/.agents/skills/remix/references/assets-and-browser-modules.md +22 -20
  41. package/template/.agents/skills/remix/references/auth-and-sessions.md +1 -15
  42. package/template/.agents/skills/remix/references/component-model.md +18 -16
  43. package/template/.agents/skills/remix/references/hydration-frames-navigation.md +75 -52
  44. package/template/.agents/skills/remix/references/middleware-and-server.md +5 -2
  45. package/template/.agents/skills/remix/references/mixins-styling-events.md +1 -1
  46. package/template/.agents/skills/remix/references/routing-and-controllers.md +1 -1
  47. package/template/.agents/skills/remix/references/testing-patterns.md +1 -1
  48. package/template/AGENTS.md +2 -3
  49. package/template/README.md +2 -3
  50. package/template/app/actions/controller.tsx +2 -4
  51. package/template/app/actions/document.tsx +7 -4
  52. package/template/app/actions/public/entry.ts +15 -29
  53. package/template/app/assets.ts +7 -8
  54. package/template/app/router.ts +5 -3
  55. package/template/app/middleware/render.tsx +0 -78
package/README.md CHANGED
@@ -5,6 +5,7 @@ Command-line interface for creating and managing Remix projects.
5
5
  ## Features
6
6
 
7
7
  - Create new Remix projects with `npx remix@next new` or installed `remix new`
8
+ - List browser-reachable files and inspect URL mappings with `remix assets`
8
9
  - Print shell completion scripts with `remix completion`
9
10
  - Check project environment and Remix app conventions with `remix doctor`
10
11
  - Apply available low-risk project fixes with `remix doctor --fix`
@@ -46,10 +47,13 @@ The rest of the CLI is available through the installed `remix` command:
46
47
 
47
48
  ```sh
48
49
  remix new my-remix-app
50
+ remix assets
51
+ remix assets inspect /assets/app/actions/public/entry.ts
49
52
  remix completion bash >> ~/.bashrc
50
53
  remix doctor
51
54
  remix doctor --fix
52
55
  remix db migrate
56
+ remix db rollback
53
57
  remix db status
54
58
  remix db reset --force
55
59
  remix routes
@@ -66,10 +70,13 @@ You can also run the CLI programmatically:
66
70
  import { runRemix } from 'remix/cli'
67
71
 
68
72
  await runRemix(['new', 'my-remix-app'])
73
+ await runRemix(['assets'])
74
+ await runRemix(['assets', 'inspect', '/assets/app/actions/public/entry.ts'])
69
75
  await runRemix(['completion', 'bash'])
70
76
  await runRemix(['doctor'])
71
77
  await runRemix(['doctor', '--fix'])
72
78
  await runRemix(['db', 'migrate'])
79
+ await runRemix(['db', 'rollback'])
73
80
  await runRemix(['db', 'status'])
74
81
  await runRemix(['db', 'reset', '--force'])
75
82
  await runRemix(['routes'])
@@ -81,8 +88,12 @@ await runRemix(['version'])
81
88
 
82
89
  Destructive database commands (`remix db wipe` and `remix db reset`) refuse to run without `--force`.
83
90
 
91
+ `remix db rollback` reverts the most recent migration by default. Use `--step <count>` or `--to <migration>` to select a bound, and use `--dry-run` to report what would be reverted without changing the database.
92
+
84
93
  `runRemix()` returns the CLI exit code as a promise.
85
94
 
95
+ `remix assets` lists each browser-reachable asset as `URL -> file`, one per line. Run `remix assets inspect <url-or-file>` to see one asset's resolved mapping and whether it is reachable, denied, unsupported, missing, or unmapped. Denied assets also show the matching deny rule.
96
+
86
97
  ## Configuration
87
98
 
88
99
  The CLI loads an optional `remix.json`. The file is parsed as JSONC, so it may contain comments and
@@ -90,7 +101,22 @@ trailing commas. Every top-level field is optional:
90
101
 
91
102
  ```jsonc
92
103
  {
93
- "$schema": "https://remix.run/schemas/remix.json",
104
+ "$schema": "./node_modules/remix/schema/remix.json",
105
+
106
+ "assets": {
107
+ "rootDir": ".",
108
+ "basePath": "/assets",
109
+ "mounts": {
110
+ "app": "app",
111
+ "npm": "node_modules",
112
+ },
113
+ "allowFiles": ["app/routes.ts", "app/**/public/**"],
114
+ "allowPackages": ["remix"],
115
+ "denyFiles": ["app/**/*.test.*"],
116
+ "files": {
117
+ "extensions": [".svg", ".png", ".jpg", ".woff2"],
118
+ },
119
+ },
94
120
 
95
121
  "db": {
96
122
  "adapter": {
@@ -152,6 +178,8 @@ trailing commas. Every top-level field is optional:
152
178
  }
153
179
  ```
154
180
 
181
+ The local `$schema` association uses the schema shipped with the directly installed `remix` package, so editor validation matches that version and remains available offline. It intentionally does not reference the transitive `@remix-run/cli` package, which may not be linked at the project root by package managers such as pnpm.
182
+
155
183
  Explicit command flags and positional arguments override configured values. Repeated flags replace
156
184
  configured arrays, while nested Playwright and coverage settings merge by field. Relative paths and
157
185
  globs are resolved from the directory containing the config file. Use `remix doctor --no-strict` to
@@ -162,8 +190,9 @@ disable configured strict mode for one run.
162
190
  a string or an object naming an environment variable with an optional default. `db.seed` names a
163
191
  SQL file that `remix db seed` and `remix db reset` run against the database. Database flags such as
164
192
  `--migrations`, `--seed`, `--journal-table`, and `--connection-env` override the corresponding
165
- config for one invocation. When no global `--config` is provided, database commands find the
166
- nearest `remix.json` by walking up from the working directory.
193
+ config for one invocation. Rollbacks also accept `--step`, `--to`, and `--dry-run`. When no global
194
+ `--config` is provided, database commands find the nearest `remix.json` by walking up from the
195
+ working directory.
167
196
 
168
197
  Use the global `--config` option to select another JSONC file. The option itself is resolved from the
169
198
  CLI working directory and may appear before or after the command:
@@ -177,6 +206,26 @@ A missing default `remix.json` is ignored. A missing explicitly selected file, m
177
206
  unknown property, or invalid value is reported as a CLI error. The optional `$schema` field enables
178
207
  editor completion and validation; it has no runtime effect.
179
208
 
209
+ Load the complete validated config from application code with `loadConfig()`:
210
+
211
+ ```ts
212
+ import { createAssetServer } from 'remix/assets'
213
+ import { loadConfig } from 'remix/cli'
214
+
215
+ let config = await loadConfig(import.meta.dirname)
216
+ if (config.assets === undefined) throw new Error('Missing assets configuration')
217
+
218
+ let assetServer = createAssetServer({
219
+ ...config.assets,
220
+ sourceMaps: process.env.NODE_ENV === 'development' ? 'external' : undefined,
221
+ })
222
+ ```
223
+
224
+ Pass a config file to load it directly, or a directory to search upward for the nearest
225
+ `remix.json`. Asset paths are resolved relative to the config file, so `config.assets` can be spread
226
+ directly into `createAssetServer()`. Add runtime-only options such as transforms, caches, HMR, or
227
+ error handlers in application code.
228
+
180
229
  ## License
181
230
 
182
231
  See [LICENSE](https://github.com/remix-run/remix/blob/main/LICENSE)
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export { runRemix, type RunRemixOptions } from './lib/cli.ts';
2
+ export { loadConfig, type RemixAssetsConfig, type RemixConfig, type RemixDbAdapterConfig, type RemixDbCommandConfig, type RemixDbString, type RemixDoctorCommandConfig, type RemixTestCommandConfig, } from './lib/remix-config.ts';
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAA;AAC7D,OAAO,EACL,UAAU,EACV,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,aAAa,EAClB,KAAK,wBAAwB,EAC7B,KAAK,sBAAsB,GAC5B,MAAM,uBAAuB,CAAA"}
package/dist/index.js CHANGED
@@ -1 +1,2 @@
1
1
  export { runRemix } from './lib/cli.js';
2
+ export { loadConfig, } from './lib/remix-config.js';
@@ -1 +1 @@
1
- {"version":3,"file":"cli-context.d.ts","sourceRoot":"","sources":["../../src/lib/cli-context.ts"],"names":[],"mappings":"AAIA,OAAO,EAAmB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAErE,UAAU,wBAAwB;IAChC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,gEAAgE;IAChE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,GAAG,EAAE,MAAM,CAAA;IACX,uEAAuE;IACvE,UAAU,IAAI,OAAO,CAAC,WAAW,CAAC,CAAA;IAClC,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,wBAAsB,iBAAiB,CACrC,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,UAAU,CAAC,CAmBrB"}
1
+ {"version":3,"file":"cli-context.d.ts","sourceRoot":"","sources":["../../src/lib/cli-context.ts"],"names":[],"mappings":"AAIA,OAAO,EAGL,KAAK,WAAW,EACjB,MAAM,mBAAmB,CAAA;AAE1B,UAAU,wBAAwB;IAChC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,gEAAgE;IAChE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,GAAG,EAAE,MAAM,CAAA;IACX,uEAAuE;IACvE,UAAU,IAAI,OAAO,CAAC,WAAW,CAAC,CAAA;IAClC,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,wBAAsB,iBAAiB,CACrC,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,UAAU,CAAC,CAuBrB"}
@@ -1,12 +1,15 @@
1
1
  import * as path from 'node:path';
2
2
  import * as process from 'node:process';
3
3
  import { resolveDefaultRemixVersion } from './remix-version.js';
4
- import { loadRemixConfig } from './remix-config.js';
4
+ import { loadConfig as loadProjectConfig, loadRemixConfig, } from './remix-config.js';
5
5
  export async function resolveCliContext(options = {}) {
6
6
  let cwd = resolveCwd(options.cwd);
7
7
  let remixVersion = normalizeRemixVersion(options.remixVersion);
8
8
  let configPromise;
9
- let loadConfig = () => (configPromise ??= loadRemixConfig(cwd, options.configPath));
9
+ let loadConfig = () => (configPromise ??=
10
+ options.configPath === undefined
11
+ ? loadProjectConfig(cwd)
12
+ : loadRemixConfig(cwd, options.configPath));
10
13
  // Validate an explicitly selected config file up front so every command
11
14
  // fails fast on a bad --config path. The default remix.json is loaded
12
15
  // lazily by the commands that read it, so an invalid file doesn't break
package/dist/lib/cli.d.ts CHANGED
@@ -15,7 +15,7 @@ export interface RunRemixOptions {
15
15
  }
16
16
  /**
17
17
  * Entry point for the `remix` CLI. Parses `argv`, dispatches to the matching
18
- * subcommand (`new`, `db`, `doctor`, `routes`, `test`, `version`,
18
+ * subcommand (`new`, `assets`, `db`, `doctor`, `routes`, `test`, `version`,
19
19
  * `completion`, `help`), and resolves with the exit code the process should
20
20
  * use.
21
21
  *
package/dist/lib/cli.js CHANGED
@@ -5,7 +5,7 @@ import { missingOptionValue, renderCliError, toCliError, unknownCommand } from '
5
5
  import { configureColors, restoreTerminalFormatting } from './terminal.js';
6
6
  /**
7
7
  * Entry point for the `remix` CLI. Parses `argv`, dispatches to the matching
8
- * subcommand (`new`, `db`, `doctor`, `routes`, `test`, `version`,
8
+ * subcommand (`new`, `assets`, `db`, `doctor`, `routes`, `test`, `version`,
9
9
  * `completion`, `help`), and resolves with the exit code the process should
10
10
  * use.
11
11
  *
@@ -70,6 +70,10 @@ async function runCommand(command, argv, context) {
70
70
  let { runCompletionCommand } = await import('./commands/completion.js');
71
71
  return runCompletionCommand(argv);
72
72
  }
73
+ if (command === 'assets') {
74
+ let { runAssetsCommand } = await import('./commands/assets.js');
75
+ return runAssetsCommand(argv, context);
76
+ }
73
77
  if (command === 'doctor') {
74
78
  let { runDoctorCommand } = await import('./commands/doctor.js');
75
79
  return runDoctorCommand(argv, context);
@@ -0,0 +1,4 @@
1
+ import type { CliContext } from '../cli-context.ts';
2
+ export declare function runAssetsCommand(argv: string[], context: CliContext): Promise<number>;
3
+ export declare function getAssetsCommandHelpText(target?: NodeJS.WriteStream): string;
4
+ //# sourceMappingURL=assets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../../src/lib/commands/assets.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAWnD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAiC3F;AAED,wBAAgB,wBAAwB,CAAC,MAAM,GAAE,MAAM,CAAC,WAA4B,GAAG,MAAM,CAc5F"}
@@ -0,0 +1,90 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import * as process from 'node:process';
4
+ import { createAssetServer } from '@remix-run/assets';
5
+ import { assetsConfigRequired, invalidOptionValue, renderCliError, toCliError, unknownCommand, } from '../errors.js';
6
+ import { formatHelpText } from '../help-text.js';
7
+ import { parseArgs } from '../parse-args.js';
8
+ export async function runAssetsCommand(argv, context) {
9
+ if (argv.includes('-h') || argv.includes('--help')) {
10
+ process.stdout.write(getAssetsCommandHelpText());
11
+ return 0;
12
+ }
13
+ try {
14
+ let invocation = parseAssetsCommandArgs(argv);
15
+ let config = await context.loadConfig();
16
+ if (config.assets === undefined)
17
+ throw assetsConfigRequired();
18
+ let assetServer = createAssetServer({ ...config.assets, watch: false });
19
+ try {
20
+ let rootDir = fs.realpathSync(config.assets.rootDir);
21
+ if (invocation.command === 'list') {
22
+ process.stdout.write(formatAssetList(await assetServer.getAssets(), rootDir));
23
+ }
24
+ else {
25
+ process.stdout.write(formatAssetDetails(await assetServer.getAssetDetails(invocation.input), rootDir));
26
+ }
27
+ }
28
+ finally {
29
+ await assetServer.close();
30
+ }
31
+ return 0;
32
+ }
33
+ catch (error) {
34
+ process.stderr.write(renderCliError(toCliError(error), { helpText: getAssetsCommandHelpText(process.stderr) }));
35
+ return 1;
36
+ }
37
+ }
38
+ export function getAssetsCommandHelpText(target = process.stdout) {
39
+ return formatHelpText({
40
+ description: 'List or inspect browser-reachable assets.',
41
+ commands: [{ description: 'Inspect one asset URL or file', label: 'inspect <url-or-file>' }],
42
+ examples: [
43
+ 'remix assets',
44
+ 'remix assets inspect /assets/app/actions/public/entry.ts',
45
+ 'remix assets inspect app/actions/public/entry.ts',
46
+ ],
47
+ usage: ['remix assets', 'remix assets inspect <url-or-file>'],
48
+ }, target);
49
+ }
50
+ function parseAssetsCommandArgs(argv) {
51
+ let parsed = parseArgs(argv, {}, { maxPositionals: 2 });
52
+ let [command, input] = parsed.positionals;
53
+ if (command === undefined)
54
+ return { command: 'list' };
55
+ if (command !== 'inspect')
56
+ throw unknownCommand(`assets ${command}`);
57
+ if (input === undefined) {
58
+ throw invalidOptionValue('`remix assets inspect` requires a URL or file path.');
59
+ }
60
+ return { command, input };
61
+ }
62
+ function formatAssetList(assets, rootDir) {
63
+ if (assets.length === 0)
64
+ return 'No assets.\n';
65
+ return `${assets
66
+ .map((asset) => `${asset.url} -> ${formatFilePath(asset.filePath, rootDir)}`)
67
+ .join('\n')}\n`;
68
+ }
69
+ function formatAssetDetails(details, rootDir) {
70
+ let lines = [`Status: ${details.status}`];
71
+ if (details.url !== undefined)
72
+ lines.push(`URL: ${details.url}`);
73
+ if (details.filePath !== undefined) {
74
+ lines.push(`File: ${formatFilePath(details.filePath, rootDir)}`);
75
+ }
76
+ if (details.access?.deniedBy !== undefined) {
77
+ lines.push(`Denied by: ${details.access.deniedBy}`);
78
+ }
79
+ return `${lines.join('\n')}\n`;
80
+ }
81
+ function formatFilePath(filePath, rootDir) {
82
+ if (filePath === undefined)
83
+ return '';
84
+ let relativePath = path.relative(rootDir, filePath);
85
+ return relativePath === '' ||
86
+ relativePath.startsWith(`..${path.sep}`) ||
87
+ path.isAbsolute(relativePath)
88
+ ? filePath
89
+ : relativePath.split(path.sep).join('/');
90
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../../src/lib/commands/db.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AA6BnD,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAiBvF;AAED,wBAAgB,oBAAoB,CAAC,MAAM,GAAE,MAAM,CAAC,WAA4B,GAAG,MAAM,CA0CxF"}
1
+ {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../../src/lib/commands/db.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AA4BnD,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAiBvF;AAED,wBAAgB,oBAAoB,CAAC,MAAM,GAAE,MAAM,CAAC,WAA4B,GAAG,MAAM,CAuDxF"}
@@ -8,7 +8,7 @@ import { isDatabaseCommand, } from '../database-command.js';
8
8
  import { dbConfigRequired, dbForceRequired, invalidOptionValue, remixConfigNotFound, renderCliError, toCliError, unknownCommand, } from '../errors.js';
9
9
  import { formatHelpText } from '../help-text.js';
10
10
  import { parseArgs } from '../parse-args.js';
11
- import { loadRemixConfig, } from '../remix-config.js';
11
+ import {} from '../remix-config.js';
12
12
  const connectionOption = { flag: '--connection-env', type: 'string' };
13
13
  const journalOption = { flag: '--journal-table', type: 'string' };
14
14
  const migrationsOption = { flag: '--migrations', type: 'string' };
@@ -36,6 +36,8 @@ export function getDbCommandHelpText(target = process.stdout) {
36
36
  'remix db wipe --force',
37
37
  'remix db migrate',
38
38
  'remix db migrate --to 20260715123000_add_users',
39
+ 'remix db rollback',
40
+ 'remix db rollback --step 2 --dry-run',
39
41
  'remix db status',
40
42
  'remix db seed',
41
43
  'remix db reset --force',
@@ -45,24 +47,33 @@ export function getDbCommandHelpText(target = process.stdout) {
45
47
  description: 'Read the database connection from an environment variable',
46
48
  label: '--connection-env <name>',
47
49
  },
50
+ {
51
+ description: 'Report what would be reverted without running it (rollback only)',
52
+ label: '--dry-run',
53
+ },
48
54
  { description: 'Confirm a destructive command (wipe and reset only)', label: '--force' },
49
55
  {
50
- description: 'Use a migration journal table (migrate, status, and reset only)',
56
+ description: 'Use a migration journal table (migrate, rollback, status, and reset only)',
51
57
  label: '--journal-table <name>',
52
58
  },
53
59
  {
54
- description: 'Load migrations from a directory (migrate, status, and reset only)',
60
+ description: 'Load migrations from a directory (migrate, rollback, status, and reset only)',
55
61
  label: '--migrations <path>',
56
62
  },
57
63
  { description: 'Run a SQL seed file (seed and reset only)', label: '--seed <path>' },
58
64
  {
59
- description: 'Stop after applying the specified migration (migrate only)',
65
+ description: 'Revert this many migrations, newest first (rollback only)',
66
+ label: '--step <count>',
67
+ },
68
+ {
69
+ description: 'Stop after applying the specified migration, or revert back through it (migrate and rollback only)',
60
70
  label: '--to <migration>',
61
71
  },
62
72
  ],
63
73
  usage: [
64
74
  'remix db wipe --force [options]',
65
75
  'remix db migrate [--to <migration>] [options]',
76
+ 'remix db rollback [--step <count> | --to <migration>] [--dry-run] [options]',
66
77
  'remix db status [options]',
67
78
  'remix db seed [options]',
68
79
  'remix db reset --force [options]',
@@ -83,6 +94,21 @@ function parseDbCommandArgs(argv) {
83
94
  }, { maxPositionals: 0 });
84
95
  return { command, ...parsed.options };
85
96
  }
97
+ if (command === 'rollback') {
98
+ let parsed = parseArgs(commandArgv, {
99
+ connectionEnv: connectionOption,
100
+ dryRun: { flag: '--dry-run', type: 'boolean' },
101
+ journalTable: journalOption,
102
+ migrations: migrationsOption,
103
+ step: { flag: '--step', type: 'string' },
104
+ to: { flag: '--to', type: 'string' },
105
+ }, { maxPositionals: 0 });
106
+ if (parsed.options.step !== undefined && parsed.options.to !== undefined) {
107
+ throw invalidOptionValue('Options --step and --to are mutually exclusive');
108
+ }
109
+ let { step: rawStep, ...options } = parsed.options;
110
+ return { command, ...options, step: parseStepOption(rawStep) };
111
+ }
86
112
  if (command === 'reset') {
87
113
  let parsed = parseArgs(commandArgv, {
88
114
  connectionEnv: connectionOption,
@@ -116,6 +142,15 @@ function parseDbCommandArgs(argv) {
116
142
  }, { maxPositionals: 0 });
117
143
  return { command, ...parsed.options };
118
144
  }
145
+ function parseStepOption(value) {
146
+ if (value === undefined)
147
+ return undefined;
148
+ let step = Number(value);
149
+ if (!Number.isInteger(step) || step < 1) {
150
+ throw invalidOptionValue(`Option --step expects a positive integer, received "${value}"`);
151
+ }
152
+ return step;
153
+ }
119
154
  async function resolveDbConfig(context) {
120
155
  let configPath;
121
156
  let config;
@@ -128,7 +163,7 @@ async function resolveDbConfig(context) {
128
163
  if (configDir === null)
129
164
  throw remixConfigNotFound(path.join(context.cwd, 'remix.json'));
130
165
  configPath = path.join(configDir, 'remix.json');
131
- config = await loadRemixConfig(configDir, undefined);
166
+ config = await context.loadConfig();
132
167
  }
133
168
  if (config.db === undefined)
134
169
  throw dbConfigRequired(configPath);
@@ -143,6 +178,7 @@ function resolveDatabaseCommandPlan(invocation, config, cwd) {
143
178
  let seed = invocation.seed ? path.resolve(cwd, invocation.seed) : config.seed;
144
179
  if ((invocation.command === 'migrate' ||
145
180
  invocation.command === 'reset' ||
181
+ invocation.command === 'rollback' ||
146
182
  invocation.command === 'status') &&
147
183
  migrations === undefined) {
148
184
  throw invalidOptionValue(`Database command "${invocation.command}" requires db.migrations.directory or --migrations`);
@@ -153,9 +189,11 @@ function resolveDatabaseCommandPlan(invocation, config, cwd) {
153
189
  return {
154
190
  adapter,
155
191
  command: invocation.command,
192
+ dryRun: invocation.dryRun,
156
193
  journalTable,
157
194
  migrations,
158
195
  seed,
196
+ step: invocation.step,
159
197
  to: invocation.to,
160
198
  };
161
199
  }
@@ -224,6 +262,26 @@ async function executeDatabaseCommand(plan, db) {
224
262
  journalTable: plan.journalTable,
225
263
  });
226
264
  }
265
+ if (plan.command === 'rollback') {
266
+ if (plan.to !== undefined) {
267
+ return runRemixDb({
268
+ command: plan.command,
269
+ db,
270
+ migrations,
271
+ to: plan.to,
272
+ dryRun: plan.dryRun,
273
+ journalTable: plan.journalTable,
274
+ });
275
+ }
276
+ return runRemixDb({
277
+ command: plan.command,
278
+ db,
279
+ migrations,
280
+ step: plan.step,
281
+ dryRun: plan.dryRun,
282
+ journalTable: plan.journalTable,
283
+ });
284
+ }
227
285
  if (plan.command === 'reset') {
228
286
  let seed = plan.seed === undefined ? undefined : await loadSeed(plan.seed);
229
287
  return runRemixDb({
@@ -1 +1 @@
1
- {"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../../src/lib/commands/help.ts"],"names":[],"mappings":"AAKA,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAepE;AAED,wBAAgB,cAAc,CAAC,MAAM,GAAE,MAAM,CAAC,WAA4B,GAAG,MAAM,CAoClF;AAED,wBAAgB,sBAAsB,CAAC,MAAM,GAAE,MAAM,CAAC,WAA4B,GAAG,MAAM,CAkB1F"}
1
+ {"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../../src/lib/commands/help.ts"],"names":[],"mappings":"AAKA,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAepE;AAED,wBAAgB,cAAc,CAAC,MAAM,GAAE,MAAM,CAAC,WAA4B,GAAG,MAAM,CAsClF;AAED,wBAAgB,sBAAsB,CAAC,MAAM,GAAE,MAAM,CAAC,WAA4B,GAAG,MAAM,CAmB1F"}
@@ -18,6 +18,7 @@ export async function runHelpCommand(argv) {
18
18
  export function getCliHelpText(target = process.stdout) {
19
19
  return formatHelpText({
20
20
  commands: [
21
+ { description: 'List or inspect browser-reachable assets', label: 'assets [command]' },
21
22
  { description: 'Print shell completion scripts for Remix', label: 'completion' },
22
23
  { description: 'Show help for Remix commands', label: 'help [command]' },
23
24
  { description: 'Create a new Remix project', label: 'new <name>' },
@@ -28,6 +29,7 @@ export function getCliHelpText(target = process.stdout) {
28
29
  { description: 'Show the current Remix version', label: 'version' },
29
30
  ],
30
31
  examples: [
32
+ 'remix assets',
31
33
  'remix completion bash',
32
34
  'remix help',
33
35
  'remix help completion',
@@ -54,6 +56,7 @@ export function getHelpCommandHelpText(target = process.stdout) {
54
56
  description: 'Show help for Remix commands.',
55
57
  examples: [
56
58
  'remix help',
59
+ 'remix help assets',
57
60
  'remix help completion',
58
61
  'remix help db',
59
62
  'remix help doctor',
@@ -77,6 +80,10 @@ async function getCommandHelpText(argv) {
77
80
  let { getNewCommandHelpText } = await import('./new.js');
78
81
  return getNewCommandHelpText();
79
82
  }
83
+ if (command === 'assets' && rest.length === 0) {
84
+ let { getAssetsCommandHelpText } = await import('./assets.js');
85
+ return getAssetsCommandHelpText();
86
+ }
80
87
  if (command === 'completion' && rest.length === 0) {
81
88
  let { getCompletionCommandHelpText } = await import('./completion.js');
82
89
  return getCompletionCommandHelpText();
@@ -1 +1 @@
1
- {"version":3,"file":"completion.d.ts","sourceRoot":"","sources":["../../src/lib/completion.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAA;IACjC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;CAClB;AAED,QAAA,MAAM,iBAAiB,YAAI,MAAM,EAAE,KAAK,CAAU,CAAA;AA6ClD,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAA;AAEhE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,eAAe,CAEzE;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,YAAY,EAAE,MAAM,GAAG,gBAAgB,CAU3F;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAQvE;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAyF5C"}
1
+ {"version":3,"file":"completion.d.ts","sourceRoot":"","sources":["../../src/lib/completion.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAA;IACjC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;CAClB;AAED,QAAA,MAAM,iBAAiB,YAAI,MAAM,EAAE,KAAK,CAAU,CAAA;AA+ClD,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAA;AAEhE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,eAAe,CAEzE;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,YAAY,EAAE,MAAM,GAAG,gBAAgB,CAU3F;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAQvE;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAyF5C"}
@@ -1,7 +1,8 @@
1
1
  import { testCommandFlags } from './commands/test.js';
2
2
  const COMPLETION_SHELLS = ['bash', 'zsh'];
3
- const DB_COMMANDS = ['migrate', 'reset', 'seed', 'status', 'wipe'];
3
+ const DB_COMMANDS = ['migrate', 'reset', 'rollback', 'seed', 'status', 'wipe'];
4
4
  const HELP_COMMANDS = [
5
+ 'assets',
5
6
  'completion',
6
7
  'db',
7
8
  'doctor',
@@ -12,6 +13,7 @@ const HELP_COMMANDS = [
12
13
  'version',
13
14
  ];
14
15
  const ROOT_COMMANDS = [
16
+ 'assets',
15
17
  'completion',
16
18
  'db',
17
19
  'doctor',
@@ -184,6 +186,9 @@ function completeCommand(command, tokens, currentWord, usedGlobalFlags) {
184
186
  if (command === 'help') {
185
187
  return completeHelp(tokens, currentWord, usedGlobalFlags);
186
188
  }
189
+ if (command === 'assets') {
190
+ return completeAssets(tokens, currentWord, usedGlobalFlags);
191
+ }
187
192
  if (command === 'new') {
188
193
  return completeNew(tokens, currentWord, usedGlobalFlags);
189
194
  }
@@ -212,6 +217,22 @@ function completeCommand(command, tokens, currentWord, usedGlobalFlags) {
212
217
  }
213
218
  return completeValues([], currentWord);
214
219
  }
220
+ function completeAssets(tokens, currentWord, usedGlobalFlags) {
221
+ let filteredTokens = filterGlobalCommandTokens(tokens, usedGlobalFlags);
222
+ if (filteredTokens == null) {
223
+ return completeValues([], currentWord);
224
+ }
225
+ if (filteredTokens.length === 0) {
226
+ return completeValues(withHelpFlags(['inspect'], usedGlobalFlags), currentWord);
227
+ }
228
+ let [subcommand, ...rest] = filteredTokens;
229
+ if (subcommand !== 'inspect' || rest.length > 0) {
230
+ return completeValues([], currentWord);
231
+ }
232
+ return currentWord.startsWith('-')
233
+ ? completeValues(withHelpFlags([], usedGlobalFlags), currentWord)
234
+ : { mode: 'files' };
235
+ }
215
236
  function completeTest(tokens, currentWord, usedGlobalFlags) {
216
237
  let filteredTokens = filterGlobalCommandTokens(tokens, usedGlobalFlags);
217
238
  if (filteredTokens == null) {
@@ -392,6 +413,9 @@ function completeDb(tokens, currentWord, usedGlobalFlags) {
392
413
  if (subcommand === 'reset') {
393
414
  return completeDbOptions(rest, currentWord, usedGlobalFlags, ['--force'], ['--connection-env', '--journal-table', '--migrations', '--seed']);
394
415
  }
416
+ if (subcommand === 'rollback') {
417
+ return completeDbOptions(rest, currentWord, usedGlobalFlags, ['--dry-run'], ['--connection-env', '--journal-table', '--migrations', '--step', '--to']);
418
+ }
395
419
  if (subcommand === 'wipe') {
396
420
  return completeDbOptions(rest, currentWord, usedGlobalFlags, ['--force'], ['--connection-env']);
397
421
  }
@@ -1,19 +1,23 @@
1
1
  import type { RemixDbAdapterConfig } from './remix-config.ts';
2
- export type DatabaseCommand = 'migrate' | 'reset' | 'seed' | 'status' | 'wipe';
2
+ export type DatabaseCommand = 'migrate' | 'reset' | 'rollback' | 'seed' | 'status' | 'wipe';
3
3
  export interface DatabaseCommandInvocation {
4
4
  command: DatabaseCommand;
5
5
  connectionEnv?: string;
6
+ dryRun?: boolean;
6
7
  journalTable?: string;
7
8
  migrations?: string;
8
9
  seed?: string;
10
+ step?: number;
9
11
  to?: string;
10
12
  }
11
13
  export interface DatabaseCommandPlan {
12
14
  adapter: RemixDbAdapterConfig;
13
15
  command: DatabaseCommand;
16
+ dryRun?: boolean;
14
17
  journalTable?: string;
15
18
  migrations?: string;
16
19
  seed?: string;
20
+ step?: number;
17
21
  to?: string;
18
22
  }
19
23
  export declare function isDatabaseCommand(value: unknown): value is DatabaseCommand;
@@ -1 +1 @@
1
- {"version":3,"file":"database-command.d.ts","sourceRoot":"","sources":["../../src/lib/database-command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AAE7D,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAA;AAE9E,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,eAAe,CAAA;IACxB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,EAAE,CAAC,EAAE,MAAM,CAAA;CACZ;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,oBAAoB,CAAA;IAC7B,OAAO,EAAE,eAAe,CAAA;IACxB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,EAAE,CAAC,EAAE,MAAM,CAAA;CACZ;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,eAAe,CAQ1E"}
1
+ {"version":3,"file":"database-command.d.ts","sourceRoot":"","sources":["../../src/lib/database-command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AAE7D,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,OAAO,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAA;AAE3F,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,eAAe,CAAA;IACxB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,EAAE,CAAC,EAAE,MAAM,CAAA;CACZ;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,oBAAoB,CAAA;IAC7B,OAAO,EAAE,eAAe,CAAA;IACxB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,EAAE,CAAC,EAAE,MAAM,CAAA;CACZ;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,eAAe,CAS1E"}
@@ -1,6 +1,7 @@
1
1
  export function isDatabaseCommand(value) {
2
2
  return (value === 'migrate' ||
3
3
  value === 'reset' ||
4
+ value === 'rollback' ||
4
5
  value === 'seed' ||
5
6
  value === 'status' ||
6
7
  value === 'wipe');
@@ -20,6 +20,11 @@ export declare const CLI_ERROR_DEFINITIONS: {
20
20
  title: string;
21
21
  fix: string;
22
22
  };
23
+ assetsConfigRequired: {
24
+ code: string;
25
+ title: string;
26
+ fix: string;
27
+ };
23
28
  dbConfigRequired: {
24
29
  code: string;
25
30
  title: string;
@@ -164,6 +169,7 @@ export declare class UsageError extends CliError {
164
169
  constructor(options: CliErrorOptions);
165
170
  }
166
171
  export declare function appNameUnavailable(targetDir?: string): UsageError;
172
+ export declare function assetsConfigRequired(): CliError;
167
173
  export declare function dbConfigRequired(filePath: string): CliError;
168
174
  export declare function dbForceRequired(command: string): UsageError;
169
175
  export declare function remixVersionUnavailable(): CliError;
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"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"}