@thegetty/quire-cli 1.0.0-rc.37 → 1.0.0-rc.39
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/package.json +5 -2
- package/src/commands/build.js +13 -6
- package/src/commands/clean.js +10 -2
- package/src/commands/clean.spec.js +10 -0
- package/src/commands/clean.test.js +122 -0
- package/src/commands/config.js +3 -1
- package/src/commands/config.test.js +42 -1
- package/src/commands/doctor.js +251 -0
- package/src/commands/doctor.spec.js +115 -0
- package/src/commands/doctor.test.js +1409 -0
- package/src/commands/epub.js +9 -2
- package/src/commands/help.js +60 -0
- package/src/commands/help.test.js +132 -0
- package/src/commands/info.js +79 -71
- package/src/commands/info.spec.js +8 -0
- package/src/commands/info.test.js +173 -76
- package/src/commands/pdf.js +10 -3
- package/src/commands/validate.js +39 -7
- package/src/commands/validate.spec.js +8 -0
- package/src/commands/validate.test.js +144 -0
- package/src/errors/help/help-topic-not-found-error.js +22 -0
- package/src/errors/help/index.js +8 -0
- package/src/errors/index.js +6 -0
- package/src/errors/input/index.js +8 -0
- package/src/errors/input/invalid-input-error.js +21 -0
- package/src/helpers/pager.js +59 -0
- package/src/helpers/pager.test.js +85 -0
- package/src/lib/README.md +77 -22
- package/src/lib/conf/README.md +6 -0
- package/src/lib/conf/build-status.js +103 -0
- package/src/lib/conf/build-status.test.js +247 -0
- package/src/lib/conf/defaults.js +14 -0
- package/src/lib/conf/format.js +1 -1
- package/src/lib/conf/schema.js +46 -1
- package/src/lib/constants.js +28 -0
- package/src/lib/doctor/README.md +667 -0
- package/src/lib/doctor/checks/environment/cli-version.js +62 -0
- package/src/lib/doctor/checks/environment/cli-version.test.js +132 -0
- package/src/lib/doctor/checks/environment/git-available.js +77 -0
- package/src/lib/doctor/checks/environment/git-available.test.js +52 -0
- package/src/lib/doctor/checks/environment/index.js +13 -0
- package/src/lib/doctor/checks/environment/node-version.js +66 -0
- package/src/lib/doctor/checks/environment/node-version.test.js +17 -0
- package/src/lib/doctor/checks/environment/npm-available.js +66 -0
- package/src/lib/doctor/checks/environment/npm-available.test.js +52 -0
- package/src/lib/doctor/checks/environment/os-info.js +48 -0
- package/src/lib/doctor/checks/environment/os-info.test.js +81 -0
- package/src/lib/doctor/checks/environment/runtime-info.js +51 -0
- package/src/lib/doctor/checks/environment/runtime-info.test.js +132 -0
- package/src/lib/doctor/checks/outputs/epub-output.js +119 -0
- package/src/lib/doctor/checks/outputs/epub-output.test.js +277 -0
- package/src/lib/doctor/checks/outputs/index.js +10 -0
- package/src/lib/doctor/checks/outputs/pdf-output.js +144 -0
- package/src/lib/doctor/checks/outputs/pdf-output.test.js +377 -0
- package/src/lib/doctor/checks/outputs/stale-build.js +122 -0
- package/src/lib/doctor/checks/outputs/stale-build.test.js +282 -0
- package/src/lib/doctor/checks/project/data-files.js +56 -0
- package/src/lib/doctor/checks/project/data-files.test.js +125 -0
- package/src/lib/doctor/checks/project/dependencies.js +53 -0
- package/src/lib/doctor/checks/project/dependencies.test.js +71 -0
- package/src/lib/doctor/checks/project/index.js +11 -0
- package/src/lib/doctor/checks/project/quire-11ty.js +98 -0
- package/src/lib/doctor/checks/project/quire-11ty.test.js +170 -0
- package/src/lib/doctor/checks/project/quire-project.js +38 -0
- package/src/lib/doctor/checks/project/quire-project.test.js +47 -0
- package/src/lib/doctor/checks/tools/index.js +10 -0
- package/src/lib/doctor/checks/tools/pandoc-available.js +82 -0
- package/src/lib/doctor/checks/tools/pandoc-available.test.js +73 -0
- package/src/lib/doctor/checks/tools/prince-available.js +81 -0
- package/src/lib/doctor/checks/tools/prince-available.test.js +73 -0
- package/src/lib/doctor/constants.js +39 -0
- package/src/lib/doctor/formatDuration.js +108 -0
- package/src/lib/doctor/formatDuration.test.js +76 -0
- package/src/lib/doctor/formatters/human.js +257 -0
- package/src/lib/doctor/formatters/human.test.js +463 -0
- package/src/lib/doctor/formatters/index.js +8 -0
- package/src/lib/doctor/formatters/json.js +78 -0
- package/src/lib/doctor/formatters/json.test.js +174 -0
- package/src/lib/doctor/formatters/shared.js +129 -0
- package/src/lib/doctor/formatters/shared.test.js +194 -0
- package/src/lib/doctor/index.js +271 -0
- package/src/lib/doctor/index.test.js +797 -0
- package/src/lib/help/frontmatter.js +77 -0
- package/src/lib/help/frontmatter.test.js +139 -0
- package/src/lib/help/index.js +135 -0
- package/src/lib/help/index.test.js +160 -0
- package/src/lib/help/topics/configuration.md +77 -0
- package/src/lib/help/topics/debugging.md +69 -0
- package/src/lib/help/topics/epub.md +74 -0
- package/src/lib/help/topics/pdf.md +74 -0
- package/src/lib/help/topics/publishing.md +80 -0
- package/src/lib/help/topics/workflows.md +50 -0
- package/src/lib/platform.js +95 -0
- package/src/lib/project/build.js +44 -25
- package/src/lib/project/build.test.js +30 -8
- package/src/lib/project/detect.js +16 -2
- package/src/lib/project/index.js +18 -2
- package/src/lib/project/output-paths.js +87 -0
- package/src/lib/project/output-paths.test.js +66 -0
- package/src/lib/project/paths.js +48 -0
- package/src/main.js +38 -3
- package/src/packageConfig.js +17 -0
- package/src/validators/validate-data-files.js +154 -0
- package/src/validators/validate-data-files.test.js +217 -0
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import esmock from 'esmock'
|
|
2
|
+
import sinon from 'sinon'
|
|
3
|
+
import test from 'ava'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Build Status Module Tests
|
|
7
|
+
*
|
|
8
|
+
* Tests the per-project build status persistence API.
|
|
9
|
+
* Mocks the config module with a simple in-memory store.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
test.beforeEach(async (t) => {
|
|
13
|
+
const sandbox = sinon.createSandbox()
|
|
14
|
+
|
|
15
|
+
// In-memory store that mimics config.get/set for 'projects'
|
|
16
|
+
const store = {}
|
|
17
|
+
const configMock = {
|
|
18
|
+
default: {
|
|
19
|
+
get: sandbox.stub().callsFake((key) => store[key]),
|
|
20
|
+
set: sandbox.stub().callsFake((key, value) => { store[key] = value }),
|
|
21
|
+
},
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const mod = await esmock('./build-status.js', {
|
|
25
|
+
'#lib/conf/config.js': configMock,
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
t.context = { sandbox, store, configMock, ...mod }
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
test.afterEach.always((t) => {
|
|
32
|
+
t.context.sandbox.restore()
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
36
|
+
// projectKey
|
|
37
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
38
|
+
|
|
39
|
+
test('projectKey returns a 12-character hex string', (t) => {
|
|
40
|
+
const { projectKey } = t.context
|
|
41
|
+
const key = projectKey('/Users/test/my-project')
|
|
42
|
+
t.is(key.length, 12)
|
|
43
|
+
t.regex(key, /^[0-9a-f]{12}$/)
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
test('projectKey returns the same key for the same path', (t) => {
|
|
47
|
+
const { projectKey } = t.context
|
|
48
|
+
const key1 = projectKey('/Users/test/my-project')
|
|
49
|
+
const key2 = projectKey('/Users/test/my-project')
|
|
50
|
+
t.is(key1, key2)
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
test('projectKey returns different keys for different paths', (t) => {
|
|
54
|
+
const { projectKey } = t.context
|
|
55
|
+
const key1 = projectKey('/Users/test/project-a')
|
|
56
|
+
const key2 = projectKey('/Users/test/project-b')
|
|
57
|
+
t.not(key1, key2)
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
61
|
+
// recordStatus
|
|
62
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
63
|
+
|
|
64
|
+
test('recordStatus writes status with timestamp to config', (t) => {
|
|
65
|
+
const { recordStatus, projectKey, configMock } = t.context
|
|
66
|
+
const projectPath = '/Users/test/my-project'
|
|
67
|
+
|
|
68
|
+
recordStatus(projectPath, 'build', 'ok')
|
|
69
|
+
|
|
70
|
+
t.true(configMock.default.set.calledOnce)
|
|
71
|
+
const [setKey, setValue] = configMock.default.set.firstCall.args
|
|
72
|
+
t.is(setKey, 'projects')
|
|
73
|
+
|
|
74
|
+
const key = projectKey(projectPath)
|
|
75
|
+
const entry = setValue[key]
|
|
76
|
+
t.is(entry.projectPath, projectPath)
|
|
77
|
+
t.is(entry.buildStatus.build.status, 'ok')
|
|
78
|
+
t.is(typeof entry.buildStatus.build.timestamp, 'number')
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
test('recordStatus records failed status', (t) => {
|
|
82
|
+
const { recordStatus, projectKey, configMock } = t.context
|
|
83
|
+
const projectPath = '/Users/test/my-project'
|
|
84
|
+
|
|
85
|
+
recordStatus(projectPath, 'pdf', 'failed')
|
|
86
|
+
|
|
87
|
+
const [, setValue] = configMock.default.set.firstCall.args
|
|
88
|
+
const key = projectKey(projectPath)
|
|
89
|
+
t.is(setValue[key].buildStatus.pdf.status, 'failed')
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
test('recordStatus silently ignores untracked commands', (t) => {
|
|
93
|
+
const { recordStatus, configMock } = t.context
|
|
94
|
+
|
|
95
|
+
recordStatus('/Users/test/my-project', 'preview', 'ok')
|
|
96
|
+
|
|
97
|
+
t.false(configMock.default.set.called)
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
test('recordStatus preserves existing command entries', (t) => {
|
|
101
|
+
const { recordStatus, projectKey, store } = t.context
|
|
102
|
+
const projectPath = '/Users/test/my-project'
|
|
103
|
+
const key = projectKey(projectPath)
|
|
104
|
+
|
|
105
|
+
// Pre-populate with a build entry
|
|
106
|
+
store.projects = {
|
|
107
|
+
[key]: {
|
|
108
|
+
projectPath,
|
|
109
|
+
buildStatus: {
|
|
110
|
+
build: { status: 'ok', timestamp: 1000 },
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
recordStatus(projectPath, 'pdf', 'failed')
|
|
116
|
+
|
|
117
|
+
const entry = store.projects[key]
|
|
118
|
+
t.is(entry.buildStatus.build.status, 'ok')
|
|
119
|
+
t.is(entry.buildStatus.build.timestamp, 1000)
|
|
120
|
+
t.is(entry.buildStatus.pdf.status, 'failed')
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
124
|
+
// getStatus
|
|
125
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
126
|
+
|
|
127
|
+
test('getStatus returns stored status entry', (t) => {
|
|
128
|
+
const { getStatus, projectKey, store } = t.context
|
|
129
|
+
const projectPath = '/Users/test/my-project'
|
|
130
|
+
const key = projectKey(projectPath)
|
|
131
|
+
|
|
132
|
+
store.projects = {
|
|
133
|
+
[key]: {
|
|
134
|
+
projectPath,
|
|
135
|
+
buildStatus: {
|
|
136
|
+
build: { status: 'ok', timestamp: 1000 },
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const result = getStatus(projectPath, 'build')
|
|
142
|
+
t.deepEqual(result, { status: 'ok', timestamp: 1000 })
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
test('getStatus returns undefined for unknown project', (t) => {
|
|
146
|
+
const { getStatus } = t.context
|
|
147
|
+
|
|
148
|
+
const result = getStatus('/Users/test/unknown-project', 'build')
|
|
149
|
+
t.is(result, undefined)
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
test('getStatus returns undefined for unrecorded command', (t) => {
|
|
153
|
+
const { getStatus, projectKey, store } = t.context
|
|
154
|
+
const projectPath = '/Users/test/my-project'
|
|
155
|
+
const key = projectKey(projectPath)
|
|
156
|
+
|
|
157
|
+
store.projects = {
|
|
158
|
+
[key]: {
|
|
159
|
+
projectPath,
|
|
160
|
+
buildStatus: {
|
|
161
|
+
build: { status: 'ok', timestamp: 1000 },
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const result = getStatus(projectPath, 'epub')
|
|
167
|
+
t.is(result, undefined)
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
171
|
+
// clearStatus
|
|
172
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
173
|
+
|
|
174
|
+
test('clearStatus removes project entry', (t) => {
|
|
175
|
+
const { clearStatus, projectKey, store, configMock } = t.context
|
|
176
|
+
const projectPath = '/Users/test/my-project'
|
|
177
|
+
const key = projectKey(projectPath)
|
|
178
|
+
|
|
179
|
+
store.projects = {
|
|
180
|
+
[key]: {
|
|
181
|
+
projectPath,
|
|
182
|
+
buildStatus: {
|
|
183
|
+
build: { status: 'ok', timestamp: 1000 },
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
clearStatus(projectPath)
|
|
189
|
+
|
|
190
|
+
const [, setValue] = configMock.default.set.firstCall.args
|
|
191
|
+
t.truthy(setValue[key], 'project entry should still exist')
|
|
192
|
+
t.is(setValue[key].projectPath, projectPath, 'projectPath should be preserved')
|
|
193
|
+
t.is(setValue[key].buildStatus, undefined, 'buildStatus should be removed')
|
|
194
|
+
})
|
|
195
|
+
|
|
196
|
+
test('clearStatus is a no-op for unknown project', (t) => {
|
|
197
|
+
const { clearStatus, configMock, store } = t.context
|
|
198
|
+
|
|
199
|
+
store.projects = {}
|
|
200
|
+
clearStatus('/Users/test/unknown-project')
|
|
201
|
+
|
|
202
|
+
t.false(configMock.default.set.called)
|
|
203
|
+
})
|
|
204
|
+
|
|
205
|
+
test('clearStatus is a no-op when project has no buildStatus', (t) => {
|
|
206
|
+
const { clearStatus, projectKey, configMock, store } = t.context
|
|
207
|
+
const projectPath = '/Users/test/my-project'
|
|
208
|
+
const key = projectKey(projectPath)
|
|
209
|
+
|
|
210
|
+
store.projects = {
|
|
211
|
+
[key]: { projectPath },
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
clearStatus(projectPath)
|
|
215
|
+
|
|
216
|
+
t.false(configMock.default.set.called)
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
220
|
+
// Multiple projects
|
|
221
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
222
|
+
|
|
223
|
+
test('multiple projects are tracked independently', (t) => {
|
|
224
|
+
const { recordStatus, getStatus } = t.context
|
|
225
|
+
const projectA = '/Users/test/project-a'
|
|
226
|
+
const projectB = '/Users/test/project-b'
|
|
227
|
+
|
|
228
|
+
recordStatus(projectA, 'build', 'ok')
|
|
229
|
+
recordStatus(projectB, 'build', 'failed')
|
|
230
|
+
|
|
231
|
+
t.is(getStatus(projectA, 'build').status, 'ok')
|
|
232
|
+
t.is(getStatus(projectB, 'build').status, 'failed')
|
|
233
|
+
})
|
|
234
|
+
|
|
235
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
236
|
+
// TRACKED_COMMANDS
|
|
237
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
238
|
+
|
|
239
|
+
test('TRACKED_COMMANDS contains build, pdf, and epub', (t) => {
|
|
240
|
+
const { TRACKED_COMMANDS } = t.context
|
|
241
|
+
t.deepEqual([...TRACKED_COMMANDS], ['build', 'pdf', 'epub'])
|
|
242
|
+
})
|
|
243
|
+
|
|
244
|
+
test('TRACKED_COMMANDS is frozen', (t) => {
|
|
245
|
+
const { TRACKED_COMMANDS } = t.context
|
|
246
|
+
t.true(Object.isFrozen(TRACKED_COMMANDS))
|
|
247
|
+
})
|
package/src/lib/conf/defaults.js
CHANGED
|
@@ -56,6 +56,15 @@ export default {
|
|
|
56
56
|
* Relative path to quire-11ty installed in the project directory.
|
|
57
57
|
*/
|
|
58
58
|
quire11tyPath: '.',
|
|
59
|
+
/**
|
|
60
|
+
* How stale an output must be before `quire doctor` warns.
|
|
61
|
+
* - 'ZERO': any time difference (0 minutes)
|
|
62
|
+
* - 'SHORT': 5 minutes
|
|
63
|
+
* - 'HOURLY': 60 minutes (default)
|
|
64
|
+
* - 'DAILY': 12 hours
|
|
65
|
+
* - 'NEVER': disable stale output warnings
|
|
66
|
+
*/
|
|
67
|
+
staleThreshold: 'HOURLY',
|
|
59
68
|
/**
|
|
60
69
|
* Version of quire-11ty to install when creating new projects.
|
|
61
70
|
*/
|
|
@@ -78,4 +87,9 @@ export default {
|
|
|
78
87
|
* File name for the quire-11ty version file.
|
|
79
88
|
*/
|
|
80
89
|
versionFile: '.quire',
|
|
90
|
+
/**
|
|
91
|
+
* Per-project data (internal).
|
|
92
|
+
* Keyed by SHA-256 hash of the project's absolute path.
|
|
93
|
+
*/
|
|
94
|
+
projects: {},
|
|
81
95
|
}
|
package/src/lib/conf/format.js
CHANGED
|
@@ -45,7 +45,7 @@ export function formatSettings(store, { configPath, showInternal = false, useCol
|
|
|
45
45
|
lines.push('')
|
|
46
46
|
|
|
47
47
|
for (const [key, value] of Object.entries(store)) {
|
|
48
|
-
if (key.startsWith('__internal__') && !showInternal) continue
|
|
48
|
+
if ((key.startsWith('__internal__') || key === 'projects') && !showInternal) continue
|
|
49
49
|
const description = getKeyDescription(key)
|
|
50
50
|
lines.push(` ${style.cyan(key)}: ${JSON.stringify(value)}`)
|
|
51
51
|
if (description) {
|
package/src/lib/conf/schema.js
CHANGED
|
@@ -50,6 +50,11 @@ export default {
|
|
|
50
50
|
type: 'string',
|
|
51
51
|
description: 'Path to the quire-11ty package (use "." for local development)'
|
|
52
52
|
},
|
|
53
|
+
staleThreshold: {
|
|
54
|
+
type: 'string',
|
|
55
|
+
enum: ['ZERO', 'SHORT', 'HOURLY', 'DAILY', 'NEVER'],
|
|
56
|
+
description: 'How stale an output must be before doctor warns (ZERO=0m, SHORT=5m, HOURLY=60m, DAILY=12h, NEVER=disabled)'
|
|
57
|
+
},
|
|
53
58
|
quireVersion: {
|
|
54
59
|
type: 'string',
|
|
55
60
|
description: 'Version of quire-11ty to use ("latest" or specific version)'
|
|
@@ -71,5 +76,45 @@ export default {
|
|
|
71
76
|
versionFile: {
|
|
72
77
|
type: 'string',
|
|
73
78
|
description: 'Filename used to identify Quire projects'
|
|
74
|
-
}
|
|
79
|
+
},
|
|
80
|
+
projects: {
|
|
81
|
+
type: 'object',
|
|
82
|
+
description: 'Per-project data keyed by hashed project path (internal)',
|
|
83
|
+
additionalProperties: {
|
|
84
|
+
type: 'object',
|
|
85
|
+
properties: {
|
|
86
|
+
projectPath: { type: 'string' },
|
|
87
|
+
buildStatus: {
|
|
88
|
+
type: 'object',
|
|
89
|
+
properties: {
|
|
90
|
+
build: {
|
|
91
|
+
type: 'object',
|
|
92
|
+
properties: {
|
|
93
|
+
status: { type: 'string', enum: ['ok', 'failed'] },
|
|
94
|
+
timestamp: { type: 'number' },
|
|
95
|
+
},
|
|
96
|
+
required: ['status', 'timestamp'],
|
|
97
|
+
},
|
|
98
|
+
pdf: {
|
|
99
|
+
type: 'object',
|
|
100
|
+
properties: {
|
|
101
|
+
status: { type: 'string', enum: ['ok', 'failed'] },
|
|
102
|
+
timestamp: { type: 'number' },
|
|
103
|
+
},
|
|
104
|
+
required: ['status', 'timestamp'],
|
|
105
|
+
},
|
|
106
|
+
epub: {
|
|
107
|
+
type: 'object',
|
|
108
|
+
properties: {
|
|
109
|
+
status: { type: 'string', enum: ['ok', 'failed'] },
|
|
110
|
+
timestamp: { type: 'number' },
|
|
111
|
+
},
|
|
112
|
+
required: ['status', 'timestamp'],
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
required: ['projectPath'],
|
|
118
|
+
},
|
|
119
|
+
},
|
|
75
120
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared CLI constants
|
|
3
|
+
*
|
|
4
|
+
* Centralized constants used across the CLI to avoid duplication
|
|
5
|
+
* and ensure consistency.
|
|
6
|
+
*
|
|
7
|
+
* @module lib/constants
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Base URL for Quire documentation (without trailing slash)
|
|
12
|
+
*
|
|
13
|
+
* Use with URL constructor for path joining:
|
|
14
|
+
* @example
|
|
15
|
+
* new URL('install-uninstall/', DOCS_BASE_URL).href
|
|
16
|
+
* // => 'https://quire.getty.edu/docs-v1/install-uninstall/'
|
|
17
|
+
*/
|
|
18
|
+
export const DOCS_BASE_URL = 'https://quire.getty.edu/docs-v1'
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Package name for quire-11ty
|
|
22
|
+
*/
|
|
23
|
+
export const QUIRE_11TY_PACKAGE = '@thegetty/quire-11ty'
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Minimum required Node.js major version
|
|
27
|
+
*/
|
|
28
|
+
export const REQUIRED_NODE_VERSION = 22
|