@atlaspack/diagnostic 2.14.1-dev.11 → 2.14.1-dev.123
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 +7 -0
- package/index.d.ts +2 -0
- package/index.js +1 -0
- package/index.js.flow +4 -0
- package/package.json +6 -15
- package/lib/diagnostic.d.ts +0 -158
- package/lib/diagnostic.js +0 -285
- package/src/diagnostic.js +0 -385
- package/test/JSONCodeHighlights.test.js +0 -36
- package/test/markdown.test.js +0 -81
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# @atlaspack/diagnostic
|
|
2
2
|
|
|
3
|
+
## 2.14.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#478](https://github.com/atlassian-labs/atlaspack/pull/478) [`570493b`](https://github.com/atlassian-labs/atlaspack/commit/570493beaf754e7985aebc7daaaf6dfcfa8fe56b) Thanks [@yamadapc](https://github.com/yamadapc)! - The first attempt at Version Packages didn't include the built artifacts.
|
|
8
|
+
This has hopefully been fixed, so this change will force those packages to re-release.
|
|
9
|
+
|
|
3
10
|
## 2.14.0
|
|
4
11
|
|
|
5
12
|
### Minor Changes
|
package/index.d.ts
ADDED
package/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('@atlaspack/unified/diagnostic');
|
package/index.js.flow
ADDED
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaspack/diagnostic",
|
|
3
|
-
"version": "2.14.1-dev.
|
|
3
|
+
"version": "2.14.1-dev.123+5a11f33c5",
|
|
4
4
|
"description": "Types and utilities for printing source-code located errors, warning and information messages.",
|
|
5
5
|
"license": "(MIT OR Apache-2.0)",
|
|
6
|
+
"type": "commonjs",
|
|
6
7
|
"publishConfig": {
|
|
7
8
|
"access": "public"
|
|
8
9
|
},
|
|
@@ -10,20 +11,10 @@
|
|
|
10
11
|
"type": "git",
|
|
11
12
|
"url": "https://github.com/atlassian-labs/atlaspack.git"
|
|
12
13
|
},
|
|
13
|
-
"main": "
|
|
14
|
-
"
|
|
15
|
-
"types": "lib/diagnostic.d.ts",
|
|
16
|
-
"engines": {
|
|
17
|
-
"node": ">= 16.0.0"
|
|
18
|
-
},
|
|
19
|
-
"scripts": {
|
|
20
|
-
"build-ts": "flow-to-ts src/*.js --write && tsc --emitDeclarationOnly --declaration --esModuleInterop src/*.ts && mkdir -p lib && mv src/*.d.ts lib/. && rm src/*.ts",
|
|
21
|
-
"check-ts": "tsc --noEmit lib/diagnostic.d.ts"
|
|
22
|
-
},
|
|
14
|
+
"main": "index.js",
|
|
15
|
+
"types": "index.d.ts",
|
|
23
16
|
"dependencies": {
|
|
24
|
-
"@
|
|
25
|
-
"nullthrows": "^1.1.1"
|
|
17
|
+
"@atlaspack/unified": "2.14.2-dev.3834+5a11f33c5"
|
|
26
18
|
},
|
|
27
|
-
"
|
|
28
|
-
"gitHead": "633800dee24b76fed158966a802c0ea5dcab65d5"
|
|
19
|
+
"gitHead": "5a11f33c51ff74d1cf8d4b72cfa0fda833aa980a"
|
|
29
20
|
}
|
package/lib/diagnostic.d.ts
DELETED
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
import type { Mapping } from "@mischnic/json-sourcemap";
|
|
2
|
-
/** These positions are 1-based (so <code>1</code> is the first line/column) */
|
|
3
|
-
export type DiagnosticHighlightLocation = {
|
|
4
|
-
readonly line: number;
|
|
5
|
-
readonly column: number;
|
|
6
|
-
};
|
|
7
|
-
export type DiagnosticSeverity = "error" | "warn" | "info";
|
|
8
|
-
/**
|
|
9
|
-
* Note: A tab character is always counted as a single character
|
|
10
|
-
* This is to prevent any mismatch of highlighting across machines
|
|
11
|
-
*/
|
|
12
|
-
export type DiagnosticCodeHighlight = {
|
|
13
|
-
/** Location of the first character that should get highlighted for this highlight. */
|
|
14
|
-
start: DiagnosticHighlightLocation;
|
|
15
|
-
/** Location of the last character that should get highlighted for this highlight. */
|
|
16
|
-
end: DiagnosticHighlightLocation;
|
|
17
|
-
/** A message that should be displayed at this location in the code (optional). */
|
|
18
|
-
message?: string;
|
|
19
|
-
};
|
|
20
|
-
/**
|
|
21
|
-
* Describes how to format a code frame.
|
|
22
|
-
* A code frame is a visualization of a piece of code with a certain amount of
|
|
23
|
-
* code highlights that point to certain chunk(s) inside the code.
|
|
24
|
-
*/
|
|
25
|
-
export type DiagnosticCodeFrame = {
|
|
26
|
-
/**
|
|
27
|
-
* The contents of the source file.
|
|
28
|
-
*
|
|
29
|
-
* If no code is passed, it will be read in from filePath, remember that
|
|
30
|
-
* the asset's current code could be different from the input contents.
|
|
31
|
-
*
|
|
32
|
-
*/
|
|
33
|
-
code?: string;
|
|
34
|
-
/** Path to the file this code frame is about (optional, absolute or relative to the project root) */
|
|
35
|
-
filePath?: string;
|
|
36
|
-
/** Language of the file this code frame is about (optional) */
|
|
37
|
-
language?: string;
|
|
38
|
-
codeHighlights: Array<DiagnosticCodeHighlight>;
|
|
39
|
-
};
|
|
40
|
-
/** A JSON object (as in "map") */
|
|
41
|
-
type JSONObject = Record<string, any>;
|
|
42
|
-
/**
|
|
43
|
-
* A style agnostic way of emitting errors, warnings and info.
|
|
44
|
-
* Reporters are responsible for rendering the message, codeframes, hints, ...
|
|
45
|
-
*/
|
|
46
|
-
export type Diagnostic = {
|
|
47
|
-
/** This is the message you want to log. */
|
|
48
|
-
message: string;
|
|
49
|
-
/** Name of plugin or file that threw this error */
|
|
50
|
-
origin?: string;
|
|
51
|
-
/** A stacktrace of the error (optional) */
|
|
52
|
-
stack?: string;
|
|
53
|
-
/** Name of the error (optional) */
|
|
54
|
-
name?: string;
|
|
55
|
-
/** A code frame points to a certain location(s) in the file this diagnostic is linked to (optional) */
|
|
56
|
-
codeFrames?: Array<DiagnosticCodeFrame> | null | undefined;
|
|
57
|
-
/** An optional list of strings that suggest ways to resolve this issue */
|
|
58
|
-
hints?: Array<string>;
|
|
59
|
-
/** @private */
|
|
60
|
-
skipFormatting?: boolean;
|
|
61
|
-
/** A URL to documentation to learn more about the diagnostic. */
|
|
62
|
-
documentationURL?: string;
|
|
63
|
-
/** Diagnostic specific metadata (optional) */
|
|
64
|
-
meta?: JSONObject;
|
|
65
|
-
};
|
|
66
|
-
export interface PrintableError extends Error {
|
|
67
|
-
fileName?: string;
|
|
68
|
-
filePath?: string;
|
|
69
|
-
codeFrame?: string;
|
|
70
|
-
highlightedCodeFrame?: string;
|
|
71
|
-
loc?: {
|
|
72
|
-
column: number;
|
|
73
|
-
line: number;
|
|
74
|
-
} | null | undefined;
|
|
75
|
-
source?: string;
|
|
76
|
-
}
|
|
77
|
-
export type DiagnosticWithoutOrigin = Diagnostic & {
|
|
78
|
-
origin?: string;
|
|
79
|
-
};
|
|
80
|
-
/** Something that can be turned into a diagnostic. */
|
|
81
|
-
export type Diagnostifiable = Diagnostic | Array<Diagnostic> | ThrowableDiagnostic | PrintableError | Error | string;
|
|
82
|
-
/** Normalize the given value into a diagnostic. */
|
|
83
|
-
export declare function anyToDiagnostic(input: Diagnostifiable): Array<Diagnostic>;
|
|
84
|
-
/** Normalize the given error into a diagnostic. */
|
|
85
|
-
export declare function errorToDiagnostic(error: ThrowableDiagnostic | PrintableError | string, defaultValues?: {
|
|
86
|
-
origin?: string | null | undefined;
|
|
87
|
-
filePath?: string | null | undefined;
|
|
88
|
-
}): Array<Diagnostic>;
|
|
89
|
-
type ThrowableDiagnosticOpts = {
|
|
90
|
-
diagnostic: Diagnostic | Array<Diagnostic>;
|
|
91
|
-
};
|
|
92
|
-
/**
|
|
93
|
-
* An error wrapper around a diagnostic that can be <code>throw</code>n (e.g. to signal a
|
|
94
|
-
* build error).
|
|
95
|
-
*/
|
|
96
|
-
export default class ThrowableDiagnostic extends Error {
|
|
97
|
-
diagnostics: Array<Diagnostic>;
|
|
98
|
-
constructor(opts: ThrowableDiagnosticOpts);
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Turns a list of positions in a JSON5 file with messages into a list of diagnostics.
|
|
102
|
-
* Uses <a href="https://github.com/mischnic/json-sourcemap">@mischnic/json-sourcemap</a>.
|
|
103
|
-
*
|
|
104
|
-
* @param code the JSON code
|
|
105
|
-
* @param ids A list of JSON keypaths (<code>key: "/some/parent/child"</code>) with corresponding messages, \
|
|
106
|
-
* <code>type</code> signifies whether the key of the value in a JSON object should be highlighted.
|
|
107
|
-
*/
|
|
108
|
-
export declare function generateJSONCodeHighlights(data: string | {
|
|
109
|
-
data: unknown;
|
|
110
|
-
pointers: Record<string, Mapping>;
|
|
111
|
-
}, ids: Array<{
|
|
112
|
-
key: string;
|
|
113
|
-
type?: ("key" | null | undefined) | "value";
|
|
114
|
-
message?: string;
|
|
115
|
-
}>): Array<DiagnosticCodeHighlight>;
|
|
116
|
-
/**
|
|
117
|
-
* Converts entries in <a href="https://github.com/mischnic/json-sourcemap">@mischnic/json-sourcemap</a>'s
|
|
118
|
-
* <code>result.pointers</code> array.
|
|
119
|
-
*/
|
|
120
|
-
export declare function getJSONHighlightLocation(pos: Mapping, type?: ("key" | null | undefined) | "value"): {
|
|
121
|
-
start: DiagnosticHighlightLocation;
|
|
122
|
-
end: DiagnosticHighlightLocation;
|
|
123
|
-
};
|
|
124
|
-
/** Result is 1-based, but end is exclusive */
|
|
125
|
-
export declare function getJSONSourceLocation(pos: Mapping, type?: ("key" | null | undefined) | "value"): {
|
|
126
|
-
start: {
|
|
127
|
-
readonly line: number;
|
|
128
|
-
readonly column: number;
|
|
129
|
-
};
|
|
130
|
-
end: {
|
|
131
|
-
readonly line: number;
|
|
132
|
-
readonly column: number;
|
|
133
|
-
};
|
|
134
|
-
};
|
|
135
|
-
export declare function convertSourceLocationToHighlight<Location extends {
|
|
136
|
-
/** 1-based, inclusive */
|
|
137
|
-
readonly start: {
|
|
138
|
-
readonly line: number;
|
|
139
|
-
readonly column: number;
|
|
140
|
-
};
|
|
141
|
-
/** 1-based, exclusive */
|
|
142
|
-
readonly end: {
|
|
143
|
-
readonly line: number;
|
|
144
|
-
readonly column: number;
|
|
145
|
-
};
|
|
146
|
-
}>({ start, end }: Location, message?: string): DiagnosticCodeHighlight;
|
|
147
|
-
/** Sanitizes object keys before using them as <code>key</code> in generateJSONCodeHighlights */
|
|
148
|
-
export declare function encodeJSONKeyComponent(component: string): string;
|
|
149
|
-
export declare function escapeMarkdown(s: string): string;
|
|
150
|
-
type TemplateInput = any;
|
|
151
|
-
export declare function md(strings: Array<string>, ...params: Array<TemplateInput>): string;
|
|
152
|
-
export declare namespace md {
|
|
153
|
-
var bold: (s: TemplateInput) => TemplateInput;
|
|
154
|
-
var italic: (s: TemplateInput) => TemplateInput;
|
|
155
|
-
var underline: (s: TemplateInput) => TemplateInput;
|
|
156
|
-
var strikethrough: (s: TemplateInput) => TemplateInput;
|
|
157
|
-
}
|
|
158
|
-
export {};
|
package/lib/diagnostic.js
DELETED
|
@@ -1,285 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.anyToDiagnostic = anyToDiagnostic;
|
|
7
|
-
exports.convertSourceLocationToHighlight = convertSourceLocationToHighlight;
|
|
8
|
-
exports.default = void 0;
|
|
9
|
-
exports.encodeJSONKeyComponent = encodeJSONKeyComponent;
|
|
10
|
-
exports.errorToDiagnostic = errorToDiagnostic;
|
|
11
|
-
exports.escapeMarkdown = escapeMarkdown;
|
|
12
|
-
exports.generateJSONCodeHighlights = generateJSONCodeHighlights;
|
|
13
|
-
exports.getJSONHighlightLocation = getJSONHighlightLocation;
|
|
14
|
-
exports.getJSONSourceLocation = getJSONSourceLocation;
|
|
15
|
-
exports.md = md;
|
|
16
|
-
function _assert() {
|
|
17
|
-
const data = _interopRequireDefault(require("assert"));
|
|
18
|
-
_assert = function () {
|
|
19
|
-
return data;
|
|
20
|
-
};
|
|
21
|
-
return data;
|
|
22
|
-
}
|
|
23
|
-
function _nullthrows() {
|
|
24
|
-
const data = _interopRequireDefault(require("nullthrows"));
|
|
25
|
-
_nullthrows = function () {
|
|
26
|
-
return data;
|
|
27
|
-
};
|
|
28
|
-
return data;
|
|
29
|
-
}
|
|
30
|
-
function _jsonSourcemap() {
|
|
31
|
-
const data = require("@mischnic/json-sourcemap");
|
|
32
|
-
_jsonSourcemap = function () {
|
|
33
|
-
return data;
|
|
34
|
-
};
|
|
35
|
-
return data;
|
|
36
|
-
}
|
|
37
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
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
|
-
/** A JSON object (as in "map") */
|
|
49
|
-
/**
|
|
50
|
-
* A style agnostic way of emitting errors, warnings and info.
|
|
51
|
-
* Reporters are responsible for rendering the message, codeframes, hints, ...
|
|
52
|
-
*/
|
|
53
|
-
// This type should represent all error formats Atlaspack can encounter...
|
|
54
|
-
/** Something that can be turned into a diagnostic. */
|
|
55
|
-
/** Normalize the given value into a diagnostic. */
|
|
56
|
-
function anyToDiagnostic(input) {
|
|
57
|
-
if (Array.isArray(input)) {
|
|
58
|
-
return input.flatMap(e => anyToDiagnostic(e));
|
|
59
|
-
} else if (input instanceof ThrowableDiagnostic) {
|
|
60
|
-
return input.diagnostics;
|
|
61
|
-
} else if (input instanceof Error) {
|
|
62
|
-
return errorToDiagnostic(input);
|
|
63
|
-
} else if (typeof input === 'string') {
|
|
64
|
-
return [{
|
|
65
|
-
message: input
|
|
66
|
-
}];
|
|
67
|
-
} else if (typeof input === 'object') {
|
|
68
|
-
return [input];
|
|
69
|
-
} else {
|
|
70
|
-
return errorToDiagnostic(input);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/** Normalize the given error into a diagnostic. */
|
|
75
|
-
function errorToDiagnostic(error, defaultValues) {
|
|
76
|
-
let codeFrames = undefined;
|
|
77
|
-
if (typeof error === 'string') {
|
|
78
|
-
return [{
|
|
79
|
-
origin: (defaultValues === null || defaultValues === void 0 ? void 0 : defaultValues.origin) ?? 'Error',
|
|
80
|
-
message: escapeMarkdown(error)
|
|
81
|
-
}];
|
|
82
|
-
}
|
|
83
|
-
if (error instanceof ThrowableDiagnostic) {
|
|
84
|
-
return error.diagnostics.map(d => {
|
|
85
|
-
return {
|
|
86
|
-
...d,
|
|
87
|
-
origin: d.origin ?? (defaultValues === null || defaultValues === void 0 ? void 0 : defaultValues.origin) ?? 'unknown'
|
|
88
|
-
};
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
if (error.loc && error.source != null) {
|
|
92
|
-
codeFrames = [{
|
|
93
|
-
filePath: error.filePath ?? error.fileName ?? (defaultValues === null || defaultValues === void 0 ? void 0 : defaultValues.filePath) ?? undefined,
|
|
94
|
-
code: error.source,
|
|
95
|
-
codeHighlights: [{
|
|
96
|
-
start: {
|
|
97
|
-
line: error.loc.line,
|
|
98
|
-
column: error.loc.column
|
|
99
|
-
},
|
|
100
|
-
end: {
|
|
101
|
-
line: error.loc.line,
|
|
102
|
-
column: error.loc.column
|
|
103
|
-
}
|
|
104
|
-
}]
|
|
105
|
-
}];
|
|
106
|
-
}
|
|
107
|
-
return [{
|
|
108
|
-
origin: (defaultValues === null || defaultValues === void 0 ? void 0 : defaultValues.origin) ?? 'Error',
|
|
109
|
-
message: escapeMarkdown(error.message),
|
|
110
|
-
name: error.name,
|
|
111
|
-
stack: codeFrames == null ? error.highlightedCodeFrame ?? error.codeFrame ?? error.stack : undefined,
|
|
112
|
-
codeFrames
|
|
113
|
-
}];
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* An error wrapper around a diagnostic that can be <code>throw</code>n (e.g. to signal a
|
|
117
|
-
* build error).
|
|
118
|
-
*/
|
|
119
|
-
class ThrowableDiagnostic extends Error {
|
|
120
|
-
constructor(opts) {
|
|
121
|
-
let diagnostics = Array.isArray(opts.diagnostic) ? opts.diagnostic : [opts.diagnostic];
|
|
122
|
-
|
|
123
|
-
// Construct error from diagnostics
|
|
124
|
-
super(diagnostics[0].message);
|
|
125
|
-
// @ts-ignore
|
|
126
|
-
this.stack = diagnostics[0].stack ?? super.stack;
|
|
127
|
-
// @ts-ignore
|
|
128
|
-
this.name = diagnostics[0].name ?? super.name;
|
|
129
|
-
this.diagnostics = diagnostics;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Turns a list of positions in a JSON5 file with messages into a list of diagnostics.
|
|
135
|
-
* Uses <a href="https://github.com/mischnic/json-sourcemap">@mischnic/json-sourcemap</a>.
|
|
136
|
-
*
|
|
137
|
-
* @param code the JSON code
|
|
138
|
-
* @param ids A list of JSON keypaths (<code>key: "/some/parent/child"</code>) with corresponding messages, \
|
|
139
|
-
* <code>type</code> signifies whether the key of the value in a JSON object should be highlighted.
|
|
140
|
-
*/
|
|
141
|
-
exports.default = ThrowableDiagnostic;
|
|
142
|
-
function generateJSONCodeHighlights(data, ids) {
|
|
143
|
-
let map = typeof data == 'string' ? (0, _jsonSourcemap().parse)(data, undefined, {
|
|
144
|
-
dialect: 'JSON5',
|
|
145
|
-
tabWidth: 1
|
|
146
|
-
}) : data;
|
|
147
|
-
return ids.map(({
|
|
148
|
-
key,
|
|
149
|
-
type,
|
|
150
|
-
message
|
|
151
|
-
}) => {
|
|
152
|
-
let pos = (0, _nullthrows().default)(map.pointers[key]);
|
|
153
|
-
return {
|
|
154
|
-
...getJSONHighlightLocation(pos, type),
|
|
155
|
-
message
|
|
156
|
-
};
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Converts entries in <a href="https://github.com/mischnic/json-sourcemap">@mischnic/json-sourcemap</a>'s
|
|
162
|
-
* <code>result.pointers</code> array.
|
|
163
|
-
*/
|
|
164
|
-
function getJSONHighlightLocation(pos, type) {
|
|
165
|
-
let key = 'key' in pos ? pos.key : undefined;
|
|
166
|
-
let keyEnd = 'keyEnd' in pos ? pos.keyEnd : undefined;
|
|
167
|
-
if (!type && key && pos.value) {
|
|
168
|
-
// key and value
|
|
169
|
-
return {
|
|
170
|
-
start: {
|
|
171
|
-
line: key.line + 1,
|
|
172
|
-
column: key.column + 1
|
|
173
|
-
},
|
|
174
|
-
end: {
|
|
175
|
-
line: pos.valueEnd.line + 1,
|
|
176
|
-
column: pos.valueEnd.column
|
|
177
|
-
}
|
|
178
|
-
};
|
|
179
|
-
} else if (type == 'key' || !pos.value) {
|
|
180
|
-
(0, _assert().default)(key && keyEnd);
|
|
181
|
-
return {
|
|
182
|
-
start: {
|
|
183
|
-
line: key.line + 1,
|
|
184
|
-
column: key.column + 1
|
|
185
|
-
},
|
|
186
|
-
end: {
|
|
187
|
-
line: keyEnd.line + 1,
|
|
188
|
-
column: keyEnd.column
|
|
189
|
-
}
|
|
190
|
-
};
|
|
191
|
-
} else {
|
|
192
|
-
return {
|
|
193
|
-
start: {
|
|
194
|
-
line: pos.value.line + 1,
|
|
195
|
-
column: pos.value.column + 1
|
|
196
|
-
},
|
|
197
|
-
end: {
|
|
198
|
-
line: pos.valueEnd.line + 1,
|
|
199
|
-
column: pos.valueEnd.column
|
|
200
|
-
}
|
|
201
|
-
};
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/** Result is 1-based, but end is exclusive */
|
|
206
|
-
function getJSONSourceLocation(pos, type) {
|
|
207
|
-
let v = getJSONHighlightLocation(pos, type);
|
|
208
|
-
return {
|
|
209
|
-
start: v.start,
|
|
210
|
-
end: {
|
|
211
|
-
line: v.end.line,
|
|
212
|
-
column: v.end.column + 1
|
|
213
|
-
}
|
|
214
|
-
};
|
|
215
|
-
}
|
|
216
|
-
function convertSourceLocationToHighlight({
|
|
217
|
-
start,
|
|
218
|
-
end
|
|
219
|
-
}, message) {
|
|
220
|
-
return {
|
|
221
|
-
message,
|
|
222
|
-
start,
|
|
223
|
-
end: {
|
|
224
|
-
line: end.line,
|
|
225
|
-
column: end.column - 1
|
|
226
|
-
}
|
|
227
|
-
};
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
/** Sanitizes object keys before using them as <code>key</code> in generateJSONCodeHighlights */
|
|
231
|
-
function encodeJSONKeyComponent(component) {
|
|
232
|
-
return component.replace(/~/g, '~0').replace(/\//g, '~1');
|
|
233
|
-
}
|
|
234
|
-
const escapeCharacters = ['\\', '*', '_', '~'];
|
|
235
|
-
function escapeMarkdown(s) {
|
|
236
|
-
let result = s;
|
|
237
|
-
for (const char of escapeCharacters) {
|
|
238
|
-
result = result.replace(new RegExp(`\\${char}`, 'g'), `\\${char}`);
|
|
239
|
-
}
|
|
240
|
-
return result;
|
|
241
|
-
}
|
|
242
|
-
const mdVerbatim = Symbol();
|
|
243
|
-
function md(strings, ...params) {
|
|
244
|
-
let result = [];
|
|
245
|
-
for (let i = 0; i < params.length; i++) {
|
|
246
|
-
result.push(strings[i]);
|
|
247
|
-
let param = params[i];
|
|
248
|
-
if (Array.isArray(param)) {
|
|
249
|
-
for (let j = 0; j < param.length; j++) {
|
|
250
|
-
var _param$j;
|
|
251
|
-
result.push(((_param$j = param[j]) === null || _param$j === void 0 ? void 0 : _param$j[mdVerbatim]) ?? escapeMarkdown(`${param[j]}`));
|
|
252
|
-
if (j < param.length - 1) {
|
|
253
|
-
result.push(', ');
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
} else {
|
|
257
|
-
result.push((param === null || param === void 0 ? void 0 : param[mdVerbatim]) ?? escapeMarkdown(`${param}`));
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
return result.join('') + strings[strings.length - 1];
|
|
261
|
-
}
|
|
262
|
-
md.bold = function (s) {
|
|
263
|
-
// $FlowFixMe[invalid-computed-prop]
|
|
264
|
-
return {
|
|
265
|
-
[mdVerbatim]: '**' + escapeMarkdown(`${s}`) + '**'
|
|
266
|
-
};
|
|
267
|
-
};
|
|
268
|
-
md.italic = function (s) {
|
|
269
|
-
// $FlowFixMe[invalid-computed-prop]
|
|
270
|
-
return {
|
|
271
|
-
[mdVerbatim]: '_' + escapeMarkdown(`${s}`) + '_'
|
|
272
|
-
};
|
|
273
|
-
};
|
|
274
|
-
md.underline = function (s) {
|
|
275
|
-
// $FlowFixMe[invalid-computed-prop]
|
|
276
|
-
return {
|
|
277
|
-
[mdVerbatim]: '__' + escapeMarkdown(`${s}`) + '__'
|
|
278
|
-
};
|
|
279
|
-
};
|
|
280
|
-
md.strikethrough = function (s) {
|
|
281
|
-
// $FlowFixMe[invalid-computed-prop]
|
|
282
|
-
return {
|
|
283
|
-
[mdVerbatim]: '~~' + escapeMarkdown(`${s}`) + '~~'
|
|
284
|
-
};
|
|
285
|
-
};
|
package/src/diagnostic.js
DELETED
|
@@ -1,385 +0,0 @@
|
|
|
1
|
-
// @flow strict-local
|
|
2
|
-
|
|
3
|
-
import invariant from 'assert';
|
|
4
|
-
import nullthrows from 'nullthrows';
|
|
5
|
-
import {parse, type Mapping} from '@mischnic/json-sourcemap';
|
|
6
|
-
|
|
7
|
-
/** These positions are 1-based (so <code>1</code> is the first line/column) */
|
|
8
|
-
export type DiagnosticHighlightLocation = {|
|
|
9
|
-
+line: number,
|
|
10
|
-
+column: number,
|
|
11
|
-
|};
|
|
12
|
-
|
|
13
|
-
export type DiagnosticSeverity = 'error' | 'warn' | 'info';
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Note: A tab character is always counted as a single character
|
|
17
|
-
* This is to prevent any mismatch of highlighting across machines
|
|
18
|
-
*/
|
|
19
|
-
export type DiagnosticCodeHighlight = {|
|
|
20
|
-
/** Location of the first character that should get highlighted for this highlight. */
|
|
21
|
-
start: DiagnosticHighlightLocation,
|
|
22
|
-
/** Location of the last character that should get highlighted for this highlight. */
|
|
23
|
-
end: DiagnosticHighlightLocation,
|
|
24
|
-
/** A message that should be displayed at this location in the code (optional). */
|
|
25
|
-
message?: string,
|
|
26
|
-
|};
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Describes how to format a code frame.
|
|
30
|
-
* A code frame is a visualization of a piece of code with a certain amount of
|
|
31
|
-
* code highlights that point to certain chunk(s) inside the code.
|
|
32
|
-
*/
|
|
33
|
-
export type DiagnosticCodeFrame = {|
|
|
34
|
-
/**
|
|
35
|
-
* The contents of the source file.
|
|
36
|
-
*
|
|
37
|
-
* If no code is passed, it will be read in from filePath, remember that
|
|
38
|
-
* the asset's current code could be different from the input contents.
|
|
39
|
-
*
|
|
40
|
-
*/
|
|
41
|
-
code?: string,
|
|
42
|
-
/** Path to the file this code frame is about (optional, absolute or relative to the project root) */
|
|
43
|
-
filePath?: string,
|
|
44
|
-
/** Language of the file this code frame is about (optional) */
|
|
45
|
-
language?: string,
|
|
46
|
-
codeHighlights: Array<DiagnosticCodeHighlight>,
|
|
47
|
-
|};
|
|
48
|
-
|
|
49
|
-
/** A JSON object (as in "map") */
|
|
50
|
-
type JSONObject = {
|
|
51
|
-
// $FlowFixMe
|
|
52
|
-
[key: string]: any,
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* A style agnostic way of emitting errors, warnings and info.
|
|
57
|
-
* Reporters are responsible for rendering the message, codeframes, hints, ...
|
|
58
|
-
*/
|
|
59
|
-
export type Diagnostic = {|
|
|
60
|
-
/** This is the message you want to log. */
|
|
61
|
-
message: string,
|
|
62
|
-
/** Name of plugin or file that threw this error */
|
|
63
|
-
origin?: string,
|
|
64
|
-
|
|
65
|
-
/** A stacktrace of the error (optional) */
|
|
66
|
-
stack?: string,
|
|
67
|
-
/** Name of the error (optional) */
|
|
68
|
-
name?: string,
|
|
69
|
-
|
|
70
|
-
/** A code frame points to a certain location(s) in the file this diagnostic is linked to (optional) */
|
|
71
|
-
codeFrames?: ?Array<DiagnosticCodeFrame>,
|
|
72
|
-
|
|
73
|
-
/** An optional list of strings that suggest ways to resolve this issue */
|
|
74
|
-
hints?: Array<string>,
|
|
75
|
-
|
|
76
|
-
/** @private */
|
|
77
|
-
skipFormatting?: boolean,
|
|
78
|
-
|
|
79
|
-
/** A URL to documentation to learn more about the diagnostic. */
|
|
80
|
-
documentationURL?: string,
|
|
81
|
-
|
|
82
|
-
/** Diagnostic specific metadata (optional) */
|
|
83
|
-
meta?: JSONObject,
|
|
84
|
-
|};
|
|
85
|
-
|
|
86
|
-
// This type should represent all error formats Atlaspack can encounter...
|
|
87
|
-
export interface PrintableError extends Error {
|
|
88
|
-
fileName?: string;
|
|
89
|
-
filePath?: string;
|
|
90
|
-
codeFrame?: string;
|
|
91
|
-
highlightedCodeFrame?: string;
|
|
92
|
-
loc?: ?{
|
|
93
|
-
column: number,
|
|
94
|
-
line: number,
|
|
95
|
-
...
|
|
96
|
-
};
|
|
97
|
-
source?: string;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export type DiagnosticWithoutOrigin = {|
|
|
101
|
-
...Diagnostic,
|
|
102
|
-
origin?: string,
|
|
103
|
-
|};
|
|
104
|
-
|
|
105
|
-
/** Something that can be turned into a diagnostic. */
|
|
106
|
-
export type Diagnostifiable =
|
|
107
|
-
| Diagnostic
|
|
108
|
-
| Array<Diagnostic>
|
|
109
|
-
| ThrowableDiagnostic
|
|
110
|
-
| PrintableError
|
|
111
|
-
| Error
|
|
112
|
-
| string;
|
|
113
|
-
|
|
114
|
-
/** Normalize the given value into a diagnostic. */
|
|
115
|
-
export function anyToDiagnostic(input: Diagnostifiable): Array<Diagnostic> {
|
|
116
|
-
if (Array.isArray(input)) {
|
|
117
|
-
return input.flatMap((e) => anyToDiagnostic(e));
|
|
118
|
-
} else if (input instanceof ThrowableDiagnostic) {
|
|
119
|
-
return input.diagnostics;
|
|
120
|
-
} else if (input instanceof Error) {
|
|
121
|
-
return errorToDiagnostic(input);
|
|
122
|
-
} else if (typeof input === 'string') {
|
|
123
|
-
return [{message: input}];
|
|
124
|
-
} else if (typeof input === 'object') {
|
|
125
|
-
return [input];
|
|
126
|
-
} else {
|
|
127
|
-
return errorToDiagnostic(input);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/** Normalize the given error into a diagnostic. */
|
|
132
|
-
export function errorToDiagnostic(
|
|
133
|
-
error: ThrowableDiagnostic | PrintableError | string,
|
|
134
|
-
defaultValues?: {|
|
|
135
|
-
origin?: ?string,
|
|
136
|
-
filePath?: ?string,
|
|
137
|
-
|},
|
|
138
|
-
): Array<Diagnostic> {
|
|
139
|
-
let codeFrames: ?Array<DiagnosticCodeFrame> = undefined;
|
|
140
|
-
|
|
141
|
-
if (typeof error === 'string') {
|
|
142
|
-
return [
|
|
143
|
-
{
|
|
144
|
-
origin: defaultValues?.origin ?? 'Error',
|
|
145
|
-
message: escapeMarkdown(error),
|
|
146
|
-
},
|
|
147
|
-
];
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
if (error instanceof ThrowableDiagnostic) {
|
|
151
|
-
return error.diagnostics.map((d) => {
|
|
152
|
-
return {
|
|
153
|
-
...d,
|
|
154
|
-
origin: d.origin ?? defaultValues?.origin ?? 'unknown',
|
|
155
|
-
};
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
if (error.loc && error.source != null) {
|
|
160
|
-
codeFrames = [
|
|
161
|
-
{
|
|
162
|
-
filePath:
|
|
163
|
-
error.filePath ??
|
|
164
|
-
error.fileName ??
|
|
165
|
-
defaultValues?.filePath ??
|
|
166
|
-
undefined,
|
|
167
|
-
code: error.source,
|
|
168
|
-
codeHighlights: [
|
|
169
|
-
{
|
|
170
|
-
start: {
|
|
171
|
-
line: error.loc.line,
|
|
172
|
-
column: error.loc.column,
|
|
173
|
-
},
|
|
174
|
-
end: {
|
|
175
|
-
line: error.loc.line,
|
|
176
|
-
column: error.loc.column,
|
|
177
|
-
},
|
|
178
|
-
},
|
|
179
|
-
],
|
|
180
|
-
},
|
|
181
|
-
];
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
return [
|
|
185
|
-
{
|
|
186
|
-
origin: defaultValues?.origin ?? 'Error',
|
|
187
|
-
message: escapeMarkdown(error.message),
|
|
188
|
-
name: error.name,
|
|
189
|
-
stack:
|
|
190
|
-
codeFrames == null
|
|
191
|
-
? error.highlightedCodeFrame ?? error.codeFrame ?? error.stack
|
|
192
|
-
: undefined,
|
|
193
|
-
codeFrames,
|
|
194
|
-
},
|
|
195
|
-
];
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
type ThrowableDiagnosticOpts = {
|
|
199
|
-
diagnostic: Diagnostic | Array<Diagnostic>,
|
|
200
|
-
...
|
|
201
|
-
};
|
|
202
|
-
|
|
203
|
-
/**
|
|
204
|
-
* An error wrapper around a diagnostic that can be <code>throw</code>n (e.g. to signal a
|
|
205
|
-
* build error).
|
|
206
|
-
*/
|
|
207
|
-
export default class ThrowableDiagnostic extends Error {
|
|
208
|
-
diagnostics: Array<Diagnostic>;
|
|
209
|
-
|
|
210
|
-
constructor(opts: ThrowableDiagnosticOpts) {
|
|
211
|
-
let diagnostics = Array.isArray(opts.diagnostic)
|
|
212
|
-
? opts.diagnostic
|
|
213
|
-
: [opts.diagnostic];
|
|
214
|
-
|
|
215
|
-
// Construct error from diagnostics
|
|
216
|
-
super(diagnostics[0].message);
|
|
217
|
-
// @ts-ignore
|
|
218
|
-
this.stack = diagnostics[0].stack ?? super.stack;
|
|
219
|
-
// @ts-ignore
|
|
220
|
-
this.name = diagnostics[0].name ?? super.name;
|
|
221
|
-
|
|
222
|
-
this.diagnostics = diagnostics;
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
/**
|
|
227
|
-
* Turns a list of positions in a JSON5 file with messages into a list of diagnostics.
|
|
228
|
-
* Uses <a href="https://github.com/mischnic/json-sourcemap">@mischnic/json-sourcemap</a>.
|
|
229
|
-
*
|
|
230
|
-
* @param code the JSON code
|
|
231
|
-
* @param ids A list of JSON keypaths (<code>key: "/some/parent/child"</code>) with corresponding messages, \
|
|
232
|
-
* <code>type</code> signifies whether the key of the value in a JSON object should be highlighted.
|
|
233
|
-
*/
|
|
234
|
-
export function generateJSONCodeHighlights(
|
|
235
|
-
data:
|
|
236
|
-
| string
|
|
237
|
-
| {|
|
|
238
|
-
data: mixed,
|
|
239
|
-
pointers: {|[key: string]: Mapping|},
|
|
240
|
-
|},
|
|
241
|
-
ids: Array<{|key: string, type?: ?'key' | 'value', message?: string|}>,
|
|
242
|
-
): Array<DiagnosticCodeHighlight> {
|
|
243
|
-
let map =
|
|
244
|
-
typeof data == 'string'
|
|
245
|
-
? parse(data, undefined, {dialect: 'JSON5', tabWidth: 1})
|
|
246
|
-
: data;
|
|
247
|
-
return ids.map(({key, type, message}) => {
|
|
248
|
-
let pos = nullthrows(map.pointers[key]);
|
|
249
|
-
return {
|
|
250
|
-
...getJSONHighlightLocation(pos, type),
|
|
251
|
-
message,
|
|
252
|
-
};
|
|
253
|
-
});
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
/**
|
|
257
|
-
* Converts entries in <a href="https://github.com/mischnic/json-sourcemap">@mischnic/json-sourcemap</a>'s
|
|
258
|
-
* <code>result.pointers</code> array.
|
|
259
|
-
*/
|
|
260
|
-
export function getJSONHighlightLocation(
|
|
261
|
-
pos: Mapping,
|
|
262
|
-
type?: ?'key' | 'value',
|
|
263
|
-
): {|
|
|
264
|
-
start: DiagnosticHighlightLocation,
|
|
265
|
-
end: DiagnosticHighlightLocation,
|
|
266
|
-
|} {
|
|
267
|
-
let key = 'key' in pos ? pos.key : undefined;
|
|
268
|
-
let keyEnd = 'keyEnd' in pos ? pos.keyEnd : undefined;
|
|
269
|
-
if (!type && key && pos.value) {
|
|
270
|
-
// key and value
|
|
271
|
-
return {
|
|
272
|
-
start: {line: key.line + 1, column: key.column + 1},
|
|
273
|
-
end: {line: pos.valueEnd.line + 1, column: pos.valueEnd.column},
|
|
274
|
-
};
|
|
275
|
-
} else if (type == 'key' || !pos.value) {
|
|
276
|
-
invariant(key && keyEnd);
|
|
277
|
-
return {
|
|
278
|
-
start: {line: key.line + 1, column: key.column + 1},
|
|
279
|
-
end: {line: keyEnd.line + 1, column: keyEnd.column},
|
|
280
|
-
};
|
|
281
|
-
} else {
|
|
282
|
-
return {
|
|
283
|
-
start: {line: pos.value.line + 1, column: pos.value.column + 1},
|
|
284
|
-
end: {line: pos.valueEnd.line + 1, column: pos.valueEnd.column},
|
|
285
|
-
};
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
/** Result is 1-based, but end is exclusive */
|
|
290
|
-
export function getJSONSourceLocation(
|
|
291
|
-
pos: Mapping,
|
|
292
|
-
type?: ?'key' | 'value',
|
|
293
|
-
): {|
|
|
294
|
-
start: {|
|
|
295
|
-
+line: number,
|
|
296
|
-
+column: number,
|
|
297
|
-
|},
|
|
298
|
-
end: {|
|
|
299
|
-
+line: number,
|
|
300
|
-
+column: number,
|
|
301
|
-
|},
|
|
302
|
-
|} {
|
|
303
|
-
let v = getJSONHighlightLocation(pos, type);
|
|
304
|
-
return {start: v.start, end: {line: v.end.line, column: v.end.column + 1}};
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
export function convertSourceLocationToHighlight<
|
|
308
|
-
Location: {
|
|
309
|
-
/** 1-based, inclusive */
|
|
310
|
-
+start: {|
|
|
311
|
-
+line: number,
|
|
312
|
-
+column: number,
|
|
313
|
-
|},
|
|
314
|
-
/** 1-based, exclusive */
|
|
315
|
-
+end: {|
|
|
316
|
-
+line: number,
|
|
317
|
-
+column: number,
|
|
318
|
-
|},
|
|
319
|
-
...
|
|
320
|
-
},
|
|
321
|
-
>({start, end}: Location, message?: string): DiagnosticCodeHighlight {
|
|
322
|
-
return {message, start, end: {line: end.line, column: end.column - 1}};
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
/** Sanitizes object keys before using them as <code>key</code> in generateJSONCodeHighlights */
|
|
326
|
-
export function encodeJSONKeyComponent(component: string): string {
|
|
327
|
-
return component.replace(/~/g, '~0').replace(/\//g, '~1');
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
const escapeCharacters = ['\\', '*', '_', '~'];
|
|
331
|
-
|
|
332
|
-
export function escapeMarkdown(s: string): string {
|
|
333
|
-
let result = s;
|
|
334
|
-
for (const char of escapeCharacters) {
|
|
335
|
-
result = result.replace(new RegExp(`\\${char}`, 'g'), `\\${char}`);
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
return result;
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
type TemplateInput = $FlowFixMe;
|
|
342
|
-
|
|
343
|
-
const mdVerbatim = Symbol();
|
|
344
|
-
export function md(
|
|
345
|
-
strings: Array<string>,
|
|
346
|
-
...params: Array<TemplateInput>
|
|
347
|
-
): string {
|
|
348
|
-
let result = [];
|
|
349
|
-
for (let i = 0; i < params.length; i++) {
|
|
350
|
-
result.push(strings[i]);
|
|
351
|
-
|
|
352
|
-
let param = params[i];
|
|
353
|
-
if (Array.isArray(param)) {
|
|
354
|
-
for (let j = 0; j < param.length; j++) {
|
|
355
|
-
result.push(param[j]?.[mdVerbatim] ?? escapeMarkdown(`${param[j]}`));
|
|
356
|
-
if (j < param.length - 1) {
|
|
357
|
-
result.push(', ');
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
} else {
|
|
361
|
-
result.push(param?.[mdVerbatim] ?? escapeMarkdown(`${param}`));
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
return result.join('') + strings[strings.length - 1];
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
md.bold = function (s: TemplateInput): TemplateInput {
|
|
368
|
-
// $FlowFixMe[invalid-computed-prop]
|
|
369
|
-
return {[mdVerbatim]: '**' + escapeMarkdown(`${s}`) + '**'};
|
|
370
|
-
};
|
|
371
|
-
|
|
372
|
-
md.italic = function (s: TemplateInput): TemplateInput {
|
|
373
|
-
// $FlowFixMe[invalid-computed-prop]
|
|
374
|
-
return {[mdVerbatim]: '_' + escapeMarkdown(`${s}`) + '_'};
|
|
375
|
-
};
|
|
376
|
-
|
|
377
|
-
md.underline = function (s: TemplateInput): TemplateInput {
|
|
378
|
-
// $FlowFixMe[invalid-computed-prop]
|
|
379
|
-
return {[mdVerbatim]: '__' + escapeMarkdown(`${s}`) + '__'};
|
|
380
|
-
};
|
|
381
|
-
|
|
382
|
-
md.strikethrough = function (s: TemplateInput): TemplateInput {
|
|
383
|
-
// $FlowFixMe[invalid-computed-prop]
|
|
384
|
-
return {[mdVerbatim]: '~~' + escapeMarkdown(`${s}`) + '~~'};
|
|
385
|
-
};
|
|
@@ -1,36 +0,0 @@
|
|
|
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
|
-
});
|
package/test/markdown.test.js
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
// @flow
|
|
2
|
-
import assert from 'assert';
|
|
3
|
-
|
|
4
|
-
import {escapeMarkdown, md} from '../src/diagnostic';
|
|
5
|
-
|
|
6
|
-
describe('escapeMarkdown', () => {
|
|
7
|
-
it('returns an escaped string 01', () => {
|
|
8
|
-
assert.strictEqual('\\*test\\*', escapeMarkdown('*test*'));
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
it('returns an escaped string 02', () => {
|
|
12
|
-
assert.strictEqual('\\_test\\_', escapeMarkdown('_test_'));
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it('returns an escaped string 03', () => {
|
|
16
|
-
assert.strictEqual('\\~test\\~', escapeMarkdown('~test~'));
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
it('returns an escaped string 04', () => {
|
|
20
|
-
assert.strictEqual('\\*\\_\\~test\\~\\_\\*', escapeMarkdown('*_~test~_*'));
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
it('returns an escaped string with backslash 01', () => {
|
|
24
|
-
assert.strictEqual('\\\\test\\\\', escapeMarkdown('\\test\\'));
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it('returns an escaped string with backslash 02', () => {
|
|
28
|
-
assert.strictEqual('\\\\\\*test\\*\\\\', escapeMarkdown('\\*test*\\'));
|
|
29
|
-
});
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
describe('md tagged template literal', () => {
|
|
33
|
-
it('bold placeholder', () => {
|
|
34
|
-
assert.strictEqual(
|
|
35
|
-
'*Test*: **\\_abc\\_**',
|
|
36
|
-
md`*Test*: ${md.bold('_abc_')}`,
|
|
37
|
-
);
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it('italic placeholder', () => {
|
|
41
|
-
assert.strictEqual(
|
|
42
|
-
'*Test*: _\\_abc\\__',
|
|
43
|
-
md`*Test*: ${md.italic('_abc_')}`,
|
|
44
|
-
);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it('underline placeholder', () => {
|
|
48
|
-
assert.strictEqual(
|
|
49
|
-
'*Test*: __\\_abc\\___',
|
|
50
|
-
md`*Test*: ${md.underline('_abc_')}`,
|
|
51
|
-
);
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it('strikethrough placeholder', () => {
|
|
55
|
-
assert.strictEqual(
|
|
56
|
-
'*Test*: ~~\\_abc\\_~~',
|
|
57
|
-
md`*Test*: ${md.strikethrough('_abc_')}`,
|
|
58
|
-
);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it('escapes only placeholders', () => {
|
|
62
|
-
assert.strictEqual('*Test*: \\_abc\\_', md`*Test*: ${'_abc_'}`);
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it('behaves like native template literal', () => {
|
|
66
|
-
let v = {
|
|
67
|
-
toString() {
|
|
68
|
-
return 'a';
|
|
69
|
-
},
|
|
70
|
-
// $FlowFixMe[invalid-computed-prop]
|
|
71
|
-
[Symbol.toPrimitive]() {
|
|
72
|
-
return 'b';
|
|
73
|
-
},
|
|
74
|
-
};
|
|
75
|
-
assert.strictEqual('Test: b', md`Test: ${v}`);
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it('supports null and undefined', () => {
|
|
79
|
-
assert.strictEqual('Test: undefined null', md`Test: ${undefined} ${null}`);
|
|
80
|
-
});
|
|
81
|
-
});
|