@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.
Files changed (121) hide show
  1. package/README.md +105 -1
  2. package/dist/index.js +1 -1
  3. package/dist/lib/app-root.d.ts +11 -0
  4. package/dist/lib/app-root.d.ts.map +1 -0
  5. package/dist/lib/app-root.js +38 -0
  6. package/dist/lib/bootstrap-project.js +2 -2
  7. package/dist/lib/cli-context.d.ts +6 -0
  8. package/dist/lib/cli-context.d.ts.map +1 -1
  9. package/dist/lib/cli-context.js +12 -1
  10. package/dist/lib/cli.d.ts +3 -2
  11. package/dist/lib/cli.d.ts.map +1 -1
  12. package/dist/lib/cli.js +42 -14
  13. package/dist/lib/commands/completion.js +4 -4
  14. package/dist/lib/commands/db.d.ts +4 -0
  15. package/dist/lib/commands/db.d.ts.map +1 -0
  16. package/dist/lib/commands/db.js +283 -0
  17. package/dist/lib/commands/doctor.d.ts +5 -0
  18. package/dist/lib/commands/doctor.d.ts.map +1 -1
  19. package/dist/lib/commands/doctor.js +26 -251
  20. package/dist/lib/commands/help.d.ts.map +1 -1
  21. package/dist/lib/commands/help.js +17 -9
  22. package/dist/lib/commands/new.js +6 -6
  23. package/dist/lib/commands/routes.js +6 -6
  24. package/dist/lib/commands/test.d.ts +20 -1
  25. package/dist/lib/commands/test.d.ts.map +1 -1
  26. package/dist/lib/commands/test.js +353 -10
  27. package/dist/lib/commands/version.js +3 -3
  28. package/dist/lib/completion.d.ts +1 -1
  29. package/dist/lib/completion.d.ts.map +1 -1
  30. package/dist/lib/completion.js +229 -6
  31. package/dist/lib/controller-files.d.ts +0 -8
  32. package/dist/lib/controller-files.d.ts.map +1 -1
  33. package/dist/lib/controller-files.js +0 -23
  34. package/dist/lib/controller-ownership.d.ts +4 -12
  35. package/dist/lib/controller-ownership.d.ts.map +1 -1
  36. package/dist/lib/controller-ownership.js +31 -127
  37. package/dist/lib/database-command.d.ts +20 -0
  38. package/dist/lib/database-command.d.ts.map +1 -0
  39. package/dist/lib/database-command.js +7 -0
  40. package/dist/lib/doctor/controller-findings.d.ts +2 -2
  41. package/dist/lib/doctor/controller-findings.d.ts.map +1 -1
  42. package/dist/lib/doctor/controller-findings.js +23 -39
  43. package/dist/lib/doctor/controllers.d.ts +1 -2
  44. package/dist/lib/doctor/controllers.d.ts.map +1 -1
  45. package/dist/lib/doctor/controllers.js +4 -7
  46. package/dist/lib/doctor/environment.js +2 -2
  47. package/dist/lib/doctor/fixes.d.ts.map +1 -1
  48. package/dist/lib/doctor/fixes.js +46 -7
  49. package/dist/lib/doctor/project.d.ts.map +1 -1
  50. package/dist/lib/doctor/project.js +3 -212
  51. package/dist/lib/doctor/run.d.ts +9 -0
  52. package/dist/lib/doctor/run.d.ts.map +1 -0
  53. package/dist/lib/doctor/run.js +237 -0
  54. package/dist/lib/doctor/types.d.ts +2 -1
  55. package/dist/lib/doctor/types.d.ts.map +1 -1
  56. package/dist/lib/doctor/types.js +4 -1
  57. package/dist/lib/errors.d.ts +30 -0
  58. package/dist/lib/errors.d.ts.map +1 -1
  59. package/dist/lib/errors.js +55 -0
  60. package/dist/lib/help-text.js +1 -1
  61. package/dist/lib/parse-args.d.ts.map +1 -1
  62. package/dist/lib/parse-args.js +17 -4
  63. package/dist/lib/remix-config.d.ts +75 -0
  64. package/dist/lib/remix-config.d.ts.map +1 -0
  65. package/dist/lib/remix-config.js +411 -0
  66. package/dist/lib/reporter.js +1 -1
  67. package/dist/lib/route-map.js +13 -33
  68. package/package.json +12 -6
  69. package/schema/remix.json +242 -0
  70. package/src/lib/app-root.ts +46 -0
  71. package/src/lib/cli-context.ts +17 -0
  72. package/src/lib/cli.ts +41 -6
  73. package/src/lib/commands/db.ts +377 -0
  74. package/src/lib/commands/doctor.ts +27 -329
  75. package/src/lib/commands/help.ts +10 -1
  76. package/src/lib/commands/test.ts +453 -12
  77. package/src/lib/completion.ts +321 -6
  78. package/src/lib/controller-files.ts +0 -38
  79. package/src/lib/controller-ownership.ts +50 -203
  80. package/src/lib/database-command.ts +31 -0
  81. package/src/lib/doctor/controller-findings.ts +30 -47
  82. package/src/lib/doctor/controllers.ts +2 -6
  83. package/src/lib/doctor/fixes.ts +55 -6
  84. package/src/lib/doctor/project.ts +0 -236
  85. package/src/lib/doctor/run.ts +311 -0
  86. package/src/lib/doctor/types.ts +6 -5
  87. package/src/lib/errors.ts +65 -0
  88. package/src/lib/parse-args.ts +19 -3
  89. package/src/lib/remix-config.ts +639 -0
  90. package/src/lib/route-map.ts +11 -48
  91. package/template/.agents/skills/remix/SKILL.md +39 -28
  92. package/template/.agents/skills/remix/references/assets-and-browser-modules.md +53 -10
  93. package/template/.agents/skills/remix/references/auth-and-sessions.md +5 -5
  94. package/template/.agents/skills/remix/references/data-and-validation.md +15 -15
  95. package/template/.agents/skills/remix/references/hydration-frames-navigation.md +54 -8
  96. package/template/.agents/skills/remix/references/middleware-and-server.md +68 -6
  97. package/template/.agents/skills/remix/references/mixins-styling-events.md +2 -0
  98. package/template/.agents/skills/remix/references/routing-and-controllers.md +8 -8
  99. package/template/.agents/skills/remix/references/testing-patterns.md +19 -18
  100. package/template/AGENTS.md +6 -3
  101. package/template/README.md +6 -3
  102. package/template/app/actions/controller.tsx +1 -1
  103. package/template/app/{ui → actions}/document.tsx +7 -5
  104. package/template/app/{ui/scaffold-home-page.tsx → actions/home-page.tsx} +2 -3
  105. package/template/app/actions/public/entry.ts +48 -0
  106. package/template/app/{assets → actions/public}/prompt-button.tsx +29 -25
  107. package/template/app/assets.ts +19 -8
  108. package/template/app/middleware/render.tsx +29 -1
  109. package/template/hmr.ts +46 -0
  110. package/template/package.json +4 -3
  111. package/template/server.ts +8 -1
  112. package/template/tsconfig.json +1 -1
  113. package/dist/lib/doctor/controller-fix-plans.d.ts +0 -4
  114. package/dist/lib/doctor/controller-fix-plans.d.ts.map +0 -1
  115. package/dist/lib/doctor/controller-fix-plans.js +0 -119
  116. package/dist/lib/doctor/controller-placeholders.d.ts +0 -3
  117. package/dist/lib/doctor/controller-placeholders.d.ts.map +0 -1
  118. package/dist/lib/doctor/controller-placeholders.js +0 -52
  119. package/src/lib/doctor/controller-fix-plans.ts +0 -168
  120. package/src/lib/doctor/controller-placeholders.ts +0 -70
  121. package/template/app/assets/entry.ts +0 -8
@@ -1,50 +1,13 @@
1
- import * as path from 'node:path'
2
1
  import * as process from 'node:process'
3
2
 
4
- import { checkControllerConventions } from '../doctor/controllers.ts'
5
3
  import type { CliContext } from '../cli-context.ts'
6
- import { checkEnvironment, getEnvironmentFixPlans } from '../doctor/environment.ts'
7
- import { applyDoctorFixPlans } from '../doctor/fixes.ts'
8
- import { checkProject, getProjectFixPlans } from '../doctor/project.ts'
9
- import {
10
- createDoctorSuite,
11
- createSkippedDoctorSuite,
12
- type DoctorAppliedFix,
13
- type DoctorFinding,
14
- type DoctorReport,
15
- type DoctorSuiteName,
16
- type DoctorSuiteResult,
17
- } from '../doctor/types.ts'
4
+ import { runRemixDoctor, type RunRemixDoctorOptions } from '../doctor/run.ts'
18
5
  import { renderCliError, toCliError } from '../errors.ts'
19
6
  import { formatHelpText } from '../help-text.ts'
20
7
  import { parseArgs } from '../parse-args.ts'
21
- import {
22
- createCommandReporter,
23
- createStepProgressReporter,
24
- type CommandReporter,
25
- type StepProgressReporter,
26
- } from '../reporter.ts'
8
+ import type { RemixDoctorCommandConfig } from '../remix-config.ts'
27
9
 
28
- const DOCTOR_SUITE_LABELS = {
29
- actions: {
30
- complete: 'actions',
31
- running: 'Checking actions',
32
- },
33
- environment: {
34
- complete: 'environment',
35
- running: 'Checking environment',
36
- },
37
- project: {
38
- complete: 'project',
39
- running: 'Checking project',
40
- },
41
- } satisfies Record<DoctorSuiteName, string | { complete: string; running: string }>
42
-
43
- interface DoctorCommandOptions {
44
- fix: boolean
45
- json: boolean
46
- strict: boolean
47
- }
10
+ type DoctorCommandOptions = Pick<RunRemixDoctorOptions, 'fix' | 'json' | 'strict'>
48
11
 
49
12
  export async function runDoctorCommand(argv: string[], context: CliContext): Promise<number> {
50
13
  if (argv.includes('-h') || argv.includes('--help')) {
@@ -52,43 +15,18 @@ export async function runDoctorCommand(argv: string[], context: CliContext): Pro
52
15
  return 0
53
16
  }
54
17
 
55
- let reporter: CommandReporter | null = null
56
- let progress: StepProgressReporter<DoctorSuiteName> | null = null
57
-
58
18
  try {
59
- let options = parseDoctorCommandArgs(argv)
60
- reporter = options.json
61
- ? null
62
- : createCommandReporter({
63
- remixVersion: context.remixVersion,
64
- stderr: process.stdout,
65
- stdout: process.stdout,
66
- })
67
- progress = reporter == null ? null : createDoctorProgressReporter(reporter)
68
- if (reporter != null) {
69
- await reporter.status.commandHeader('doctor')
70
- }
71
-
72
- let report = await collectDoctorReport(progress, options, reporter, context)
73
-
74
- if (options.json) {
75
- process.stdout.write(`${JSON.stringify(report, null, 2)}\n`)
76
- } else if (reporter != null) {
77
- writeDoctorReport(reporter, report)
78
- reporter.finish()
79
- }
80
-
81
- if ((options.fix || options.strict) && hasWarningFindings(report.findings)) {
82
- return 1
83
- }
84
-
85
- return 0
19
+ let config = await context.loadConfig()
20
+ let options = resolveDoctorCommandOptions(argv, config.doctor)
21
+ return await runRemixDoctor({
22
+ ...options,
23
+ cwd: context.cwd,
24
+ remixVersion: context.remixVersion,
25
+ })
86
26
  } catch (error) {
87
- progress?.writeSummaryGap()
88
27
  process.stderr.write(
89
28
  renderCliError(toCliError(error), { helpText: getDoctorCommandHelpText(process.stderr) }),
90
29
  )
91
- reporter?.finish()
92
30
  return 1
93
31
  }
94
32
  }
@@ -109,7 +47,11 @@ export function getDoctorCommandHelpText(target: NodeJS.WriteStream = process.st
109
47
  description: 'Exit with status 1 when warning-level findings are present',
110
48
  label: '--strict',
111
49
  },
112
- { description: 'Apply low-risk project and action fixes', label: '--fix' },
50
+ {
51
+ description: 'Do not exit with status 1 when warning-level findings are present',
52
+ label: '--no-strict',
53
+ },
54
+ { description: 'Apply available low-risk fixes', label: '--fix' },
113
55
  ],
114
56
  usage: ['remix doctor [--json] [--strict] [--fix] [--no-color]'],
115
57
  },
@@ -117,274 +59,30 @@ export function getDoctorCommandHelpText(target: NodeJS.WriteStream = process.st
117
59
  )
118
60
  }
119
61
 
120
- function parseDoctorCommandArgs(argv: string[]): DoctorCommandOptions {
62
+ export function resolveDoctorCommandOptions(
63
+ argv: string[],
64
+ config: RemixDoctorCommandConfig | undefined,
65
+ ): DoctorCommandOptions {
121
66
  let parsed = parseArgs(
122
67
  argv,
123
68
  {
124
69
  fix: { flag: '--fix', type: 'boolean' },
125
70
  json: { flag: '--json', type: 'boolean' },
71
+ noStrict: { flag: '--no-strict', type: 'boolean' },
126
72
  strict: { flag: '--strict', type: 'boolean' },
127
73
  },
128
74
  { maxPositionals: 0 },
129
75
  )
130
76
 
77
+ let strict = config?.strict ?? false
78
+ for (let arg of argv) {
79
+ if (arg === '--strict') strict = true
80
+ if (arg === '--no-strict') strict = false
81
+ }
82
+
131
83
  return {
132
84
  fix: parsed.options.fix,
133
85
  json: parsed.options.json,
134
- strict: parsed.options.strict,
135
- }
136
- }
137
-
138
- async function collectDoctorReport(
139
- progress: StepProgressReporter<DoctorSuiteName> | null,
140
- options: DoctorCommandOptions,
141
- reporter: CommandReporter | null,
142
- context: CliContext,
143
- ): Promise<DoctorReport> {
144
- let cwd = context.cwd
145
- let appliedFixes: DoctorAppliedFix[] = []
146
- let environment = await runDoctorSuite(progress, 'environment', async () => {
147
- let result = await checkEnvironment(cwd)
148
- let suiteAppliedFixes: DoctorAppliedFix[] = []
149
- let finalResult = result
150
-
151
- if (options.fix && result.projectRoot != null) {
152
- let fixPlans = getEnvironmentFixPlans(result, context.remixVersion)
153
- if (fixPlans.length > 0) {
154
- suiteAppliedFixes = await applyDoctorFixPlans(result.projectRoot, fixPlans)
155
- finalResult = await checkEnvironment(result.projectRoot)
156
- }
157
- }
158
-
159
- let suite = finalResult.suite
160
- if (suiteAppliedFixes.length > 0) {
161
- suite = {
162
- ...suite,
163
- appliedFixes: suiteAppliedFixes,
164
- }
165
- }
166
-
167
- return {
168
- appliedFixes: suiteAppliedFixes,
169
- projectRoot: finalResult.projectRoot ?? result.projectRoot,
170
- suite,
171
- }
172
- })
173
- let findings = [...environment.suite.findings]
174
- appliedFixes.push(...(environment.appliedFixes ?? []))
175
- let suites: DoctorSuiteResult[] = [environment.suite]
176
- let routesFile =
177
- environment.projectRoot == null
178
- ? undefined
179
- : path.join(environment.projectRoot, 'app', 'routes.ts')
180
- writeDoctorSuiteDetails(reporter, environment.suite)
181
- progress?.writeSummaryGap()
182
-
183
- if (hasWarningFindings(environment.suite.findings)) {
184
- let projectSuite = createSkippedDoctorSuite('project', 'Blocked by environment warnings.')
185
- let actionsSuite = createSkippedDoctorSuite('actions', 'Blocked by environment warnings.')
186
- suites.push(projectSuite, actionsSuite)
187
- progress?.skip(projectSuite.name, projectSuite.reason)
188
- writeDoctorSuiteDetails(reporter, projectSuite)
189
- progress?.writeSummaryGap()
190
- progress?.skip(actionsSuite.name, actionsSuite.reason)
191
- writeDoctorSuiteDetails(reporter, actionsSuite)
192
- progress?.writeSummaryGap()
193
-
194
- return {
195
- appRoot: environment.projectRoot,
196
- appliedFixes,
197
- findings,
198
- remainingFindings: findings,
199
- routesFile,
200
- suites,
201
- }
202
- }
203
-
204
- let project = await runDoctorSuite(progress, 'project', async () => {
205
- let result = await checkProject(environment.projectRoot!)
206
- let suiteAppliedFixes: DoctorAppliedFix[] = []
207
- let finalResult = result
208
-
209
- if (options.fix) {
210
- let fixPlans = await getProjectFixPlans(environment.projectRoot!)
211
- if (fixPlans.length > 0) {
212
- suiteAppliedFixes = await applyDoctorFixPlans(environment.projectRoot!, fixPlans)
213
- finalResult = await checkProject(environment.projectRoot!)
214
- }
215
- }
216
-
217
- let suite = finalResult.suite
218
- if (suiteAppliedFixes.length > 0) {
219
- suite = {
220
- ...suite,
221
- appliedFixes: suiteAppliedFixes,
222
- }
223
- }
224
-
225
- return {
226
- appliedFixes: suiteAppliedFixes,
227
- routeManifest: finalResult.routeManifest,
228
- routesFile: finalResult.routesFile,
229
- suite,
230
- }
231
- })
232
- findings.push(...project.suite.findings)
233
- appliedFixes.push(...(project.appliedFixes ?? []))
234
- routesFile = project.routesFile
235
- suites.push(project.suite)
236
- writeDoctorSuiteDetails(reporter, project.suite)
237
- progress?.writeSummaryGap()
238
-
239
- if (hasWarningFindings(project.suite.findings)) {
240
- let actionsSuite = createSkippedDoctorSuite('actions', 'Blocked by project warnings.')
241
- suites.push(actionsSuite)
242
- progress?.skip(actionsSuite.name, actionsSuite.reason)
243
- writeDoctorSuiteDetails(reporter, actionsSuite)
244
- progress?.writeSummaryGap()
245
-
246
- return {
247
- appRoot: environment.projectRoot,
248
- appliedFixes,
249
- findings,
250
- remainingFindings: findings,
251
- routesFile,
252
- suites,
253
- }
254
- }
255
-
256
- let actions = await runDoctorSuite(progress, 'actions', async () => {
257
- let controllerResult = await checkControllerConventions(
258
- project.routeManifest!.appRoot,
259
- project.routeManifest!.tree,
260
- )
261
- let remainingFindings = controllerResult.suite.findings
262
- let suiteAppliedFixes: DoctorAppliedFix[] = []
263
-
264
- if (options.fix && controllerResult.fixPlans.length > 0) {
265
- suiteAppliedFixes = await applyDoctorFixPlans(
266
- project.routeManifest!.appRoot,
267
- controllerResult.fixPlans,
268
- )
269
- let finalControllerResult = await checkControllerConventions(
270
- project.routeManifest!.appRoot,
271
- project.routeManifest!.tree,
272
- )
273
- remainingFindings = finalControllerResult.suite.findings
274
- }
275
-
276
- let suite = createDoctorSuite('actions', remainingFindings)
277
- if (suiteAppliedFixes.length > 0) {
278
- suite.appliedFixes = suiteAppliedFixes
279
- }
280
-
281
- return { appliedFixes: suiteAppliedFixes, suite }
282
- })
283
-
284
- findings.push(...actions.suite.findings)
285
- appliedFixes.push(...(actions.appliedFixes ?? []))
286
- suites.push(actions.suite)
287
- writeDoctorSuiteDetails(reporter, actions.suite)
288
- progress?.writeSummaryGap()
289
-
290
- let report: DoctorReport = {
291
- appRoot: environment.projectRoot,
292
- findings,
293
- routesFile,
294
- suites,
295
- }
296
-
297
- if (options.fix) {
298
- report.appliedFixes = appliedFixes
299
- report.remainingFindings = findings
300
- }
301
-
302
- return report
303
- }
304
-
305
- function hasWarningFindings(findings: DoctorFinding[]): boolean {
306
- return findings.some((finding) => finding.severity === 'warn')
307
- }
308
-
309
- function formatAppliedFix(appliedFix: DoctorAppliedFix): string {
310
- if (appliedFix.kind === 'update-file') {
311
- return `Updated ${appliedFix.path}`
312
- }
313
-
314
- return `Created ${appliedFix.path}`
315
- }
316
-
317
- async function runDoctorSuite<
318
- result extends { appliedFixes?: DoctorAppliedFix[]; suite: DoctorSuiteResult },
319
- >(
320
- progress: StepProgressReporter<DoctorSuiteName> | null,
321
- label: DoctorSuiteName,
322
- callback: () => Promise<result>,
323
- ): Promise<result> {
324
- progress?.start(label)
325
-
326
- try {
327
- let result = await callback()
328
-
329
- if (result.suite.status === 'ok') {
330
- progress?.succeed(label)
331
- } else if (result.suite.status === 'issues') {
332
- progress?.fail(label)
333
- } else {
334
- progress?.skip(label, result.suite.reason)
335
- }
336
-
337
- return result
338
- } catch (error) {
339
- progress?.fail(label)
340
- throw error
341
- }
342
- }
343
-
344
- function createDoctorProgressReporter(
345
- reporter: CommandReporter,
346
- ): StepProgressReporter<DoctorSuiteName> {
347
- return createStepProgressReporter(reporter.status, DOCTOR_SUITE_LABELS)
348
- }
349
-
350
- function writeDoctorReport(reporter: CommandReporter, report: DoctorReport): void {
351
- let warningCount = report.findings.filter((finding) => finding.severity === 'warn').length
352
- let adviceCount = report.findings.length - warningCount
353
-
354
- if ((report.appliedFixes?.length ?? 0) > 0) {
355
- let fixCount = report.appliedFixes!.length
356
- reporter.out.line(`Applied ${fixCount} ${fixCount === 1 ? 'fix' : 'fixes'}.`)
357
- }
358
-
359
- if (report.findings.length === 0) {
360
- reporter.out.line('Doctor found no issues.')
86
+ strict,
361
87
  }
362
-
363
- reporter.out.line(`Summary: ${warningCount} warnings, ${adviceCount} advice.`)
364
- }
365
-
366
- function writeDoctorSuiteDetails(reporter: CommandReporter | null, suite: DoctorSuiteResult): void {
367
- if (reporter == null) {
368
- return
369
- }
370
-
371
- if (suite.findings.length === 0 && (suite.appliedFixes?.length ?? 0) === 0) {
372
- return
373
- }
374
-
375
- reporter.out.withIndent(() => {
376
- for (let finding of suite.findings) {
377
- reporter.out.bullet(
378
- reporter.out.label(finding.severity.toUpperCase(), finding.message, {
379
- tone: finding.severity === 'warn' ? 'warn' : undefined,
380
- }),
381
- )
382
- }
383
-
384
- if ((suite.appliedFixes?.length ?? 0) > 0) {
385
- reporter.out.section('Applied fixes:', () => {
386
- reporter.out.bullets((suite.appliedFixes ?? []).map(formatAppliedFix))
387
- })
388
- }
389
- })
390
88
  }
@@ -27,6 +27,7 @@ export function getCliHelpText(target: NodeJS.WriteStream = process.stdout): str
27
27
  { description: 'Print shell completion scripts for Remix', label: 'completion' },
28
28
  { description: 'Show help for Remix commands', label: 'help [command]' },
29
29
  { description: 'Create a new Remix project', label: 'new <name>' },
30
+ { description: 'Manage the current app database', label: 'db <command>' },
30
31
  { description: 'Check project health for the current project', label: 'doctor' },
31
32
  { description: 'Show the route tree for the current project', label: 'routes' },
32
33
  { description: 'Run tests for the current project', label: 'test [glob]' },
@@ -37,6 +38,7 @@ export function getCliHelpText(target: NodeJS.WriteStream = process.stdout): str
37
38
  'remix help',
38
39
  'remix help completion',
39
40
  'remix help doctor',
41
+ 'remix db status',
40
42
  'remix doctor',
41
43
  'remix new my-remix-app',
42
44
  'remix new my-remix-app --app-name "My Remix App"',
@@ -45,6 +47,7 @@ export function getCliHelpText(target: NodeJS.WriteStream = process.stdout): str
45
47
  'remix version',
46
48
  ],
47
49
  options: [
50
+ { description: 'Use a custom Remix config file', label: '--config <path>' },
48
51
  { description: 'Show help', label: '-h, --help' },
49
52
  { description: 'Disable ANSI color output', label: '--no-color' },
50
53
  { description: 'Show version', label: '-v, --version' },
@@ -62,6 +65,7 @@ export function getHelpCommandHelpText(target: NodeJS.WriteStream = process.stdo
62
65
  examples: [
63
66
  'remix help',
64
67
  'remix help completion',
68
+ 'remix help db',
65
69
  'remix help doctor',
66
70
  'remix help new',
67
71
  'remix help routes',
@@ -100,6 +104,11 @@ async function getCommandHelpText(argv: string[]): Promise<string> {
100
104
  return getDoctorCommandHelpText()
101
105
  }
102
106
 
107
+ if (command === 'db' && rest.length === 0) {
108
+ let { getDbCommandHelpText } = await import('./db.ts')
109
+ return getDbCommandHelpText()
110
+ }
111
+
103
112
  if (command === 'routes' && rest.length === 0) {
104
113
  let { getRoutesCommandHelpText } = await import('./routes.ts')
105
114
  return getRoutesCommandHelpText()
@@ -107,7 +116,7 @@ async function getCommandHelpText(argv: string[]): Promise<string> {
107
116
 
108
117
  if (command === 'test' && rest.length === 0) {
109
118
  let { getTestCommandHelpText } = await import('./test.ts')
110
- return await getTestCommandHelpText()
119
+ return getTestCommandHelpText()
111
120
  }
112
121
 
113
122
  if (command === 'version' && rest.length === 0) {