@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
package/src/lib/conf/defaults.js
CHANGED
|
@@ -5,56 +5,10 @@
|
|
|
5
5
|
* @see https://github.com/sindresorhus/conf#defaults
|
|
6
6
|
*/
|
|
7
7
|
export default {
|
|
8
|
-
/**
|
|
9
|
-
* Enable debug output by default (DEBUG=quire:* namespace logging).
|
|
10
|
-
* Can be overridden per-command with --debug or --no-debug.
|
|
11
|
-
*/
|
|
12
|
-
debug: false,
|
|
13
|
-
/**
|
|
14
|
-
* Default EPUB engine for quire epub command.
|
|
15
|
-
*/
|
|
16
|
-
epubEngine: 'epubjs',
|
|
17
8
|
/**
|
|
18
9
|
* Logging level for the Quire CLI output.
|
|
19
10
|
*/
|
|
20
11
|
logLevel: 'info',
|
|
21
|
-
/**
|
|
22
|
-
* Prefix text for log output messages.
|
|
23
|
-
*/
|
|
24
|
-
logPrefix: 'quire',
|
|
25
|
-
/**
|
|
26
|
-
* Style of the log prefix.
|
|
27
|
-
* - 'bracket': [quire] message
|
|
28
|
-
* - 'emoji': 📖 message
|
|
29
|
-
* - 'plain': quire: message
|
|
30
|
-
* - 'none': message (no prefix)
|
|
31
|
-
*/
|
|
32
|
-
logPrefixStyle: 'bracket',
|
|
33
|
-
/**
|
|
34
|
-
* Whether to show log level labels (INFO, WARN, ERROR).
|
|
35
|
-
* Defaults to false for cleaner user output.
|
|
36
|
-
*/
|
|
37
|
-
logShowLevel: false,
|
|
38
|
-
/**
|
|
39
|
-
* Whether to use colored output in terminal.
|
|
40
|
-
*/
|
|
41
|
-
logUseColor: true,
|
|
42
|
-
/**
|
|
43
|
-
* Whether to color message text by log level (e.g., red for errors).
|
|
44
|
-
* Requires logUseColor to be enabled.
|
|
45
|
-
*/
|
|
46
|
-
logColorMessages: true,
|
|
47
|
-
/**
|
|
48
|
-
* Default PDF engine for quire pdf command.
|
|
49
|
-
*/
|
|
50
|
-
pdfEngine: 'pagedjs',
|
|
51
|
-
/**
|
|
52
|
-
* Disable spinner animation and line overwriting.
|
|
53
|
-
* When enabled, progress output uses static text instead of animated spinners,
|
|
54
|
-
* and each stage prints on a new line rather than overwriting the current line.
|
|
55
|
-
* Can be overridden per-command with --reduced-motion.
|
|
56
|
-
*/
|
|
57
|
-
reducedMotion: false,
|
|
58
12
|
/**
|
|
59
13
|
* Project starter template to use when creating new projects.
|
|
60
14
|
*/
|
|
@@ -63,15 +17,6 @@ export default {
|
|
|
63
17
|
* Relative path to quire-11ty installed in the project directory.
|
|
64
18
|
*/
|
|
65
19
|
quire11tyPath: '.',
|
|
66
|
-
/**
|
|
67
|
-
* How stale an output must be before `quire doctor` warns.
|
|
68
|
-
* - 'ZERO': any time difference (0 minutes)
|
|
69
|
-
* - 'SHORT': 5 minutes
|
|
70
|
-
* - 'HOURLY': 60 minutes (default)
|
|
71
|
-
* - 'DAILY': 12 hours
|
|
72
|
-
* - 'NEVER': disable stale output warnings
|
|
73
|
-
*/
|
|
74
|
-
staleThreshold: 'HOURLY',
|
|
75
20
|
/**
|
|
76
21
|
* Version of quire-11ty to install when creating new projects.
|
|
77
22
|
*/
|
|
@@ -85,18 +30,8 @@ export default {
|
|
|
85
30
|
* and to quire-11ty version for a prject.
|
|
86
31
|
*/
|
|
87
32
|
updateInterval: 'DAILY',
|
|
88
|
-
/**
|
|
89
|
-
* Enable verbose output by default (detailed progress with paths, timing).
|
|
90
|
-
* Can be overridden per-command with --verbose or --no-verbose.
|
|
91
|
-
*/
|
|
92
|
-
verbose: false,
|
|
93
33
|
/**
|
|
94
34
|
* File name for the quire-11ty version file.
|
|
95
35
|
*/
|
|
96
36
|
versionFile: '.quire',
|
|
97
|
-
/**
|
|
98
|
-
* Per-project data (internal).
|
|
99
|
-
* Keyed by SHA-256 hash of the project's absolute path.
|
|
100
|
-
*/
|
|
101
|
-
projects: {},
|
|
102
37
|
}
|
package/src/lib/conf/schema.js
CHANGED
|
@@ -2,123 +2,29 @@
|
|
|
2
2
|
* Quire configuration schema
|
|
3
3
|
* @see https://github.com/sindresorhus/conf#schema
|
|
4
4
|
*
|
|
5
|
-
* Nota bene: default values
|
|
5
|
+
* Nota bene: schema default values will are overwritten by `defaults.js` values
|
|
6
6
|
* @see https://github.com/sindresorhus/conf#defaults
|
|
7
7
|
*/
|
|
8
|
-
import { schema as epubEngineSchema } from '#lib/epub/schema.js'
|
|
9
|
-
import { schema as pdfEngineSchema } from '#lib/pdf/schema.js'
|
|
10
|
-
|
|
11
8
|
export default {
|
|
12
|
-
debug: {
|
|
13
|
-
type: 'boolean',
|
|
14
|
-
description: 'Enable debug output by default (equivalent to --debug flag)'
|
|
15
|
-
},
|
|
16
|
-
epubEngine: epubEngineSchema,
|
|
17
|
-
pdfEngine: pdfEngineSchema,
|
|
18
9
|
logLevel: {
|
|
19
|
-
type: 'string'
|
|
20
|
-
enum: ['trace', 'debug', 'info', 'warn', 'error', 'silent'],
|
|
21
|
-
description: 'Minimum log level to display (trace, debug, info, warn, error, silent)'
|
|
22
|
-
},
|
|
23
|
-
logPrefix: {
|
|
24
|
-
type: 'string',
|
|
25
|
-
description: 'Prefix text shown before log messages'
|
|
26
|
-
},
|
|
27
|
-
logPrefixStyle: {
|
|
28
|
-
type: 'string',
|
|
29
|
-
enum: ['bracket', 'emoji', 'plain', 'none'],
|
|
30
|
-
description: 'Style for displaying the log prefix (bracket: [quire], emoji: 📖, plain: quire:, none: no prefix)'
|
|
31
|
-
},
|
|
32
|
-
logShowLevel: {
|
|
33
|
-
type: 'boolean',
|
|
34
|
-
description: 'Show log level label (INFO, WARN, etc.) in output'
|
|
35
|
-
},
|
|
36
|
-
logUseColor: {
|
|
37
|
-
type: 'boolean',
|
|
38
|
-
description: 'Use colored output for log messages'
|
|
39
|
-
},
|
|
40
|
-
logColorMessages: {
|
|
41
|
-
type: 'boolean',
|
|
42
|
-
description: 'Color message text by log level (e.g., red for errors). Requires logUseColor'
|
|
43
|
-
},
|
|
44
|
-
reducedMotion: {
|
|
45
|
-
type: 'boolean',
|
|
46
|
-
description: 'Disable spinner animation and line overwriting (for screen readers and reduced-motion preferences)'
|
|
10
|
+
type: 'string'
|
|
47
11
|
},
|
|
48
12
|
projectTemplate: {
|
|
49
|
-
type: 'string'
|
|
50
|
-
format: 'uri',
|
|
51
|
-
description: 'URL of the default project template for quire new'
|
|
13
|
+
type: 'string'
|
|
52
14
|
},
|
|
53
15
|
quire11tyPath: {
|
|
54
|
-
type: 'string'
|
|
55
|
-
description: 'Path to the quire-11ty package (use "." for local development)'
|
|
56
|
-
},
|
|
57
|
-
staleThreshold: {
|
|
58
|
-
type: 'string',
|
|
59
|
-
enum: ['ZERO', 'SHORT', 'HOURLY', 'DAILY', 'NEVER'],
|
|
60
|
-
description: 'How stale an output must be before doctor warns (ZERO=0m, SHORT=5m, HOURLY=60m, DAILY=12h, NEVER=disabled)'
|
|
16
|
+
type: 'string'
|
|
61
17
|
},
|
|
62
18
|
quireVersion: {
|
|
63
|
-
type: 'string'
|
|
64
|
-
description: 'Version of quire-11ty to use ("latest" or specific version)'
|
|
19
|
+
type: 'string'
|
|
65
20
|
},
|
|
66
21
|
updateChannel: {
|
|
67
|
-
type: 'string'
|
|
68
|
-
enum: ['stable', 'rc', 'beta', 'alpha'],
|
|
69
|
-
description: 'Release channel for updates (stable, rc, beta, alpha)'
|
|
22
|
+
type: 'string'
|
|
70
23
|
},
|
|
71
24
|
updateInterval: {
|
|
72
|
-
type: 'string'
|
|
73
|
-
enum: ['DAILY', 'WEEKLY', 'MONTHLY', 'NEVER'],
|
|
74
|
-
description: 'How often to check for updates (DAILY, WEEKLY, MONTHLY, NEVER)'
|
|
75
|
-
},
|
|
76
|
-
verbose: {
|
|
77
|
-
type: 'boolean',
|
|
78
|
-
description: 'Enable verbose output by default (equivalent to --verbose flag)'
|
|
25
|
+
type: 'string'
|
|
79
26
|
},
|
|
80
27
|
versionFile: {
|
|
81
|
-
type: 'string'
|
|
82
|
-
|
|
83
|
-
},
|
|
84
|
-
projects: {
|
|
85
|
-
type: 'object',
|
|
86
|
-
description: 'Per-project data keyed by hashed project path (internal)',
|
|
87
|
-
additionalProperties: {
|
|
88
|
-
type: 'object',
|
|
89
|
-
properties: {
|
|
90
|
-
projectPath: { type: 'string' },
|
|
91
|
-
buildStatus: {
|
|
92
|
-
type: 'object',
|
|
93
|
-
properties: {
|
|
94
|
-
build: {
|
|
95
|
-
type: 'object',
|
|
96
|
-
properties: {
|
|
97
|
-
status: { type: 'string', enum: ['ok', 'failed'] },
|
|
98
|
-
timestamp: { type: 'number' },
|
|
99
|
-
},
|
|
100
|
-
required: ['status', 'timestamp'],
|
|
101
|
-
},
|
|
102
|
-
pdf: {
|
|
103
|
-
type: 'object',
|
|
104
|
-
properties: {
|
|
105
|
-
status: { type: 'string', enum: ['ok', 'failed'] },
|
|
106
|
-
timestamp: { type: 'number' },
|
|
107
|
-
},
|
|
108
|
-
required: ['status', 'timestamp'],
|
|
109
|
-
},
|
|
110
|
-
epub: {
|
|
111
|
-
type: 'object',
|
|
112
|
-
properties: {
|
|
113
|
-
status: { type: 'string', enum: ['ok', 'failed'] },
|
|
114
|
-
timestamp: { type: 'number' },
|
|
115
|
-
},
|
|
116
|
-
required: ['status', 'timestamp'],
|
|
117
|
-
},
|
|
118
|
-
},
|
|
119
|
-
},
|
|
120
|
-
},
|
|
121
|
-
required: ['projectPath'],
|
|
122
|
-
},
|
|
123
|
-
},
|
|
28
|
+
type: 'string'
|
|
29
|
+
}
|
|
124
30
|
}
|
package/src/lib/epub/README.md
CHANGED
|
@@ -1,138 +1,7 @@
|
|
|
1
1
|
## CLI lib/EPUB Module
|
|
2
2
|
|
|
3
|
-
This module
|
|
4
|
-
|
|
5
|
-
### Architecture
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
┌───────────────────────────────────────────────────────────┐
|
|
9
|
-
│ lib/epub/index.js (Façade) │
|
|
10
|
-
│ • Resolve engine (epubjs/pandoc) │
|
|
11
|
-
│ • Check engine availability (fail-fast) │
|
|
12
|
-
│ • Resolve output path (CLI > default) │
|
|
13
|
-
│ • Own reporter lifecycle (start/succeed/fail) │
|
|
14
|
-
│ • Dynamic import of engine implementation │
|
|
15
|
-
└───────────────────────────┬───────────────────────────────┘
|
|
16
|
-
│
|
|
17
|
-
┌─────────────┴─────────────────┐
|
|
18
|
-
│ lib/epub/engines.js │
|
|
19
|
-
│ • Central engine registry │
|
|
20
|
-
│ • Metadata (name, binary, │
|
|
21
|
-
│ toolInfo for errors) │
|
|
22
|
-
└─────────────┬─────────────────┘
|
|
23
|
-
│
|
|
24
|
-
┌────────────────┴────────────────────┐
|
|
25
|
-
│ │
|
|
26
|
-
┌──────────▼───────────┐ ┌───────────▼────────────┐
|
|
27
|
-
│ lib/epub/epub.js │ │ lib/epub/pandoc.js │
|
|
28
|
-
│ • Epub.js wrapper │ │ • Pandoc CLI wrapper │
|
|
29
|
-
│ • Load manifest │ │ • Filter XHTML files │
|
|
30
|
-
│ • Generate EPUB │ │ • Invoke pandoc │
|
|
31
|
-
│ • Write file │ │ • Write file │
|
|
32
|
-
└──────────────────────┘ └────────────────────────┘
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
### Usage
|
|
36
|
-
|
|
37
|
-
```javascript
|
|
38
|
-
import generateEpub from '#lib/epub/index.js'
|
|
39
|
-
|
|
40
|
-
// Generate EPUB with Epub.js (default)
|
|
41
|
-
const output = await generateEpub({
|
|
42
|
-
lib: 'epubjs',
|
|
43
|
-
output: 'my-book.epub',
|
|
44
|
-
reporter,
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
// Generate EPUB with Pandoc
|
|
48
|
-
const output = await generateEpub({
|
|
49
|
-
lib: 'pandoc',
|
|
50
|
-
output: 'my-book.epub',
|
|
51
|
-
reporter,
|
|
52
|
-
})
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
### Options
|
|
56
|
-
|
|
57
|
-
| Option | Type | Default | Description |
|
|
58
|
-
|--------|------|---------|-------------|
|
|
59
|
-
| `lib` | string | `'epubjs'` | Engine to use: `'epubjs'` or `'pandoc'` |
|
|
60
|
-
| `output` | string | `'{lib}.epub'` | Output file path |
|
|
61
|
-
| `reporter` | object | required | Reporter instance for progress messages |
|
|
62
|
-
| `debug` | boolean | `false` | Enable debug output |
|
|
63
|
-
|
|
64
|
-
### Output Path Resolution
|
|
65
|
-
|
|
66
|
-
The output path is resolved in priority order:
|
|
67
|
-
1. CLI `--output` option value
|
|
68
|
-
2. Default: `{lib}.epub` (e.g., `epubjs.epub` or `pandoc.epub`)
|
|
69
|
-
|
|
70
|
-
Relative paths are resolved against the project root. The `.epub` extension is auto-added if missing.
|
|
3
|
+
This module implements a façade for EPUB e-book file format generation libries. The module exports a single method that accepts a `lib` option and delegates to a façade for the specified EPUB library.
|
|
71
4
|
|
|
72
5
|
### Epub.js Façade
|
|
73
6
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
**How it works:**
|
|
77
|
-
1. Loads `manifest.json` from the build output directory
|
|
78
|
-
2. Uses `ManifestToEpub` to generate the EPUB content
|
|
79
|
-
3. Writes the generated file to the output path
|
|
80
|
-
|
|
81
|
-
See the [Epub.js documentation](https://github.com/futurepress/epub.js) for more details.
|
|
82
|
-
|
|
83
|
-
### Pandoc Façade
|
|
84
|
-
|
|
85
|
-
Wraps the [Pandoc](https://pandoc.org/) command-line tool for EPUB generation.
|
|
86
|
-
|
|
87
|
-
**How it works:**
|
|
88
|
-
1. Filters XHTML files from the build output
|
|
89
|
-
2. Invokes `pandoc` with appropriate options
|
|
90
|
-
3. Writes the generated EPUB to the output path
|
|
91
|
-
|
|
92
|
-
**Requirements:** Pandoc must be installed and available in PATH.
|
|
93
|
-
|
|
94
|
-
See the [Pandoc documentation](https://pandoc.org/MANUAL.html#creating-epubs-with-pandoc) for EPUB-specific options.
|
|
95
|
-
|
|
96
|
-
### Engine Availability Check
|
|
97
|
-
|
|
98
|
-
The façade performs a fail-fast check before starting the reporter:
|
|
99
|
-
|
|
100
|
-
```javascript
|
|
101
|
-
// Runs BEFORE reporter.start()
|
|
102
|
-
checkEngineAvailable(engine) // Throws ToolNotFoundError if binary missing
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
- **Epub.js:** No binary check needed (pure JavaScript)
|
|
106
|
-
- **Pandoc:** Checks for `pandoc` in PATH
|
|
107
|
-
|
|
108
|
-
If the engine is unavailable, a `ToolNotFoundError` is thrown with:
|
|
109
|
-
- Install URL for the missing tool
|
|
110
|
-
- Fallback suggestion (use default engine)
|
|
111
|
-
- Link to documentation
|
|
112
|
-
|
|
113
|
-
### Error Handling
|
|
114
|
-
|
|
115
|
-
The module uses typed errors for consistent error handling:
|
|
116
|
-
|
|
117
|
-
| Error | When Thrown |
|
|
118
|
-
|-------|-------------|
|
|
119
|
-
| `InvalidEpubLibraryError` | Unknown engine name provided |
|
|
120
|
-
| `EpubGenerationError` | Generation fails (with tool/operation context) |
|
|
121
|
-
| `ToolNotFoundError` | Required binary not found in PATH |
|
|
122
|
-
|
|
123
|
-
### Test Strategy
|
|
124
|
-
|
|
125
|
-
| Component | Test Type | Coverage |
|
|
126
|
-
|-----------|-----------|----------|
|
|
127
|
-
| `commands/epub.js` | spec + integration | CLI interface, option handling |
|
|
128
|
-
| `lib/epub/index.js` | integration | Façade logic, path resolution, engine dispatch |
|
|
129
|
-
| `lib/epub/epub.js` | E2E | Happy path via full generation |
|
|
130
|
-
| `lib/epub/pandoc.js` | E2E | Happy path via full generation |
|
|
131
|
-
|
|
132
|
-
The engine implementations (`epub.js`, `pandoc.js`) are thin wrappers with limited logic, so E2E tests provide sufficient coverage. Error path tests would have lower ROI compared to the PDF module's `split.js`.
|
|
133
|
-
|
|
134
|
-
### Related Documentation
|
|
135
|
-
|
|
136
|
-
- [EPUB Command](../../commands/epub.js) - CLI command implementation
|
|
137
|
-
- [Reporter Pattern](../reporter/README.md) - Progress reporting ownership
|
|
138
|
-
- [Error Classes](../../errors/output/) - Typed error definitions
|
|
7
|
+
See the [`Epub.js` documentation](https://github.com/futurepress/epub.js).
|
package/src/lib/epub/epub.js
CHANGED
|
@@ -1,52 +1,27 @@
|
|
|
1
1
|
import { ManifestToEpub } from 'epubjs-cli'
|
|
2
2
|
import fs from 'fs-extra'
|
|
3
3
|
import { pathToFileURL } from 'node:url'
|
|
4
|
-
import { EpubGenerationError } from '#src/errors/index.js'
|
|
5
|
-
import createDebug from '#debug'
|
|
6
|
-
import ENGINES from './engines.js'
|
|
7
|
-
|
|
8
|
-
const debug = createDebug('lib:epub:epubjs')
|
|
9
|
-
|
|
10
|
-
/** Re-export engine metadata from central registry */
|
|
11
|
-
export const metadata = ENGINES.epubjs
|
|
12
4
|
|
|
13
5
|
/**
|
|
14
6
|
* A façade module for the EPUB.js library
|
|
15
7
|
* @see https://github.com/futurepress/epubjs-cli
|
|
16
|
-
*
|
|
17
|
-
* @param {string} input - Path to the input directory containing manifest.json
|
|
18
|
-
* @param {string} output - Path where the EPUB should be written
|
|
19
|
-
* @param {Object} [options={}] - Generation options
|
|
20
|
-
* @returns {Promise<void>}
|
|
21
8
|
*/
|
|
22
9
|
export default async (input, output, options = {}) => {
|
|
23
|
-
|
|
24
|
-
|
|
10
|
+
try {
|
|
11
|
+
console.info(`[CLI:lib/epub/epubjs] Generating ePub from ${input}`)
|
|
25
12
|
|
|
26
|
-
|
|
13
|
+
const url = pathToFileURL(`${input}/manifest.json`).toString()
|
|
27
14
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
epub = await new ManifestToEpub(url)
|
|
31
|
-
} catch (error) {
|
|
32
|
-
throw new EpubGenerationError('Epub.js', 'manifest loading', error.message)
|
|
33
|
-
}
|
|
15
|
+
const epub = await new ManifestToEpub(url)
|
|
16
|
+
.catch((error) => console.error(error))
|
|
34
17
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
file = await epub.save()
|
|
38
|
-
} catch (error) {
|
|
39
|
-
throw new EpubGenerationError('Epub.js', 'file generation', error.message)
|
|
40
|
-
}
|
|
18
|
+
const file = await epub.save()
|
|
19
|
+
.catch((error) => console.error(error))
|
|
41
20
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
try {
|
|
45
|
-
await fs.writeFile(output, file)
|
|
46
|
-
} catch (error) {
|
|
47
|
-
throw new EpubGenerationError('Epub.js', 'file write', error.message)
|
|
21
|
+
if (file && output) {
|
|
22
|
+
fs.writeFile(output, file, (error) => { if (error) throw error })
|
|
48
23
|
}
|
|
24
|
+
} catch (ERR_FILE_NOT_FOUND) {
|
|
25
|
+
console.error(`[CLI:lib/epub/epubjs] file not found ${input}`)
|
|
49
26
|
}
|
|
50
|
-
|
|
51
|
-
debug('complete')
|
|
52
27
|
}
|
package/src/lib/epub/index.js
CHANGED
|
@@ -1,130 +1,40 @@
|
|
|
1
1
|
import { dynamicImport } from '#helpers/os-utils.js'
|
|
2
|
-
import which from '#helpers/which.js'
|
|
3
2
|
import { fileURLToPath } from 'node:url'
|
|
4
3
|
import path from 'node:path'
|
|
5
|
-
import fs from 'fs-extra'
|
|
6
|
-
import paths from '#lib/project/index.js'
|
|
7
|
-
import reporter from '#lib/reporter/index.js'
|
|
8
|
-
import { InvalidEpubLibraryError } from '#src/errors/index.js'
|
|
9
|
-
import createDebug from '#debug'
|
|
10
|
-
import ENGINE_METADATA from './engines.js'
|
|
11
|
-
import { ENGINES } from './schema.js'
|
|
12
|
-
|
|
13
|
-
export { ENGINES }
|
|
14
4
|
|
|
15
5
|
const __filename = fileURLToPath(import.meta.url)
|
|
16
6
|
const __dirname = path.dirname(__filename)
|
|
17
7
|
|
|
18
|
-
const debug = createDebug('lib:epub')
|
|
19
|
-
|
|
20
8
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* @param {string} name - Library name to resolve
|
|
24
|
-
* @returns {Object} Resolved engine with absolute module path
|
|
25
|
-
* @throws {InvalidEpubLibraryError} When library name is not recognized
|
|
9
|
+
* A façade delegation module for EPUB libraries
|
|
26
10
|
*/
|
|
27
|
-
|
|
11
|
+
export default async (name = 'epubjs', options = {}) => {
|
|
12
|
+
const lib = { name, options, path }
|
|
13
|
+
|
|
28
14
|
const normalizedName = name.replace(/[-_.\s]/g, '').toLowerCase()
|
|
29
15
|
|
|
30
16
|
switch (normalizedName) {
|
|
31
|
-
case 'epubjs':
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
17
|
+
case 'epubjs': {
|
|
18
|
+
lib.name = 'Epub.js'
|
|
19
|
+
lib.options = {}
|
|
20
|
+
lib.path = path.join(__dirname, 'epub.js')
|
|
21
|
+
break
|
|
22
|
+
}
|
|
23
|
+
case 'pandoc': {
|
|
24
|
+
lib.name = 'Pandoc'
|
|
25
|
+
lib.options = {}
|
|
26
|
+
lib.path = path.join(__dirname, 'pandoc.js')
|
|
27
|
+
break
|
|
28
|
+
}
|
|
36
29
|
default:
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Check if the required binary for an engine is available
|
|
43
|
-
*
|
|
44
|
-
* @param {Object} engine - Engine definition from ENGINES
|
|
45
|
-
* @throws {ToolNotFoundError} When required binary is not in PATH
|
|
46
|
-
*/
|
|
47
|
-
function checkEngineAvailable(engine) {
|
|
48
|
-
if (!engine.requiresBinary) {
|
|
49
|
-
return // No binary required (e.g., epubjs uses Node.js)
|
|
30
|
+
console.error(`[CLI:lib/pdf] Unrecognized EPUB library '${name}'`)
|
|
31
|
+
return
|
|
50
32
|
}
|
|
51
33
|
|
|
52
|
-
const result = which(engine.requiresBinary, engine.toolInfo)
|
|
53
|
-
debug('found %s at %s', engine.requiresBinary, result)
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Construct the default output path for the EPUB
|
|
58
|
-
*/
|
|
59
|
-
function getOutputPath(projectRoot, libName) {
|
|
60
|
-
return path.join(projectRoot, `${libName}.epub`)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Resolve a custom output path, handling relative paths and ensuring .epub extension
|
|
65
|
-
*
|
|
66
|
-
* @param {string} customOutput - User-provided output path
|
|
67
|
-
* @param {string} projectRoot - Project root directory
|
|
68
|
-
* @returns {string} Resolved absolute path with .epub extension
|
|
69
|
-
*/
|
|
70
|
-
function resolveOutputPath(customOutput, projectRoot) {
|
|
71
|
-
// Resolve relative paths against project root
|
|
72
|
-
const resolved = path.isAbsolute(customOutput)
|
|
73
|
-
? customOutput
|
|
74
|
-
: path.join(projectRoot, customOutput)
|
|
75
|
-
|
|
76
|
-
// Ensure .epub extension
|
|
77
|
-
return resolved.endsWith('.epub') ? resolved : `${resolved}.epub`
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Generate an EPUB from the built publication
|
|
82
|
-
*
|
|
83
|
-
* @param {Object} options - Generation options
|
|
84
|
-
* @param {string} [options.lib='epubjs'] - EPUB library to use ('epubjs' or 'pandoc')
|
|
85
|
-
* @param {string} [options.output] - Custom output path (relative to project root or absolute)
|
|
86
|
-
* @param {boolean} [options.debug] - Enable debug output
|
|
87
|
-
* @returns {Promise<string>} Absolute path to the generated EPUB file
|
|
88
|
-
*/
|
|
89
|
-
export default async function generateEpub(options = {}) {
|
|
90
|
-
const libName = options.lib || 'epubjs'
|
|
91
|
-
const lib = resolveLibrary(libName)
|
|
92
|
-
|
|
93
|
-
debug('resolved library: %s → %s', libName, lib.name)
|
|
94
|
-
|
|
95
|
-
// Check engine availability BEFORE starting reporter (fail fast with clean error)
|
|
96
|
-
checkEngineAvailable(lib)
|
|
97
|
-
|
|
98
|
-
const projectRoot = paths.getProjectRoot()
|
|
99
|
-
const inputDir = path.join(projectRoot, paths.getEpubDir())
|
|
100
|
-
|
|
101
|
-
// Resolve output path from user option or default to {libName}.epub
|
|
102
|
-
const epubPath = options.output
|
|
103
|
-
? resolveOutputPath(options.output, projectRoot)
|
|
104
|
-
: getOutputPath(projectRoot, libName)
|
|
105
|
-
|
|
106
|
-
// Ensure parent directory exists (epub generators use fs.writeFile directly)
|
|
107
|
-
const epubDir = path.dirname(epubPath)
|
|
108
|
-
if (!fs.existsSync(epubDir)) {
|
|
109
|
-
fs.mkdirSync(epubDir, { recursive: true })
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
debug('input: %s', inputDir)
|
|
113
|
-
debug('output: %s', epubPath)
|
|
114
|
-
|
|
115
34
|
const { default: epubLib } = await dynamicImport(lib.path)
|
|
116
35
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
try {
|
|
122
|
-
await epubLib(inputDir, epubPath, options)
|
|
123
|
-
reporter.succeed(`EPUB saved to ${epubPath}`)
|
|
124
|
-
} catch (error) {
|
|
125
|
-
reporter.fail(`EPUB generation failed`)
|
|
126
|
-
throw error
|
|
36
|
+
return async (input, output) => {
|
|
37
|
+
console.info(`[CLI:lib/epub] generating EPUB using ${lib.name}`)
|
|
38
|
+
return await epubLib(input, output, lib.options)
|
|
127
39
|
}
|
|
128
|
-
|
|
129
|
-
return epubPath
|
|
130
40
|
}
|
package/src/lib/epub/pandoc.js
CHANGED
|
@@ -1,14 +1,8 @@
|
|
|
1
1
|
import { execa } from 'execa'
|
|
2
2
|
import fs from 'fs-extra'
|
|
3
3
|
import path from 'node:path'
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
-
import ENGINES from './engines.js'
|
|
7
|
-
|
|
8
|
-
const debug = createDebug('lib:epub:pandoc')
|
|
9
|
-
|
|
10
|
-
/** Re-export engine metadata from central registry */
|
|
11
|
-
export const metadata = ENGINES.pandoc
|
|
4
|
+
import paths, { projectRoot } from '#lib/11ty/paths.js'
|
|
5
|
+
import which from '#helpers/which.js'
|
|
12
6
|
|
|
13
7
|
/**
|
|
14
8
|
* Filter directory entries for XHTML files
|
|
@@ -25,18 +19,9 @@ const xhtmlFiles = (dirent) => {
|
|
|
25
19
|
/**
|
|
26
20
|
* A façade module for interacting with Pandoc CLI.
|
|
27
21
|
* @see https://pandoc.org/MANUAL.html#general-options
|
|
28
|
-
*
|
|
29
|
-
* Pandoc availability is checked by the parent façade (lib/epub/index.js)
|
|
30
|
-
* before this module is loaded, so we can assume pandoc is in PATH.
|
|
31
|
-
*
|
|
32
|
-
* @param {string} input - Path to the input directory containing XHTML files
|
|
33
|
-
* @param {string} output - Path where the EPUB should be written
|
|
34
|
-
* @param {Object} [options={}] - Generation options
|
|
35
|
-
* @returns {Promise<void>}
|
|
36
22
|
*/
|
|
37
23
|
export default async (input, output, options = {}) => {
|
|
38
|
-
|
|
39
|
-
debug('output: %s', output)
|
|
24
|
+
which('pandoc')
|
|
40
25
|
|
|
41
26
|
const inputs = fs.readdirSync(input)
|
|
42
27
|
.map((entry) => path.join(input, entry))
|
|
@@ -53,19 +38,5 @@ export default async (input, output, options = {}) => {
|
|
|
53
38
|
`--standalone`,
|
|
54
39
|
]
|
|
55
40
|
|
|
56
|
-
|
|
57
|
-
debug('inputs: %d XHTML files', inputs.length)
|
|
58
|
-
|
|
59
|
-
try {
|
|
60
|
-
const { stderr } = await execa('pandoc', [...cmdOptions, ...inputs])
|
|
61
|
-
// Pandoc may emit warnings to stderr even on success
|
|
62
|
-
if (stderr) {
|
|
63
|
-
debug('pandoc stderr: %s', stderr)
|
|
64
|
-
}
|
|
65
|
-
} catch (error) {
|
|
66
|
-
const details = error.stderr || error.message
|
|
67
|
-
throw new EpubGenerationError(`Pandoc EPUB generation failed: ${details}`)
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
debug('complete')
|
|
41
|
+
await execa('pandoc', [...cmdOptions, ...inputs])
|
|
71
42
|
}
|