@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.
- package/CHANGELOG.md +0 -36
- package/README.md +0 -9
- package/bin/cli.js +1 -46
- package/package.json +9 -25
- 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/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
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import test from 'ava'
|
|
2
|
-
import debug from 'debug'
|
|
3
|
-
// Import to register formatter and formatArgs overrides
|
|
4
|
-
import './debug.js'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Debug formatter and output tests
|
|
8
|
-
*
|
|
9
|
-
* Verifies the custom %O formatter produces indented multi-line output,
|
|
10
|
-
* the %o formatter remains compact single-line, and the formatArgs
|
|
11
|
-
* override prevents per-line namespace prefixing in colored output.
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Helper to call a debug formatter with a value
|
|
16
|
-
*
|
|
17
|
-
* Formatters are called with `this` bound to a debugger-like context.
|
|
18
|
-
* We provide the minimal context the formatters expect.
|
|
19
|
-
*/
|
|
20
|
-
function callFormatter(specifier, value) {
|
|
21
|
-
const formatter = debug.formatters[specifier]
|
|
22
|
-
const context = {
|
|
23
|
-
useColors: false,
|
|
24
|
-
inspectOpts: { colors: false },
|
|
25
|
-
}
|
|
26
|
-
return formatter.call(context, value)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
30
|
-
// %O formatter (pretty-printed, indented)
|
|
31
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
32
|
-
|
|
33
|
-
test('%O output starts with a newline', (t) => {
|
|
34
|
-
const result = callFormatter('O', { a: 1 })
|
|
35
|
-
t.true(result.startsWith('\n'))
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
test('%O output lines are indented with 2 spaces', (t) => {
|
|
39
|
-
const result = callFormatter('O', { a: 1, b: 2 })
|
|
40
|
-
const lines = result.split('\n').slice(1) // skip leading empty line
|
|
41
|
-
for (const line of lines) {
|
|
42
|
-
t.true(line.startsWith(' '), `Line not indented: "${line}"`)
|
|
43
|
-
}
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
test('%O formats nested objects with indentation', (t) => {
|
|
47
|
-
const result = callFormatter('O', { outer: { inner: 'value' } })
|
|
48
|
-
t.true(result.includes('outer'))
|
|
49
|
-
t.true(result.includes('inner'))
|
|
50
|
-
// Every line after the leading newline should be indented
|
|
51
|
-
const lines = result.split('\n').slice(1)
|
|
52
|
-
for (const line of lines) {
|
|
53
|
-
t.true(line.startsWith(' '), `Line not indented: "${line}"`)
|
|
54
|
-
}
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
test('%O handles null without error', (t) => {
|
|
58
|
-
const result = callFormatter('O', null)
|
|
59
|
-
t.true(result.includes('null'))
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
test('%O handles undefined without error', (t) => {
|
|
63
|
-
const result = callFormatter('O', undefined)
|
|
64
|
-
t.true(result.includes('undefined'))
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
test('%O handles primitive values', (t) => {
|
|
68
|
-
t.true(callFormatter('O', 42).includes('42'))
|
|
69
|
-
t.true(callFormatter('O', 'hello').includes('hello'))
|
|
70
|
-
t.true(callFormatter('O', true).includes('true'))
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
test('%O handles arrays', (t) => {
|
|
74
|
-
const result = callFormatter('O', [1, 2, 3])
|
|
75
|
-
t.true(result.includes('1'))
|
|
76
|
-
t.true(result.includes('2'))
|
|
77
|
-
t.true(result.includes('3'))
|
|
78
|
-
})
|
|
79
|
-
|
|
80
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
81
|
-
// %o formatter (compact single-line, built-in)
|
|
82
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
83
|
-
|
|
84
|
-
test('%o output is single-line', (t) => {
|
|
85
|
-
const result = callFormatter('o', { a: 1, b: 2, c: 3 })
|
|
86
|
-
t.false(result.includes('\n'))
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
test('%o does not start with a newline', (t) => {
|
|
90
|
-
const result = callFormatter('o', { a: 1 })
|
|
91
|
-
t.false(result.startsWith('\n'))
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
95
|
-
// formatArgs override (prefix only on first line)
|
|
96
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Helper to call formatArgs and capture the result
|
|
100
|
-
*
|
|
101
|
-
* Creates a minimal debugger-like context to test formatArgs behavior.
|
|
102
|
-
* In color mode, the default debug formatArgs would split on newlines
|
|
103
|
-
* and insert the prefix before every line. Our override prevents this.
|
|
104
|
-
*/
|
|
105
|
-
function callFormatArgs(message, useColors = true) {
|
|
106
|
-
const args = [message]
|
|
107
|
-
const context = {
|
|
108
|
-
namespace: 'test',
|
|
109
|
-
useColors,
|
|
110
|
-
color: 5,
|
|
111
|
-
diff: 0,
|
|
112
|
-
}
|
|
113
|
-
debug.formatArgs.call(context, args)
|
|
114
|
-
return args[0]
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
test('formatArgs prefixes the first line in color mode', (t) => {
|
|
118
|
-
const result = callFormatArgs('hello')
|
|
119
|
-
t.true(result.includes('test'))
|
|
120
|
-
t.true(result.includes('hello'))
|
|
121
|
-
})
|
|
122
|
-
|
|
123
|
-
test('formatArgs does not duplicate prefix on multi-line output', (t) => {
|
|
124
|
-
const result = callFormatArgs('paths:\n { a: 1 }\n { b: 2 }')
|
|
125
|
-
// Namespace should appear exactly once
|
|
126
|
-
const matches = result.match(/test/g)
|
|
127
|
-
t.is(matches.length, 1)
|
|
128
|
-
})
|
package/src/lib/logger/index.js
DELETED
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
import { format } from 'node:util'
|
|
2
|
-
import chalk from 'chalk'
|
|
3
|
-
import log from 'loglevel'
|
|
4
|
-
import config from '#lib/conf/config.js'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Logger factory for Quire CLI
|
|
8
|
-
*
|
|
9
|
-
* Creates loggers with colored output, log level filtering, and configurable prefixes.
|
|
10
|
-
* Configuration is read from the conf module for prefix style, colors, etc.
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* // Default singleton for simple usage
|
|
14
|
-
* import { logger } from '#lib/logger/index.js'
|
|
15
|
-
* logger.info('Building site...')
|
|
16
|
-
* // Output: [quire] INFO Building site...
|
|
17
|
-
*
|
|
18
|
-
* @example
|
|
19
|
-
* // In tests - mock the factory
|
|
20
|
-
* const mockLogger = {
|
|
21
|
-
* info: sandbox.stub(),
|
|
22
|
-
* error: sandbox.stub(),
|
|
23
|
-
* debug: sandbox.stub(),
|
|
24
|
-
* warn: sandbox.stub(),
|
|
25
|
-
* trace: sandbox.stub()
|
|
26
|
-
* }
|
|
27
|
-
* const module = await esmock('./module.js', {
|
|
28
|
-
* '#lib/logger/index.js': { logger: mockLogger }
|
|
29
|
-
* })
|
|
30
|
-
*/
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Log level constants matching loglevel library
|
|
34
|
-
* @see https://github.com/pimterry/loglevel#documentation
|
|
35
|
-
*/
|
|
36
|
-
export const LOG_LEVELS = {
|
|
37
|
-
trace: 0,
|
|
38
|
-
debug: 1,
|
|
39
|
-
info: 2,
|
|
40
|
-
warn: 3,
|
|
41
|
-
error: 4,
|
|
42
|
-
silent: 5
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Chalk style functions for prefix and level label
|
|
47
|
-
*/
|
|
48
|
-
const lableStyleFns = {
|
|
49
|
-
trace: chalk.gray,
|
|
50
|
-
debug: chalk.yellow,
|
|
51
|
-
info: chalk.magenta,
|
|
52
|
-
warn: chalk.yellow.inverse,
|
|
53
|
-
error: chalk.redBright.inverse
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Chalk style functions for message text
|
|
58
|
-
*
|
|
59
|
-
* Only levels that need distinct message styling are listed.
|
|
60
|
-
* Unlisted levels render message text without styling.
|
|
61
|
-
*/
|
|
62
|
-
const messageStyleFns = {
|
|
63
|
-
error: chalk.red,
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Emoji map for prefix styles
|
|
68
|
-
*/
|
|
69
|
-
const EMOJI_MAP = {
|
|
70
|
-
build: '🔨',
|
|
71
|
-
cli: '⚡',
|
|
72
|
-
conf: '⚙️',
|
|
73
|
-
epub: '📚',
|
|
74
|
-
pdf: '📄',
|
|
75
|
-
quire: '📖',
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Environment variable for log level configuration
|
|
80
|
-
* Set by CLI startup from config, can be overridden by CLI flags
|
|
81
|
-
*/
|
|
82
|
-
export const LOG_LEVEL_ENV_VAR = 'QUIRE_LOG_LEVEL'
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Format the log prefix based on configuration style
|
|
86
|
-
*
|
|
87
|
-
* @param {string} style - Prefix style (bracket, emoji, plain, none)
|
|
88
|
-
* @param {string} text - Prefix text
|
|
89
|
-
* @returns {string} Formatted prefix
|
|
90
|
-
*/
|
|
91
|
-
export function formatPrefix(style, text) {
|
|
92
|
-
switch (style) {
|
|
93
|
-
case 'bracket':
|
|
94
|
-
return `[${text}]`
|
|
95
|
-
case 'emoji':
|
|
96
|
-
return EMOJI_MAP[text] || '📖'
|
|
97
|
-
case 'plain':
|
|
98
|
-
return `${text}:`
|
|
99
|
-
case 'none':
|
|
100
|
-
return ''
|
|
101
|
-
default:
|
|
102
|
-
return `[${text}]`
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Resolve log level from various sources
|
|
108
|
-
*
|
|
109
|
-
* Priority order:
|
|
110
|
-
* 1. Explicit level parameter (for createLogger calls with specific level)
|
|
111
|
-
* 2. QUIRE_LOG_LEVEL environment variable (set by CLI from config/flags)
|
|
112
|
-
* 3. Config file setting
|
|
113
|
-
* 4. Default to 'info'
|
|
114
|
-
*
|
|
115
|
-
* @param {string|number} [level] - Explicit level override
|
|
116
|
-
* @returns {number} Numeric log level
|
|
117
|
-
*/
|
|
118
|
-
function resolveLevel(level) {
|
|
119
|
-
// If level is explicitly provided, use it
|
|
120
|
-
if (level !== undefined) {
|
|
121
|
-
if (typeof level === 'number') return level
|
|
122
|
-
return LOG_LEVELS[level] ?? LOG_LEVELS.info
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// Check environment variable (set by CLI startup from config)
|
|
126
|
-
const envVar = process.env[LOG_LEVEL_ENV_VAR]
|
|
127
|
-
if (envVar) {
|
|
128
|
-
return LOG_LEVELS[envVar] ?? LOG_LEVELS.info
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// Check config
|
|
132
|
-
const configLevel = config.get('logLevel')
|
|
133
|
-
if (configLevel && LOG_LEVELS[configLevel] !== undefined) {
|
|
134
|
-
return LOG_LEVELS[configLevel]
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// Default to info
|
|
138
|
-
return LOG_LEVELS.info
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Create a logger instance
|
|
143
|
-
*
|
|
144
|
-
* @param {string} [name='quire'] - Logger name for loglevel instance
|
|
145
|
-
* @param {string|number} [level] - Log level (trace, debug, info, warn, error, silent)
|
|
146
|
-
* @returns {Object} Logger instance with trace, debug, info, warn, error, setLevel methods
|
|
147
|
-
*/
|
|
148
|
-
export default function createLogger(name = 'quire', level) {
|
|
149
|
-
const loggerInstance = log.getLogger(name)
|
|
150
|
-
loggerInstance.setLevel(resolveLevel(level), false)
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Create a log function for a specific level
|
|
154
|
-
*/
|
|
155
|
-
const createLogFn = (type) => {
|
|
156
|
-
const logMethod = loggerInstance[type]
|
|
157
|
-
const styleLabel = lableStyleFns[type]
|
|
158
|
-
const styleMessage = messageStyleFns[type]
|
|
159
|
-
|
|
160
|
-
return (...args) => {
|
|
161
|
-
// Read config each time to support runtime changes
|
|
162
|
-
const prefix = config.get('logPrefix')
|
|
163
|
-
const prefixStyle = config.get('logPrefixStyle')
|
|
164
|
-
const showLevel = config.get('logShowLevel')
|
|
165
|
-
const useColor = config.get('logUseColor') && !process.env.NO_COLOR
|
|
166
|
-
const colorMessages = config.get('logColorMessages')
|
|
167
|
-
|
|
168
|
-
const parts = []
|
|
169
|
-
|
|
170
|
-
// Add prefix
|
|
171
|
-
const formattedPrefix = formatPrefix(prefixStyle, prefix)
|
|
172
|
-
if (formattedPrefix) {
|
|
173
|
-
if (useColor) {
|
|
174
|
-
parts.push(styleLabel(chalk.bold(formattedPrefix)))
|
|
175
|
-
} else {
|
|
176
|
-
parts.push(formattedPrefix)
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// Add level label
|
|
181
|
-
if (showLevel) {
|
|
182
|
-
const levelLabel = type.toUpperCase().padEnd(5, ' ')
|
|
183
|
-
if (useColor) {
|
|
184
|
-
parts.push(styleLabel(levelLabel))
|
|
185
|
-
} else {
|
|
186
|
-
parts.push(levelLabel)
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
// Format message with printf-style substitution (%s, %d, %i, %o, %O, %j)
|
|
191
|
-
const message = format(...args)
|
|
192
|
-
|
|
193
|
-
logMethod(...parts, useColor && colorMessages && styleMessage ? styleMessage(message) : message)
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
return {
|
|
198
|
-
trace: createLogFn('trace'),
|
|
199
|
-
debug: createLogFn('debug'),
|
|
200
|
-
info: createLogFn('info'),
|
|
201
|
-
warn: createLogFn('warn'),
|
|
202
|
-
error: createLogFn('error'),
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* Change the log level at runtime
|
|
206
|
-
* @param {string|number} newLevel - New log level
|
|
207
|
-
*/
|
|
208
|
-
setLevel(newLevel) {
|
|
209
|
-
const numericLevel = typeof newLevel === 'number'
|
|
210
|
-
? newLevel
|
|
211
|
-
: LOG_LEVELS[newLevel] ?? LOG_LEVELS.info
|
|
212
|
-
loggerInstance.setLevel(numericLevel, false)
|
|
213
|
-
},
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* Get the current log level
|
|
217
|
-
* @returns {number} Current numeric log level
|
|
218
|
-
*/
|
|
219
|
-
getLevel() {
|
|
220
|
-
return loggerInstance.getLevel()
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* Default singleton logger for simple usage
|
|
227
|
-
*/
|
|
228
|
-
export const logger = createLogger('quire')
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import test from 'ava'
|
|
2
|
-
import createLogger, { logger, LOG_LEVELS } from './index.js'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Logger Module Unit Tests
|
|
6
|
-
*
|
|
7
|
-
* Tests the logger factory exports and API surface.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
11
|
-
// Export tests
|
|
12
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
13
|
-
|
|
14
|
-
test('createLogger is exported as default', (t) => {
|
|
15
|
-
t.is(typeof createLogger, 'function')
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
test('logger singleton is exported', (t) => {
|
|
19
|
-
t.truthy(logger)
|
|
20
|
-
t.is(typeof logger.info, 'function')
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
test('LOG_LEVELS constants are exported', (t) => {
|
|
24
|
-
t.deepEqual(LOG_LEVELS, {
|
|
25
|
-
trace: 0,
|
|
26
|
-
debug: 1,
|
|
27
|
-
info: 2,
|
|
28
|
-
warn: 3,
|
|
29
|
-
error: 4,
|
|
30
|
-
silent: 5
|
|
31
|
-
})
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
35
|
-
// Factory function tests
|
|
36
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
37
|
-
|
|
38
|
-
test('createLogger returns logger with all methods', (t) => {
|
|
39
|
-
const log = createLogger('test')
|
|
40
|
-
|
|
41
|
-
t.is(typeof log.trace, 'function')
|
|
42
|
-
t.is(typeof log.debug, 'function')
|
|
43
|
-
t.is(typeof log.info, 'function')
|
|
44
|
-
t.is(typeof log.warn, 'function')
|
|
45
|
-
t.is(typeof log.error, 'function')
|
|
46
|
-
t.is(typeof log.setLevel, 'function')
|
|
47
|
-
t.is(typeof log.getLevel, 'function')
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
test('createLogger uses default prefix when none provided', (t) => {
|
|
51
|
-
const log = createLogger()
|
|
52
|
-
t.truthy(log)
|
|
53
|
-
t.is(typeof log.info, 'function')
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
test('createLogger accepts custom prefix', (t) => {
|
|
57
|
-
const log = createLogger('custom:prefix')
|
|
58
|
-
t.truthy(log)
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
test('createLogger accepts level as string', (t) => {
|
|
62
|
-
const log = createLogger('test', 'debug')
|
|
63
|
-
t.is(log.getLevel(), LOG_LEVELS.debug)
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
test('createLogger accepts level as number', (t) => {
|
|
67
|
-
const log = createLogger('test', 3)
|
|
68
|
-
t.is(log.getLevel(), 3)
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
test('createLogger defaults to info level', (t) => {
|
|
72
|
-
const log = createLogger('test')
|
|
73
|
-
t.is(log.getLevel(), LOG_LEVELS.info)
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
77
|
-
// setLevel tests
|
|
78
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
79
|
-
|
|
80
|
-
test('setLevel changes log level with string', (t) => {
|
|
81
|
-
const log = createLogger('test', 'info')
|
|
82
|
-
t.is(log.getLevel(), LOG_LEVELS.info)
|
|
83
|
-
|
|
84
|
-
log.setLevel('debug')
|
|
85
|
-
t.is(log.getLevel(), LOG_LEVELS.debug)
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
test('setLevel changes log level with number', (t) => {
|
|
89
|
-
const log = createLogger('test', 'info')
|
|
90
|
-
|
|
91
|
-
log.setLevel(0)
|
|
92
|
-
t.is(log.getLevel(), 0)
|
|
93
|
-
})
|
|
94
|
-
|
|
95
|
-
test('setLevel defaults to info for invalid level', (t) => {
|
|
96
|
-
const log = createLogger('test', 'debug')
|
|
97
|
-
|
|
98
|
-
log.setLevel('invalid')
|
|
99
|
-
t.is(log.getLevel(), LOG_LEVELS.info)
|
|
100
|
-
})
|
|
101
|
-
|
|
102
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
103
|
-
// Singleton tests
|
|
104
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
105
|
-
|
|
106
|
-
test('logger singleton has all required methods', (t) => {
|
|
107
|
-
t.is(typeof logger.trace, 'function')
|
|
108
|
-
t.is(typeof logger.debug, 'function')
|
|
109
|
-
t.is(typeof logger.info, 'function')
|
|
110
|
-
t.is(typeof logger.warn, 'function')
|
|
111
|
-
t.is(typeof logger.error, 'function')
|
|
112
|
-
t.is(typeof logger.setLevel, 'function')
|
|
113
|
-
t.is(typeof logger.getLevel, 'function')
|
|
114
|
-
})
|
|
115
|
-
|
|
116
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
117
|
-
// Multiple logger instances tests
|
|
118
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
119
|
-
|
|
120
|
-
test('createLogger creates independent instances', (t) => {
|
|
121
|
-
const log1 = createLogger('module:one', 'debug')
|
|
122
|
-
const log2 = createLogger('module:two', 'error')
|
|
123
|
-
|
|
124
|
-
t.is(log1.getLevel(), LOG_LEVELS.debug)
|
|
125
|
-
t.is(log2.getLevel(), LOG_LEVELS.error)
|
|
126
|
-
|
|
127
|
-
// Changing one shouldn't affect the other
|
|
128
|
-
log1.setLevel('warn')
|
|
129
|
-
t.is(log1.getLevel(), LOG_LEVELS.warn)
|
|
130
|
-
t.is(log2.getLevel(), LOG_LEVELS.error)
|
|
131
|
-
})
|