@thegetty/quire-cli 1.0.0-rc.45 → 1.0.0-rc.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +0 -36
- package/README.md +0 -9
- package/bin/cli.js +1 -46
- package/package.json +10 -27
- package/src/Command.js +6 -26
- package/src/commands/README.md +122 -213
- package/src/commands/build.js +37 -45
- package/src/commands/clean.js +19 -33
- package/src/commands/conf.js +43 -0
- package/src/commands/create.js +14 -42
- package/src/commands/epub.js +31 -67
- package/src/commands/index.js +2 -9
- package/src/commands/info.js +86 -88
- package/src/commands/pdf.js +82 -63
- package/src/commands/preview.js +31 -32
- package/src/commands/validate.js +20 -64
- package/src/commands/version.js +43 -0
- package/src/errors/validation/validation-error.js +11 -20
- package/src/helpers/clean.js +1 -1
- package/src/helpers/is-quire.js +31 -0
- package/src/helpers/test-cwd.js +6 -5
- package/src/helpers/which.js +4 -10
- package/src/lib/11ty/README.md +19 -135
- package/src/lib/11ty/api.js +93 -235
- package/src/lib/11ty/cli.js +37 -112
- package/src/lib/11ty/index.js +5 -64
- package/src/lib/11ty/paths.js +103 -0
- package/src/lib/README.md +0 -330
- package/src/lib/conf/README.md +69 -86
- package/src/lib/conf/config.js +3 -5
- package/src/lib/conf/defaults.js +0 -65
- package/src/lib/conf/schema.js +9 -103
- package/src/lib/epub/README.md +2 -133
- package/src/lib/epub/epub.js +11 -36
- package/src/lib/epub/index.js +21 -111
- package/src/lib/epub/pandoc.js +4 -33
- package/src/lib/git/README.md +2 -151
- package/src/lib/git/index.js +13 -217
- package/src/lib/i18n/README.md +3 -0
- package/src/lib/i18n/config.js +53 -0
- package/src/lib/i18n/index.js +43 -0
- package/src/lib/i18n/localeService.js +58 -0
- package/src/lib/pdf/README.md +0 -131
- package/src/lib/pdf/index.js +21 -124
- package/src/lib/pdf/paged.js +52 -100
- package/src/lib/pdf/prince.js +37 -115
- package/src/lib/pdf/split.js +33 -61
- package/src/lib/quire/README.md +19 -0
- package/src/lib/quire/index.js +353 -0
- package/src/lib/reporter/README.md +2 -211
- package/src/lib/reporter/index.js +0 -607
- package/src/main.js +48 -221
- package/src/packageConfig.js +0 -17
- package/src/validators/utils.js +1 -2
- package/man/quire.1 +0 -341
- package/man/quire.1.md +0 -232
- package/schemas/config.schema.json +0 -194
- package/schemas/figures.schema.json +0 -56
- package/schemas/layout.schema.json +0 -5
- package/schemas/objects.schema.json +0 -62
- package/schemas/publication.schema.json +0 -140
- package/schemas/references.schema.json +0 -29
- package/src/Command.spec.js +0 -99
- package/src/commands/build.spec.js +0 -113
- package/src/commands/build.test.js +0 -397
- package/src/commands/clean.spec.js +0 -118
- package/src/commands/clean.test.js +0 -382
- package/src/commands/config.js +0 -238
- package/src/commands/config.spec.js +0 -107
- package/src/commands/config.test.js +0 -845
- package/src/commands/create.spec.js +0 -112
- package/src/commands/create.test.js +0 -415
- package/src/commands/doctor.js +0 -251
- package/src/commands/doctor.spec.js +0 -115
- package/src/commands/doctor.test.js +0 -1409
- package/src/commands/epub.spec.js +0 -114
- package/src/commands/epub.test.js +0 -503
- package/src/commands/help.js +0 -60
- package/src/commands/help.test.js +0 -132
- package/src/commands/info.spec.js +0 -72
- package/src/commands/info.test.js +0 -512
- package/src/commands/pdf.spec.js +0 -114
- package/src/commands/pdf.test.js +0 -464
- package/src/commands/preview.spec.js +0 -97
- package/src/commands/preview.test.js +0 -250
- package/src/commands/use.js +0 -56
- package/src/commands/use.spec.js +0 -61
- package/src/commands/use.test.js +0 -280
- package/src/commands/validate.spec.js +0 -90
- package/src/commands/validate.test.js +0 -378
- package/src/commands/workflows.js +0 -70
- package/src/errors/build/build-failed-error.js +0 -19
- package/src/errors/build/config-field-missing-error.js +0 -20
- package/src/errors/build/config-file-not-found-error.js +0 -20
- package/src/errors/build/index.js +0 -11
- package/src/errors/help/help-topic-not-found-error.js +0 -30
- package/src/errors/help/index.js +0 -8
- package/src/errors/index.js +0 -58
- package/src/errors/input/index.js +0 -8
- package/src/errors/input/invalid-input-error.js +0 -21
- package/src/errors/install/dependency-install-error.js +0 -19
- package/src/errors/install/directory-not-empty-error.js +0 -25
- package/src/errors/install/index.js +0 -12
- package/src/errors/install/invalid-path-error.js +0 -31
- package/src/errors/install/invalid-starter-error.js +0 -27
- package/src/errors/install/version-not-found-error.js +0 -35
- package/src/errors/output/epub-generation-error.js +0 -19
- package/src/errors/output/index.js +0 -14
- package/src/errors/output/invalid-epub-library-error.js +0 -20
- package/src/errors/output/invalid-pdf-library-error.js +0 -20
- package/src/errors/output/missing-build-output-error.js +0 -21
- package/src/errors/output/pdf-generation-error.js +0 -24
- package/src/errors/output/tool-not-found-error.js +0 -37
- package/src/errors/project/index.js +0 -10
- package/src/errors/project/not-in-project-error.js +0 -20
- package/src/errors/project/project-create-error.js +0 -21
- package/src/errors/quire-error.js +0 -27
- package/src/errors/validation/index.js +0 -3
- package/src/errors/validation/unknown-config-key-error.js +0 -27
- package/src/errors/validation/unknown-config-operation-error.js +0 -24
- package/src/helpers/docs-url.js +0 -32
- package/src/helpers/pager.js +0 -59
- package/src/helpers/pager.test.js +0 -85
- package/src/helpers/suggest-similar.js +0 -124
- package/src/helpers/suggest-similar.test.js +0 -108
- package/src/helpers/test-cwd.test.js +0 -192
- package/src/lib/11ty/index.test.js +0 -655
- package/src/lib/commander/index.js +0 -103
- package/src/lib/commander/index.test.js +0 -86
- package/src/lib/commander/options.js +0 -237
- package/src/lib/commander/options.test.js +0 -205
- package/src/lib/conf/build-status.js +0 -103
- package/src/lib/conf/build-status.test.js +0 -247
- package/src/lib/conf/config.test.js +0 -281
- package/src/lib/conf/format.js +0 -60
- package/src/lib/conf/format.test.js +0 -106
- package/src/lib/conf/helpers.js +0 -91
- package/src/lib/conf/helpers.test.js +0 -136
- package/src/lib/conf/index.js +0 -22
- package/src/lib/constants.js +0 -28
- package/src/lib/doctor/README.md +0 -667
- package/src/lib/doctor/checks/environment/cli-version.js +0 -62
- package/src/lib/doctor/checks/environment/cli-version.test.js +0 -132
- package/src/lib/doctor/checks/environment/git-available.js +0 -77
- package/src/lib/doctor/checks/environment/git-available.test.js +0 -52
- package/src/lib/doctor/checks/environment/index.js +0 -13
- package/src/lib/doctor/checks/environment/node-version.js +0 -66
- package/src/lib/doctor/checks/environment/node-version.test.js +0 -17
- package/src/lib/doctor/checks/environment/npm-available.js +0 -66
- package/src/lib/doctor/checks/environment/npm-available.test.js +0 -52
- package/src/lib/doctor/checks/environment/os-info.js +0 -48
- package/src/lib/doctor/checks/environment/os-info.test.js +0 -81
- package/src/lib/doctor/checks/environment/runtime-info.js +0 -51
- package/src/lib/doctor/checks/environment/runtime-info.test.js +0 -132
- package/src/lib/doctor/checks/outputs/epub-output.js +0 -119
- package/src/lib/doctor/checks/outputs/epub-output.test.js +0 -277
- package/src/lib/doctor/checks/outputs/index.js +0 -10
- package/src/lib/doctor/checks/outputs/pdf-output.js +0 -144
- package/src/lib/doctor/checks/outputs/pdf-output.test.js +0 -377
- package/src/lib/doctor/checks/outputs/stale-build.js +0 -122
- package/src/lib/doctor/checks/outputs/stale-build.test.js +0 -282
- package/src/lib/doctor/checks/project/data-files.js +0 -56
- package/src/lib/doctor/checks/project/data-files.test.js +0 -125
- package/src/lib/doctor/checks/project/dependencies.js +0 -53
- package/src/lib/doctor/checks/project/dependencies.test.js +0 -71
- package/src/lib/doctor/checks/project/index.js +0 -11
- package/src/lib/doctor/checks/project/quire-11ty.js +0 -98
- package/src/lib/doctor/checks/project/quire-11ty.test.js +0 -170
- package/src/lib/doctor/checks/project/quire-project.js +0 -38
- package/src/lib/doctor/checks/project/quire-project.test.js +0 -47
- package/src/lib/doctor/checks/tools/index.js +0 -10
- package/src/lib/doctor/checks/tools/pandoc-available.js +0 -82
- package/src/lib/doctor/checks/tools/pandoc-available.test.js +0 -73
- package/src/lib/doctor/checks/tools/prince-available.js +0 -81
- package/src/lib/doctor/checks/tools/prince-available.test.js +0 -73
- package/src/lib/doctor/constants.js +0 -39
- package/src/lib/doctor/formatDuration.js +0 -108
- package/src/lib/doctor/formatDuration.test.js +0 -76
- package/src/lib/doctor/formatters/human.js +0 -257
- package/src/lib/doctor/formatters/human.test.js +0 -463
- package/src/lib/doctor/formatters/index.js +0 -8
- package/src/lib/doctor/formatters/json.js +0 -78
- package/src/lib/doctor/formatters/json.test.js +0 -174
- package/src/lib/doctor/formatters/shared.js +0 -129
- package/src/lib/doctor/formatters/shared.test.js +0 -194
- package/src/lib/doctor/index.js +0 -271
- package/src/lib/doctor/index.test.js +0 -797
- package/src/lib/epub/engines.js +0 -46
- package/src/lib/epub/index.test.js +0 -518
- package/src/lib/epub/pandoc.test.js +0 -122
- package/src/lib/epub/schema.js +0 -21
- package/src/lib/error/README.md +0 -170
- package/src/lib/error/handler.js +0 -107
- package/src/lib/git/index.spec.js +0 -80
- package/src/lib/git/index.test.js +0 -453
- package/src/lib/help/frontmatter.js +0 -77
- package/src/lib/help/frontmatter.test.js +0 -139
- package/src/lib/help/index.js +0 -146
- package/src/lib/help/index.test.js +0 -188
- package/src/lib/help/topics/configuration.md +0 -77
- package/src/lib/help/topics/debugging.md +0 -69
- package/src/lib/help/topics/epub.md +0 -74
- package/src/lib/help/topics/pdf.md +0 -74
- package/src/lib/help/topics/publishing.md +0 -80
- package/src/lib/help/topics/workflows.md +0 -50
- package/src/lib/installer/index.js +0 -309
- package/src/lib/installer/index.spec.js +0 -83
- package/src/lib/installer/index.test.js +0 -545
- package/src/lib/logger/README.md +0 -424
- package/src/lib/logger/debug.js +0 -132
- package/src/lib/logger/debug.spec.js +0 -130
- package/src/lib/logger/debug.test.js +0 -128
- package/src/lib/logger/index.js +0 -228
- package/src/lib/logger/index.spec.js +0 -131
- package/src/lib/logger/index.test.js +0 -578
- package/src/lib/npm/README.md +0 -127
- package/src/lib/npm/index.js +0 -198
- package/src/lib/npm/index.spec.js +0 -60
- package/src/lib/npm/index.test.js +0 -355
- package/src/lib/pdf/engines.js +0 -46
- package/src/lib/pdf/index.test.js +0 -708
- package/src/lib/pdf/paged.test.js +0 -366
- package/src/lib/pdf/prince.test.js +0 -202
- package/src/lib/pdf/schema.js +0 -21
- package/src/lib/pdf/split.test.js +0 -445
- package/src/lib/platform.js +0 -95
- package/src/lib/process/manager.js +0 -110
- package/src/lib/process/manager.test.js +0 -55
- package/src/lib/project/build.js +0 -162
- package/src/lib/project/build.test.js +0 -275
- package/src/lib/project/config.js +0 -48
- package/src/lib/project/config.test.js +0 -134
- package/src/lib/project/detect.js +0 -47
- package/src/lib/project/detect.test.js +0 -157
- package/src/lib/project/index.js +0 -56
- package/src/lib/project/output-paths.js +0 -87
- package/src/lib/project/output-paths.test.js +0 -66
- package/src/lib/project/paths.js +0 -272
- package/src/lib/project/version.js +0 -110
- package/src/lib/project/version.test.js +0 -350
- package/src/lib/reporter/index.test.js +0 -862
- package/src/main.spec.js +0 -61
- package/src/main.test.js +0 -347
- package/src/validators/validate-data-files.js +0 -154
- package/src/validators/validate-data-files.test.js +0 -217
package/src/lib/npm/index.js
DELETED
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* NPM façade class providing abstracted npm operations
|
|
3
|
-
*
|
|
4
|
-
* Provides a consistent interface for npm commands with unified
|
|
5
|
-
* logging, error handling, and testability. Follows the singleton
|
|
6
|
-
* pattern like lib/logger.js for easy mocking in tests.
|
|
7
|
-
*
|
|
8
|
-
* @example in production code
|
|
9
|
-
* import npm from '#lib/npm/index.js'
|
|
10
|
-
* await npm.install(projectPath, { saveDev: true })
|
|
11
|
-
*
|
|
12
|
-
* @example in test code
|
|
13
|
-
* const mockNpm = {
|
|
14
|
-
* install: sandbox.stub().resolves(),
|
|
15
|
-
* version: sandbox.stub().resolves('10.2.4')
|
|
16
|
-
* }
|
|
17
|
-
* const MyCommand = await esmock('./mycommand.js', {
|
|
18
|
-
* '#lib/npm/index.js': { default: mockNpm }
|
|
19
|
-
* })
|
|
20
|
-
*
|
|
21
|
-
* @see https://docs.npmjs.com/cli/ - npm CLI documentation
|
|
22
|
-
* @module npm
|
|
23
|
-
*/
|
|
24
|
-
import { execa } from 'execa'
|
|
25
|
-
import fetch from 'node-fetch'
|
|
26
|
-
import semver from 'semver'
|
|
27
|
-
import which from '#helpers/which.js'
|
|
28
|
-
import createDebug from '#debug'
|
|
29
|
-
|
|
30
|
-
const debug = createDebug('lib:npm')
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* NPM façade class
|
|
34
|
-
*/
|
|
35
|
-
class Npm {
|
|
36
|
-
/**
|
|
37
|
-
* Clean npm cache
|
|
38
|
-
* @see https://docs.npmjs.com/cli/commands/npm-cache
|
|
39
|
-
* @param {string} [cwd] - Working directory (optional)
|
|
40
|
-
* @returns {Promise<void>}
|
|
41
|
-
*/
|
|
42
|
-
async cacheClean(cwd) {
|
|
43
|
-
debug('cleaning npm cache')
|
|
44
|
-
const options = cwd ? { cwd } : {}
|
|
45
|
-
const { stderr } = await execa('npm', ['cache', 'clean', '--force'], options)
|
|
46
|
-
if (stderr) {
|
|
47
|
-
debug('npm cache clean stderr: %s', stderr)
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Fetch package metadata directly from npm registry
|
|
53
|
-
* @see https://github.com/npm/registry/blob/main/docs/REGISTRY-API.md
|
|
54
|
-
* @param {string} packageName - Package name
|
|
55
|
-
* @returns {Promise<Object>} Package metadata from registry
|
|
56
|
-
*/
|
|
57
|
-
async fetchFromRegistry(packageName) {
|
|
58
|
-
debug('fetching registry metadata for %s', packageName)
|
|
59
|
-
const response = await fetch(`https://registry.npmjs.org/${packageName}`)
|
|
60
|
-
if (!response.ok) {
|
|
61
|
-
throw new Error(
|
|
62
|
-
`Failed to fetch package metadata for ${packageName}: ${response.statusText}`
|
|
63
|
-
)
|
|
64
|
-
}
|
|
65
|
-
return await response.json()
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Get latest version compatible with a semver range
|
|
70
|
-
* @see https://docs.npmjs.com/about-semantic-versioning
|
|
71
|
-
* @see https://github.com/npm/node-semver#ranges
|
|
72
|
-
* @param {string} packageName - Package name
|
|
73
|
-
* @param {string} range - Semver range (e.g., "^1.0.0")
|
|
74
|
-
* @returns {Promise<string|null>} Latest compatible version or null if none found
|
|
75
|
-
*/
|
|
76
|
-
async getCompatibleVersion(packageName, range) {
|
|
77
|
-
debug('finding version of %s compatible with %s', packageName, range)
|
|
78
|
-
const metadata = await this.fetchFromRegistry(packageName)
|
|
79
|
-
const versions = Object.keys(metadata.versions)
|
|
80
|
-
return semver.maxSatisfying(versions, range)
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Initialize a new package.json
|
|
85
|
-
* @see https://docs.npmjs.com/cli/commands/npm-init
|
|
86
|
-
* @param {string} cwd - Working directory
|
|
87
|
-
* @param {Object} options - Configuration options
|
|
88
|
-
* @param {boolean} [options.yes=true] - Auto-accept defaults
|
|
89
|
-
* @returns {Promise<void>}
|
|
90
|
-
*/
|
|
91
|
-
async init(cwd, options = {}) {
|
|
92
|
-
const { yes = true } = options
|
|
93
|
-
const args = ['init']
|
|
94
|
-
if (yes) args.push('--yes')
|
|
95
|
-
|
|
96
|
-
debug('initializing package.json in %s', cwd)
|
|
97
|
-
const { stderr } = await execa('npm', args, { cwd })
|
|
98
|
-
if (stderr) {
|
|
99
|
-
debug('npm init stderr: %s', stderr)
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Install dependencies
|
|
105
|
-
* @see https://docs.npmjs.com/cli/commands/npm-install
|
|
106
|
-
* @param {string} cwd - Working directory
|
|
107
|
-
* @param {Object} options - Configuration options
|
|
108
|
-
* @param {boolean} [options.saveDev=false] - Install as devDependencies
|
|
109
|
-
* @param {boolean} [options.preferOffline=false] - Prefer cached packages
|
|
110
|
-
* @returns {Promise<void>}
|
|
111
|
-
*/
|
|
112
|
-
async install(cwd, options = {}) {
|
|
113
|
-
const { preferOffline = false, saveDev = false } = options
|
|
114
|
-
const args = ['install']
|
|
115
|
-
if (preferOffline) args.push('--prefer-offline')
|
|
116
|
-
if (saveDev) args.push('--save-dev')
|
|
117
|
-
|
|
118
|
-
debug('installing dependencies in %s', cwd)
|
|
119
|
-
const { stderr } = await execa('npm', args, { cwd })
|
|
120
|
-
if (stderr) {
|
|
121
|
-
debug('npm install stderr: %s', stderr)
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Check if npm is available in PATH
|
|
127
|
-
* @returns {boolean} True if npm is available
|
|
128
|
-
*/
|
|
129
|
-
isAvailable() {
|
|
130
|
-
return !!which('npm')
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Create a tarball (.tgz file) of the npm package
|
|
135
|
-
* @see https://docs.npmjs.com/cli/commands/npm-pack
|
|
136
|
-
* @param {string} packageSpec - Package name with version (e.g., "@thegetty/quire-11ty@1.0.0")
|
|
137
|
-
* @param {string} destination - Destination directory for the tarball
|
|
138
|
-
* @param {Object} options - Configuration options
|
|
139
|
-
* @param {boolean} [options.quiet=true] - Suppress output
|
|
140
|
-
* @param {boolean} [options.debug=false] - Enable debug output
|
|
141
|
-
* @returns {Promise<void>}
|
|
142
|
-
*/
|
|
143
|
-
async pack(packageSpec, destination, options = {}) {
|
|
144
|
-
const { debug: debugMode = false, quiet = true } = options
|
|
145
|
-
const args = ['pack']
|
|
146
|
-
if (debugMode) {
|
|
147
|
-
args.push('--debug')
|
|
148
|
-
} else if (quiet) {
|
|
149
|
-
args.push('--quiet')
|
|
150
|
-
}
|
|
151
|
-
args.push('--pack-destination', destination, packageSpec)
|
|
152
|
-
|
|
153
|
-
debug('packing %s to %s', packageSpec, destination)
|
|
154
|
-
const { stderr } = await execa('npm', args)
|
|
155
|
-
if (stderr) {
|
|
156
|
-
debug('npm pack stderr: %s', stderr)
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Show package info (similar to view)
|
|
162
|
-
* @see https://docs.npmjs.com/cli/commands/npm-view
|
|
163
|
-
* @param {string} packageName - Package name
|
|
164
|
-
* @param {string} [field='versions'] - Field to retrieve
|
|
165
|
-
* @returns {Promise<string>} The requested field value
|
|
166
|
-
*/
|
|
167
|
-
async show(packageName, field = 'versions') {
|
|
168
|
-
debug('showing %s for %s', field, packageName)
|
|
169
|
-
const result = await execa('npm', ['show', packageName, field])
|
|
170
|
-
return result
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Get npm version
|
|
175
|
-
* @see https://docs.npmjs.com/cli/commands/npm-version
|
|
176
|
-
* @returns {Promise<string>} npm version string
|
|
177
|
-
*/
|
|
178
|
-
async version() {
|
|
179
|
-
const { stdout } = await execa('npm', ['--version'])
|
|
180
|
-
return stdout
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* View package info from registry
|
|
185
|
-
* @see https://docs.npmjs.com/cli/commands/npm-view
|
|
186
|
-
* @param {string} packageName - Package name
|
|
187
|
-
* @param {string} [field='version'] - Field to retrieve
|
|
188
|
-
* @returns {Promise<string>} The requested field value
|
|
189
|
-
*/
|
|
190
|
-
async view(packageName, field = 'version') {
|
|
191
|
-
debug('viewing %s for %s', field, packageName)
|
|
192
|
-
const { stdout } = await execa('npm', ['view', packageName, field])
|
|
193
|
-
return stdout
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
// Export singleton instance
|
|
198
|
-
export default new Npm()
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import test from 'ava'
|
|
2
|
-
import npm from './index.js'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* NPM Façade Unit Tests
|
|
6
|
-
*
|
|
7
|
-
* Tests the npm façade module interface and API contract.
|
|
8
|
-
* These tests verify the module exports and method signatures
|
|
9
|
-
* without actually executing npm commands.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
test('npm façade exports a singleton object', (t) => {
|
|
13
|
-
t.truthy(npm, 'npm should be exported')
|
|
14
|
-
t.is(typeof npm, 'object', 'npm should be an object')
|
|
15
|
-
})
|
|
16
|
-
|
|
17
|
-
test('npm façade has isAvailable method', (t) => {
|
|
18
|
-
t.is(typeof npm.isAvailable, 'function', 'isAvailable should be a function')
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
test('npm façade has version method', (t) => {
|
|
22
|
-
t.is(typeof npm.version, 'function', 'version should be a function')
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
test('npm façade has init method', (t) => {
|
|
26
|
-
t.is(typeof npm.init, 'function', 'init should be a function')
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
test('npm façade has install method', (t) => {
|
|
30
|
-
t.is(typeof npm.install, 'function', 'install should be a function')
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
test('npm façade has pack method', (t) => {
|
|
34
|
-
t.is(typeof npm.pack, 'function', 'pack should be a function')
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
test('npm façade has cacheClean method', (t) => {
|
|
38
|
-
t.is(typeof npm.cacheClean, 'function', 'cacheClean should be a function')
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
test('npm façade has view method', (t) => {
|
|
42
|
-
t.is(typeof npm.view, 'function', 'view should be a function')
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
test('npm façade has show method', (t) => {
|
|
46
|
-
t.is(typeof npm.show, 'function', 'show should be a function')
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
test('npm façade has fetchFromRegistry method', (t) => {
|
|
50
|
-
t.is(typeof npm.fetchFromRegistry, 'function', 'fetchFromRegistry should be a function')
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
test('npm façade has getCompatibleVersion method', (t) => {
|
|
54
|
-
t.is(typeof npm.getCompatibleVersion, 'function', 'getCompatibleVersion should be a function')
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
test('isAvailable returns a boolean', (t) => {
|
|
58
|
-
const result = npm.isAvailable()
|
|
59
|
-
t.is(typeof result, 'boolean', 'isAvailable should return a boolean')
|
|
60
|
-
})
|
|
@@ -1,355 +0,0 @@
|
|
|
1
|
-
import esmock from 'esmock'
|
|
2
|
-
import sinon from 'sinon'
|
|
3
|
-
import test from 'ava'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* NPM Façade Integration Tests
|
|
7
|
-
*
|
|
8
|
-
* Tests the npm façade module behavior with mocked dependencies.
|
|
9
|
-
* Uses esmock to replace execa and node-fetch calls.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
test.beforeEach((t) => {
|
|
13
|
-
t.context.sandbox = sinon.createSandbox()
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
test.afterEach.always((t) => {
|
|
17
|
-
t.context.sandbox.restore()
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
test('version() calls npm --version and returns stdout', async (t) => {
|
|
21
|
-
const { sandbox } = t.context
|
|
22
|
-
|
|
23
|
-
const mockExeca = sandbox.stub().resolves({ stdout: '10.2.4' })
|
|
24
|
-
const mockWhich = sandbox.stub().returns('/usr/bin/npm')
|
|
25
|
-
|
|
26
|
-
const npm = await esmock('./index.js', {
|
|
27
|
-
execa: { execa: mockExeca },
|
|
28
|
-
'#helpers/which.js': { default: mockWhich }
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
const result = await npm.version()
|
|
32
|
-
|
|
33
|
-
t.is(result, '10.2.4')
|
|
34
|
-
t.true(mockExeca.calledOnce)
|
|
35
|
-
t.true(mockExeca.calledWith('npm', ['--version']))
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
test('init() calls npm init with --yes flag by default', async (t) => {
|
|
39
|
-
const { sandbox } = t.context
|
|
40
|
-
|
|
41
|
-
const mockExeca = sandbox.stub().resolves({})
|
|
42
|
-
const mockWhich = sandbox.stub().returns('/usr/bin/npm')
|
|
43
|
-
|
|
44
|
-
const npm = await esmock('./index.js', {
|
|
45
|
-
execa: { execa: mockExeca },
|
|
46
|
-
'#helpers/which.js': { default: mockWhich }
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
await npm.init('/path/to/project')
|
|
50
|
-
|
|
51
|
-
t.true(mockExeca.calledOnce)
|
|
52
|
-
t.true(mockExeca.calledWith('npm', ['init', '--yes'], { cwd: '/path/to/project' }))
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
test('init() omits --yes flag when yes option is false', async (t) => {
|
|
56
|
-
const { sandbox } = t.context
|
|
57
|
-
|
|
58
|
-
const mockExeca = sandbox.stub().resolves({})
|
|
59
|
-
const mockWhich = sandbox.stub().returns('/usr/bin/npm')
|
|
60
|
-
|
|
61
|
-
const npm = await esmock('./index.js', {
|
|
62
|
-
execa: { execa: mockExeca },
|
|
63
|
-
'#helpers/which.js': { default: mockWhich }
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
await npm.init('/path/to/project', { yes: false })
|
|
67
|
-
|
|
68
|
-
t.true(mockExeca.calledWith('npm', ['init'], { cwd: '/path/to/project' }))
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
test('install() calls npm install with correct flags', async (t) => {
|
|
72
|
-
const { sandbox } = t.context
|
|
73
|
-
|
|
74
|
-
const mockExeca = sandbox.stub().resolves({})
|
|
75
|
-
const mockWhich = sandbox.stub().returns('/usr/bin/npm')
|
|
76
|
-
|
|
77
|
-
const npm = await esmock('./index.js', {
|
|
78
|
-
execa: { execa: mockExeca },
|
|
79
|
-
'#helpers/which.js': { default: mockWhich }
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
await npm.install('/path/to/project', { saveDev: true, preferOffline: true })
|
|
83
|
-
|
|
84
|
-
t.true(mockExeca.calledOnce)
|
|
85
|
-
t.true(mockExeca.calledWith('npm', ['install', '--prefer-offline', '--save-dev'], { cwd: '/path/to/project' }))
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
test('install() calls npm install without flags when no options provided', async (t) => {
|
|
89
|
-
const { sandbox } = t.context
|
|
90
|
-
|
|
91
|
-
const mockExeca = sandbox.stub().resolves({})
|
|
92
|
-
const mockWhich = sandbox.stub().returns('/usr/bin/npm')
|
|
93
|
-
|
|
94
|
-
const npm = await esmock('./index.js', {
|
|
95
|
-
execa: { execa: mockExeca },
|
|
96
|
-
'#helpers/which.js': { default: mockWhich }
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
await npm.install('/path/to/project')
|
|
100
|
-
|
|
101
|
-
t.true(mockExeca.calledWith('npm', ['install'], { cwd: '/path/to/project' }))
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
test('pack() calls npm pack with package spec and destination', async (t) => {
|
|
105
|
-
const { sandbox } = t.context
|
|
106
|
-
|
|
107
|
-
const mockExeca = sandbox.stub().resolves({})
|
|
108
|
-
const mockWhich = sandbox.stub().returns('/usr/bin/npm')
|
|
109
|
-
|
|
110
|
-
const npm = await esmock('./index.js', {
|
|
111
|
-
execa: { execa: mockExeca },
|
|
112
|
-
'#helpers/which.js': { default: mockWhich }
|
|
113
|
-
})
|
|
114
|
-
|
|
115
|
-
await npm.pack('@thegetty/quire-11ty@1.0.0', '/tmp/dest', { quiet: true })
|
|
116
|
-
|
|
117
|
-
t.true(mockExeca.calledOnce)
|
|
118
|
-
t.true(mockExeca.calledWith('npm', ['pack', '--quiet', '--pack-destination', '/tmp/dest', '@thegetty/quire-11ty@1.0.0']))
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
test('pack() uses --debug flag when debug option is true', async (t) => {
|
|
122
|
-
const { sandbox } = t.context
|
|
123
|
-
|
|
124
|
-
const mockExeca = sandbox.stub().resolves({})
|
|
125
|
-
const mockWhich = sandbox.stub().returns('/usr/bin/npm')
|
|
126
|
-
|
|
127
|
-
const npm = await esmock('./index.js', {
|
|
128
|
-
execa: { execa: mockExeca },
|
|
129
|
-
'#helpers/which.js': { default: mockWhich }
|
|
130
|
-
})
|
|
131
|
-
|
|
132
|
-
await npm.pack('@thegetty/quire-11ty@1.0.0', '/tmp/dest', { debug: true, quiet: false })
|
|
133
|
-
|
|
134
|
-
t.true(mockExeca.calledWith('npm', ['pack', '--debug', '--pack-destination', '/tmp/dest', '@thegetty/quire-11ty@1.0.0']))
|
|
135
|
-
})
|
|
136
|
-
|
|
137
|
-
test('cacheClean() calls npm cache clean --force', async (t) => {
|
|
138
|
-
const { sandbox } = t.context
|
|
139
|
-
|
|
140
|
-
const mockExeca = sandbox.stub().resolves({})
|
|
141
|
-
const mockWhich = sandbox.stub().returns('/usr/bin/npm')
|
|
142
|
-
|
|
143
|
-
const npm = await esmock('./index.js', {
|
|
144
|
-
execa: { execa: mockExeca },
|
|
145
|
-
'#helpers/which.js': { default: mockWhich }
|
|
146
|
-
})
|
|
147
|
-
|
|
148
|
-
await npm.cacheClean('/path/to/project')
|
|
149
|
-
|
|
150
|
-
t.true(mockExeca.calledOnce)
|
|
151
|
-
t.true(mockExeca.calledWith('npm', ['cache', 'clean', '--force'], { cwd: '/path/to/project' }))
|
|
152
|
-
})
|
|
153
|
-
|
|
154
|
-
test('view() calls npm view with package name and field', async (t) => {
|
|
155
|
-
const { sandbox } = t.context
|
|
156
|
-
|
|
157
|
-
const mockExeca = sandbox.stub().resolves({ stdout: '1.0.0' })
|
|
158
|
-
const mockWhich = sandbox.stub().returns('/usr/bin/npm')
|
|
159
|
-
|
|
160
|
-
const npm = await esmock('./index.js', {
|
|
161
|
-
execa: { execa: mockExeca },
|
|
162
|
-
'#helpers/which.js': { default: mockWhich }
|
|
163
|
-
})
|
|
164
|
-
|
|
165
|
-
const result = await npm.view('@thegetty/quire-11ty', 'version')
|
|
166
|
-
|
|
167
|
-
t.is(result, '1.0.0')
|
|
168
|
-
t.true(mockExeca.calledWith('npm', ['view', '@thegetty/quire-11ty', 'version']))
|
|
169
|
-
})
|
|
170
|
-
|
|
171
|
-
test('show() calls npm show with package name and field', async (t) => {
|
|
172
|
-
const { sandbox } = t.context
|
|
173
|
-
|
|
174
|
-
const mockExeca = sandbox.stub().resolves({ stdout: "['1.0.0', '1.0.1']" })
|
|
175
|
-
const mockWhich = sandbox.stub().returns('/usr/bin/npm')
|
|
176
|
-
|
|
177
|
-
const npm = await esmock('./index.js', {
|
|
178
|
-
execa: { execa: mockExeca },
|
|
179
|
-
'#helpers/which.js': { default: mockWhich }
|
|
180
|
-
})
|
|
181
|
-
|
|
182
|
-
await npm.show('@thegetty/quire-11ty', 'versions')
|
|
183
|
-
|
|
184
|
-
t.true(mockExeca.calledWith('npm', ['show', '@thegetty/quire-11ty', 'versions']))
|
|
185
|
-
})
|
|
186
|
-
|
|
187
|
-
test('fetchFromRegistry() fetches package metadata from npm registry', async (t) => {
|
|
188
|
-
const { sandbox } = t.context
|
|
189
|
-
|
|
190
|
-
const mockResponse = {
|
|
191
|
-
ok: true,
|
|
192
|
-
json: sandbox.stub().resolves({
|
|
193
|
-
name: '@thegetty/quire-11ty',
|
|
194
|
-
versions: { '1.0.0': {}, '1.0.1': {} }
|
|
195
|
-
})
|
|
196
|
-
}
|
|
197
|
-
const mockFetch = sandbox.stub().resolves(mockResponse)
|
|
198
|
-
const mockWhich = sandbox.stub().returns('/usr/bin/npm')
|
|
199
|
-
|
|
200
|
-
const npm = await esmock('./index.js', {
|
|
201
|
-
'node-fetch': { default: mockFetch },
|
|
202
|
-
execa: { execa: sandbox.stub() },
|
|
203
|
-
'#helpers/which.js': { default: mockWhich }
|
|
204
|
-
})
|
|
205
|
-
|
|
206
|
-
const result = await npm.fetchFromRegistry('@thegetty/quire-11ty')
|
|
207
|
-
|
|
208
|
-
t.deepEqual(result, { name: '@thegetty/quire-11ty', versions: { '1.0.0': {}, '1.0.1': {} } })
|
|
209
|
-
t.true(mockFetch.calledWith('https://registry.npmjs.org/@thegetty/quire-11ty'))
|
|
210
|
-
})
|
|
211
|
-
|
|
212
|
-
test('fetchFromRegistry() throws error when response is not ok', async (t) => {
|
|
213
|
-
const { sandbox } = t.context
|
|
214
|
-
|
|
215
|
-
const mockResponse = {
|
|
216
|
-
ok: false,
|
|
217
|
-
statusText: 'Not Found'
|
|
218
|
-
}
|
|
219
|
-
const mockFetch = sandbox.stub().resolves(mockResponse)
|
|
220
|
-
const mockWhich = sandbox.stub().returns('/usr/bin/npm')
|
|
221
|
-
|
|
222
|
-
const npm = await esmock('./index.js', {
|
|
223
|
-
'node-fetch': { default: mockFetch },
|
|
224
|
-
execa: { execa: sandbox.stub() },
|
|
225
|
-
'#helpers/which.js': { default: mockWhich }
|
|
226
|
-
})
|
|
227
|
-
|
|
228
|
-
await t.throwsAsync(
|
|
229
|
-
() => npm.fetchFromRegistry('nonexistent-package'),
|
|
230
|
-
{ message: /Failed to fetch package metadata/ }
|
|
231
|
-
)
|
|
232
|
-
})
|
|
233
|
-
|
|
234
|
-
test('getCompatibleVersion() returns latest version matching semver range', async (t) => {
|
|
235
|
-
const { sandbox } = t.context
|
|
236
|
-
|
|
237
|
-
const mockResponse = {
|
|
238
|
-
ok: true,
|
|
239
|
-
json: sandbox.stub().resolves({
|
|
240
|
-
versions: {
|
|
241
|
-
'1.0.0': {},
|
|
242
|
-
'1.0.1': {},
|
|
243
|
-
'1.1.0': {},
|
|
244
|
-
'2.0.0': {}
|
|
245
|
-
}
|
|
246
|
-
})
|
|
247
|
-
}
|
|
248
|
-
const mockFetch = sandbox.stub().resolves(mockResponse)
|
|
249
|
-
const mockWhich = sandbox.stub().returns('/usr/bin/npm')
|
|
250
|
-
|
|
251
|
-
const npm = await esmock('./index.js', {
|
|
252
|
-
'node-fetch': { default: mockFetch },
|
|
253
|
-
execa: { execa: sandbox.stub() },
|
|
254
|
-
'#helpers/which.js': { default: mockWhich }
|
|
255
|
-
})
|
|
256
|
-
|
|
257
|
-
const result = await npm.getCompatibleVersion('@thegetty/quire-11ty', '^1.0.0')
|
|
258
|
-
|
|
259
|
-
t.is(result, '1.1.0')
|
|
260
|
-
})
|
|
261
|
-
|
|
262
|
-
test('getCompatibleVersion() returns null when no compatible version found', async (t) => {
|
|
263
|
-
const { sandbox } = t.context
|
|
264
|
-
|
|
265
|
-
const mockResponse = {
|
|
266
|
-
ok: true,
|
|
267
|
-
json: sandbox.stub().resolves({
|
|
268
|
-
versions: {
|
|
269
|
-
'2.0.0': {},
|
|
270
|
-
'3.0.0': {}
|
|
271
|
-
}
|
|
272
|
-
})
|
|
273
|
-
}
|
|
274
|
-
const mockFetch = sandbox.stub().resolves(mockResponse)
|
|
275
|
-
const mockWhich = sandbox.stub().returns('/usr/bin/npm')
|
|
276
|
-
|
|
277
|
-
const npm = await esmock('./index.js', {
|
|
278
|
-
'node-fetch': { default: mockFetch },
|
|
279
|
-
execa: { execa: sandbox.stub() },
|
|
280
|
-
'#helpers/which.js': { default: mockWhich }
|
|
281
|
-
})
|
|
282
|
-
|
|
283
|
-
const result = await npm.getCompatibleVersion('@thegetty/quire-11ty', '^1.0.0')
|
|
284
|
-
|
|
285
|
-
t.is(result, null)
|
|
286
|
-
})
|
|
287
|
-
|
|
288
|
-
test('isAvailable() returns true when npm is found in PATH', async (t) => {
|
|
289
|
-
const { sandbox } = t.context
|
|
290
|
-
|
|
291
|
-
const mockWhich = sandbox.stub().returns('/usr/bin/npm')
|
|
292
|
-
|
|
293
|
-
const npm = await esmock('./index.js', {
|
|
294
|
-
execa: { execa: sandbox.stub() },
|
|
295
|
-
'#helpers/which.js': { default: mockWhich }
|
|
296
|
-
})
|
|
297
|
-
|
|
298
|
-
const result = npm.isAvailable()
|
|
299
|
-
|
|
300
|
-
t.true(result)
|
|
301
|
-
t.true(mockWhich.calledWith('npm'))
|
|
302
|
-
})
|
|
303
|
-
|
|
304
|
-
test('isAvailable() returns false when npm is not found in PATH', async (t) => {
|
|
305
|
-
const { sandbox } = t.context
|
|
306
|
-
|
|
307
|
-
const mockWhich = sandbox.stub().returns(null)
|
|
308
|
-
|
|
309
|
-
const npm = await esmock('./index.js', {
|
|
310
|
-
execa: { execa: sandbox.stub() },
|
|
311
|
-
'#helpers/which.js': { default: mockWhich }
|
|
312
|
-
})
|
|
313
|
-
|
|
314
|
-
const result = npm.isAvailable()
|
|
315
|
-
|
|
316
|
-
t.false(result)
|
|
317
|
-
})
|
|
318
|
-
|
|
319
|
-
test('install() logs stderr via debug when present', async (t) => {
|
|
320
|
-
const { sandbox } = t.context
|
|
321
|
-
|
|
322
|
-
const mockExeca = sandbox.stub().resolves({ stderr: 'npm WARN deprecated' })
|
|
323
|
-
const mockWhich = sandbox.stub().returns('/usr/bin/npm')
|
|
324
|
-
const mockDebug = sandbox.stub()
|
|
325
|
-
const mockCreateDebug = sandbox.stub().returns(mockDebug)
|
|
326
|
-
|
|
327
|
-
const npm = await esmock('./index.js', {
|
|
328
|
-
execa: { execa: mockExeca },
|
|
329
|
-
'#helpers/which.js': { default: mockWhich },
|
|
330
|
-
'#debug': { default: mockCreateDebug }
|
|
331
|
-
})
|
|
332
|
-
|
|
333
|
-
await npm.install('/path/to/project')
|
|
334
|
-
|
|
335
|
-
t.true(mockDebug.calledWith('npm install stderr: %s', 'npm WARN deprecated'))
|
|
336
|
-
})
|
|
337
|
-
|
|
338
|
-
test('cacheClean() logs stderr via debug when present', async (t) => {
|
|
339
|
-
const { sandbox } = t.context
|
|
340
|
-
|
|
341
|
-
const mockExeca = sandbox.stub().resolves({ stderr: 'cache warning' })
|
|
342
|
-
const mockWhich = sandbox.stub().returns('/usr/bin/npm')
|
|
343
|
-
const mockDebug = sandbox.stub()
|
|
344
|
-
const mockCreateDebug = sandbox.stub().returns(mockDebug)
|
|
345
|
-
|
|
346
|
-
const npm = await esmock('./index.js', {
|
|
347
|
-
execa: { execa: mockExeca },
|
|
348
|
-
'#helpers/which.js': { default: mockWhich },
|
|
349
|
-
'#debug': { default: mockCreateDebug }
|
|
350
|
-
})
|
|
351
|
-
|
|
352
|
-
await npm.cacheClean('/path/to/project')
|
|
353
|
-
|
|
354
|
-
t.true(mockDebug.calledWith('npm cache clean stderr: %s', 'cache warning'))
|
|
355
|
-
})
|
package/src/lib/pdf/engines.js
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* PDF Engine Registry
|
|
3
|
-
*
|
|
4
|
-
* Centralized metadata for PDF engines. Each engine module re-exports
|
|
5
|
-
* its metadata from here, ensuring single source of truth.
|
|
6
|
-
*
|
|
7
|
-
* The façade imports this registry to:
|
|
8
|
-
* 1. Resolve engine names to implementations
|
|
9
|
-
* 2. Check binary availability before loading heavy modules
|
|
10
|
-
* 3. Provide helpful error messages with install URLs
|
|
11
|
-
*/
|
|
12
|
-
import { docsUrl } from '#helpers/docs-url.js'
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* @typedef {Object} EngineMetadata
|
|
16
|
-
* @property {string} name - Human-readable display name
|
|
17
|
-
* @property {string} module - Module filename (e.g., 'paged.js')
|
|
18
|
-
* @property {string|null} requiresBinary - CLI binary name, or null if built-in
|
|
19
|
-
* @property {Object} [toolInfo] - Error metadata (only for engines requiring binaries)
|
|
20
|
-
* @property {string} [toolInfo.displayName] - Display name for error messages
|
|
21
|
-
* @property {string} [toolInfo.installUrl] - URL to download the tool
|
|
22
|
-
* @property {string} [toolInfo.docsUrl] - Quire docs URL
|
|
23
|
-
* @property {string} [toolInfo.fallback] - Alternative suggestion
|
|
24
|
-
*/
|
|
25
|
-
|
|
26
|
-
/** @type {Record<string, EngineMetadata>} */
|
|
27
|
-
const ENGINES = {
|
|
28
|
-
pagedjs: {
|
|
29
|
-
name: 'Paged.js',
|
|
30
|
-
module: 'paged.js',
|
|
31
|
-
requiresBinary: null, // Built-in Node.js library
|
|
32
|
-
},
|
|
33
|
-
prince: {
|
|
34
|
-
name: 'Prince',
|
|
35
|
-
module: 'prince.js',
|
|
36
|
-
requiresBinary: 'prince',
|
|
37
|
-
toolInfo: {
|
|
38
|
-
displayName: 'PrinceXML',
|
|
39
|
-
installUrl: 'https://www.princexml.com/download/',
|
|
40
|
-
docsUrl: docsUrl('pdf-output'),
|
|
41
|
-
fallback: 'Or use the default PDF engine: quire pdf --engine pagedjs',
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export default ENGINES
|