@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.
- package/CHANGELOG.md +0 -36
- package/README.md +0 -9
- package/bin/cli.js +1 -46
- package/package.json +10 -27
- package/src/Command.js +6 -26
- package/src/commands/README.md +122 -213
- package/src/commands/build.js +37 -45
- package/src/commands/clean.js +19 -33
- package/src/commands/conf.js +43 -0
- package/src/commands/create.js +14 -42
- package/src/commands/epub.js +31 -67
- package/src/commands/index.js +2 -9
- package/src/commands/info.js +86 -88
- package/src/commands/pdf.js +82 -63
- package/src/commands/preview.js +31 -32
- package/src/commands/validate.js +20 -64
- package/src/commands/version.js +43 -0
- package/src/errors/validation/validation-error.js +11 -20
- package/src/helpers/clean.js +1 -1
- package/src/helpers/is-quire.js +31 -0
- package/src/helpers/test-cwd.js +6 -5
- package/src/helpers/which.js +4 -10
- package/src/lib/11ty/README.md +19 -135
- package/src/lib/11ty/api.js +93 -235
- package/src/lib/11ty/cli.js +37 -112
- package/src/lib/11ty/index.js +5 -64
- package/src/lib/11ty/paths.js +103 -0
- package/src/lib/README.md +0 -330
- package/src/lib/conf/README.md +69 -86
- package/src/lib/conf/config.js +3 -5
- package/src/lib/conf/defaults.js +0 -65
- package/src/lib/conf/schema.js +9 -103
- package/src/lib/epub/README.md +2 -133
- package/src/lib/epub/epub.js +11 -36
- package/src/lib/epub/index.js +21 -111
- package/src/lib/epub/pandoc.js +4 -33
- package/src/lib/git/README.md +2 -151
- package/src/lib/git/index.js +13 -217
- package/src/lib/i18n/README.md +3 -0
- package/src/lib/i18n/config.js +53 -0
- package/src/lib/i18n/index.js +43 -0
- package/src/lib/i18n/localeService.js +58 -0
- package/src/lib/pdf/README.md +0 -131
- package/src/lib/pdf/index.js +21 -124
- package/src/lib/pdf/paged.js +52 -100
- package/src/lib/pdf/prince.js +37 -115
- package/src/lib/pdf/split.js +33 -61
- package/src/lib/quire/README.md +19 -0
- package/src/lib/quire/index.js +353 -0
- package/src/lib/reporter/README.md +2 -211
- package/src/lib/reporter/index.js +0 -607
- package/src/main.js +48 -221
- package/src/packageConfig.js +0 -17
- package/src/validators/utils.js +1 -2
- package/man/quire.1 +0 -341
- package/man/quire.1.md +0 -232
- package/schemas/config.schema.json +0 -194
- package/schemas/figures.schema.json +0 -56
- package/schemas/layout.schema.json +0 -5
- package/schemas/objects.schema.json +0 -62
- package/schemas/publication.schema.json +0 -140
- package/schemas/references.schema.json +0 -29
- package/src/Command.spec.js +0 -99
- package/src/commands/build.spec.js +0 -113
- package/src/commands/build.test.js +0 -397
- package/src/commands/clean.spec.js +0 -118
- package/src/commands/clean.test.js +0 -382
- package/src/commands/config.js +0 -238
- package/src/commands/config.spec.js +0 -107
- package/src/commands/config.test.js +0 -845
- package/src/commands/create.spec.js +0 -112
- package/src/commands/create.test.js +0 -415
- package/src/commands/doctor.js +0 -251
- package/src/commands/doctor.spec.js +0 -115
- package/src/commands/doctor.test.js +0 -1409
- package/src/commands/epub.spec.js +0 -114
- package/src/commands/epub.test.js +0 -503
- package/src/commands/help.js +0 -60
- package/src/commands/help.test.js +0 -132
- package/src/commands/info.spec.js +0 -72
- package/src/commands/info.test.js +0 -512
- package/src/commands/pdf.spec.js +0 -114
- package/src/commands/pdf.test.js +0 -464
- package/src/commands/preview.spec.js +0 -97
- package/src/commands/preview.test.js +0 -250
- package/src/commands/use.js +0 -56
- package/src/commands/use.spec.js +0 -61
- package/src/commands/use.test.js +0 -280
- package/src/commands/validate.spec.js +0 -90
- package/src/commands/validate.test.js +0 -378
- package/src/commands/workflows.js +0 -70
- package/src/errors/build/build-failed-error.js +0 -19
- package/src/errors/build/config-field-missing-error.js +0 -20
- package/src/errors/build/config-file-not-found-error.js +0 -20
- package/src/errors/build/index.js +0 -11
- package/src/errors/help/help-topic-not-found-error.js +0 -30
- package/src/errors/help/index.js +0 -8
- package/src/errors/index.js +0 -58
- package/src/errors/input/index.js +0 -8
- package/src/errors/input/invalid-input-error.js +0 -21
- package/src/errors/install/dependency-install-error.js +0 -19
- package/src/errors/install/directory-not-empty-error.js +0 -25
- package/src/errors/install/index.js +0 -12
- package/src/errors/install/invalid-path-error.js +0 -31
- package/src/errors/install/invalid-starter-error.js +0 -27
- package/src/errors/install/version-not-found-error.js +0 -35
- package/src/errors/output/epub-generation-error.js +0 -19
- package/src/errors/output/index.js +0 -14
- package/src/errors/output/invalid-epub-library-error.js +0 -20
- package/src/errors/output/invalid-pdf-library-error.js +0 -20
- package/src/errors/output/missing-build-output-error.js +0 -21
- package/src/errors/output/pdf-generation-error.js +0 -24
- package/src/errors/output/tool-not-found-error.js +0 -37
- package/src/errors/project/index.js +0 -10
- package/src/errors/project/not-in-project-error.js +0 -20
- package/src/errors/project/project-create-error.js +0 -21
- package/src/errors/quire-error.js +0 -27
- package/src/errors/validation/index.js +0 -3
- package/src/errors/validation/unknown-config-key-error.js +0 -27
- package/src/errors/validation/unknown-config-operation-error.js +0 -24
- package/src/helpers/docs-url.js +0 -32
- package/src/helpers/pager.js +0 -59
- package/src/helpers/pager.test.js +0 -85
- package/src/helpers/suggest-similar.js +0 -124
- package/src/helpers/suggest-similar.test.js +0 -108
- package/src/helpers/test-cwd.test.js +0 -192
- package/src/lib/11ty/index.test.js +0 -655
- package/src/lib/commander/index.js +0 -103
- package/src/lib/commander/index.test.js +0 -86
- package/src/lib/commander/options.js +0 -237
- package/src/lib/commander/options.test.js +0 -205
- package/src/lib/conf/build-status.js +0 -103
- package/src/lib/conf/build-status.test.js +0 -247
- package/src/lib/conf/config.test.js +0 -281
- package/src/lib/conf/format.js +0 -60
- package/src/lib/conf/format.test.js +0 -106
- package/src/lib/conf/helpers.js +0 -91
- package/src/lib/conf/helpers.test.js +0 -136
- package/src/lib/conf/index.js +0 -22
- package/src/lib/constants.js +0 -28
- package/src/lib/doctor/README.md +0 -667
- package/src/lib/doctor/checks/environment/cli-version.js +0 -62
- package/src/lib/doctor/checks/environment/cli-version.test.js +0 -132
- package/src/lib/doctor/checks/environment/git-available.js +0 -77
- package/src/lib/doctor/checks/environment/git-available.test.js +0 -52
- package/src/lib/doctor/checks/environment/index.js +0 -13
- package/src/lib/doctor/checks/environment/node-version.js +0 -66
- package/src/lib/doctor/checks/environment/node-version.test.js +0 -17
- package/src/lib/doctor/checks/environment/npm-available.js +0 -66
- package/src/lib/doctor/checks/environment/npm-available.test.js +0 -52
- package/src/lib/doctor/checks/environment/os-info.js +0 -48
- package/src/lib/doctor/checks/environment/os-info.test.js +0 -81
- package/src/lib/doctor/checks/environment/runtime-info.js +0 -51
- package/src/lib/doctor/checks/environment/runtime-info.test.js +0 -132
- package/src/lib/doctor/checks/outputs/epub-output.js +0 -119
- package/src/lib/doctor/checks/outputs/epub-output.test.js +0 -277
- package/src/lib/doctor/checks/outputs/index.js +0 -10
- package/src/lib/doctor/checks/outputs/pdf-output.js +0 -144
- package/src/lib/doctor/checks/outputs/pdf-output.test.js +0 -377
- package/src/lib/doctor/checks/outputs/stale-build.js +0 -122
- package/src/lib/doctor/checks/outputs/stale-build.test.js +0 -282
- package/src/lib/doctor/checks/project/data-files.js +0 -56
- package/src/lib/doctor/checks/project/data-files.test.js +0 -125
- package/src/lib/doctor/checks/project/dependencies.js +0 -53
- package/src/lib/doctor/checks/project/dependencies.test.js +0 -71
- package/src/lib/doctor/checks/project/index.js +0 -11
- package/src/lib/doctor/checks/project/quire-11ty.js +0 -98
- package/src/lib/doctor/checks/project/quire-11ty.test.js +0 -170
- package/src/lib/doctor/checks/project/quire-project.js +0 -38
- package/src/lib/doctor/checks/project/quire-project.test.js +0 -47
- package/src/lib/doctor/checks/tools/index.js +0 -10
- package/src/lib/doctor/checks/tools/pandoc-available.js +0 -82
- package/src/lib/doctor/checks/tools/pandoc-available.test.js +0 -73
- package/src/lib/doctor/checks/tools/prince-available.js +0 -81
- package/src/lib/doctor/checks/tools/prince-available.test.js +0 -73
- package/src/lib/doctor/constants.js +0 -39
- package/src/lib/doctor/formatDuration.js +0 -108
- package/src/lib/doctor/formatDuration.test.js +0 -76
- package/src/lib/doctor/formatters/human.js +0 -257
- package/src/lib/doctor/formatters/human.test.js +0 -463
- package/src/lib/doctor/formatters/index.js +0 -8
- package/src/lib/doctor/formatters/json.js +0 -78
- package/src/lib/doctor/formatters/json.test.js +0 -174
- package/src/lib/doctor/formatters/shared.js +0 -129
- package/src/lib/doctor/formatters/shared.test.js +0 -194
- package/src/lib/doctor/index.js +0 -271
- package/src/lib/doctor/index.test.js +0 -797
- package/src/lib/epub/engines.js +0 -46
- package/src/lib/epub/index.test.js +0 -518
- package/src/lib/epub/pandoc.test.js +0 -122
- package/src/lib/epub/schema.js +0 -21
- package/src/lib/error/README.md +0 -170
- package/src/lib/error/handler.js +0 -107
- package/src/lib/git/index.spec.js +0 -80
- package/src/lib/git/index.test.js +0 -453
- package/src/lib/help/frontmatter.js +0 -77
- package/src/lib/help/frontmatter.test.js +0 -139
- package/src/lib/help/index.js +0 -146
- package/src/lib/help/index.test.js +0 -188
- package/src/lib/help/topics/configuration.md +0 -77
- package/src/lib/help/topics/debugging.md +0 -69
- package/src/lib/help/topics/epub.md +0 -74
- package/src/lib/help/topics/pdf.md +0 -74
- package/src/lib/help/topics/publishing.md +0 -80
- package/src/lib/help/topics/workflows.md +0 -50
- package/src/lib/installer/index.js +0 -309
- package/src/lib/installer/index.spec.js +0 -83
- package/src/lib/installer/index.test.js +0 -545
- package/src/lib/logger/README.md +0 -424
- package/src/lib/logger/debug.js +0 -132
- package/src/lib/logger/debug.spec.js +0 -130
- package/src/lib/logger/debug.test.js +0 -128
- package/src/lib/logger/index.js +0 -228
- package/src/lib/logger/index.spec.js +0 -131
- package/src/lib/logger/index.test.js +0 -578
- package/src/lib/npm/README.md +0 -127
- package/src/lib/npm/index.js +0 -198
- package/src/lib/npm/index.spec.js +0 -60
- package/src/lib/npm/index.test.js +0 -355
- package/src/lib/pdf/engines.js +0 -46
- package/src/lib/pdf/index.test.js +0 -708
- package/src/lib/pdf/paged.test.js +0 -366
- package/src/lib/pdf/prince.test.js +0 -202
- package/src/lib/pdf/schema.js +0 -21
- package/src/lib/pdf/split.test.js +0 -445
- package/src/lib/platform.js +0 -95
- package/src/lib/process/manager.js +0 -110
- package/src/lib/process/manager.test.js +0 -55
- package/src/lib/project/build.js +0 -162
- package/src/lib/project/build.test.js +0 -275
- package/src/lib/project/config.js +0 -48
- package/src/lib/project/config.test.js +0 -134
- package/src/lib/project/detect.js +0 -47
- package/src/lib/project/detect.test.js +0 -157
- package/src/lib/project/index.js +0 -56
- package/src/lib/project/output-paths.js +0 -87
- package/src/lib/project/output-paths.test.js +0 -66
- package/src/lib/project/paths.js +0 -272
- package/src/lib/project/version.js +0 -110
- package/src/lib/project/version.test.js +0 -350
- package/src/lib/reporter/index.test.js +0 -862
- package/src/main.spec.js +0 -61
- package/src/main.test.js +0 -347
- package/src/validators/validate-data-files.js +0 -154
- package/src/validators/validate-data-files.test.js +0 -217
package/src/commands/doctor.js
DELETED
|
@@ -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
|
-
})
|