@thegetty/quire-cli 1.0.0-rc.35 → 1.0.0-rc.36

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 (158) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/README.md +9 -0
  3. package/bin/cli.js +19 -1
  4. package/package.json +21 -8
  5. package/patches/README.md +19 -0
  6. package/patches/install-npm-version+1.0.9.patch +12119 -0
  7. package/schemas/objects.schema.json +12 -38
  8. package/schemas/publication.schema.json +0 -22
  9. package/schemas/references.schema.json +0 -1
  10. package/src/Command.js +26 -6
  11. package/src/Command.spec.js +99 -0
  12. package/src/commands/README.md +213 -122
  13. package/src/commands/build.js +46 -37
  14. package/src/commands/build.spec.js +113 -0
  15. package/src/commands/build.test.js +402 -0
  16. package/src/commands/clean.js +25 -19
  17. package/src/commands/clean.spec.js +108 -0
  18. package/src/commands/clean.test.js +260 -0
  19. package/src/commands/config.js +251 -0
  20. package/src/commands/config.spec.js +107 -0
  21. package/src/commands/config.test.js +715 -0
  22. package/src/commands/create.js +42 -14
  23. package/src/commands/create.spec.js +112 -0
  24. package/src/commands/create.test.js +415 -0
  25. package/src/commands/epub.js +59 -30
  26. package/src/commands/epub.spec.js +114 -0
  27. package/src/commands/epub.test.js +503 -0
  28. package/src/commands/index.js +9 -2
  29. package/src/commands/info.js +18 -24
  30. package/src/commands/info.spec.js +64 -0
  31. package/src/commands/info.test.js +415 -0
  32. package/src/commands/pdf.js +58 -84
  33. package/src/commands/pdf.spec.js +114 -0
  34. package/src/commands/pdf.test.js +464 -0
  35. package/src/commands/preview.js +26 -31
  36. package/src/commands/preview.spec.js +97 -0
  37. package/src/commands/preview.test.js +250 -0
  38. package/src/commands/use.js +56 -0
  39. package/src/commands/use.spec.js +61 -0
  40. package/src/commands/use.test.js +280 -0
  41. package/src/commands/validate.js +31 -19
  42. package/src/commands/validate.spec.js +82 -0
  43. package/src/commands/validate.test.js +234 -0
  44. package/src/commands/workflows.js +70 -0
  45. package/src/errors/build/build-failed-error.js +19 -0
  46. package/src/errors/build/config-field-missing-error.js +20 -0
  47. package/src/errors/build/config-file-not-found-error.js +20 -0
  48. package/src/errors/build/index.js +11 -0
  49. package/src/errors/index.js +48 -0
  50. package/src/errors/install/dependency-install-error.js +19 -0
  51. package/src/errors/install/directory-not-empty-error.js +25 -0
  52. package/src/errors/install/index.js +12 -0
  53. package/src/errors/install/invalid-path-error.js +31 -0
  54. package/src/errors/install/invalid-starter-error.js +27 -0
  55. package/src/errors/install/version-not-found-error.js +35 -0
  56. package/src/errors/output/epub-generation-error.js +19 -0
  57. package/src/errors/output/index.js +14 -0
  58. package/src/errors/output/invalid-epub-library-error.js +20 -0
  59. package/src/errors/output/invalid-pdf-library-error.js +20 -0
  60. package/src/errors/output/missing-build-output-error.js +21 -0
  61. package/src/errors/output/pdf-generation-error.js +24 -0
  62. package/src/errors/output/tool-not-found-error.js +37 -0
  63. package/src/errors/project/index.js +10 -0
  64. package/src/errors/project/not-in-project-error.js +20 -0
  65. package/src/errors/project/project-create-error.js +21 -0
  66. package/src/errors/quire-error.js +27 -0
  67. package/src/errors/validation/validation-error.js +20 -11
  68. package/src/helpers/clean.js +1 -1
  69. package/src/helpers/docs-url.js +32 -0
  70. package/src/helpers/test-cwd.js +5 -6
  71. package/src/helpers/test-cwd.test.js +192 -0
  72. package/src/helpers/which.js +10 -4
  73. package/src/lib/11ty/README.md +135 -19
  74. package/src/lib/11ty/api.js +176 -93
  75. package/src/lib/11ty/cli.js +77 -35
  76. package/src/lib/11ty/index.js +64 -5
  77. package/src/lib/11ty/index.test.js +655 -0
  78. package/src/lib/README.md +275 -0
  79. package/src/lib/commander/index.js +100 -0
  80. package/src/lib/commander/index.test.js +86 -0
  81. package/src/lib/commander/options.js +195 -0
  82. package/src/lib/commander/options.test.js +109 -0
  83. package/src/lib/conf/README.md +84 -73
  84. package/src/lib/conf/config.js +5 -3
  85. package/src/lib/conf/config.test.js +281 -0
  86. package/src/lib/conf/defaults.js +44 -0
  87. package/src/lib/conf/format.js +60 -0
  88. package/src/lib/conf/format.test.js +106 -0
  89. package/src/lib/conf/helpers.js +91 -0
  90. package/src/lib/conf/helpers.test.js +136 -0
  91. package/src/lib/conf/index.js +22 -0
  92. package/src/lib/conf/schema.js +53 -8
  93. package/src/lib/epub/README.md +133 -2
  94. package/src/lib/epub/engines.js +46 -0
  95. package/src/lib/epub/epub.js +36 -11
  96. package/src/lib/epub/index.js +111 -21
  97. package/src/lib/epub/index.test.js +518 -0
  98. package/src/lib/epub/pandoc.js +33 -4
  99. package/src/lib/epub/pandoc.test.js +122 -0
  100. package/src/lib/epub/schema.js +21 -0
  101. package/src/lib/error/README.md +170 -0
  102. package/src/lib/error/handler.js +107 -0
  103. package/src/lib/git/README.md +151 -2
  104. package/src/lib/git/index.js +217 -13
  105. package/src/lib/git/index.spec.js +80 -0
  106. package/src/lib/git/index.test.js +453 -0
  107. package/src/lib/installer/index.js +309 -0
  108. package/src/lib/installer/index.spec.js +83 -0
  109. package/src/lib/installer/index.test.js +545 -0
  110. package/src/lib/logger/README.md +424 -0
  111. package/src/lib/logger/debug.js +90 -0
  112. package/src/lib/logger/debug.spec.js +130 -0
  113. package/src/lib/logger/index.js +228 -0
  114. package/src/lib/logger/index.spec.js +131 -0
  115. package/src/lib/logger/index.test.js +477 -0
  116. package/src/lib/npm/README.md +127 -0
  117. package/src/lib/npm/index.js +198 -0
  118. package/src/lib/npm/index.spec.js +60 -0
  119. package/src/lib/npm/index.test.js +355 -0
  120. package/src/lib/pdf/README.md +131 -0
  121. package/src/lib/pdf/engines.js +46 -0
  122. package/src/lib/pdf/index.js +124 -21
  123. package/src/lib/pdf/index.test.js +708 -0
  124. package/src/lib/pdf/paged.js +100 -52
  125. package/src/lib/pdf/paged.test.js +366 -0
  126. package/src/lib/pdf/prince.js +115 -37
  127. package/src/lib/pdf/prince.test.js +202 -0
  128. package/src/lib/pdf/schema.js +21 -0
  129. package/src/lib/pdf/split.js +61 -33
  130. package/src/lib/pdf/split.test.js +445 -0
  131. package/src/lib/process/manager.js +110 -0
  132. package/src/lib/process/manager.test.js +55 -0
  133. package/src/lib/project/build.js +143 -0
  134. package/src/lib/project/build.test.js +253 -0
  135. package/src/lib/project/config.js +48 -0
  136. package/src/lib/project/config.test.js +134 -0
  137. package/src/{helpers/is-quire.js → lib/project/detect.js} +5 -3
  138. package/src/lib/project/detect.test.js +157 -0
  139. package/src/lib/project/index.js +40 -0
  140. package/src/lib/project/paths.js +224 -0
  141. package/src/lib/project/version.js +110 -0
  142. package/src/lib/project/version.test.js +350 -0
  143. package/src/lib/reporter/README.md +211 -2
  144. package/src/lib/reporter/index.js +512 -0
  145. package/src/lib/reporter/index.test.js +593 -0
  146. package/src/main.js +134 -47
  147. package/src/main.spec.js +61 -0
  148. package/src/main.test.js +347 -0
  149. package/src/validators/utils.js +2 -1
  150. package/src/commands/conf.js +0 -43
  151. package/src/commands/version.js +0 -43
  152. package/src/lib/11ty/paths.js +0 -103
  153. package/src/lib/i18n/README.md +0 -3
  154. package/src/lib/i18n/config.js +0 -53
  155. package/src/lib/i18n/index.js +0 -43
  156. package/src/lib/i18n/localeService.js +0 -58
  157. package/src/lib/quire/README.md +0 -19
  158. package/src/lib/quire/index.js +0 -350
@@ -1,350 +0,0 @@
1
- import { IS_WINDOWS } from '#helpers/os-utils.js'
2
- import { chdir, cwd } from 'node:process'
3
- import { execa, execaCommand } from 'execa'
4
- import { fileURLToPath } from 'node:url'
5
- import { isEmpty } from '#helpers/is-empty.js'
6
- import config from '#lib/conf/config.js'
7
- import fetch from 'node-fetch'
8
- import fs from 'fs-extra'
9
- import git from '#lib/git/index.js'
10
- import packageConfig from '#src/packageConfig.js'
11
- import path from 'node:path'
12
- import semver from 'semver'
13
-
14
- const __filename = fileURLToPath(import.meta.url)
15
- const __dirname = path.dirname(__filename)
16
-
17
- // Version install path is relative to process working directory
18
- const INSTALL_PATH = path.join('src', 'lib', 'quire', 'versions')
19
- const PACKAGE_NAME = '@thegetty/quire-11ty'
20
-
21
- const QUIRE_VERSION = config.get('quireVersion')
22
- const VERSION_FILE = config.get('versionFile')
23
-
24
- /**
25
- * Return an absolute path to an installed quire-11ty version
26
- *
27
- * @return {String} path to installed quire-11ty version
28
- */
29
- function getPath(version=QUIRE_VERSION) {
30
- const absolutePath = path.relative('/', path.join(INSTALL_PATH, version))
31
- if (!fs.existsSync(absolutePath)) {
32
- console.error(`[CLI:quire] quire-11ty@${version} is not installed`)
33
- return null
34
- }
35
- console.debug(`[CLI:quire] %s`, absolutePath)
36
- return absolutePath
37
- }
38
-
39
- /**
40
- * Read the required quire-11ty version for the quire version file
41
- *
42
- * @param {String} projectPath Absolute system path to the project root
43
- *
44
- * @return {String} version Quire-11ty semantic version
45
- */
46
- function getVersion(projectPath) {
47
- projectPath = projectPath || path.resolve(cwd())
48
- const version = fs.readFileSync(path.join(projectPath, VERSION_FILE), { encoding:'utf8' })
49
- const projectName = path.basename(projectPath)
50
- console.debug(`${projectName} set to use quire-11ty@${version}`)
51
- return version
52
- }
53
-
54
- /**
55
- * Read required quire-11ty and starter versions from starter peerDependencies
56
- *
57
- * @param {String} projectPath Absolute system path to the project root
58
- *
59
- * @return {Object}
60
- * @property {String} quire11tyVersion Latest compatible Quire-11ty semantic version
61
- * @property {String} starterVersion Starter project version defined in the starter package.json
62
- */
63
- async function getVersionsFromStarter(projectPath) {
64
- const projectPackageConfig = fs.readFileSync(path.join(projectPath, 'package.json'), { encoding:'utf8' })
65
- const { peerDependencies, version: starterVersion } = JSON.parse(projectPackageConfig)
66
- const quire11tyVersion = peerDependencies[PACKAGE_NAME]
67
- return { quire11tyVersion, starterVersion }
68
- }
69
-
70
- /**
71
- * Clone or copy a Quire starter project
72
- *
73
- * @param {String} starter A repository URL or an absolute path to local starter
74
- * @TODO resolve both absolute and relative paths to local starter repositories
75
- * @param {String} projectPath Absolute system path to the project root
76
- *
77
- * @return {String} quireVersion A string indicating the current version
78
- * of quire being used with a new project
79
- */
80
- async function initStarter (starter, projectPath, options) {
81
- projectPath = projectPath || cwd()
82
-
83
- // ensure that the target path exists
84
- fs.ensureDirSync(projectPath)
85
-
86
- // if the target directory exists it must be empty
87
- if (!isEmpty(projectPath)) {
88
- const location = projectPath === '.' ? 'the current directory' : projectPath
89
- console.error(`[CLI] cannot create a starter project in ${location} because it is not empty`)
90
- // @TODO cleanup directories from failed new command
91
- return
92
- }
93
-
94
- console.debug('[CLI:quire] init-starter',
95
- `\n project: ${path.join(__dirname, projectPath)}`,
96
- `\n starter: ${starter}`
97
- )
98
-
99
- /**
100
- * Clone starter project repository
101
- * @todo pipe `git clone` status to stdout for better UX
102
- */
103
- await git
104
- .cwd(projectPath)
105
- .clone(starter, '.')
106
- .catch((error) => console.error('[CLI:error] ', error))
107
-
108
- /**
109
- * Determine the quire-11ty version to use in the new project,
110
- * from the quireVersion option or as required by the starter project.
111
- *
112
- * Uses 'latest' to get the latest semantic version compatible with version ranges
113
- */
114
- const { quire11tyVersion, starterVersion } = await getVersionsFromStarter(projectPath)
115
- const quireVersion = await latest(options.quireVersion || quire11tyVersion)
116
- setVersion(projectPath, quireVersion)
117
-
118
- /**
119
- * Write quire-11ty, quire-cli, starter versions to the version file
120
- */
121
- const versionInfo = {
122
- cli: packageConfig.version,
123
- starter: `${starter}@${starterVersion}`,
124
- }
125
- fs.writeFileSync(path.join(projectPath, VERSION_FILE), JSON.stringify(versionInfo))
126
-
127
- // Re-initialize project directory as a new git repository
128
- await fs.remove(path.join(projectPath, '.git'))
129
-
130
- /**
131
- * Remove the starter repository package config file
132
- * and create a new package config for the project
133
- * (this is necessary for Eleventy to resolve project paths)
134
- * @todo allow interactive init using a custom questionnaire
135
- * @see https://docs.npmjs.com/creating-a-package-json-file#customizing-the-packagejson-questionnaire
136
- */
137
- await fs.remove(path.join(projectPath, 'package.json'))
138
- await execaCommand('npm init --yes', { cwd: projectPath })
139
-
140
- /**
141
- * Create an initial commit of files in new repository
142
- * @todo use a localized string for the commit message
143
- */
144
- const projectFiles = fs.readdirSync(projectPath)
145
- await git.init().add(projectFiles).commit('Initial Commit')
146
- return quireVersion
147
- }
148
-
149
- /**
150
- * Install `quire-11ty` directly into a quire project
151
- *
152
- * @TODO refactor this to use the install method with pre and post-install hooks
153
- * or steps to prepare the working directory and cleanup on error and completion
154
- *
155
- * @param {String} projectPath Absolute system path to the project root
156
- * @param {Object} options options passed from `quire new` command
157
- * @return {Promise}
158
- */
159
- async function installInProject(projectPath, quireVersion, options = {}) {
160
- const { quirePath } = options
161
- const quire11tyPackage = `${PACKAGE_NAME}@${quireVersion}`
162
-
163
- console.debug(`[CLI:quire] installing ${quire11tyPackage} into ${projectPath}`)
164
-
165
- /**
166
- * Delete the starter project package configuration so that it can be replaced
167
- * with the `@thegetty/quire-11ty` configuration
168
- * @TODO If a user runs quire eject at a later date we may want to merge their
169
- * package.json with the `quire-11ty` dev dependencies, scripts, etc
170
- */
171
- await git
172
- .cwd(projectPath)
173
- .rm(['package.json'])
174
- .catch((error) => console.error('[CLI:error] ', error))
175
-
176
- const temp11tyDirectory = '.temp'
177
- const tempDir = path.join(projectPath,temp11tyDirectory)
178
- fs.mkdirSync(tempDir)
179
-
180
- // Copy if passed a path and it exists, otherwise attempt to download the tarball for this pathspec
181
- if (fs.existsSync(quirePath)) {
182
- fs.copySync(quirePath, tempDir)
183
- } else {
184
- await execaCommand(`npm pack ${ options.debug ? '--debug' : '--quiet' } ${quire11tyPackage}`)
185
-
186
- // Extract only the package dir from the tar bar and strip it from the extracted path
187
- await execaCommand(`tar -xzf thegetty-quire-11ty-${quireVersion}.tgz -C ${tempDir} --strip-components=1 package/`)
188
- }
189
-
190
- // Copy `.temp` to projectPath
191
- fs.copySync(tempDir, projectPath)
192
-
193
- console.debug('[CLI:quire] installing dev dependencies into quire project')
194
- /**
195
- * Manually install necessary dev dependencies to run 11ty;
196
- * these must be `devDependencies` so that they are not bundled into
197
- * the final `_site` package when running `quire build`
198
- */
199
- await execaCommand('npm cache clean --force', { cwd: projectPath })
200
- try {
201
- await execaCommand('npm install --save-dev', { cwd: projectPath })
202
- } catch(error) {
203
- console.warn(`[CLI:error]`, error)
204
- fs.removeSync(projectPath)
205
- return
206
- }
207
-
208
- const eleventyFilesToCommit = fs
209
- .readdirSync(tempDir)
210
- .filter((filePath) => filePath !== 'node_modules')
211
-
212
- eleventyFilesToCommit.push('package-lock.json')
213
-
214
- /**
215
- * Create an additional commit of new `@thegetty/quire-11ty` files in repository
216
- * @todo use a localized string for the commit message
217
- */
218
- await git.add(eleventyFilesToCommit).commit('Adds `@thegetty/quire-11ty` files')
219
-
220
- // remove temporary 11ty install directory
221
- fs.removeSync(path.join(projectPath, temp11tyDirectory))
222
- }
223
-
224
- /**
225
- * Retrieve latest published version of the `quire-11ty` package
226
- * or the latest compatible version with the provided semantic version string
227
- *
228
- * @param {String} version A semantic version string, i.e `^1.0.0-pre-release.0`
229
- *
230
- * @return {String} `quire-11ty@latest` semantic version string
231
- */
232
- async function latest(version) {
233
- let quireVersion;
234
- if (!version || version === 'latest') {
235
- const { stdout } =
236
- await execa('npm', ['view', PACKAGE_NAME, 'version'])
237
- quireVersion = stdout
238
- } else {
239
- const response = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}`)
240
- const json = await response.json()
241
- const versions = Object.keys(json.versions)
242
- quireVersion = semver.maxSatisfying(versions, version)
243
- }
244
- if (!quireVersion) {
245
- throw new Error(`[CLI:quire] Sorry, we couldn't find a version of quire-11ty compatible with the version "${version}". You can set the quire-11ty version in the starter project's package.json or specify a version when running \`quire new\` with the \`--quire-version\` flag. You can run \`npm view @thegetty/quire-11ty versions\` to view all versions.`)
246
- }
247
- return quireVersion
248
- }
249
-
250
- /**
251
- * List installed versions of the `quire-11ty` package
252
- */
253
- function list() {
254
- return fs.readdirSync(INSTALL_PATH)
255
- }
256
-
257
- /**
258
- * Removes the installed version of `quire-11ty`
259
- *
260
- * @param {String} `quire-11ty` semantic version
261
- * @return {Promise}
262
- */
263
- async function remove(version) {
264
- if (!version) {
265
- console.error('No version specified.')
266
- }
267
- const dir = `${INSTALL_PATH}/${version}`
268
- fs.rmdir(dir, { recursive: true }, (error) => {
269
- if (error) {
270
- throw error
271
- }
272
- console.info(`deleted ${dir}`)
273
- })
274
- symlinkLatest()
275
- }
276
-
277
- /**
278
- * Sets the quire-11ty version for a project
279
- *
280
- * @param {String} version a version identifier or distribution tag
281
- */
282
- function setVersion(projectPath, version) {
283
- const projectName = path.basename(projectPath)
284
- console.info(`${projectName} set to use quire-11ty@${version}`)
285
- }
286
-
287
- /**
288
- * Update symbolic link to the latest _installed_ version of `quire-11ty`
289
- *
290
- * @todo why does this not work using `fs-extra` `createSymlinkSync()`
291
- */
292
- function symlinkLatest() {
293
- const latestInstalledVersion = fs
294
- .readdirSync(path.join(__dirname, 'versions'))
295
- .filter((dirent) => semver.valid(semver.coerce(dirent)))
296
- .sort(semver.rcompare)[0]
297
- const target = path.join(__dirname, 'versions', latestInstalledVersion)
298
- const source = path.join(__dirname, 'versions', 'latest')
299
- const type = IS_WINDOWS ? 'junction' : 'dir'
300
-
301
- console.debug('[CLI:quire] symlinking latest installed version')
302
-
303
- try {
304
- return fs.symlinkSync(target, source, type)
305
- } catch (error) {
306
- switch (error.code) {
307
- case 'EEXIST':
308
- case 'EISDIR':
309
- // if the target file already exists proceed...
310
- break
311
- case 'ENOENT':
312
- try {
313
- fs.mkdirSync(path.dirname(source))
314
- } catch (mkdirError) {
315
- mkdirError.message = `Error trying to symlink ${target} to ${source}`
316
- throw mkdirError
317
- }
318
- // do we need to symlink in this case?
319
- // return fs.symlinkSync(target, source, type)
320
- break
321
- default:
322
- console.error('[CLI:quire] unable to symlink latest installed version')
323
- throw error
324
- }
325
- }
326
-
327
- fs.unlinkSync(source)
328
- return fs.symlinkSync(target, source, type)
329
- }
330
-
331
- /**
332
- * Get an array of published `quire-11ty` package versions
333
- *
334
- * @return {Array<String>} published versions
335
- */
336
- async function versions() {
337
- return await execa('npm', ['show', PACKAGE_NAME, 'versions'])
338
- }
339
-
340
- export const quire = {
341
- getPath,
342
- getVersion,
343
- initStarter,
344
- installInProject,
345
- latest,
346
- list,
347
- remove,
348
- setVersion,
349
- versions,
350
- }