@thegetty/quire-cli 1.0.0-rc.44 → 1.0.0-rc.46

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 (243) hide show
  1. package/CHANGELOG.md +0 -36
  2. package/README.md +0 -9
  3. package/bin/cli.js +1 -46
  4. package/package.json +9 -25
  5. package/src/Command.js +6 -26
  6. package/src/commands/README.md +122 -213
  7. package/src/commands/build.js +37 -45
  8. package/src/commands/clean.js +19 -33
  9. package/src/commands/conf.js +43 -0
  10. package/src/commands/create.js +14 -42
  11. package/src/commands/epub.js +31 -67
  12. package/src/commands/index.js +2 -9
  13. package/src/commands/info.js +86 -88
  14. package/src/commands/pdf.js +82 -63
  15. package/src/commands/preview.js +31 -32
  16. package/src/commands/validate.js +20 -64
  17. package/src/commands/version.js +43 -0
  18. package/src/errors/validation/validation-error.js +11 -20
  19. package/src/helpers/clean.js +1 -1
  20. package/src/helpers/is-quire.js +31 -0
  21. package/src/helpers/test-cwd.js +6 -5
  22. package/src/helpers/which.js +4 -10
  23. package/src/lib/11ty/README.md +19 -135
  24. package/src/lib/11ty/api.js +93 -235
  25. package/src/lib/11ty/cli.js +37 -112
  26. package/src/lib/11ty/index.js +5 -64
  27. package/src/lib/11ty/paths.js +103 -0
  28. package/src/lib/README.md +0 -330
  29. package/src/lib/conf/README.md +69 -86
  30. package/src/lib/conf/config.js +3 -5
  31. package/src/lib/conf/defaults.js +0 -65
  32. package/src/lib/conf/schema.js +9 -103
  33. package/src/lib/epub/README.md +2 -133
  34. package/src/lib/epub/epub.js +11 -36
  35. package/src/lib/epub/index.js +21 -111
  36. package/src/lib/epub/pandoc.js +4 -33
  37. package/src/lib/git/README.md +2 -151
  38. package/src/lib/git/index.js +13 -217
  39. package/src/lib/i18n/README.md +3 -0
  40. package/src/lib/i18n/config.js +53 -0
  41. package/src/lib/i18n/index.js +43 -0
  42. package/src/lib/i18n/localeService.js +58 -0
  43. package/src/lib/pdf/README.md +0 -131
  44. package/src/lib/pdf/index.js +21 -124
  45. package/src/lib/pdf/paged.js +52 -100
  46. package/src/lib/pdf/prince.js +37 -115
  47. package/src/lib/pdf/split.js +33 -61
  48. package/src/lib/quire/README.md +19 -0
  49. package/src/lib/quire/index.js +353 -0
  50. package/src/lib/reporter/README.md +2 -211
  51. package/src/lib/reporter/index.js +0 -607
  52. package/src/main.js +48 -221
  53. package/src/packageConfig.js +0 -17
  54. package/src/validators/utils.js +1 -2
  55. package/schemas/config.schema.json +0 -194
  56. package/schemas/figures.schema.json +0 -56
  57. package/schemas/layout.schema.json +0 -5
  58. package/schemas/objects.schema.json +0 -62
  59. package/schemas/publication.schema.json +0 -140
  60. package/schemas/references.schema.json +0 -29
  61. package/src/Command.spec.js +0 -99
  62. package/src/commands/build.spec.js +0 -113
  63. package/src/commands/build.test.js +0 -397
  64. package/src/commands/clean.spec.js +0 -118
  65. package/src/commands/clean.test.js +0 -382
  66. package/src/commands/config.js +0 -238
  67. package/src/commands/config.spec.js +0 -107
  68. package/src/commands/config.test.js +0 -845
  69. package/src/commands/create.spec.js +0 -112
  70. package/src/commands/create.test.js +0 -415
  71. package/src/commands/doctor.js +0 -251
  72. package/src/commands/doctor.spec.js +0 -115
  73. package/src/commands/doctor.test.js +0 -1409
  74. package/src/commands/epub.spec.js +0 -114
  75. package/src/commands/epub.test.js +0 -503
  76. package/src/commands/help.js +0 -60
  77. package/src/commands/help.test.js +0 -132
  78. package/src/commands/info.spec.js +0 -72
  79. package/src/commands/info.test.js +0 -512
  80. package/src/commands/pdf.spec.js +0 -114
  81. package/src/commands/pdf.test.js +0 -464
  82. package/src/commands/preview.spec.js +0 -97
  83. package/src/commands/preview.test.js +0 -250
  84. package/src/commands/use.js +0 -56
  85. package/src/commands/use.spec.js +0 -61
  86. package/src/commands/use.test.js +0 -280
  87. package/src/commands/validate.spec.js +0 -90
  88. package/src/commands/validate.test.js +0 -378
  89. package/src/commands/workflows.js +0 -70
  90. package/src/errors/build/build-failed-error.js +0 -19
  91. package/src/errors/build/config-field-missing-error.js +0 -20
  92. package/src/errors/build/config-file-not-found-error.js +0 -20
  93. package/src/errors/build/index.js +0 -11
  94. package/src/errors/help/help-topic-not-found-error.js +0 -30
  95. package/src/errors/help/index.js +0 -8
  96. package/src/errors/index.js +0 -58
  97. package/src/errors/input/index.js +0 -8
  98. package/src/errors/input/invalid-input-error.js +0 -21
  99. package/src/errors/install/dependency-install-error.js +0 -19
  100. package/src/errors/install/directory-not-empty-error.js +0 -25
  101. package/src/errors/install/index.js +0 -12
  102. package/src/errors/install/invalid-path-error.js +0 -31
  103. package/src/errors/install/invalid-starter-error.js +0 -27
  104. package/src/errors/install/version-not-found-error.js +0 -35
  105. package/src/errors/output/epub-generation-error.js +0 -19
  106. package/src/errors/output/index.js +0 -14
  107. package/src/errors/output/invalid-epub-library-error.js +0 -20
  108. package/src/errors/output/invalid-pdf-library-error.js +0 -20
  109. package/src/errors/output/missing-build-output-error.js +0 -21
  110. package/src/errors/output/pdf-generation-error.js +0 -24
  111. package/src/errors/output/tool-not-found-error.js +0 -37
  112. package/src/errors/project/index.js +0 -10
  113. package/src/errors/project/not-in-project-error.js +0 -20
  114. package/src/errors/project/project-create-error.js +0 -21
  115. package/src/errors/quire-error.js +0 -27
  116. package/src/errors/validation/index.js +0 -3
  117. package/src/errors/validation/unknown-config-key-error.js +0 -27
  118. package/src/errors/validation/unknown-config-operation-error.js +0 -24
  119. package/src/helpers/docs-url.js +0 -32
  120. package/src/helpers/pager.js +0 -59
  121. package/src/helpers/pager.test.js +0 -85
  122. package/src/helpers/suggest-similar.js +0 -124
  123. package/src/helpers/suggest-similar.test.js +0 -108
  124. package/src/helpers/test-cwd.test.js +0 -192
  125. package/src/lib/11ty/index.test.js +0 -655
  126. package/src/lib/commander/index.js +0 -103
  127. package/src/lib/commander/index.test.js +0 -86
  128. package/src/lib/commander/options.js +0 -237
  129. package/src/lib/commander/options.test.js +0 -205
  130. package/src/lib/conf/build-status.js +0 -103
  131. package/src/lib/conf/build-status.test.js +0 -247
  132. package/src/lib/conf/config.test.js +0 -281
  133. package/src/lib/conf/format.js +0 -60
  134. package/src/lib/conf/format.test.js +0 -106
  135. package/src/lib/conf/helpers.js +0 -91
  136. package/src/lib/conf/helpers.test.js +0 -136
  137. package/src/lib/conf/index.js +0 -22
  138. package/src/lib/constants.js +0 -28
  139. package/src/lib/doctor/README.md +0 -667
  140. package/src/lib/doctor/checks/environment/cli-version.js +0 -62
  141. package/src/lib/doctor/checks/environment/cli-version.test.js +0 -132
  142. package/src/lib/doctor/checks/environment/git-available.js +0 -77
  143. package/src/lib/doctor/checks/environment/git-available.test.js +0 -52
  144. package/src/lib/doctor/checks/environment/index.js +0 -13
  145. package/src/lib/doctor/checks/environment/node-version.js +0 -66
  146. package/src/lib/doctor/checks/environment/node-version.test.js +0 -17
  147. package/src/lib/doctor/checks/environment/npm-available.js +0 -66
  148. package/src/lib/doctor/checks/environment/npm-available.test.js +0 -52
  149. package/src/lib/doctor/checks/environment/os-info.js +0 -48
  150. package/src/lib/doctor/checks/environment/os-info.test.js +0 -81
  151. package/src/lib/doctor/checks/environment/runtime-info.js +0 -51
  152. package/src/lib/doctor/checks/environment/runtime-info.test.js +0 -132
  153. package/src/lib/doctor/checks/outputs/epub-output.js +0 -119
  154. package/src/lib/doctor/checks/outputs/epub-output.test.js +0 -277
  155. package/src/lib/doctor/checks/outputs/index.js +0 -10
  156. package/src/lib/doctor/checks/outputs/pdf-output.js +0 -144
  157. package/src/lib/doctor/checks/outputs/pdf-output.test.js +0 -377
  158. package/src/lib/doctor/checks/outputs/stale-build.js +0 -122
  159. package/src/lib/doctor/checks/outputs/stale-build.test.js +0 -282
  160. package/src/lib/doctor/checks/project/data-files.js +0 -56
  161. package/src/lib/doctor/checks/project/data-files.test.js +0 -125
  162. package/src/lib/doctor/checks/project/dependencies.js +0 -53
  163. package/src/lib/doctor/checks/project/dependencies.test.js +0 -71
  164. package/src/lib/doctor/checks/project/index.js +0 -11
  165. package/src/lib/doctor/checks/project/quire-11ty.js +0 -98
  166. package/src/lib/doctor/checks/project/quire-11ty.test.js +0 -170
  167. package/src/lib/doctor/checks/project/quire-project.js +0 -38
  168. package/src/lib/doctor/checks/project/quire-project.test.js +0 -47
  169. package/src/lib/doctor/checks/tools/index.js +0 -10
  170. package/src/lib/doctor/checks/tools/pandoc-available.js +0 -82
  171. package/src/lib/doctor/checks/tools/pandoc-available.test.js +0 -73
  172. package/src/lib/doctor/checks/tools/prince-available.js +0 -81
  173. package/src/lib/doctor/checks/tools/prince-available.test.js +0 -73
  174. package/src/lib/doctor/constants.js +0 -39
  175. package/src/lib/doctor/formatDuration.js +0 -108
  176. package/src/lib/doctor/formatDuration.test.js +0 -76
  177. package/src/lib/doctor/formatters/human.js +0 -257
  178. package/src/lib/doctor/formatters/human.test.js +0 -463
  179. package/src/lib/doctor/formatters/index.js +0 -8
  180. package/src/lib/doctor/formatters/json.js +0 -78
  181. package/src/lib/doctor/formatters/json.test.js +0 -174
  182. package/src/lib/doctor/formatters/shared.js +0 -129
  183. package/src/lib/doctor/formatters/shared.test.js +0 -194
  184. package/src/lib/doctor/index.js +0 -271
  185. package/src/lib/doctor/index.test.js +0 -797
  186. package/src/lib/epub/engines.js +0 -46
  187. package/src/lib/epub/index.test.js +0 -518
  188. package/src/lib/epub/pandoc.test.js +0 -122
  189. package/src/lib/epub/schema.js +0 -21
  190. package/src/lib/error/README.md +0 -170
  191. package/src/lib/error/handler.js +0 -107
  192. package/src/lib/git/index.spec.js +0 -80
  193. package/src/lib/git/index.test.js +0 -453
  194. package/src/lib/help/frontmatter.js +0 -77
  195. package/src/lib/help/frontmatter.test.js +0 -139
  196. package/src/lib/help/index.js +0 -146
  197. package/src/lib/help/index.test.js +0 -188
  198. package/src/lib/help/topics/configuration.md +0 -77
  199. package/src/lib/help/topics/debugging.md +0 -69
  200. package/src/lib/help/topics/epub.md +0 -74
  201. package/src/lib/help/topics/pdf.md +0 -74
  202. package/src/lib/help/topics/publishing.md +0 -80
  203. package/src/lib/help/topics/workflows.md +0 -50
  204. package/src/lib/installer/index.js +0 -309
  205. package/src/lib/installer/index.spec.js +0 -83
  206. package/src/lib/installer/index.test.js +0 -545
  207. package/src/lib/logger/README.md +0 -424
  208. package/src/lib/logger/debug.js +0 -132
  209. package/src/lib/logger/debug.spec.js +0 -130
  210. package/src/lib/logger/debug.test.js +0 -128
  211. package/src/lib/logger/index.js +0 -228
  212. package/src/lib/logger/index.spec.js +0 -131
  213. package/src/lib/logger/index.test.js +0 -578
  214. package/src/lib/npm/README.md +0 -127
  215. package/src/lib/npm/index.js +0 -198
  216. package/src/lib/npm/index.spec.js +0 -60
  217. package/src/lib/npm/index.test.js +0 -355
  218. package/src/lib/pdf/engines.js +0 -46
  219. package/src/lib/pdf/index.test.js +0 -708
  220. package/src/lib/pdf/paged.test.js +0 -366
  221. package/src/lib/pdf/prince.test.js +0 -202
  222. package/src/lib/pdf/schema.js +0 -21
  223. package/src/lib/pdf/split.test.js +0 -445
  224. package/src/lib/platform.js +0 -95
  225. package/src/lib/process/manager.js +0 -110
  226. package/src/lib/process/manager.test.js +0 -55
  227. package/src/lib/project/build.js +0 -162
  228. package/src/lib/project/build.test.js +0 -275
  229. package/src/lib/project/config.js +0 -48
  230. package/src/lib/project/config.test.js +0 -134
  231. package/src/lib/project/detect.js +0 -47
  232. package/src/lib/project/detect.test.js +0 -157
  233. package/src/lib/project/index.js +0 -56
  234. package/src/lib/project/output-paths.js +0 -87
  235. package/src/lib/project/output-paths.test.js +0 -66
  236. package/src/lib/project/paths.js +0 -272
  237. package/src/lib/project/version.js +0 -110
  238. package/src/lib/project/version.test.js +0 -350
  239. package/src/lib/reporter/index.test.js +0 -862
  240. package/src/main.spec.js +0 -61
  241. package/src/main.test.js +0 -347
  242. package/src/validators/validate-data-files.js +0 -154
  243. package/src/validators/validate-data-files.test.js +0 -217
@@ -1,251 +0,0 @@
1
- import fs from 'node:fs'
2
- import path from 'node:path'
3
- import Command from '#src/Command.js'
4
- import { withOutputModes } from '#lib/commander/index.js'
5
- import { clearStatus } from '#lib/conf/build-status.js'
6
- import { runAllChecksWithSections, checkSections, SECTION_NAMES, CHECK_IDS } from '#lib/doctor/index.js'
7
- import { formatHuman } from '#lib/doctor/formatters/human.js'
8
- import { formatJson } from '#lib/doctor/formatters/json.js'
9
-
10
- /**
11
- * Map section name to its check IDs
12
- */
13
- const SECTION_CHECK_MAP = Object.fromEntries(
14
- checkSections.map((s) => [s.name.toLowerCase(), s.checks.map((c) => c.id)])
15
- )
16
-
17
- /**
18
- * Quire CLI `doctor` Command
19
- *
20
- * Diagnose common issues with the Quire environment and project setup.
21
- *
22
- * @class DoctorCommand
23
- * @extends {Command}
24
- */
25
- export default class DoctorCommand extends Command {
26
- static definition = withOutputModes({
27
- name: 'doctor',
28
- aliases: ['checkup', 'check', 'diagnostic', 'health'],
29
- description: 'Diagnose common issues with your Quire setup',
30
- summary: 'check environment and project health',
31
- docsLink: 'quire-commands/#troubleshooting',
32
- helpText: `
33
- Runs diagnostic checks organized into four sections:
34
- • Environment: os, cli, node, runtime, npm, git
35
- • Tools: prince, pandoc
36
- • Project: project, deps, 11ty, data
37
- • Outputs: build, pdf, epub
38
-
39
- Examples:
40
- quire doctor Run all diagnostic checks
41
- quire doctor all Run all checks (same as no argument)
42
- quire doctor environment Check environment section only
43
- quire doctor node Check Node.js version only
44
- quire doctor node git Check multiple items
45
- quire doctor --errors Show only failed checks
46
- quire doctor --warnings Show only warnings
47
- quire doctor --verbose Show additional details (paths, versions)
48
- quire doctor --json Output results as JSON (to stdout)
49
- quire doctor --json report.json Save JSON results to file
50
- quire doctor --reset Clear stored build status
51
- quire checkup Alias for doctor command
52
-
53
- CI/Scripting:
54
- quire doctor --quiet Exit code only (0=success, 1=failure)
55
- quire doctor --quiet --json out.json Save JSON report silently
56
- `,
57
- version: '1.0.0',
58
- args: [
59
- [
60
- '[checks...]',
61
- `run specific check(s): all, ${SECTION_NAMES.join(', ')}, or ${CHECK_IDS.join(', ')}`,
62
- ],
63
- ],
64
- options: [
65
- ['-e, --errors', 'show only failed checks'],
66
- ['-w, --warnings', 'show only warnings'],
67
- ['--json [file]', 'output results as JSON (to standard out or a file)'],
68
- ['--reset', 'clear stored build status for the current project'],
69
- ],
70
- })
71
-
72
- constructor() {
73
- super(DoctorCommand.definition)
74
- }
75
-
76
- async action(checks, options, command) {
77
- this.debug('called with checks=%O options=%O', checks, options)
78
-
79
- // --reset: clear stored build status and exit without running checks
80
- if (options.reset) {
81
- clearStatus(process.cwd())
82
- if (!options.quiet) {
83
- this.logger.info('Build status cleared for this project')
84
- }
85
- return
86
- }
87
-
88
- // Parse variadic checks argument into sections and individual checks
89
- const filterOptions = { sections: null, checks: null }
90
- let label = 'diagnostic checks'
91
-
92
- if (checks.length > 0) {
93
- const values = checks.map((v) => v.toLowerCase())
94
-
95
- // "all" means no filtering
96
- if (!values.includes('all')) {
97
- // Separate section names from individual check IDs
98
- const sectionValues = values.filter((v) => SECTION_NAMES.includes(v))
99
- const checkValues = values.filter((v) => CHECK_IDS.includes(v))
100
-
101
- // If we have section names, use them as section filter
102
- if (sectionValues.length > 0 && checkValues.length === 0) {
103
- filterOptions.sections = sectionValues
104
- label = sectionValues.length === 1
105
- ? `${sectionValues[0]} checks`
106
- : `${sectionValues.join(', ')} checks`
107
- } else if (checkValues.length > 0) {
108
- // If we have individual checks (with or without sections),
109
- // expand sections to their check IDs and combine
110
- const expandedChecks = new Set(checkValues)
111
- for (const section of sectionValues) {
112
- const sectionCheckIds = SECTION_CHECK_MAP[section] || []
113
- sectionCheckIds.forEach((id) => expandedChecks.add(id))
114
- }
115
- filterOptions.checks = [...expandedChecks]
116
- label = filterOptions.checks.length === 1
117
- ? `${filterOptions.checks[0]} check`
118
- : `${filterOptions.checks.join(', ')} checks`
119
- }
120
- }
121
- }
122
-
123
- const sections = await runAllChecksWithSections(filterOptions)
124
-
125
- // JSON output mode (options.json is true for flag-only, or string for file path)
126
- if (options.json) {
127
- this.outputJson(sections, options)
128
- return
129
- }
130
-
131
- // Quiet mode without JSON: just exit with appropriate code
132
- if (options.quiet) {
133
- this.outputQuiet(sections)
134
- return
135
- }
136
-
137
- // Human-readable output
138
- this.outputHuman(sections, options, label)
139
- }
140
-
141
- /**
142
- * Quiet mode: no output, just exit code
143
- * @param {Array} sections - Check results organized by section
144
- */
145
- outputQuiet(sections) {
146
- const { exitCode } = formatJson(sections, {})
147
- if (exitCode !== 0) {
148
- process.exitCode = exitCode
149
- }
150
- }
151
-
152
- /**
153
- * Output results as JSON for programmatic consumption
154
- * @param {Array} sections - Check results organized by section
155
- * @param {Object} options - Command options (options.json is true or filename string)
156
- */
157
- outputJson(sections, options) {
158
- const { json, exitCode } = formatJson(sections, {
159
- errors: options.errors,
160
- warnings: options.warnings,
161
- verbose: options.verbose,
162
- })
163
-
164
- // Write to file (if string path provided) or stdout (if just --json flag)
165
- if (typeof options.json === 'string') {
166
- const outputPath = path.resolve(options.json)
167
- fs.writeFileSync(outputPath, json + '\n')
168
- if (!options.quiet) {
169
- this.logger.info(`Results written to ${outputPath}`)
170
- }
171
- } else if (!options.quiet) {
172
- // Write to stdout (bypassing logger formatting) unless quiet mode
173
- console.log(json)
174
- }
175
-
176
- // Set exit code if any checks failed
177
- if (exitCode !== 0) {
178
- process.exitCode = exitCode
179
- }
180
- }
181
-
182
- /**
183
- * Map log level to console method for direct output
184
- *
185
- * Nota bene: doctor output bypasses the logger to avoid the `[quire]`
186
- * prefix on every line. The formatter already handles its own formatting
187
- * (icons, indentation, section headers). Using console methods directly
188
- * routes output to the correct output stream (stdout for info, stderr for
189
- * warn/error) without logger prefix and level labels.
190
- */
191
- static #consoleMethods = {
192
- info: console.log,
193
- warn: console.warn,
194
- error: console.error,
195
- }
196
-
197
- /**
198
- * Output results in human-readable format
199
- * @param {Array} sections - Check results organized by section
200
- * @param {Object} options - Command options
201
- * @param {string} label - Description of checks being run
202
- */
203
- outputHuman(sections, options, label) {
204
- const { lines, summary, key, exitCode, isEmpty } = formatHuman(sections, {
205
- errors: options.errors,
206
- warnings: options.warnings,
207
- verbose: options.verbose,
208
- label,
209
- })
210
-
211
- // Handle case where filters excluded all results
212
- if (isEmpty) {
213
- for (const { text, level } of lines) {
214
- this.#log(level, text)
215
- }
216
- return
217
- }
218
-
219
- // Output all formatted lines routed by log level
220
- for (const { text, level } of lines) {
221
- this.#log(level, text)
222
- }
223
-
224
- // Output summary
225
- if (summary) {
226
- this.#log(summary.level, summary.text)
227
- }
228
-
229
- // Output symbol key
230
- if (key) {
231
- this.#log('info', '')
232
- this.#log(key.level, key.text)
233
- }
234
-
235
- // Set exit code if any checks failed
236
- if (exitCode !== 0) {
237
- process.exitCode = exitCode
238
- }
239
- }
240
-
241
- /**
242
- * Write a line to the console, routed by log level
243
- *
244
- * @param {string} level - Log level (info, warn, error)
245
- * @param {string} text - Text to output
246
- */
247
- #log(level, text) {
248
- const method = DoctorCommand.#consoleMethods[level] || console.log
249
- method(text)
250
- }
251
- }
@@ -1,115 +0,0 @@
1
- import { Command, Option } from 'commander'
2
- import program from '#src/main.js'
3
- import test from 'ava'
4
-
5
- /**
6
- * Command Contract/Interface Tests
7
- *
8
- * Verifies the command's public API and Commander.js integration.
9
- * @see docs/testing-commands.md
10
- */
11
-
12
- test.before((t) => {
13
- // Get the registered command (from program.commands) once and share across all tests
14
- t.context.command = program.commands.find((cmd) => cmd.name() === 'doctor')
15
- })
16
-
17
- test('command is registered in CLI program', (t) => {
18
- const { command } = t.context
19
-
20
- t.truthy(command, 'command "doctor" should be registered in program')
21
- t.true(command instanceof Command, 'registered command should be Commander.js Command instance')
22
- })
23
-
24
- test('registered command has correct metadata', (t) => {
25
- const { command } = t.context
26
-
27
- t.is(command.name(), 'doctor')
28
- t.truthy(command.description())
29
- t.is(typeof command._actionHandler, 'function', 'command should have action handler')
30
- })
31
-
32
- test('registered command has correct aliases', (t) => {
33
- const { command } = t.context
34
- const aliases = command.aliases()
35
-
36
- t.true(aliases.includes('checkup'), 'should have "checkup" alias')
37
- t.true(aliases.includes('diagnostic'), 'should have "diagnostic" alias')
38
- t.true(aliases.includes('health'), 'should have "health" alias')
39
- })
40
-
41
- test('registered command has variadic checks argument', (t) => {
42
- const { command } = t.context
43
- const registeredArguments = command.registeredArguments
44
-
45
- t.is(registeredArguments.length, 1, 'doctor command should have one argument')
46
-
47
- const checksArg = registeredArguments[0]
48
- t.is(checksArg.name(), 'checks', 'argument should be named "checks"')
49
- t.false(checksArg.required, 'checks argument should be optional')
50
- t.true(checksArg.variadic, 'checks argument should be variadic')
51
- t.truthy(checksArg.description, 'checks argument should have a description')
52
- t.true(checksArg.description.includes('all'), 'description should mention "all"')
53
- t.true(checksArg.description.includes('environment'), 'description should mention section names')
54
- t.true(checksArg.description.includes('node'), 'description should mention check IDs')
55
- })
56
-
57
- test('registered command has correct options', (t) => {
58
- const { command } = t.context
59
-
60
- // Doctor command has 4 local + 4 shared output mode options = 8
61
- // Local: --errors, --warnings, --json, --reset
62
- // Shared (via withOutputModes): --quiet, --verbose, --progress, --debug
63
- t.is(command.options.length, 8, 'doctor command should have 8 options')
64
-
65
- // Verify --errors option
66
- const errorsOption = command.options.find((opt) => opt.long === '--errors')
67
- t.truthy(errorsOption, '--errors option should exist')
68
- t.true(errorsOption instanceof Option, '--errors should be Option instance')
69
- t.is(errorsOption.short, '-e', '--errors should have -e short flag')
70
- t.truthy(errorsOption.description)
71
-
72
- // Verify --warnings option
73
- const warningsOption = command.options.find((opt) => opt.long === '--warnings')
74
- t.truthy(warningsOption, '--warnings option should exist')
75
- t.true(warningsOption instanceof Option, '--warnings should be Option instance')
76
- t.is(warningsOption.short, '-w', '--warnings should have -w short flag')
77
- t.truthy(warningsOption.description)
78
-
79
- // Verify --json option with optional file parameter
80
- const jsonOption = command.options.find((opt) => opt.long === '--json')
81
- t.truthy(jsonOption, '--json option should exist')
82
- t.true(jsonOption instanceof Option, '--json should be Option instance')
83
- t.truthy(jsonOption.description)
84
- t.true(jsonOption.description.includes('JSON'), 'description should mention JSON')
85
- t.true(jsonOption.description.includes('file'), 'description should mention file output')
86
-
87
- // Verify --reset option
88
- const resetOption = command.options.find((opt) => opt.long === '--reset')
89
- t.truthy(resetOption, '--reset option should exist')
90
- t.true(resetOption instanceof Option, '--reset should be Option instance')
91
- t.truthy(resetOption.description)
92
-
93
- // Verify shared output mode options (via withOutputModes)
94
- const quietOption = command.options.find((opt) => opt.long === '--quiet')
95
- t.truthy(quietOption, '--quiet option should exist')
96
- t.is(quietOption.short, '-q', '--quiet should have -q short flag')
97
-
98
- const verboseOption = command.options.find((opt) => opt.long === '--verbose')
99
- t.truthy(verboseOption, '--verbose option should exist')
100
- t.is(verboseOption.short, '-v', '--verbose should have -v short flag')
101
-
102
- const progressOption = command.options.find((opt) => opt.long === '--progress')
103
- t.truthy(progressOption, '--progress option should exist (hidden alias for --verbose)')
104
-
105
- const debugOption = command.options.find((opt) => opt.long === '--debug')
106
- t.truthy(debugOption, '--debug option should exist')
107
- })
108
-
109
- test('command is accessible via checkup alias', (t) => {
110
- // Find command by alias
111
- const command = program.commands.find((cmd) => cmd.aliases().includes('checkup'))
112
-
113
- t.truthy(command, 'command should be findable via "checkup" alias')
114
- t.is(command.name(), 'doctor', 'alias should resolve to doctor command')
115
- })