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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (243) hide show
  1. package/CHANGELOG.md +0 -36
  2. package/README.md +0 -9
  3. package/bin/cli.js +1 -46
  4. package/package.json +9 -25
  5. package/src/Command.js +6 -26
  6. package/src/commands/README.md +122 -213
  7. package/src/commands/build.js +37 -45
  8. package/src/commands/clean.js +19 -33
  9. package/src/commands/conf.js +43 -0
  10. package/src/commands/create.js +14 -42
  11. package/src/commands/epub.js +31 -67
  12. package/src/commands/index.js +2 -9
  13. package/src/commands/info.js +86 -88
  14. package/src/commands/pdf.js +82 -63
  15. package/src/commands/preview.js +31 -32
  16. package/src/commands/validate.js +20 -64
  17. package/src/commands/version.js +43 -0
  18. package/src/errors/validation/validation-error.js +11 -20
  19. package/src/helpers/clean.js +1 -1
  20. package/src/helpers/is-quire.js +31 -0
  21. package/src/helpers/test-cwd.js +6 -5
  22. package/src/helpers/which.js +4 -10
  23. package/src/lib/11ty/README.md +19 -135
  24. package/src/lib/11ty/api.js +93 -235
  25. package/src/lib/11ty/cli.js +37 -112
  26. package/src/lib/11ty/index.js +5 -64
  27. package/src/lib/11ty/paths.js +103 -0
  28. package/src/lib/README.md +0 -330
  29. package/src/lib/conf/README.md +69 -86
  30. package/src/lib/conf/config.js +3 -5
  31. package/src/lib/conf/defaults.js +0 -65
  32. package/src/lib/conf/schema.js +9 -103
  33. package/src/lib/epub/README.md +2 -133
  34. package/src/lib/epub/epub.js +11 -36
  35. package/src/lib/epub/index.js +21 -111
  36. package/src/lib/epub/pandoc.js +4 -33
  37. package/src/lib/git/README.md +2 -151
  38. package/src/lib/git/index.js +13 -217
  39. package/src/lib/i18n/README.md +3 -0
  40. package/src/lib/i18n/config.js +53 -0
  41. package/src/lib/i18n/index.js +43 -0
  42. package/src/lib/i18n/localeService.js +58 -0
  43. package/src/lib/pdf/README.md +0 -131
  44. package/src/lib/pdf/index.js +21 -124
  45. package/src/lib/pdf/paged.js +52 -100
  46. package/src/lib/pdf/prince.js +37 -115
  47. package/src/lib/pdf/split.js +33 -61
  48. package/src/lib/quire/README.md +19 -0
  49. package/src/lib/quire/index.js +353 -0
  50. package/src/lib/reporter/README.md +2 -211
  51. package/src/lib/reporter/index.js +0 -607
  52. package/src/main.js +48 -221
  53. package/src/packageConfig.js +0 -17
  54. package/src/validators/utils.js +1 -2
  55. package/schemas/config.schema.json +0 -194
  56. package/schemas/figures.schema.json +0 -56
  57. package/schemas/layout.schema.json +0 -5
  58. package/schemas/objects.schema.json +0 -62
  59. package/schemas/publication.schema.json +0 -140
  60. package/schemas/references.schema.json +0 -29
  61. package/src/Command.spec.js +0 -99
  62. package/src/commands/build.spec.js +0 -113
  63. package/src/commands/build.test.js +0 -397
  64. package/src/commands/clean.spec.js +0 -118
  65. package/src/commands/clean.test.js +0 -382
  66. package/src/commands/config.js +0 -238
  67. package/src/commands/config.spec.js +0 -107
  68. package/src/commands/config.test.js +0 -845
  69. package/src/commands/create.spec.js +0 -112
  70. package/src/commands/create.test.js +0 -415
  71. package/src/commands/doctor.js +0 -251
  72. package/src/commands/doctor.spec.js +0 -115
  73. package/src/commands/doctor.test.js +0 -1409
  74. package/src/commands/epub.spec.js +0 -114
  75. package/src/commands/epub.test.js +0 -503
  76. package/src/commands/help.js +0 -60
  77. package/src/commands/help.test.js +0 -132
  78. package/src/commands/info.spec.js +0 -72
  79. package/src/commands/info.test.js +0 -512
  80. package/src/commands/pdf.spec.js +0 -114
  81. package/src/commands/pdf.test.js +0 -464
  82. package/src/commands/preview.spec.js +0 -97
  83. package/src/commands/preview.test.js +0 -250
  84. package/src/commands/use.js +0 -56
  85. package/src/commands/use.spec.js +0 -61
  86. package/src/commands/use.test.js +0 -280
  87. package/src/commands/validate.spec.js +0 -90
  88. package/src/commands/validate.test.js +0 -378
  89. package/src/commands/workflows.js +0 -70
  90. package/src/errors/build/build-failed-error.js +0 -19
  91. package/src/errors/build/config-field-missing-error.js +0 -20
  92. package/src/errors/build/config-file-not-found-error.js +0 -20
  93. package/src/errors/build/index.js +0 -11
  94. package/src/errors/help/help-topic-not-found-error.js +0 -30
  95. package/src/errors/help/index.js +0 -8
  96. package/src/errors/index.js +0 -58
  97. package/src/errors/input/index.js +0 -8
  98. package/src/errors/input/invalid-input-error.js +0 -21
  99. package/src/errors/install/dependency-install-error.js +0 -19
  100. package/src/errors/install/directory-not-empty-error.js +0 -25
  101. package/src/errors/install/index.js +0 -12
  102. package/src/errors/install/invalid-path-error.js +0 -31
  103. package/src/errors/install/invalid-starter-error.js +0 -27
  104. package/src/errors/install/version-not-found-error.js +0 -35
  105. package/src/errors/output/epub-generation-error.js +0 -19
  106. package/src/errors/output/index.js +0 -14
  107. package/src/errors/output/invalid-epub-library-error.js +0 -20
  108. package/src/errors/output/invalid-pdf-library-error.js +0 -20
  109. package/src/errors/output/missing-build-output-error.js +0 -21
  110. package/src/errors/output/pdf-generation-error.js +0 -24
  111. package/src/errors/output/tool-not-found-error.js +0 -37
  112. package/src/errors/project/index.js +0 -10
  113. package/src/errors/project/not-in-project-error.js +0 -20
  114. package/src/errors/project/project-create-error.js +0 -21
  115. package/src/errors/quire-error.js +0 -27
  116. package/src/errors/validation/index.js +0 -3
  117. package/src/errors/validation/unknown-config-key-error.js +0 -27
  118. package/src/errors/validation/unknown-config-operation-error.js +0 -24
  119. package/src/helpers/docs-url.js +0 -32
  120. package/src/helpers/pager.js +0 -59
  121. package/src/helpers/pager.test.js +0 -85
  122. package/src/helpers/suggest-similar.js +0 -124
  123. package/src/helpers/suggest-similar.test.js +0 -108
  124. package/src/helpers/test-cwd.test.js +0 -192
  125. package/src/lib/11ty/index.test.js +0 -655
  126. package/src/lib/commander/index.js +0 -103
  127. package/src/lib/commander/index.test.js +0 -86
  128. package/src/lib/commander/options.js +0 -237
  129. package/src/lib/commander/options.test.js +0 -205
  130. package/src/lib/conf/build-status.js +0 -103
  131. package/src/lib/conf/build-status.test.js +0 -247
  132. package/src/lib/conf/config.test.js +0 -281
  133. package/src/lib/conf/format.js +0 -60
  134. package/src/lib/conf/format.test.js +0 -106
  135. package/src/lib/conf/helpers.js +0 -91
  136. package/src/lib/conf/helpers.test.js +0 -136
  137. package/src/lib/conf/index.js +0 -22
  138. package/src/lib/constants.js +0 -28
  139. package/src/lib/doctor/README.md +0 -667
  140. package/src/lib/doctor/checks/environment/cli-version.js +0 -62
  141. package/src/lib/doctor/checks/environment/cli-version.test.js +0 -132
  142. package/src/lib/doctor/checks/environment/git-available.js +0 -77
  143. package/src/lib/doctor/checks/environment/git-available.test.js +0 -52
  144. package/src/lib/doctor/checks/environment/index.js +0 -13
  145. package/src/lib/doctor/checks/environment/node-version.js +0 -66
  146. package/src/lib/doctor/checks/environment/node-version.test.js +0 -17
  147. package/src/lib/doctor/checks/environment/npm-available.js +0 -66
  148. package/src/lib/doctor/checks/environment/npm-available.test.js +0 -52
  149. package/src/lib/doctor/checks/environment/os-info.js +0 -48
  150. package/src/lib/doctor/checks/environment/os-info.test.js +0 -81
  151. package/src/lib/doctor/checks/environment/runtime-info.js +0 -51
  152. package/src/lib/doctor/checks/environment/runtime-info.test.js +0 -132
  153. package/src/lib/doctor/checks/outputs/epub-output.js +0 -119
  154. package/src/lib/doctor/checks/outputs/epub-output.test.js +0 -277
  155. package/src/lib/doctor/checks/outputs/index.js +0 -10
  156. package/src/lib/doctor/checks/outputs/pdf-output.js +0 -144
  157. package/src/lib/doctor/checks/outputs/pdf-output.test.js +0 -377
  158. package/src/lib/doctor/checks/outputs/stale-build.js +0 -122
  159. package/src/lib/doctor/checks/outputs/stale-build.test.js +0 -282
  160. package/src/lib/doctor/checks/project/data-files.js +0 -56
  161. package/src/lib/doctor/checks/project/data-files.test.js +0 -125
  162. package/src/lib/doctor/checks/project/dependencies.js +0 -53
  163. package/src/lib/doctor/checks/project/dependencies.test.js +0 -71
  164. package/src/lib/doctor/checks/project/index.js +0 -11
  165. package/src/lib/doctor/checks/project/quire-11ty.js +0 -98
  166. package/src/lib/doctor/checks/project/quire-11ty.test.js +0 -170
  167. package/src/lib/doctor/checks/project/quire-project.js +0 -38
  168. package/src/lib/doctor/checks/project/quire-project.test.js +0 -47
  169. package/src/lib/doctor/checks/tools/index.js +0 -10
  170. package/src/lib/doctor/checks/tools/pandoc-available.js +0 -82
  171. package/src/lib/doctor/checks/tools/pandoc-available.test.js +0 -73
  172. package/src/lib/doctor/checks/tools/prince-available.js +0 -81
  173. package/src/lib/doctor/checks/tools/prince-available.test.js +0 -73
  174. package/src/lib/doctor/constants.js +0 -39
  175. package/src/lib/doctor/formatDuration.js +0 -108
  176. package/src/lib/doctor/formatDuration.test.js +0 -76
  177. package/src/lib/doctor/formatters/human.js +0 -257
  178. package/src/lib/doctor/formatters/human.test.js +0 -463
  179. package/src/lib/doctor/formatters/index.js +0 -8
  180. package/src/lib/doctor/formatters/json.js +0 -78
  181. package/src/lib/doctor/formatters/json.test.js +0 -174
  182. package/src/lib/doctor/formatters/shared.js +0 -129
  183. package/src/lib/doctor/formatters/shared.test.js +0 -194
  184. package/src/lib/doctor/index.js +0 -271
  185. package/src/lib/doctor/index.test.js +0 -797
  186. package/src/lib/epub/engines.js +0 -46
  187. package/src/lib/epub/index.test.js +0 -518
  188. package/src/lib/epub/pandoc.test.js +0 -122
  189. package/src/lib/epub/schema.js +0 -21
  190. package/src/lib/error/README.md +0 -170
  191. package/src/lib/error/handler.js +0 -107
  192. package/src/lib/git/index.spec.js +0 -80
  193. package/src/lib/git/index.test.js +0 -453
  194. package/src/lib/help/frontmatter.js +0 -77
  195. package/src/lib/help/frontmatter.test.js +0 -139
  196. package/src/lib/help/index.js +0 -146
  197. package/src/lib/help/index.test.js +0 -188
  198. package/src/lib/help/topics/configuration.md +0 -77
  199. package/src/lib/help/topics/debugging.md +0 -69
  200. package/src/lib/help/topics/epub.md +0 -74
  201. package/src/lib/help/topics/pdf.md +0 -74
  202. package/src/lib/help/topics/publishing.md +0 -80
  203. package/src/lib/help/topics/workflows.md +0 -50
  204. package/src/lib/installer/index.js +0 -309
  205. package/src/lib/installer/index.spec.js +0 -83
  206. package/src/lib/installer/index.test.js +0 -545
  207. package/src/lib/logger/README.md +0 -424
  208. package/src/lib/logger/debug.js +0 -132
  209. package/src/lib/logger/debug.spec.js +0 -130
  210. package/src/lib/logger/debug.test.js +0 -128
  211. package/src/lib/logger/index.js +0 -228
  212. package/src/lib/logger/index.spec.js +0 -131
  213. package/src/lib/logger/index.test.js +0 -578
  214. package/src/lib/npm/README.md +0 -127
  215. package/src/lib/npm/index.js +0 -198
  216. package/src/lib/npm/index.spec.js +0 -60
  217. package/src/lib/npm/index.test.js +0 -355
  218. package/src/lib/pdf/engines.js +0 -46
  219. package/src/lib/pdf/index.test.js +0 -708
  220. package/src/lib/pdf/paged.test.js +0 -366
  221. package/src/lib/pdf/prince.test.js +0 -202
  222. package/src/lib/pdf/schema.js +0 -21
  223. package/src/lib/pdf/split.test.js +0 -445
  224. package/src/lib/platform.js +0 -95
  225. package/src/lib/process/manager.js +0 -110
  226. package/src/lib/process/manager.test.js +0 -55
  227. package/src/lib/project/build.js +0 -162
  228. package/src/lib/project/build.test.js +0 -275
  229. package/src/lib/project/config.js +0 -48
  230. package/src/lib/project/config.test.js +0 -134
  231. package/src/lib/project/detect.js +0 -47
  232. package/src/lib/project/detect.test.js +0 -157
  233. package/src/lib/project/index.js +0 -56
  234. package/src/lib/project/output-paths.js +0 -87
  235. package/src/lib/project/output-paths.test.js +0 -66
  236. package/src/lib/project/paths.js +0 -272
  237. package/src/lib/project/version.js +0 -110
  238. package/src/lib/project/version.test.js +0 -350
  239. package/src/lib/reporter/index.test.js +0 -862
  240. package/src/main.spec.js +0 -61
  241. package/src/main.test.js +0 -347
  242. package/src/validators/validate-data-files.js +0 -154
  243. package/src/validators/validate-data-files.test.js +0 -217
@@ -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
  }
@@ -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 here are overwritten by values in defaults.js
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
- description: 'Filename used to identify Quire projects'
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
  }
@@ -1,138 +1,7 @@
1
1
  ## CLI lib/EPUB Module
2
2
 
3
- This module provides an abstraction for EPUB e-book generation across Epub.js and Pandoc. The exported function accepts a `lib` option and dynamically loads the corresponding engine façade.
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
- Wraps the [`epubjs-cli`](https://github.com/futurepress/epubjs-cli) package for EPUB generation.
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).
@@ -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
- debug('input: %s', input)
24
- debug('output: %s', output)
10
+ try {
11
+ console.info(`[CLI:lib/epub/epubjs] Generating ePub from ${input}`)
25
12
 
26
- const url = pathToFileURL(`${input}/manifest.json`).toString()
13
+ const url = pathToFileURL(`${input}/manifest.json`).toString()
27
14
 
28
- let epub
29
- try {
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
- let file
36
- try {
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
- if (file && output) {
43
- debug('writing EPUB to %s', output)
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
  }
@@ -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
- * Resolve the EPUB library implementation
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
- function resolveLibrary(name) {
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
- case 'epub':
33
- return { ...ENGINE_METADATA.epubjs, path: path.join(__dirname, ENGINE_METADATA.epubjs.module) }
34
- case 'pandoc':
35
- return { ...ENGINE_METADATA.pandoc, path: path.join(__dirname, ENGINE_METADATA.pandoc.module) }
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
- throw new InvalidEpubLibraryError(name)
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
- reporter.start(`Generating EPUB using ${lib.name}...`, { showElapsed: true })
118
- reporter.detail(`Input: ${inputDir}`)
119
- reporter.detail(`Output: ${epubPath}`)
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
  }
@@ -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 { EpubGenerationError } from '#src/errors/index.js'
5
- import createDebug from '#debug'
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
- debug('input: %s', input)
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
- debug('cmd options: %O', cmdOptions)
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
  }