@remix-run/cli 0.0.0 → 0.2.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/LICENSE +21 -0
- package/README.md +77 -3
- package/bootstrap/.agents/skills/remix/SKILL.md +501 -0
- package/bootstrap/.agents/skills/remix/references/animate-elements.md +195 -0
- package/bootstrap/.agents/skills/remix/references/assets-and-browser-modules.md +122 -0
- package/bootstrap/.agents/skills/remix/references/auth-and-sessions.md +420 -0
- package/bootstrap/.agents/skills/remix/references/component-model.md +282 -0
- package/bootstrap/.agents/skills/remix/references/create-mixins.md +158 -0
- package/bootstrap/.agents/skills/remix/references/data-and-validation.md +363 -0
- package/bootstrap/.agents/skills/remix/references/hydration-frames-navigation.md +297 -0
- package/bootstrap/.agents/skills/remix/references/middleware-and-server.md +243 -0
- package/bootstrap/.agents/skills/remix/references/mixins-styling-events.md +213 -0
- package/bootstrap/.agents/skills/remix/references/routing-and-controllers.md +324 -0
- package/bootstrap/.agents/skills/remix/references/testing-patterns.md +156 -0
- package/bootstrap/AGENTS.md +39 -0
- package/bootstrap/README.md +27 -0
- package/bootstrap/app/assets/entry.ts +19 -0
- package/bootstrap/app/assets.ts +18 -0
- package/bootstrap/app/controllers/auth.tsx +21 -0
- package/bootstrap/app/controllers/home.tsx +11 -0
- package/bootstrap/app/router.ts +16 -0
- package/bootstrap/app/routes.ts +7 -0
- package/bootstrap/app/ui/document.tsx +26 -0
- package/bootstrap/app/ui/layout.tsx +22 -0
- package/bootstrap/app/ui/prompt-button.tsx +162 -0
- package/bootstrap/app/ui/scaffold-home-page.tsx +526 -0
- package/bootstrap/app/utils/render.tsx +26 -0
- package/bootstrap/package.json +22 -0
- package/bootstrap/server.ts +37 -0
- package/bootstrap/tsconfig.json +18 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -0
- package/dist/lib/bootstrap-project.d.ts +17 -0
- package/dist/lib/bootstrap-project.d.ts.map +1 -0
- package/dist/lib/bootstrap-project.js +137 -0
- package/dist/lib/cli-context.d.ts +11 -0
- package/dist/lib/cli-context.d.ts.map +1 -0
- package/dist/lib/cli-context.js +19 -0
- package/dist/lib/cli.d.ts +6 -0
- package/dist/lib/cli.d.ts.map +1 -0
- package/dist/lib/cli.js +84 -0
- package/dist/lib/commands/completion.d.ts +3 -0
- package/dist/lib/commands/completion.d.ts.map +1 -0
- package/dist/lib/commands/completion.js +51 -0
- package/dist/lib/commands/doctor.d.ts +4 -0
- package/dist/lib/commands/doctor.d.ts.map +1 -0
- package/dist/lib/commands/doctor.js +293 -0
- package/dist/lib/commands/help.d.ts +4 -0
- package/dist/lib/commands/help.d.ts.map +1 -0
- package/dist/lib/commands/help.js +100 -0
- package/dist/lib/commands/new.d.ts +4 -0
- package/dist/lib/commands/new.d.ts.map +1 -0
- package/dist/lib/commands/new.js +70 -0
- package/dist/lib/commands/routes.d.ts +4 -0
- package/dist/lib/commands/routes.d.ts.map +1 -0
- package/dist/lib/commands/routes.js +161 -0
- package/dist/lib/commands/test.d.ts +4 -0
- package/dist/lib/commands/test.d.ts.map +1 -0
- package/dist/lib/commands/test.js +23 -0
- package/dist/lib/commands/version.d.ts +4 -0
- package/dist/lib/commands/version.d.ts.map +1 -0
- package/dist/lib/commands/version.js +29 -0
- package/dist/lib/completion.d.ts +12 -0
- package/dist/lib/completion.d.ts.map +1 -0
- package/dist/lib/completion.js +310 -0
- package/dist/lib/contained-path.d.ts +2 -0
- package/dist/lib/contained-path.d.ts.map +1 -0
- package/dist/lib/contained-path.js +10 -0
- package/dist/lib/controller-files.d.ts +14 -0
- package/dist/lib/controller-files.d.ts.map +1 -0
- package/dist/lib/controller-files.js +53 -0
- package/dist/lib/controller-ownership.d.ts +41 -0
- package/dist/lib/controller-ownership.d.ts.map +1 -0
- package/dist/lib/controller-ownership.js +224 -0
- package/dist/lib/display-path.d.ts +2 -0
- package/dist/lib/display-path.d.ts.map +1 -0
- package/dist/lib/display-path.js +12 -0
- package/dist/lib/doctor/controller-findings.d.ts +4 -0
- package/dist/lib/doctor/controller-findings.d.ts.map +1 -0
- package/dist/lib/doctor/controller-findings.js +132 -0
- package/dist/lib/doctor/controller-fix-plans.d.ts +4 -0
- package/dist/lib/doctor/controller-fix-plans.d.ts.map +1 -0
- package/dist/lib/doctor/controller-fix-plans.js +130 -0
- package/dist/lib/doctor/controller-placeholders.d.ts +4 -0
- package/dist/lib/doctor/controller-placeholders.d.ts.map +1 -0
- package/dist/lib/doctor/controller-placeholders.js +183 -0
- package/dist/lib/doctor/controllers.d.ts +8 -0
- package/dist/lib/doctor/controllers.d.ts.map +1 -0
- package/dist/lib/doctor/controllers.js +13 -0
- package/dist/lib/doctor/environment.d.ts +17 -0
- package/dist/lib/doctor/environment.d.ts.map +1 -0
- package/dist/lib/doctor/environment.js +226 -0
- package/dist/lib/doctor/fixes.d.ts +3 -0
- package/dist/lib/doctor/fixes.d.ts.map +1 -0
- package/dist/lib/doctor/fixes.js +65 -0
- package/dist/lib/doctor/project.d.ts +10 -0
- package/dist/lib/doctor/project.d.ts.map +1 -0
- package/dist/lib/doctor/project.js +371 -0
- package/dist/lib/doctor/types.d.ts +48 -0
- package/dist/lib/doctor/types.d.ts.map +1 -0
- package/dist/lib/doctor/types.js +15 -0
- package/dist/lib/errors.d.ts +167 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +307 -0
- package/dist/lib/help-text.d.ts +13 -0
- package/dist/lib/help-text.d.ts.map +1 -0
- package/dist/lib/help-text.js +43 -0
- package/dist/lib/load-route-map-worker.d.ts +2 -0
- package/dist/lib/load-route-map-worker.d.ts.map +1 -0
- package/dist/lib/load-route-map-worker.js +92 -0
- package/dist/lib/parse-args.d.ts +22 -0
- package/dist/lib/parse-args.d.ts.map +1 -0
- package/dist/lib/parse-args.js +35 -0
- package/dist/lib/remix-version.d.ts +2 -0
- package/dist/lib/remix-version.d.ts.map +1 -0
- package/dist/lib/remix-version.js +58 -0
- package/dist/lib/reporter.d.ts +56 -0
- package/dist/lib/reporter.d.ts.map +1 -0
- package/dist/lib/reporter.js +357 -0
- package/dist/lib/route-map.d.ts +38 -0
- package/dist/lib/route-map.d.ts.map +1 -0
- package/dist/lib/route-map.js +195 -0
- package/dist/lib/terminal.d.ts +17 -0
- package/dist/lib/terminal.d.ts.map +1 -0
- package/dist/lib/terminal.js +66 -0
- package/package.json +47 -5
- package/src/index.ts +1 -0
- package/src/lib/bootstrap-project.ts +222 -0
- package/src/lib/cli-context.ts +38 -0
- package/src/lib/cli.ts +116 -0
- package/src/lib/commands/completion.ts +74 -0
- package/src/lib/commands/doctor.ts +393 -0
- package/src/lib/commands/help.ts +123 -0
- package/src/lib/commands/new.ts +104 -0
- package/src/lib/commands/routes.ts +251 -0
- package/src/lib/commands/test.ts +31 -0
- package/src/lib/commands/version.ts +39 -0
- package/src/lib/completion.ts +418 -0
- package/src/lib/contained-path.ts +13 -0
- package/src/lib/controller-files.ts +79 -0
- package/src/lib/controller-ownership.ts +397 -0
- package/src/lib/display-path.ts +16 -0
- package/src/lib/doctor/controller-findings.ts +157 -0
- package/src/lib/doctor/controller-fix-plans.ts +184 -0
- package/src/lib/doctor/controller-placeholders.ts +242 -0
- package/src/lib/doctor/controllers.ts +23 -0
- package/src/lib/doctor/environment.ts +289 -0
- package/src/lib/doctor/fixes.ts +84 -0
- package/src/lib/doctor/project.ts +435 -0
- package/src/lib/doctor/types.ts +95 -0
- package/src/lib/errors.ts +367 -0
- package/src/lib/help-text.ts +88 -0
- package/src/lib/load-route-map-worker.ts +110 -0
- package/src/lib/parse-args.ts +82 -0
- package/src/lib/remix-version.ts +80 -0
- package/src/lib/reporter.ts +535 -0
- package/src/lib/route-map.ts +303 -0
- package/src/lib/terminal.ts +86 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import * as process from 'node:process';
|
|
2
|
+
import { renderCliError, toCliError, unknownHelpTopic } from "../errors.js";
|
|
3
|
+
import { formatHelpText } from "../help-text.js";
|
|
4
|
+
export async function runHelpCommand(argv) {
|
|
5
|
+
if (argv.includes('-h') || argv.includes('--help')) {
|
|
6
|
+
process.stdout.write(getHelpCommandHelpText());
|
|
7
|
+
return 0;
|
|
8
|
+
}
|
|
9
|
+
try {
|
|
10
|
+
process.stdout.write(await getCommandHelpText(argv));
|
|
11
|
+
return 0;
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
process.stderr.write(renderCliError(toCliError(error), { helpText: getCliHelpText(process.stderr) }));
|
|
15
|
+
return 1;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export function getCliHelpText(target = process.stdout) {
|
|
19
|
+
return formatHelpText({
|
|
20
|
+
commands: [
|
|
21
|
+
{ description: 'Print shell completion scripts for Remix', label: 'completion' },
|
|
22
|
+
{ description: 'Show help for Remix commands', label: 'help [command]' },
|
|
23
|
+
{ description: 'Create a new Remix project', label: 'new <name>' },
|
|
24
|
+
{ description: 'Check project health for the current project', label: 'doctor' },
|
|
25
|
+
{ description: 'Show the route tree for the current project', label: 'routes' },
|
|
26
|
+
{ description: 'Run tests for the current project', label: 'test [glob]' },
|
|
27
|
+
{ description: 'Show the current Remix version', label: 'version' },
|
|
28
|
+
],
|
|
29
|
+
examples: [
|
|
30
|
+
'remix completion bash',
|
|
31
|
+
'remix help',
|
|
32
|
+
'remix help completion',
|
|
33
|
+
'remix help doctor',
|
|
34
|
+
'remix doctor',
|
|
35
|
+
'remix new my-remix-app',
|
|
36
|
+
'remix new my-remix-app --app-name "My Remix App"',
|
|
37
|
+
'remix routes',
|
|
38
|
+
'remix test',
|
|
39
|
+
'remix version',
|
|
40
|
+
],
|
|
41
|
+
options: [
|
|
42
|
+
{ description: 'Show help', label: '-h, --help' },
|
|
43
|
+
{ description: 'Disable ANSI color output', label: '--no-color' },
|
|
44
|
+
{ description: 'Show version', label: '-v, --version' },
|
|
45
|
+
],
|
|
46
|
+
usage: ['remix <command> [options]'],
|
|
47
|
+
}, target);
|
|
48
|
+
}
|
|
49
|
+
export function getHelpCommandHelpText(target = process.stdout) {
|
|
50
|
+
return formatHelpText({
|
|
51
|
+
description: 'Show help for Remix commands.',
|
|
52
|
+
examples: [
|
|
53
|
+
'remix help',
|
|
54
|
+
'remix help completion',
|
|
55
|
+
'remix help doctor',
|
|
56
|
+
'remix help new',
|
|
57
|
+
'remix help routes',
|
|
58
|
+
'remix help test',
|
|
59
|
+
'remix help version',
|
|
60
|
+
],
|
|
61
|
+
usage: ['remix help [command]'],
|
|
62
|
+
}, target);
|
|
63
|
+
}
|
|
64
|
+
async function getCommandHelpText(argv) {
|
|
65
|
+
if (argv.length === 0) {
|
|
66
|
+
return getCliHelpText();
|
|
67
|
+
}
|
|
68
|
+
let [command, ...rest] = argv;
|
|
69
|
+
if (command === 'help') {
|
|
70
|
+
return rest.length === 0 ? getHelpCommandHelpText() : getNestedHelpText(command, rest);
|
|
71
|
+
}
|
|
72
|
+
if (command === 'new' && rest.length === 0) {
|
|
73
|
+
let { getNewCommandHelpText } = await import("./new.js");
|
|
74
|
+
return getNewCommandHelpText();
|
|
75
|
+
}
|
|
76
|
+
if (command === 'completion' && rest.length === 0) {
|
|
77
|
+
let { getCompletionCommandHelpText } = await import("./completion.js");
|
|
78
|
+
return getCompletionCommandHelpText();
|
|
79
|
+
}
|
|
80
|
+
if (command === 'doctor' && rest.length === 0) {
|
|
81
|
+
let { getDoctorCommandHelpText } = await import("./doctor.js");
|
|
82
|
+
return getDoctorCommandHelpText();
|
|
83
|
+
}
|
|
84
|
+
if (command === 'routes' && rest.length === 0) {
|
|
85
|
+
let { getRoutesCommandHelpText } = await import("./routes.js");
|
|
86
|
+
return getRoutesCommandHelpText();
|
|
87
|
+
}
|
|
88
|
+
if (command === 'test' && rest.length === 0) {
|
|
89
|
+
let { getTestCommandHelpText } = await import("./test.js");
|
|
90
|
+
return await getTestCommandHelpText();
|
|
91
|
+
}
|
|
92
|
+
if (command === 'version' && rest.length === 0) {
|
|
93
|
+
let { getVersionCommandHelpText } = await import("./version.js");
|
|
94
|
+
return getVersionCommandHelpText();
|
|
95
|
+
}
|
|
96
|
+
throw unknownHelpTopic(argv.join(' '));
|
|
97
|
+
}
|
|
98
|
+
function getNestedHelpText(command, argv) {
|
|
99
|
+
throw unknownHelpTopic(`${command} ${argv.join(' ')}`);
|
|
100
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"new.d.ts","sourceRoot":"","sources":["../../../src/lib/commands/new.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAiBnD,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAqCxF;AAED,wBAAgB,qBAAqB,CAAC,MAAM,GAAE,MAAM,CAAC,WAA4B,GAAG,MAAM,CAazF"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import * as process from 'node:process';
|
|
2
|
+
import { bootstrapProject } from "../bootstrap-project.js";
|
|
3
|
+
import { renderCliError, missingTargetDirectory, toCliError } from "../errors.js";
|
|
4
|
+
import { getDisplayPath } from "../display-path.js";
|
|
5
|
+
import { formatHelpText } from "../help-text.js";
|
|
6
|
+
import { parseArgs } from "../parse-args.js";
|
|
7
|
+
import { createCommandReporter, createStepProgressReporter, } from "../reporter.js";
|
|
8
|
+
const NEW_PROGRESS_LABELS = {
|
|
9
|
+
'finalize-package-json': 'Finalize package.json',
|
|
10
|
+
'generate-scaffold-files': 'Generate scaffold files',
|
|
11
|
+
'prepare-target-directory': 'Prepare target directory',
|
|
12
|
+
};
|
|
13
|
+
export async function runNewCommand(argv, context) {
|
|
14
|
+
if (argv.length === 0 || argv.includes('-h') || argv.includes('--help')) {
|
|
15
|
+
process.stdout.write(getNewCommandHelpText());
|
|
16
|
+
return 0;
|
|
17
|
+
}
|
|
18
|
+
let reporter = null;
|
|
19
|
+
let progress = null;
|
|
20
|
+
try {
|
|
21
|
+
let options = parseNewCommandArgs(argv);
|
|
22
|
+
reporter = createCommandReporter({ remixVersion: context.remixVersion });
|
|
23
|
+
progress = createNewProgressReporter(reporter);
|
|
24
|
+
await reporter.status.commandHeader('new');
|
|
25
|
+
let result = await bootstrapProject({
|
|
26
|
+
...options,
|
|
27
|
+
cwd: context.cwd,
|
|
28
|
+
remixVersion: context.remixVersion,
|
|
29
|
+
}, progress);
|
|
30
|
+
progress.writeSummaryGap();
|
|
31
|
+
reporter.out.line(`Created ${result.appDisplayName} at ${getDisplayPath(result.targetDir, context.cwd)}`);
|
|
32
|
+
reporter.finish();
|
|
33
|
+
return 0;
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
progress?.writeSummaryGap();
|
|
37
|
+
process.stderr.write(renderCliError(toCliError(error), { helpText: getNewCommandHelpText(process.stderr) }));
|
|
38
|
+
reporter?.finish();
|
|
39
|
+
return 1;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export function getNewCommandHelpText(target = process.stdout) {
|
|
43
|
+
return formatHelpText({
|
|
44
|
+
description: 'Create a new Remix project in the target directory.',
|
|
45
|
+
examples: [
|
|
46
|
+
'remix new ./my-remix-app',
|
|
47
|
+
'remix new ./my-remix-app --app-name "My Remix App"',
|
|
48
|
+
'remix new ./my-remix-app --force',
|
|
49
|
+
],
|
|
50
|
+
usage: ['remix new <target-dir> [--app-name <name>] [--force]'],
|
|
51
|
+
}, target);
|
|
52
|
+
}
|
|
53
|
+
function parseNewCommandArgs(argv) {
|
|
54
|
+
let parsed = parseArgs(argv, {
|
|
55
|
+
appName: { flag: '--app-name', type: 'string' },
|
|
56
|
+
force: { flag: '--force', type: 'boolean' },
|
|
57
|
+
}, { maxPositionals: 1 });
|
|
58
|
+
let targetDir = parsed.positionals[0] ?? null;
|
|
59
|
+
if (targetDir == null) {
|
|
60
|
+
throw missingTargetDirectory();
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
appName: parsed.options.appName ?? null,
|
|
64
|
+
force: parsed.options.force,
|
|
65
|
+
targetDir,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function createNewProgressReporter(reporter) {
|
|
69
|
+
return createStepProgressReporter(reporter.status, NEW_PROGRESS_LABELS);
|
|
70
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { CliContext } from '../cli-context.ts';
|
|
2
|
+
export declare function runRoutesCommand(argv: string[], context: CliContext): Promise<number>;
|
|
3
|
+
export declare function getRoutesCommandHelpText(target?: NodeJS.WriteStream): string;
|
|
4
|
+
//# sourceMappingURL=routes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../src/lib/commands/routes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAUnD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAyB3F;AAED,wBAAgB,wBAAwB,CAAC,MAAM,GAAE,MAAM,CAAC,WAA4B,GAAG,MAAM,CAwB5F"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import * as process from 'node:process';
|
|
2
|
+
import { invalidFlagCombination, renderCliError, toCliError } from "../errors.js";
|
|
3
|
+
import { formatHelpText } from "../help-text.js";
|
|
4
|
+
import { parseArgs } from "../parse-args.js";
|
|
5
|
+
import { createCommandReporter } from "../reporter.js";
|
|
6
|
+
import { loadRouteMap } from "../route-map.js";
|
|
7
|
+
import { lightRed } from "../terminal.js";
|
|
8
|
+
const CONTROLLERS_PATH_PREFIX = 'app/controllers/';
|
|
9
|
+
export async function runRoutesCommand(argv, context) {
|
|
10
|
+
if (argv.includes('-h') || argv.includes('--help')) {
|
|
11
|
+
process.stdout.write(getRoutesCommandHelpText());
|
|
12
|
+
return 0;
|
|
13
|
+
}
|
|
14
|
+
try {
|
|
15
|
+
let options = parseRoutesCommandArgs(argv);
|
|
16
|
+
let routeMap = await loadRouteMap(context.cwd);
|
|
17
|
+
if (options.json) {
|
|
18
|
+
process.stdout.write(`${JSON.stringify(routeMap, null, 2)}\n`);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
let reporter = createCommandReporter({ remixVersion: context.remixVersion });
|
|
22
|
+
writeRouteMap(reporter.out, routeMap, options);
|
|
23
|
+
reporter.finish();
|
|
24
|
+
}
|
|
25
|
+
return 0;
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
process.stderr.write(renderCliError(toCliError(error), { helpText: getRoutesCommandHelpText(process.stderr) }));
|
|
29
|
+
return 1;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export function getRoutesCommandHelpText(target = process.stdout) {
|
|
33
|
+
return formatHelpText({
|
|
34
|
+
description: 'Show the Remix route tree for the current app.',
|
|
35
|
+
examples: [
|
|
36
|
+
'remix routes',
|
|
37
|
+
'remix routes --table',
|
|
38
|
+
'remix routes --table --no-headers',
|
|
39
|
+
'remix routes --verbose',
|
|
40
|
+
'remix routes --json',
|
|
41
|
+
],
|
|
42
|
+
options: [
|
|
43
|
+
{ description: 'Print the normalized route tree as JSON', label: '--json' },
|
|
44
|
+
{ description: 'Print routes as a flat table', label: '--table' },
|
|
45
|
+
{
|
|
46
|
+
description: 'Omit the table header row when using --table',
|
|
47
|
+
label: '--no-headers',
|
|
48
|
+
},
|
|
49
|
+
{ description: 'Show full owner paths in tree or table output', label: '--verbose' },
|
|
50
|
+
],
|
|
51
|
+
usage: ['remix routes [--json | --table] [--no-headers] [--verbose] [--no-color]'],
|
|
52
|
+
}, target);
|
|
53
|
+
}
|
|
54
|
+
function parseRoutesCommandArgs(argv) {
|
|
55
|
+
let parsed = parseArgs(argv, {
|
|
56
|
+
json: { flag: '--json', type: 'boolean' },
|
|
57
|
+
noHeaders: { flag: '--no-headers', type: 'boolean' },
|
|
58
|
+
table: { flag: '--table', type: 'boolean' },
|
|
59
|
+
verbose: { flag: '--verbose', type: 'boolean' },
|
|
60
|
+
}, { maxPositionals: 0 });
|
|
61
|
+
let json = parsed.options.json;
|
|
62
|
+
let noHeaders = parsed.options.noHeaders;
|
|
63
|
+
let table = parsed.options.table;
|
|
64
|
+
let verbose = parsed.options.verbose;
|
|
65
|
+
if (json && table) {
|
|
66
|
+
throw invalidFlagCombination('Cannot combine --json with --table.');
|
|
67
|
+
}
|
|
68
|
+
if (json && verbose) {
|
|
69
|
+
throw invalidFlagCombination('Cannot combine --json with --verbose.');
|
|
70
|
+
}
|
|
71
|
+
if (noHeaders && !table) {
|
|
72
|
+
throw invalidFlagCombination('Cannot use --no-headers without --table.');
|
|
73
|
+
}
|
|
74
|
+
return { json, noHeaders, table, verbose };
|
|
75
|
+
}
|
|
76
|
+
function writeRouteMap(out, routeMap, options) {
|
|
77
|
+
if (routeMap.tree.length === 0) {
|
|
78
|
+
out.line('No routes.');
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (options.table) {
|
|
82
|
+
writeRouteTable(out, routeMap, options);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
let lines = [];
|
|
86
|
+
renderRouteNodes(lines, routeMap.tree, '', true, null, options);
|
|
87
|
+
for (let line of lines) {
|
|
88
|
+
out.line(line);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function renderRouteNodes(lines, nodes, prefix, isRoot, parentOwnerPath, options) {
|
|
92
|
+
let leafKeyWidth = getLeafKeyWidth(nodes);
|
|
93
|
+
nodes.forEach((node, index) => {
|
|
94
|
+
renderRouteNode(lines, node, prefix, index === nodes.length - 1, isRoot, parentOwnerPath, leafKeyWidth, options);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
function renderRouteNode(lines, node, prefix, isLast, isRoot, parentOwnerPath, leafKeyWidth, options) {
|
|
98
|
+
let branch = isRoot ? '' : isLast ? '└─ ' : '├─ ';
|
|
99
|
+
let line = `${prefix}${branch}${formatRouteNode(node, parentOwnerPath, leafKeyWidth, options)}`;
|
|
100
|
+
lines.push(colorRouteLine(line, node));
|
|
101
|
+
if (node.kind !== 'group') {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
let childPrefix = isRoot ? '' : `${prefix}${isLast ? ' ' : '│ '}`;
|
|
105
|
+
renderRouteNodes(lines, node.children, childPrefix, false, node.owner.path, options);
|
|
106
|
+
}
|
|
107
|
+
function getLeafKeyWidth(nodes) {
|
|
108
|
+
let leafNodes = nodes.filter((node) => node.kind === 'route');
|
|
109
|
+
return leafNodes.reduce((width, node) => Math.max(width, node.key.length), 0);
|
|
110
|
+
}
|
|
111
|
+
function formatRouteNode(node, parentOwnerPath, leafKeyWidth, options) {
|
|
112
|
+
let owner = formatOwner(node, options);
|
|
113
|
+
if (node.kind === 'group') {
|
|
114
|
+
return `${node.key} -> ${owner}`;
|
|
115
|
+
}
|
|
116
|
+
let leaf = `${node.key.padEnd(leafKeyWidth)} ${node.method.padEnd(6)} ${node.pattern}`;
|
|
117
|
+
if (options.verbose || parentOwnerPath == null || parentOwnerPath !== node.owner.path) {
|
|
118
|
+
return `${leaf} -> ${owner}`;
|
|
119
|
+
}
|
|
120
|
+
return leaf;
|
|
121
|
+
}
|
|
122
|
+
function writeRouteTable(out, routeMap, options) {
|
|
123
|
+
let rows = flattenRoutes(routeMap.tree).map((node) => ({
|
|
124
|
+
method: node.method,
|
|
125
|
+
node,
|
|
126
|
+
owner: formatOwner(node, options),
|
|
127
|
+
path: node.pattern,
|
|
128
|
+
route: node.name,
|
|
129
|
+
}));
|
|
130
|
+
out.table({
|
|
131
|
+
formatRow(line, rowIndex) {
|
|
132
|
+
return colorRouteLine(line, rows[rowIndex].node);
|
|
133
|
+
},
|
|
134
|
+
headers: ['Route', 'Method', 'Path', 'Owner'],
|
|
135
|
+
noHeaders: options.noHeaders,
|
|
136
|
+
rows: rows.map((row) => [row.route, row.method, row.path, row.owner]),
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
function flattenRoutes(nodes, routes = []) {
|
|
140
|
+
for (let node of nodes) {
|
|
141
|
+
if (node.kind === 'route') {
|
|
142
|
+
routes.push(node);
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
flattenRoutes(node.children, routes);
|
|
146
|
+
}
|
|
147
|
+
return routes;
|
|
148
|
+
}
|
|
149
|
+
function formatOwner(node, options) {
|
|
150
|
+
let ownerPath = options.verbose ? node.owner.path : getCompactOwnerPath(node.owner.path);
|
|
151
|
+
return `${ownerPath}${node.owner.exists ? '' : ' [missing]'}`;
|
|
152
|
+
}
|
|
153
|
+
function colorRouteLine(line, node) {
|
|
154
|
+
return node.owner.exists ? line : lightRed(line);
|
|
155
|
+
}
|
|
156
|
+
function getCompactOwnerPath(ownerPath) {
|
|
157
|
+
if (ownerPath.startsWith(CONTROLLERS_PATH_PREFIX)) {
|
|
158
|
+
return ownerPath.slice(CONTROLLERS_PATH_PREFIX.length);
|
|
159
|
+
}
|
|
160
|
+
return ownerPath;
|
|
161
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { CliContext } from '../cli-context.ts';
|
|
2
|
+
export declare function runTestCommand(argv: string[], context: CliContext): Promise<number>;
|
|
3
|
+
export declare function getTestCommandHelpText(target?: NodeJS.WriteStream): Promise<string>;
|
|
4
|
+
//# sourceMappingURL=test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../../../src/lib/commands/test.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAGnD,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAkBzF;AAED,wBAAsB,sBAAsB,CAC1C,MAAM,GAAE,MAAM,CAAC,WAA4B,GAC1C,OAAO,CAAC,MAAM,CAAC,CAGjB"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as process from 'node:process';
|
|
2
|
+
import { renderCliError, toCliError } from "../errors.js";
|
|
3
|
+
export async function runTestCommand(argv, context) {
|
|
4
|
+
if (argv.includes('-h') || argv.includes('--help')) {
|
|
5
|
+
process.stdout.write(`${await getTestCommandHelpText()}\n`);
|
|
6
|
+
return 0;
|
|
7
|
+
}
|
|
8
|
+
try {
|
|
9
|
+
let { runRemixTest } = await import('@remix-run/test/cli');
|
|
10
|
+
return await runRemixTest({ argv, cwd: context.cwd });
|
|
11
|
+
}
|
|
12
|
+
catch (error) {
|
|
13
|
+
let helpText = await getTestCommandHelpText(process.stderr);
|
|
14
|
+
process.stderr.write(renderCliError(toCliError(error), {
|
|
15
|
+
helpText,
|
|
16
|
+
}));
|
|
17
|
+
return 1;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export async function getTestCommandHelpText(target = process.stdout) {
|
|
21
|
+
let { getRemixTestHelpText } = await import('@remix-run/test/cli');
|
|
22
|
+
return getRemixTestHelpText(target);
|
|
23
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { CliContext } from '../cli-context.ts';
|
|
2
|
+
export declare function runVersionCommand(argv: string[], context: CliContext): Promise<number>;
|
|
3
|
+
export declare function getVersionCommandHelpText(target?: NodeJS.WriteStream): string;
|
|
4
|
+
//# sourceMappingURL=version.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../../src/lib/commands/version.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAKnD,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAoB5F;AAED,wBAAgB,yBAAyB,CAAC,MAAM,GAAE,MAAM,CAAC,WAA4B,GAAG,MAAM,CAS7F"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as process from 'node:process';
|
|
2
|
+
import { remixVersionUnavailable, renderCliError, toCliError } from "../errors.js";
|
|
3
|
+
import { formatHelpText } from "../help-text.js";
|
|
4
|
+
import { parseArgs } from "../parse-args.js";
|
|
5
|
+
export async function runVersionCommand(argv, context) {
|
|
6
|
+
if (argv.includes('-h') || argv.includes('--help')) {
|
|
7
|
+
process.stdout.write(getVersionCommandHelpText());
|
|
8
|
+
return 0;
|
|
9
|
+
}
|
|
10
|
+
try {
|
|
11
|
+
parseArgs(argv, {}, { maxPositionals: 0 });
|
|
12
|
+
if (context.remixVersion == null) {
|
|
13
|
+
throw remixVersionUnavailable();
|
|
14
|
+
}
|
|
15
|
+
process.stdout.write(`${context.remixVersion}\n`);
|
|
16
|
+
return 0;
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
process.stderr.write(renderCliError(toCliError(error), { helpText: getVersionCommandHelpText(process.stderr) }));
|
|
20
|
+
return 1;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export function getVersionCommandHelpText(target = process.stdout) {
|
|
24
|
+
return formatHelpText({
|
|
25
|
+
description: 'Show the current Remix version.',
|
|
26
|
+
examples: ['remix version', 'remix --version'],
|
|
27
|
+
usage: ['remix version'],
|
|
28
|
+
}, target);
|
|
29
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface CompletionResult {
|
|
2
|
+
mode: 'files' | 'none' | 'values';
|
|
3
|
+
values?: string[];
|
|
4
|
+
}
|
|
5
|
+
declare const COMPLETION_SHELLS: readonly ["bash", "zsh"];
|
|
6
|
+
export type CompletionShell = (typeof COMPLETION_SHELLS)[number];
|
|
7
|
+
export declare function isCompletionShell(value: string): value is CompletionShell;
|
|
8
|
+
export declare function getCompletionResult(words: string[], currentIndex: number): CompletionResult;
|
|
9
|
+
export declare function renderCompletionResult(result: CompletionResult): string;
|
|
10
|
+
export declare function getCompletionScript(): string;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=completion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completion.d.ts","sourceRoot":"","sources":["../../src/lib/completion.ts"],"names":[],"mappings":"AAAA,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,0BAA2B,CAAA;AAIlD,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,CAM3F;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAQvE;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CA4E5C"}
|