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

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