@thegetty/quire-cli 1.0.0-rc.44 → 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.
Files changed (243) hide show
  1. package/CHANGELOG.md +0 -36
  2. package/README.md +0 -9
  3. package/bin/cli.js +1 -46
  4. package/package.json +9 -25
  5. package/src/Command.js +6 -26
  6. package/src/commands/README.md +122 -213
  7. package/src/commands/build.js +37 -45
  8. package/src/commands/clean.js +19 -33
  9. package/src/commands/conf.js +43 -0
  10. package/src/commands/create.js +14 -42
  11. package/src/commands/epub.js +31 -67
  12. package/src/commands/index.js +2 -9
  13. package/src/commands/info.js +86 -88
  14. package/src/commands/pdf.js +82 -63
  15. package/src/commands/preview.js +31 -32
  16. package/src/commands/validate.js +20 -64
  17. package/src/commands/version.js +43 -0
  18. package/src/errors/validation/validation-error.js +11 -20
  19. package/src/helpers/clean.js +1 -1
  20. package/src/helpers/is-quire.js +31 -0
  21. package/src/helpers/test-cwd.js +6 -5
  22. package/src/helpers/which.js +4 -10
  23. package/src/lib/11ty/README.md +19 -135
  24. package/src/lib/11ty/api.js +93 -235
  25. package/src/lib/11ty/cli.js +37 -112
  26. package/src/lib/11ty/index.js +5 -64
  27. package/src/lib/11ty/paths.js +103 -0
  28. package/src/lib/README.md +0 -330
  29. package/src/lib/conf/README.md +69 -86
  30. package/src/lib/conf/config.js +3 -5
  31. package/src/lib/conf/defaults.js +0 -65
  32. package/src/lib/conf/schema.js +9 -103
  33. package/src/lib/epub/README.md +2 -133
  34. package/src/lib/epub/epub.js +11 -36
  35. package/src/lib/epub/index.js +21 -111
  36. package/src/lib/epub/pandoc.js +4 -33
  37. package/src/lib/git/README.md +2 -151
  38. package/src/lib/git/index.js +13 -217
  39. package/src/lib/i18n/README.md +3 -0
  40. package/src/lib/i18n/config.js +53 -0
  41. package/src/lib/i18n/index.js +43 -0
  42. package/src/lib/i18n/localeService.js +58 -0
  43. package/src/lib/pdf/README.md +0 -131
  44. package/src/lib/pdf/index.js +21 -124
  45. package/src/lib/pdf/paged.js +52 -100
  46. package/src/lib/pdf/prince.js +37 -115
  47. package/src/lib/pdf/split.js +33 -61
  48. package/src/lib/quire/README.md +19 -0
  49. package/src/lib/quire/index.js +353 -0
  50. package/src/lib/reporter/README.md +2 -211
  51. package/src/lib/reporter/index.js +0 -607
  52. package/src/main.js +48 -221
  53. package/src/packageConfig.js +0 -17
  54. package/src/validators/utils.js +1 -2
  55. package/schemas/config.schema.json +0 -194
  56. package/schemas/figures.schema.json +0 -56
  57. package/schemas/layout.schema.json +0 -5
  58. package/schemas/objects.schema.json +0 -62
  59. package/schemas/publication.schema.json +0 -140
  60. package/schemas/references.schema.json +0 -29
  61. package/src/Command.spec.js +0 -99
  62. package/src/commands/build.spec.js +0 -113
  63. package/src/commands/build.test.js +0 -397
  64. package/src/commands/clean.spec.js +0 -118
  65. package/src/commands/clean.test.js +0 -382
  66. package/src/commands/config.js +0 -238
  67. package/src/commands/config.spec.js +0 -107
  68. package/src/commands/config.test.js +0 -845
  69. package/src/commands/create.spec.js +0 -112
  70. package/src/commands/create.test.js +0 -415
  71. package/src/commands/doctor.js +0 -251
  72. package/src/commands/doctor.spec.js +0 -115
  73. package/src/commands/doctor.test.js +0 -1409
  74. package/src/commands/epub.spec.js +0 -114
  75. package/src/commands/epub.test.js +0 -503
  76. package/src/commands/help.js +0 -60
  77. package/src/commands/help.test.js +0 -132
  78. package/src/commands/info.spec.js +0 -72
  79. package/src/commands/info.test.js +0 -512
  80. package/src/commands/pdf.spec.js +0 -114
  81. package/src/commands/pdf.test.js +0 -464
  82. package/src/commands/preview.spec.js +0 -97
  83. package/src/commands/preview.test.js +0 -250
  84. package/src/commands/use.js +0 -56
  85. package/src/commands/use.spec.js +0 -61
  86. package/src/commands/use.test.js +0 -280
  87. package/src/commands/validate.spec.js +0 -90
  88. package/src/commands/validate.test.js +0 -378
  89. package/src/commands/workflows.js +0 -70
  90. package/src/errors/build/build-failed-error.js +0 -19
  91. package/src/errors/build/config-field-missing-error.js +0 -20
  92. package/src/errors/build/config-file-not-found-error.js +0 -20
  93. package/src/errors/build/index.js +0 -11
  94. package/src/errors/help/help-topic-not-found-error.js +0 -30
  95. package/src/errors/help/index.js +0 -8
  96. package/src/errors/index.js +0 -58
  97. package/src/errors/input/index.js +0 -8
  98. package/src/errors/input/invalid-input-error.js +0 -21
  99. package/src/errors/install/dependency-install-error.js +0 -19
  100. package/src/errors/install/directory-not-empty-error.js +0 -25
  101. package/src/errors/install/index.js +0 -12
  102. package/src/errors/install/invalid-path-error.js +0 -31
  103. package/src/errors/install/invalid-starter-error.js +0 -27
  104. package/src/errors/install/version-not-found-error.js +0 -35
  105. package/src/errors/output/epub-generation-error.js +0 -19
  106. package/src/errors/output/index.js +0 -14
  107. package/src/errors/output/invalid-epub-library-error.js +0 -20
  108. package/src/errors/output/invalid-pdf-library-error.js +0 -20
  109. package/src/errors/output/missing-build-output-error.js +0 -21
  110. package/src/errors/output/pdf-generation-error.js +0 -24
  111. package/src/errors/output/tool-not-found-error.js +0 -37
  112. package/src/errors/project/index.js +0 -10
  113. package/src/errors/project/not-in-project-error.js +0 -20
  114. package/src/errors/project/project-create-error.js +0 -21
  115. package/src/errors/quire-error.js +0 -27
  116. package/src/errors/validation/index.js +0 -3
  117. package/src/errors/validation/unknown-config-key-error.js +0 -27
  118. package/src/errors/validation/unknown-config-operation-error.js +0 -24
  119. package/src/helpers/docs-url.js +0 -32
  120. package/src/helpers/pager.js +0 -59
  121. package/src/helpers/pager.test.js +0 -85
  122. package/src/helpers/suggest-similar.js +0 -124
  123. package/src/helpers/suggest-similar.test.js +0 -108
  124. package/src/helpers/test-cwd.test.js +0 -192
  125. package/src/lib/11ty/index.test.js +0 -655
  126. package/src/lib/commander/index.js +0 -103
  127. package/src/lib/commander/index.test.js +0 -86
  128. package/src/lib/commander/options.js +0 -237
  129. package/src/lib/commander/options.test.js +0 -205
  130. package/src/lib/conf/build-status.js +0 -103
  131. package/src/lib/conf/build-status.test.js +0 -247
  132. package/src/lib/conf/config.test.js +0 -281
  133. package/src/lib/conf/format.js +0 -60
  134. package/src/lib/conf/format.test.js +0 -106
  135. package/src/lib/conf/helpers.js +0 -91
  136. package/src/lib/conf/helpers.test.js +0 -136
  137. package/src/lib/conf/index.js +0 -22
  138. package/src/lib/constants.js +0 -28
  139. package/src/lib/doctor/README.md +0 -667
  140. package/src/lib/doctor/checks/environment/cli-version.js +0 -62
  141. package/src/lib/doctor/checks/environment/cli-version.test.js +0 -132
  142. package/src/lib/doctor/checks/environment/git-available.js +0 -77
  143. package/src/lib/doctor/checks/environment/git-available.test.js +0 -52
  144. package/src/lib/doctor/checks/environment/index.js +0 -13
  145. package/src/lib/doctor/checks/environment/node-version.js +0 -66
  146. package/src/lib/doctor/checks/environment/node-version.test.js +0 -17
  147. package/src/lib/doctor/checks/environment/npm-available.js +0 -66
  148. package/src/lib/doctor/checks/environment/npm-available.test.js +0 -52
  149. package/src/lib/doctor/checks/environment/os-info.js +0 -48
  150. package/src/lib/doctor/checks/environment/os-info.test.js +0 -81
  151. package/src/lib/doctor/checks/environment/runtime-info.js +0 -51
  152. package/src/lib/doctor/checks/environment/runtime-info.test.js +0 -132
  153. package/src/lib/doctor/checks/outputs/epub-output.js +0 -119
  154. package/src/lib/doctor/checks/outputs/epub-output.test.js +0 -277
  155. package/src/lib/doctor/checks/outputs/index.js +0 -10
  156. package/src/lib/doctor/checks/outputs/pdf-output.js +0 -144
  157. package/src/lib/doctor/checks/outputs/pdf-output.test.js +0 -377
  158. package/src/lib/doctor/checks/outputs/stale-build.js +0 -122
  159. package/src/lib/doctor/checks/outputs/stale-build.test.js +0 -282
  160. package/src/lib/doctor/checks/project/data-files.js +0 -56
  161. package/src/lib/doctor/checks/project/data-files.test.js +0 -125
  162. package/src/lib/doctor/checks/project/dependencies.js +0 -53
  163. package/src/lib/doctor/checks/project/dependencies.test.js +0 -71
  164. package/src/lib/doctor/checks/project/index.js +0 -11
  165. package/src/lib/doctor/checks/project/quire-11ty.js +0 -98
  166. package/src/lib/doctor/checks/project/quire-11ty.test.js +0 -170
  167. package/src/lib/doctor/checks/project/quire-project.js +0 -38
  168. package/src/lib/doctor/checks/project/quire-project.test.js +0 -47
  169. package/src/lib/doctor/checks/tools/index.js +0 -10
  170. package/src/lib/doctor/checks/tools/pandoc-available.js +0 -82
  171. package/src/lib/doctor/checks/tools/pandoc-available.test.js +0 -73
  172. package/src/lib/doctor/checks/tools/prince-available.js +0 -81
  173. package/src/lib/doctor/checks/tools/prince-available.test.js +0 -73
  174. package/src/lib/doctor/constants.js +0 -39
  175. package/src/lib/doctor/formatDuration.js +0 -108
  176. package/src/lib/doctor/formatDuration.test.js +0 -76
  177. package/src/lib/doctor/formatters/human.js +0 -257
  178. package/src/lib/doctor/formatters/human.test.js +0 -463
  179. package/src/lib/doctor/formatters/index.js +0 -8
  180. package/src/lib/doctor/formatters/json.js +0 -78
  181. package/src/lib/doctor/formatters/json.test.js +0 -174
  182. package/src/lib/doctor/formatters/shared.js +0 -129
  183. package/src/lib/doctor/formatters/shared.test.js +0 -194
  184. package/src/lib/doctor/index.js +0 -271
  185. package/src/lib/doctor/index.test.js +0 -797
  186. package/src/lib/epub/engines.js +0 -46
  187. package/src/lib/epub/index.test.js +0 -518
  188. package/src/lib/epub/pandoc.test.js +0 -122
  189. package/src/lib/epub/schema.js +0 -21
  190. package/src/lib/error/README.md +0 -170
  191. package/src/lib/error/handler.js +0 -107
  192. package/src/lib/git/index.spec.js +0 -80
  193. package/src/lib/git/index.test.js +0 -453
  194. package/src/lib/help/frontmatter.js +0 -77
  195. package/src/lib/help/frontmatter.test.js +0 -139
  196. package/src/lib/help/index.js +0 -146
  197. package/src/lib/help/index.test.js +0 -188
  198. package/src/lib/help/topics/configuration.md +0 -77
  199. package/src/lib/help/topics/debugging.md +0 -69
  200. package/src/lib/help/topics/epub.md +0 -74
  201. package/src/lib/help/topics/pdf.md +0 -74
  202. package/src/lib/help/topics/publishing.md +0 -80
  203. package/src/lib/help/topics/workflows.md +0 -50
  204. package/src/lib/installer/index.js +0 -309
  205. package/src/lib/installer/index.spec.js +0 -83
  206. package/src/lib/installer/index.test.js +0 -545
  207. package/src/lib/logger/README.md +0 -424
  208. package/src/lib/logger/debug.js +0 -132
  209. package/src/lib/logger/debug.spec.js +0 -130
  210. package/src/lib/logger/debug.test.js +0 -128
  211. package/src/lib/logger/index.js +0 -228
  212. package/src/lib/logger/index.spec.js +0 -131
  213. package/src/lib/logger/index.test.js +0 -578
  214. package/src/lib/npm/README.md +0 -127
  215. package/src/lib/npm/index.js +0 -198
  216. package/src/lib/npm/index.spec.js +0 -60
  217. package/src/lib/npm/index.test.js +0 -355
  218. package/src/lib/pdf/engines.js +0 -46
  219. package/src/lib/pdf/index.test.js +0 -708
  220. package/src/lib/pdf/paged.test.js +0 -366
  221. package/src/lib/pdf/prince.test.js +0 -202
  222. package/src/lib/pdf/schema.js +0 -21
  223. package/src/lib/pdf/split.test.js +0 -445
  224. package/src/lib/platform.js +0 -95
  225. package/src/lib/process/manager.js +0 -110
  226. package/src/lib/process/manager.test.js +0 -55
  227. package/src/lib/project/build.js +0 -162
  228. package/src/lib/project/build.test.js +0 -275
  229. package/src/lib/project/config.js +0 -48
  230. package/src/lib/project/config.test.js +0 -134
  231. package/src/lib/project/detect.js +0 -47
  232. package/src/lib/project/detect.test.js +0 -157
  233. package/src/lib/project/index.js +0 -56
  234. package/src/lib/project/output-paths.js +0 -87
  235. package/src/lib/project/output-paths.test.js +0 -66
  236. package/src/lib/project/paths.js +0 -272
  237. package/src/lib/project/version.js +0 -110
  238. package/src/lib/project/version.test.js +0 -350
  239. package/src/lib/reporter/index.test.js +0 -862
  240. package/src/main.spec.js +0 -61
  241. package/src/main.test.js +0 -347
  242. package/src/validators/validate-data-files.js +0 -154
  243. package/src/validators/validate-data-files.test.js +0 -217
@@ -1,62 +0,0 @@
1
- /**
2
- * Quire CLI version check
3
- *
4
- * @module lib/doctor/checks/environment/cli-version
5
- */
6
- import updateNotifier from 'update-notifier'
7
- import packageConfig from '#src/packageConfig.js'
8
- import config from '#lib/conf/config.js'
9
- import createDebug from '#debug'
10
- import { DOCS_BASE_URL } from '#lib/doctor/constants.js'
11
-
12
- const debug = createDebug('lib:doctor:cli-version')
13
-
14
- /**
15
- * Check Quire CLI version and report if an update is available
16
- *
17
- * Uses the cached update info from update-notifier (which checks in background
18
- * on CLI startup) to avoid blocking the doctor command with network requests.
19
- *
20
- * @returns {import('../../index.js').CheckResult}
21
- */
22
- export function checkCliVersion() {
23
- const current = packageConfig.version
24
- debug('Current CLI version: %s', current)
25
-
26
- // Access cached update info from update-notifier
27
- // Using a high updateCheckInterval prevents triggering a new check,
28
- // we just want to read the cached result from the CLI startup check
29
- const updateChannel = config.get('updateChannel') || 'rc'
30
- const notifier = updateNotifier({
31
- pkg: packageConfig,
32
- distTag: updateChannel,
33
- updateCheckInterval: Number.MAX_SAFE_INTEGER, // Don't trigger new check
34
- })
35
-
36
- debug('Cached update info: %o', notifier.update)
37
-
38
- // Check if an update is available
39
- if (notifier.update && notifier.update.latest !== current) {
40
- const { latest } = notifier.update
41
- debug('Update available: %s -> %s', current, latest)
42
-
43
- return {
44
- ok: false,
45
- level: 'warn',
46
- message: `v${current} installed, v${latest} available`,
47
- remediation: `Update Quire CLI to the latest version:
48
- • npm install -g @thegetty/quire-cli@${latest}
49
- • Or update via your package manager if installed differently`,
50
- docsUrl: `${DOCS_BASE_URL}/install-uninstall/`,
51
- }
52
- }
53
-
54
- // No update info or already up to date
55
- const upToDateSuffix = notifier.update ? ' (up to date)' : ''
56
- return {
57
- ok: true,
58
- message: `v${current}${upToDateSuffix}`,
59
- }
60
- }
61
-
62
- export default checkCliVersion
@@ -1,132 +0,0 @@
1
- import test from 'ava'
2
- import sinon from 'sinon'
3
- import esmock from 'esmock'
4
-
5
- test.beforeEach((t) => {
6
- t.context.sandbox = sinon.createSandbox()
7
- })
8
-
9
- test.afterEach.always((t) => {
10
- t.context.sandbox.restore()
11
- })
12
-
13
- test('checkCliVersion returns ok with version when up to date', async (t) => {
14
- const { sandbox } = t.context
15
-
16
- const mockUpdateNotifier = sandbox.stub().returns({
17
- update: { current: '1.0.0-rc.33', latest: '1.0.0-rc.33', type: 'latest' },
18
- })
19
-
20
- const { checkCliVersion } = await esmock('./cli-version.js', {
21
- 'update-notifier': { default: mockUpdateNotifier },
22
- '#src/packageConfig.js': { default: { name: '@thegetty/quire-cli', version: '1.0.0-rc.33' } },
23
- '#lib/conf/config.js': { default: { get: sandbox.stub().returns('rc') } },
24
- })
25
-
26
- const result = checkCliVersion()
27
-
28
- t.true(result.ok)
29
- t.regex(result.message, /v1\.0\.0-rc\.33/)
30
- t.regex(result.message, /up to date/)
31
- })
32
-
33
- test('checkCliVersion returns warning when update is available', async (t) => {
34
- const { sandbox } = t.context
35
-
36
- const mockUpdateNotifier = sandbox.stub().returns({
37
- update: { current: '1.0.0-rc.30', latest: '1.0.0-rc.33', type: 'prerelease' },
38
- })
39
-
40
- const { checkCliVersion } = await esmock('./cli-version.js', {
41
- 'update-notifier': { default: mockUpdateNotifier },
42
- '#src/packageConfig.js': { default: { name: '@thegetty/quire-cli', version: '1.0.0-rc.30' } },
43
- '#lib/conf/config.js': { default: { get: sandbox.stub().returns('rc') } },
44
- })
45
-
46
- const result = checkCliVersion()
47
-
48
- t.false(result.ok)
49
- t.is(result.level, 'warn')
50
- t.regex(result.message, /v1\.0\.0-rc\.30 installed/)
51
- t.regex(result.message, /v1\.0\.0-rc\.33 available/)
52
- t.truthy(result.remediation)
53
- t.regex(result.remediation, /npm install/)
54
- t.truthy(result.docsUrl)
55
- })
56
-
57
- test('checkCliVersion returns ok without "up to date" when no cached update info', async (t) => {
58
- const { sandbox } = t.context
59
-
60
- // No cached update info (first run or cache cleared)
61
- const mockUpdateNotifier = sandbox.stub().returns({
62
- update: undefined,
63
- })
64
-
65
- const { checkCliVersion } = await esmock('./cli-version.js', {
66
- 'update-notifier': { default: mockUpdateNotifier },
67
- '#src/packageConfig.js': { default: { name: '@thegetty/quire-cli', version: '1.0.0-rc.33' } },
68
- '#lib/conf/config.js': { default: { get: sandbox.stub().returns('rc') } },
69
- })
70
-
71
- const result = checkCliVersion()
72
-
73
- t.true(result.ok)
74
- t.is(result.message, 'v1.0.0-rc.33')
75
- t.notRegex(result.message, /up to date/)
76
- })
77
-
78
- test('checkCliVersion uses configured updateChannel', async (t) => {
79
- const { sandbox } = t.context
80
-
81
- const mockUpdateNotifier = sandbox.stub().returns({ update: undefined })
82
- const mockConfigGet = sandbox.stub().returns('latest')
83
-
84
- const { checkCliVersion } = await esmock('./cli-version.js', {
85
- 'update-notifier': { default: mockUpdateNotifier },
86
- '#src/packageConfig.js': { default: { name: '@thegetty/quire-cli', version: '1.0.0' } },
87
- '#lib/conf/config.js': { default: { get: mockConfigGet } },
88
- })
89
-
90
- checkCliVersion()
91
-
92
- t.true(mockUpdateNotifier.calledOnce)
93
- const callArgs = mockUpdateNotifier.firstCall.args[0]
94
- t.is(callArgs.distTag, 'latest')
95
- })
96
-
97
- test('checkCliVersion defaults to rc channel when config returns undefined', async (t) => {
98
- const { sandbox } = t.context
99
-
100
- const mockUpdateNotifier = sandbox.stub().returns({ update: undefined })
101
- const mockConfigGet = sandbox.stub().returns(undefined)
102
-
103
- const { checkCliVersion } = await esmock('./cli-version.js', {
104
- 'update-notifier': { default: mockUpdateNotifier },
105
- '#src/packageConfig.js': { default: { name: '@thegetty/quire-cli', version: '1.0.0' } },
106
- '#lib/conf/config.js': { default: { get: mockConfigGet } },
107
- })
108
-
109
- checkCliVersion()
110
-
111
- t.true(mockUpdateNotifier.calledOnce)
112
- const callArgs = mockUpdateNotifier.firstCall.args[0]
113
- t.is(callArgs.distTag, 'rc')
114
- })
115
-
116
- test('checkCliVersion remediation includes latest version number', async (t) => {
117
- const { sandbox } = t.context
118
-
119
- const mockUpdateNotifier = sandbox.stub().returns({
120
- update: { current: '1.0.0-rc.30', latest: '1.0.0-rc.35', type: 'prerelease' },
121
- })
122
-
123
- const { checkCliVersion } = await esmock('./cli-version.js', {
124
- 'update-notifier': { default: mockUpdateNotifier },
125
- '#src/packageConfig.js': { default: { name: '@thegetty/quire-cli', version: '1.0.0-rc.30' } },
126
- '#lib/conf/config.js': { default: { get: sandbox.stub().returns('rc') } },
127
- })
128
-
129
- const result = checkCliVersion()
130
-
131
- t.regex(result.remediation, /@thegetty\/quire-cli@1\.0\.0-rc\.35/)
132
- })
@@ -1,77 +0,0 @@
1
- /**
2
- * Git availability check
3
- *
4
- * @module lib/doctor/checks/environment/git-available
5
- */
6
- import git from '#lib/git/index.js'
7
- import which from 'which'
8
- import createDebug from '#debug'
9
- import { getPlatform, Platform } from '#lib/platform.js'
10
- import { DOCS_BASE_URL } from '#lib/doctor/constants.js'
11
-
12
- const debug = createDebug('lib:doctor:git-available')
13
-
14
- /**
15
- * Get OS-specific Git installation instructions and docs URL
16
- * @returns {{ remediation: string, docsUrl: string }}
17
- */
18
- function getRemediationAndDocs() {
19
- const platform = getPlatform()
20
-
21
- switch (platform) {
22
- case Platform.MACOS:
23
- return {
24
- remediation: `Install Git:
25
- • Run: xcode-select --install
26
- • Or using Homebrew: brew install git`,
27
- docsUrl: `${DOCS_BASE_URL}/install-uninstall/#mac-os-installation`,
28
- }
29
- case Platform.WINDOWS:
30
- return {
31
- remediation: `Install Git for Windows:
32
- • Download from: https://git-scm.com/download/win
33
- • Or using winget: winget install Git.Git
34
- • Restart your terminal after installation`,
35
- docsUrl: `${DOCS_BASE_URL}/install-uninstall/#windows-installation`,
36
- }
37
- case Platform.LINUX:
38
- return {
39
- remediation: `Install Git:
40
- • Debian/Ubuntu: sudo apt-get install git
41
- • Fedora: sudo dnf install git
42
- • Arch: sudo pacman -S git`,
43
- docsUrl: `${DOCS_BASE_URL}/install-uninstall/#1-install-nodejs`,
44
- }
45
- default:
46
- return {
47
- remediation: 'Install Git from https://git-scm.com/',
48
- docsUrl: `${DOCS_BASE_URL}/install-uninstall/`,
49
- }
50
- }
51
- }
52
-
53
- /**
54
- * Check Git is available in PATH
55
- * @returns {Promise<import('../../index.js').CheckResult>}
56
- */
57
- export async function checkGitAvailable() {
58
- const ok = await git.isAvailable()
59
- debug('git available: %s', ok)
60
-
61
- if (ok) {
62
- const version = await git.version()
63
- const gitPath = which.sync('git', { nothrow: true })
64
- return { ok: true, message: version, details: gitPath }
65
- }
66
-
67
- const { remediation, docsUrl } = getRemediationAndDocs()
68
-
69
- return {
70
- ok: false,
71
- message: 'not found in PATH',
72
- remediation,
73
- docsUrl,
74
- }
75
- }
76
-
77
- export default checkGitAvailable
@@ -1,52 +0,0 @@
1
- import test from 'ava'
2
- import sinon from 'sinon'
3
- import esmock from 'esmock'
4
-
5
- test.beforeEach((t) => {
6
- t.context.sandbox = sinon.createSandbox()
7
- })
8
-
9
- test.afterEach.always((t) => {
10
- t.context.sandbox.restore()
11
- })
12
-
13
- test('checkGitAvailable returns ok when git is available', async (t) => {
14
- const { sandbox } = t.context
15
-
16
- const { checkGitAvailable } = await esmock('./git-available.js', {
17
- '#lib/git/index.js': {
18
- default: {
19
- isAvailable: sandbox.stub().resolves(true),
20
- version: sandbox.stub().resolves('2.43.0'),
21
- },
22
- },
23
- which: {
24
- sync: sandbox.stub().returns('/usr/bin/git'),
25
- },
26
- })
27
-
28
- const result = await checkGitAvailable()
29
-
30
- t.true(result.ok)
31
- t.is(result.message, '2.43.0')
32
- t.is(result.details, '/usr/bin/git')
33
- })
34
-
35
- test('checkGitAvailable returns not ok when git is missing', async (t) => {
36
- const { sandbox } = t.context
37
-
38
- const { checkGitAvailable } = await esmock('./git-available.js', {
39
- '#lib/git/index.js': {
40
- default: {
41
- isAvailable: sandbox.stub().resolves(false),
42
- },
43
- },
44
- })
45
-
46
- const result = await checkGitAvailable()
47
-
48
- t.false(result.ok)
49
- t.is(result.message, 'not found in PATH')
50
- t.truthy(result.remediation, 'should include remediation guidance')
51
- t.truthy(result.docsUrl, 'should include documentation link')
52
- })
@@ -1,13 +0,0 @@
1
- /**
2
- * Environment checks
3
- *
4
- * System prerequisites that must exist for Quire to function.
5
- *
6
- * @module lib/doctor/checks/environment
7
- */
8
- export { checkOsInfo } from './os-info.js'
9
- export { checkCliVersion } from './cli-version.js'
10
- export { checkNodeVersion } from './node-version.js'
11
- export { checkRuntimeInfo } from './runtime-info.js'
12
- export { checkNpmAvailable } from './npm-available.js'
13
- export { checkGitAvailable } from './git-available.js'
@@ -1,66 +0,0 @@
1
- /**
2
- * Node.js version check
3
- *
4
- * @module lib/doctor/checks/environment/node-version
5
- */
6
- import createDebug from '#debug'
7
- import { getPlatform, Platform } from '#lib/platform.js'
8
- import { DOCS_BASE_URL, REQUIRED_NODE_VERSION } from '#lib/doctor/constants.js'
9
-
10
- const debug = createDebug('lib:doctor:node-version')
11
-
12
- /**
13
- * Get OS-specific Node.js installation instructions
14
- * @returns {string}
15
- */
16
- function getRemediation() {
17
- const platform = getPlatform()
18
- const version = REQUIRED_NODE_VERSION
19
-
20
- switch (platform) {
21
- case Platform.MACOS:
22
- return `Install Node.js ${version} or later:
23
- • Using nvm (recommended): nvm install ${version} && nvm use ${version}
24
- • Using Homebrew: brew install node@${version}
25
- • Download from: https://nodejs.org/`
26
- case Platform.WINDOWS:
27
- return `Install Node.js ${version} or later:
28
- • Using nvm-windows: nvm install ${version} && nvm use ${version}
29
- • Download installer from: https://nodejs.org/
30
- • Using winget: winget install OpenJS.NodeJS.LTS`
31
- case Platform.LINUX:
32
- return `Install Node.js ${version} or later:
33
- • Using nvm (recommended): nvm install ${version} && nvm use ${version}
34
- • Using apt (Debian/Ubuntu): See https://nodejs.org/en/download/package-manager
35
- • Download from: https://nodejs.org/`
36
- default:
37
- return `Install Node.js ${version} or later from https://nodejs.org/`
38
- }
39
- }
40
-
41
- /**
42
- * Check Node.js version meets minimum requirement
43
- * @returns {import('../../index.js').CheckResult}
44
- */
45
- export function checkNodeVersion() {
46
- const current = parseInt(process.version.slice(1), 10)
47
- const ok = current >= REQUIRED_NODE_VERSION
48
- debug('Node.js version check: %s (required >= %d)', process.version, REQUIRED_NODE_VERSION)
49
-
50
- if (ok) {
51
- return {
52
- ok: true,
53
- message: `v${process.version.slice(1)} (>= ${REQUIRED_NODE_VERSION} required)`,
54
- details: process.execPath,
55
- }
56
- }
57
-
58
- return {
59
- ok: false,
60
- message: `v${process.version.slice(1)} found, but >= ${REQUIRED_NODE_VERSION} required`,
61
- remediation: getRemediation(),
62
- docsUrl: `${DOCS_BASE_URL}/install-uninstall/#1-install-nodejs`,
63
- }
64
- }
65
-
66
- export default checkNodeVersion
@@ -1,17 +0,0 @@
1
- import test from 'ava'
2
-
3
- test('checkNodeVersion returns ok when version meets requirement', async (t) => {
4
- const { checkNodeVersion } = await import('./node-version.js')
5
-
6
- const result = checkNodeVersion()
7
-
8
- // Current Node.js version should be >= 22 in dev environment
9
- t.is(typeof result.ok, 'boolean')
10
- t.is(typeof result.message, 'string')
11
- t.regex(result.message, /v\d+/)
12
-
13
- // When check passes, details should be the Node.js executable path
14
- if (result.ok) {
15
- t.is(result.details, process.execPath)
16
- }
17
- })
@@ -1,66 +0,0 @@
1
- /**
2
- * npm availability check
3
- *
4
- * @module lib/doctor/checks/environment/npm-available
5
- */
6
- import npm from '#lib/npm/index.js'
7
- import which from 'which'
8
- import createDebug from '#debug'
9
- import { getPlatform, Platform } from '#lib/platform.js'
10
- import { DOCS_BASE_URL } from '#lib/doctor/constants.js'
11
-
12
- const debug = createDebug('lib:doctor:npm-available')
13
-
14
- /**
15
- * Get OS-specific npm troubleshooting instructions
16
- * @returns {string}
17
- */
18
- function getRemediation() {
19
- const platform = getPlatform()
20
- const commonSteps = `npm is included with Node.js. Ensure Node.js is properly installed:
21
- • Verify installation: node --version`
22
-
23
- switch (platform) {
24
- case Platform.MACOS:
25
- return `${commonSteps}
26
- • If using nvm, run: nvm use default
27
- • Reinstall Node.js: brew reinstall node (or download from nodejs.org)`
28
- case Platform.WINDOWS:
29
- return `${commonSteps}
30
- • Restart your terminal after Node.js installation
31
- • Check PATH includes: %APPDATA%\\npm
32
- • Reinstall Node.js from: https://nodejs.org/`
33
- case Platform.LINUX:
34
- return `${commonSteps}
35
- • If using nvm, run: nvm use default
36
- • Check PATH includes Node.js bin directory
37
- • Reinstall Node.js from: https://nodejs.org/`
38
- default:
39
- return `${commonSteps}
40
- • Reinstall Node.js if needed: https://nodejs.org/`
41
- }
42
- }
43
-
44
- /**
45
- * Check npm is available in PATH
46
- * @returns {Promise<import('../../index.js').CheckResult>}
47
- */
48
- export async function checkNpmAvailable() {
49
- const ok = await npm.isAvailable()
50
- debug('npm available: %s', ok)
51
-
52
- if (ok) {
53
- const version = await npm.version()
54
- const npmPath = which.sync('npm', { nothrow: true })
55
- return { ok: true, message: version, details: npmPath }
56
- }
57
-
58
- return {
59
- ok: false,
60
- message: 'not found in PATH',
61
- remediation: getRemediation(),
62
- docsUrl: `${DOCS_BASE_URL}/install-uninstall/#1-install-nodejs`,
63
- }
64
- }
65
-
66
- export default checkNpmAvailable
@@ -1,52 +0,0 @@
1
- import test from 'ava'
2
- import sinon from 'sinon'
3
- import esmock from 'esmock'
4
-
5
- test.beforeEach((t) => {
6
- t.context.sandbox = sinon.createSandbox()
7
- })
8
-
9
- test.afterEach.always((t) => {
10
- t.context.sandbox.restore()
11
- })
12
-
13
- test('checkNpmAvailable returns ok when npm is available', async (t) => {
14
- const { sandbox } = t.context
15
-
16
- const { checkNpmAvailable } = await esmock('./npm-available.js', {
17
- '#lib/npm/index.js': {
18
- default: {
19
- isAvailable: sandbox.stub().resolves(true),
20
- version: sandbox.stub().resolves('10.2.4'),
21
- },
22
- },
23
- which: {
24
- sync: sandbox.stub().returns('/usr/local/bin/npm'),
25
- },
26
- })
27
-
28
- const result = await checkNpmAvailable()
29
-
30
- t.true(result.ok)
31
- t.is(result.message, '10.2.4')
32
- t.is(result.details, '/usr/local/bin/npm')
33
- })
34
-
35
- test('checkNpmAvailable returns not ok when npm is missing', async (t) => {
36
- const { sandbox } = t.context
37
-
38
- const { checkNpmAvailable } = await esmock('./npm-available.js', {
39
- '#lib/npm/index.js': {
40
- default: {
41
- isAvailable: sandbox.stub().resolves(false),
42
- },
43
- },
44
- })
45
-
46
- const result = await checkNpmAvailable()
47
-
48
- t.false(result.ok)
49
- t.is(result.message, 'not found in PATH')
50
- t.truthy(result.remediation, 'should include remediation guidance')
51
- t.truthy(result.docsUrl, 'should include documentation link')
52
- })
@@ -1,48 +0,0 @@
1
- /**
2
- * Operating system info check
3
- *
4
- * @module lib/doctor/checks/environment/os-info
5
- */
6
- import os from 'node:os'
7
- import { getPlatformName, getPlatform, Platform } from '#lib/platform.js'
8
- import createDebug from '#debug'
9
-
10
- const debug = createDebug('lib:doctor:os-info')
11
-
12
- /**
13
- * Report operating system information
14
- *
15
- * This is an informational check that always passes.
16
- * It provides context for other checks and helps with troubleshooting.
17
- *
18
- * @returns {import('../../index.js').CheckResult}
19
- */
20
- export function checkOsInfo() {
21
- const platform = getPlatform()
22
- const platformName = getPlatformName()
23
-
24
- const arch = os.arch()
25
- const cpuCount = os.cpus().length
26
- const totalMem = os.totalmem()
27
-
28
- debug('Platform: %s, Name: %s, Arch: %s', platform, platformName, arch)
29
-
30
- // Build informational message
31
- let message = `${platformName} (${arch})`
32
-
33
- // Add platform-specific notes
34
- if (platform === Platform.WINDOWS) {
35
- message += ' - Git for Windows recommended'
36
- }
37
-
38
- const memGB = (totalMem / 1024 / 1024 / 1024).toFixed(1)
39
- const details = `Memory: ${memGB} GB, CPUs: ${cpuCount}`
40
-
41
- return {
42
- ok: true,
43
- message,
44
- details,
45
- }
46
- }
47
-
48
- export default checkOsInfo
@@ -1,81 +0,0 @@
1
- import test from 'ava'
2
- import sinon from 'sinon'
3
- import esmock from 'esmock'
4
-
5
- test.beforeEach((t) => {
6
- t.context.sandbox = sinon.createSandbox()
7
- })
8
-
9
- test.afterEach.always((t) => {
10
- t.context.sandbox.restore()
11
- })
12
-
13
- test('checkOsInfo returns ok with platform info and details', async (t) => {
14
- const { sandbox } = t.context
15
-
16
- const { checkOsInfo } = await esmock('./os-info.js', {
17
- '#lib/platform.js': {
18
- getPlatform: sandbox.stub().returns('macos'),
19
- getPlatformName: sandbox.stub().returns('macOS 14'),
20
- Platform: { MACOS: 'macos', WINDOWS: 'windows', LINUX: 'linux' },
21
- },
22
- 'node:os': {
23
- arch: sandbox.stub().returns('arm64'),
24
- totalmem: sandbox.stub().returns(64 * 1024 * 1024 * 1024),
25
- cpus: sandbox.stub().returns(new Array(12)),
26
- },
27
- })
28
-
29
- const result = checkOsInfo()
30
-
31
- t.true(result.ok)
32
- t.regex(result.message, /macOS 14/)
33
- t.regex(result.message, /arm64/)
34
- t.is(result.details, 'Memory: 64.0 GB, CPUs: 12')
35
- })
36
-
37
- test('checkOsInfo adds Windows note on Windows', async (t) => {
38
- const { sandbox } = t.context
39
-
40
- const { checkOsInfo } = await esmock('./os-info.js', {
41
- '#lib/platform.js': {
42
- getPlatform: sandbox.stub().returns('windows'),
43
- getPlatformName: sandbox.stub().returns('Windows (10.0.22621)'),
44
- Platform: { MACOS: 'macos', WINDOWS: 'windows', LINUX: 'linux' },
45
- },
46
- 'node:os': {
47
- arch: sandbox.stub().returns('x64'),
48
- totalmem: sandbox.stub().returns(16 * 1024 * 1024 * 1024),
49
- cpus: sandbox.stub().returns(new Array(8)),
50
- },
51
- })
52
-
53
- const result = checkOsInfo()
54
-
55
- t.true(result.ok)
56
- t.regex(result.message, /Windows/)
57
- t.regex(result.message, /Git for Windows/)
58
- })
59
-
60
- test('checkOsInfo works on Linux', async (t) => {
61
- const { sandbox } = t.context
62
-
63
- const { checkOsInfo } = await esmock('./os-info.js', {
64
- '#lib/platform.js': {
65
- getPlatform: sandbox.stub().returns('linux'),
66
- getPlatformName: sandbox.stub().returns('Linux (5.15.0)'),
67
- Platform: { MACOS: 'macos', WINDOWS: 'windows', LINUX: 'linux' },
68
- },
69
- 'node:os': {
70
- arch: sandbox.stub().returns('x64'),
71
- totalmem: sandbox.stub().returns(32 * 1024 * 1024 * 1024),
72
- cpus: sandbox.stub().returns(new Array(4)),
73
- },
74
- })
75
-
76
- const result = checkOsInfo()
77
-
78
- t.true(result.ok)
79
- t.regex(result.message, /Linux/)
80
- t.notRegex(result.message, /Git for Windows/)
81
- })