Move the webapp into its own folder

This commit is contained in:
iamBadgers
2025-06-02 17:56:58 -07:00
parent cf3abe92f5
commit f6fcf82eae
51 changed files with 2 additions and 2 deletions

View File

@@ -0,0 +1,177 @@
import Tokenizr from 'tokenizr'
import { Op } from 'sequelize'
export { ParsingError } from 'tokenizr'
export class OrderByParser {
lexer = new Tokenizr()
constructor() {
this.lexer.rule(/,/, (ctx, m) => {
ctx.accept('spacer')
})
this.lexer.rule(/ASC|DESC/, (ctx, m) => {
ctx.accept('direction', m[0])
})
this.lexer.rule(/[a-zA-Z]+/, (ctx, m) => {
ctx.accept('column', m[0])
})
this.lexer.rule(/\s/, (ctx, m) => {
ctx.ignore()
})
}
parse(orderBy: string) {
const output = []
let holding = []
this.lexer
.input(orderBy)
.tokens()
.forEach((token) => {
switch (token.type) {
case 'spacer':
output.push(holding)
holding = []
break
case 'column':
case 'direction':
holding.push(token.value)
break
}
})
if (holding) {
output.push(holding)
}
return output
}
}
const openGroupRegex = /\(/
const closeGroupRegex = /\)/
const conjunctinoRegex = /AND|OR/
const equalityRegex = /([a-zA-Z]+)\s?(=|!=|<|>|<=|>=|:)\s?([\d]+)/
const stringEqualityRegex = /([a-zA-Z]+)\s?(=|!=|<|>|<=|>=|:)\s?\"([a-zA-Z'"\d\s]*)\"/
const spacerRegex = /\s/
const opperatorMap = {
'=': Op.eq,
'!=': Op.ne,
'<=': Op.lte,
'>=': Op.gte,
'>': Op.gt,
'<': Op.lt,
':': Op.like,
AND: Op.and,
OR: Op.or
}
export class FilterParser {
lexer: Tokenizr
constructor() {
this.lexer = new Tokenizr()
this.lexer.rule(openGroupRegex, (ctx, m) => {
ctx.accept('opengroup')
})
this.lexer.rule(closeGroupRegex, (ctx, m) => {
ctx.accept('closegroup')
})
this.lexer.rule(conjunctinoRegex, (ctx, m) => {
ctx.accept('conjunction', m[0])
})
this.lexer.rule(stringEqualityRegex, (ctx, m) => {
ctx.accept('column', m[1])
ctx.accept('opperator', m[2])
ctx.accept('value', m[3])
})
this.lexer.rule(equalityRegex, (ctx, m) => {
ctx.accept('column', m[1])
ctx.accept('opperator', m[2])
ctx.accept('value', m[3])
})
this.lexer.rule(spacerRegex, (ctx, m) => {
ctx.ignore()
})
}
parse(filter: string) {
this.lexer.input(filter)
let block = this.parseBlock('AND')
this.lexer.consume('EOF')
this.lexer.reset()
return block
}
private parseBlock(conjunciton: string) {
let items = []
let activeCon = conjunciton
for (;;) {
let nextItem = this.lexer.alternatives(
() => this.parseEquality(),
() => this.parseGroup(),
() => {
let conToken = this.lexer.consume('conjunction')
if (items.length === 1) {
activeCon = conToken.value
}
if (conToken.value === activeCon) {
return this.parseEquality()
} else {
return this.parseBlock(conToken.value)
}
},
() => this.parseEmpty()
)
if (nextItem === undefined) {
break
}
items.push(nextItem)
}
return { [opperatorMap[activeCon]]: items }
}
private parseEquality() {
let columnToken = this.lexer.consume('column')
let opperatorToken = this.lexer.consume('opperator')
let valueToken = this.lexer.consume('value')
if (opperatorToken.value === ':') {
return {
[columnToken.value]: {
[opperatorMap[opperatorToken.value]]: `%${valueToken.value.toString()}%`
}
}
} else {
return {
[columnToken.value]: { [opperatorMap[opperatorToken.value]]: valueToken.value.toString() }
}
}
}
private parseGroup() {
this.lexer.consume('opengroup')
let block = this.parseBlock('AND')
this.lexer.consume('closegroup')
return block
}
private parseEmpty() {
return undefined
}
}