@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.
- package/CHANGELOG.md +0 -36
- package/README.md +0 -9
- package/bin/cli.js +1 -46
- package/package.json +9 -25
- 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/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
|
@@ -1,114 +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() === 'epub')
|
|
15
|
-
})
|
|
16
|
-
|
|
17
|
-
test('command is registered in CLI program', (t) => {
|
|
18
|
-
const { command } = t.context
|
|
19
|
-
|
|
20
|
-
t.truthy(command, 'command "epub" 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(), 'epub')
|
|
28
|
-
t.truthy(command.description())
|
|
29
|
-
t.is(typeof command._actionHandler, 'function', 'command should have action handler')
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
test('registered command has no arguments', (t) => {
|
|
33
|
-
const { command } = t.context
|
|
34
|
-
const registeredArguments = command.registeredArguments
|
|
35
|
-
|
|
36
|
-
t.is(registeredArguments.length, 0, 'epub command should have no arguments')
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
test('registered command has correct options', (t) => {
|
|
40
|
-
const { command } = t.context
|
|
41
|
-
|
|
42
|
-
// Get all options
|
|
43
|
-
const engineOption = command.options.find((opt) => opt.long === '--engine')
|
|
44
|
-
const libOption = command.options.find((opt) => opt.long === '--lib')
|
|
45
|
-
const buildOption = command.options.find((opt) => opt.long === '--build')
|
|
46
|
-
const openOption = command.options.find((opt) => opt.long === '--open')
|
|
47
|
-
const quietOption = command.options.find((opt) => opt.long === '--quiet')
|
|
48
|
-
const verboseOption = command.options.find((opt) => opt.long === '--verbose')
|
|
49
|
-
const debugOption = command.options.find((opt) => opt.long === '--debug')
|
|
50
|
-
|
|
51
|
-
// Verify all options exist
|
|
52
|
-
t.truthy(engineOption, '--engine option should exist')
|
|
53
|
-
t.truthy(libOption, '--lib option should exist (deprecated alias)')
|
|
54
|
-
t.truthy(buildOption, '--build option should exist')
|
|
55
|
-
t.truthy(openOption, '--open option should exist')
|
|
56
|
-
t.truthy(quietOption, '--quiet option should exist')
|
|
57
|
-
t.truthy(verboseOption, '--verbose option should exist')
|
|
58
|
-
t.truthy(debugOption, '--debug option should exist')
|
|
59
|
-
|
|
60
|
-
// Verify they are Option instances
|
|
61
|
-
t.true(engineOption instanceof Option, '--engine should be Option instance')
|
|
62
|
-
t.true(libOption instanceof Option, '--lib should be Option instance')
|
|
63
|
-
t.true(buildOption instanceof Option, '--build should be Option instance')
|
|
64
|
-
t.true(openOption instanceof Option, '--open should be Option instance')
|
|
65
|
-
t.true(quietOption instanceof Option, '--quiet should be Option instance')
|
|
66
|
-
t.true(verboseOption instanceof Option, '--verbose should be Option instance')
|
|
67
|
-
t.true(debugOption instanceof Option, '--debug should be Option instance')
|
|
68
|
-
|
|
69
|
-
// Verify --engine option properties
|
|
70
|
-
t.is(engineOption.long, '--engine')
|
|
71
|
-
t.truthy(engineOption.description)
|
|
72
|
-
t.true(engineOption.required, '--engine should require a value')
|
|
73
|
-
|
|
74
|
-
// Verify --lib is hidden (deprecated alias)
|
|
75
|
-
t.is(libOption.long, '--lib')
|
|
76
|
-
t.true(libOption.hidden, '--lib should be hidden (deprecated)')
|
|
77
|
-
|
|
78
|
-
t.is(buildOption.long, '--build')
|
|
79
|
-
t.truthy(buildOption.description)
|
|
80
|
-
t.false(buildOption.required, '--build should not require a value')
|
|
81
|
-
|
|
82
|
-
t.is(openOption.long, '--open')
|
|
83
|
-
t.truthy(openOption.description)
|
|
84
|
-
t.false(openOption.required, '--open should not require a value')
|
|
85
|
-
|
|
86
|
-
t.is(quietOption.long, '--quiet')
|
|
87
|
-
t.is(quietOption.short, '-q', '--quiet should have -q short flag')
|
|
88
|
-
t.truthy(quietOption.description)
|
|
89
|
-
t.false(quietOption.required, '--quiet should not require a value')
|
|
90
|
-
|
|
91
|
-
t.is(verboseOption.long, '--verbose')
|
|
92
|
-
t.is(verboseOption.short, '-v', '--verbose should have -v short flag')
|
|
93
|
-
t.truthy(verboseOption.description)
|
|
94
|
-
t.false(verboseOption.required, '--verbose should not require a value')
|
|
95
|
-
|
|
96
|
-
t.is(debugOption.long, '--debug')
|
|
97
|
-
t.truthy(debugOption.description)
|
|
98
|
-
t.false(debugOption.required, '--debug should not require a value')
|
|
99
|
-
})
|
|
100
|
-
|
|
101
|
-
test('command options are accessible via public API', (t) => {
|
|
102
|
-
const { command } = t.context
|
|
103
|
-
|
|
104
|
-
// Test that options can be accessed the way Commander.js does
|
|
105
|
-
const optionNames = command.options.map((opt) => opt.long)
|
|
106
|
-
|
|
107
|
-
t.true(optionNames.includes('--engine'))
|
|
108
|
-
t.true(optionNames.includes('--lib')) // deprecated alias still exists
|
|
109
|
-
t.true(optionNames.includes('--build'))
|
|
110
|
-
t.true(optionNames.includes('--open'))
|
|
111
|
-
t.true(optionNames.includes('--quiet'))
|
|
112
|
-
t.true(optionNames.includes('--verbose'))
|
|
113
|
-
t.true(optionNames.includes('--debug'))
|
|
114
|
-
})
|
|
@@ -1,503 +0,0 @@
|
|
|
1
|
-
import test from 'ava'
|
|
2
|
-
import sinon from 'sinon'
|
|
3
|
-
import esmock from 'esmock'
|
|
4
|
-
|
|
5
|
-
test.beforeEach((t) => {
|
|
6
|
-
t.context.sandbox = sinon.createSandbox()
|
|
7
|
-
|
|
8
|
-
// Create mock reporter
|
|
9
|
-
t.context.mockReporter = {
|
|
10
|
-
configure: t.context.sandbox.stub().returnsThis(),
|
|
11
|
-
start: t.context.sandbox.stub().returnsThis(),
|
|
12
|
-
update: t.context.sandbox.stub().returnsThis(),
|
|
13
|
-
succeed: t.context.sandbox.stub().returnsThis(),
|
|
14
|
-
fail: t.context.sandbox.stub().returnsThis(),
|
|
15
|
-
stop: t.context.sandbox.stub().returnsThis(),
|
|
16
|
-
}
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
test.afterEach.always((t) => {
|
|
20
|
-
t.context.sandbox.restore()
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
test('epub command should call generateEpub with epubjs engine', async (t) => {
|
|
24
|
-
const { sandbox, mockReporter } = t.context
|
|
25
|
-
|
|
26
|
-
const mockGenerateEpub = sandbox.stub().resolves('/project/epubjs.epub')
|
|
27
|
-
|
|
28
|
-
const EPUBCommand = await esmock('./epub.js', {
|
|
29
|
-
'#lib/epub/index.js': {
|
|
30
|
-
default: mockGenerateEpub
|
|
31
|
-
},
|
|
32
|
-
'#lib/project/index.js': {
|
|
33
|
-
hasEpubOutput: () => true
|
|
34
|
-
},
|
|
35
|
-
'#lib/reporter/index.js': {
|
|
36
|
-
default: mockReporter
|
|
37
|
-
},
|
|
38
|
-
'fs-extra': {
|
|
39
|
-
existsSync: () => true
|
|
40
|
-
},
|
|
41
|
-
open: {
|
|
42
|
-
default: sandbox.stub()
|
|
43
|
-
}
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
const command = new EPUBCommand()
|
|
47
|
-
command.name = sandbox.stub().returns('epub')
|
|
48
|
-
|
|
49
|
-
await command.action({ engine: 'epubjs' }, command)
|
|
50
|
-
|
|
51
|
-
t.true(mockGenerateEpub.called, 'generateEpub should be called')
|
|
52
|
-
t.is(mockGenerateEpub.firstCall.args[0].lib, 'epubjs', 'should pass lib to generateEpub')
|
|
53
|
-
// Nota bene: reporter.start/succeed are called by façade (lib/epub/index.js), not the command
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
test('epub command should call generateEpub with pandoc engine', async (t) => {
|
|
57
|
-
const { sandbox, mockReporter } = t.context
|
|
58
|
-
|
|
59
|
-
const mockGenerateEpub = sandbox.stub().resolves('/project/pandoc.epub')
|
|
60
|
-
|
|
61
|
-
const EPUBCommand = await esmock('./epub.js', {
|
|
62
|
-
'#lib/epub/index.js': {
|
|
63
|
-
default: mockGenerateEpub
|
|
64
|
-
},
|
|
65
|
-
'#lib/project/index.js': {
|
|
66
|
-
hasEpubOutput: () => true
|
|
67
|
-
},
|
|
68
|
-
'#lib/reporter/index.js': {
|
|
69
|
-
default: mockReporter
|
|
70
|
-
},
|
|
71
|
-
'fs-extra': {
|
|
72
|
-
existsSync: () => true
|
|
73
|
-
},
|
|
74
|
-
open: {
|
|
75
|
-
default: sandbox.stub()
|
|
76
|
-
}
|
|
77
|
-
})
|
|
78
|
-
|
|
79
|
-
const command = new EPUBCommand()
|
|
80
|
-
command.name = sandbox.stub().returns('epub')
|
|
81
|
-
|
|
82
|
-
await command.action({ engine: 'pandoc' }, command)
|
|
83
|
-
|
|
84
|
-
t.true(mockGenerateEpub.called, 'generateEpub should be called')
|
|
85
|
-
t.is(mockGenerateEpub.firstCall.args[0].lib, 'pandoc', 'should pass lib to generateEpub')
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
test('epub command should open EPUB when --open flag is provided', async (t) => {
|
|
89
|
-
const { sandbox, mockReporter } = t.context
|
|
90
|
-
|
|
91
|
-
const outputPath = '/project/epubjs.epub'
|
|
92
|
-
const mockGenerateEpub = sandbox.stub().resolves(outputPath)
|
|
93
|
-
const mockOpen = sandbox.stub()
|
|
94
|
-
|
|
95
|
-
const EPUBCommand = await esmock('./epub.js', {
|
|
96
|
-
'#lib/epub/index.js': {
|
|
97
|
-
default: mockGenerateEpub
|
|
98
|
-
},
|
|
99
|
-
'#lib/project/index.js': {
|
|
100
|
-
hasEpubOutput: () => true
|
|
101
|
-
},
|
|
102
|
-
'#lib/reporter/index.js': {
|
|
103
|
-
default: mockReporter
|
|
104
|
-
},
|
|
105
|
-
'fs-extra': {
|
|
106
|
-
existsSync: () => true
|
|
107
|
-
},
|
|
108
|
-
open: {
|
|
109
|
-
default: mockOpen
|
|
110
|
-
}
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
const command = new EPUBCommand()
|
|
114
|
-
command.name = sandbox.stub().returns('epub')
|
|
115
|
-
|
|
116
|
-
await command.action({ engine: 'epubjs', open: true }, command)
|
|
117
|
-
|
|
118
|
-
t.true(mockGenerateEpub.called, 'generateEpub should be called')
|
|
119
|
-
t.true(mockOpen.called, 'open should be called when --open flag is provided')
|
|
120
|
-
t.is(mockOpen.firstCall.args[0], outputPath, 'should open the generated EPUB path')
|
|
121
|
-
})
|
|
122
|
-
|
|
123
|
-
test('epub command should not open EPUB when --open flag is not provided', async (t) => {
|
|
124
|
-
const { sandbox, mockReporter } = t.context
|
|
125
|
-
|
|
126
|
-
const mockGenerateEpub = sandbox.stub().resolves('/project/epubjs.epub')
|
|
127
|
-
const mockOpen = sandbox.stub()
|
|
128
|
-
|
|
129
|
-
const EPUBCommand = await esmock('./epub.js', {
|
|
130
|
-
'#lib/epub/index.js': {
|
|
131
|
-
default: mockGenerateEpub
|
|
132
|
-
},
|
|
133
|
-
'#lib/project/index.js': {
|
|
134
|
-
hasEpubOutput: () => true
|
|
135
|
-
},
|
|
136
|
-
'#lib/reporter/index.js': {
|
|
137
|
-
default: mockReporter
|
|
138
|
-
},
|
|
139
|
-
'fs-extra': {
|
|
140
|
-
existsSync: () => true
|
|
141
|
-
},
|
|
142
|
-
open: {
|
|
143
|
-
default: mockOpen
|
|
144
|
-
}
|
|
145
|
-
})
|
|
146
|
-
|
|
147
|
-
const command = new EPUBCommand()
|
|
148
|
-
command.name = sandbox.stub().returns('epub')
|
|
149
|
-
|
|
150
|
-
await command.action({ engine: 'epubjs' }, command)
|
|
151
|
-
|
|
152
|
-
t.true(mockGenerateEpub.called, 'generateEpub should be called')
|
|
153
|
-
t.false(mockOpen.called, 'open should not be called without --open flag')
|
|
154
|
-
})
|
|
155
|
-
|
|
156
|
-
test('epub command should pass debug option to generateEpub', async (t) => {
|
|
157
|
-
const { sandbox, mockReporter } = t.context
|
|
158
|
-
|
|
159
|
-
const mockGenerateEpub = sandbox.stub().resolves('/project/epubjs.epub')
|
|
160
|
-
|
|
161
|
-
const EPUBCommand = await esmock('./epub.js', {
|
|
162
|
-
'#lib/epub/index.js': {
|
|
163
|
-
default: mockGenerateEpub
|
|
164
|
-
},
|
|
165
|
-
'#lib/project/index.js': {
|
|
166
|
-
hasEpubOutput: () => true
|
|
167
|
-
},
|
|
168
|
-
'#lib/reporter/index.js': {
|
|
169
|
-
default: mockReporter
|
|
170
|
-
},
|
|
171
|
-
'fs-extra': {
|
|
172
|
-
existsSync: () => true
|
|
173
|
-
},
|
|
174
|
-
open: {
|
|
175
|
-
default: sandbox.stub()
|
|
176
|
-
}
|
|
177
|
-
})
|
|
178
|
-
|
|
179
|
-
const command = new EPUBCommand()
|
|
180
|
-
command.name = sandbox.stub().returns('epub')
|
|
181
|
-
|
|
182
|
-
await command.action({ engine: 'epubjs', debug: true }, command)
|
|
183
|
-
|
|
184
|
-
t.true(mockGenerateEpub.called, 'generateEpub should be called')
|
|
185
|
-
t.is(mockGenerateEpub.firstCall.args[0].lib, 'epubjs', 'should pass lib to generateEpub')
|
|
186
|
-
t.true(mockGenerateEpub.firstCall.args[0].debug, 'should pass debug option')
|
|
187
|
-
})
|
|
188
|
-
|
|
189
|
-
test('epub command should throw MissingBuildOutputError when build output is missing', async (t) => {
|
|
190
|
-
const { sandbox, mockReporter } = t.context
|
|
191
|
-
|
|
192
|
-
const mockGenerateEpub = sandbox.stub().resolves('/project/epubjs.epub')
|
|
193
|
-
|
|
194
|
-
const EPUBCommand = await esmock('./epub.js', {
|
|
195
|
-
'#lib/epub/index.js': {
|
|
196
|
-
default: mockGenerateEpub
|
|
197
|
-
},
|
|
198
|
-
'#lib/project/index.js': {
|
|
199
|
-
default: { getEpubDir: () => '_epub' },
|
|
200
|
-
hasEpubOutput: () => false
|
|
201
|
-
},
|
|
202
|
-
'#lib/reporter/index.js': {
|
|
203
|
-
default: mockReporter
|
|
204
|
-
},
|
|
205
|
-
'fs-extra': {
|
|
206
|
-
existsSync: () => true
|
|
207
|
-
},
|
|
208
|
-
open: {
|
|
209
|
-
default: sandbox.stub()
|
|
210
|
-
}
|
|
211
|
-
})
|
|
212
|
-
|
|
213
|
-
const command = new EPUBCommand()
|
|
214
|
-
command.name = sandbox.stub().returns('epub')
|
|
215
|
-
|
|
216
|
-
const error = await t.throwsAsync(() => command.action({ engine: 'epubjs' }, command))
|
|
217
|
-
|
|
218
|
-
t.is(error.code, 'BUILD_OUTPUT_MISSING', 'should throw BUILD_OUTPUT_MISSING error')
|
|
219
|
-
t.regex(error.message, /EPUB/, 'error should mention EPUB')
|
|
220
|
-
t.false(mockGenerateEpub.called, 'generateEpub should not be called when build output is missing')
|
|
221
|
-
})
|
|
222
|
-
|
|
223
|
-
test('epub command should run build first when --build flag is set and output missing', async (t) => {
|
|
224
|
-
const { sandbox, mockReporter } = t.context
|
|
225
|
-
|
|
226
|
-
const mockGenerateEpub = sandbox.stub().resolves('/project/epubjs.epub')
|
|
227
|
-
const mockBuild = sandbox.stub().resolves()
|
|
228
|
-
let buildCalled = false
|
|
229
|
-
|
|
230
|
-
const EPUBCommand = await esmock('./epub.js', {
|
|
231
|
-
'#lib/epub/index.js': {
|
|
232
|
-
default: mockGenerateEpub
|
|
233
|
-
},
|
|
234
|
-
'#lib/project/index.js': {
|
|
235
|
-
hasEpubOutput: () => {
|
|
236
|
-
// Return false first (before build), true after build
|
|
237
|
-
if (!buildCalled) return false
|
|
238
|
-
return true
|
|
239
|
-
}
|
|
240
|
-
},
|
|
241
|
-
'#lib/11ty/index.js': {
|
|
242
|
-
default: {
|
|
243
|
-
build: async (opts) => {
|
|
244
|
-
buildCalled = true
|
|
245
|
-
return mockBuild(opts)
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
},
|
|
249
|
-
'#lib/reporter/index.js': {
|
|
250
|
-
default: mockReporter
|
|
251
|
-
},
|
|
252
|
-
'fs-extra': {
|
|
253
|
-
existsSync: () => true
|
|
254
|
-
},
|
|
255
|
-
open: {
|
|
256
|
-
default: sandbox.stub()
|
|
257
|
-
}
|
|
258
|
-
})
|
|
259
|
-
|
|
260
|
-
const command = new EPUBCommand()
|
|
261
|
-
command.name = sandbox.stub().returns('epub')
|
|
262
|
-
|
|
263
|
-
await command.action({ engine: 'epubjs', build: true }, command)
|
|
264
|
-
|
|
265
|
-
t.true(mockBuild.called, 'build should be called when --build flag is set')
|
|
266
|
-
t.true(mockGenerateEpub.called, 'generateEpub should be called after build')
|
|
267
|
-
})
|
|
268
|
-
|
|
269
|
-
test('epub command should support deprecated --lib option', async (t) => {
|
|
270
|
-
const { sandbox, mockReporter } = t.context
|
|
271
|
-
|
|
272
|
-
const mockGenerateEpub = sandbox.stub().resolves('/project/pandoc.epub')
|
|
273
|
-
|
|
274
|
-
const EPUBCommand = await esmock('./epub.js', {
|
|
275
|
-
'#lib/epub/index.js': {
|
|
276
|
-
default: mockGenerateEpub
|
|
277
|
-
},
|
|
278
|
-
'#lib/project/index.js': {
|
|
279
|
-
hasEpubOutput: () => true
|
|
280
|
-
},
|
|
281
|
-
'#lib/reporter/index.js': {
|
|
282
|
-
default: mockReporter
|
|
283
|
-
},
|
|
284
|
-
'fs-extra': {
|
|
285
|
-
existsSync: () => true
|
|
286
|
-
},
|
|
287
|
-
open: {
|
|
288
|
-
default: sandbox.stub()
|
|
289
|
-
}
|
|
290
|
-
})
|
|
291
|
-
|
|
292
|
-
const command = new EPUBCommand()
|
|
293
|
-
command.name = sandbox.stub().returns('epub')
|
|
294
|
-
|
|
295
|
-
// Use deprecated --lib option (should still work)
|
|
296
|
-
await command.action({ lib: 'pandoc' }, command)
|
|
297
|
-
|
|
298
|
-
t.true(mockGenerateEpub.called, 'generateEpub should be called with deprecated --lib')
|
|
299
|
-
t.is(mockGenerateEpub.firstCall.args[0].lib, 'pandoc', 'should pass lib to generateEpub from deprecated option')
|
|
300
|
-
})
|
|
301
|
-
|
|
302
|
-
test('epub command should propagate errors from generateEpub', async (t) => {
|
|
303
|
-
const { sandbox, mockReporter } = t.context
|
|
304
|
-
|
|
305
|
-
const epubError = new Error('EPUB generation failed')
|
|
306
|
-
const mockGenerateEpub = sandbox.stub().rejects(epubError)
|
|
307
|
-
|
|
308
|
-
const EPUBCommand = await esmock('./epub.js', {
|
|
309
|
-
'#lib/epub/index.js': {
|
|
310
|
-
default: mockGenerateEpub
|
|
311
|
-
},
|
|
312
|
-
'#lib/project/index.js': {
|
|
313
|
-
hasEpubOutput: () => true
|
|
314
|
-
},
|
|
315
|
-
'#lib/reporter/index.js': {
|
|
316
|
-
default: mockReporter
|
|
317
|
-
},
|
|
318
|
-
'fs-extra': {
|
|
319
|
-
existsSync: () => true
|
|
320
|
-
},
|
|
321
|
-
open: {
|
|
322
|
-
default: sandbox.stub()
|
|
323
|
-
}
|
|
324
|
-
})
|
|
325
|
-
|
|
326
|
-
const command = new EPUBCommand()
|
|
327
|
-
command.name = sandbox.stub().returns('epub')
|
|
328
|
-
|
|
329
|
-
// Error is propagated; reporter lifecycle is handled by façade (lib/epub/index.js)
|
|
330
|
-
await t.throwsAsync(() => command.action({ engine: 'epubjs' }, command), { message: 'EPUB generation failed' })
|
|
331
|
-
})
|
|
332
|
-
|
|
333
|
-
test('epub command should configure reporter with quiet option', async (t) => {
|
|
334
|
-
const { sandbox, mockReporter } = t.context
|
|
335
|
-
|
|
336
|
-
const mockGenerateEpub = sandbox.stub().resolves('/project/epubjs.epub')
|
|
337
|
-
|
|
338
|
-
const EPUBCommand = await esmock('./epub.js', {
|
|
339
|
-
'#lib/epub/index.js': {
|
|
340
|
-
default: mockGenerateEpub
|
|
341
|
-
},
|
|
342
|
-
'#lib/project/index.js': {
|
|
343
|
-
hasEpubOutput: () => true
|
|
344
|
-
},
|
|
345
|
-
'#lib/reporter/index.js': {
|
|
346
|
-
default: mockReporter
|
|
347
|
-
},
|
|
348
|
-
'fs-extra': {
|
|
349
|
-
existsSync: () => true
|
|
350
|
-
},
|
|
351
|
-
open: {
|
|
352
|
-
default: sandbox.stub()
|
|
353
|
-
}
|
|
354
|
-
})
|
|
355
|
-
|
|
356
|
-
const command = new EPUBCommand()
|
|
357
|
-
command.name = sandbox.stub().returns('epub')
|
|
358
|
-
|
|
359
|
-
await command.action({ engine: 'epubjs', quiet: true }, command)
|
|
360
|
-
|
|
361
|
-
t.true(
|
|
362
|
-
mockReporter.configure.calledWith(sinon.match({ quiet: true })),
|
|
363
|
-
'reporter.configure should be called with quiet option'
|
|
364
|
-
)
|
|
365
|
-
})
|
|
366
|
-
|
|
367
|
-
test('epub command should pass output option to generateEpub', async (t) => {
|
|
368
|
-
const { sandbox, mockReporter } = t.context
|
|
369
|
-
|
|
370
|
-
const customOutput = '/custom/path/my-book.epub'
|
|
371
|
-
const mockGenerateEpub = sandbox.stub().resolves(customOutput)
|
|
372
|
-
|
|
373
|
-
const EPUBCommand = await esmock('./epub.js', {
|
|
374
|
-
'#lib/epub/index.js': {
|
|
375
|
-
default: mockGenerateEpub
|
|
376
|
-
},
|
|
377
|
-
'#lib/project/index.js': {
|
|
378
|
-
hasEpubOutput: () => true
|
|
379
|
-
},
|
|
380
|
-
'#lib/reporter/index.js': {
|
|
381
|
-
default: mockReporter
|
|
382
|
-
},
|
|
383
|
-
'fs-extra': {
|
|
384
|
-
existsSync: () => true
|
|
385
|
-
},
|
|
386
|
-
open: {
|
|
387
|
-
default: sandbox.stub()
|
|
388
|
-
}
|
|
389
|
-
})
|
|
390
|
-
|
|
391
|
-
const command = new EPUBCommand()
|
|
392
|
-
command.name = sandbox.stub().returns('epub')
|
|
393
|
-
|
|
394
|
-
await command.action({ engine: 'epubjs', output: customOutput }, command)
|
|
395
|
-
|
|
396
|
-
t.true(mockGenerateEpub.called, 'generateEpub should be called')
|
|
397
|
-
t.is(mockGenerateEpub.firstCall.args[0].output, customOutput, 'should pass output option to generateEpub')
|
|
398
|
-
})
|
|
399
|
-
|
|
400
|
-
test('epub command should use epubEngine from config when --engine not specified', async (t) => {
|
|
401
|
-
const { sandbox, mockReporter } = t.context
|
|
402
|
-
|
|
403
|
-
const mockGenerateEpub = sandbox.stub().resolves('/project/pandoc.epub')
|
|
404
|
-
|
|
405
|
-
const EPUBCommand = await esmock('./epub.js', {
|
|
406
|
-
'#lib/epub/index.js': {
|
|
407
|
-
default: mockGenerateEpub
|
|
408
|
-
},
|
|
409
|
-
'#lib/project/index.js': {
|
|
410
|
-
hasEpubOutput: () => true
|
|
411
|
-
},
|
|
412
|
-
'#lib/reporter/index.js': {
|
|
413
|
-
default: mockReporter
|
|
414
|
-
},
|
|
415
|
-
'fs-extra': {
|
|
416
|
-
existsSync: () => true
|
|
417
|
-
},
|
|
418
|
-
open: {
|
|
419
|
-
default: sandbox.stub()
|
|
420
|
-
}
|
|
421
|
-
})
|
|
422
|
-
|
|
423
|
-
const command = new EPUBCommand()
|
|
424
|
-
command.name = sandbox.stub().returns('epub')
|
|
425
|
-
// Mock config to return 'pandoc' for epubEngine
|
|
426
|
-
command.config = { get: (key) => key === 'epubEngine' ? 'pandoc' : undefined }
|
|
427
|
-
|
|
428
|
-
// No --engine specified, should use config value
|
|
429
|
-
await command.action({}, command)
|
|
430
|
-
|
|
431
|
-
t.true(mockGenerateEpub.called, 'generateEpub should be called')
|
|
432
|
-
t.is(mockGenerateEpub.firstCall.args[0].lib, 'pandoc', 'should use epubEngine from config')
|
|
433
|
-
})
|
|
434
|
-
|
|
435
|
-
test('epub command should use default engine when --engine not specified and config not set', async (t) => {
|
|
436
|
-
const { sandbox, mockReporter } = t.context
|
|
437
|
-
|
|
438
|
-
const mockGenerateEpub = sandbox.stub().resolves('/project/epubjs.epub')
|
|
439
|
-
|
|
440
|
-
const EPUBCommand = await esmock('./epub.js', {
|
|
441
|
-
'#lib/epub/index.js': {
|
|
442
|
-
default: mockGenerateEpub
|
|
443
|
-
},
|
|
444
|
-
'#lib/project/index.js': {
|
|
445
|
-
hasEpubOutput: () => true
|
|
446
|
-
},
|
|
447
|
-
'#lib/reporter/index.js': {
|
|
448
|
-
default: mockReporter
|
|
449
|
-
},
|
|
450
|
-
'fs-extra': {
|
|
451
|
-
existsSync: () => true
|
|
452
|
-
},
|
|
453
|
-
open: {
|
|
454
|
-
default: sandbox.stub()
|
|
455
|
-
}
|
|
456
|
-
})
|
|
457
|
-
|
|
458
|
-
const command = new EPUBCommand()
|
|
459
|
-
command.name = sandbox.stub().returns('epub')
|
|
460
|
-
// Mock config to return undefined (no epubEngine set)
|
|
461
|
-
command.config = { get: () => undefined }
|
|
462
|
-
|
|
463
|
-
// No --engine specified, no config, should use default 'epubjs'
|
|
464
|
-
await command.action({}, command)
|
|
465
|
-
|
|
466
|
-
t.true(mockGenerateEpub.called, 'generateEpub should be called')
|
|
467
|
-
t.is(mockGenerateEpub.firstCall.args[0].lib, 'epubjs', 'should use default epubjs when no config')
|
|
468
|
-
})
|
|
469
|
-
|
|
470
|
-
test('epub command --engine flag should override config epubEngine', async (t) => {
|
|
471
|
-
const { sandbox, mockReporter } = t.context
|
|
472
|
-
|
|
473
|
-
const mockGenerateEpub = sandbox.stub().resolves('/project/epubjs.epub')
|
|
474
|
-
|
|
475
|
-
const EPUBCommand = await esmock('./epub.js', {
|
|
476
|
-
'#lib/epub/index.js': {
|
|
477
|
-
default: mockGenerateEpub
|
|
478
|
-
},
|
|
479
|
-
'#lib/project/index.js': {
|
|
480
|
-
hasEpubOutput: () => true
|
|
481
|
-
},
|
|
482
|
-
'#lib/reporter/index.js': {
|
|
483
|
-
default: mockReporter
|
|
484
|
-
},
|
|
485
|
-
'fs-extra': {
|
|
486
|
-
existsSync: () => true
|
|
487
|
-
},
|
|
488
|
-
open: {
|
|
489
|
-
default: sandbox.stub()
|
|
490
|
-
}
|
|
491
|
-
})
|
|
492
|
-
|
|
493
|
-
const command = new EPUBCommand()
|
|
494
|
-
command.name = sandbox.stub().returns('epub')
|
|
495
|
-
// Mock config to return 'pandoc' for epubEngine
|
|
496
|
-
command.config = { get: (key) => key === 'epubEngine' ? 'pandoc' : undefined }
|
|
497
|
-
|
|
498
|
-
// --engine epubjs should override config's 'pandoc'
|
|
499
|
-
await command.action({ engine: 'epubjs' }, command)
|
|
500
|
-
|
|
501
|
-
t.true(mockGenerateEpub.called, 'generateEpub should be called')
|
|
502
|
-
t.is(mockGenerateEpub.firstCall.args[0].lib, 'epubjs', 'CLI --engine should override config')
|
|
503
|
-
})
|
package/src/commands/help.js
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import Command from '#src/Command.js'
|
|
2
|
-
import { outputWithPaging } from '#helpers/pager.js'
|
|
3
|
-
import { getTopicContent, getTopicList } from '#lib/help/index.js'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Quire CLI `help` Command
|
|
7
|
-
*
|
|
8
|
-
* Display help for a specific topic or list available topics.
|
|
9
|
-
* Complements Commander's built-in help with extended documentation.
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* quire help # List available topics
|
|
13
|
-
* quire help workflows # Show workflows topic
|
|
14
|
-
* quire help --list # List available topics
|
|
15
|
-
*
|
|
16
|
-
* @class HelpCommand
|
|
17
|
-
* @extends {Command}
|
|
18
|
-
*/
|
|
19
|
-
export default class HelpCommand extends Command {
|
|
20
|
-
static definition = {
|
|
21
|
-
name: 'help',
|
|
22
|
-
aliases: ['h'],
|
|
23
|
-
description: 'Display help for a topic or list available topics',
|
|
24
|
-
summary: 'show help for a topic',
|
|
25
|
-
docsLink: 'quire-commands/',
|
|
26
|
-
helpText: `
|
|
27
|
-
Examples:
|
|
28
|
-
quire help List available help topics
|
|
29
|
-
quire help workflows Show common workflow examples
|
|
30
|
-
quire help pdf Show PDF generation guide
|
|
31
|
-
quire help --list List all available topics
|
|
32
|
-
`,
|
|
33
|
-
version: '1.0.0',
|
|
34
|
-
args: [
|
|
35
|
-
['[topic]', 'help topic to display']
|
|
36
|
-
],
|
|
37
|
-
options: [
|
|
38
|
-
['--list', 'list all available topics'],
|
|
39
|
-
],
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
constructor() {
|
|
43
|
-
super(HelpCommand.definition)
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
async action(topic, options, command) {
|
|
47
|
-
this.debug('called with topic=%s options=%O', topic, options)
|
|
48
|
-
|
|
49
|
-
// List topics if no topic specified or --list flag
|
|
50
|
-
if (!topic || options.list) {
|
|
51
|
-
const list = await getTopicList()
|
|
52
|
-
process.stdout.write(list + '\n')
|
|
53
|
-
return
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Display requested topic with paging (throws HelpTopicNotFoundError if missing)
|
|
57
|
-
const content = await getTopicContent(topic)
|
|
58
|
-
await outputWithPaging(content)
|
|
59
|
-
}
|
|
60
|
-
}
|