@remix-run/cli 0.3.3 → 0.4.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 +105 -1
- package/dist/index.js +1 -1
- package/dist/lib/app-root.d.ts +11 -0
- package/dist/lib/app-root.d.ts.map +1 -0
- package/dist/lib/app-root.js +38 -0
- package/dist/lib/bootstrap-project.js +2 -2
- package/dist/lib/cli-context.d.ts +6 -0
- package/dist/lib/cli-context.d.ts.map +1 -1
- package/dist/lib/cli-context.js +12 -1
- package/dist/lib/cli.d.ts +3 -2
- package/dist/lib/cli.d.ts.map +1 -1
- package/dist/lib/cli.js +42 -14
- package/dist/lib/commands/completion.js +4 -4
- package/dist/lib/commands/db.d.ts +4 -0
- package/dist/lib/commands/db.d.ts.map +1 -0
- package/dist/lib/commands/db.js +283 -0
- package/dist/lib/commands/doctor.d.ts +5 -0
- package/dist/lib/commands/doctor.d.ts.map +1 -1
- package/dist/lib/commands/doctor.js +26 -251
- package/dist/lib/commands/help.d.ts.map +1 -1
- package/dist/lib/commands/help.js +17 -9
- package/dist/lib/commands/new.js +6 -6
- package/dist/lib/commands/routes.js +6 -6
- package/dist/lib/commands/test.d.ts +20 -1
- package/dist/lib/commands/test.d.ts.map +1 -1
- package/dist/lib/commands/test.js +353 -10
- package/dist/lib/commands/version.js +3 -3
- package/dist/lib/completion.d.ts +1 -1
- package/dist/lib/completion.d.ts.map +1 -1
- package/dist/lib/completion.js +229 -6
- package/dist/lib/controller-files.d.ts +0 -8
- package/dist/lib/controller-files.d.ts.map +1 -1
- package/dist/lib/controller-files.js +0 -23
- package/dist/lib/controller-ownership.d.ts +4 -12
- package/dist/lib/controller-ownership.d.ts.map +1 -1
- package/dist/lib/controller-ownership.js +31 -127
- package/dist/lib/database-command.d.ts +20 -0
- package/dist/lib/database-command.d.ts.map +1 -0
- package/dist/lib/database-command.js +7 -0
- package/dist/lib/doctor/controller-findings.d.ts +2 -2
- package/dist/lib/doctor/controller-findings.d.ts.map +1 -1
- package/dist/lib/doctor/controller-findings.js +23 -39
- package/dist/lib/doctor/controllers.d.ts +1 -2
- package/dist/lib/doctor/controllers.d.ts.map +1 -1
- package/dist/lib/doctor/controllers.js +4 -7
- package/dist/lib/doctor/environment.js +2 -2
- package/dist/lib/doctor/fixes.d.ts.map +1 -1
- package/dist/lib/doctor/fixes.js +46 -7
- package/dist/lib/doctor/project.d.ts.map +1 -1
- package/dist/lib/doctor/project.js +3 -212
- package/dist/lib/doctor/run.d.ts +9 -0
- package/dist/lib/doctor/run.d.ts.map +1 -0
- package/dist/lib/doctor/run.js +237 -0
- package/dist/lib/doctor/types.d.ts +2 -1
- package/dist/lib/doctor/types.d.ts.map +1 -1
- package/dist/lib/doctor/types.js +4 -1
- package/dist/lib/errors.d.ts +30 -0
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +55 -0
- package/dist/lib/help-text.js +1 -1
- package/dist/lib/parse-args.d.ts.map +1 -1
- package/dist/lib/parse-args.js +17 -4
- package/dist/lib/remix-config.d.ts +75 -0
- package/dist/lib/remix-config.d.ts.map +1 -0
- package/dist/lib/remix-config.js +411 -0
- package/dist/lib/reporter.js +1 -1
- package/dist/lib/route-map.js +13 -33
- package/package.json +12 -6
- package/schema/remix.json +242 -0
- package/src/lib/app-root.ts +46 -0
- package/src/lib/cli-context.ts +17 -0
- package/src/lib/cli.ts +41 -6
- package/src/lib/commands/db.ts +377 -0
- package/src/lib/commands/doctor.ts +27 -329
- package/src/lib/commands/help.ts +10 -1
- package/src/lib/commands/test.ts +453 -12
- package/src/lib/completion.ts +321 -6
- package/src/lib/controller-files.ts +0 -38
- package/src/lib/controller-ownership.ts +50 -203
- package/src/lib/database-command.ts +31 -0
- package/src/lib/doctor/controller-findings.ts +30 -47
- package/src/lib/doctor/controllers.ts +2 -6
- package/src/lib/doctor/fixes.ts +55 -6
- package/src/lib/doctor/project.ts +0 -236
- package/src/lib/doctor/run.ts +311 -0
- package/src/lib/doctor/types.ts +6 -5
- package/src/lib/errors.ts +65 -0
- package/src/lib/parse-args.ts +19 -3
- package/src/lib/remix-config.ts +639 -0
- package/src/lib/route-map.ts +11 -48
- package/template/.agents/skills/remix/SKILL.md +39 -28
- package/template/.agents/skills/remix/references/assets-and-browser-modules.md +53 -10
- package/template/.agents/skills/remix/references/auth-and-sessions.md +5 -5
- package/template/.agents/skills/remix/references/data-and-validation.md +15 -15
- package/template/.agents/skills/remix/references/hydration-frames-navigation.md +54 -8
- package/template/.agents/skills/remix/references/middleware-and-server.md +68 -6
- package/template/.agents/skills/remix/references/mixins-styling-events.md +2 -0
- package/template/.agents/skills/remix/references/routing-and-controllers.md +8 -8
- package/template/.agents/skills/remix/references/testing-patterns.md +19 -18
- package/template/AGENTS.md +6 -3
- package/template/README.md +6 -3
- package/template/app/actions/controller.tsx +1 -1
- package/template/app/{ui → actions}/document.tsx +7 -5
- package/template/app/{ui/scaffold-home-page.tsx → actions/home-page.tsx} +2 -3
- package/template/app/actions/public/entry.ts +48 -0
- package/template/app/{assets → actions/public}/prompt-button.tsx +29 -25
- package/template/app/assets.ts +19 -8
- package/template/app/middleware/render.tsx +29 -1
- package/template/hmr.ts +46 -0
- package/template/package.json +4 -3
- package/template/server.ts +8 -1
- package/template/tsconfig.json +1 -1
- package/dist/lib/doctor/controller-fix-plans.d.ts +0 -4
- package/dist/lib/doctor/controller-fix-plans.d.ts.map +0 -1
- package/dist/lib/doctor/controller-fix-plans.js +0 -119
- package/dist/lib/doctor/controller-placeholders.d.ts +0 -3
- package/dist/lib/doctor/controller-placeholders.d.ts.map +0 -1
- package/dist/lib/doctor/controller-placeholders.js +0 -52
- package/src/lib/doctor/controller-fix-plans.ts +0 -168
- package/src/lib/doctor/controller-placeholders.ts +0 -70
- package/template/app/assets/entry.ts +0 -8
package/README.md
CHANGED
|
@@ -7,9 +7,11 @@ Command-line interface for creating and managing Remix projects.
|
|
|
7
7
|
- Create new Remix projects with `npx remix@next new` or installed `remix new`
|
|
8
8
|
- Print shell completion scripts with `remix completion`
|
|
9
9
|
- Check project environment and Remix app conventions with `remix doctor`
|
|
10
|
-
-
|
|
10
|
+
- Apply available low-risk project fixes with `remix doctor --fix`
|
|
11
|
+
- Manage the current app database with `remix db`
|
|
11
12
|
- Inspect the current app route tree with `remix routes`
|
|
12
13
|
- Run project tests with `remix test`
|
|
14
|
+
- Configure commands with a static, commented `remix.json` file
|
|
13
15
|
- Print the current Remix version with `remix version`
|
|
14
16
|
- Use the same CLI through the `remix` package or the `remix/cli` API
|
|
15
17
|
- Scaffold a starter app that matches the Remix project layout conventions
|
|
@@ -47,6 +49,9 @@ remix new my-remix-app
|
|
|
47
49
|
remix completion bash >> ~/.bashrc
|
|
48
50
|
remix doctor
|
|
49
51
|
remix doctor --fix
|
|
52
|
+
remix db migrate
|
|
53
|
+
remix db status
|
|
54
|
+
remix db reset --force
|
|
50
55
|
remix routes
|
|
51
56
|
remix routes --table
|
|
52
57
|
remix routes --table --no-headers
|
|
@@ -64,6 +69,9 @@ await runRemix(['new', 'my-remix-app'])
|
|
|
64
69
|
await runRemix(['completion', 'bash'])
|
|
65
70
|
await runRemix(['doctor'])
|
|
66
71
|
await runRemix(['doctor', '--fix'])
|
|
72
|
+
await runRemix(['db', 'migrate'])
|
|
73
|
+
await runRemix(['db', 'status'])
|
|
74
|
+
await runRemix(['db', 'reset', '--force'])
|
|
67
75
|
await runRemix(['routes'])
|
|
68
76
|
await runRemix(['routes', '--table'])
|
|
69
77
|
await runRemix(['routes', '--table', '--no-headers'])
|
|
@@ -71,8 +79,104 @@ await runRemix(['test'])
|
|
|
71
79
|
await runRemix(['version'])
|
|
72
80
|
```
|
|
73
81
|
|
|
82
|
+
Destructive database commands (`remix db wipe` and `remix db reset`) refuse to run without `--force`.
|
|
83
|
+
|
|
74
84
|
`runRemix()` returns the CLI exit code as a promise.
|
|
75
85
|
|
|
86
|
+
## Configuration
|
|
87
|
+
|
|
88
|
+
The CLI loads an optional `remix.json`. The file is parsed as JSONC, so it may contain comments and
|
|
89
|
+
trailing commas. Every top-level field is optional:
|
|
90
|
+
|
|
91
|
+
```jsonc
|
|
92
|
+
{
|
|
93
|
+
"$schema": "https://remix.run/schemas/remix.json",
|
|
94
|
+
|
|
95
|
+
"db": {
|
|
96
|
+
"adapter": {
|
|
97
|
+
"type": "sqlite",
|
|
98
|
+
"filename": { "env": "DATABASE_URL", "default": "./db/app.sqlite" },
|
|
99
|
+
"foreignKeys": true,
|
|
100
|
+
"busyTimeout": 5000,
|
|
101
|
+
},
|
|
102
|
+
"migrations": {
|
|
103
|
+
"directory": "./db/migrations",
|
|
104
|
+
"journalTable": "data_table_migrations",
|
|
105
|
+
},
|
|
106
|
+
"seed": "./db/seed.sql",
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
"doctor": {
|
|
110
|
+
"strict": true,
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
"test": {
|
|
114
|
+
// Test discovery
|
|
115
|
+
"files": ["**/*.test{,.browser,.e2e}.{ts,tsx}"],
|
|
116
|
+
"browserFiles": ["**/*.test.browser.{ts,tsx}"],
|
|
117
|
+
"e2eFiles": ["**/*.test.e2e.{ts,tsx}"],
|
|
118
|
+
"exclude": ["node_modules/**", "dist/**"],
|
|
119
|
+
"type": ["server", "browser", "e2e"],
|
|
120
|
+
"only": ["/checkout/i"],
|
|
121
|
+
|
|
122
|
+
// Test execution
|
|
123
|
+
"concurrency": 4,
|
|
124
|
+
"pool": "forks",
|
|
125
|
+
"setup": "./test/setup.ts",
|
|
126
|
+
"watch": false,
|
|
127
|
+
|
|
128
|
+
// Playwright
|
|
129
|
+
"playwright": {
|
|
130
|
+
"echo": false,
|
|
131
|
+
"open": false,
|
|
132
|
+
"configFile": "./playwright.config.ts",
|
|
133
|
+
"projects": ["chromium", "firefox"],
|
|
134
|
+
},
|
|
135
|
+
|
|
136
|
+
// Output
|
|
137
|
+
"reporter": "spec",
|
|
138
|
+
"quiet": false,
|
|
139
|
+
|
|
140
|
+
// Coverage
|
|
141
|
+
"coverage": {
|
|
142
|
+
"enabled": true,
|
|
143
|
+
"dir": ".coverage",
|
|
144
|
+
"include": ["app/**"],
|
|
145
|
+
"exclude": ["**/*.test.*"],
|
|
146
|
+
"branches": 80,
|
|
147
|
+
"functions": 80,
|
|
148
|
+
"lines": 80,
|
|
149
|
+
"statements": 80,
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Explicit command flags and positional arguments override configured values. Repeated flags replace
|
|
156
|
+
configured arrays, while nested Playwright and coverage settings merge by field. Relative paths and
|
|
157
|
+
globs are resolved from the directory containing the config file. Use `remix doctor --no-strict` to
|
|
158
|
+
disable configured strict mode for one run.
|
|
159
|
+
|
|
160
|
+
`remix db` requires `db.adapter`. Adapters use `type: "sqlite"`, `type: "postgres"`, or
|
|
161
|
+
`type: "mysql"`; PostgreSQL uses `connectionString` and MySQL uses `uri`. A connection value may be
|
|
162
|
+
a string or an object naming an environment variable with an optional default. `db.seed` names a
|
|
163
|
+
SQL file that `remix db seed` and `remix db reset` run against the database. Database flags such as
|
|
164
|
+
`--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.
|
|
167
|
+
|
|
168
|
+
Use the global `--config` option to select another JSONC file. The option itself is resolved from the
|
|
169
|
+
CLI working directory and may appear before or after the command:
|
|
170
|
+
|
|
171
|
+
```sh
|
|
172
|
+
remix --config ./config/remix.ci.json test
|
|
173
|
+
remix test --config ./config/remix.ci.json
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
A missing default `remix.json` is ignored. A missing explicitly selected file, malformed JSONC,
|
|
177
|
+
unknown property, or invalid value is reported as a CLI error. The optional `$schema` field enables
|
|
178
|
+
editor completion and validation; it has no runtime effect.
|
|
179
|
+
|
|
76
180
|
## License
|
|
77
181
|
|
|
78
182
|
See [LICENSE](https://github.com/remix-run/remix/blob/main/LICENSE)
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { runRemix } from
|
|
1
|
+
export { runRemix } from './lib/cli.js';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Walks up from `startDir` looking for the closest directory that contains
|
|
3
|
+
* `relativeFilePath`.
|
|
4
|
+
*
|
|
5
|
+
* @param startDir Directory the walk starts from.
|
|
6
|
+
* @param relativeFilePath Slash-separated app file path, for example `app/routes.ts`.
|
|
7
|
+
* @returns The closest ancestor directory that contains the file, or `null`
|
|
8
|
+
* when no ancestor contains it.
|
|
9
|
+
*/
|
|
10
|
+
export declare function findAppRoot(startDir: string, relativeFilePath: string): Promise<string | null>;
|
|
11
|
+
//# sourceMappingURL=app-root.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-root.d.ts","sourceRoot":"","sources":["../../src/lib/app-root.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,MAAM,EAChB,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAgBxB"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as fs from 'node:fs/promises';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* Walks up from `startDir` looking for the closest directory that contains
|
|
5
|
+
* `relativeFilePath`.
|
|
6
|
+
*
|
|
7
|
+
* @param startDir Directory the walk starts from.
|
|
8
|
+
* @param relativeFilePath Slash-separated app file path, for example `app/routes.ts`.
|
|
9
|
+
* @returns The closest ancestor directory that contains the file, or `null`
|
|
10
|
+
* when no ancestor contains it.
|
|
11
|
+
*/
|
|
12
|
+
export async function findAppRoot(startDir, relativeFilePath) {
|
|
13
|
+
let relativeSegments = relativeFilePath.split('/');
|
|
14
|
+
let currentDir = path.resolve(startDir);
|
|
15
|
+
while (true) {
|
|
16
|
+
if (await pathExists(path.join(currentDir, ...relativeSegments))) {
|
|
17
|
+
return currentDir;
|
|
18
|
+
}
|
|
19
|
+
let parentDir = path.dirname(currentDir);
|
|
20
|
+
if (parentDir === currentDir) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
currentDir = parentDir;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
async function pathExists(filePath) {
|
|
27
|
+
try {
|
|
28
|
+
await fs.access(filePath);
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
let nodeError = error;
|
|
33
|
+
if (nodeError.code === 'ENOENT') {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
throw error;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -3,8 +3,8 @@ import * as path from 'node:path';
|
|
|
3
3
|
import * as process from 'node:process';
|
|
4
4
|
import { fileURLToPath } from 'node:url';
|
|
5
5
|
import semver from 'semver';
|
|
6
|
-
import { appNameUnavailable, invalidPackageName, targetDirectoryNotEmpty, targetPathNotDirectory, } from
|
|
7
|
-
import { runProgressStep } from
|
|
6
|
+
import { appNameUnavailable, invalidPackageName, targetDirectoryNotEmpty, targetPathNotDirectory, } from './errors.js';
|
|
7
|
+
import { runProgressStep } from './reporter.js';
|
|
8
8
|
const MODULE_DIRECTORY = path.dirname(fileURLToPath(import.meta.url));
|
|
9
9
|
const PACKAGE_TEMPLATE_DIRECTORY = path.resolve(MODULE_DIRECTORY, '../../template');
|
|
10
10
|
const IS_RUNNING_FROM_SRC = path.extname(new URL(import.meta.url).pathname) === '.ts';
|
|
@@ -1,9 +1,15 @@
|
|
|
1
|
+
import { type RemixConfig } from './remix-config.ts';
|
|
1
2
|
interface ResolveCliContextOptions {
|
|
3
|
+
configPath?: string;
|
|
2
4
|
cwd?: string;
|
|
3
5
|
remixVersion?: string;
|
|
4
6
|
}
|
|
5
7
|
export interface CliContext {
|
|
8
|
+
/** Explicit Remix configuration path selected by the caller. */
|
|
9
|
+
configPath?: string;
|
|
6
10
|
cwd: string;
|
|
11
|
+
/** Loads and validates the Remix config file, memoizing the result. */
|
|
12
|
+
loadConfig(): Promise<RemixConfig>;
|
|
7
13
|
remixVersion?: string;
|
|
8
14
|
}
|
|
9
15
|
export declare function resolveCliContext(options?: ResolveCliContextOptions): Promise<CliContext>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-context.d.ts","sourceRoot":"","sources":["../../src/lib/cli-context.ts"],"names":[],"mappings":"
|
|
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"}
|
package/dist/lib/cli-context.js
CHANGED
|
@@ -1,11 +1,22 @@
|
|
|
1
1
|
import * as path from 'node:path';
|
|
2
2
|
import * as process from 'node:process';
|
|
3
|
-
import { resolveDefaultRemixVersion } from
|
|
3
|
+
import { resolveDefaultRemixVersion } from './remix-version.js';
|
|
4
|
+
import { loadRemixConfig } from './remix-config.js';
|
|
4
5
|
export async function resolveCliContext(options = {}) {
|
|
5
6
|
let cwd = resolveCwd(options.cwd);
|
|
6
7
|
let remixVersion = normalizeRemixVersion(options.remixVersion);
|
|
8
|
+
let configPromise;
|
|
9
|
+
let loadConfig = () => (configPromise ??= loadRemixConfig(cwd, options.configPath));
|
|
10
|
+
// Validate an explicitly selected config file up front so every command
|
|
11
|
+
// fails fast on a bad --config path. The default remix.json is loaded
|
|
12
|
+
// lazily by the commands that read it, so an invalid file doesn't break
|
|
13
|
+
// unrelated commands like help, version, or shell completion.
|
|
14
|
+
if (options.configPath !== undefined)
|
|
15
|
+
await loadConfig();
|
|
7
16
|
return {
|
|
17
|
+
configPath: options.configPath,
|
|
8
18
|
cwd,
|
|
19
|
+
loadConfig,
|
|
9
20
|
remixVersion: remixVersion ?? (await resolveDefaultRemixVersion(cwd)),
|
|
10
21
|
};
|
|
11
22
|
}
|
package/dist/lib/cli.d.ts
CHANGED
|
@@ -15,8 +15,9 @@ export interface RunRemixOptions {
|
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
17
17
|
* Entry point for the `remix` CLI. Parses `argv`, dispatches to the matching
|
|
18
|
-
* subcommand (`new`, `doctor`, `routes`, `test`, `version`,
|
|
19
|
-
* `help`), and resolves with the exit code the process should
|
|
18
|
+
* subcommand (`new`, `db`, `doctor`, `routes`, `test`, `version`,
|
|
19
|
+
* `completion`, `help`), and resolves with the exit code the process should
|
|
20
|
+
* use.
|
|
20
21
|
*
|
|
21
22
|
* @param argv Argument vector to parse, excluding the node and script paths
|
|
22
23
|
* (default `process.argv.slice(2)`).
|
package/dist/lib/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/lib/cli.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/lib/cli.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,QAAQ,CAC5B,IAAI,GAAE,MAAM,EAA0B,EACtC,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,MAAM,CAAC,CA8BjB"}
|
package/dist/lib/cli.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import * as process from 'node:process';
|
|
2
|
-
import { getCliHelpText, runHelpCommand } from
|
|
3
|
-
import { resolveCliContext } from
|
|
4
|
-
import { renderCliError, unknownCommand } from
|
|
5
|
-
import { configureColors, restoreTerminalFormatting } from
|
|
2
|
+
import { getCliHelpText, runHelpCommand } from './commands/help.js';
|
|
3
|
+
import { resolveCliContext } from './cli-context.js';
|
|
4
|
+
import { missingOptionValue, renderCliError, toCliError, unknownCommand } from './errors.js';
|
|
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`, `doctor`, `routes`, `test`, `version`,
|
|
9
|
-
* `help`), and resolves with the exit code the process should
|
|
8
|
+
* subcommand (`new`, `db`, `doctor`, `routes`, `test`, `version`,
|
|
9
|
+
* `completion`, `help`), and resolves with the exit code the process should
|
|
10
|
+
* use.
|
|
10
11
|
*
|
|
11
12
|
* @param argv Argument vector to parse, excluding the node and script paths
|
|
12
13
|
* (default `process.argv.slice(2)`).
|
|
@@ -22,12 +23,12 @@ import { configureColors, restoreTerminalFormatting } from "./terminal.js";
|
|
|
22
23
|
* ```
|
|
23
24
|
*/
|
|
24
25
|
export async function runRemix(argv = process.argv.slice(2), options = {}) {
|
|
25
|
-
let context = await resolveCliContext(options);
|
|
26
26
|
try {
|
|
27
27
|
argv = stripLeadingSeparators(argv);
|
|
28
28
|
let globalOptions = extractGlobalOptions(argv);
|
|
29
29
|
argv = stripLeadingSeparators(globalOptions.argv);
|
|
30
30
|
configureColors({ disabled: globalOptions.noColor });
|
|
31
|
+
let context = await resolveCliContext({ ...options, configPath: globalOptions.configPath });
|
|
31
32
|
if (argv.length === 0) {
|
|
32
33
|
process.stdout.write(getCliHelpText());
|
|
33
34
|
return 0;
|
|
@@ -39,6 +40,10 @@ export async function runRemix(argv = process.argv.slice(2), options = {}) {
|
|
|
39
40
|
}
|
|
40
41
|
return await runCommand(command, rest, context);
|
|
41
42
|
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
process.stderr.write(renderCliError(toCliError(error), { helpText: getCliHelpText(process.stderr) }));
|
|
45
|
+
return 1;
|
|
46
|
+
}
|
|
42
47
|
finally {
|
|
43
48
|
restoreTerminalFormatting();
|
|
44
49
|
}
|
|
@@ -54,31 +59,35 @@ async function runCommand(command, argv, context) {
|
|
|
54
59
|
return runHelpCommand(argv);
|
|
55
60
|
}
|
|
56
61
|
if (command === '-v' || command === '--version') {
|
|
57
|
-
let { runVersionCommand } = await import(
|
|
62
|
+
let { runVersionCommand } = await import('./commands/version.js');
|
|
58
63
|
return runVersionCommand([], context);
|
|
59
64
|
}
|
|
60
65
|
if (command === 'new') {
|
|
61
|
-
let { runNewCommand } = await import(
|
|
66
|
+
let { runNewCommand } = await import('./commands/new.js');
|
|
62
67
|
return runNewCommand(argv, context);
|
|
63
68
|
}
|
|
64
69
|
if (command === 'completion') {
|
|
65
|
-
let { runCompletionCommand } = await import(
|
|
70
|
+
let { runCompletionCommand } = await import('./commands/completion.js');
|
|
66
71
|
return runCompletionCommand(argv);
|
|
67
72
|
}
|
|
68
73
|
if (command === 'doctor') {
|
|
69
|
-
let { runDoctorCommand } = await import(
|
|
74
|
+
let { runDoctorCommand } = await import('./commands/doctor.js');
|
|
70
75
|
return runDoctorCommand(argv, context);
|
|
71
76
|
}
|
|
77
|
+
if (command === 'db') {
|
|
78
|
+
let { runDbCommand } = await import('./commands/db.js');
|
|
79
|
+
return runDbCommand(argv, context);
|
|
80
|
+
}
|
|
72
81
|
if (command === 'routes') {
|
|
73
|
-
let { runRoutesCommand } = await import(
|
|
82
|
+
let { runRoutesCommand } = await import('./commands/routes.js');
|
|
74
83
|
return runRoutesCommand(argv, context);
|
|
75
84
|
}
|
|
76
85
|
if (command === 'test') {
|
|
77
|
-
let { runTestCommand } = await import(
|
|
86
|
+
let { runTestCommand } = await import('./commands/test.js');
|
|
78
87
|
return runTestCommand(argv, context);
|
|
79
88
|
}
|
|
80
89
|
if (command === 'version') {
|
|
81
|
-
let { runVersionCommand } = await import(
|
|
90
|
+
let { runVersionCommand } = await import('./commands/version.js');
|
|
82
91
|
return runVersionCommand(argv, context);
|
|
83
92
|
}
|
|
84
93
|
process.stderr.write(renderCliError(unknownCommand(command), { helpText: getCliHelpText(process.stderr) }));
|
|
@@ -86,6 +95,7 @@ async function runCommand(command, argv, context) {
|
|
|
86
95
|
}
|
|
87
96
|
function extractGlobalOptions(argv) {
|
|
88
97
|
let filteredArgv = [];
|
|
98
|
+
let configPath;
|
|
89
99
|
let noColor = false;
|
|
90
100
|
for (let index = 0; index < argv.length; index++) {
|
|
91
101
|
let arg = argv[index];
|
|
@@ -97,10 +107,28 @@ function extractGlobalOptions(argv) {
|
|
|
97
107
|
noColor = true;
|
|
98
108
|
continue;
|
|
99
109
|
}
|
|
110
|
+
if (arg === '--config') {
|
|
111
|
+
let value = argv[index + 1];
|
|
112
|
+
if (value == null || value.length === 0 || value.startsWith('-')) {
|
|
113
|
+
throw missingOptionValue('--config');
|
|
114
|
+
}
|
|
115
|
+
configPath = value;
|
|
116
|
+
index++;
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
if (arg.startsWith('--config=')) {
|
|
120
|
+
let value = arg.slice('--config='.length);
|
|
121
|
+
if (value.length === 0) {
|
|
122
|
+
throw missingOptionValue('--config');
|
|
123
|
+
}
|
|
124
|
+
configPath = value;
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
100
127
|
filteredArgv.push(arg);
|
|
101
128
|
}
|
|
102
129
|
return {
|
|
103
130
|
argv: filteredArgv,
|
|
131
|
+
configPath,
|
|
104
132
|
noColor,
|
|
105
133
|
};
|
|
106
134
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as process from 'node:process';
|
|
2
|
-
import { getCompletionResult, getCompletionScript, isCompletionShell, renderCompletionResult, } from
|
|
3
|
-
import { invalidCompletionRequest, renderCliError, toCliError, unknownCompletionShell, } from
|
|
4
|
-
import { formatHelpText } from
|
|
5
|
-
import { parseArgs } from
|
|
2
|
+
import { getCompletionResult, getCompletionScript, isCompletionShell, renderCompletionResult, } from '../completion.js';
|
|
3
|
+
import { invalidCompletionRequest, renderCliError, toCliError, unknownCompletionShell, } from '../errors.js';
|
|
4
|
+
import { formatHelpText } from '../help-text.js';
|
|
5
|
+
import { parseArgs } from '../parse-args.js';
|
|
6
6
|
export async function runCompletionCommand(argv) {
|
|
7
7
|
if (argv.length === 0) {
|
|
8
8
|
process.stdout.write(getCompletionCommandHelpText());
|
|
@@ -0,0 +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"}
|