@atlaspack/diagnostic 2.14.2-typescript-e769947a5.0 → 2.14.2-typescript-6de04fbae.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 → index.d.mts} +37 -32
- package/lib/index.js +310 -0
- package/lib/index.js.flow +270 -0
- package/lib/index.mjs +201 -0
- package/package.json +19 -8
- package/src/{diagnostic.js → index.mts} +90 -87
- package/test/{JSONCodeHighlights.test.js → JSONCodeHighlights.test.mts} +1 -2
- package/test/{markdown.test.js → markdown.test.mts} +1 -2
- package/tsconfig.json +4 -0
- package/lib/diagnostic.js +0 -285
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as jsonSourcemap from '@mischnic/json-sourcemap';
|
|
2
2
|
/** These positions are 1-based (so <code>1</code> is the first line/column) */
|
|
3
3
|
export type DiagnosticHighlightLocation = {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
line: number;
|
|
5
|
+
column: number;
|
|
6
6
|
};
|
|
7
|
-
export type DiagnosticSeverity =
|
|
7
|
+
export type DiagnosticSeverity = 'error' | 'warn' | 'info';
|
|
8
8
|
/**
|
|
9
9
|
* Note: A tab character is always counted as a single character
|
|
10
10
|
* This is to prevent any mismatch of highlighting across machines
|
|
@@ -38,7 +38,9 @@ export type DiagnosticCodeFrame = {
|
|
|
38
38
|
codeHighlights: Array<DiagnosticCodeHighlight>;
|
|
39
39
|
};
|
|
40
40
|
/** A JSON object (as in "map") */
|
|
41
|
-
type JSONObject =
|
|
41
|
+
type JSONObject = {
|
|
42
|
+
[key: string]: any;
|
|
43
|
+
};
|
|
42
44
|
/**
|
|
43
45
|
* A style agnostic way of emitting errors, warnings and info.
|
|
44
46
|
* Reporters are responsible for rendering the message, codeframes, hints, ...
|
|
@@ -53,7 +55,7 @@ export type Diagnostic = {
|
|
|
53
55
|
/** Name of the error (optional) */
|
|
54
56
|
name?: string;
|
|
55
57
|
/** A code frame points to a certain location(s) in the file this diagnostic is linked to (optional) */
|
|
56
|
-
codeFrames?: Array<DiagnosticCodeFrame
|
|
58
|
+
codeFrames?: Array<DiagnosticCodeFrame>;
|
|
57
59
|
/** An optional list of strings that suggest ways to resolve this issue */
|
|
58
60
|
hints?: Array<string>;
|
|
59
61
|
/** @private */
|
|
@@ -71,7 +73,7 @@ export interface PrintableError extends Error {
|
|
|
71
73
|
loc?: {
|
|
72
74
|
column: number;
|
|
73
75
|
line: number;
|
|
74
|
-
}
|
|
76
|
+
};
|
|
75
77
|
source?: string;
|
|
76
78
|
}
|
|
77
79
|
export type DiagnosticWithoutOrigin = Diagnostic & {
|
|
@@ -83,10 +85,10 @@ export type Diagnostifiable = Diagnostic | Array<Diagnostic> | ThrowableDiagnost
|
|
|
83
85
|
export declare function anyToDiagnostic(input: Diagnostifiable): Array<Diagnostic>;
|
|
84
86
|
/** Normalize the given error into a diagnostic. */
|
|
85
87
|
export declare function errorToDiagnostic(error: ThrowableDiagnostic | PrintableError | string, defaultValues?: {
|
|
86
|
-
origin?: string
|
|
87
|
-
filePath?: string
|
|
88
|
+
origin?: string;
|
|
89
|
+
filePath?: string;
|
|
88
90
|
}): Array<Diagnostic>;
|
|
89
|
-
type ThrowableDiagnosticOpts = {
|
|
91
|
+
export type ThrowableDiagnosticOpts = {
|
|
90
92
|
diagnostic: Diagnostic | Array<Diagnostic>;
|
|
91
93
|
};
|
|
92
94
|
/**
|
|
@@ -106,53 +108,56 @@ export default class ThrowableDiagnostic extends Error {
|
|
|
106
108
|
* <code>type</code> signifies whether the key of the value in a JSON object should be highlighted.
|
|
107
109
|
*/
|
|
108
110
|
export declare function generateJSONCodeHighlights(data: string | {
|
|
109
|
-
data:
|
|
110
|
-
pointers:
|
|
111
|
+
data: any;
|
|
112
|
+
pointers: {
|
|
113
|
+
[key: string]: jsonSourcemap.Mapping;
|
|
114
|
+
};
|
|
111
115
|
}, ids: Array<{
|
|
112
116
|
key: string;
|
|
113
|
-
type?:
|
|
117
|
+
type?: 'key' | 'value';
|
|
114
118
|
message?: string;
|
|
115
119
|
}>): Array<DiagnosticCodeHighlight>;
|
|
116
120
|
/**
|
|
117
121
|
* Converts entries in <a href="https://github.com/mischnic/json-sourcemap">@mischnic/json-sourcemap</a>'s
|
|
118
122
|
* <code>result.pointers</code> array.
|
|
119
123
|
*/
|
|
120
|
-
export declare function getJSONHighlightLocation(pos: Mapping, type?:
|
|
124
|
+
export declare function getJSONHighlightLocation(pos: jsonSourcemap.Mapping, type?: 'key' | 'value'): {
|
|
121
125
|
start: DiagnosticHighlightLocation;
|
|
122
126
|
end: DiagnosticHighlightLocation;
|
|
123
127
|
};
|
|
124
128
|
/** Result is 1-based, but end is exclusive */
|
|
125
|
-
export declare function getJSONSourceLocation(pos: Mapping, type?:
|
|
129
|
+
export declare function getJSONSourceLocation(pos: jsonSourcemap.Mapping, type?: 'key' | 'value'): {
|
|
126
130
|
start: {
|
|
127
|
-
|
|
128
|
-
|
|
131
|
+
line: number;
|
|
132
|
+
column: number;
|
|
129
133
|
};
|
|
130
134
|
end: {
|
|
131
|
-
|
|
132
|
-
|
|
135
|
+
line: number;
|
|
136
|
+
column: number;
|
|
133
137
|
};
|
|
134
138
|
};
|
|
135
139
|
export declare function convertSourceLocationToHighlight<Location extends {
|
|
136
140
|
/** 1-based, inclusive */
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
141
|
+
start: {
|
|
142
|
+
line: number;
|
|
143
|
+
column: number;
|
|
140
144
|
};
|
|
141
145
|
/** 1-based, exclusive */
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
146
|
+
end: {
|
|
147
|
+
line: number;
|
|
148
|
+
column: number;
|
|
145
149
|
};
|
|
146
150
|
}>({ start, end }: Location, message?: string): DiagnosticCodeHighlight;
|
|
147
151
|
/** Sanitizes object keys before using them as <code>key</code> in generateJSONCodeHighlights */
|
|
148
152
|
export declare function encodeJSONKeyComponent(component: string): string;
|
|
149
153
|
export declare function escapeMarkdown(s: string): string;
|
|
150
|
-
type TemplateInput = any;
|
|
151
|
-
export
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
154
|
+
export type TemplateInput = any;
|
|
155
|
+
export interface MdFunction {
|
|
156
|
+
(strings: TemplateStringsArray, ...params: Array<TemplateInput>): string;
|
|
157
|
+
bold: (s: TemplateInput) => TemplateInput;
|
|
158
|
+
italic: (s: TemplateInput) => TemplateInput;
|
|
159
|
+
underline: (s: TemplateInput) => TemplateInput;
|
|
160
|
+
strikethrough: (s: TemplateInput) => TemplateInput;
|
|
157
161
|
}
|
|
162
|
+
export declare const md: MdFunction;
|
|
158
163
|
export {};
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: all[name]
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
anyToDiagnostic: function() {
|
|
13
|
+
return anyToDiagnostic;
|
|
14
|
+
},
|
|
15
|
+
convertSourceLocationToHighlight: function() {
|
|
16
|
+
return convertSourceLocationToHighlight;
|
|
17
|
+
},
|
|
18
|
+
/**
|
|
19
|
+
* An error wrapper around a diagnostic that can be <code>throw</code>n (e.g. to signal a
|
|
20
|
+
* build error).
|
|
21
|
+
*/ default: function() {
|
|
22
|
+
return ThrowableDiagnostic;
|
|
23
|
+
},
|
|
24
|
+
encodeJSONKeyComponent: function() {
|
|
25
|
+
return encodeJSONKeyComponent;
|
|
26
|
+
},
|
|
27
|
+
errorToDiagnostic: function() {
|
|
28
|
+
return errorToDiagnostic;
|
|
29
|
+
},
|
|
30
|
+
escapeMarkdown: function() {
|
|
31
|
+
return escapeMarkdown;
|
|
32
|
+
},
|
|
33
|
+
generateJSONCodeHighlights: function() {
|
|
34
|
+
return generateJSONCodeHighlights;
|
|
35
|
+
},
|
|
36
|
+
getJSONHighlightLocation: function() {
|
|
37
|
+
return getJSONHighlightLocation;
|
|
38
|
+
},
|
|
39
|
+
getJSONSourceLocation: function() {
|
|
40
|
+
return getJSONSourceLocation;
|
|
41
|
+
},
|
|
42
|
+
md: function() {
|
|
43
|
+
return md;
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
const _nodeassert = /*#__PURE__*/ _interop_require_default(require("node:assert"));
|
|
47
|
+
const _nullthrows = /*#__PURE__*/ _interop_require_default(require("nullthrows"));
|
|
48
|
+
const _jsonsourcemap = /*#__PURE__*/ _interop_require_wildcard(require("@mischnic/json-sourcemap"));
|
|
49
|
+
function _interop_require_default(obj) {
|
|
50
|
+
return obj && obj.__esModule ? obj : {
|
|
51
|
+
default: obj
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
function _getRequireWildcardCache(nodeInterop) {
|
|
55
|
+
if (typeof WeakMap !== "function") return null;
|
|
56
|
+
var cacheBabelInterop = new WeakMap();
|
|
57
|
+
var cacheNodeInterop = new WeakMap();
|
|
58
|
+
return (_getRequireWildcardCache = function(nodeInterop) {
|
|
59
|
+
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
|
|
60
|
+
})(nodeInterop);
|
|
61
|
+
}
|
|
62
|
+
function _interop_require_wildcard(obj, nodeInterop) {
|
|
63
|
+
if (!nodeInterop && obj && obj.__esModule) {
|
|
64
|
+
return obj;
|
|
65
|
+
}
|
|
66
|
+
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
|
|
67
|
+
return {
|
|
68
|
+
default: obj
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
var cache = _getRequireWildcardCache(nodeInterop);
|
|
72
|
+
if (cache && cache.has(obj)) {
|
|
73
|
+
return cache.get(obj);
|
|
74
|
+
}
|
|
75
|
+
var newObj = {
|
|
76
|
+
__proto__: null
|
|
77
|
+
};
|
|
78
|
+
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
79
|
+
for(var key in obj){
|
|
80
|
+
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
81
|
+
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
|
|
82
|
+
if (desc && (desc.get || desc.set)) {
|
|
83
|
+
Object.defineProperty(newObj, key, desc);
|
|
84
|
+
} else {
|
|
85
|
+
newObj[key] = obj[key];
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
newObj.default = obj;
|
|
90
|
+
if (cache) {
|
|
91
|
+
cache.set(obj, newObj);
|
|
92
|
+
}
|
|
93
|
+
return newObj;
|
|
94
|
+
}
|
|
95
|
+
function anyToDiagnostic(input) {
|
|
96
|
+
if (Array.isArray(input)) {
|
|
97
|
+
return input.flatMap((e)=>anyToDiagnostic(e));
|
|
98
|
+
} else if (input instanceof ThrowableDiagnostic) {
|
|
99
|
+
return input.diagnostics;
|
|
100
|
+
} else if (input instanceof Error) {
|
|
101
|
+
return errorToDiagnostic(input);
|
|
102
|
+
} else if (typeof input === 'string') {
|
|
103
|
+
return [
|
|
104
|
+
{
|
|
105
|
+
message: input
|
|
106
|
+
}
|
|
107
|
+
];
|
|
108
|
+
} else if (typeof input === 'object') {
|
|
109
|
+
return [
|
|
110
|
+
input
|
|
111
|
+
];
|
|
112
|
+
} else {
|
|
113
|
+
return errorToDiagnostic(input);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function errorToDiagnostic(error, defaultValues) {
|
|
117
|
+
let codeFrames = undefined;
|
|
118
|
+
if (typeof error === 'string') {
|
|
119
|
+
return [
|
|
120
|
+
{
|
|
121
|
+
origin: defaultValues?.origin ?? 'Error',
|
|
122
|
+
message: escapeMarkdown(error)
|
|
123
|
+
}
|
|
124
|
+
];
|
|
125
|
+
}
|
|
126
|
+
if (error instanceof ThrowableDiagnostic) {
|
|
127
|
+
return error.diagnostics.map((d)=>{
|
|
128
|
+
return {
|
|
129
|
+
...d,
|
|
130
|
+
origin: d.origin ?? defaultValues?.origin ?? 'unknown'
|
|
131
|
+
};
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
if (error.loc && error.source != null) {
|
|
135
|
+
codeFrames = [
|
|
136
|
+
{
|
|
137
|
+
filePath: error.filePath ?? error.fileName ?? defaultValues?.filePath ?? undefined,
|
|
138
|
+
code: error.source,
|
|
139
|
+
codeHighlights: [
|
|
140
|
+
{
|
|
141
|
+
start: {
|
|
142
|
+
line: error.loc.line,
|
|
143
|
+
column: error.loc.column
|
|
144
|
+
},
|
|
145
|
+
end: {
|
|
146
|
+
line: error.loc.line,
|
|
147
|
+
column: error.loc.column
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
]
|
|
151
|
+
}
|
|
152
|
+
];
|
|
153
|
+
}
|
|
154
|
+
return [
|
|
155
|
+
{
|
|
156
|
+
origin: defaultValues?.origin ?? 'Error',
|
|
157
|
+
message: escapeMarkdown(error.message),
|
|
158
|
+
name: error.name,
|
|
159
|
+
stack: codeFrames == null ? error.highlightedCodeFrame ?? error.codeFrame ?? error.stack : undefined,
|
|
160
|
+
codeFrames
|
|
161
|
+
}
|
|
162
|
+
];
|
|
163
|
+
}
|
|
164
|
+
class ThrowableDiagnostic extends Error {
|
|
165
|
+
diagnostics;
|
|
166
|
+
constructor(opts){
|
|
167
|
+
let diagnostics = Array.isArray(opts.diagnostic) ? opts.diagnostic : [
|
|
168
|
+
opts.diagnostic
|
|
169
|
+
];
|
|
170
|
+
// Construct error from diagnostics
|
|
171
|
+
super(diagnostics[0].message);
|
|
172
|
+
// @ts-ignore
|
|
173
|
+
this.stack = diagnostics[0].stack ?? super.stack;
|
|
174
|
+
// @ts-ignore
|
|
175
|
+
this.name = diagnostics[0].name ?? super.name;
|
|
176
|
+
this.diagnostics = diagnostics;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
function generateJSONCodeHighlights(data, ids) {
|
|
180
|
+
let map = typeof data == 'string' ? _jsonsourcemap.default.parse(data, undefined, {
|
|
181
|
+
dialect: 'JSON5',
|
|
182
|
+
tabWidth: 1
|
|
183
|
+
}) : data;
|
|
184
|
+
return ids.map(({ key, type, message })=>{
|
|
185
|
+
let pos = _nullthrows.default.default(map.pointers[key]);
|
|
186
|
+
return {
|
|
187
|
+
...getJSONHighlightLocation(pos, type),
|
|
188
|
+
message
|
|
189
|
+
};
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
function getJSONHighlightLocation(pos, type) {
|
|
193
|
+
let key = 'key' in pos ? pos.key : undefined;
|
|
194
|
+
let keyEnd = 'keyEnd' in pos ? pos.keyEnd : undefined;
|
|
195
|
+
if (!type && key && pos.value) {
|
|
196
|
+
// key and value
|
|
197
|
+
return {
|
|
198
|
+
start: {
|
|
199
|
+
line: key.line + 1,
|
|
200
|
+
column: key.column + 1
|
|
201
|
+
},
|
|
202
|
+
end: {
|
|
203
|
+
line: pos.valueEnd.line + 1,
|
|
204
|
+
column: pos.valueEnd.column
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
} else if (type == 'key' || !pos.value) {
|
|
208
|
+
(0, _nodeassert.default)(key && keyEnd);
|
|
209
|
+
return {
|
|
210
|
+
start: {
|
|
211
|
+
line: key.line + 1,
|
|
212
|
+
column: key.column + 1
|
|
213
|
+
},
|
|
214
|
+
end: {
|
|
215
|
+
line: keyEnd.line + 1,
|
|
216
|
+
column: keyEnd.column
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
} else {
|
|
220
|
+
return {
|
|
221
|
+
start: {
|
|
222
|
+
line: pos.value.line + 1,
|
|
223
|
+
column: pos.value.column + 1
|
|
224
|
+
},
|
|
225
|
+
end: {
|
|
226
|
+
line: pos.valueEnd.line + 1,
|
|
227
|
+
column: pos.valueEnd.column
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
function getJSONSourceLocation(pos, type) {
|
|
233
|
+
let v = getJSONHighlightLocation(pos, type);
|
|
234
|
+
return {
|
|
235
|
+
start: v.start,
|
|
236
|
+
end: {
|
|
237
|
+
line: v.end.line,
|
|
238
|
+
column: v.end.column + 1
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
function convertSourceLocationToHighlight({ start, end }, message) {
|
|
243
|
+
return {
|
|
244
|
+
message,
|
|
245
|
+
start,
|
|
246
|
+
end: {
|
|
247
|
+
line: end.line,
|
|
248
|
+
column: end.column - 1
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
function encodeJSONKeyComponent(component) {
|
|
253
|
+
return component.replace(/~/g, '~0').replace(/\//g, '~1');
|
|
254
|
+
}
|
|
255
|
+
const escapeCharacters = [
|
|
256
|
+
'\\',
|
|
257
|
+
'*',
|
|
258
|
+
'_',
|
|
259
|
+
'~'
|
|
260
|
+
];
|
|
261
|
+
function escapeMarkdown(s) {
|
|
262
|
+
let result = s;
|
|
263
|
+
for (const char of escapeCharacters){
|
|
264
|
+
result = result.replace(new RegExp(`\\${char}`, 'g'), `\\${char}`);
|
|
265
|
+
}
|
|
266
|
+
return result;
|
|
267
|
+
}
|
|
268
|
+
const mdVerbatim = Symbol();
|
|
269
|
+
const md = function(strings, ...params) {
|
|
270
|
+
let result = [];
|
|
271
|
+
for(let i = 0; i < params.length; i++){
|
|
272
|
+
result.push(strings[i]);
|
|
273
|
+
let param = params[i];
|
|
274
|
+
if (Array.isArray(param)) {
|
|
275
|
+
for(let j = 0; j < param.length; j++){
|
|
276
|
+
result.push(param[j]?.[mdVerbatim] ?? escapeMarkdown(`${param[j]}`));
|
|
277
|
+
if (j < param.length - 1) {
|
|
278
|
+
result.push(', ');
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
} else {
|
|
282
|
+
result.push(param?.[mdVerbatim] ?? escapeMarkdown(`${param}`));
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return result.join('') + strings[strings.length - 1];
|
|
286
|
+
};
|
|
287
|
+
md.bold = function(s) {
|
|
288
|
+
// $FlowFixMe[invalid-computed-prop]
|
|
289
|
+
return {
|
|
290
|
+
[mdVerbatim]: '**' + escapeMarkdown(`${s}`) + '**'
|
|
291
|
+
};
|
|
292
|
+
};
|
|
293
|
+
md.italic = function(s) {
|
|
294
|
+
// $FlowFixMe[invalid-computed-prop]
|
|
295
|
+
return {
|
|
296
|
+
[mdVerbatim]: '_' + escapeMarkdown(`${s}`) + '_'
|
|
297
|
+
};
|
|
298
|
+
};
|
|
299
|
+
md.underline = function(s) {
|
|
300
|
+
// $FlowFixMe[invalid-computed-prop]
|
|
301
|
+
return {
|
|
302
|
+
[mdVerbatim]: '__' + escapeMarkdown(`${s}`) + '__'
|
|
303
|
+
};
|
|
304
|
+
};
|
|
305
|
+
md.strikethrough = function(s) {
|
|
306
|
+
// $FlowFixMe[invalid-computed-prop]
|
|
307
|
+
return {
|
|
308
|
+
[mdVerbatim]: '~~' + escapeMarkdown(`${s}`) + '~~'
|
|
309
|
+
};
|
|
310
|
+
};
|