@remotex-labs/xmap 3.0.5 → 4.0.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/README.md +190 -122
- package/dist/cjs/formatter.component.js +3 -3
- package/dist/cjs/formatter.component.js.map +3 -3
- package/dist/cjs/highlighter.component.js +1 -1
- package/dist/cjs/highlighter.component.js.map +4 -4
- package/dist/cjs/index.js +3 -3
- package/dist/cjs/index.js.map +4 -4
- package/dist/cjs/parser.component.js +1 -1
- package/dist/cjs/parser.component.js.map +3 -3
- package/dist/esm/formatter.component.js +4 -4
- package/dist/esm/formatter.component.js.map +3 -3
- package/dist/esm/highlighter.component.js +1 -1
- package/dist/esm/highlighter.component.js.map +4 -4
- package/dist/esm/index.js +3 -3
- package/dist/esm/index.js.map +4 -4
- package/dist/esm/parser.component.js +2 -2
- package/dist/esm/parser.component.js.map +3 -3
- package/dist/formatter.component.d.ts +256 -95
- package/dist/highlighter.component.d.ts +169 -128
- package/dist/index.d.ts +429 -400
- package/dist/parser.component.d.ts +84 -72
- package/package.json +19 -12
package/README.md
CHANGED
|
@@ -1,8 +1,20 @@
|
|
|
1
|
-
# xMap
|
|
2
|
-
`xMap` is a library designed to help with sourcemap parsing and TypeScript code formatting for the CLI.\
|
|
3
|
-
It includes components for parsing error stack traces, formatting code, and providing syntax highlighting, as well as a service for handling source maps.
|
|
1
|
+
# xMap
|
|
4
2
|
|
|
5
|
-
|
|
3
|
+
[](https://remotex-labs.github.io/xMap/)
|
|
4
|
+
[](https://www.npmjs.com/package/@remotex-labs/xmap)
|
|
5
|
+
[](https://opensource.org/licenses/MPL-2.0)
|
|
6
|
+
[](https://github.com/remotex-labs/xMap/actions/workflows/node.js.yml)
|
|
7
|
+
|
|
8
|
+
`xMap` is a TypeScript library for working with source maps, stack trace parsing, and code formatting. It provides powerful tools for debugging, error reporting, and code visualization in CLI environments.
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
- **Source Map Processing**: Parse, manipulate, and query source maps
|
|
12
|
+
- **Stack Trace Parsing**: Parse error stacks from V8, SpiderMonkey, and JavaScriptCore engines
|
|
13
|
+
- **Code Formatting**: Display code with line numbers and custom highlighting
|
|
14
|
+
- **Syntax Highlighting**: Semantic TypeScript code highlighting with customizable themes
|
|
15
|
+
- **Error Visualization**: Format code snippets with error indicators
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
6
18
|
To install the package, use npm or yarn:
|
|
7
19
|
```bash
|
|
8
20
|
npm install @remotex-labs/xmap
|
|
@@ -11,170 +23,211 @@ or
|
|
|
11
23
|
```bash
|
|
12
24
|
yarn add @remotex-labs/xmap
|
|
13
25
|
```
|
|
14
|
-
# Usage SourceService
|
|
15
|
-
A TypeScript service for validating and processing source maps.
|
|
16
|
-
The `SourceService` class provides functionality for parsing and manipulating source maps, including retrieving position mappings,
|
|
17
|
-
concatenating source maps, and getting code snippets based on mappings.
|
|
18
|
-
|
|
19
|
-
### Importing the SourceService
|
|
20
|
-
You can import the SourceService class in your TypeScript project as follows:
|
|
21
|
-
```typescript
|
|
22
|
-
import { SourceService } from '@remotex-labs/xmap'
|
|
23
|
-
```
|
|
24
26
|
|
|
25
|
-
##
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
## Optimizing Bundle Size
|
|
28
|
+
xMap supports subpath imports, allowing you to import only the specific components you need:
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
// Import only what you need
|
|
32
|
+
import { parseErrorStack } from '@remotex-labs/xmap/parser.component';
|
|
33
|
+
import { formatCode } from '@remotex-labs/xmap/formatter.component';
|
|
34
|
+
import { highlightCode } from '@remotex-labs/xmap/highlighter.component';
|
|
30
35
|
import { SourceService } from '@remotex-labs/xmap';
|
|
36
|
+
```
|
|
31
37
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
`;
|
|
38
|
+
## Key Components
|
|
39
|
+
### SourceService
|
|
40
|
+
Process and query source maps to get original positions, concatenate maps, and retrieve code snippets.
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
import { SourceService, Bias } from '@remotex-labs/xmap';
|
|
44
|
+
|
|
45
|
+
// Create from JSON string
|
|
42
46
|
const sourceService = new SourceService(sourceMapJSON, 'bundle.js');
|
|
43
|
-
console.log(sourceService);
|
|
44
|
-
```
|
|
45
47
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
Example:
|
|
49
|
-
```typescript
|
|
50
|
-
const position = sourceService.getPositionByOriginal(3, 7, 'index.ts');
|
|
51
|
-
console.log(position);
|
|
52
|
-
```
|
|
53
|
-
## Getting Code Snippets
|
|
54
|
-
To retrieve the position and a code snippet from the original source based on the given generated code position,
|
|
55
|
-
you can use the `getPositionWithCode` method.
|
|
56
|
-
Example:
|
|
57
|
-
```typescript
|
|
58
|
-
const positionWithCode = sourceService.getPositionWithCode(1, 104, Bias.UPPER_BOUND, { linesBefore: 2, linesAfter: 2 });
|
|
59
|
-
console.log(positionWithCode);
|
|
60
|
-
```
|
|
48
|
+
// Get original position for generated code
|
|
49
|
+
const originalPosition = sourceService.getPositionByGenerated(12, 34);
|
|
61
50
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
51
|
+
// Get position with code context
|
|
52
|
+
const positionWithCode = sourceService.getPositionWithCode(12, 34, Bias.LOWER_BOUND, {
|
|
53
|
+
linesBefore: 2,
|
|
54
|
+
linesAfter: 2
|
|
55
|
+
});
|
|
67
56
|
```
|
|
68
57
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
file: "another-bundle.js",
|
|
75
|
-
sources: ["bar.ts"],
|
|
76
|
-
names: [],
|
|
77
|
-
mappings: "AAAA"
|
|
78
|
-
};
|
|
58
|
+
#### Understanding Bias
|
|
59
|
+
When querying source maps, the parameter controls how positions are matched: `Bias`
|
|
60
|
+
- `Bias.BOUND` - No directional preference; returns the first match found
|
|
61
|
+
- `Bias.LOWER_BOUND` - Prefers segments with column values ≤ the target
|
|
62
|
+
- `Bias.UPPER_BOUND` - Prefers segments with column values ≥ the target `Bias.UPPER_BOUND`
|
|
79
63
|
|
|
80
|
-
|
|
81
|
-
|
|
64
|
+
Example:
|
|
65
|
+
```ts
|
|
66
|
+
// Using different bias values for position lookup
|
|
67
|
+
const exactPosition = sourceService.getPosition(10, 15, Bias.BOUND);
|
|
68
|
+
const beforePosition = sourceService.getPosition(10, 15, Bias.LOWER_BOUND);
|
|
69
|
+
const afterPosition = sourceService.getPosition(10, 15, Bias.UPPER_BOUND);
|
|
82
70
|
```
|
|
83
71
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
Each entry contains information about the function call, file, line number, column number,
|
|
87
|
-
and if applicable, details about the eval context.
|
|
72
|
+
### Stack Trace Parser
|
|
73
|
+
Parse error stack traces from different JavaScript engines into a structured format.
|
|
88
74
|
|
|
89
|
-
|
|
90
|
-
```typescript
|
|
75
|
+
```ts
|
|
91
76
|
import { parseErrorStack } from '@remotex-labs/xmap/parser.component';
|
|
92
77
|
|
|
93
|
-
// Example with Error object
|
|
94
78
|
try {
|
|
95
|
-
|
|
79
|
+
throw new Error('Example error');
|
|
96
80
|
} catch (error) {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
81
|
+
const parsedStack = parseErrorStack(error);
|
|
82
|
+
|
|
83
|
+
console.log(parsedStack.name); // "Error"
|
|
84
|
+
console.log(parsedStack.message); // "Example error"
|
|
85
|
+
|
|
86
|
+
// Access the first stack frame
|
|
87
|
+
const frame = parsedStack.stack[0];
|
|
88
|
+
console.log(frame.fileName); // File where error occurred
|
|
89
|
+
console.log(frame.line); // Line number
|
|
90
|
+
console.log(frame.functionName); // Function name
|
|
100
91
|
}
|
|
92
|
+
|
|
101
93
|
```
|
|
102
94
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
This function creates a source file from the provided code string, walks through its nodes,
|
|
106
|
-
and applies syntax highlighting according to the given schema.
|
|
95
|
+
### Code Highlighter
|
|
96
|
+
Apply semantic syntax highlighting to TypeScript code.
|
|
107
97
|
|
|
108
|
-
|
|
109
|
-
```typescript
|
|
98
|
+
```ts
|
|
110
99
|
import { highlightCode } from '@remotex-labs/xmap/highlighter.component';
|
|
111
100
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
return 'Hello, ' + name;
|
|
101
|
+
const code = `
|
|
102
|
+
function sum(a: number, b: number): number {
|
|
103
|
+
return a + b;
|
|
116
104
|
}
|
|
117
105
|
`;
|
|
118
106
|
|
|
119
|
-
//
|
|
107
|
+
// Use default color scheme
|
|
108
|
+
const highlightedCode = highlightCode(code);
|
|
109
|
+
|
|
110
|
+
// Or customize with your own color scheme
|
|
120
111
|
const customScheme = {
|
|
121
|
-
keywordColor:
|
|
122
|
-
stringColor:
|
|
123
|
-
numberColor:
|
|
112
|
+
keywordColor: (text: string): string => `\x1b[36m${ text }\x1b[0m`, // Blue for keywords
|
|
113
|
+
stringColor: (text: string): string => `\x1b[32m${ text }\x1b[0m`, // Blue for keywords
|
|
114
|
+
numberColor: (text: string): string => `\x1b[31m${ text }\x1b[0m` // Blue for keywords
|
|
124
115
|
};
|
|
125
116
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
const highlightedCode2 = highlightCode(codeToHighlight, customScheme);
|
|
129
|
-
const highlightedCode3 = highlightCode(codeToHighlight);
|
|
130
|
-
|
|
131
|
-
// Output the highlighted code
|
|
132
|
-
console.log(highlightedCode, highlightedCode2, highlightedCode3);
|
|
117
|
+
const customHighlightedCode = highlightCode(code, customScheme);
|
|
118
|
+
console.log(customHighlightedCode)
|
|
133
119
|
```
|
|
134
|
-
> If you provide a customScheme, it will override the default highlighting scheme. This means you won't need to pass it each time you call highlightCode.
|
|
135
120
|
|
|
136
|
-

|
|
121
|
+

|
|
137
122
|
## formatCode
|
|
138
123
|
The `formatCode` function formats a given code snippet, adding line numbers with customizable padding and enabling specific actions for particular lines.
|
|
139
124
|
This utility is useful for displaying code snippets in a user-friendly manner, particularly in documentation or debugging scenarios.
|
|
140
125
|
|
|
141
|
-
|
|
142
|
-
```typescript
|
|
126
|
+
```ts
|
|
143
127
|
import { formatCode } from '@remotex-labs/xmap/formatter.component';
|
|
144
128
|
import { highlightCode } from '@remotex-labs/xmap/highlighter.component';
|
|
145
129
|
|
|
146
130
|
const code = `
|
|
147
131
|
function greet(name: string) {
|
|
148
|
-
|
|
132
|
+
console.log('Hello, ' + name);
|
|
149
133
|
}
|
|
150
134
|
|
|
151
135
|
greet('World');
|
|
152
136
|
`;
|
|
153
137
|
|
|
138
|
+
// Format with custom options
|
|
154
139
|
const formattedCode = formatCode(highlightCode(code), {
|
|
155
|
-
padding: 8,
|
|
156
|
-
startLine:
|
|
140
|
+
padding: 8, // Padding for line numbers
|
|
141
|
+
startLine: 1, // Starting line number
|
|
157
142
|
action: {
|
|
158
|
-
triggerLine:
|
|
143
|
+
triggerLine: 3, // Line to apply custom formatting
|
|
159
144
|
callback: (lineString, padding, lineNumber) => {
|
|
160
|
-
return `***
|
|
145
|
+
return `*** Line ${ lineNumber } ***\n${ lineString }`;
|
|
161
146
|
}
|
|
162
147
|
}
|
|
163
148
|
});
|
|
164
149
|
|
|
165
150
|
console.log(formattedCode);
|
|
166
151
|
```
|
|
167
|
-

|
|
152
|
+

|
|
168
153
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
applying special highlighting to indicate where the error occurred. This function is particularly useful for debugging and error reporting,
|
|
172
|
-
as it helps to visually identify issues in the source code.
|
|
154
|
+
```ts
|
|
155
|
+
import { formatErrorCode } from '@remotex-labs/xmap/formatter.component';
|
|
173
156
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
157
|
+
const sourcePosition = {
|
|
158
|
+
code: 'function divide(a, b) {\n return a / b;\n}',
|
|
159
|
+
line: 2,
|
|
160
|
+
column: 13,
|
|
161
|
+
startLine: 1,
|
|
162
|
+
endLine: 0,
|
|
163
|
+
name: null,
|
|
164
|
+
source: '',
|
|
165
|
+
sourceRoot: null,
|
|
166
|
+
sourceIndex: 0,
|
|
167
|
+
generatedLine: 0,
|
|
168
|
+
generatedColumn: 0
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
// Format with error indicator
|
|
172
|
+
const formattedError = formatErrorCode(sourcePosition, {
|
|
173
|
+
color: (text) => `\x1b[31m${ text }\x1b[0m` // Red color for error indicator
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
console.log(formattedError)
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+

|
|
180
|
+
|
|
181
|
+
## Practical Examples
|
|
182
|
+
### Working with Source Maps and Errors
|
|
183
|
+
|
|
184
|
+
```ts
|
|
185
|
+
import { SourceService, Bias } from '@remotex-labs/xmap';
|
|
186
|
+
import { parseErrorStack } from '@remotex-labs/xmap/parser.component';
|
|
177
187
|
import { formatErrorCode } from '@remotex-labs/xmap/formatter.component';
|
|
188
|
+
import { highlightCode } from '@remotex-labs/xmap/highlighter.component';
|
|
189
|
+
|
|
190
|
+
try {
|
|
191
|
+
// Code that throws an error
|
|
192
|
+
throw new Error('Something went wrong');
|
|
193
|
+
} catch (error) {
|
|
194
|
+
// Parse the error stack
|
|
195
|
+
const parsedStack = parseErrorStack(error);
|
|
196
|
+
|
|
197
|
+
// Get the top frame
|
|
198
|
+
const frame = parsedStack.stack[0];
|
|
199
|
+
|
|
200
|
+
if (frame.fileName && frame.line && frame.column) {
|
|
201
|
+
// Initialize source service with your source map
|
|
202
|
+
const sourceService = new SourceService(sourceMapJSON);
|
|
203
|
+
|
|
204
|
+
// Get original position with code
|
|
205
|
+
const position = sourceService.getPositionWithCode(
|
|
206
|
+
frame.line,
|
|
207
|
+
frame.column,
|
|
208
|
+
Bias.LOWER_BOUND,
|
|
209
|
+
{ linesBefore: 2, linesAfter: 2 }
|
|
210
|
+
);
|
|
211
|
+
|
|
212
|
+
if (position) {
|
|
213
|
+
// Apply syntax highlighting
|
|
214
|
+
position.code = highlightCode(position.code);
|
|
215
|
+
|
|
216
|
+
// Format with error indicator
|
|
217
|
+
const formattedError = formatErrorCode(position, {
|
|
218
|
+
color: (text) => `\x1b[31m${ text }\x1b[0m`
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
console.log('Error occurred:');
|
|
222
|
+
console.log(formattedError);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
```ts
|
|
230
|
+
import { SourceService } from '@remotex-labs/xmap';
|
|
178
231
|
|
|
179
232
|
const sourceMapJSON = `
|
|
180
233
|
{
|
|
@@ -187,16 +240,31 @@ const sourceMapJSON = `
|
|
|
187
240
|
}
|
|
188
241
|
`;
|
|
189
242
|
const sourceService = new SourceService(sourceMapJSON, 'bundle.js');
|
|
190
|
-
|
|
243
|
+
console.log(sourceService);
|
|
191
244
|
|
|
192
|
-
const
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
};
|
|
245
|
+
const position = sourceService.getPositionByOriginal(3, 7, 'index.ts');
|
|
246
|
+
console.log(position);
|
|
247
|
+
|
|
248
|
+
const positionWithCode = sourceService.getPositionWithCode(1, 104, 1, { linesBefore: 2, linesAfter: 2 });
|
|
249
|
+
console.log(positionWithCode);
|
|
196
250
|
|
|
197
|
-
if (error) {
|
|
198
|
-
error.code = highlightCode(error.code);
|
|
199
|
-
console.log(formatErrorCode(error, ansiOption));
|
|
200
|
-
}
|
|
201
251
|
```
|
|
202
|
-
|
|
252
|
+
|
|
253
|
+
## Documentation
|
|
254
|
+
For complete API documentation, examples, and guides, visit: [xMap Documentation](https://remotex-labs.github.io/xMap/)
|
|
255
|
+
|
|
256
|
+
## Compatibility
|
|
257
|
+
- Node.js 20+
|
|
258
|
+
- All modern browsers (via bundlers)
|
|
259
|
+
- TypeScript 4.5+
|
|
260
|
+
|
|
261
|
+
## Contributing
|
|
262
|
+
Contributions are welcome!\
|
|
263
|
+
Please see our [Contributing Guide](CONTRIBUTING.md) for details.
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
## License
|
|
267
|
+
This project is licensed under the Mozilla Public License 2.0 - see the [LICENSE](LICENSE) file for details.
|
|
268
|
+
|
|
269
|
+
## Acknowledgments
|
|
270
|
+
- Built with TypeScript
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
"use strict";var s=Object.defineProperty;var
|
|
2
|
-
`),o=
|
|
3
|
-
`)}function
|
|
1
|
+
"use strict";var s=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var C=Object.getOwnPropertyNames;var I=Object.prototype.hasOwnProperty;var L=(e,r)=>{for(var n in r)s(e,n,{get:r[n],enumerable:!0})},$=(e,r,n,o)=>{if(r&&typeof r=="object"||typeof r=="function")for(let t of C(r))!I.call(e,t)&&t!==n&&s(e,t,{get:()=>r[t],enumerable:!(o=g(r,t))||o.enumerable});return e};var x=e=>$(s({},"__esModule",{value:!0}),e);var h={};L(h,{formatCode:()=>d,formatErrorCode:()=>b});module.exports=x(h);function d(e,r={}){let n=e.split(`
|
|
2
|
+
`),o=r.padding??10,t=r.startLine??0;return n.map((f,a)=>{let c=a+t+1,i=`${`${c} | `.padStart(o)}${f}`;return r.action&&c===r.action.triggerLine?r.action.callback(i,o,c):i}).join(`
|
|
3
|
+
`)}function b(e,r){let{code:n,line:o,column:t,startLine:f}=e;if(o<f||t<1)throw new Error("Invalid line or column number.");return d(n,{startLine:f,action:{triggerLine:o,callback:(a,c,m)=>{let i="^",p=c-1,l=">";r&&(i=r.color(i),p+=i.length-1,l=r.color(">"));let u=" | ".padStart(c)+" ".repeat(t-1)+`${i}`;return a=`${l} ${m} |`.padStart(p)+a.split("|")[1],a+`
|
|
4
4
|
${u}`}}})}0&&(module.exports={formatCode,formatErrorCode});
|
|
5
5
|
//# sourceMappingURL=formatter.component.js.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/components/formatter.component.ts"],
|
|
4
|
-
"sourceRoot": "https://github.com/remotex-lab/xmap/tree/
|
|
5
|
-
"sourcesContent": ["/**\n *
|
|
6
|
-
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,gBAAAE,EAAA,oBAAAC,IAAA,eAAAC,EAAAJ,GA0CO,SAASE,EAAWG,EAAcC,EAA+B,CAAC,EAAW,CAChF,IAAMC,EAAQF,EAAK,MAAM;AAAA,CAAI,EACvBG,EAAUF,EAAQ,SAAW,GAC7BG,EAAYH,EAAQ,WAAa,EAEvC,OAAOC,EAAM,IAAI,CAACG,EAAaC,IAAU,CACrC,IAAMC,EAAoBD,EAAQF,EAAY,EAExCI,EAAS,GADA,GAAID,
|
|
4
|
+
"sourceRoot": "https://github.com/remotex-lab/xmap/tree/v4.0.0/",
|
|
5
|
+
"sourcesContent": ["/**\n * Import will remove at compile time\n */\n\nimport type { PositionWithCodeInterface } from '@services/interfaces/source-service.interface';\nimport type { AnsiOptionInterface, FormatCodeInterface } from '@components/interfaces/formatter-component.interface';\n\n/**\n * Export interfaces\n */\n\nexport type * from '@components/interfaces/formatter-component.interface';\n\n/**\n * Formats a code snippet with optional line padding and custom actions\n *\n * @param code - The source code | stack to be formatted\n * @param options - Configuration options for formatting the code\n * @returns A formatted string of the code snippet with applied padding and custom actions\n *\n * @remarks\n * This function takes a code string and an options object to format the code snippet.\n * It applies padding to line numbers and can trigger custom actions for specific lines.\n * Options include padding (default 10), startLine (default 0), and custom actions for specific lines.\n *\n * @example\n * ```ts\n * const formattedCode = formatCode(code, {\n * padding: 8,\n * startLine: 5,\n * action: {\n * triggerLine: 7,\n * callback: (lineString, padding, lineNumber) => {\n * return `Custom formatting for line ${lineNumber}: ${lineString}`;\n * }\n * }\n * });\n * ```\n *\n * @since 1.0.0\n */\n\nexport function formatCode(code: string, options: FormatCodeInterface = {}): string {\n const lines = code.split('\\n');\n const padding = options.padding ?? 10;\n const startLine = options.startLine ?? 0;\n\n return lines.map((lineContent, index) => {\n const currentLineNumber = index + startLine + 1;\n const prefix = `${ currentLineNumber } | `;\n const string = `${ prefix.padStart(padding) }${ lineContent }`;\n\n if (options.action && currentLineNumber === options.action.triggerLine) {\n return options.action.callback(string, padding, currentLineNumber);\n }\n\n return string;\n }).join('\\n');\n}\n\n/**\n * Formats a code snippet around an error location with special highlighting\n *\n * @param sourcePosition - An object containing information about the source code and error location\n * @param ansiOption - Optional configuration for ANSI color codes\n * @returns A formatted string representing the relevant code snippet with error highlighting\n *\n * @throws Error - If the provided sourcePosition object has invalid line or column numbers\n *\n * @remarks\n * This function takes a sourcePosition object with code content and error location information,\n * then uses formatCode to format and highlight the relevant code snippet around the error.\n * The sourcePosition object should contain code (string), line (number), column (number),\n * and optional startLine (number, defaults to 1).\n *\n * @example\n * ```ts\n * const formattedErrorCode = formatErrorCode({\n * code: \"const x = 1;\\nconst y = x.undefined;\\n\",\n * line: 2,\n * column: 15,\n * startLine: 1\n * });\n * ```\n *\n * @see formatCode - The underlying function used for basic code formatting\n *\n * @since 1.0.0\n */\n\nexport function formatErrorCode(sourcePosition: PositionWithCodeInterface, ansiOption?: AnsiOptionInterface): string {\n const { code, line: errorLine, column: errorColumn, startLine } = sourcePosition;\n\n // Validate line and column numbers\n if (errorLine < startLine || errorColumn < 1) {\n throw new Error('Invalid line or column number.');\n }\n\n return formatCode(code, {\n startLine,\n action: {\n triggerLine: errorLine,\n callback: (lineString, padding, line) => {\n let pointer = '^';\n let ansiPadding = padding - 1; // 1 size of the char we added\n let prefixPointer = '>';\n\n if (ansiOption) {\n pointer = ansiOption.color(pointer);\n ansiPadding += pointer.length - 1;\n prefixPointer = ansiOption.color('>');\n }\n\n const errorMarker = ' | '.padStart(padding) + ' '.repeat(errorColumn - 1) + `${ pointer }`;\n lineString = `${ prefixPointer } ${ line } |`.padStart(ansiPadding) + lineString.split('|')[1];\n\n return lineString + `\\n${ errorMarker }`;\n }\n }\n });\n}\n"],
|
|
6
|
+
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,gBAAAE,EAAA,oBAAAC,IAAA,eAAAC,EAAAJ,GA0CO,SAASE,EAAWG,EAAcC,EAA+B,CAAC,EAAW,CAChF,IAAMC,EAAQF,EAAK,MAAM;AAAA,CAAI,EACvBG,EAAUF,EAAQ,SAAW,GAC7BG,EAAYH,EAAQ,WAAa,EAEvC,OAAOC,EAAM,IAAI,CAACG,EAAaC,IAAU,CACrC,IAAMC,EAAoBD,EAAQF,EAAY,EAExCI,EAAS,GADA,GAAID,CAAkB,MACX,SAASJ,CAAO,CAAE,GAAIE,CAAY,GAE5D,OAAIJ,EAAQ,QAAUM,IAAsBN,EAAQ,OAAO,YAChDA,EAAQ,OAAO,SAASO,EAAQL,EAASI,CAAiB,EAG9DC,CACX,CAAC,EAAE,KAAK;AAAA,CAAI,CAChB,CAgCO,SAASV,EAAgBW,EAA2CC,EAA0C,CACjH,GAAM,CAAE,KAAAV,EAAM,KAAMW,EAAW,OAAQC,EAAa,UAAAR,CAAU,EAAIK,EAGlE,GAAIE,EAAYP,GAAaQ,EAAc,EACvC,MAAM,IAAI,MAAM,gCAAgC,EAGpD,OAAOf,EAAWG,EAAM,CACpB,UAAAI,EACA,OAAQ,CACJ,YAAaO,EACb,SAAU,CAACE,EAAYV,EAASW,IAAS,CACrC,IAAIC,EAAU,IACVC,EAAcb,EAAU,EACxBc,EAAgB,IAEhBP,IACAK,EAAUL,EAAW,MAAMK,CAAO,EAClCC,GAAeD,EAAQ,OAAS,EAChCE,EAAgBP,EAAW,MAAM,GAAG,GAGxC,IAAMQ,EAAc,MAAM,SAASf,CAAO,EAAI,IAAI,OAAOS,EAAc,CAAC,EAAI,GAAIG,CAAQ,GACxF,OAAAF,EAAa,GAAII,CAAc,IAAKH,CAAK,KAAK,SAASE,CAAW,EAAIH,EAAW,MAAM,GAAG,EAAE,CAAC,EAEtFA,EAAa;AAAA,EAAMK,CAAY,EAC1C,CACJ,CACJ,CAAC,CACL",
|
|
7
7
|
"names": ["formatter_component_exports", "__export", "formatCode", "formatErrorCode", "__toCommonJS", "code", "options", "lines", "padding", "startLine", "lineContent", "index", "currentLineNumber", "string", "sourcePosition", "ansiOption", "errorLine", "errorColumn", "lineString", "line", "pointer", "ansiPadding", "prefixPointer", "errorMarker"]
|
|
8
8
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var S=Object.create;var l=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var y=Object.getOwnPropertyNames;var x=Object.getPrototypeOf,C=Object.prototype.hasOwnProperty;var K=(i,e)=>{for(var t in e)l(i,t,{get:e[t],enumerable:!0})},m=(i,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of y(e))!C.call(i,o)&&o!==t&&l(i,o,{get:()=>e[o],enumerable:!(n=u(e,o))||n.enumerable});return i};var f=(i,e,t)=>(t=i!=null?S(x(i)):{},m(e||!i||!i.__esModule?l(t,"default",{value:i,enumerable:!0}):t,i)),v=i=>m(l({},"__esModule",{value:!0}),i);var T={};K(T,{CodeHighlighter:()=>d,highlightCode:()=>w});module.exports=v(T);var r=f(require("typescript"),1),h=require("typescript"),a=require("@remotex-labs/xansi/xterm.component"),E={enumColor:a.xterm.burntOrange,typeColor:a.xterm.lightGoldenrodYellow,classColor:a.xterm.lightOrange,stringColor:a.xterm.oliveGreen,keywordColor:a.xterm.lightCoral,commentColor:a.xterm.darkGray,functionColor:a.xterm.lightOrange,variableColor:a.xterm.burntOrange,interfaceColor:a.xterm.lightGoldenrodYellow,parameterColor:a.xterm.deepOrange,getAccessorColor:a.xterm.lightYellow,numericLiteralColor:a.xterm.lightGray,methodSignatureColor:a.xterm.burntOrange,regularExpressionColor:a.xterm.oliveGreen,propertyAssignmentColor:a.xterm.canaryYellow,propertyAccessExpressionColor:a.xterm.lightYellow,expressionWithTypeArgumentsColor:a.xterm.lightOrange},d=class{constructor(e,t,n){this.sourceFile=e;this.code=t;this.schema=n}segments=new Map;parseNode(e){this.processComments(e),this.processKeywords(e),this.processNode(e)}highlight(){let e=0,t,n=[];return Array.from(this.segments.values()).sort((s,c)=>s.start-c.start||s.end-c.end).forEach(s=>{if(t&&s.start<t.end){let c=n.pop();if(!c)return;let g=this.getSegmentSource(s.start,s.end),p=`${s.color(g)}`;n.push(c.replace(g,p));return}n.push(this.getSegmentSource(e,s.start)),n.push(s.color(this.getSegmentSource(s.start,s.end))),e=s.end,t=s}),n.join("")+this.getSegmentSource(e)}getSegmentSource(e,t){return this.code.slice(e,t)}addSegment(e,t,n){let o=`${e}-${t}`;this.segments.set(o,{start:e,end:t,color:n})}processComments(e){[...r.default.getTrailingCommentRanges(this.sourceFile.getFullText(),e.getFullStart())||[],...r.default.getLeadingCommentRanges(this.sourceFile.getFullText(),e.getFullStart())||[]].forEach(n=>this.addSegment(n.pos,n.end,this.schema.commentColor))}processKeywords(e){if([h.SyntaxKind.NullKeyword,h.SyntaxKind.VoidKeyword,h.SyntaxKind.StringKeyword,h.SyntaxKind.NumberKeyword,h.SyntaxKind.BooleanKeyword,h.SyntaxKind.UndefinedKeyword].includes(e.kind))return this.addSegment(e.getStart(),e.getEnd(),this.schema.typeColor);e&&e.kind>=r.default.SyntaxKind.FirstKeyword&&e.kind<=r.default.SyntaxKind.LastKeyword&&this.addSegment(e.getStart(),e.getEnd(),this.schema.keywordColor)}processIdentifier(e){let t=e.getEnd(),n=e.getStart();switch(e.parent.kind){case r.default.SyntaxKind.EnumMember:return this.addSegment(n,t,this.schema.enumColor);case r.default.SyntaxKind.CallExpression:case r.default.SyntaxKind.EnumDeclaration:case r.default.SyntaxKind.PropertySignature:case r.default.SyntaxKind.ModuleDeclaration:return this.addSegment(n,t,this.schema.variableColor);case r.default.SyntaxKind.InterfaceDeclaration:return this.addSegment(n,t,this.schema.interfaceColor);case r.default.SyntaxKind.GetAccessor:return this.addSegment(n,t,this.schema.getAccessorColor);case r.default.SyntaxKind.PropertyAssignment:return this.addSegment(n,t,this.schema.propertyAssignmentColor);case r.default.SyntaxKind.MethodSignature:return this.addSegment(n,t,this.schema.methodSignatureColor);case r.default.SyntaxKind.MethodDeclaration:case r.default.SyntaxKind.FunctionDeclaration:return this.addSegment(n,t,this.schema.functionColor);case r.default.SyntaxKind.ClassDeclaration:return this.addSegment(n,t,this.schema.classColor);case r.default.SyntaxKind.Parameter:return this.addSegment(n,t,this.schema.parameterColor);case r.default.SyntaxKind.VariableDeclaration:return this.addSegment(n,t,this.schema.variableColor);case r.default.SyntaxKind.PropertyDeclaration:return this.addSegment(n,t,this.schema.variableColor);case r.default.SyntaxKind.PropertyAccessExpression:return e.parent.getChildAt(0).getText()===e.getText()?this.addSegment(n,t,this.schema.variableColor):this.addSegment(n,t,this.schema.propertyAccessExpressionColor);case r.default.SyntaxKind.ExpressionWithTypeArguments:return this.addSegment(n,t,this.schema.expressionWithTypeArgumentsColor);case r.default.SyntaxKind.BreakStatement:case r.default.SyntaxKind.ShorthandPropertyAssignment:case r.default.SyntaxKind.BindingElement:return this.addSegment(n,t,this.schema.variableColor);case r.default.SyntaxKind.BinaryExpression:case r.default.SyntaxKind.SwitchStatement:case r.default.SyntaxKind.TemplateSpan:return this.addSegment(n,t,this.schema.variableColor);case r.default.SyntaxKind.TypeReference:case r.default.SyntaxKind.TypeAliasDeclaration:return this.addSegment(n,t,this.schema.typeColor);case r.default.SyntaxKind.NewExpression:return this.addSegment(n,t,this.schema.variableColor)}}processTemplateExpression(e){let t=e.head.getStart(),n=e.head.getEnd();this.addSegment(t,n,this.schema.stringColor),e.templateSpans.forEach(o=>{let s=o.literal.getStart(),c=o.literal.getEnd();this.addSegment(s,c,this.schema.stringColor)})}processNode(e){let t=e.getStart(),n=e.getEnd();switch(e.kind){case r.default.SyntaxKind.TypeParameter:return this.addSegment(t,t+e.name.text.length,this.schema.typeColor);case r.default.SyntaxKind.TypeReference:return this.addSegment(t,n,this.schema.typeColor);case r.default.SyntaxKind.StringLiteral:case r.default.SyntaxKind.NoSubstitutionTemplateLiteral:return this.addSegment(t,n,this.schema.stringColor);case r.default.SyntaxKind.RegularExpressionLiteral:return this.addSegment(t,n,this.schema.regularExpressionColor);case r.default.SyntaxKind.TemplateExpression:return this.processTemplateExpression(e);case r.default.SyntaxKind.Identifier:return this.processIdentifier(e);case r.default.SyntaxKind.BigIntLiteral:case r.default.SyntaxKind.NumericLiteral:return this.addSegment(t,n,this.schema.numericLiteralColor)}}};function w(i,e={}){let t=r.default.createSourceFile("temp.ts",i,r.default.ScriptTarget.Latest,!0,r.default.ScriptKind.TS),n=new d(t,i,Object.assign(E,e));function o(s){n.parseNode(s);for(let c=0;c<s.getChildCount();c++)o(s.getChildAt(c))}return r.default.forEachChild(t,o),n.highlight()}0&&(module.exports={CodeHighlighter,highlightCode});
|
|
2
2
|
//# sourceMappingURL=highlighter.component.js.map
|