@thegetty/quire-cli 1.0.0-rc.45 → 1.0.0-rc.47

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 (245) 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 +10 -27
  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/man/quire.1 +0 -341
  56. package/man/quire.1.md +0 -232
  57. package/schemas/config.schema.json +0 -194
  58. package/schemas/figures.schema.json +0 -56
  59. package/schemas/layout.schema.json +0 -5
  60. package/schemas/objects.schema.json +0 -62
  61. package/schemas/publication.schema.json +0 -140
  62. package/schemas/references.schema.json +0 -29
  63. package/src/Command.spec.js +0 -99
  64. package/src/commands/build.spec.js +0 -113
  65. package/src/commands/build.test.js +0 -397
  66. package/src/commands/clean.spec.js +0 -118
  67. package/src/commands/clean.test.js +0 -382
  68. package/src/commands/config.js +0 -238
  69. package/src/commands/config.spec.js +0 -107
  70. package/src/commands/config.test.js +0 -845
  71. package/src/commands/create.spec.js +0 -112
  72. package/src/commands/create.test.js +0 -415
  73. package/src/commands/doctor.js +0 -251
  74. package/src/commands/doctor.spec.js +0 -115
  75. package/src/commands/doctor.test.js +0 -1409
  76. package/src/commands/epub.spec.js +0 -114
  77. package/src/commands/epub.test.js +0 -503
  78. package/src/commands/help.js +0 -60
  79. package/src/commands/help.test.js +0 -132
  80. package/src/commands/info.spec.js +0 -72
  81. package/src/commands/info.test.js +0 -512
  82. package/src/commands/pdf.spec.js +0 -114
  83. package/src/commands/pdf.test.js +0 -464
  84. package/src/commands/preview.spec.js +0 -97
  85. package/src/commands/preview.test.js +0 -250
  86. package/src/commands/use.js +0 -56
  87. package/src/commands/use.spec.js +0 -61
  88. package/src/commands/use.test.js +0 -280
  89. package/src/commands/validate.spec.js +0 -90
  90. package/src/commands/validate.test.js +0 -378
  91. package/src/commands/workflows.js +0 -70
  92. package/src/errors/build/build-failed-error.js +0 -19
  93. package/src/errors/build/config-field-missing-error.js +0 -20
  94. package/src/errors/build/config-file-not-found-error.js +0 -20
  95. package/src/errors/build/index.js +0 -11
  96. package/src/errors/help/help-topic-not-found-error.js +0 -30
  97. package/src/errors/help/index.js +0 -8
  98. package/src/errors/index.js +0 -58
  99. package/src/errors/input/index.js +0 -8
  100. package/src/errors/input/invalid-input-error.js +0 -21
  101. package/src/errors/install/dependency-install-error.js +0 -19
  102. package/src/errors/install/directory-not-empty-error.js +0 -25
  103. package/src/errors/install/index.js +0 -12
  104. package/src/errors/install/invalid-path-error.js +0 -31
  105. package/src/errors/install/invalid-starter-error.js +0 -27
  106. package/src/errors/install/version-not-found-error.js +0 -35
  107. package/src/errors/output/epub-generation-error.js +0 -19
  108. package/src/errors/output/index.js +0 -14
  109. package/src/errors/output/invalid-epub-library-error.js +0 -20
  110. package/src/errors/output/invalid-pdf-library-error.js +0 -20
  111. package/src/errors/output/missing-build-output-error.js +0 -21
  112. package/src/errors/output/pdf-generation-error.js +0 -24
  113. package/src/errors/output/tool-not-found-error.js +0 -37
  114. package/src/errors/project/index.js +0 -10
  115. package/src/errors/project/not-in-project-error.js +0 -20
  116. package/src/errors/project/project-create-error.js +0 -21
  117. package/src/errors/quire-error.js +0 -27
  118. package/src/errors/validation/index.js +0 -3
  119. package/src/errors/validation/unknown-config-key-error.js +0 -27
  120. package/src/errors/validation/unknown-config-operation-error.js +0 -24
  121. package/src/helpers/docs-url.js +0 -32
  122. package/src/helpers/pager.js +0 -59
  123. package/src/helpers/pager.test.js +0 -85
  124. package/src/helpers/suggest-similar.js +0 -124
  125. package/src/helpers/suggest-similar.test.js +0 -108
  126. package/src/helpers/test-cwd.test.js +0 -192
  127. package/src/lib/11ty/index.test.js +0 -655
  128. package/src/lib/commander/index.js +0 -103
  129. package/src/lib/commander/index.test.js +0 -86
  130. package/src/lib/commander/options.js +0 -237
  131. package/src/lib/commander/options.test.js +0 -205
  132. package/src/lib/conf/build-status.js +0 -103
  133. package/src/lib/conf/build-status.test.js +0 -247
  134. package/src/lib/conf/config.test.js +0 -281
  135. package/src/lib/conf/format.js +0 -60
  136. package/src/lib/conf/format.test.js +0 -106
  137. package/src/lib/conf/helpers.js +0 -91
  138. package/src/lib/conf/helpers.test.js +0 -136
  139. package/src/lib/conf/index.js +0 -22
  140. package/src/lib/constants.js +0 -28
  141. package/src/lib/doctor/README.md +0 -667
  142. package/src/lib/doctor/checks/environment/cli-version.js +0 -62
  143. package/src/lib/doctor/checks/environment/cli-version.test.js +0 -132
  144. package/src/lib/doctor/checks/environment/git-available.js +0 -77
  145. package/src/lib/doctor/checks/environment/git-available.test.js +0 -52
  146. package/src/lib/doctor/checks/environment/index.js +0 -13
  147. package/src/lib/doctor/checks/environment/node-version.js +0 -66
  148. package/src/lib/doctor/checks/environment/node-version.test.js +0 -17
  149. package/src/lib/doctor/checks/environment/npm-available.js +0 -66
  150. package/src/lib/doctor/checks/environment/npm-available.test.js +0 -52
  151. package/src/lib/doctor/checks/environment/os-info.js +0 -48
  152. package/src/lib/doctor/checks/environment/os-info.test.js +0 -81
  153. package/src/lib/doctor/checks/environment/runtime-info.js +0 -51
  154. package/src/lib/doctor/checks/environment/runtime-info.test.js +0 -132
  155. package/src/lib/doctor/checks/outputs/epub-output.js +0 -119
  156. package/src/lib/doctor/checks/outputs/epub-output.test.js +0 -277
  157. package/src/lib/doctor/checks/outputs/index.js +0 -10
  158. package/src/lib/doctor/checks/outputs/pdf-output.js +0 -144
  159. package/src/lib/doctor/checks/outputs/pdf-output.test.js +0 -377
  160. package/src/lib/doctor/checks/outputs/stale-build.js +0 -122
  161. package/src/lib/doctor/checks/outputs/stale-build.test.js +0 -282
  162. package/src/lib/doctor/checks/project/data-files.js +0 -56
  163. package/src/lib/doctor/checks/project/data-files.test.js +0 -125
  164. package/src/lib/doctor/checks/project/dependencies.js +0 -53
  165. package/src/lib/doctor/checks/project/dependencies.test.js +0 -71
  166. package/src/lib/doctor/checks/project/index.js +0 -11
  167. package/src/lib/doctor/checks/project/quire-11ty.js +0 -98
  168. package/src/lib/doctor/checks/project/quire-11ty.test.js +0 -170
  169. package/src/lib/doctor/checks/project/quire-project.js +0 -38
  170. package/src/lib/doctor/checks/project/quire-project.test.js +0 -47
  171. package/src/lib/doctor/checks/tools/index.js +0 -10
  172. package/src/lib/doctor/checks/tools/pandoc-available.js +0 -82
  173. package/src/lib/doctor/checks/tools/pandoc-available.test.js +0 -73
  174. package/src/lib/doctor/checks/tools/prince-available.js +0 -81
  175. package/src/lib/doctor/checks/tools/prince-available.test.js +0 -73
  176. package/src/lib/doctor/constants.js +0 -39
  177. package/src/lib/doctor/formatDuration.js +0 -108
  178. package/src/lib/doctor/formatDuration.test.js +0 -76
  179. package/src/lib/doctor/formatters/human.js +0 -257
  180. package/src/lib/doctor/formatters/human.test.js +0 -463
  181. package/src/lib/doctor/formatters/index.js +0 -8
  182. package/src/lib/doctor/formatters/json.js +0 -78
  183. package/src/lib/doctor/formatters/json.test.js +0 -174
  184. package/src/lib/doctor/formatters/shared.js +0 -129
  185. package/src/lib/doctor/formatters/shared.test.js +0 -194
  186. package/src/lib/doctor/index.js +0 -271
  187. package/src/lib/doctor/index.test.js +0 -797
  188. package/src/lib/epub/engines.js +0 -46
  189. package/src/lib/epub/index.test.js +0 -518
  190. package/src/lib/epub/pandoc.test.js +0 -122
  191. package/src/lib/epub/schema.js +0 -21
  192. package/src/lib/error/README.md +0 -170
  193. package/src/lib/error/handler.js +0 -107
  194. package/src/lib/git/index.spec.js +0 -80
  195. package/src/lib/git/index.test.js +0 -453
  196. package/src/lib/help/frontmatter.js +0 -77
  197. package/src/lib/help/frontmatter.test.js +0 -139
  198. package/src/lib/help/index.js +0 -146
  199. package/src/lib/help/index.test.js +0 -188
  200. package/src/lib/help/topics/configuration.md +0 -77
  201. package/src/lib/help/topics/debugging.md +0 -69
  202. package/src/lib/help/topics/epub.md +0 -74
  203. package/src/lib/help/topics/pdf.md +0 -74
  204. package/src/lib/help/topics/publishing.md +0 -80
  205. package/src/lib/help/topics/workflows.md +0 -50
  206. package/src/lib/installer/index.js +0 -309
  207. package/src/lib/installer/index.spec.js +0 -83
  208. package/src/lib/installer/index.test.js +0 -545
  209. package/src/lib/logger/README.md +0 -424
  210. package/src/lib/logger/debug.js +0 -132
  211. package/src/lib/logger/debug.spec.js +0 -130
  212. package/src/lib/logger/debug.test.js +0 -128
  213. package/src/lib/logger/index.js +0 -228
  214. package/src/lib/logger/index.spec.js +0 -131
  215. package/src/lib/logger/index.test.js +0 -578
  216. package/src/lib/npm/README.md +0 -127
  217. package/src/lib/npm/index.js +0 -198
  218. package/src/lib/npm/index.spec.js +0 -60
  219. package/src/lib/npm/index.test.js +0 -355
  220. package/src/lib/pdf/engines.js +0 -46
  221. package/src/lib/pdf/index.test.js +0 -708
  222. package/src/lib/pdf/paged.test.js +0 -366
  223. package/src/lib/pdf/prince.test.js +0 -202
  224. package/src/lib/pdf/schema.js +0 -21
  225. package/src/lib/pdf/split.test.js +0 -445
  226. package/src/lib/platform.js +0 -95
  227. package/src/lib/process/manager.js +0 -110
  228. package/src/lib/process/manager.test.js +0 -55
  229. package/src/lib/project/build.js +0 -162
  230. package/src/lib/project/build.test.js +0 -275
  231. package/src/lib/project/config.js +0 -48
  232. package/src/lib/project/config.test.js +0 -134
  233. package/src/lib/project/detect.js +0 -47
  234. package/src/lib/project/detect.test.js +0 -157
  235. package/src/lib/project/index.js +0 -56
  236. package/src/lib/project/output-paths.js +0 -87
  237. package/src/lib/project/output-paths.test.js +0 -66
  238. package/src/lib/project/paths.js +0 -272
  239. package/src/lib/project/version.js +0 -110
  240. package/src/lib/project/version.test.js +0 -350
  241. package/src/lib/reporter/index.test.js +0 -862
  242. package/src/main.spec.js +0 -61
  243. package/src/main.test.js +0 -347
  244. package/src/validators/validate-data-files.js +0 -154
  245. 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
- })