@plugjs/plug 0.4.27 → 0.4.29
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/dist/async.cjs +3 -3
- package/dist/async.cjs.map +1 -1
- package/dist/async.d.ts +1 -1
- package/dist/async.mjs +3 -3
- package/dist/async.mjs.map +1 -1
- package/dist/build.cjs +6 -6
- package/dist/build.cjs.map +1 -1
- package/dist/build.d.ts +1 -1
- package/dist/build.mjs +4 -4
- package/dist/build.mjs.map +1 -1
- package/dist/cli.mjs +1 -1
- package/dist/fork.cjs +1 -1
- package/dist/fork.cjs.map +1 -1
- package/dist/fork.mjs +1 -1
- package/dist/fork.mjs.map +1 -1
- package/dist/helpers.cjs +15 -3
- package/dist/helpers.cjs.map +1 -1
- package/dist/helpers.d.ts +2 -2
- package/dist/helpers.mjs +17 -5
- package/dist/helpers.mjs.map +1 -1
- package/dist/logging/colors.cjs +5 -0
- package/dist/logging/colors.cjs.map +2 -2
- package/dist/logging/colors.d.ts +2 -0
- package/dist/logging/colors.mjs +4 -0
- package/dist/logging/colors.mjs.map +2 -2
- package/dist/logging/report.cjs +3 -3
- package/dist/logging/report.cjs.map +1 -1
- package/dist/logging/report.mjs +5 -5
- package/dist/logging/report.mjs.map +1 -1
- package/dist/logging/spinner.cjs +2 -2
- package/dist/logging/spinner.cjs.map +1 -1
- package/dist/logging/spinner.mjs +3 -3
- package/dist/logging/spinner.mjs.map +1 -1
- package/dist/types.cjs +0 -12
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.ts +1 -10
- package/dist/types.mjs +0 -5
- package/dist/types.mjs.map +2 -2
- package/dist/utils/jsonc.cjs +76 -0
- package/dist/utils/jsonc.cjs.map +6 -0
- package/dist/utils/jsonc.d.ts +17 -0
- package/dist/utils/jsonc.mjs +50 -0
- package/dist/utils/jsonc.mjs.map +6 -0
- package/dist/utils.cjs +2 -0
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.d.ts +1 -0
- package/dist/utils.mjs +1 -0
- package/dist/utils.mjs.map +1 -1
- package/package.json +2 -1
- package/src/async.ts +2 -3
- package/src/build.ts +17 -10
- package/src/fork.ts +1 -1
- package/src/helpers.ts +18 -6
- package/src/logging/colors.ts +11 -0
- package/src/logging/report.ts +5 -5
- package/src/logging/spinner.ts +3 -3
- package/src/types.ts +1 -15
- package/src/utils/jsonc.ts +62 -0
- package/src/utils.ts +1 -0
package/src/helpers.ts
CHANGED
|
@@ -2,11 +2,11 @@ import { mkdtempSync, readFileSync } from 'node:fs'
|
|
|
2
2
|
import { tmpdir } from 'node:os'
|
|
3
3
|
import { join } from 'node:path'
|
|
4
4
|
|
|
5
|
-
import { assert, assertPromises } from './asserts'
|
|
5
|
+
import { BuildFailure, assert, assertPromises } from './asserts'
|
|
6
6
|
import { requireContext } from './async'
|
|
7
7
|
import { Files } from './files'
|
|
8
8
|
import { rm } from './fs'
|
|
9
|
-
import { $p, log } from './logging'
|
|
9
|
+
import { $gry, $p, $plur, $wht, $ylw, log } from './logging'
|
|
10
10
|
import {
|
|
11
11
|
commonPath,
|
|
12
12
|
getAbsoluteParent,
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
} from './paths'
|
|
17
17
|
import { PipeImpl } from './pipe'
|
|
18
18
|
import { RunBuild } from './plugs/build'
|
|
19
|
+
import { JsoncError, parseJsonc } from './utils'
|
|
19
20
|
import { execChild } from './utils/exec'
|
|
20
21
|
import { parseOptions } from './utils/options'
|
|
21
22
|
import { walk } from './utils/walk'
|
|
@@ -260,11 +261,11 @@ export function exec(
|
|
|
260
261
|
}
|
|
261
262
|
|
|
262
263
|
/**
|
|
263
|
-
* Read and parse a JSON file, throwing an error if not found.
|
|
264
|
+
* Read and parse a JSON/JSONC file, throwing an error if not found.
|
|
264
265
|
*
|
|
265
266
|
* @params file The JSON file to parse
|
|
266
267
|
*/
|
|
267
|
-
export function parseJson(file: string): any {
|
|
268
|
+
export function parseJson(file: string, strict: boolean = false): any {
|
|
268
269
|
const jsonFile = requireContext().resolve(file)
|
|
269
270
|
let jsonText: string
|
|
270
271
|
try {
|
|
@@ -276,8 +277,19 @@ export function parseJson(file: string): any {
|
|
|
276
277
|
}
|
|
277
278
|
|
|
278
279
|
try {
|
|
279
|
-
return
|
|
280
|
+
return parseJsonc(jsonText, {
|
|
281
|
+
disallowComments: strict,
|
|
282
|
+
allowTrailingComma: ! strict,
|
|
283
|
+
})
|
|
280
284
|
} catch (error) {
|
|
281
|
-
|
|
285
|
+
if (error instanceof JsoncError) {
|
|
286
|
+
const errors = error.errors
|
|
287
|
+
log.error(`Found ${$plur(errors.length, 'error', 'errors')} parsing ${$p(jsonFile)}`)
|
|
288
|
+
for (const e of errors) {
|
|
289
|
+
log.error(` ${$wht(e.code)} ${$gry('at line')} ${$ylw(e.line)}${$gry(', column')} ${$ylw(e.column)}`)
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
throw new BuildFailure()
|
|
293
|
+
} else throw error
|
|
282
294
|
}
|
|
283
295
|
}
|
package/src/logging/colors.ts
CHANGED
|
@@ -127,3 +127,14 @@ export function $wht(string: any): string {
|
|
|
127
127
|
export function $und(string: any): string {
|
|
128
128
|
return colorize(und, string)
|
|
129
129
|
}
|
|
130
|
+
|
|
131
|
+
/** Pluralize (not really colors, but peace, love unity and respect). */
|
|
132
|
+
export function $plur(number: number, singular: string, plural: string, colorize: boolean = _colors): string {
|
|
133
|
+
return colorize ?
|
|
134
|
+
number === 1 ?
|
|
135
|
+
`${$ylw(number)} ${singular}` :
|
|
136
|
+
`${$ylw(number)} ${plural}` :
|
|
137
|
+
number === 1 ?
|
|
138
|
+
`${number} ${singular}` :
|
|
139
|
+
`${number} ${plural}`
|
|
140
|
+
}
|
package/src/logging/report.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { BuildFailure } from '../asserts'
|
|
2
2
|
import { readFile } from '../fs'
|
|
3
|
-
import { $blu, $cyn, $gry, $red, $und, $wht, $ylw } from './colors'
|
|
4
|
-
import { ERROR, logLevels, NOTICE, WARN } from './levels'
|
|
5
|
-
import { logOptions } from './options'
|
|
3
|
+
import { $blu, $cyn, $gry, $plur, $red, $und, $wht, $ylw } from './colors'
|
|
6
4
|
import { githubAnnotation } from './github'
|
|
5
|
+
import { ERROR, NOTICE, WARN, logLevels } from './levels'
|
|
6
|
+
import { logOptions } from './options'
|
|
7
7
|
|
|
8
8
|
import type { AbsolutePath } from '../paths'
|
|
9
9
|
import type { LogEmitter } from './emit'
|
|
@@ -427,12 +427,12 @@ export class ReportImpl implements Report {
|
|
|
427
427
|
|
|
428
428
|
const status: any[] = [ 'Found' ]
|
|
429
429
|
if (this.errors) {
|
|
430
|
-
status.push($
|
|
430
|
+
status.push($plur(this.errors, 'error', 'errors'))
|
|
431
431
|
}
|
|
432
432
|
|
|
433
433
|
if (this.warnings) {
|
|
434
434
|
if (this.errors) status.push('and')
|
|
435
|
-
status.push($
|
|
435
|
+
status.push($plur(this.warnings, 'warning', 'warnings'))
|
|
436
436
|
}
|
|
437
437
|
|
|
438
438
|
if (this.errors || this.warnings) {
|
package/src/logging/spinner.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* coverage ignore file */
|
|
2
2
|
|
|
3
3
|
import { runningTasks } from '../async'
|
|
4
|
-
import { $cyn, $gry, $t } from './colors'
|
|
4
|
+
import { $cyn, $gry, $plur, $t } from './colors'
|
|
5
5
|
import { logOptions } from './options'
|
|
6
6
|
|
|
7
7
|
/* ========================================================================== */
|
|
@@ -60,11 +60,11 @@ function spin(): void {
|
|
|
60
60
|
const pad = ''.padStart(_taskLength, ' ')
|
|
61
61
|
const names = tasks.map((task) => $t(task)).join($gry(', '))
|
|
62
62
|
|
|
63
|
-
const task = tasks.length
|
|
63
|
+
const task = $plur(tasks.length, 'task', 'tasks')
|
|
64
64
|
|
|
65
65
|
_nextSpin = (++ _nextSpin) % _spins.length
|
|
66
66
|
|
|
67
|
-
_output.write(`${zapSpinner}${pad} ${_spins[_nextSpin]} Running ${
|
|
67
|
+
_output.write(`${zapSpinner}${pad} ${_spins[_nextSpin]} Running ${task}: ${$gry(names)}`)
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
/* Start or stop the spinner */
|
package/src/types.ts
CHANGED
|
@@ -123,25 +123,11 @@ export type ThisBuild<D extends BuildDef> = {
|
|
|
123
123
|
never
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
/**
|
|
127
|
-
* Symbol indicating that an object is a {@link Build}.
|
|
128
|
-
*
|
|
129
|
-
* In a compiled {@link Build} this symbol will be associated with a function
|
|
130
|
-
* taking an array of strings (task names) and record of props to override
|
|
131
|
-
*/
|
|
132
|
-
export const buildMarker = Symbol.for('plugjs:plug:types:Build')
|
|
133
|
-
|
|
134
126
|
/**
|
|
135
127
|
* The {@link Build} type represents the collection of {@link Task}s
|
|
136
128
|
* and _properties_ compiled from a {@link BuildDef | build definition}.
|
|
137
129
|
*/
|
|
138
|
-
export type Build<D extends BuildDef = BuildDef> = Props<D> & Tasks<D>
|
|
139
|
-
readonly [buildMarker]: (
|
|
140
|
-
tasks: readonly string[],
|
|
141
|
-
props?: Record<string, string | undefined>,
|
|
142
|
-
) => Promise<void>
|
|
143
|
-
}
|
|
144
|
-
|
|
130
|
+
export type Build<D extends BuildDef = BuildDef> = Props<D> & Tasks<D>
|
|
145
131
|
/** A type identifying all _task names_ in a {@link Build}. */
|
|
146
132
|
export type BuildTasks<B extends Build> = string & keyof {
|
|
147
133
|
[ name in keyof B as B[name] extends Function ? name : never ] : any
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { EOL } from 'node:os'
|
|
2
|
+
|
|
3
|
+
import { parse, printParseErrorCode } from 'jsonc-parser'
|
|
4
|
+
|
|
5
|
+
import { $plur } from '../logging/colors'
|
|
6
|
+
|
|
7
|
+
import type { ParseError } from 'jsonc-parser'
|
|
8
|
+
|
|
9
|
+
export interface JsoncOptions {
|
|
10
|
+
disallowComments?: boolean;
|
|
11
|
+
allowTrailingComma?: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export class JsoncError extends Error {
|
|
15
|
+
constructor(public errors: { code: string, line: number, column: number } []) {
|
|
16
|
+
const message = [ `Found ${$plur(errors.length, 'error', 'errors', false)} parsing` ]
|
|
17
|
+
|
|
18
|
+
for (const { code, line, column } of errors) {
|
|
19
|
+
message.push(` ${code} at line ${line}, column ${column}`)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
super(message.join('\n'))
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function parseJsonc<T = any>(
|
|
27
|
+
data: string | null | undefined,
|
|
28
|
+
options: JsoncOptions = {},
|
|
29
|
+
): T {
|
|
30
|
+
const { disallowComments = false, allowTrailingComma = true } = options
|
|
31
|
+
|
|
32
|
+
if (! data) return undefined as T
|
|
33
|
+
const errors: ParseError[] = []
|
|
34
|
+
const result = parse(data, errors, {
|
|
35
|
+
disallowComments,
|
|
36
|
+
allowTrailingComma,
|
|
37
|
+
allowEmptyContent: false,
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
if (errors.length === 0) return result
|
|
41
|
+
|
|
42
|
+
const offsets = data.split(EOL).reduce(({ offsets, offset }, line) => {
|
|
43
|
+
offset += line.length + EOL.length
|
|
44
|
+
offsets.push(offset)
|
|
45
|
+
return { offsets, offset }
|
|
46
|
+
}, { offset: 0, offsets: [ 0 ] }).offsets
|
|
47
|
+
|
|
48
|
+
function resolveOffset(offset: number): { line: number, column: number } {
|
|
49
|
+
for (let i = offsets.length - 1; i > 0; i--) {
|
|
50
|
+
const lineOffset = offsets[i]!
|
|
51
|
+
if (offset < lineOffset) continue
|
|
52
|
+
return { line: i + 1, column: offset - lineOffset + 1 }
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return { line: 1, column: offset + 1 }
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
throw new JsoncError(errors.map((error) => {
|
|
59
|
+
const code = printParseErrorCode(error.error)
|
|
60
|
+
return { code, ...resolveOffset(error.offset) }
|
|
61
|
+
}))
|
|
62
|
+
}
|