@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.
@@ -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 getJSONSourceLocation(pos: Mapping, type?: ("key" | null | undefined) | "value"): {
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
- return { ...d,
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
- let diagnostics = Array.isArray(opts.diagnostic) ? opts.diagnostic : [opts.diagnostic]; // Construct error from diagnostics
129
-
130
- super(diagnostics[0].message); // @ts-ignore
131
-
132
- this.stack = (_diagnostics$0$stack = diagnostics[0].stack) !== null && _diagnostics$0$stack !== void 0 ? _diagnostics$0$stack : super.stack; // @ts-ignore
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 { ...getJSONSourceLocation(pos, type),
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.8.3",
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": "349a6caf40ec8abb6a49fcae0765f8f8deb2073d"
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
- ...getJSONSourceLocation(pos, type),
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 getJSONSourceLocation(
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
+ });