1- import { type EncoderNode , EncoderPrecedence } from '../encoder/types' ;
1+ import type { EncodeOutput } from '../encoder/types' ;
22import { escapeText } from '../utils/text' ;
3- import type { CharacterClass } from './types' ;
3+
4+ export interface CharacterClass {
5+ type : 'characterClass' ;
6+ characters : string [ ] ;
7+ ranges : CharacterRange [ ] ;
8+ isInverted : boolean ;
9+ encode : ( ) => EncodeOutput ;
10+ }
11+
12+ /**
13+ * Character range from start to end (inclusive).
14+ */
15+ export interface CharacterRange {
16+ start : string ;
17+ end : string ;
18+ }
419
520export const any : CharacterClass = {
621 type : 'characterClass' ,
722 characters : [ '.' ] ,
823 ranges : [ ] ,
924 isInverted : false ,
25+ encode : encodeCharacterClass ,
1026} ;
1127
1228export const digit : CharacterClass = {
1329 type : 'characterClass' ,
1430 characters : [ '\\d' ] ,
1531 ranges : [ ] ,
1632 isInverted : false ,
33+ encode : encodeCharacterClass ,
1734} ;
1835
1936export const word : CharacterClass = {
2037 type : 'characterClass' ,
2138 characters : [ '\\w' ] ,
2239 ranges : [ ] ,
2340 isInverted : false ,
41+ encode : encodeCharacterClass ,
2442} ;
2543
2644export const whitespace : CharacterClass = {
2745 type : 'characterClass' ,
2846 characters : [ '\\s' ] ,
2947 ranges : [ ] ,
3048 isInverted : false ,
49+ encode : encodeCharacterClass ,
3150} ;
3251
3352export function characterClass ( ...elements : CharacterClass [ ] ) : CharacterClass {
@@ -44,6 +63,7 @@ export function characterClass(...elements: CharacterClass[]): CharacterClass {
4463 characters : elements . map ( ( c ) => c . characters ) . flat ( ) ,
4564 ranges : elements . map ( ( c ) => c . ranges ) . flat ( ) ,
4665 isInverted : false ,
66+ encode : encodeCharacterClass ,
4767 } ;
4868}
4969
@@ -61,7 +81,7 @@ export function characterRange(start: string, end: string): CharacterClass {
6181 }
6282
6383 if ( start > end ) {
64- throw new Error ( '`start` should be less or equal to `end`' ) ;
84+ throw new Error ( '`start` should be before or equal to `end`' ) ;
6585 }
6686
6787 const range = {
@@ -74,6 +94,7 @@ export function characterRange(start: string, end: string): CharacterClass {
7494 characters : [ ] ,
7595 ranges : [ range ] ,
7696 isInverted : false ,
97+ encode : encodeCharacterClass ,
7798 } ;
7899}
79100
@@ -88,53 +109,51 @@ export function anyOf(characters: string): CharacterClass {
88109 characters : charactersArray ,
89110 ranges : [ ] ,
90111 isInverted : false ,
112+ encode : encodeCharacterClass ,
91113 } ;
92114}
93115
94- export function inverted ( {
95- characters,
96- ranges,
97- isInverted,
98- } : CharacterClass ) : CharacterClass {
116+ export function inverted ( element : CharacterClass ) : CharacterClass {
99117 return {
100118 type : 'characterClass' ,
101- characters : characters ,
102- ranges : ranges ,
103- isInverted : ! isInverted ,
119+ characters : element . characters ,
120+ ranges : element . ranges ,
121+ isInverted : ! element . isInverted ,
122+ encode : encodeCharacterClass ,
104123 } ;
105124}
106125
107- export function encodeCharacterClass ( {
108- characters,
109- ranges,
110- isInverted,
111- } : CharacterClass ) : EncoderNode {
112- if ( characters . length === 0 && ranges . length === 0 ) {
126+ function encodeCharacterClass ( this : CharacterClass ) : EncodeOutput {
127+ if ( this . characters . length === 0 && this . ranges . length === 0 ) {
113128 throw new Error (
114129 'Character class should contain at least one character or character range'
115130 ) ;
116131 }
117132
118133 // Direct rendering for single-character class
119- if ( characters . length === 1 && ranges ?. length === 0 && ! isInverted ) {
134+ if (
135+ this . characters . length === 1 &&
136+ this . ranges ?. length === 0 &&
137+ ! this . isInverted
138+ ) {
120139 return {
121- precedence : EncoderPrecedence . Atom ,
122- pattern : characters [ 0 ] ! ,
140+ precedence : 'atom' ,
141+ pattern : this . characters [ 0 ] ! ,
123142 } ;
124143 }
125144
126145 // If passed characters includes hyphen (`-`) it need to be moved to
127146 // first (or last) place in order to treat it as hyphen character and not a range.
128147 // See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions/Character_classes#types
129- const hyphenString = characters . includes ( '-' ) ? '-' : '' ;
130- const charactersString = characters . filter ( ( c ) => c !== '-' ) . join ( '' ) ;
131- const rangesString = ranges
148+ const hyphen = this . characters . includes ( '-' ) ? '-' : '' ;
149+ const otherCharacters = this . characters . filter ( ( c ) => c !== '-' ) . join ( '' ) ;
150+ const ranges = this . ranges
132151 . map ( ( { start, end } ) => `${ start } -${ end } ` )
133152 . join ( '' ) ;
134- const invertedString = isInverted ? '^' : '' ;
153+ const isInverted = this . isInverted ? '^' : '' ;
135154
136155 return {
137- precedence : EncoderPrecedence . Atom ,
138- pattern : `[${ invertedString } ${ hyphenString } ${ rangesString } ${ charactersString } ]` ,
156+ precedence : 'atom' ,
157+ pattern : `[${ isInverted } ${ hyphen } ${ ranges } ${ otherCharacters } ]` ,
139158 } ;
140159}
0 commit comments