@parcel/diagnostic 2.8.3 → 2.9.0
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/lib/diagnostic.d.ts +24 -1
- package/lib/diagnostic.js +57 -55
- package/package.json +2 -2
- package/src/diagnostic.js +38 -2
- package/test/JSONCodeHighlights.test.js +36 -0
package/lib/diagnostic.d.ts
CHANGED
|
@@ -113,10 +113,33 @@ export declare function generateJSONCodeHighlights(data: string | {
|
|
|
113
113
|
* Converts entries in <a href="https://github.com/mischnic/json-sourcemap">@mischnic/json-sourcemap</a>'s
|
|
114
114
|
* <code>result.pointers</code> array.
|
|
115
115
|
*/
|
|
116
|
-
export declare function
|
|
116
|
+
export declare function getJSONHighlightLocation(pos: Mapping, type?: ("key" | null | undefined) | "value"): {
|
|
117
117
|
start: DiagnosticHighlightLocation;
|
|
118
118
|
end: DiagnosticHighlightLocation;
|
|
119
119
|
};
|
|
120
|
+
/** Result is 1-based, but end is exclusive */
|
|
121
|
+
export declare function getJSONSourceLocation(pos: Mapping, type?: ("key" | null | undefined) | "value"): {
|
|
122
|
+
start: {
|
|
123
|
+
readonly line: number;
|
|
124
|
+
readonly column: number;
|
|
125
|
+
};
|
|
126
|
+
end: {
|
|
127
|
+
readonly line: number;
|
|
128
|
+
readonly column: number;
|
|
129
|
+
};
|
|
130
|
+
};
|
|
131
|
+
export declare function convertSourceLocationToHighlight<Location extends {
|
|
132
|
+
/** 1-based, inclusive */
|
|
133
|
+
readonly start: {
|
|
134
|
+
readonly line: number;
|
|
135
|
+
readonly column: number;
|
|
136
|
+
};
|
|
137
|
+
/** 1-based, exclusive */
|
|
138
|
+
readonly end: {
|
|
139
|
+
readonly line: number;
|
|
140
|
+
readonly column: number;
|
|
141
|
+
};
|
|
142
|
+
}>({ start, end }: Location, message?: string): DiagnosticCodeHighlight;
|
|
120
143
|
/** Sanitizes object keys before using them as <code>key</code> in generateJSONCodeHighlights */
|
|
121
144
|
export declare function encodeJSONKeyComponent(component: string): string;
|
|
122
145
|
export declare function escapeMarkdown(s: string): string;
|
package/lib/diagnostic.js
CHANGED
|
@@ -4,46 +4,53 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.anyToDiagnostic = anyToDiagnostic;
|
|
7
|
+
exports.convertSourceLocationToHighlight = convertSourceLocationToHighlight;
|
|
7
8
|
exports.default = void 0;
|
|
8
9
|
exports.encodeJSONKeyComponent = encodeJSONKeyComponent;
|
|
9
10
|
exports.errorToDiagnostic = errorToDiagnostic;
|
|
10
11
|
exports.escapeMarkdown = escapeMarkdown;
|
|
11
12
|
exports.generateJSONCodeHighlights = generateJSONCodeHighlights;
|
|
13
|
+
exports.getJSONHighlightLocation = getJSONHighlightLocation;
|
|
12
14
|
exports.getJSONSourceLocation = getJSONSourceLocation;
|
|
13
15
|
exports.md = md;
|
|
14
|
-
|
|
15
16
|
function _assert() {
|
|
16
17
|
const data = _interopRequireDefault(require("assert"));
|
|
17
|
-
|
|
18
18
|
_assert = function () {
|
|
19
19
|
return data;
|
|
20
20
|
};
|
|
21
|
-
|
|
22
21
|
return data;
|
|
23
22
|
}
|
|
24
|
-
|
|
25
23
|
function _nullthrows() {
|
|
26
24
|
const data = _interopRequireDefault(require("nullthrows"));
|
|
27
|
-
|
|
28
25
|
_nullthrows = function () {
|
|
29
26
|
return data;
|
|
30
27
|
};
|
|
31
|
-
|
|
32
28
|
return data;
|
|
33
29
|
}
|
|
34
|
-
|
|
35
30
|
function _jsonSourcemap() {
|
|
36
31
|
const data = require("@mischnic/json-sourcemap");
|
|
37
|
-
|
|
38
32
|
_jsonSourcemap = function () {
|
|
39
33
|
return data;
|
|
40
34
|
};
|
|
41
|
-
|
|
42
35
|
return data;
|
|
43
36
|
}
|
|
44
|
-
|
|
45
37
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
46
|
-
|
|
38
|
+
/** These positions are 1-based (so <code>1</code> is the first line/column) */
|
|
39
|
+
/**
|
|
40
|
+
* Note: A tab character is always counted as a single character
|
|
41
|
+
* This is to prevent any mismatch of highlighting across machines
|
|
42
|
+
*/
|
|
43
|
+
/**
|
|
44
|
+
* Describes how to format a code frame.
|
|
45
|
+
* A code frame is a visualization of a piece of code with a certain amount of
|
|
46
|
+
* code highlights that point to certain chunk(s) inside the code.
|
|
47
|
+
*/
|
|
48
|
+
/**
|
|
49
|
+
* A style agnostic way of emitting errors, warnings and info.
|
|
50
|
+
* Reporters are responsible for rendering the message, codeframes, hints, ...
|
|
51
|
+
*/
|
|
52
|
+
// This type should represent all error formats Parcel can encounter...
|
|
53
|
+
/** Something that can be turned into a diagnostic. */
|
|
47
54
|
/** Normalize the given value into a diagnostic. */
|
|
48
55
|
function anyToDiagnostic(input) {
|
|
49
56
|
if (Array.isArray(input)) {
|
|
@@ -62,36 +69,29 @@ function anyToDiagnostic(input) {
|
|
|
62
69
|
return errorToDiagnostic(input);
|
|
63
70
|
}
|
|
64
71
|
}
|
|
65
|
-
/** Normalize the given error into a diagnostic. */
|
|
66
|
-
|
|
67
72
|
|
|
73
|
+
/** Normalize the given error into a diagnostic. */
|
|
68
74
|
function errorToDiagnostic(error, defaultValues) {
|
|
69
75
|
var _defaultValues$origin2, _ref4, _error$highlightedCod;
|
|
70
|
-
|
|
71
76
|
let codeFrames = undefined;
|
|
72
|
-
|
|
73
77
|
if (typeof error === 'string') {
|
|
74
78
|
var _defaultValues$origin;
|
|
75
|
-
|
|
76
79
|
return [{
|
|
77
80
|
origin: (_defaultValues$origin = defaultValues === null || defaultValues === void 0 ? void 0 : defaultValues.origin) !== null && _defaultValues$origin !== void 0 ? _defaultValues$origin : 'Error',
|
|
78
81
|
message: escapeMarkdown(error)
|
|
79
82
|
}];
|
|
80
83
|
}
|
|
81
|
-
|
|
82
84
|
if (error instanceof ThrowableDiagnostic) {
|
|
83
85
|
return error.diagnostics.map(d => {
|
|
84
86
|
var _ref, _d$origin;
|
|
85
|
-
|
|
86
|
-
|
|
87
|
+
return {
|
|
88
|
+
...d,
|
|
87
89
|
origin: (_ref = (_d$origin = d.origin) !== null && _d$origin !== void 0 ? _d$origin : defaultValues === null || defaultValues === void 0 ? void 0 : defaultValues.origin) !== null && _ref !== void 0 ? _ref : 'unknown'
|
|
88
90
|
};
|
|
89
91
|
});
|
|
90
92
|
}
|
|
91
|
-
|
|
92
93
|
if (error.loc && error.source != null) {
|
|
93
94
|
var _ref2, _ref3, _error$filePath;
|
|
94
|
-
|
|
95
95
|
codeFrames = [{
|
|
96
96
|
filePath: (_ref2 = (_ref3 = (_error$filePath = error.filePath) !== null && _error$filePath !== void 0 ? _error$filePath : error.fileName) !== null && _ref3 !== void 0 ? _ref3 : defaultValues === null || defaultValues === void 0 ? void 0 : defaultValues.filePath) !== null && _ref2 !== void 0 ? _ref2 : undefined,
|
|
97
97
|
code: error.source,
|
|
@@ -107,7 +107,6 @@ function errorToDiagnostic(error, defaultValues) {
|
|
|
107
107
|
}]
|
|
108
108
|
}];
|
|
109
109
|
}
|
|
110
|
-
|
|
111
110
|
return [{
|
|
112
111
|
origin: (_defaultValues$origin2 = defaultValues === null || defaultValues === void 0 ? void 0 : defaultValues.origin) !== null && _defaultValues$origin2 !== void 0 ? _defaultValues$origin2 : 'Error',
|
|
113
112
|
message: escapeMarkdown(error.message),
|
|
@@ -116,7 +115,6 @@ function errorToDiagnostic(error, defaultValues) {
|
|
|
116
115
|
codeFrames
|
|
117
116
|
}];
|
|
118
117
|
}
|
|
119
|
-
|
|
120
118
|
/**
|
|
121
119
|
* An error wrapper around a diagnostic that can be <code>throw</code>n (e.g. to signal a
|
|
122
120
|
* build error).
|
|
@@ -124,18 +122,18 @@ function errorToDiagnostic(error, defaultValues) {
|
|
|
124
122
|
class ThrowableDiagnostic extends Error {
|
|
125
123
|
constructor(opts) {
|
|
126
124
|
var _diagnostics$0$stack, _diagnostics$0$name;
|
|
125
|
+
let diagnostics = Array.isArray(opts.diagnostic) ? opts.diagnostic : [opts.diagnostic];
|
|
127
126
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
127
|
+
// Construct error from diagnostics
|
|
128
|
+
super(diagnostics[0].message);
|
|
129
|
+
// @ts-ignore
|
|
130
|
+
this.stack = (_diagnostics$0$stack = diagnostics[0].stack) !== null && _diagnostics$0$stack !== void 0 ? _diagnostics$0$stack : super.stack;
|
|
131
|
+
// @ts-ignore
|
|
134
132
|
this.name = (_diagnostics$0$name = diagnostics[0].name) !== null && _diagnostics$0$name !== void 0 ? _diagnostics$0$name : super.name;
|
|
135
133
|
this.diagnostics = diagnostics;
|
|
136
134
|
}
|
|
137
|
-
|
|
138
135
|
}
|
|
136
|
+
|
|
139
137
|
/**
|
|
140
138
|
* Turns a list of positions in a JSON5 file with messages into a list of diagnostics.
|
|
141
139
|
* Uses <a href="https://github.com/mischnic/json-sourcemap">@mischnic/json-sourcemap</a>.
|
|
@@ -144,10 +142,7 @@ class ThrowableDiagnostic extends Error {
|
|
|
144
142
|
* @param ids A list of JSON keypaths (<code>key: "/some/parent/child"</code>) with corresponding messages, \
|
|
145
143
|
* <code>type</code> signifies whether the key of the value in a JSON object should be highlighted.
|
|
146
144
|
*/
|
|
147
|
-
|
|
148
|
-
|
|
149
145
|
exports.default = ThrowableDiagnostic;
|
|
150
|
-
|
|
151
146
|
function generateJSONCodeHighlights(data, ids) {
|
|
152
147
|
let map = typeof data == 'string' ? (0, _jsonSourcemap().parse)(data, undefined, {
|
|
153
148
|
dialect: 'JSON5',
|
|
@@ -159,21 +154,20 @@ function generateJSONCodeHighlights(data, ids) {
|
|
|
159
154
|
message
|
|
160
155
|
}) => {
|
|
161
156
|
let pos = (0, _nullthrows().default)(map.pointers[key]);
|
|
162
|
-
return {
|
|
157
|
+
return {
|
|
158
|
+
...getJSONHighlightLocation(pos, type),
|
|
163
159
|
message
|
|
164
160
|
};
|
|
165
161
|
});
|
|
166
162
|
}
|
|
163
|
+
|
|
167
164
|
/**
|
|
168
165
|
* Converts entries in <a href="https://github.com/mischnic/json-sourcemap">@mischnic/json-sourcemap</a>'s
|
|
169
166
|
* <code>result.pointers</code> array.
|
|
170
167
|
*/
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
function getJSONSourceLocation(pos, type) {
|
|
168
|
+
function getJSONHighlightLocation(pos, type) {
|
|
174
169
|
let key = 'key' in pos ? pos.key : undefined;
|
|
175
170
|
let keyEnd = 'keyEnd' in pos ? pos.keyEnd : undefined;
|
|
176
|
-
|
|
177
171
|
if (!type && key && pos.value) {
|
|
178
172
|
// key and value
|
|
179
173
|
return {
|
|
@@ -211,75 +205,83 @@ function getJSONSourceLocation(pos, type) {
|
|
|
211
205
|
};
|
|
212
206
|
}
|
|
213
207
|
}
|
|
214
|
-
/** Sanitizes object keys before using them as <code>key</code> in generateJSONCodeHighlights */
|
|
215
208
|
|
|
209
|
+
/** Result is 1-based, but end is exclusive */
|
|
210
|
+
function getJSONSourceLocation(pos, type) {
|
|
211
|
+
let v = getJSONHighlightLocation(pos, type);
|
|
212
|
+
return {
|
|
213
|
+
start: v.start,
|
|
214
|
+
end: {
|
|
215
|
+
line: v.end.line,
|
|
216
|
+
column: v.end.column + 1
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
function convertSourceLocationToHighlight({
|
|
221
|
+
start,
|
|
222
|
+
end
|
|
223
|
+
}, message) {
|
|
224
|
+
return {
|
|
225
|
+
message,
|
|
226
|
+
start,
|
|
227
|
+
end: {
|
|
228
|
+
line: end.line,
|
|
229
|
+
column: end.column - 1
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
}
|
|
216
233
|
|
|
234
|
+
/** Sanitizes object keys before using them as <code>key</code> in generateJSONCodeHighlights */
|
|
217
235
|
function encodeJSONKeyComponent(component) {
|
|
218
236
|
return component.replace(/~/g, '~0').replace(/\//g, '~1');
|
|
219
237
|
}
|
|
220
|
-
|
|
221
238
|
const escapeCharacters = ['\\', '*', '_', '~'];
|
|
222
|
-
|
|
223
239
|
function escapeMarkdown(s) {
|
|
224
240
|
let result = s;
|
|
225
|
-
|
|
226
241
|
for (const char of escapeCharacters) {
|
|
227
242
|
result = result.replace(new RegExp(`\\${char}`, 'g'), `\\${char}`);
|
|
228
243
|
}
|
|
229
|
-
|
|
230
244
|
return result;
|
|
231
245
|
}
|
|
232
|
-
|
|
233
246
|
const mdVerbatim = Symbol();
|
|
234
|
-
|
|
235
247
|
function md(strings, ...params) {
|
|
236
248
|
let result = [];
|
|
237
|
-
|
|
238
249
|
for (let i = 0; i < params.length; i++) {
|
|
239
250
|
result.push(strings[i]);
|
|
240
251
|
let param = params[i];
|
|
241
|
-
|
|
242
252
|
if (Array.isArray(param)) {
|
|
243
253
|
for (let j = 0; j < param.length; j++) {
|
|
244
254
|
var _param$j$mdVerbatim, _param$j;
|
|
245
|
-
|
|
246
255
|
result.push((_param$j$mdVerbatim = (_param$j = param[j]) === null || _param$j === void 0 ? void 0 : _param$j[mdVerbatim]) !== null && _param$j$mdVerbatim !== void 0 ? _param$j$mdVerbatim : escapeMarkdown(`${param[j]}`));
|
|
247
|
-
|
|
248
256
|
if (j < param.length - 1) {
|
|
249
257
|
result.push(', ');
|
|
250
258
|
}
|
|
251
259
|
}
|
|
252
260
|
} else {
|
|
253
261
|
var _param$mdVerbatim;
|
|
254
|
-
|
|
255
262
|
result.push((_param$mdVerbatim = param === null || param === void 0 ? void 0 : param[mdVerbatim]) !== null && _param$mdVerbatim !== void 0 ? _param$mdVerbatim : escapeMarkdown(`${param}`));
|
|
256
263
|
}
|
|
257
264
|
}
|
|
258
|
-
|
|
259
265
|
return result.join('') + strings[strings.length - 1];
|
|
260
266
|
}
|
|
261
|
-
|
|
262
267
|
md.bold = function (s) {
|
|
263
268
|
// $FlowFixMe[invalid-computed-prop]
|
|
264
269
|
return {
|
|
265
270
|
[mdVerbatim]: '**' + escapeMarkdown(`${s}`) + '**'
|
|
266
271
|
};
|
|
267
272
|
};
|
|
268
|
-
|
|
269
273
|
md.italic = function (s) {
|
|
270
274
|
// $FlowFixMe[invalid-computed-prop]
|
|
271
275
|
return {
|
|
272
276
|
[mdVerbatim]: '_' + escapeMarkdown(`${s}`) + '_'
|
|
273
277
|
};
|
|
274
278
|
};
|
|
275
|
-
|
|
276
279
|
md.underline = function (s) {
|
|
277
280
|
// $FlowFixMe[invalid-computed-prop]
|
|
278
281
|
return {
|
|
279
282
|
[mdVerbatim]: '__' + escapeMarkdown(`${s}`) + '__'
|
|
280
283
|
};
|
|
281
284
|
};
|
|
282
|
-
|
|
283
285
|
md.strikethrough = function (s) {
|
|
284
286
|
// $FlowFixMe[invalid-computed-prop]
|
|
285
287
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parcel/diagnostic",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.9.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -27,5 +27,5 @@
|
|
|
27
27
|
"@mischnic/json-sourcemap": "^0.1.0",
|
|
28
28
|
"nullthrows": "^1.1.1"
|
|
29
29
|
},
|
|
30
|
-
"gitHead": "
|
|
30
|
+
"gitHead": "dd9435be8afed35c5ffc161cf4b586fd6c78fc1f"
|
|
31
31
|
}
|
package/src/diagnostic.js
CHANGED
|
@@ -238,7 +238,7 @@ export function generateJSONCodeHighlights(
|
|
|
238
238
|
return ids.map(({key, type, message}) => {
|
|
239
239
|
let pos = nullthrows(map.pointers[key]);
|
|
240
240
|
return {
|
|
241
|
-
...
|
|
241
|
+
...getJSONHighlightLocation(pos, type),
|
|
242
242
|
message,
|
|
243
243
|
};
|
|
244
244
|
});
|
|
@@ -248,7 +248,7 @@ export function generateJSONCodeHighlights(
|
|
|
248
248
|
* Converts entries in <a href="https://github.com/mischnic/json-sourcemap">@mischnic/json-sourcemap</a>'s
|
|
249
249
|
* <code>result.pointers</code> array.
|
|
250
250
|
*/
|
|
251
|
-
export function
|
|
251
|
+
export function getJSONHighlightLocation(
|
|
252
252
|
pos: Mapping,
|
|
253
253
|
type?: ?'key' | 'value',
|
|
254
254
|
): {|
|
|
@@ -277,6 +277,42 @@ export function getJSONSourceLocation(
|
|
|
277
277
|
}
|
|
278
278
|
}
|
|
279
279
|
|
|
280
|
+
/** Result is 1-based, but end is exclusive */
|
|
281
|
+
export function getJSONSourceLocation(
|
|
282
|
+
pos: Mapping,
|
|
283
|
+
type?: ?'key' | 'value',
|
|
284
|
+
): {|
|
|
285
|
+
start: {|
|
|
286
|
+
+line: number,
|
|
287
|
+
+column: number,
|
|
288
|
+
|},
|
|
289
|
+
end: {|
|
|
290
|
+
+line: number,
|
|
291
|
+
+column: number,
|
|
292
|
+
|},
|
|
293
|
+
|} {
|
|
294
|
+
let v = getJSONHighlightLocation(pos, type);
|
|
295
|
+
return {start: v.start, end: {line: v.end.line, column: v.end.column + 1}};
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
export function convertSourceLocationToHighlight<
|
|
299
|
+
Location: {
|
|
300
|
+
/** 1-based, inclusive */
|
|
301
|
+
+start: {|
|
|
302
|
+
+line: number,
|
|
303
|
+
+column: number,
|
|
304
|
+
|},
|
|
305
|
+
/** 1-based, exclusive */
|
|
306
|
+
+end: {|
|
|
307
|
+
+line: number,
|
|
308
|
+
+column: number,
|
|
309
|
+
|},
|
|
310
|
+
...
|
|
311
|
+
},
|
|
312
|
+
>({start, end}: Location, message?: string): DiagnosticCodeHighlight {
|
|
313
|
+
return {message, start, end: {line: end.line, column: end.column - 1}};
|
|
314
|
+
}
|
|
315
|
+
|
|
280
316
|
/** Sanitizes object keys before using them as <code>key</code> in generateJSONCodeHighlights */
|
|
281
317
|
export function encodeJSONKeyComponent(component: string): string {
|
|
282
318
|
return component.replace(/~/g, '~0').replace(/\//g, '~1');
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// @flow strict-local
|
|
2
|
+
import assert from 'assert';
|
|
3
|
+
|
|
4
|
+
import {generateJSONCodeHighlights} from '../src/diagnostic';
|
|
5
|
+
|
|
6
|
+
describe('generateJSONCodeHighlights', () => {
|
|
7
|
+
it('returns an escaped string 01', () => {
|
|
8
|
+
let result = generateJSONCodeHighlights(
|
|
9
|
+
`{
|
|
10
|
+
"a": 1
|
|
11
|
+
}`,
|
|
12
|
+
[
|
|
13
|
+
{key: '/a', type: 'key', message: 'foo1'},
|
|
14
|
+
{key: '/a', type: 'value', message: 'foo2'},
|
|
15
|
+
{key: '/a', message: 'foo3'},
|
|
16
|
+
],
|
|
17
|
+
);
|
|
18
|
+
assert.deepEqual(result, [
|
|
19
|
+
{
|
|
20
|
+
start: {line: 2, column: 3},
|
|
21
|
+
end: {line: 2, column: 5},
|
|
22
|
+
message: 'foo1',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
start: {line: 2, column: 8},
|
|
26
|
+
end: {line: 2, column: 8},
|
|
27
|
+
message: 'foo2',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
start: {line: 2, column: 3},
|
|
31
|
+
end: {line: 2, column: 8},
|
|
32
|
+
message: 'foo3',
|
|
33
|
+
},
|
|
34
|
+
]);
|
|
35
|
+
});
|
|
36
|
+
});
|