@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.
- package/CHANGELOG.md +36 -0
- package/README.md +9 -0
- package/bin/cli.js +19 -1
- package/package.json +21 -8
- package/patches/README.md +19 -0
- package/patches/install-npm-version+1.0.9.patch +12119 -0
- package/schemas/objects.schema.json +12 -38
- package/schemas/publication.schema.json +0 -22
- package/schemas/references.schema.json +0 -1
- package/src/Command.js +26 -6
- package/src/Command.spec.js +99 -0
- package/src/commands/README.md +213 -122
- package/src/commands/build.js +46 -37
- package/src/commands/build.spec.js +113 -0
- package/src/commands/build.test.js +402 -0
- package/src/commands/clean.js +25 -19
- package/src/commands/clean.spec.js +108 -0
- package/src/commands/clean.test.js +260 -0
- package/src/commands/config.js +251 -0
- package/src/commands/config.spec.js +107 -0
- package/src/commands/config.test.js +715 -0
- package/src/commands/create.js +42 -14
- package/src/commands/create.spec.js +112 -0
- package/src/commands/create.test.js +415 -0
- package/src/commands/epub.js +59 -30
- package/src/commands/epub.spec.js +114 -0
- package/src/commands/epub.test.js +503 -0
- package/src/commands/index.js +9 -2
- package/src/commands/info.js +18 -24
- package/src/commands/info.spec.js +64 -0
- package/src/commands/info.test.js +415 -0
- package/src/commands/pdf.js +58 -84
- package/src/commands/pdf.spec.js +114 -0
- package/src/commands/pdf.test.js +464 -0
- package/src/commands/preview.js +26 -31
- package/src/commands/preview.spec.js +97 -0
- package/src/commands/preview.test.js +250 -0
- package/src/commands/use.js +56 -0
- package/src/commands/use.spec.js +61 -0
- package/src/commands/use.test.js +280 -0
- package/src/commands/validate.js +31 -19
- package/src/commands/validate.spec.js +82 -0
- package/src/commands/validate.test.js +234 -0
- package/src/commands/workflows.js +70 -0
- package/src/errors/build/build-failed-error.js +19 -0
- package/src/errors/build/config-field-missing-error.js +20 -0
- package/src/errors/build/config-file-not-found-error.js +20 -0
- package/src/errors/build/index.js +11 -0
- package/src/errors/index.js +48 -0
- package/src/errors/install/dependency-install-error.js +19 -0
- package/src/errors/install/directory-not-empty-error.js +25 -0
- package/src/errors/install/index.js +12 -0
- package/src/errors/install/invalid-path-error.js +31 -0
- package/src/errors/install/invalid-starter-error.js +27 -0
- package/src/errors/install/version-not-found-error.js +35 -0
- package/src/errors/output/epub-generation-error.js +19 -0
- package/src/errors/output/index.js +14 -0
- package/src/errors/output/invalid-epub-library-error.js +20 -0
- package/src/errors/output/invalid-pdf-library-error.js +20 -0
- package/src/errors/output/missing-build-output-error.js +21 -0
- package/src/errors/output/pdf-generation-error.js +24 -0
- package/src/errors/output/tool-not-found-error.js +37 -0
- package/src/errors/project/index.js +10 -0
- package/src/errors/project/not-in-project-error.js +20 -0
- package/src/errors/project/project-create-error.js +21 -0
- package/src/errors/quire-error.js +27 -0
- package/src/errors/validation/validation-error.js +20 -11
- package/src/helpers/clean.js +1 -1
- package/src/helpers/docs-url.js +32 -0
- package/src/helpers/test-cwd.js +5 -6
- package/src/helpers/test-cwd.test.js +192 -0
- package/src/helpers/which.js +10 -4
- package/src/lib/11ty/README.md +135 -19
- package/src/lib/11ty/api.js +176 -93
- package/src/lib/11ty/cli.js +77 -35
- package/src/lib/11ty/index.js +64 -5
- package/src/lib/11ty/index.test.js +655 -0
- package/src/lib/README.md +275 -0
- package/src/lib/commander/index.js +100 -0
- package/src/lib/commander/index.test.js +86 -0
- package/src/lib/commander/options.js +195 -0
- package/src/lib/commander/options.test.js +109 -0
- package/src/lib/conf/README.md +84 -73
- package/src/lib/conf/config.js +5 -3
- package/src/lib/conf/config.test.js +281 -0
- package/src/lib/conf/defaults.js +44 -0
- package/src/lib/conf/format.js +60 -0
- package/src/lib/conf/format.test.js +106 -0
- package/src/lib/conf/helpers.js +91 -0
- package/src/lib/conf/helpers.test.js +136 -0
- package/src/lib/conf/index.js +22 -0
- package/src/lib/conf/schema.js +53 -8
- package/src/lib/epub/README.md +133 -2
- package/src/lib/epub/engines.js +46 -0
- package/src/lib/epub/epub.js +36 -11
- package/src/lib/epub/index.js +111 -21
- package/src/lib/epub/index.test.js +518 -0
- package/src/lib/epub/pandoc.js +33 -4
- package/src/lib/epub/pandoc.test.js +122 -0
- package/src/lib/epub/schema.js +21 -0
- package/src/lib/error/README.md +170 -0
- package/src/lib/error/handler.js +107 -0
- package/src/lib/git/README.md +151 -2
- package/src/lib/git/index.js +217 -13
- package/src/lib/git/index.spec.js +80 -0
- package/src/lib/git/index.test.js +453 -0
- package/src/lib/installer/index.js +309 -0
- package/src/lib/installer/index.spec.js +83 -0
- package/src/lib/installer/index.test.js +545 -0
- package/src/lib/logger/README.md +424 -0
- package/src/lib/logger/debug.js +90 -0
- package/src/lib/logger/debug.spec.js +130 -0
- package/src/lib/logger/index.js +228 -0
- package/src/lib/logger/index.spec.js +131 -0
- package/src/lib/logger/index.test.js +477 -0
- package/src/lib/npm/README.md +127 -0
- package/src/lib/npm/index.js +198 -0
- package/src/lib/npm/index.spec.js +60 -0
- package/src/lib/npm/index.test.js +355 -0
- package/src/lib/pdf/README.md +131 -0
- package/src/lib/pdf/engines.js +46 -0
- package/src/lib/pdf/index.js +124 -21
- package/src/lib/pdf/index.test.js +708 -0
- package/src/lib/pdf/paged.js +100 -52
- package/src/lib/pdf/paged.test.js +366 -0
- package/src/lib/pdf/prince.js +115 -37
- package/src/lib/pdf/prince.test.js +202 -0
- package/src/lib/pdf/schema.js +21 -0
- package/src/lib/pdf/split.js +61 -33
- package/src/lib/pdf/split.test.js +445 -0
- package/src/lib/process/manager.js +110 -0
- package/src/lib/process/manager.test.js +55 -0
- package/src/lib/project/build.js +143 -0
- package/src/lib/project/build.test.js +253 -0
- package/src/lib/project/config.js +48 -0
- package/src/lib/project/config.test.js +134 -0
- package/src/{helpers/is-quire.js → lib/project/detect.js} +5 -3
- package/src/lib/project/detect.test.js +157 -0
- package/src/lib/project/index.js +40 -0
- package/src/lib/project/paths.js +224 -0
- package/src/lib/project/version.js +110 -0
- package/src/lib/project/version.test.js +350 -0
- package/src/lib/reporter/README.md +211 -2
- package/src/lib/reporter/index.js +512 -0
- package/src/lib/reporter/index.test.js +593 -0
- package/src/main.js +134 -47
- package/src/main.spec.js +61 -0
- package/src/main.test.js +347 -0
- package/src/validators/utils.js +2 -1
- package/src/commands/conf.js +0 -43
- package/src/commands/version.js +0 -43
- package/src/lib/11ty/paths.js +0 -103
- package/src/lib/i18n/README.md +0 -3
- package/src/lib/i18n/config.js +0 -53
- package/src/lib/i18n/index.js +0 -43
- package/src/lib/i18n/localeService.js +0 -58
- package/src/lib/quire/README.md +0 -19
- package/src/lib/quire/index.js +0 -350
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import test from 'ava'
|
|
2
|
+
import { Volume, createFsFromVolume } from 'memfs'
|
|
3
|
+
import esmock from 'esmock'
|
|
4
|
+
|
|
5
|
+
test.beforeEach((t) => {
|
|
6
|
+
// Create in-memory file system
|
|
7
|
+
t.context.vol = new Volume()
|
|
8
|
+
t.context.fs = createFsFromVolume(t.context.vol)
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
test.afterEach.always((t) => {
|
|
12
|
+
// Clear in-memory file system
|
|
13
|
+
t.context.vol.reset()
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
test('detect should recognize .eleventy.js marker file', async (t) => {
|
|
17
|
+
const { fs, vol } = t.context
|
|
18
|
+
|
|
19
|
+
// Setup a Quire project directory with .eleventy.js
|
|
20
|
+
vol.fromJSON({
|
|
21
|
+
'/quire-project/.eleventy.js': 'module.exports = function() {}',
|
|
22
|
+
'/quire-project/content/_data/config.yaml': 'title: Test Project'
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
// Mock node:fs to use memfs
|
|
26
|
+
const detect = await esmock('./detect.js', {
|
|
27
|
+
'node:fs': fs
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
const result = detect('/quire-project')
|
|
31
|
+
|
|
32
|
+
t.truthy(result, 'should return truthy value for directory with .eleventy.js')
|
|
33
|
+
t.is(result, '.eleventy.js', 'should return the marker file name')
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
test('detect should recognize eleventy.config.js marker file', async (t) => {
|
|
37
|
+
const { fs, vol } = t.context
|
|
38
|
+
|
|
39
|
+
// Setup a Quire project directory with eleventy.config.js
|
|
40
|
+
vol.fromJSON({
|
|
41
|
+
'/quire-project/eleventy.config.js': 'module.exports = function() {}',
|
|
42
|
+
'/quire-project/content/_data/config.yaml': 'title: Test Project'
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
// Mock node:fs to use memfs
|
|
46
|
+
const detect = await esmock('./detect.js', {
|
|
47
|
+
'node:fs': fs
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
const result = detect('/quire-project')
|
|
51
|
+
|
|
52
|
+
t.truthy(result, 'should return truthy value for directory with eleventy.config.js')
|
|
53
|
+
t.is(result, 'eleventy.config.js', 'should return the marker file name')
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
test('detect should recognize .quire marker file', async (t) => {
|
|
57
|
+
const { fs, vol } = t.context
|
|
58
|
+
|
|
59
|
+
// Setup a Quire project directory with .quire marker
|
|
60
|
+
vol.fromJSON({
|
|
61
|
+
'/quire-project/.quire': '',
|
|
62
|
+
'/quire-project/content/index.md': '# Welcome'
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
// Mock node:fs to use memfs
|
|
66
|
+
const detect = await esmock('./detect.js', {
|
|
67
|
+
'node:fs': fs
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
const result = detect('/quire-project')
|
|
71
|
+
|
|
72
|
+
t.truthy(result, 'should return truthy value for directory with .quire')
|
|
73
|
+
t.is(result, '.quire', 'should return the marker file name')
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
test('detect should recognize .quire-11ty marker file', async (t) => {
|
|
77
|
+
const { fs, vol } = t.context
|
|
78
|
+
|
|
79
|
+
// Setup a Quire project directory with .quire-11ty marker
|
|
80
|
+
vol.fromJSON({
|
|
81
|
+
'/quire-project/.quire-11ty': '',
|
|
82
|
+
'/quire-project/content/index.md': '# Welcome'
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
// Mock node:fs to use memfs
|
|
86
|
+
const detect = await esmock('./detect.js', {
|
|
87
|
+
'node:fs': fs
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
const result = detect('/quire-project')
|
|
91
|
+
|
|
92
|
+
t.truthy(result, 'should return truthy value for directory with .quire-11ty')
|
|
93
|
+
t.is(result, '.quire-11ty', 'should return the marker file name')
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
test('detect should recognize .quire-version marker file', async (t) => {
|
|
97
|
+
const { fs, vol } = t.context
|
|
98
|
+
|
|
99
|
+
// Setup a Quire project directory with .quire-version marker
|
|
100
|
+
vol.fromJSON({
|
|
101
|
+
'/quire-project/.quire-version': '1.0.0',
|
|
102
|
+
'/quire-project/content/index.md': '# Welcome'
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
// Mock node:fs to use memfs
|
|
106
|
+
const detect = await esmock('./detect.js', {
|
|
107
|
+
'node:fs': fs
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
const result = detect('/quire-project')
|
|
111
|
+
|
|
112
|
+
t.truthy(result, 'should return truthy value for directory with .quire-version')
|
|
113
|
+
t.is(result, '.quire-version', 'should return the marker file name')
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
test('detect should return falsy for non-Quire directory', async (t) => {
|
|
117
|
+
const { fs, vol } = t.context
|
|
118
|
+
|
|
119
|
+
// Setup a non-Quire directory (no marker files)
|
|
120
|
+
vol.fromJSON({
|
|
121
|
+
'/non-quire-directory/some-file.txt': 'not a quire project',
|
|
122
|
+
'/non-quire-directory/package.json': JSON.stringify({ name: 'some-other-project' })
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
// Mock node:fs to use memfs
|
|
126
|
+
const detect = await esmock('./detect.js', {
|
|
127
|
+
'node:fs': fs
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
const result = detect('/non-quire-directory')
|
|
131
|
+
|
|
132
|
+
t.falsy(result, 'should return falsy value for directory without marker files')
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
test('detect should return first marker file found when multiple exist', async (t) => {
|
|
136
|
+
const { fs, vol } = t.context
|
|
137
|
+
|
|
138
|
+
// Setup a Quire project directory with multiple markers
|
|
139
|
+
vol.fromJSON({
|
|
140
|
+
'/quire-project/.eleventy.js': 'module.exports = function() {}',
|
|
141
|
+
'/quire-project/.quire': '',
|
|
142
|
+
'/quire-project/.quire-version': '1.0.0'
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
// Mock node:fs to use memfs
|
|
146
|
+
const detect = await esmock('./detect.js', {
|
|
147
|
+
'node:fs': fs
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
const result = detect('/quire-project')
|
|
151
|
+
|
|
152
|
+
t.truthy(result, 'should return truthy value for directory with multiple markers')
|
|
153
|
+
t.true(
|
|
154
|
+
['.eleventy.js', '.quire', '.quire-11ty', '.quire-version', 'eleventy.config.js'].includes(result),
|
|
155
|
+
'should return one of the valid marker file names'
|
|
156
|
+
)
|
|
157
|
+
})
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project module
|
|
3
|
+
*
|
|
4
|
+
* Provides project-level concerns including paths, detection, configuration,
|
|
5
|
+
* build status, and version management.
|
|
6
|
+
*/
|
|
7
|
+
import paths, { Paths } from './paths.js'
|
|
8
|
+
import detect from './detect.js'
|
|
9
|
+
import { loadProjectConfig } from './config.js'
|
|
10
|
+
import {
|
|
11
|
+
getBuildInfo,
|
|
12
|
+
hasEpubOutput,
|
|
13
|
+
hasPdfOutput,
|
|
14
|
+
hasSiteOutput,
|
|
15
|
+
requireBuildOutput,
|
|
16
|
+
} from './build.js'
|
|
17
|
+
import {
|
|
18
|
+
getVersion,
|
|
19
|
+
setVersion,
|
|
20
|
+
getVersionsFromStarter,
|
|
21
|
+
readVersionFile,
|
|
22
|
+
writeVersionFile,
|
|
23
|
+
} from './version.js'
|
|
24
|
+
|
|
25
|
+
export {
|
|
26
|
+
detect,
|
|
27
|
+
getBuildInfo,
|
|
28
|
+
hasEpubOutput,
|
|
29
|
+
hasPdfOutput,
|
|
30
|
+
hasSiteOutput,
|
|
31
|
+
loadProjectConfig,
|
|
32
|
+
paths as default,
|
|
33
|
+
Paths,
|
|
34
|
+
requireBuildOutput,
|
|
35
|
+
getVersion,
|
|
36
|
+
setVersion,
|
|
37
|
+
getVersionsFromStarter,
|
|
38
|
+
readVersionFile,
|
|
39
|
+
writeVersionFile,
|
|
40
|
+
}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { fileURLToPath } from 'node:url'
|
|
2
|
+
import fs from 'fs-extra'
|
|
3
|
+
import path from 'node:path'
|
|
4
|
+
|
|
5
|
+
const __filename = fileURLToPath(import.meta.url)
|
|
6
|
+
const __dirname = path.dirname(__filename)
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Project path configuration
|
|
10
|
+
*
|
|
11
|
+
* Provides accessor methods for project paths, computing values on access
|
|
12
|
+
* to ensure they reflect the current working directory state.
|
|
13
|
+
*
|
|
14
|
+
* Naming convention:
|
|
15
|
+
* - methods ending in `Path` or `Root` return absolute paths
|
|
16
|
+
* - methods ending in `Dir` return relative directory names
|
|
17
|
+
*
|
|
18
|
+
* @see https://www.11ty.dev/docs/config/#configuration-options
|
|
19
|
+
*/
|
|
20
|
+
class Paths {
|
|
21
|
+
/**
|
|
22
|
+
* @param {Object} options
|
|
23
|
+
* @param {string} [options.version='latest'] - quire-11ty version to use
|
|
24
|
+
*/
|
|
25
|
+
constructor(options = {}) {
|
|
26
|
+
this.cliRoot = path.resolve(__dirname, '..')
|
|
27
|
+
this.eleventyConfig = '.eleventy.js'
|
|
28
|
+
this.version = options.version || 'latest'
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
32
|
+
// Implicit getters for domain-specific grouping of paths
|
|
33
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Eleventy configuration paths
|
|
37
|
+
*/
|
|
38
|
+
get eleventy() {
|
|
39
|
+
return {
|
|
40
|
+
config: this.getConfigPath(),
|
|
41
|
+
data: this.getDataDir(),
|
|
42
|
+
includes: this.getIncludesDir(),
|
|
43
|
+
input: this.getInputDir(),
|
|
44
|
+
layouts: this.getLayoutsDir(),
|
|
45
|
+
output: this.getOutputDir(),
|
|
46
|
+
root: this.getEleventyRoot(),
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Output format-specific paths
|
|
52
|
+
*/
|
|
53
|
+
get output() {
|
|
54
|
+
return {
|
|
55
|
+
site: this.getOutputDir(),
|
|
56
|
+
epub: this.getEpubDir(),
|
|
57
|
+
public: this.getPublicDir(),
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Project root paths (general)
|
|
63
|
+
*/
|
|
64
|
+
get project() {
|
|
65
|
+
return {
|
|
66
|
+
content: this.getInputPath(),
|
|
67
|
+
root: this.getProjectRoot(),
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
72
|
+
// Absolute paths (method names ends with Path or Root)
|
|
73
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Get the absolute path to eleventy config module
|
|
77
|
+
* @returns {string} Absolute path to .eleventy.js
|
|
78
|
+
*/
|
|
79
|
+
getConfigPath() {
|
|
80
|
+
return path.join(this.getEleventyRoot(), this.eleventyConfig)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Get the Eleventy root directory
|
|
85
|
+
*
|
|
86
|
+
* @todo refactor how and *when* the eleventyRoot is determined:
|
|
87
|
+
* - we only need eleventyRoot for cli commands that run 11ty
|
|
88
|
+
* - paths module is a concern of the `quire` module
|
|
89
|
+
* - global quire-cli installation
|
|
90
|
+
* - local quire-cli installation
|
|
91
|
+
*
|
|
92
|
+
* @returns {string} Absolute path to Eleventy root
|
|
93
|
+
*/
|
|
94
|
+
getEleventyRoot() {
|
|
95
|
+
return this.getProjectRoot()
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Get the absolute path to content input directory
|
|
100
|
+
* @returns {string} Absolute path to content directory
|
|
101
|
+
*/
|
|
102
|
+
getInputPath() {
|
|
103
|
+
return path.join(this.getProjectRoot(), 'content')
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Get the path to installed quire-11ty version
|
|
108
|
+
* @returns {string} Absolute path to quire-11ty installation
|
|
109
|
+
*/
|
|
110
|
+
getLibQuirePath() {
|
|
111
|
+
return path.resolve(
|
|
112
|
+
__dirname,
|
|
113
|
+
path.join(this.cliRoot, 'lib', 'quire', 'versions', this.version)
|
|
114
|
+
)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Get the current project root directory
|
|
119
|
+
* @returns {string} Absolute path to project root
|
|
120
|
+
*/
|
|
121
|
+
getProjectRoot() {
|
|
122
|
+
return process.cwd()
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
126
|
+
// Relative directory names (method names ends with Dir)
|
|
127
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Get data directory relative to input
|
|
131
|
+
* @returns {string} Relative directory name for computed data
|
|
132
|
+
*/
|
|
133
|
+
getDataDir() {
|
|
134
|
+
return '_computed'
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Get epub output directory relative to eleventy config
|
|
139
|
+
* @returns {string} Relative directory name for epub output (_epub)
|
|
140
|
+
*/
|
|
141
|
+
getEpubDir() {
|
|
142
|
+
return path.relative(
|
|
143
|
+
this.getEleventyRoot(),
|
|
144
|
+
path.join(this.getProjectRoot(), '_epub')
|
|
145
|
+
)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Get includes directory relative to input
|
|
150
|
+
* @returns {string} Relative directory name for _includes
|
|
151
|
+
*/
|
|
152
|
+
getIncludesDir() {
|
|
153
|
+
return path.relative(
|
|
154
|
+
this.getInputPath(),
|
|
155
|
+
path.join(this.getEleventyRoot(), '_includes')
|
|
156
|
+
)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Get input directory relative to eleventy config
|
|
161
|
+
* @returns {string} Relative directory name for 11ty input
|
|
162
|
+
*/
|
|
163
|
+
getInputDir() {
|
|
164
|
+
return path.relative(this.getEleventyRoot(), this.getInputPath())
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Get layouts directory relative to input
|
|
169
|
+
* @returns {string} Relative directory name for _layouts
|
|
170
|
+
*/
|
|
171
|
+
getLayoutsDir() {
|
|
172
|
+
return path.relative(
|
|
173
|
+
this.getInputPath(),
|
|
174
|
+
path.join(this.getEleventyRoot(), '_layouts')
|
|
175
|
+
)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Get output directory relative to eleventy config
|
|
180
|
+
* @returns {string} Relative directory name for 11ty output (_site)
|
|
181
|
+
*/
|
|
182
|
+
getOutputDir() {
|
|
183
|
+
return path.relative(
|
|
184
|
+
this.getEleventyRoot(),
|
|
185
|
+
path.join(this.getProjectRoot(), '_site')
|
|
186
|
+
)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Get public assets directory
|
|
191
|
+
* @returns {string} Relative directory name for public assets
|
|
192
|
+
*/
|
|
193
|
+
getPublicDir() {
|
|
194
|
+
return './public'
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
198
|
+
// Utility methods
|
|
199
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Get all paths as an object (for backward compatibility and logging)
|
|
203
|
+
* @returns {Object} Object containing all path values
|
|
204
|
+
*/
|
|
205
|
+
toObject() {
|
|
206
|
+
return {
|
|
207
|
+
config: this.getConfigPath(),
|
|
208
|
+
data: this.getDataDir(),
|
|
209
|
+
epub: this.getEpubDir(),
|
|
210
|
+
includes: this.getIncludesDir(),
|
|
211
|
+
input: this.getInputDir(),
|
|
212
|
+
layouts: this.getLayoutsDir(),
|
|
213
|
+
output: this.getOutputDir(),
|
|
214
|
+
public: this.getPublicDir(),
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Default Paths instance
|
|
221
|
+
*/
|
|
222
|
+
const paths = new Paths()
|
|
223
|
+
|
|
224
|
+
export { Paths, paths as default }
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project version module
|
|
3
|
+
*
|
|
4
|
+
* Manages quire-11ty version files in Quire projects.
|
|
5
|
+
*
|
|
6
|
+
* @module lib/project/version
|
|
7
|
+
*/
|
|
8
|
+
import fs from 'fs-extra'
|
|
9
|
+
import path from 'node:path'
|
|
10
|
+
import config from '#lib/conf/config.js'
|
|
11
|
+
import paths from './paths.js'
|
|
12
|
+
|
|
13
|
+
const PACKAGE_NAME = '@thegetty/quire-11ty'
|
|
14
|
+
const VERSION_FILE = config.get('versionFile')
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Read the required quire-11ty version from the project version file
|
|
18
|
+
*
|
|
19
|
+
* @param {string} [projectPath] - Absolute system path to the project root
|
|
20
|
+
* @returns {string} Quire-11ty semantic version
|
|
21
|
+
*/
|
|
22
|
+
export function getVersion(projectPath) {
|
|
23
|
+
projectPath = projectPath || paths.getProjectRoot()
|
|
24
|
+
const version = fs.readFileSync(path.join(projectPath, VERSION_FILE), { encoding: 'utf8' })
|
|
25
|
+
const projectName = path.basename(projectPath)
|
|
26
|
+
console.debug(`${projectName} set to use quire-11ty@${version}`)
|
|
27
|
+
return version
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Sets the quire-11ty version for a project
|
|
32
|
+
*
|
|
33
|
+
* Updates the version file with the new quire-11ty version while
|
|
34
|
+
* preserving other metadata (cli version, starter info).
|
|
35
|
+
*
|
|
36
|
+
* @param {string} version - A version identifier or distribution tag
|
|
37
|
+
* @param {string} [projectPath] - Absolute path to project root (defaults to cwd)
|
|
38
|
+
*/
|
|
39
|
+
export function setVersion(version, projectPath) {
|
|
40
|
+
projectPath = projectPath || paths.getProjectRoot()
|
|
41
|
+
const projectName = path.basename(projectPath)
|
|
42
|
+
const versionFilePath = path.join(projectPath, VERSION_FILE)
|
|
43
|
+
|
|
44
|
+
// Read existing version info or create new
|
|
45
|
+
let versionInfo = {}
|
|
46
|
+
if (fs.existsSync(versionFilePath)) {
|
|
47
|
+
const content = fs.readFileSync(versionFilePath, { encoding: 'utf8' })
|
|
48
|
+
try {
|
|
49
|
+
versionInfo = JSON.parse(content)
|
|
50
|
+
} catch {
|
|
51
|
+
// Legacy format or invalid JSON, start fresh
|
|
52
|
+
versionInfo = {}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Update the quire-11ty version
|
|
57
|
+
versionInfo.quire11ty = version
|
|
58
|
+
|
|
59
|
+
// Write updated version info
|
|
60
|
+
fs.writeFileSync(versionFilePath, JSON.stringify(versionInfo, null, 2))
|
|
61
|
+
console.info(`${projectName} set to use quire-11ty@${version}`)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Read required quire-11ty and starter versions from starter peerDependencies
|
|
66
|
+
*
|
|
67
|
+
* @param {string} projectPath - Absolute system path to the project root
|
|
68
|
+
* @returns {Promise<Object>}
|
|
69
|
+
* @property {string} quire11tyVersion - Latest compatible Quire-11ty semantic version
|
|
70
|
+
* @property {string} starterVersion - Starter project version from package.json
|
|
71
|
+
*/
|
|
72
|
+
export async function getVersionsFromStarter(projectPath) {
|
|
73
|
+
const projectPackageConfig = fs.readFileSync(
|
|
74
|
+
path.join(projectPath, 'package.json'),
|
|
75
|
+
{ encoding: 'utf8' }
|
|
76
|
+
)
|
|
77
|
+
const { peerDependencies, version: starterVersion } = JSON.parse(projectPackageConfig)
|
|
78
|
+
const quire11tyVersion = peerDependencies[PACKAGE_NAME]
|
|
79
|
+
return { quire11tyVersion, starterVersion }
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Write version info to the project version file
|
|
84
|
+
*
|
|
85
|
+
* @param {string} projectPath - Absolute system path to the project root
|
|
86
|
+
* @param {Object} versionInfo - Version information to write
|
|
87
|
+
*/
|
|
88
|
+
export function writeVersionFile(projectPath, versionInfo) {
|
|
89
|
+
fs.writeFileSync(path.join(projectPath, VERSION_FILE), JSON.stringify(versionInfo))
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Read version info from the project version file
|
|
94
|
+
*
|
|
95
|
+
* @param {string} projectPath - Absolute system path to the project root
|
|
96
|
+
* @returns {Object|null} Parsed version info or null if file doesn't exist
|
|
97
|
+
*/
|
|
98
|
+
export function readVersionFile(projectPath) {
|
|
99
|
+
const versionFilePath = path.join(projectPath, VERSION_FILE)
|
|
100
|
+
if (!fs.existsSync(versionFilePath)) {
|
|
101
|
+
return null
|
|
102
|
+
}
|
|
103
|
+
const content = fs.readFileSync(versionFilePath, { encoding: 'utf8' })
|
|
104
|
+
try {
|
|
105
|
+
return JSON.parse(content)
|
|
106
|
+
} catch {
|
|
107
|
+
// Legacy format: plain version string
|
|
108
|
+
return { version: content.trim() }
|
|
109
|
+
}
|
|
110
|
+
}
|