This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const runExpr = (e: Expr, i: any): any => { | |
if (e.kind == 'acs') return i[e.id] | |
if (e.kind == '==') return runExpr(e.left, i) == runExpr(e.right, i) | |
if (e.kind == 'includes') return runExpr(e.left, i).contains(runExpr(e.right, i)) | |
if (e.kind == '&&') return runExpr(e.left, i) && runExpr(e.right, i) | |
if (e.kind == 'val') return e.value | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
odata<Blog>('Blog') | |
.where(b => b.Id.equals(1).and(b.Title.includes('hello'))) | |
.toArray() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const odata = <T>(name: string, baseuri = '/odata'): IQueryable<T> => { | |
const exprs: Expr<T>[] = [] | |
return { | |
where(e) { | |
exprs.push(e(builder()).getExpr()) | |
return this | |
}, | |
toArray: async () => { | |
const res = await fetch(`${baseuri}/${name}?$filter=${exprs.map(compileOdata).join(' and ')}`) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const compileOdata = (e: Expr): string => { | |
if (e.kind == 'acs') return e.id.toString() | |
if (e.kind == '==') return `${compileOdata(e.left)} eq ${compileOdata(e.right)}` | |
if (e.kind == 'includes') return `substringof( ${compileOdata(e.right)}, ${compileOdata(e.left)})` | |
if (e.kind == '&&') return `${compileOdata(e.left)} and ${compileOdata(e.right)}` | |
if (e.kind == 'val') return typeof e.value == 'string' ? `'${e.value}'` : e.value | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface IQueryable<T> { | |
where(e: Expr<T>): IQueryable<T> | |
toArray(): Promise<T[]> | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Fake<T extends object> = { | |
[k in keyof T]: | |
T[k] extends string ? StringExprBuilder : | |
T[k] extends number ? NumberExprBuilder : | |
BoolExprBuilder | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface StringExprBuilder { | |
equals(s: string | StringExprBuilder): BoolExprBuilder | |
includes(s: string | StringExprBuilder): BoolExprBuilder | |
getExpr(): Expr | |
} | |
interface BoolExprBuilder { | |
equals(s: boolean | BoolExprBuilder): BoolExprBuilder | |
and(e: BoolExprBuilder): BoolExprBuilder | |
getExpr(): Expr |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const handler = { | |
get(_, name: string) => new ExprBuilder(createIndexExpression(name)) | |
} | |
fakeBlog.Id.equals(1) | |
/** | |
{ | |
kind: '==', | |
left: { | |
kind: 'index', |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ExprBuilder { | |
constructor(protected ast: Expr) { } | |
GetExpr = () => this.ast | |
equals(v: string | number | boolean | ExprBuilder) { | |
if (['string', 'number', 'boolean'].indexOf(typeof v) != -1) { | |
return new ExprBuilder(createBinaryExpression('==', this.ast, createValExpression(v))) | |
} | |
return new ExprBuilder(createBinaryExpression('==', this.ast, (v as ExprBuilder).GetExpr())) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ExprBuilder { | |
constructor(protected currentAst: Expr) { } | |
equals(v: any) { | |
return new ExprBuilder((createBinaryExpression('==', this.currentAst, createValExpression(v)))) | |
} | |
} |