@remotex-labs/xmap 2.0.2 → 2.0.3
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/dist/cjs/index.js +6 -5
- package/dist/cjs/index.js.map +3 -3
- package/dist/cjs/package.json +1 -0
- package/dist/components/base64.component.js +2 -0
- package/dist/components/base64.component.js.map +8 -0
- package/dist/components/formatter.component.js +5 -0
- package/dist/components/formatter.component.js.map +8 -0
- package/dist/components/highlighter.component.js +2 -0
- package/dist/components/highlighter.component.js.map +8 -0
- package/dist/components/parser.component.js +3 -0
- package/dist/components/parser.component.js.map +8 -0
- package/dist/esm/index.js +6 -5
- package/dist/esm/index.js.map +3 -3
- package/dist/esm/package.json +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +8 -0
- package/dist/package.json +1 -0
- package/dist/providers/interfaces/mapping.interface.js +2 -0
- package/dist/providers/interfaces/mapping.interface.js.map +8 -0
- package/dist/{cjs/providers → providers}/mapping.provider.d.ts +5 -1
- package/dist/providers/mapping.provider.js +2 -0
- package/dist/providers/mapping.provider.js.map +8 -0
- package/dist/services/source.service.js +4 -0
- package/dist/services/source.service.js.map +8 -0
- package/package.json +10 -10
- package/dist/esm/components/base64.component.d.ts +0 -26
- package/dist/esm/components/formatter.component.d.ts +0 -66
- package/dist/esm/components/highlighter.component.d.ts +0 -186
- package/dist/esm/components/interfaces/formatter.interface.d.ts +0 -42
- package/dist/esm/components/interfaces/highlighter.interface.d.ts +0 -48
- package/dist/esm/components/interfaces/parse.interface.d.ts +0 -31
- package/dist/esm/components/parser.component.d.ts +0 -11
- package/dist/esm/index.d.ts +0 -9
- package/dist/esm/providers/interfaces/mapping.interface.d.ts +0 -52
- package/dist/esm/providers/mapping.provider.d.ts +0 -229
- package/dist/esm/services/interfaces/source.interface.d.ts +0 -53
- package/dist/esm/services/source.service.d.ts +0 -217
- /package/dist/{cjs/components → components}/base64.component.d.ts +0 -0
- /package/dist/{cjs/components → components}/formatter.component.d.ts +0 -0
- /package/dist/{cjs/components → components}/highlighter.component.d.ts +0 -0
- /package/dist/{cjs/components → components}/interfaces/formatter.interface.d.ts +0 -0
- /package/dist/{cjs/components → components}/interfaces/highlighter.interface.d.ts +0 -0
- /package/dist/{cjs/components → components}/interfaces/parse.interface.d.ts +0 -0
- /package/dist/{cjs/components → components}/parser.component.d.ts +0 -0
- /package/dist/{cjs/index.d.ts → index.d.ts} +0 -0
- /package/dist/{cjs/providers → providers}/interfaces/mapping.interface.d.ts +0 -0
- /package/dist/{cjs/services → services}/interfaces/source.interface.d.ts +0 -0
- /package/dist/{cjs/services → services}/source.service.d.ts +0 -0
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Import will remove at compile time
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
4
|
+
import type { MapType, SegmentInterface } from './interfaces/mapping.interface';
|
|
5
|
+
/**
|
|
6
|
+
* Imports
|
|
7
|
+
*/
|
|
8
|
+
import { Bias } from './interfaces/mapping.interface';
|
|
5
9
|
/**
|
|
6
10
|
* The `MappingProvider` class provides methods to encode and decode mappings
|
|
7
11
|
* from a source map or mapping string to an internal structured representation.
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{Bias as c}from"./interfaces/mapping.interface.js";import{decodeVLQ as p,encodeArrayVLQ as g}from"../components/base64.component.js";class l{mapping=[];constructor(e,r=0,t=0){e=e instanceof l?e.mapping:e,Array.isArray(e)?this.decodeMappingArray(e,r,t):this.decodeMappingString(e,r,t)}encode(){return this.encodeMappings(this.mapping)}decode(e,r=0,t=0){e=e instanceof l?e.mapping:e,Array.isArray(e)?this.decodeMappingArray(e,r,t):this.decodeMappingString(e,r,t)}getSegment(e,r,t=c.BOUND){const d=this.mapping[e-1];if(!d||d.length===0)return null;let n=0,o=d.length-1,i=null;for(;n<=o;){const a=Math.floor((n+o)/2),u=d[a];if(u.generatedColumn<r)n=a+1,i=t===c.LOWER_BOUND?u:i;else if(u.generatedColumn>r)o=a-1,i=t===c.UPPER_BOUND?u:i;else return u}return i}getOriginalSegment(e,r,t,d=c.BOUND){let n=null;for(const o of this.mapping){if(!o)continue;let i=0,a=o.length-1;for(;i<=a;){const u=Math.floor((i+a)/2),s=o[u];if(s.sourceIndex<t||s.line<e)i=u+1;else if(s.sourceIndex>t||s.line>e)a=u-1;else if(s.column<r)i=u+1,n=d===c.LOWER_BOUND?s:n;else if(s.column>r)a=u-1,n=d===c.UPPER_BOUND?s:n;else return s}}return n}initPositionOffsets(e=0,r=0){return{line:0,column:0,nameIndex:e,sourceIndex:r,generatedLine:0,generatedColumn:0}}validateMappingString(e){return/^[a-zA-Z0-9+/,;]+$/.test(e)}validateSegment(e){if(!Number.isFinite(e.line))throw new Error(`Invalid segment: line must be a finite number, received ${e.line}`);if(!Number.isFinite(e.column))throw new Error(`Invalid segment: column must be a finite number, received ${e.column}`);if(e.nameIndex!==null&&!Number.isFinite(e.nameIndex))throw new Error(`Invalid segment: nameIndex must be a number or null, received ${e.nameIndex}`);if(!Number.isFinite(e.sourceIndex))throw new Error(`Invalid segment: sourceIndex must be a finite number, received ${e.sourceIndex}`);if(!Number.isFinite(e.generatedLine))throw new Error(`Invalid segment: generatedLine must be a finite number, received ${e.generatedLine}`);if(!Number.isFinite(e.generatedColumn))throw new Error(`Invalid segment: generatedColumn must be a finite number, received ${e.generatedColumn}`)}encodeSegment(e,r){const{line:t,column:d,generatedColumn:n,nameIndex:o,sourceIndex:i}=r,a=t-1,u=d-1,s=n-1,m=[s-e.generatedColumn,i!==e.sourceIndex?i-e.sourceIndex:0,a-e.line,u-e.column];return o!=null&&(m[4]=o-e.nameIndex,e.nameIndex=o),e.line=a,e.column=u,e.generatedColumn=s,e.sourceIndex=i,g(m)}encodeMappings(e){const r=this.initPositionOffsets();return e.map(t=>t?(r.generatedColumn=0,t.map(n=>this.encodeSegment(r,n)).join(",")):"").join(";")}decodedSegment(e,r){const[t,d,n,o,i]=r;return e.line+=n,e.column+=o,e.nameIndex+=i??0,e.sourceIndex+=d,e.generatedColumn+=t,{line:e.line+1,column:e.column+1,nameIndex:i!==void 0?e.nameIndex:null,sourceIndex:e.sourceIndex,generatedLine:e.generatedLine+1,generatedColumn:e.generatedColumn+1}}decodeMappingString(e,r,t){if(!this.validateMappingString(e))throw new Error("Invalid Mappings string format: the provided string does not conform to expected VLQ format.");const d=e.split(";"),n=this.mapping.length,o=this.initPositionOffsets(r,t);try{d.forEach((i,a)=>{if(!i){this.mapping.push(null);return}o.generatedColumn=0,o.generatedLine=n+a;const u=i.split(",").map(s=>this.decodedSegment(o,p(s)));this.mapping.push(u)})}catch(i){throw new Error(`Error decoding mappings at frame index ${d.length}: ${i.message}`)}}decodeMappingArray(e,r,t){const d=this.mapping.length;if(!Array.isArray(e))throw new Error("Invalid encoded map: expected an array of frames.");try{e.forEach((n,o)=>{if(!n){this.mapping.push(n);return}if(!Array.isArray(n))throw new Error(`Invalid Mappings array format at frame index ${o}: expected an array, received ${typeof n}.`);const i=n.map(a=>(this.validateSegment(a),{...a,nameIndex:typeof a.nameIndex=="number"?a.nameIndex+r:null,sourceIndex:a.sourceIndex+t,generatedLine:a.generatedLine+d}));this.mapping.push(i)})}catch(n){const o=n instanceof Error?n.message:"Unknown error";throw new Error(`Error decoding mappings: ${o}`)}}}export{l as MappingProvider};
|
|
2
|
+
//# sourceMappingURL=mapping.provider.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/providers/mapping.provider.ts"],
|
|
4
|
+
"sourceRoot": "https://github.com/remotex-lab/xmap/tree/2.0.3/",
|
|
5
|
+
"sourcesContent": ["/**\n * Import will remove at compile time\n */\n\nimport type { MapType, FrameType, SegmentInterface, SegmentOffsetInterface } from './interfaces/mapping.interface.js';\n\n/**\n * Imports\n */\n\nimport { Bias } from './interfaces/mapping.interface.js';\nimport { decodeVLQ, encodeArrayVLQ } from '../components/base64.component.js';\n\n/**\n * The `MappingProvider` class provides methods to encode and decode mappings\n * from a source map or mapping string to an internal structured representation.\n */\n\nexport class MappingProvider {\n /**\n * The internal mapping representation, where each index represents a frame of segments.\n */\n\n private mapping: MapType = [];\n\n /**\n * Constructor to initialize the `MappingProvider` with a mapping.\n * Can be initialized with either a mapping string or a structured mapping array.\n *\n * @param mapping - The mapping data, either as a string or structured array.\n * @param namesOffset - Optional offset for the names index.\n * @param sourceOffset - Optional offset for the sources index.\n *\n * @example\n * ```ts\n * const provider = new MappingProvider(\";;;AAiBO,SAAS,OAAO;AACnB,UAAQ,IAAI,MAAM;AACtB;;;ACjBA,QAAQ,IAAI,GAAG;AACf,KAAK;\", 0, 0);\n * const provider2 = new MappingProvider([\n * null,\n * [\n * {\n * line: 1,\n * column: 1,\n * nameIndex: null,\n * sourceIndex: 0,\n * generatedLine: 2,\n * generatedColumn: 1\n * }\n * ],\n * null\n * ], 0, 0);\n * ```\n */\n\n constructor(mapping: string, namesOffset?: number, sourceOffset?: number);\n constructor(mapping: MapType, namesOffset?: number, sourceOffset?: number);\n constructor(mapping: MappingProvider, namesOffset?: number, sourceOffset?: number);\n constructor(mapping: MappingProvider| MapType | string, namesOffset = 0, sourcesOffset = 0) {\n mapping = mapping instanceof MappingProvider ? mapping.mapping : mapping;\n if (Array.isArray(mapping)) {\n this.decodeMappingArray(mapping, namesOffset, sourcesOffset);\n } else {\n this.decodeMappingString(mapping, namesOffset, sourcesOffset);\n }\n }\n\n /**\n * Encodes the internal mapping array back into a mapping string.\n *\n * @returns {string} - The encoded mapping string.\n * @example\n * ```ts\n * const encoded = provider.encode();\n * console.log(encoded); // Outputs encoded mapping string\n * ```\n */\n\n encode(): string {\n return this.encodeMappings(this.mapping);\n }\n\n /**\n * Decodes a mapping from either a string or structured array into the internal mapping.\n *\n * @param mapping - The mapping data to decode.\n * @param namesOffset - Offset for the names index.\n * @param sourcesOffset - Offset for the sources index.\n * @example\n * ```ts\n * provider.decode(\";;;AAiBO,SAAS,OAAO;AACnB,UAAQ,IAAI,MAAM;AACtB;;;ACjBA,QAAQ,IAAI,GAAG;AACf,KAAK;\", 0, 0);\n * provider.decode([\n * null,\n * [\n * {\n * line: 1,\n * column: 1,\n * nameIndex: null,\n * sourceIndex: 0,\n * generatedLine: 2,\n * generatedColumn: 1\n * }\n * ],\n * null\n * ], 0, 0);\n * ```\n */\n\n decode(mapping: MappingProvider| MapType | string, namesOffset = 0, sourcesOffset = 0): void {\n mapping = mapping instanceof MappingProvider ? mapping.mapping : mapping;\n if (Array.isArray(mapping)) {\n this.decodeMappingArray(mapping, namesOffset, sourcesOffset);\n } else {\n this.decodeMappingString(mapping, namesOffset, sourcesOffset);\n }\n }\n\n /**\n * Retrieves a segment based on the provided generated line and column,\n * applying the specified bias when the exact match is not found.\n *\n * This method performs a binary search on the segments of the specified\n * generated line to efficiently locate the segment corresponding to\n * the provided generated column. If an exact match is not found,\n * the method returns the closest segment based on the specified bias:\n * - `Bias.BOUND`: No preference for column matching (returns the closest segment).\n * - `Bias.LOWER_BOUND`: Prefers the closest mapping with a lower column value.\n * - `Bias.UPPER_BOUND`: Prefers the closest mapping with a higher column value.\n *\n * @param generatedLine - The line number of the generated code (1-based index).\n * @param generatedColumn - The column number of the generated code (0-based index).\n * @param bias - The bias to use when the line matches, can be one of:\n * - `Bias.BOUND` (default): No preference for column matching.\n * - `Bias.LOWER_BOUND`: Prefer the closest mapping with a lower column value.\n * - `Bias.UPPER_BOUND`: Prefer the closest mapping with a higher column value.\n * @returns The matching segment if found;\n * returns null if no segments exist for the specified generated line\n * or if the generated line is out of bounds.\n *\n * @throws { Error } - Throws an error if the generated line is invalid\n * (out of bounds).\n *\n * @example\n * ```ts\n * const segment = sourceMap.getSegment(5, 10, Bias.UPPER_BOUND);\n * if (segment) {\n * console.log(`Found segment: line ${segment.line}, column ${segment.column}`);\n * } else {\n * console.log('No matching segment found.');\n * }\n * ```\n */\n\n getSegment(generatedLine: number, generatedColumn: number, bias: Bias = Bias.BOUND): SegmentInterface | null {\n const segments = this.mapping[generatedLine - 1];\n if (!segments || segments.length === 0)\n return null;\n\n let low = 0;\n let high = segments.length - 1;\n let closestSegment: SegmentInterface | null = null;\n while (low <= high) {\n const mid = Math.floor((low + high) / 2);\n const segment = segments[mid];\n\n if (segment.generatedColumn < generatedColumn) {\n low = mid + 1;\n closestSegment = bias === Bias.LOWER_BOUND ? segment : closestSegment;\n } else if (segment.generatedColumn > generatedColumn) {\n high = mid - 1;\n closestSegment = bias === Bias.UPPER_BOUND ? segment : closestSegment;\n } else {\n return segment;\n }\n }\n\n return closestSegment;\n }\n\n /**\n * Retrieves the original segment based on the provided line, column, and source index.\n *\n * This method searches for the original segment that corresponds to the specified\n * line, column, and source index. It uses binary search to find the closest segment\n * based on the provided bias.\n *\n * @param line - The line number of the original code (1-based index).\n * @param column - The column number of the original code (0-based index).\n * @param sourceIndex - The index of the source file in the source map.\n * @param bias - The bias to apply when multiple segments match; defaults to `Bias.BOUND`.\n * @returns {SegmentInterface | null} - The matching original segment if found;\n * returns null if no segments exist for the specified line and source index.\n *\n * @example\n * ```ts\n * const originalSegment = sourceMap.getOriginalSegment(3, 5, 0, Bias.LOWER_BOUND);\n * if (originalSegment) {\n * console.log(`Found original segment: line ${originalSegment.line}, column ${originalSegment.column}`);\n * } else {\n * console.log('No matching original segment found.');\n * }\n * ```\n */\n\n getOriginalSegment(line: number, column: number, sourceIndex: number, bias: Bias = Bias.BOUND): SegmentInterface | null {\n let closestSegment: SegmentInterface | null = null;\n for (const segments of this.mapping) {\n if (!segments)\n continue;\n\n let low = 0;\n let high = segments.length - 1;\n while (low <= high) {\n const mid = Math.floor((low + high) / 2);\n const midSegment = segments[mid];\n\n if (midSegment.sourceIndex < sourceIndex || midSegment.line < line) {\n low = mid + 1;\n } else if (midSegment.sourceIndex > sourceIndex || midSegment.line > line) {\n high = mid - 1;\n } else if (midSegment.column < column) {\n low = mid + 1;\n closestSegment = bias === Bias.LOWER_BOUND ? midSegment : closestSegment;\n } else if (midSegment.column > column) {\n high = mid - 1;\n closestSegment = bias === Bias.UPPER_BOUND ? midSegment : closestSegment;\n } else {\n return midSegment;\n }\n }\n }\n\n return closestSegment;\n }\n\n /**\n * Initializes the segment offsets used to track the current decoding position.\n *\n * @param namesOffset - The offset for the names index.\n * @param sourceIndex - The offset for the source index.\n * @returns { SegmentOffsetInterface } - The initialized segment offset.\n */\n\n private initPositionOffsets(namesOffset: number = 0, sourceIndex: number = 0): SegmentOffsetInterface {\n return {\n line: 0,\n column: 0,\n nameIndex: namesOffset,\n sourceIndex: sourceIndex,\n generatedLine: 0,\n generatedColumn: 0\n };\n }\n\n /**\n * Validates the format of an encoded mapping string.\n *\n * @param encodedSourceMap - The encoded source map string to validate.\n * @returns Returns `true` if the format is valid, otherwise `false`.\n */\n\n private validateMappingString(encodedSourceMap: string): boolean {\n // /^(;+)?([a-z0-9+/]{1,10}(,|;+)?)+$/\n return /^[a-zA-Z0-9+/,;]+$/.test(encodedSourceMap);\n }\n\n /**\n * Validates the properties of a segment to ensure they conform to expected types.\n *\n * This method checks that the segment's properties are finite numbers and that\n * the nameIndex, if provided, is either a finite number or null.\n * An error is thrown if any of the properties do not meet the specified criteria.\n *\n * @param segment - The segment object to validate, which must conform to the\n * SegmentInterface structure, including:\n * - line: number (finite)\n * - column: number (finite)\n * - nameIndex: number | null (if not null, must be finite)\n * - sourceIndex: number (finite)\n * - generatedLine: number (finite)\n * - generatedColumn: number (finite)\n *\n * @throws {Error} - Throws an error if any property of the segment is invalid.\n * The error message will specify which property is invalid\n * and the value that was received.\n */\n\n private validateSegment(segment: SegmentInterface): void {\n if (!Number.isFinite(segment.line)) {\n throw new Error(`Invalid segment: line must be a finite number, received ${segment.line}`);\n }\n if (!Number.isFinite(segment.column)) {\n throw new Error(`Invalid segment: column must be a finite number, received ${segment.column}`);\n }\n if (segment.nameIndex !== null && !Number.isFinite(segment.nameIndex)) {\n throw new Error(`Invalid segment: nameIndex must be a number or null, received ${segment.nameIndex}`);\n }\n if (!Number.isFinite(segment.sourceIndex)) {\n throw new Error(`Invalid segment: sourceIndex must be a finite number, received ${segment.sourceIndex}`);\n }\n if (!Number.isFinite(segment.generatedLine)) {\n throw new Error(`Invalid segment: generatedLine must be a finite number, received ${segment.generatedLine}`);\n }\n if (!Number.isFinite(segment.generatedColumn)) {\n throw new Error(`Invalid segment: generatedColumn must be a finite number, received ${segment.generatedColumn}`);\n }\n }\n\n /**\n * Encodes a segment into a VLQ-encoded string based on the segment offsets.\n *\n * @param segmentOffset - The current segment offset.\n * @param segmentObject - The segment to encode.\n * @returns The encoded segment string.\n */\n\n private encodeSegment(segmentOffset: SegmentOffsetInterface, segmentObject: SegmentInterface): string {\n const { line, column, generatedColumn, nameIndex, sourceIndex } = segmentObject;\n const adjustedLine = line - 1;\n const adjustedColumn = column - 1;\n const adjustedGeneratedColumn = generatedColumn - 1;\n\n const segment: Array<number> = [\n adjustedGeneratedColumn - segmentOffset.generatedColumn, // generatedColumn difference\n sourceIndex !== segmentOffset.sourceIndex ? sourceIndex - segmentOffset.sourceIndex : 0, // sourceIndex difference\n adjustedLine - segmentOffset.line, // line difference\n adjustedColumn - segmentOffset.column // column difference\n ];\n\n if (nameIndex !== null && nameIndex !== undefined) {\n segment[4] = nameIndex - segmentOffset.nameIndex; // nameIndex difference\n segmentOffset.nameIndex = nameIndex;\n }\n\n segmentOffset.line = adjustedLine;\n segmentOffset.column = adjustedColumn;\n segmentOffset.generatedColumn = adjustedGeneratedColumn;\n segmentOffset.sourceIndex = sourceIndex;\n\n return encodeArrayVLQ(segment);\n }\n\n /**\n * Encodes the entire mapping array into a VLQ-encoded mapping string.\n *\n * @param map - The mapping array to encode.\n * @returns The encoded mapping string.\n */\n\n private encodeMappings(map: MapType): string {\n const positionOffset = this.initPositionOffsets();\n\n return map.map(frame => {\n if (!frame)\n return '';\n\n positionOffset.generatedColumn = 0;\n const segments = frame.map(segment => this.encodeSegment(positionOffset, segment));\n\n return segments.join(',');\n }).join(';');\n }\n\n /**\n * Decodes a VLQ-encoded segment into a segment object based on the current offset.\n *\n * @param segmentOffset - The current segment offset.\n * @param decodedSegment - The decoded VLQ segment values.\n * @returns The decoded segment object.\n */\n\n private decodedSegment(segmentOffset: SegmentOffsetInterface, decodedSegment: Array<number>): SegmentInterface {\n const [ generatedColumn, sourceIndex, sourceLine, sourceColumn, nameIndex ] = decodedSegment;\n segmentOffset.line += sourceLine;\n segmentOffset.column += sourceColumn;\n segmentOffset.nameIndex += nameIndex ?? 0;\n segmentOffset.sourceIndex += sourceIndex;\n segmentOffset.generatedColumn += generatedColumn;\n\n return {\n line: segmentOffset.line + 1,\n column: segmentOffset.column + 1,\n nameIndex: nameIndex !== undefined ? segmentOffset.nameIndex : null,\n sourceIndex: segmentOffset.sourceIndex,\n generatedLine: segmentOffset.generatedLine + 1,\n generatedColumn: segmentOffset.generatedColumn + 1\n };\n }\n\n /**\n * Decodes a VLQ-encoded mapping string into the internal mapping representation.\n *\n * @param encodedMap - The VLQ-encoded mapping string.\n * @param namesOffset - Offset for the names index.\n * @param sourceOffset - Offset for the sources index.\n * @throws { Error } - Throws an error if the mapping string is invalid.\n */\n\n private decodeMappingString(encodedMap: string, namesOffset: number, sourceOffset: number): void {\n if (!this.validateMappingString(encodedMap))\n throw new Error('Invalid Mappings string format: the provided string does not conform to expected VLQ format.');\n\n const frames = encodedMap.split(';');\n const linesOffset = this.mapping.length;\n const positionOffset = this.initPositionOffsets(namesOffset, sourceOffset);\n try {\n frames.forEach((frame, index) => {\n if (!frame) {\n this.mapping.push(null);\n\n return;\n }\n\n positionOffset.generatedColumn = 0;\n positionOffset.generatedLine = linesOffset + index;\n const segmentsArray: Array<SegmentInterface> = frame.split(',')\n .map(segment => this.decodedSegment(positionOffset, decodeVLQ(segment)));\n\n this.mapping.push(segmentsArray);\n });\n } catch (error) {\n throw new Error(`Error decoding mappings at frame index ${frames.length}: ${(<Error>error).message}`);\n }\n }\n\n /**\n * Decodes a mapping array into the internal mapping representation, adjusting for offsets.\n *\n * This method processes each frame in the provided structured mapping array,\n * validating each segment within the frame and adjusting the indices based on the\n * specified offsets for names and sources. If a frame is invalid or not an array,\n * an error will be thrown.\n *\n * @param encodedMap - The structured mapping array, which should be an array of frames,\n * where each frame is an array of segments. Each segment must conform\n * to the SegmentInterface.\n * @param namesOffset - Offset for the names index, which will be added to each segment's nameIndex.\n * @param sourceOffset - Offset for the sources index, which will be added to each segment's sourceIndex.\n * @throws { Error } - Throws an error if:\n * - The mapping array is invalid (not an array).\n * - Any frame is not an array.\n * - Any segment does not conform to the SegmentInterface.\n */\n\n private decodeMappingArray(encodedMap: MapType, namesOffset: number, sourceOffset: number): void {\n const linesOffset = this.mapping.length;\n if (!Array.isArray(encodedMap))\n throw new Error('Invalid encoded map: expected an array of frames.');\n\n try {\n encodedMap.forEach((frame, index) => {\n if (!frame) {\n this.mapping.push(frame);\n\n return;\n }\n\n if (!Array.isArray(frame))\n throw new Error(`Invalid Mappings array format at frame index ${index}: expected an array, received ${typeof frame}.`);\n\n const segments: FrameType = frame.map(segment => {\n this.validateSegment(segment);\n\n return {\n ...segment,\n nameIndex: (typeof segment.nameIndex === 'number') ? segment.nameIndex + namesOffset : null,\n sourceIndex: segment.sourceIndex + sourceOffset,\n generatedLine: segment.generatedLine + linesOffset\n };\n });\n\n this.mapping.push(segments);\n });\n } catch (error: unknown) {\n const errorMessage = (error instanceof Error) ? error.message : 'Unknown error';\n throw new Error(`Error decoding mappings: ${errorMessage}`);\n }\n }\n}\n"],
|
|
6
|
+
"mappings": "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",
|
|
7
|
+
"names": ["Bias", "decodeVLQ", "encodeArrayVLQ", "MappingProvider", "mapping", "namesOffset", "sourcesOffset", "generatedLine", "generatedColumn", "bias", "segments", "low", "high", "closestSegment", "mid", "segment", "line", "column", "sourceIndex", "midSegment", "encodedSourceMap", "segmentOffset", "segmentObject", "nameIndex", "adjustedLine", "adjustedColumn", "adjustedGeneratedColumn", "map", "positionOffset", "frame", "decodedSegment", "sourceLine", "sourceColumn", "encodedMap", "sourceOffset", "frames", "linesOffset", "index", "segmentsArray", "error", "errorMessage"]
|
|
8
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{MappingProvider as m}from"../providers/mapping.provider.js";import{Bias as c}from"../providers/interfaces/mapping.interface.js";class l{file;mappings;sourceRoot;names;sources;sourcesContent;constructor(e,n=null){typeof e=="string"&&(e=JSON.parse(e)),e=e,this.validateSourceMap(e),this.file=e.file??n,this.names=[...e.names??[]],this.sources=[...e.sources??[]],this.sourceRoot=e.sourceRoot??null,this.sourcesContent=e.sourcesContent?[...e.sourcesContent]:[],this.mappings=new m(e.mappings)}getMapObject(){const e={version:3,names:this.names,sources:this.sources,mappings:this.mappings.encode(),sourcesContent:this.sourcesContent};return this.file&&(e.file=this.file),this.sourceRoot&&(e.sourceRoot=this.sourceRoot),e}concat(...e){if(e.length<1)throw new Error("At least one map must be provided for concatenation.");for(const n of e)this.mappings.decode(n.mappings,this.names.length,this.sources.length),this.names.push(...n.names),this.sources.push(...n.sources),this.sourcesContent.push(...n.sourcesContent??[])}concatNewMap(...e){if(e.length<1)throw new Error("At least one map must be provided for concatenation.");const n=new l(this);for(const t of e)n.mappings.decode(t.mappings,n.names.length,n.sources.length),n.names.push(...t.names),n.sources.push(...t.sources),n.sourcesContent.push(...t.sourcesContent??[]);return n}getPositionByOriginal(e,n,t,r=c.BOUND){let o=t;if(typeof t=="string"&&(o=this.sources.findIndex(i=>i.includes(t))),o<0)return null;const s=this.mappings.getOriginalSegment(e,n,o,r);return s?{name:this.names[s.nameIndex??-1]??null,line:s.line,column:s.column,source:this.sources[s.sourceIndex],sourceRoot:this.sourceRoot,sourceIndex:s.sourceIndex,generatedLine:s.generatedLine,generatedColumn:s.generatedColumn}:null}getPosition(e,n,t=c.BOUND){const r=this.mappings.getSegment(e,n,t);return r?{name:this.names[r.nameIndex??-1]??null,line:r.line,column:r.column,source:this.sources[r.sourceIndex],sourceRoot:this.sourceRoot,sourceIndex:r.sourceIndex,generatedLine:r.generatedLine,generatedColumn:r.generatedColumn}:null}getPositionWithContent(e,n,t=c.BOUND){const r=this.getPosition(e,n,t);return r?{...r,sourcesContent:this.sourcesContent[r.sourceIndex]}:null}getPositionWithCode(e,n,t=c.BOUND,r){const o=this.getPosition(e,n,t);if(!o||!this.sourcesContent[o.sourceIndex])return null;const s=Object.assign({linesAfter:4,linesBefore:3},r),i=this.sourcesContent[o.sourceIndex].split(`
|
|
2
|
+
`),a=Math.min((o.line??1)+s.linesAfter,i.length),u=Math.max((o.line??1)-s.linesBefore,0),p=i.slice(u,Math.min(a+1,i.length)).join(`
|
|
3
|
+
`);return{...o,code:p,endLine:a,startLine:u}}toString(){return JSON.stringify(this.getMapObject())}validateSourceMap(e){if(!["sources","mappings","names"].every(t=>t in e))throw new Error("Missing required keys in SourceMap.")}}export{l as SourceService};
|
|
4
|
+
//# sourceMappingURL=source.service.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/services/source.service.ts"],
|
|
4
|
+
"sourceRoot": "https://github.com/remotex-lab/xmap/tree/2.0.3/",
|
|
5
|
+
"sourcesContent": ["/**\n * Import will remove at compile time\n */\n\nimport type {\n PositionInterface,\n SourceMapInterface,\n SourceOptionsInterface,\n PositionWithCodeInterface,\n PositionWithContentInterface\n} from './/interfaces/source.interface';\n\n/**\n * Imports\n */\n\nimport { MappingProvider } from '../providers/mapping.provider.js';\nimport { Bias } from '../providers/interfaces/mapping.interface.js';\n\n/**\n * A service for validating and processing source maps.\n * This class allows parsing and manipulation of source maps, providing functionality such as\n * retrieving position mappings between original and generated code, concatenating source maps,\n * and getting code snippets based on mappings.\n *\n * @example\n * ```ts\n * const sourceMapJSON = '{\"version\": 3, \"file\": \"bundle.js\", \"sources\": [\"foo.ts\"], \"names\": [], \"mappings\": \"AAAA\"}';\n * const sourceService = new SourceService(sourceMapJSON);\n *\n * console.log(sourceService.file); // Outputs: 'bundle.js'\n * ```\n */\n\nexport class SourceService {\n /**\n * The name of the generated file (bundle) that this source map applies to.\n *\n * @example\n * ```ts\n * console.log(sourceService.file); // 'bundle.js'\n * ```\n */\n\n readonly file: string | null;\n\n /**\n * A MappingProvider instance of base64 VLQ-encoded mappings.\n */\n\n readonly mappings: MappingProvider;\n\n /**\n * The root URL for the sources, if present in the source map.\n */\n\n readonly sourceRoot: string | null;\n\n /**\n * A list of symbol names used by the \u201Cmappings\u201D entry.\n */\n\n readonly names: Array<string>;\n\n /**\n * An array of source file paths.\n */\n\n readonly sources: Array<string>;\n\n /**\n * An array of source files contents.\n */\n\n readonly sourcesContent: Array<string>;\n\n /**\n * Creates a new instance of the `SourceService` class.\n *\n * This constructor initializes the class using either a `SourceMapInterface` object,\n * a JSON string representing the source map, or an existing `SourceService` instance.\n * It validates the source map and populates its properties such as `file`, `sources`, and `mappings`.\n *\n * @param source - Can be one of the following:\n * - An object conforming to the `SourceMapInterface`.\n * - A JSON string representing the source map.\n * - A `SourceService` instance to copy the properties.\n * @param file - (Optional) A string representing the file name of the generated bundle.\n * Defaults to `null`. It will overwrite any existing `file` property in the source map.\n * @throws {Error} - If the source map does not contain required properties or has an invalid format.\n *\n * @example\n * ```ts\n * const sourceMapJSON = '{\"version\": 3, \"file\": \"bundle.js\", \"sources\": [\"foo.ts\"], \"names\": [], \"mappings\": \"AAAA\"}';\n * const sourceService = new SourceService(sourceMapJSON);\n * ```\n */\n\n constructor(source: SourceService);\n constructor(source: SourceMapInterface | string, file?: string | null);\n constructor(source: SourceService | SourceMapInterface | string, file: string | null = null) {\n if (typeof source === 'string') {\n source = <SourceMapInterface> JSON.parse(source);\n }\n\n source = <SourceMapInterface> source;\n this.validateSourceMap(source);\n this.file = source.file ?? file;\n this.names = [ ...source.names ?? [] ];\n this.sources = [ ...source.sources ?? [] ];\n this.sourceRoot = source.sourceRoot ?? null;\n this.sourcesContent = source.sourcesContent ? [ ...source.sourcesContent ] : [];;\n this.mappings = new MappingProvider(source.mappings);\n }\n\n /**\n * Converts the current source map data into a plain object format.\n *\n * @returns The source map json object.\n *\n * @example\n * ```ts\n * const mapObject = sourceService.getMapObject();\n * console.log(mapObject.file); // 'bundle.js'\n * ```\n */\n\n getMapObject(): SourceMapInterface {\n const sourceMap: SourceMapInterface = {\n version: 3,\n names: this.names,\n sources: this.sources,\n mappings: this.mappings.encode(),\n sourcesContent: this.sourcesContent\n };\n\n if (this.file)\n sourceMap.file = this.file;\n\n if (this.sourceRoot)\n sourceMap.sourceRoot = this.sourceRoot;\n\n return sourceMap;\n }\n\n /**\n * Concatenates one or more source maps to the current source map.\n *\n * This method merges additional source maps into the current source map,\n * updating the `mappings`, `names`, `sources`, and `sourcesContent` arrays.\n *\n * @param maps - An array of `SourceMapInterface` or `SourceService` instances to be concatenated.\n * @throws { Error } If no source maps are provided for concatenation.\n *\n * @example\n * ```ts\n * sourceService.concat(anotherSourceMap);\n * console.log(sourceService.sources); // Updated source paths\n * ```\n */\n\n concat(...maps: Array<SourceMapInterface | SourceService>): void {\n if (maps.length < 1)\n throw new Error('At least one map must be provided for concatenation.');\n\n for (const map of (maps as Array<SourceMapInterface>)) {\n this.mappings.decode(map.mappings, this.names.length, this.sources.length);\n this.names.push(...map.names);\n this.sources.push(...map.sources);\n this.sourcesContent.push(...map.sourcesContent ?? []);\n }\n }\n\n /**\n * Creates a new instance of `SourceService` with concatenated source maps.\n *\n * @param maps - An array of `SourceMapInterface` or `SourceService` instances to be concatenated.\n * @returns { SourceService } A new `SourceService` instance with the concatenated maps.\n * @throws { Error } If no source maps are provided.\n *\n * @example\n * ```ts\n * const newService = sourceService.concatNewMap(anotherSourceMap);\n * console.log(newService.file); // The file from the new source map\n * ```\n */\n\n concatNewMap(...maps: Array<SourceMapInterface | SourceService>): SourceService {\n if (maps.length < 1)\n throw new Error('At least one map must be provided for concatenation.');\n\n const sourceService = new SourceService(this);\n for (const map of (maps as Array<SourceMapInterface>)) {\n sourceService.mappings.decode(map.mappings, sourceService.names.length, sourceService.sources.length);\n sourceService.names.push(...map.names);\n sourceService.sources.push(...map.sources);\n sourceService.sourcesContent.push(...map.sourcesContent ?? []);\n }\n\n return sourceService;\n }\n\n /**\n * Retrieves the position information based on the original source line and column.\n *\n * @param line - The line number in the generated code.\n * @param column - The column number in the generated code.\n * @param sourceIndex - The index or file path of the original source.\n * @param bias - The bias to use when matching positions (`Bias.LOWER_BOUND`, `Bias.UPPER_BOUND`, or `Bias.BOUND`).\n * @returns { PositionInterface | null } The corresponding position in the original source, or `null` if not found.\n *\n * @example\n * ```ts\n * const position = sourceService.getPositionByOriginal(1, 10, 'foo.ts');\n * console.log(position?.line); // The line number in the original source\n * ```\n */\n\n getPositionByOriginal(line: number, column: number, sourceIndex: number | string, bias: Bias = Bias.BOUND): PositionInterface | null {\n let index = <number> sourceIndex;\n if (typeof sourceIndex === 'string')\n index = this.sources.findIndex(str => str.includes(sourceIndex));\n\n if (index < 0)\n return null;\n\n const segment = this.mappings.getOriginalSegment(line, column, index, bias);\n if (!segment)\n return null;\n\n return {\n name: this.names[segment.nameIndex ?? -1] ?? null,\n line: segment.line,\n column: segment.column,\n source: this.sources[segment.sourceIndex],\n sourceRoot: this.sourceRoot,\n sourceIndex: segment.sourceIndex,\n generatedLine: segment.generatedLine,\n generatedColumn: segment.generatedColumn\n };\n }\n\n /**\n * Retrieves the position in the original source code based on a given line and column\n * in the generated code.\n *\n * @param line - Line number in the generated code.\n * @param column - Column number in the generated code.\n * @param bias - The bias to use for matching positions. Defaults to `Bias.BOUND`.\n * @returns {PositionInterface | null} The position in the original source, or null if not found.\n *\n * @example\n * ```ts\n * const position = sourceService.getPosition(2, 15);\n * console.log(position?.source); // The original source file\n * ```\n */\n\n getPosition(line: number, column: number, bias: Bias = Bias.BOUND): PositionInterface | null {\n const segment = this.mappings.getSegment(line, column, bias);\n if (!segment)\n return null;\n\n return {\n name: this.names[segment.nameIndex ?? -1] ?? null,\n line: segment.line,\n column: segment.column,\n source: this.sources[segment.sourceIndex],\n sourceRoot: this.sourceRoot,\n sourceIndex: segment.sourceIndex,\n generatedLine: segment.generatedLine,\n generatedColumn: segment.generatedColumn\n };\n }\n\n /**\n * Retrieves the position and original source content for a given position in the generated code.\n *\n * @param line - Line number in the generated code.\n * @param column - Column number in the generated code.\n * @param bias - Bias used for position matching.\n * @returns { PositionWithContentInterface | null } The position and its associated content, or `null` if not found.\n *\n * @example\n * ```ts\n * const positionWithContent = sourceService.getPositionWithContent(3, 5);\n * console.log(positionWithContent?.sourcesContent); // The source code content\n * ```\n */\n\n getPositionWithContent(line: number, column: number, bias: Bias = Bias.BOUND): PositionWithContentInterface | null {\n const position = this.getPosition(line, column, bias);\n if (!position)\n return null;\n\n return {\n ...position,\n sourcesContent: this.sourcesContent[position.sourceIndex]\n };\n }\n\n /**\n * Retrieves the position and a code snippet from the original source based on the given\n * generated code position, with additional lines of code around the matching line.\n *\n * @param line - Line number in the generated code.\n * @param column - Column number in the generated code.\n * @param bias - Bias used for position matching.\n * @param options - (Optional) Extra options for the amount of surrounding lines to include.\n * @returns { PositionWithCodeInterface | null } The position and code snippet.\n *\n * @example\n * ```ts\n * const positionWithCode = sourceService.getPositionWithCode(4, 8, Bias.BOUND, { linesBefore: 2, linesAfter: 2 });\n * console.log(positionWithCode?.code); // The code snippet from the original source\n * ```\n */\n\n getPositionWithCode(line: number, column: number, bias: Bias = Bias.BOUND, options?: SourceOptionsInterface): PositionWithCodeInterface | null {\n const position = this.getPosition(line, column, bias);\n if (!position || !this.sourcesContent[position.sourceIndex])\n return null;\n\n const settings = Object.assign({\n linesAfter: 4,\n linesBefore: 3\n }, options);\n\n const code = this.sourcesContent[position.sourceIndex].split('\\n');\n const endLine = Math.min( (position.line ?? 1) + settings.linesAfter, code.length);\n const startLine = Math.max((position.line ?? 1) - settings.linesBefore, 0);\n const relevantCode = code.slice(startLine, Math.min(endLine + 1, code.length)).join('\\n');\n\n return {\n ...position,\n code: relevantCode,\n endLine: endLine,\n startLine: startLine\n };\n }\n\n /**\n * Converts the current source map object to a JSON string.\n *\n * @returns A stringified version of the source map object.\n *\n * @example\n * ```ts\n * console.log(sourceService.toString()); // JSON string of the source map\n * ```\n */\n\n toString(): string {\n return JSON.stringify(this.getMapObject());\n }\n\n /**\n * Validates the provided source map object.\n *\n * This method checks whether all required keys are present in the source map object.\n * It throws an error if any required keys are missing.\n *\n * @private\n * @param input - The source map object to be validated.\n * @throws Error If any required key is missing from the source map.\n *\n * @example\n * ```ts\n * const sourceMap = {\n * version: 3,\n * file: 'example.js',\n * names: ['src', 'maps', 'example', 'function', 'line', 'column'],\n * sources: ['source1.js', 'source2.js'],\n * mappings: 'AAAA,SAASA,CAAC,CAAC,CAAC;AAAA,CAAC,CAAC;AAAC,CAAC',\n * };\n * sourceService['validateSource'](sourceMap); // Throws if invalid\n * ```\n */\n\n private validateSourceMap(input: SourceMapInterface): void {\n const requiredKeys: (keyof SourceMapInterface)[] = [ 'sources', 'mappings', 'names' ];\n if (!requiredKeys.every(key => key in input)) {\n throw new Error('Missing required keys in SourceMap.');\n }\n }\n}\n"],
|
|
6
|
+
"mappings": "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",
|
|
7
|
+
"names": ["MappingProvider", "Bias", "SourceService", "source", "file", "sourceMap", "maps", "map", "sourceService", "line", "column", "sourceIndex", "bias", "index", "str", "segment", "position", "options", "settings", "code", "endLine", "startLine", "relevantCode", "input", "key"]
|
|
8
|
+
}
|
package/package.json
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
"name": "@remotex-labs/xmap",
|
|
3
3
|
"main": "dist/cjs/index.js",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"types": "./dist/
|
|
5
|
+
"types": "./dist/index.d.ts",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
7
7
|
"author": "Garefild",
|
|
8
|
-
"version": "2.0.
|
|
8
|
+
"version": "2.0.3",
|
|
9
9
|
"license": "Mozilla Public License Version 2.0",
|
|
10
10
|
"description": "A library with a sourcemap parser and TypeScript code formatter for the CLI",
|
|
11
11
|
"homepage": "https://github.com/remotex-lab/xMap",
|
|
@@ -38,11 +38,11 @@
|
|
|
38
38
|
"./package.json": "./package.json",
|
|
39
39
|
".": {
|
|
40
40
|
"import": {
|
|
41
|
-
"types": "./dist/
|
|
41
|
+
"types": "./dist/index.d.ts",
|
|
42
42
|
"default": "./dist/esm/index.js"
|
|
43
43
|
},
|
|
44
44
|
"require": {
|
|
45
|
-
"types": "./dist/
|
|
45
|
+
"types": "./dist/index.d.ts",
|
|
46
46
|
"default": "./dist/cjs/index.js"
|
|
47
47
|
}
|
|
48
48
|
}
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"scripts": {
|
|
56
56
|
"dev": "xBuild -w",
|
|
57
57
|
"test": "jest",
|
|
58
|
-
"build": "xBuild
|
|
58
|
+
"build": "xBuild",
|
|
59
59
|
"test:coverage": "jest --coverage",
|
|
60
60
|
"lint": "xbuild --tc && eslint . -c ./eslint.config.mjs",
|
|
61
61
|
"ci:test": "jest",
|
|
@@ -64,13 +64,13 @@
|
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
66
|
"jest": "^29.7.0",
|
|
67
|
-
"eslint": "^9.
|
|
68
|
-
"typescript-eslint": "^8.
|
|
69
|
-
"eslint-plugin-jsdoc": "^50.4.
|
|
67
|
+
"eslint": "^9.13.0",
|
|
68
|
+
"typescript-eslint": "^8.11.0",
|
|
69
|
+
"eslint-plugin-jsdoc": "^50.4.3",
|
|
70
70
|
"@swc/jest": "^0.2.36",
|
|
71
71
|
"@types/jest": "^29.5.13",
|
|
72
|
-
"@types/node": "^22.7.
|
|
73
|
-
"@remotex-labs/xbuild": "^1.
|
|
72
|
+
"@types/node": "^22.7.8",
|
|
73
|
+
"@remotex-labs/xbuild": "^1.3.0"
|
|
74
74
|
},
|
|
75
75
|
"dependencies": {
|
|
76
76
|
"typescript": "^5.6.3"
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Encodes a given number using Variable-Length Quantity (VLQ) encoding.
|
|
3
|
-
* Negative numbers are encoded by converting to a non-negative representation.
|
|
4
|
-
* The continuation bit is used to indicate if more bytes follow.
|
|
5
|
-
*
|
|
6
|
-
* @param value - The number to be encoded.
|
|
7
|
-
* @returns The VLQ encoded string.
|
|
8
|
-
*/
|
|
9
|
-
export declare function encodeVLQ(value: number): string;
|
|
10
|
-
/**
|
|
11
|
-
* Encodes an array of numbers using VLQ encoding.
|
|
12
|
-
* Each number in the array is individually encoded and the results are concatenated.
|
|
13
|
-
*
|
|
14
|
-
* @param values - The array of numbers to be encoded.
|
|
15
|
-
* @returns The concatenated VLQ encoded string.
|
|
16
|
-
*/
|
|
17
|
-
export declare function encodeArrayVLQ(values: number[]): string;
|
|
18
|
-
/**
|
|
19
|
-
* Decodes a VLQ encoded string back into an array of numbers.
|
|
20
|
-
* Each character is decoded using the Base64 map and continuation bits are processed.
|
|
21
|
-
*
|
|
22
|
-
* @param data - The VLQ encoded string.
|
|
23
|
-
* @returns The array of decoded numbers.
|
|
24
|
-
* @throws Error If the string contains invalid Base64 characters.
|
|
25
|
-
*/
|
|
26
|
-
export declare function decodeVLQ(data: string): number[];
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Import will remove at compile time
|
|
3
|
-
*/
|
|
4
|
-
import type { PositionWithCodeInterface } from "../services/interfaces/source.interface";
|
|
5
|
-
import type { AnsiOptionInterface, FormatCodeInterface } from "./interfaces/formatter.interface";
|
|
6
|
-
/**
|
|
7
|
-
* Formats a code snippet with optional line padding and custom actions.
|
|
8
|
-
*
|
|
9
|
-
* This function takes a code string and an options object to format the code snippet.
|
|
10
|
-
* It applies padding to line numbers and can trigger custom actions for specific lines.
|
|
11
|
-
*
|
|
12
|
-
* @param code - The source code | stack to be formatted.
|
|
13
|
-
* @param options - Configuration options for formatting the code.
|
|
14
|
-
* - `padding` (number, optional): Number of characters for line number padding. Defaults to 10.
|
|
15
|
-
* - `startLine` (number, optional): The starting line number for formatting. Defaults to 1.
|
|
16
|
-
* - `action` (object, optional): Custom actions to apply to specific lines.
|
|
17
|
-
* - `triggerLine` (number): The line number where the action should be triggered.
|
|
18
|
-
* - `callback` (function): A callback function to format the line string when `triggerLine` is matched.
|
|
19
|
-
* The callback receives the formatted line string, the padding value, and the current line number as arguments.
|
|
20
|
-
*
|
|
21
|
-
* @returns A formatted string of the code snippet with applied padding and custom actions.
|
|
22
|
-
*
|
|
23
|
-
* @example
|
|
24
|
-
* ```typescript
|
|
25
|
-
* const formattedCode = formatCode(code, {
|
|
26
|
-
* padding: 8,
|
|
27
|
-
* startLine: 5,
|
|
28
|
-
* action: {
|
|
29
|
-
* triggerLine: 7,
|
|
30
|
-
* callback: (lineString, padding, lineNumber) => {
|
|
31
|
-
* return `Custom formatting for line ${lineNumber}: ${lineString}`;
|
|
32
|
-
* }
|
|
33
|
-
* }
|
|
34
|
-
* });
|
|
35
|
-
* console.log(formattedCode);
|
|
36
|
-
* ```
|
|
37
|
-
*/
|
|
38
|
-
export declare function formatCode(code: string, options?: FormatCodeInterface): string;
|
|
39
|
-
/**
|
|
40
|
-
* Formats a code snippet around an error location with special highlighting.
|
|
41
|
-
*
|
|
42
|
-
* This function takes a `sourcePosition` object containing information about the source code
|
|
43
|
-
* and error location, then uses `formatCode` to format and highlight the relevant code snippet.
|
|
44
|
-
*
|
|
45
|
-
* @param sourcePosition - An object containing information about the source code and error location.
|
|
46
|
-
* - `code` (string): The entire source code content.
|
|
47
|
-
* - `line` (number): The line number where the error occurred (1-based indexing).
|
|
48
|
-
* - `column` (number): The column number within the line where the error occurred (1-based indexing).
|
|
49
|
-
* - `startLine` (number, optional): The starting line number of the code snippet (defaults to 1).
|
|
50
|
-
* @param ansiOption - Optional configuration for ANSI color codes.
|
|
51
|
-
* - `color` (string): The ANSI escape sequence to colorize the error marker and prefix (e.g., `'\x1b[38;5;160m'`).
|
|
52
|
-
* - `reset` (string): The ANSI escape sequence to reset the color (e.g., `'\x1b[0m'`).
|
|
53
|
-
*
|
|
54
|
-
* @throws Error - If the provided `sourcePosition` object has invalid line or column numbers,
|
|
55
|
-
* or if the error line is outside the boundaries of the provided code content.
|
|
56
|
-
*
|
|
57
|
-
* @returns A formatted string representing the relevant code snippet around the error location,
|
|
58
|
-
* including special highlighting for the error line and column.
|
|
59
|
-
*
|
|
60
|
-
* @example
|
|
61
|
-
* ```typescript
|
|
62
|
-
* const formattedErrorCode = formatErrorCode(sourcePosition);
|
|
63
|
-
* console.log(formattedErrorCode);
|
|
64
|
-
* ```
|
|
65
|
-
*/
|
|
66
|
-
export declare function formatErrorCode(sourcePosition: PositionWithCodeInterface, ansiOption?: AnsiOptionInterface): string;
|
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Import will remove at compile time
|
|
3
|
-
*/
|
|
4
|
-
import type { HighlightSchemeInterface } from "./interfaces/highlighter.interface";
|
|
5
|
-
/**
|
|
6
|
-
* Imports
|
|
7
|
-
*/
|
|
8
|
-
import * as ts from 'typescript';
|
|
9
|
-
/**
|
|
10
|
-
* An enum containing ANSI escape sequences for various colors.
|
|
11
|
-
*
|
|
12
|
-
* This enum is primarily intended for terminal output and won't work directly in JavaScript for web development.
|
|
13
|
-
* It defines color codes for various colors and a reset code to return to
|
|
14
|
-
* the default text color.
|
|
15
|
-
*
|
|
16
|
-
* @example
|
|
17
|
-
* ```typescript
|
|
18
|
-
* console.log(`${Colors.red}This the text will be red in the terminal.${Colors.reset}`);
|
|
19
|
-
* ```
|
|
20
|
-
*
|
|
21
|
-
* This functionality is limited to terminal environments.
|
|
22
|
-
* Consider alternative methods
|
|
23
|
-
* for color highlighting in web development contexts, such as CSS classes.
|
|
24
|
-
*/
|
|
25
|
-
export declare const enum Colors {
|
|
26
|
-
reset = "\u001B[0m",
|
|
27
|
-
gray = "\u001B[38;5;243m",
|
|
28
|
-
darkGray = "\u001B[38;5;238m",
|
|
29
|
-
lightCoral = "\u001B[38;5;203m",
|
|
30
|
-
lightOrange = "\u001B[38;5;215m",
|
|
31
|
-
oliveGreen = "\u001B[38;5;149m",
|
|
32
|
-
burntOrange = "\u001B[38;5;208m",
|
|
33
|
-
lightGoldenrodYellow = "\u001B[38;5;221m",
|
|
34
|
-
lightYellow = "\u001B[38;5;230m",
|
|
35
|
-
canaryYellow = "\u001B[38;5;227m",
|
|
36
|
-
deepOrange = "\u001B[38;5;166m",
|
|
37
|
-
lightGray = "\u001B[38;5;252m",
|
|
38
|
-
brightPink = "\u001B[38;5;197m"
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Class responsible for applying semantic highlighting to a source code string based on a given color scheme.
|
|
42
|
-
*
|
|
43
|
-
* @class
|
|
44
|
-
*
|
|
45
|
-
* @param sourceFile - The TypeScript AST node representing the source file.
|
|
46
|
-
* @param code - The source code string to be highlighted.
|
|
47
|
-
* @param schema - The color scheme used for highlighting different elements in the code.
|
|
48
|
-
*
|
|
49
|
-
* const highlighter = new CodeHighlighter(sourceFile, code, schema);
|
|
50
|
-
*/
|
|
51
|
-
export declare class CodeHighlighter {
|
|
52
|
-
private sourceFile;
|
|
53
|
-
private code;
|
|
54
|
-
private schema;
|
|
55
|
-
/**
|
|
56
|
-
* A Map of segments where the key is a combination of start and end positions,
|
|
57
|
-
* and the value is an object containing the color and reset code.
|
|
58
|
-
* This structure ensures unique segments and allows for fast lookups and updates.
|
|
59
|
-
*
|
|
60
|
-
* @example
|
|
61
|
-
* this.segments = new Map([
|
|
62
|
-
* ['0-10', { start: 1, end: 11, color: '\x1b[31m', reset: '\x1b[0m' }],
|
|
63
|
-
* ['11-20', { start: 12, end: 20, color: '\x1b[32m', reset: '\x1b[0m' }]
|
|
64
|
-
* ]);
|
|
65
|
-
*/
|
|
66
|
-
private segments;
|
|
67
|
-
/**
|
|
68
|
-
* Creates an instance of the CodeHighlighter class.
|
|
69
|
-
*
|
|
70
|
-
* @param sourceFile - The TypeScript AST node representing the source file.
|
|
71
|
-
* @param code - The source code string to be highlighted.
|
|
72
|
-
* @param schema - The color scheme used for highlighting different elements in the code.
|
|
73
|
-
*/
|
|
74
|
-
constructor(sourceFile: ts.Node, code: string, schema: HighlightSchemeInterface);
|
|
75
|
-
/**
|
|
76
|
-
* Parses a TypeScript AST node and processes its comments to identify segments that need highlighting.
|
|
77
|
-
*
|
|
78
|
-
* @param node - The TypeScript AST node to be parsed.
|
|
79
|
-
*/
|
|
80
|
-
parseNode(node: ts.Node): void;
|
|
81
|
-
/**
|
|
82
|
-
* Generates a string with highlighted code segments based on the provided color scheme.
|
|
83
|
-
*
|
|
84
|
-
* This method processes the stored segments, applies the appropriate colors to each segment,
|
|
85
|
-
* and returns the resulting highlighted code as a single string.
|
|
86
|
-
*
|
|
87
|
-
* @returns The highlighted code as a string, with ANSI color codes applied to the segments.
|
|
88
|
-
*/
|
|
89
|
-
highlight(): string;
|
|
90
|
-
/**
|
|
91
|
-
* Extracts a substring from the code based on the specified start and end positions.
|
|
92
|
-
*
|
|
93
|
-
* This method is used to retrieve the source code segment that corresponds to the
|
|
94
|
-
* given start and end positions. It is primarily used for highlighting specific
|
|
95
|
-
* segments of the code.
|
|
96
|
-
*
|
|
97
|
-
* @param start - The starting index of the segment to be extracted.
|
|
98
|
-
* @param end - The ending index of the segment to be extracted.
|
|
99
|
-
* @returns The extracted substring from the code.
|
|
100
|
-
*/
|
|
101
|
-
private getSegmentSource;
|
|
102
|
-
/**
|
|
103
|
-
* Adds a new segment to the list of segments to be highlighted.
|
|
104
|
-
* The segment is defined by its start and end positions, the color to apply, and an optional reset code.
|
|
105
|
-
*
|
|
106
|
-
* @param start - The starting index of the segment in the code string.
|
|
107
|
-
* @param end - The ending index of the segment in the code string.
|
|
108
|
-
* @param color - The color code to apply to the segment.
|
|
109
|
-
* @param reset - The color reset code to apply after the segment, Defaults to the reset code defined in `Colors.reset`.
|
|
110
|
-
*/
|
|
111
|
-
private addSegment;
|
|
112
|
-
/**
|
|
113
|
-
* Processes comments within a TypeScript AST node and adds segments for highlighting.
|
|
114
|
-
* Extracts trailing and leading comments from the node and adds them as segments using the color defined in `this.colorSchema.comments`.
|
|
115
|
-
*
|
|
116
|
-
* @param node - The TypeScript AST node whose comments are to be processed.
|
|
117
|
-
*/
|
|
118
|
-
private processComments;
|
|
119
|
-
/**
|
|
120
|
-
* Processes the keywords within a TypeScript AST node and adds them as segments for highlighting.
|
|
121
|
-
*
|
|
122
|
-
* This method identifies potential keyword tokens within the provided node and adds them to the
|
|
123
|
-
* list of segments with the color defined in `this.schema.keywordColor`.
|
|
124
|
-
* The method considers the current node, its first token, and its last token to determine if they should be highlighted
|
|
125
|
-
* as keywords.
|
|
126
|
-
*
|
|
127
|
-
* The method checks if the node's kind falls within the range of keyword kinds defined by TypeScript.
|
|
128
|
-
* If the node or any of its tokens are identified as keywords, a segment is added to `this.segments`
|
|
129
|
-
* with the start and end positions of the node and the specified color for keywords.
|
|
130
|
-
*
|
|
131
|
-
* @param node - The TypeScript AST node to be processed for keywords.
|
|
132
|
-
*/
|
|
133
|
-
private processKeywords;
|
|
134
|
-
/**
|
|
135
|
-
* Processes identifiers within a TypeScript AST node and adds them as segments for highlighting
|
|
136
|
-
* based on the node's parent type.
|
|
137
|
-
*
|
|
138
|
-
* This method determines the appropriate color for an identifier based on its parent node's kind.
|
|
139
|
-
* If the parent node matches one of the specified kinds, the identifier is highlighted with a cyan color.
|
|
140
|
-
* Supported parent kinds include various declarations, expressions, and signatures.
|
|
141
|
-
*
|
|
142
|
-
* @param node - The TypeScript AST node representing the identifier to be processed.
|
|
143
|
-
*/
|
|
144
|
-
private processIdentifier;
|
|
145
|
-
/**
|
|
146
|
-
* Processes a TypeScript template expression and adds segments for highlighting its literal parts.
|
|
147
|
-
*
|
|
148
|
-
* This method adds a segment for the head of the template expression with the color specified in `this.schema.stringColor`.
|
|
149
|
-
* It also processes each template span within the expression, adding
|
|
150
|
-
* segments for each span's literal part.
|
|
151
|
-
*
|
|
152
|
-
* @param templateExpression - The TypeScript template expression to be processed.
|
|
153
|
-
*/
|
|
154
|
-
private processTemplateExpression;
|
|
155
|
-
/**
|
|
156
|
-
* Processes a TypeScript AST node and adds segments for highlighting based on the node's kind.
|
|
157
|
-
*
|
|
158
|
-
* This method identifies the kind of the node and determines the appropriate color for highlighting.
|
|
159
|
-
* It handles various node kinds including string literals, regular expressions, template expressions, and identifiers.
|
|
160
|
-
* Specific methods are invoked for more complex node kinds, such as template expressions and identifiers.
|
|
161
|
-
*
|
|
162
|
-
* @param node - The TypeScript AST node to be processed.
|
|
163
|
-
*/
|
|
164
|
-
private processNode;
|
|
165
|
-
}
|
|
166
|
-
/**
|
|
167
|
-
* Applies semantic highlighting to the provided code string using the specified color scheme.
|
|
168
|
-
*
|
|
169
|
-
* @param code - The source code to be highlighted.
|
|
170
|
-
* @param schema - An optional partial schema defining the color styles for various code elements.
|
|
171
|
-
* Defaults to an empty object, which means no specific highlighting will be applied.
|
|
172
|
-
*
|
|
173
|
-
* @returns A string with the code elements wrapped in the appropriate color styles as specified by the schema.
|
|
174
|
-
*
|
|
175
|
-
* @example
|
|
176
|
-
* const code = 'const x: number = 42;';
|
|
177
|
-
* const schema = {
|
|
178
|
-
* keywordColor: '\x1b[34m', // Blue
|
|
179
|
-
* stringColor: '\x1b[32m', // Green
|
|
180
|
-
* numberColor: '\x1b[31m', // Red
|
|
181
|
-
* reset: '\x1b[0m' // Reset
|
|
182
|
-
* };
|
|
183
|
-
* const highlightedCode = highlightCode(code, schema);
|
|
184
|
-
* console.log(highlightedCode);
|
|
185
|
-
*/
|
|
186
|
-
export declare function highlightCode(code: string, schema?: Partial<HighlightSchemeInterface>): string;
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A callback function type used for formatting code lines.
|
|
3
|
-
*
|
|
4
|
-
* @param lineString - The content of the line to be formatted.
|
|
5
|
-
* @param padding - The amount of padding to be applied to the line.
|
|
6
|
-
* @param line - The line number of the line to be formatted.
|
|
7
|
-
* @returns The formatted line string.
|
|
8
|
-
*/
|
|
9
|
-
export type FormatCodeCallbackType = (lineString: string, padding: number, line: number) => string;
|
|
10
|
-
/**
|
|
11
|
-
* Configuration options for formatting code.
|
|
12
|
-
*/
|
|
13
|
-
export interface FormatCodeInterface {
|
|
14
|
-
/**
|
|
15
|
-
* The amount of padding to be applied to each line. If not specified, defaults to 0.
|
|
16
|
-
*/
|
|
17
|
-
padding?: number;
|
|
18
|
-
/**
|
|
19
|
-
* The starting line number for formatting. If not specified, defaults to 1.
|
|
20
|
-
*/
|
|
21
|
-
startLine?: number;
|
|
22
|
-
/**
|
|
23
|
-
* An optional action object specifying a line where a callback function should be triggered.
|
|
24
|
-
*/
|
|
25
|
-
action?: {
|
|
26
|
-
/**
|
|
27
|
-
* The line number at which the callback function should be triggered.
|
|
28
|
-
*/
|
|
29
|
-
triggerLine: number;
|
|
30
|
-
/**
|
|
31
|
-
* The callback function to be executed when the trigger line is encountered.
|
|
32
|
-
*/
|
|
33
|
-
callback: FormatCodeCallbackType;
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Set color to an error pointer
|
|
38
|
-
*/
|
|
39
|
-
export interface AnsiOptionInterface {
|
|
40
|
-
color: string;
|
|
41
|
-
reset: string;
|
|
42
|
-
}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* HighlightSchemeInterface defines the structure for a color style schema
|
|
3
|
-
* used in semantic highlighting.
|
|
4
|
-
* This interface ensures that the highlighting styles are consistent and easily configurable.
|
|
5
|
-
*/
|
|
6
|
-
export interface HighlightSchemeInterface {
|
|
7
|
-
enumColor: string;
|
|
8
|
-
typeColor: string;
|
|
9
|
-
classColor: string;
|
|
10
|
-
stringColor: string;
|
|
11
|
-
keywordColor: string;
|
|
12
|
-
commentColor: string;
|
|
13
|
-
functionColor: string;
|
|
14
|
-
variableColor: string;
|
|
15
|
-
interfaceColor: string;
|
|
16
|
-
parameterColor: string;
|
|
17
|
-
getAccessorColor: string;
|
|
18
|
-
numericLiteralColor: string;
|
|
19
|
-
methodSignatureColor: string;
|
|
20
|
-
regularExpressionColor: string;
|
|
21
|
-
propertyAssignmentColor: string;
|
|
22
|
-
propertyAccessExpressionColor: string;
|
|
23
|
-
expressionWithTypeArgumentsColor: string;
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Represents a segment of a code string that needs to be highlighted.
|
|
27
|
-
*
|
|
28
|
-
* @interface
|
|
29
|
-
*
|
|
30
|
-
* @property start - The starting index of the segment in the code string.
|
|
31
|
-
* @property end - The ending index of the segment in the code string.
|
|
32
|
-
* @property color - The color code to apply to the segment.
|
|
33
|
-
* @property reset - The color reset code to apply after the segment.
|
|
34
|
-
*
|
|
35
|
-
* @example
|
|
36
|
-
* const segment: HighlightNodeSegment = {
|
|
37
|
-
* start: 0,
|
|
38
|
-
* end: 10,
|
|
39
|
-
* color: '\x1b[31m', // Red
|
|
40
|
-
* reset: '\x1b[0m' // Reset
|
|
41
|
-
* };
|
|
42
|
-
*/
|
|
43
|
-
export interface HighlightNodeSegmentInterface {
|
|
44
|
-
end: number;
|
|
45
|
-
start: number;
|
|
46
|
-
color: string;
|
|
47
|
-
reset: string;
|
|
48
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Represents an entry in the stack trace.
|
|
3
|
-
*/
|
|
4
|
-
export interface StackInterface {
|
|
5
|
-
/**
|
|
6
|
-
* The function or method where the error occurred.
|
|
7
|
-
*/
|
|
8
|
-
at: string;
|
|
9
|
-
/**
|
|
10
|
-
* The file path where the error occurred.
|
|
11
|
-
*/
|
|
12
|
-
file: string;
|
|
13
|
-
/**
|
|
14
|
-
* The line number where the error occurred.
|
|
15
|
-
*/
|
|
16
|
-
line: number;
|
|
17
|
-
/**
|
|
18
|
-
* The column number where the error occurred.
|
|
19
|
-
*/
|
|
20
|
-
column: number;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Represents a detailed entry in the stack trace, which may include an executor stack entry.
|
|
24
|
-
*/
|
|
25
|
-
export interface StackEntryInterface extends StackInterface {
|
|
26
|
-
/**
|
|
27
|
-
* The executor information if the error occurred within an eval function.
|
|
28
|
-
* This will be `null` if the error did not occur within an eval function.
|
|
29
|
-
*/
|
|
30
|
-
executor?: StackInterface | null;
|
|
31
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Import will remove at compile time
|
|
3
|
-
*/
|
|
4
|
-
import type { StackEntryInterface } from "./interfaces/parse.interface";
|
|
5
|
-
/**
|
|
6
|
-
* Parses an error stack trace and returns an object with a message and an array of stack entries.
|
|
7
|
-
*
|
|
8
|
-
* @param stackString - The error stack trace.
|
|
9
|
-
* @returns The parsed stack trace object.
|
|
10
|
-
*/
|
|
11
|
-
export declare function parseErrorStack(stackString: string): Array<StackEntryInterface>;
|
package/dist/esm/index.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export type * from "./components/interfaces/parse.interface";
|
|
2
|
-
export type * from "./components/interfaces/formatter.interface";
|
|
3
|
-
export type * from "./components/interfaces/highlighter.interface";
|
|
4
|
-
export type * from "./services/interfaces/source.interface";
|
|
5
|
-
export * from "./components/parser.component";
|
|
6
|
-
export * from "./components/base64.component";
|
|
7
|
-
export * from "./components/formatter.component";
|
|
8
|
-
export * from "./components/highlighter.component";
|
|
9
|
-
export * from "./services/source.service";
|