mirror of
https://github.com/harttle/liquidjs.git
synced 2026-09-20 06:50:47 -07:00
style: introduce @typescript-eslint/recommended
This commit is contained in:
+9
-1
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"extends": "standard",
|
"extends": ["standard", "plugin:@typescript-eslint/recommended"],
|
||||||
"env": {
|
"env": {
|
||||||
"mocha": true,
|
"mocha": true,
|
||||||
"es6": true,
|
"es6": true,
|
||||||
@@ -17,6 +17,14 @@
|
|||||||
"no-var": 2,
|
"no-var": 2,
|
||||||
"prefer-const": 2,
|
"prefer-const": 2,
|
||||||
"no-unused-vars": "off",
|
"no-unused-vars": "off",
|
||||||
|
"indent": "off",
|
||||||
|
"@typescript-eslint/indent": ["error", 2],
|
||||||
|
"@typescript-eslint/explicit-function-return-type": "off",
|
||||||
|
"@typescript-eslint/no-explicit-any": "off",
|
||||||
|
"@typescript-eslint/no-object-literal-type-assertion": "off",
|
||||||
|
"@typescript-eslint/no-use-before-define": "off",
|
||||||
|
"@typescript-eslint/interface-name-prefix": "off",
|
||||||
|
"@typescript-eslint/no-non-null-assertion": "off",
|
||||||
"import/export": "off",
|
"import/export": "off",
|
||||||
"@typescript-eslint/no-unused-vars": ["error", { "vars": "all", "args": "none", "ignoreRestSiblings": false }]
|
"@typescript-eslint/no-unused-vars": ["error", { "vars": "all", "args": "none", "ignoreRestSiblings": false }]
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+36
-23
@@ -448,6 +448,12 @@
|
|||||||
"integrity": "sha512-aRnpPa7ysx3aNW60hTiCtLHlQaIFsXFCgQlpakNgDNVFzbtusSY8PwjAQgRWfSk0ekNoBjO51eQRB6upA9uuyw==",
|
"integrity": "sha512-aRnpPa7ysx3aNW60hTiCtLHlQaIFsXFCgQlpakNgDNVFzbtusSY8PwjAQgRWfSk0ekNoBjO51eQRB6upA9uuyw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@types/eslint-visitor-keys": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"@types/estree": {
|
"@types/estree": {
|
||||||
"version": "0.0.39",
|
"version": "0.0.39",
|
||||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
|
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
|
||||||
@@ -568,31 +574,44 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@typescript-eslint/eslint-plugin": {
|
"@typescript-eslint/eslint-plugin": {
|
||||||
"version": "1.3.0",
|
"version": "1.11.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.11.0.tgz",
|
||||||
"integrity": "sha512-s+vjO9+PvYS2A6FnQC/imyEDOkrEKIzSpPf2OEGnkKqa5+1d0cuXgCi/oROtuBht2/u/iK22nrYcO/Ei4R8F/g==",
|
"integrity": "sha512-mXv9ccCou89C8/4avKHuPB2WkSZyY/XcTQUXd5LFZAcLw1I3mWYVjUu6eS9Ja0QkP/ClolbcW9tb3Ov/pMdcqw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@typescript-eslint/parser": "1.3.0",
|
"@typescript-eslint/experimental-utils": "1.11.0",
|
||||||
"requireindex": "^1.2.0",
|
"eslint-utils": "^1.3.1",
|
||||||
|
"functional-red-black-tree": "^1.0.1",
|
||||||
|
"regexpp": "^2.0.1",
|
||||||
"tsutils": "^3.7.0"
|
"tsutils": "^3.7.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@typescript-eslint/parser": {
|
"@typescript-eslint/experimental-utils": {
|
||||||
"version": "1.3.0",
|
"version": "1.11.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-1.11.0.tgz",
|
||||||
"integrity": "sha512-Q5cz9nyEQyRrtItRElvQXdNs0Xja1xvOdphDQR7N6MqUdi4juWVNxHKypdHQCx9OcEBev6pWHOda8lwg/2W9/g==",
|
"integrity": "sha512-7LbfaqF6B8oa8cp/315zxKk8FFzosRzzhF8Kn/ZRsRsnpm7Qcu25cR/9RnAQo5utZ2KIWVgaALr+ZmcbG47ruw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@typescript-eslint/typescript-estree": "1.3.0",
|
"@typescript-eslint/typescript-estree": "1.11.0",
|
||||||
"eslint-scope": "^4.0.0",
|
"eslint-scope": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@typescript-eslint/parser": {
|
||||||
|
"version": "1.11.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-1.11.0.tgz",
|
||||||
|
"integrity": "sha512-5xBExyXaxVyczrZvbRKEXvaTUFFq7gIM9BynXukXZE0zF3IQP/FxF4mPmmh3gJ9egafZFqByCpPTFm3dk4SY7Q==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/eslint-visitor-keys": "^1.0.0",
|
||||||
|
"@typescript-eslint/experimental-utils": "1.11.0",
|
||||||
|
"@typescript-eslint/typescript-estree": "1.11.0",
|
||||||
"eslint-visitor-keys": "^1.0.0"
|
"eslint-visitor-keys": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@typescript-eslint/typescript-estree": {
|
"@typescript-eslint/typescript-estree": {
|
||||||
"version": "1.3.0",
|
"version": "1.11.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.11.0.tgz",
|
||||||
"integrity": "sha512-h6UxHSmBUopFcxHg/eryrA+GwHMbh7PxotMbkq9p2f3nX60CKm5Zc0VN8krBD3IS5KqsK0iOz24VpEWrP+JZ2Q==",
|
"integrity": "sha512-fquUHF5tAx1sM2OeRCC7wVxFd1iMELWMGCzOSmJ3pLzArj9+kRixdlC4d5MncuzXpjEqc6045p3KwM0o/3FuUA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"lodash.unescape": "4.0.1",
|
"lodash.unescape": "4.0.1",
|
||||||
@@ -9316,12 +9335,6 @@
|
|||||||
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
|
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"requireindex": {
|
|
||||||
"version": "1.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz",
|
|
||||||
"integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"resolve": {
|
"resolve": {
|
||||||
"version": "1.10.0",
|
"version": "1.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz",
|
||||||
@@ -10475,9 +10488,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"tsutils": {
|
"tsutils": {
|
||||||
"version": "3.8.0",
|
"version": "3.14.0",
|
||||||
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.14.0.tgz",
|
||||||
"integrity": "sha512-XQdPhgcoTbCD8baXC38PQ0vpTZ8T3YrE+vR66YIj/xvDt1//8iAhafpIT/4DmvzzC1QFapEImERu48Pa01dIUA==",
|
"integrity": "sha512-SmzGbB0l+8I0QwsPgjooFRaRvHLBLNYM8SeQ0k6rtNDru5sCGeLJcZdwilNndN+GysuFjF5EIYgN8GfFG6UeUw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"tslib": "^1.8.1"
|
"tslib": "^1.8.1"
|
||||||
|
|||||||
+2
-1
@@ -57,7 +57,8 @@
|
|||||||
"@types/sinon": "^7.0.6",
|
"@types/sinon": "^7.0.6",
|
||||||
"@types/sinon-chai": "^3.2.2",
|
"@types/sinon-chai": "^3.2.2",
|
||||||
"@types/supertest": "^2.0.7",
|
"@types/supertest": "^2.0.7",
|
||||||
"@typescript-eslint/eslint-plugin": "^1.3.0",
|
"@typescript-eslint/eslint-plugin": "^1.11.0",
|
||||||
|
"@typescript-eslint/parser": "^1.11.0",
|
||||||
"benchmark": "^2.1.4",
|
"benchmark": "^2.1.4",
|
||||||
"chai": "^4.2.0",
|
"chai": "^4.2.0",
|
||||||
"chai-as-promised": "^7.1.1",
|
"chai-as-promised": "^7.1.1",
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export default {
|
|||||||
'reverse': (v: any[]) => [...v].reverse(),
|
'reverse': (v: any[]) => [...v].reverse(),
|
||||||
'sort': <T>(v: T[], arg: (lhs: T, rhs: T) => number) => v.sort(arg),
|
'sort': <T>(v: T[], arg: (lhs: T, rhs: T) => number) => v.sort(arg),
|
||||||
'size': (v: string | any[]) => v.length,
|
'size': (v: string | any[]) => v.length,
|
||||||
'concat': <T1, T2>(v: T1[], arg: T2[] | T2): Array<T1 | T2> => Array.prototype.concat.call(v, arg),
|
'concat': <T1, T2>(v: T1[], arg: T2[] | T2): (T1 | T2)[] => Array.prototype.concat.call(v, arg),
|
||||||
'slice': <T>(v: T[], begin: number, length: number = 1): T[] => {
|
'slice': <T>(v: T[], begin: number, length: number = 1): T[] => {
|
||||||
begin = begin < 0 ? v.length + begin : begin
|
begin = begin < 0 ? v.length + begin : begin
|
||||||
return v.slice(begin, begin + length)
|
return v.slice(begin, begin + length)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export default {
|
|||||||
'times': (v: number, arg: number) => v * arg
|
'times': (v: number, arg: number) => v * arg
|
||||||
}
|
}
|
||||||
|
|
||||||
function caseInsensitiveCmp (a, b) {
|
function caseInsensitiveCmp (a: any, b: any) {
|
||||||
if (!b) return -1
|
if (!b) return -1
|
||||||
if (!a) return 1
|
if (!a) return 1
|
||||||
a = toLowerCase.call(a)
|
a = toLowerCase.call(a)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import ITagImplOptions from '../../template/tag/itag-impl-options'
|
|||||||
const groupRE = new RegExp(`^(?:(${rValue.source})\\s*:\\s*)?(.*)$`)
|
const groupRE = new RegExp(`^(?:(${rValue.source})\\s*:\\s*)?(.*)$`)
|
||||||
const candidatesRE = new RegExp(rValue.source, 'g')
|
const candidatesRE = new RegExp(rValue.source, 'g')
|
||||||
|
|
||||||
export default <ITagImplOptions>{
|
export default {
|
||||||
parse: function (tagToken: TagToken) {
|
parse: function (tagToken: TagToken) {
|
||||||
let match: RegExpExecArray | null = groupRE.exec(tagToken.args) as RegExpExecArray
|
let match: RegExpExecArray | null = groupRE.exec(tagToken.args) as RegExpExecArray
|
||||||
assert(match, `illegal tag: ${tagToken.raw}`)
|
assert(match, `illegal tag: ${tagToken.raw}`)
|
||||||
@@ -40,4 +40,4 @@ export default <ITagImplOptions>{
|
|||||||
|
|
||||||
return evalValue(candidate, ctx)
|
return evalValue(candidate, ctx)
|
||||||
}
|
}
|
||||||
}
|
} as ITagImplOptions
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ const re = new RegExp(`^(${identifier.source})\\s+in\\s+` +
|
|||||||
`(?:\\s+(reversed))?` +
|
`(?:\\s+(reversed))?` +
|
||||||
`(?:\\s+${hash.source})*$`)
|
`(?:\\s+${hash.source})*$`)
|
||||||
|
|
||||||
export default <ITagImplOptions>{
|
export default {
|
||||||
type: 'block',
|
type: 'block',
|
||||||
parse: function (tagToken: TagToken, remainTokens: Token[]) {
|
parse: function (tagToken: TagToken, remainTokens: Token[]) {
|
||||||
const match = re.exec(tagToken.args) as RegExpExecArray
|
const match = re.exec(tagToken.args) as RegExpExecArray
|
||||||
@@ -79,4 +79,4 @@ export default <ITagImplOptions>{
|
|||||||
ctx.pop()
|
ctx.pop()
|
||||||
return html
|
return html
|
||||||
}
|
}
|
||||||
}
|
} as ITagImplOptions
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import ITagImplOptions from '../../template/tag/itag-impl-options'
|
|||||||
const staticFileRE = /[^\s,]+/
|
const staticFileRE = /[^\s,]+/
|
||||||
const withRE = new RegExp(`with\\s+(${value.source})`)
|
const withRE = new RegExp(`with\\s+(${value.source})`)
|
||||||
|
|
||||||
export default <ITagImplOptions>{
|
export default {
|
||||||
parse: function (token: TagToken) {
|
parse: function (token: TagToken) {
|
||||||
let match = staticFileRE.exec(token.args)
|
let match = staticFileRE.exec(token.args)
|
||||||
if (match) this.staticValue = match[0]
|
if (match) this.staticValue = match[0]
|
||||||
@@ -51,4 +51,4 @@ export default <ITagImplOptions>{
|
|||||||
ctx.setRegister('blockMode', originBlockMode)
|
ctx.setRegister('blockMode', originBlockMode)
|
||||||
return html
|
return html
|
||||||
}
|
}
|
||||||
}
|
} as ITagImplOptions
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import TagToken from '../../parser/tag-token'
|
|||||||
import Token from '../../parser/token'
|
import Token from '../../parser/token'
|
||||||
import ITagImplOptions from '../../template/tag/itag-impl-options'
|
import ITagImplOptions from '../../template/tag/itag-impl-options'
|
||||||
|
|
||||||
export default <ITagImplOptions>{
|
export default {
|
||||||
parse: function (tagToken: TagToken, remainTokens: Token[]) {
|
parse: function (tagToken: TagToken, remainTokens: Token[]) {
|
||||||
this.tokens = []
|
this.tokens = []
|
||||||
|
|
||||||
@@ -20,4 +20,4 @@ export default <ITagImplOptions>{
|
|||||||
render: function () {
|
render: function () {
|
||||||
return this.tokens.map((token: Token) => token.raw).join('')
|
return this.tokens.map((token: Token) => token.raw).join('')
|
||||||
}
|
}
|
||||||
}
|
} as ITagImplOptions
|
||||||
|
|||||||
+11
-11
@@ -6,25 +6,25 @@ import { NormalizedFullOptions, applyDefault } from '../liquid-options'
|
|||||||
import { Scope } from './scope'
|
import { Scope } from './scope'
|
||||||
|
|
||||||
export default class Context {
|
export default class Context {
|
||||||
opts: NormalizedFullOptions
|
private scopes: Scope[] = [{}]
|
||||||
environments: Scope
|
|
||||||
private scopes: Array<Scope> = [{}]
|
|
||||||
private registers = {}
|
private registers = {}
|
||||||
constructor (ctx: object = {}, opts?: NormalizedFullOptions) {
|
public environments: Scope
|
||||||
|
public opts: NormalizedFullOptions
|
||||||
|
public constructor (ctx: object = {}, opts?: NormalizedFullOptions) {
|
||||||
this.opts = applyDefault(opts)
|
this.opts = applyDefault(opts)
|
||||||
this.environments = ctx
|
this.environments = ctx
|
||||||
}
|
}
|
||||||
getRegister (key: string, defaultValue = {}) {
|
public getRegister (key: string, defaultValue = {}) {
|
||||||
return (this.registers[key] = this.registers[key] || defaultValue)
|
return (this.registers[key] = this.registers[key] || defaultValue)
|
||||||
}
|
}
|
||||||
setRegister (key: string, value: any) {
|
public setRegister (key: string, value: any) {
|
||||||
return (this.registers[key] = value)
|
return (this.registers[key] = value)
|
||||||
}
|
}
|
||||||
getAll () {
|
public getAll () {
|
||||||
return [this.environments, ...this.scopes]
|
return [this.environments, ...this.scopes]
|
||||||
.reduce((ctx, val) => __assign(ctx, val), {})
|
.reduce((ctx, val) => __assign(ctx, val), {})
|
||||||
}
|
}
|
||||||
async get (path: string) {
|
public async get (path: string) {
|
||||||
const paths = await this.parseProp(path)
|
const paths = await this.parseProp(path)
|
||||||
let ctx = this.findScope(paths[0]) || this.environments
|
let ctx = this.findScope(paths[0]) || this.environments
|
||||||
for (const path of paths) {
|
for (const path of paths) {
|
||||||
@@ -35,13 +35,13 @@ export default class Context {
|
|||||||
}
|
}
|
||||||
return ctx
|
return ctx
|
||||||
}
|
}
|
||||||
push (ctx: object) {
|
public push (ctx: object) {
|
||||||
return this.scopes.push(ctx)
|
return this.scopes.push(ctx)
|
||||||
}
|
}
|
||||||
pop () {
|
public pop () {
|
||||||
return this.scopes.pop()
|
return this.scopes.pop()
|
||||||
}
|
}
|
||||||
front () {
|
public front () {
|
||||||
return this.scopes[0]
|
return this.scopes[0]
|
||||||
}
|
}
|
||||||
private findScope (key: string) {
|
private findScope (key: string) {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { Drop } from '../drop/drop'
|
import { Drop } from '../drop/drop'
|
||||||
|
|
||||||
type PlainObject = {
|
interface PlainObject {
|
||||||
[key: string]: any
|
[key: string]: any;
|
||||||
toLiquid?: () => any
|
toLiquid?: () => any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Scope = PlainObject | Drop
|
export type Scope = PlainObject | Drop
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { isNil, isString, toValue } from '../util/underscore'
|
|||||||
import { EmptyDrop } from '../drop/empty-drop'
|
import { EmptyDrop } from '../drop/empty-drop'
|
||||||
|
|
||||||
export class BlankDrop extends EmptyDrop {
|
export class BlankDrop extends EmptyDrop {
|
||||||
equals (value: any) {
|
public equals (value: any) {
|
||||||
if (value === false) return true
|
if (value === false) return true
|
||||||
if (isNil(toValue(value))) return true
|
if (isNil(toValue(value))) return true
|
||||||
if (isString(value)) return /^\s*$/.test(value)
|
if (isString(value)) return /^\s*$/.test(value)
|
||||||
|
|||||||
+2
-2
@@ -1,9 +1,9 @@
|
|||||||
export abstract class Drop {
|
export abstract class Drop {
|
||||||
valueOf (): any {
|
public valueOf (): any {
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
liquidMethodMissing (key: string): Promise<string | undefined> | string | undefined {
|
public liquidMethodMissing (key: string): Promise<string | undefined> | string | undefined {
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,24 +3,24 @@ import { IComparable } from './icomparable'
|
|||||||
import { isObject, isString, isArray } from '../util/underscore'
|
import { isObject, isString, isArray } from '../util/underscore'
|
||||||
|
|
||||||
export class EmptyDrop extends Drop implements IComparable {
|
export class EmptyDrop extends Drop implements IComparable {
|
||||||
equals (value: any) {
|
public equals (value: any) {
|
||||||
if (isString(value) || isArray(value)) return value.length === 0
|
if (isString(value) || isArray(value)) return value.length === 0
|
||||||
if (isObject(value)) return Object.keys(value).length === 0
|
if (isObject(value)) return Object.keys(value).length === 0
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
gt () {
|
public gt () {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
geq () {
|
public geq () {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
lt () {
|
public lt () {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
leq () {
|
public leq () {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
valueOf () {
|
public valueOf () {
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-10
@@ -2,33 +2,33 @@ import { Drop } from './drop'
|
|||||||
|
|
||||||
export class ForloopDrop extends Drop {
|
export class ForloopDrop extends Drop {
|
||||||
protected i: number = 0
|
protected i: number = 0
|
||||||
length: number
|
public length: number
|
||||||
constructor (length: number) {
|
public constructor (length: number) {
|
||||||
super()
|
super()
|
||||||
this.length = length
|
this.length = length
|
||||||
}
|
}
|
||||||
next () {
|
public next () {
|
||||||
this.i++
|
this.i++
|
||||||
}
|
}
|
||||||
index0 () {
|
public index0 () {
|
||||||
return this.i
|
return this.i
|
||||||
}
|
}
|
||||||
index () {
|
public index () {
|
||||||
return this.i + 1
|
return this.i + 1
|
||||||
}
|
}
|
||||||
first () {
|
public first () {
|
||||||
return this.i === 0
|
return this.i === 0
|
||||||
}
|
}
|
||||||
last () {
|
public last () {
|
||||||
return this.i === this.length - 1
|
return this.i === this.length - 1
|
||||||
}
|
}
|
||||||
rindex () {
|
public rindex () {
|
||||||
return this.length - this.i
|
return this.length - this.i
|
||||||
}
|
}
|
||||||
rindex0 () {
|
public rindex0 () {
|
||||||
return this.length - this.i - 1
|
return this.length - this.i - 1
|
||||||
}
|
}
|
||||||
valueOf () {
|
public valueOf () {
|
||||||
return JSON.stringify(this)
|
return JSON.stringify(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { isFunction } from '../util/underscore'
|
import { isFunction } from '../util/underscore'
|
||||||
|
|
||||||
export interface IComparable {
|
export interface IComparable {
|
||||||
equals: (rhs: any) => boolean
|
equals: (rhs: any) => boolean;
|
||||||
gt: (rhs: any) => boolean
|
gt: (rhs: any) => boolean;
|
||||||
geq: (rhs: any) => boolean
|
geq: (rhs: any) => boolean;
|
||||||
lt: (rhs: any) => boolean
|
lt: (rhs: any) => boolean;
|
||||||
leq: (rhs: any) => boolean
|
leq: (rhs: any) => boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isComparable (arg: any): arg is IComparable {
|
export function isComparable (arg: any): arg is IComparable {
|
||||||
|
|||||||
@@ -4,22 +4,22 @@ import { isNil, toValue } from '../util/underscore'
|
|||||||
import { BlankDrop } from '../drop/blank-drop'
|
import { BlankDrop } from '../drop/blank-drop'
|
||||||
|
|
||||||
export class NullDrop extends Drop implements IComparable {
|
export class NullDrop extends Drop implements IComparable {
|
||||||
equals (value: any) {
|
public equals (value: any) {
|
||||||
return isNil(toValue(value)) || value instanceof BlankDrop
|
return isNil(toValue(value)) || value instanceof BlankDrop
|
||||||
}
|
}
|
||||||
gt () {
|
public gt () {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
geq () {
|
public geq () {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
lt () {
|
public lt () {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
leq () {
|
public leq () {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
valueOf () {
|
public valueOf () {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,24 +2,24 @@ import { ForloopDrop } from './forloop-drop'
|
|||||||
|
|
||||||
export class TablerowloopDrop extends ForloopDrop {
|
export class TablerowloopDrop extends ForloopDrop {
|
||||||
private cols: number
|
private cols: number
|
||||||
constructor (length: number, cols: number) {
|
public constructor (length: number, cols: number) {
|
||||||
super(length)
|
super(length)
|
||||||
this.length = length
|
this.length = length
|
||||||
this.cols = cols
|
this.cols = cols
|
||||||
}
|
}
|
||||||
row () {
|
public row () {
|
||||||
return Math.floor(this.i / this.cols) + 1
|
return Math.floor(this.i / this.cols) + 1
|
||||||
}
|
}
|
||||||
col0 () {
|
public col0 () {
|
||||||
return (this.i % this.cols)
|
return (this.i % this.cols)
|
||||||
}
|
}
|
||||||
col () {
|
public col () {
|
||||||
return this.col0() + 1
|
return this.col0() + 1
|
||||||
}
|
}
|
||||||
col_first () { // eslint-disable-line
|
public col_first () { // eslint-disable-line
|
||||||
return this.col0() === 0
|
return this.col0() === 0
|
||||||
}
|
}
|
||||||
col_last () { // eslint-disable-line
|
public col_last () { // eslint-disable-line
|
||||||
return this.col() === this.cols
|
return this.col() === this.cols
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -1,5 +1,5 @@
|
|||||||
export default interface IFS {
|
export default interface IFS {
|
||||||
exists: (filepath: string) => Promise<boolean>
|
exists: (filepath: string) => Promise<boolean>;
|
||||||
readFile: (filepath:string) => Promise<string>
|
readFile: (filepath: string) => Promise<string>;
|
||||||
resolve: (root: string, file: string, ext: string) => string
|
resolve: (root: string, file: string, ext: string) => string;
|
||||||
}
|
}
|
||||||
|
|||||||
+32
-32
@@ -3,57 +3,57 @@ import IFS from './fs/ifs'
|
|||||||
|
|
||||||
export interface LiquidOptions {
|
export interface LiquidOptions {
|
||||||
/** `root` is a directory or an array of directories to resolve layouts and includes, as well as the filename passed in when calling `.renderFile()`. If an array, the files are looked up in the order they occur in the array. Defaults to `["."]` */
|
/** `root` is a directory or an array of directories to resolve layouts and includes, as well as the filename passed in when calling `.renderFile()`. If an array, the files are looked up in the order they occur in the array. Defaults to `["."]` */
|
||||||
root?: string | string[]
|
root?: string | string[];
|
||||||
/** `extname` is used to lookup the template file when filepath doesn't include an extension name. Eg: setting to `".html"` will allow including file by basename. Defaults to `""`. */
|
/** `extname` is used to lookup the template file when filepath doesn't include an extension name. Eg: setting to `".html"` will allow including file by basename. Defaults to `""`. */
|
||||||
extname?: string
|
extname?: string;
|
||||||
/** `cache` indicates whether or not to cache resolved templates. Defaults to `false`. */
|
/** `cache` indicates whether or not to cache resolved templates. Defaults to `false`. */
|
||||||
cache?: boolean
|
cache?: boolean;
|
||||||
/** `dynamicPartials`: if set, treat `<filepath>` parameter in `{%include filepath %}`, `{%layout filepath%}` as a variable, otherwise as a literal value. Defaults to `true`. */
|
/** `dynamicPartials`: if set, treat `<filepath>` parameter in `{%include filepath %}`, `{%layout filepath%}` as a variable, otherwise as a literal value. Defaults to `true`. */
|
||||||
dynamicPartials?: boolean
|
dynamicPartials?: boolean;
|
||||||
/** `strictFilters` is used to enable strict filter existence. If set to `false`, undefined filters will be rendered as empty string. Otherwise, undefined filters will cause an exception. Defaults to `false`. */
|
/** `strictFilters` is used to enable strict filter existence. If set to `false`, undefined filters will be rendered as empty string. Otherwise, undefined filters will cause an exception. Defaults to `false`. */
|
||||||
strictFilters?: boolean
|
strictFilters?: boolean;
|
||||||
/** `strictVariables` is used to enable strict variable derivation. If set to `false`, undefined variables will be rendered as empty string. Otherwise, undefined variables will cause an exception. Defaults to `false`. */
|
/** `strictVariables` is used to enable strict variable derivation. If set to `false`, undefined variables will be rendered as empty string. Otherwise, undefined variables will cause an exception. Defaults to `false`. */
|
||||||
strictVariables?: boolean
|
strictVariables?: boolean;
|
||||||
/** `trimTagRight` is used to strip blank characters (including ` `, `\t`, and `\r`) from the right of tags (`{% %}`) until `\n` (inclusive). Defaults to `false`. */
|
/** `trimTagRight` is used to strip blank characters (including ` `, `\t`, and `\r`) from the right of tags (`{% %}`) until `\n` (inclusive). Defaults to `false`. */
|
||||||
trimTagRight?: boolean
|
trimTagRight?: boolean;
|
||||||
/** `trimTagLeft` is similar to `trimTagRight`, whereas the `\n` is exclusive. Defaults to `false`. See Whitespace Control for details. */
|
/** `trimTagLeft` is similar to `trimTagRight`, whereas the `\n` is exclusive. Defaults to `false`. See Whitespace Control for details. */
|
||||||
trimTagLeft?: boolean
|
trimTagLeft?: boolean;
|
||||||
/** ``trimOutputRight` is used to strip blank characters (including ` `, `\t`, and `\r`) from the right of values (`{{ }}`) until `\n` (inclusive). Defaults to `false`. */
|
/** ``trimOutputRight` is used to strip blank characters (including ` `, `\t`, and `\r`) from the right of values (`{{ }}`) until `\n` (inclusive). Defaults to `false`. */
|
||||||
trimOutputRight?: boolean
|
trimOutputRight?: boolean;
|
||||||
/** `trimOutputLeft` is similar to `trimOutputRight`, whereas the `\n` is exclusive. Defaults to `false`. See Whitespace Control for details. */
|
/** `trimOutputLeft` is similar to `trimOutputRight`, whereas the `\n` is exclusive. Defaults to `false`. See Whitespace Control for details. */
|
||||||
trimOutputLeft?: boolean
|
trimOutputLeft?: boolean;
|
||||||
/** `tagDelimiterLeft` and `tagDelimiterRight` are used to override the delimiter for liquid tags **/
|
/** `tagDelimiterLeft` and `tagDelimiterRight` are used to override the delimiter for liquid tags **/
|
||||||
tagDelimiterLeft?: string,
|
tagDelimiterLeft?: string;
|
||||||
tagDelimiterRight?: string,
|
tagDelimiterRight?: string;
|
||||||
/** `outputDelimiterLeft` and `outputDelimiterRight` are used to override the delimiter for liquid outputs **/
|
/** `outputDelimiterLeft` and `outputDelimiterRight` are used to override the delimiter for liquid outputs **/
|
||||||
outputDelimiterLeft?: string,
|
outputDelimiterLeft?: string;
|
||||||
outputDelimiterRight?: string,
|
outputDelimiterRight?: string;
|
||||||
/** `greedy` is used to specify whether `trim*Left`/`trim*Right` is greedy. When set to `true`, all consecutive blank characters including `\n` will be trimed regardless of line breaks. Defaults to `true`. */
|
/** `greedy` is used to specify whether `trim*Left`/`trim*Right` is greedy. When set to `true`, all consecutive blank characters including `\n` will be trimed regardless of line breaks. Defaults to `true`. */
|
||||||
greedy?: boolean,
|
greedy?: boolean;
|
||||||
/** `fs` is used to override the default file-system module with a custom implementation */
|
/** `fs` is used to override the default file-system module with a custom implementation */
|
||||||
fs?: IFS
|
fs?: IFS;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface NormalizedOptions extends LiquidOptions {
|
interface NormalizedOptions extends LiquidOptions {
|
||||||
root?: string[]
|
root?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface NormalizedFullOptions extends NormalizedOptions {
|
export interface NormalizedFullOptions extends NormalizedOptions {
|
||||||
root: string[]
|
root: string[];
|
||||||
extname: string
|
extname: string;
|
||||||
cache: boolean
|
cache: boolean;
|
||||||
dynamicPartials: boolean
|
dynamicPartials: boolean;
|
||||||
strictFilters: boolean
|
strictFilters: boolean;
|
||||||
strictVariables: boolean
|
strictVariables: boolean;
|
||||||
trimTagRight: boolean
|
trimTagRight: boolean;
|
||||||
trimTagLeft: boolean
|
trimTagLeft: boolean;
|
||||||
trimOutputRight: boolean
|
trimOutputRight: boolean;
|
||||||
trimOutputLeft: boolean
|
trimOutputLeft: boolean;
|
||||||
tagDelimiterLeft: string,
|
tagDelimiterLeft: string;
|
||||||
tagDelimiterRight: string,
|
tagDelimiterRight: string;
|
||||||
outputDelimiterLeft: string,
|
outputDelimiterLeft: string;
|
||||||
outputDelimiterRight: string,
|
outputDelimiterRight: string;
|
||||||
greedy: boolean
|
greedy: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultOptions: NormalizedFullOptions = {
|
const defaultOptions: NormalizedFullOptions = {
|
||||||
|
|||||||
+17
-17
@@ -25,7 +25,7 @@ export default class Liquid {
|
|||||||
private tokenizer: Tokenizer
|
private tokenizer: Tokenizer
|
||||||
private fs: IFS
|
private fs: IFS
|
||||||
|
|
||||||
constructor (opts: LiquidOptions = {}) {
|
public constructor (opts: LiquidOptions = {}) {
|
||||||
this.options = applyDefault(normalize(opts))
|
this.options = applyDefault(normalize(opts))
|
||||||
this.parser = new Parser(this)
|
this.parser = new Parser(this)
|
||||||
this.renderer = new Render()
|
this.renderer = new Render()
|
||||||
@@ -35,20 +35,20 @@ export default class Liquid {
|
|||||||
_.forOwn(builtinTags, (conf, name) => this.registerTag(name, conf))
|
_.forOwn(builtinTags, (conf, name) => this.registerTag(name, conf))
|
||||||
_.forOwn(builtinFilters, (handler, name) => this.registerFilter(name, handler))
|
_.forOwn(builtinFilters, (handler, name) => this.registerFilter(name, handler))
|
||||||
}
|
}
|
||||||
parse (html: string, filepath?: string) {
|
public parse (html: string, filepath?: string) {
|
||||||
const tokens = this.tokenizer.tokenize(html, filepath)
|
const tokens = this.tokenizer.tokenize(html, filepath)
|
||||||
return this.parser.parse(tokens)
|
return this.parser.parse(tokens)
|
||||||
}
|
}
|
||||||
render (tpl: Array<ITemplate>, ctx?: object, opts?: LiquidOptions) {
|
public render (tpl: ITemplate[], ctx?: object, opts?: LiquidOptions) {
|
||||||
const options = { ...this.options, ...normalize(opts) }
|
const options = { ...this.options, ...normalize(opts) }
|
||||||
const scope = new Context(ctx, options)
|
const scope = new Context(ctx, options)
|
||||||
return this.renderer.renderTemplates(tpl, scope)
|
return this.renderer.renderTemplates(tpl, scope)
|
||||||
}
|
}
|
||||||
async parseAndRender (html: string, ctx?: object, opts?: LiquidOptions) {
|
public async parseAndRender (html: string, ctx?: object, opts?: LiquidOptions) {
|
||||||
const tpl = await this.parse(html)
|
const tpl = await this.parse(html)
|
||||||
return this.render(tpl, ctx, opts)
|
return this.render(tpl, ctx, opts)
|
||||||
}
|
}
|
||||||
async getTemplate (file: string, opts?: LiquidOptions) {
|
public async getTemplate (file: string, opts?: LiquidOptions) {
|
||||||
const options = normalize(opts)
|
const options = normalize(opts)
|
||||||
const roots = options.root ? [...options.root, ...this.options.root] : this.options.root
|
const roots = options.root ? [...options.root, ...this.options.root] : this.options.root
|
||||||
const paths = roots.map(root => this.fs.resolve(root, file, this.options.extname))
|
const paths = roots.map(root => this.fs.resolve(root, file, this.options.extname))
|
||||||
@@ -68,34 +68,34 @@ export default class Liquid {
|
|||||||
err.code = 'ENOENT'
|
err.code = 'ENOENT'
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
async renderFile (file: string, ctx?: object, opts?: LiquidOptions) {
|
public async renderFile (file: string, ctx?: object, opts?: LiquidOptions) {
|
||||||
const options = normalize(opts)
|
const options = normalize(opts)
|
||||||
const templates = await this.getTemplate(file, options)
|
const templates = await this.getTemplate(file, options)
|
||||||
return this.render(templates, ctx, opts)
|
return this.render(templates, ctx, opts)
|
||||||
}
|
}
|
||||||
evalValue (str: string, ctx: Context) {
|
public evalValue (str: string, ctx: Context) {
|
||||||
return new Value(str, this.options.strictFilters).value(ctx)
|
return new Value(str, this.options.strictFilters).value(ctx)
|
||||||
}
|
}
|
||||||
registerFilter (name: string, filter: FilterImplOptions) {
|
public registerFilter (name: string, filter: FilterImplOptions) {
|
||||||
return Filter.register(name, filter)
|
return Filter.register(name, filter)
|
||||||
}
|
}
|
||||||
registerTag (name: string, tag: ITagImplOptions) {
|
public registerTag (name: string, tag: ITagImplOptions) {
|
||||||
return Tag.register(name, tag)
|
return Tag.register(name, tag)
|
||||||
}
|
}
|
||||||
plugin (plugin: (this: Liquid, L: typeof Liquid) => void) {
|
public plugin (plugin: (this: Liquid, L: typeof Liquid) => void) {
|
||||||
return plugin.call(this, Liquid)
|
return plugin.call(this, Liquid)
|
||||||
}
|
}
|
||||||
express () {
|
public express () {
|
||||||
const self = this
|
const self = this
|
||||||
return function (this: any, filePath: string, ctx: object, cb: (err: Error | null, html?: string) => void) {
|
return function (this: any, filePath: string, ctx: object, cb: (err: Error | null, html?: string) => void) {
|
||||||
const opts = { root: this.root }
|
const opts = { root: this.root }
|
||||||
self.renderFile(filePath, ctx, opts).then(html => cb(null, html), cb)
|
self.renderFile(filePath, ctx, opts).then(html => cb(null, html), cb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static default = Liquid
|
public static default = Liquid
|
||||||
static isTruthy = isTruthy
|
public static isTruthy = isTruthy
|
||||||
static isFalsy = isFalsy
|
public static isFalsy = isFalsy
|
||||||
static evalExp = evalExp
|
public static evalExp = evalExp
|
||||||
static evalValue = evalValue
|
public static evalValue = evalValue
|
||||||
static Types = Types
|
public static Types = Types
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import Token from './token'
|
|||||||
import { last } from '../util/underscore'
|
import { last } from '../util/underscore'
|
||||||
|
|
||||||
export default class DelimitedToken extends Token {
|
export default class DelimitedToken extends Token {
|
||||||
constructor (
|
public constructor (
|
||||||
raw: string,
|
raw: string,
|
||||||
value: string,
|
value: string,
|
||||||
input: string,
|
input: string,
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import Token from './token'
|
import Token from './token'
|
||||||
|
|
||||||
export default class HTMLToken extends Token {
|
export default class HTMLToken extends Token {
|
||||||
constructor (str: string, input: string, line: number, col: number, file?: string) {
|
public constructor (str: string, input: string, line: number, col: number, file?: string) {
|
||||||
super(str, input, line, col, file)
|
super(str, input, line, col, file)
|
||||||
this.type = 'html'
|
this.type = 'html'
|
||||||
this.value = str
|
this.value = str
|
||||||
}
|
}
|
||||||
static is (token: Token): token is HTMLToken {
|
public static is (token: Token): token is HTMLToken {
|
||||||
return token.type === 'html'
|
return token.type === 'html'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import Token from './token'
|
|||||||
import { NormalizedFullOptions } from '../liquid-options'
|
import { NormalizedFullOptions } from '../liquid-options'
|
||||||
|
|
||||||
export default class OutputToken extends DelimitedToken {
|
export default class OutputToken extends DelimitedToken {
|
||||||
constructor (
|
public constructor (
|
||||||
raw: string,
|
raw: string,
|
||||||
value: string,
|
value: string,
|
||||||
input: string,
|
input: string,
|
||||||
@@ -15,7 +15,7 @@ export default class OutputToken extends DelimitedToken {
|
|||||||
super(raw, value, input, line, pos, options.trimOutputLeft, options.trimOutputRight, file)
|
super(raw, value, input, line, pos, options.trimOutputLeft, options.trimOutputRight, file)
|
||||||
this.type = 'output'
|
this.type = 'output'
|
||||||
}
|
}
|
||||||
static is (token: Token): token is OutputToken {
|
public static is (token: Token): token is OutputToken {
|
||||||
return token.type === 'output'
|
return token.type === 'output'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,19 +2,19 @@ import Token from '../parser/token'
|
|||||||
import ITemplate from '../template/itemplate'
|
import ITemplate from '../template/itemplate'
|
||||||
import TagToken from './tag-token'
|
import TagToken from './tag-token'
|
||||||
|
|
||||||
type ParseToken = ((token: Token, remainTokens: Array<Token>) => ITemplate)
|
type ParseToken = ((token: Token, remainTokens: Token[]) => ITemplate)
|
||||||
|
|
||||||
export default class ParseStream {
|
export default class ParseStream {
|
||||||
private tokens: Array<Token>
|
private tokens: Token[]
|
||||||
private handlers: {[key: string]: (arg: any) => void} = {}
|
private handlers: {[key: string]: (arg: any) => void} = {}
|
||||||
private stopRequested: boolean = false
|
private stopRequested: boolean = false
|
||||||
private parseToken: ParseToken
|
private parseToken: ParseToken
|
||||||
|
|
||||||
constructor (tokens: Array<Token>, parseToken: ParseToken) {
|
public constructor (tokens: Token[], parseToken: ParseToken) {
|
||||||
this.tokens = tokens
|
this.tokens = tokens
|
||||||
this.parseToken = parseToken
|
this.parseToken = parseToken
|
||||||
}
|
}
|
||||||
on<T extends ITemplate | Token | undefined> (name: string, cb: (arg: T) => void): ParseStream {
|
public on<T extends ITemplate | Token | undefined> (name: string, cb: (arg: T) => void): ParseStream {
|
||||||
this.handlers[name] = cb
|
this.handlers[name] = cb
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
@@ -22,7 +22,7 @@ export default class ParseStream {
|
|||||||
const h = this.handlers[event]
|
const h = this.handlers[event]
|
||||||
return h ? (h(arg), true) : false
|
return h ? (h(arg), true) : false
|
||||||
}
|
}
|
||||||
start () {
|
public start () {
|
||||||
this.trigger('start')
|
this.trigger('start')
|
||||||
let token: Token | undefined
|
let token: Token | undefined
|
||||||
while (!this.stopRequested && (token = this.tokens.shift())) {
|
while (!this.stopRequested && (token = this.tokens.shift())) {
|
||||||
@@ -36,7 +36,7 @@ export default class ParseStream {
|
|||||||
if (!this.stopRequested) this.trigger('end')
|
if (!this.stopRequested) this.trigger('end')
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
stop () {
|
public stop () {
|
||||||
this.stopRequested = true
|
this.stopRequested = true
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,12 +10,12 @@ import HTML from '../template/html'
|
|||||||
import ITemplate from '../template/itemplate'
|
import ITemplate from '../template/itemplate'
|
||||||
|
|
||||||
export default class Parser {
|
export default class Parser {
|
||||||
liquid: Liquid
|
private liquid: Liquid
|
||||||
|
|
||||||
constructor (liquid: Liquid) {
|
public constructor (liquid: Liquid) {
|
||||||
this.liquid = liquid
|
this.liquid = liquid
|
||||||
}
|
}
|
||||||
parse (tokens: Array<Token>) {
|
public parse (tokens: Token[]) {
|
||||||
let token
|
let token
|
||||||
const templates: ITemplate[] = []
|
const templates: ITemplate[] = []
|
||||||
while ((token = tokens.shift())) {
|
while ((token = tokens.shift())) {
|
||||||
@@ -23,7 +23,7 @@ export default class Parser {
|
|||||||
}
|
}
|
||||||
return templates
|
return templates
|
||||||
}
|
}
|
||||||
parseToken (token: Token, remainTokens: Array<Token>) {
|
public parseToken (token: Token, remainTokens: Token[]) {
|
||||||
try {
|
try {
|
||||||
if (TagToken.is(token)) {
|
if (TagToken.is(token)) {
|
||||||
return new Tag(token, remainTokens, this.liquid)
|
return new Tag(token, remainTokens, this.liquid)
|
||||||
@@ -36,7 +36,7 @@ export default class Parser {
|
|||||||
throw new ParseError(e, token)
|
throw new ParseError(e, token)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
parseStream (tokens: Array<Token>) {
|
public parseStream (tokens: Token[]) {
|
||||||
return new ParseStream(tokens, (token, tokens) => this.parseToken(token, tokens))
|
return new ParseStream(tokens, (token, tokens) => this.parseToken(token, tokens))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ import * as lexical from './lexical'
|
|||||||
import { NormalizedFullOptions } from '../liquid-options'
|
import { NormalizedFullOptions } from '../liquid-options'
|
||||||
|
|
||||||
export default class TagToken extends DelimitedToken {
|
export default class TagToken extends DelimitedToken {
|
||||||
name: string
|
public name: string
|
||||||
args: string
|
public args: string
|
||||||
constructor (
|
public constructor (
|
||||||
raw: string,
|
raw: string,
|
||||||
value: string,
|
value: string,
|
||||||
input: string,
|
input: string,
|
||||||
@@ -25,7 +25,7 @@ export default class TagToken extends DelimitedToken {
|
|||||||
this.name = match[1]
|
this.name = match[1]
|
||||||
this.args = match[2]
|
this.args = match[2]
|
||||||
}
|
}
|
||||||
static is (token: Token): token is TagToken {
|
public static is (token: Token): token is TagToken {
|
||||||
return token.type === 'tag'
|
return token.type === 'tag'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-10
@@ -1,14 +1,14 @@
|
|||||||
export default class Token {
|
export default class Token {
|
||||||
trimLeft: boolean = false
|
public trimLeft: boolean = false
|
||||||
trimRight: boolean = false
|
public trimRight: boolean = false
|
||||||
type: string = 'notset'
|
public type: string = 'notset'
|
||||||
line: number
|
public line: number
|
||||||
col: number
|
public col: number
|
||||||
raw: string
|
public raw: string
|
||||||
input: string
|
public input: string
|
||||||
file?: string
|
public file?: string
|
||||||
value: string
|
public value: string
|
||||||
constructor (raw: string, input: string, line: number, col: number, file?: string) {
|
public constructor (raw: string, input: string, line: number, col: number, file?: string) {
|
||||||
this.col = col
|
this.col = col
|
||||||
this.line = line
|
this.line = line
|
||||||
this.raw = raw
|
this.raw = raw
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ enum ParseState { HTML, OUTPUT, TAG }
|
|||||||
|
|
||||||
export default class Tokenizer {
|
export default class Tokenizer {
|
||||||
private options: NormalizedFullOptions
|
private options: NormalizedFullOptions
|
||||||
constructor (options?: NormalizedFullOptions) {
|
public constructor (options?: NormalizedFullOptions) {
|
||||||
this.options = applyDefault(options)
|
this.options = applyDefault(options)
|
||||||
}
|
}
|
||||||
tokenize (input: string, file?: string) {
|
public tokenize (input: string, file?: string) {
|
||||||
const tokens: Token[] = []
|
const tokens: Token[] = []
|
||||||
const {
|
const {
|
||||||
tagDelimiterLeft,
|
tagDelimiterLeft,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import Context from '../context/context'
|
|||||||
import ITemplate from '../template/itemplate'
|
import ITemplate from '../template/itemplate'
|
||||||
|
|
||||||
export default class Render {
|
export default class Render {
|
||||||
async renderTemplates (templates: ITemplate[], ctx: Context) {
|
public async renderTemplates (templates: ITemplate[], ctx: Context) {
|
||||||
assert(ctx, 'unable to evalTemplates: context undefined')
|
assert(ctx, 'unable to evalTemplates: context undefined')
|
||||||
|
|
||||||
let html = ''
|
let html = ''
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import Context from '../../context/context'
|
import Context from '../../context/context'
|
||||||
|
|
||||||
export interface FilterImpl {
|
export interface FilterImpl {
|
||||||
context: Context
|
context: Context;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,15 +5,15 @@ import { FilterImplOptions } from './filter-impl-options'
|
|||||||
|
|
||||||
type KeyValuePair = [string?, string?]
|
type KeyValuePair = [string?, string?]
|
||||||
type FilterArg = string|KeyValuePair
|
type FilterArg = string|KeyValuePair
|
||||||
export type FilterArgs = Array<FilterArg>
|
export type FilterArgs = FilterArg[]
|
||||||
|
|
||||||
export class Filter {
|
export class Filter {
|
||||||
name: string
|
private name: string
|
||||||
impl: FilterImplOptions
|
private impl: FilterImplOptions
|
||||||
args: FilterArgs
|
private args: FilterArgs
|
||||||
private static impls: {[key: string]: FilterImplOptions} = {}
|
private static impls: {[key: string]: FilterImplOptions} = {}
|
||||||
|
|
||||||
constructor (name: string, args: FilterArgs, strictFilters: boolean) {
|
public constructor (name: string, args: FilterArgs, strictFilters: boolean) {
|
||||||
const impl = Filter.impls[name]
|
const impl = Filter.impls[name]
|
||||||
if (!impl && strictFilters) throw new TypeError(`undefined filter: ${name}`)
|
if (!impl && strictFilters) throw new TypeError(`undefined filter: ${name}`)
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ export class Filter {
|
|||||||
this.impl = impl || (x => x)
|
this.impl = impl || (x => x)
|
||||||
this.args = args
|
this.args = args
|
||||||
}
|
}
|
||||||
async render (value: any, context: Context) {
|
public async render (value: any, context: Context) {
|
||||||
const argv: any[] = []
|
const argv: any[] = []
|
||||||
for (const arg of this.args) {
|
for (const arg of this.args) {
|
||||||
if (isKeyValuePair(arg)) argv.push([arg[0], await parseValue(arg[1], context)])
|
if (isKeyValuePair(arg)) argv.push([arg[0], await parseValue(arg[1], context)])
|
||||||
@@ -29,10 +29,10 @@ export class Filter {
|
|||||||
}
|
}
|
||||||
return this.impl.apply({ context }, [value, ...argv])
|
return this.impl.apply({ context }, [value, ...argv])
|
||||||
}
|
}
|
||||||
static register (name: string, filter: FilterImplOptions) {
|
public static register (name: string, filter: FilterImplOptions) {
|
||||||
Filter.impls[name] = filter
|
Filter.impls[name] = filter
|
||||||
}
|
}
|
||||||
static clear () {
|
public static clear () {
|
||||||
Filter.impls = {}
|
Filter.impls = {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ import ITemplate from '../template/itemplate'
|
|||||||
import HTMLToken from '../parser/html-token'
|
import HTMLToken from '../parser/html-token'
|
||||||
|
|
||||||
export default class extends Template<HTMLToken> implements ITemplate {
|
export default class extends Template<HTMLToken> implements ITemplate {
|
||||||
str: string
|
private str: string
|
||||||
constructor (token: HTMLToken) {
|
public constructor (token: HTMLToken) {
|
||||||
super(token)
|
super(token)
|
||||||
this.str = token.value
|
this.str = token.value
|
||||||
}
|
}
|
||||||
async render (): Promise<string> {
|
public async render (): Promise<string> {
|
||||||
return this.str
|
return this.str
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,12 +6,12 @@ import Context from '../context/context'
|
|||||||
import OutputToken from '../parser/output-token'
|
import OutputToken from '../parser/output-token'
|
||||||
|
|
||||||
export default class Output extends Template<OutputToken> implements ITemplate {
|
export default class Output extends Template<OutputToken> implements ITemplate {
|
||||||
value: Value
|
private value: Value
|
||||||
constructor (token: OutputToken, strictFilters: boolean) {
|
public constructor (token: OutputToken, strictFilters: boolean) {
|
||||||
super(token)
|
super(token)
|
||||||
this.value = new Value(token.value, strictFilters)
|
this.value = new Value(token.value, strictFilters)
|
||||||
}
|
}
|
||||||
async render (ctx: Context): Promise<string> {
|
public async render (ctx: Context): Promise<string> {
|
||||||
const val = await this.value.value(ctx)
|
const val = await this.value.value(ctx)
|
||||||
return stringify(toValue(val))
|
return stringify(toValue(val))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import Context from '../../context/context'
|
|||||||
*/
|
*/
|
||||||
export default class Hash {
|
export default class Hash {
|
||||||
[key: string]: any
|
[key: string]: any
|
||||||
static async create (markup: string, ctx: Context) {
|
public static async create (markup: string, ctx: Context) {
|
||||||
const instance = new Hash()
|
const instance = new Hash()
|
||||||
let match
|
let match
|
||||||
hashCapture.lastIndex = 0
|
hashCapture.lastIndex = 0
|
||||||
|
|||||||
@@ -5,6 +5,6 @@ import Hash from '../../template/tag/hash'
|
|||||||
import ITagImpl from './itag-impl'
|
import ITagImpl from './itag-impl'
|
||||||
|
|
||||||
export default interface ITagImplOptions {
|
export default interface ITagImplOptions {
|
||||||
parse?: (this: ITagImpl, token: TagToken, remainingTokens: Array<Token>) => void
|
parse?: (this: ITagImpl, token: TagToken, remainingTokens: Token[]) => void;
|
||||||
render?: (this: ITagImpl, ctx: Context, hash: Hash) => any | Promise<any>
|
render?: (this: ITagImpl, ctx: Context, hash: Hash) => any | Promise<any>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,6 @@ import Liquid from '../../liquid'
|
|||||||
import ITagImplOptions from './itag-impl-options'
|
import ITagImplOptions from './itag-impl-options'
|
||||||
|
|
||||||
export default interface ITagImpl extends ITagImplOptions {
|
export default interface ITagImpl extends ITagImplOptions {
|
||||||
liquid: Liquid,
|
liquid: Liquid;
|
||||||
[key: string]: any
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,11 +11,11 @@ import TagToken from '../../parser/tag-token'
|
|||||||
import Token from '../../parser/token'
|
import Token from '../../parser/token'
|
||||||
|
|
||||||
export default class Tag extends Template<TagToken> implements ITemplate {
|
export default class Tag extends Template<TagToken> implements ITemplate {
|
||||||
name: string
|
public name: string
|
||||||
private impl: ITagImpl
|
private impl: ITagImpl
|
||||||
static impls: { [key: string]: ITagImplOptions } = {}
|
private static impls: { [key: string]: ITagImplOptions } = {}
|
||||||
|
|
||||||
constructor (token: TagToken, tokens: Token[], liquid: Liquid) {
|
public constructor (token: TagToken, tokens: Token[], liquid: Liquid) {
|
||||||
super(token)
|
super(token)
|
||||||
this.name = token.name
|
this.name = token.name
|
||||||
|
|
||||||
@@ -28,15 +28,15 @@ export default class Tag extends Template<TagToken> implements ITemplate {
|
|||||||
this.impl.parse(token, tokens)
|
this.impl.parse(token, tokens)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async render (ctx: Context) {
|
public async render (ctx: Context) {
|
||||||
const hash = await Hash.create(this.token.args, ctx)
|
const hash = await Hash.create(this.token.args, ctx)
|
||||||
const impl = this.impl
|
const impl = this.impl
|
||||||
return isFunction(impl.render) ? stringify(await impl.render(ctx, hash)) : ''
|
return isFunction(impl.render) ? stringify(await impl.render(ctx, hash)) : ''
|
||||||
}
|
}
|
||||||
static register (name: string, tag: ITagImplOptions) {
|
public static register (name: string, tag: ITagImplOptions) {
|
||||||
Tag.impls[name] = tag
|
Tag.impls[name] = tag
|
||||||
}
|
}
|
||||||
static clear () {
|
public static clear () {
|
||||||
Tag.impls = {}
|
Tag.impls = {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
export default abstract class Template<T> {
|
export default abstract class Template<T> {
|
||||||
token: T;
|
public token: T;
|
||||||
constructor (token: T) {
|
public constructor (token: T) {
|
||||||
this.token = token
|
this.token = token
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,12 +5,12 @@ import Context from '../context/context'
|
|||||||
export default class Value {
|
export default class Value {
|
||||||
private strictFilters: boolean
|
private strictFilters: boolean
|
||||||
private initial: string
|
private initial: string
|
||||||
private filters: Array<Filter> = []
|
private filters: Filter[] = []
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param str value string, like: "i have a dream | truncate: 3
|
* @param str value string, like: "i have a dream | truncate: 3
|
||||||
*/
|
*/
|
||||||
constructor (str: string, strictFilters: boolean) {
|
public constructor (str: string, strictFilters: boolean) {
|
||||||
const tokens = Value.tokenize(str)
|
const tokens = Value.tokenize(str)
|
||||||
this.strictFilters = strictFilters
|
this.strictFilters = strictFilters
|
||||||
this.initial = tokens[0]
|
this.initial = tokens[0]
|
||||||
@@ -35,7 +35,7 @@ export default class Value {
|
|||||||
for (let i = begin + 1; i < end + 1; i++) {
|
for (let i = begin + 1; i < end + 1; i++) {
|
||||||
if (i === end || tokens[i] === ',') {
|
if (i === end || tokens[i] === ',') {
|
||||||
if (argName || argValue) {
|
if (argName || argValue) {
|
||||||
args.push(argName ? [argName, argValue] : <string>argValue)
|
args.push(argName ? [argName, argValue] : argValue as string)
|
||||||
}
|
}
|
||||||
argValue = argName = undefined
|
argValue = argName = undefined
|
||||||
} else if (tokens[i] === ':') {
|
} else if (tokens[i] === ':') {
|
||||||
@@ -47,14 +47,14 @@ export default class Value {
|
|||||||
}
|
}
|
||||||
this.filters.push(new Filter(name, args, this.strictFilters))
|
this.filters.push(new Filter(name, args, this.strictFilters))
|
||||||
}
|
}
|
||||||
async value (ctx: Context) {
|
public async value (ctx: Context) {
|
||||||
let val = await parseExp(this.initial, ctx)
|
let val = await parseExp(this.initial, ctx)
|
||||||
for (const filter of this.filters) {
|
for (const filter of this.filters) {
|
||||||
val = await filter.render(val, ctx)
|
val = await filter.render(val, ctx)
|
||||||
}
|
}
|
||||||
return val
|
return val
|
||||||
}
|
}
|
||||||
static tokenize (str: string): Array<'|' | ',' | ':' | string> {
|
public static tokenize (str: string): ('|' | ',' | ':' | string)[] {
|
||||||
const tokens = []
|
const tokens = []
|
||||||
let i = 0
|
let i = 0
|
||||||
while (i < str.length) {
|
while (i < str.length) {
|
||||||
|
|||||||
+7
-7
@@ -5,7 +5,7 @@ import ITemplate from '../template/itemplate'
|
|||||||
abstract class LiquidError extends Error {
|
abstract class LiquidError extends Error {
|
||||||
private token: Token
|
private token: Token
|
||||||
private originalError: Error
|
private originalError: Error
|
||||||
constructor (err: Error, token: Token) {
|
public constructor (err: Error, token: Token) {
|
||||||
super(err.message)
|
super(err.message)
|
||||||
this.originalError = err
|
this.originalError = err
|
||||||
this.token = token
|
this.token = token
|
||||||
@@ -20,7 +20,7 @@ abstract class LiquidError extends Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class TokenizationError extends LiquidError {
|
export class TokenizationError extends LiquidError {
|
||||||
constructor (message: string, token: Token) {
|
public constructor (message: string, token: Token) {
|
||||||
super(new Error(message), token)
|
super(new Error(message), token)
|
||||||
this.name = 'TokenizationError'
|
this.name = 'TokenizationError'
|
||||||
super.update()
|
super.update()
|
||||||
@@ -28,7 +28,7 @@ export class TokenizationError extends LiquidError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class ParseError extends LiquidError {
|
export class ParseError extends LiquidError {
|
||||||
constructor (err: Error, token: Token) {
|
public constructor (err: Error, token: Token) {
|
||||||
super(err, token)
|
super(err, token)
|
||||||
this.name = 'ParseError'
|
this.name = 'ParseError'
|
||||||
this.message = err.message
|
this.message = err.message
|
||||||
@@ -37,7 +37,7 @@ export class ParseError extends LiquidError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class RenderError extends LiquidError {
|
export class RenderError extends LiquidError {
|
||||||
constructor (err: Error, tpl: ITemplate) {
|
public constructor (err: Error, tpl: ITemplate) {
|
||||||
super(err, tpl.token)
|
super(err, tpl.token)
|
||||||
this.name = 'RenderError'
|
this.name = 'RenderError'
|
||||||
this.message = err.message
|
this.message = err.message
|
||||||
@@ -46,8 +46,8 @@ export class RenderError extends LiquidError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class RenderBreakError extends Error {
|
export class RenderBreakError extends Error {
|
||||||
resolvedHTML: string = ''
|
public resolvedHTML: string = ''
|
||||||
constructor (message: string) {
|
public constructor (message: string) {
|
||||||
super(message)
|
super(message)
|
||||||
this.name = 'RenderBreakError'
|
this.name = 'RenderBreakError'
|
||||||
this.message = message + ''
|
this.message = message + ''
|
||||||
@@ -55,7 +55,7 @@ export class RenderBreakError extends Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class AssertionError extends Error {
|
export class AssertionError extends Error {
|
||||||
constructor (message: string) {
|
public constructor (message: string) {
|
||||||
super(message)
|
super(message)
|
||||||
this.name = 'AssertionError'
|
this.name = 'AssertionError'
|
||||||
this.message = message + ''
|
this.message = message + ''
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export function isFunction (value: any): value is Function {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function promisify<T1, T2> (fn: (arg1: T1, cb: (err: Error | null, result: T2) => void) => void): (arg1: T1) => Promise<T2>;
|
export function promisify<T1, T2> (fn: (arg1: T1, cb: (err: Error | null, result: T2) => void) => void): (arg1: T1) => Promise<T2>;
|
||||||
export function promisify<T1, T2, T3> (fn: (arg1: T1, arg2: T2, cb: (err: Error | null, result: T3) => void) => void):(arg1: T1, arg2: T2) => Promise<T3>;
|
export function promisify<T1, T2, T3> (fn: (arg1: T1, arg2: T2, cb: (err: Error | null, result: T3) => void) => void): (arg1: T1, arg2: T2) => Promise<T3>;
|
||||||
export function promisify (fn: any) {
|
export function promisify (fn: any) {
|
||||||
return function (...args: any[]) {
|
return function (...args: any[]) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|||||||
+6
-6
@@ -5,11 +5,11 @@ import * as chaiAsPromised from 'chai-as-promised'
|
|||||||
use(chaiAsPromised)
|
use(chaiAsPromised)
|
||||||
|
|
||||||
class SettingsDrop extends Liquid.Types.Drop {
|
class SettingsDrop extends Liquid.Types.Drop {
|
||||||
foo: string = 'FOO'
|
private foo: string = 'FOO'
|
||||||
bar () {
|
public bar () {
|
||||||
return 'BAR'
|
return 'BAR'
|
||||||
}
|
}
|
||||||
liquidMethodMissing (key: string) {
|
public liquidMethodMissing (key: string) {
|
||||||
return key.toUpperCase()
|
return key.toUpperCase()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -29,10 +29,10 @@ describe('drop', function () {
|
|||||||
describe('BlandDrop', function () {
|
describe('BlandDrop', function () {
|
||||||
it('should test blank strings', async function () {
|
it('should test blank strings', async function () {
|
||||||
const src = `
|
const src = `
|
||||||
{% unless settings.fp_heading == blank %}
|
{% unless settings.fpHeading == blank %}
|
||||||
<h1>{{ settings.fp_heading }}</h1>
|
<h1>{{ settings.fpHeading }}</h1>
|
||||||
{% endunless %}`
|
{% endunless %}`
|
||||||
var ctx = { settings: { fp_heading: '' } }
|
var ctx = { settings: { fpHeading: '' } }
|
||||||
const html = await engine.parseAndRender(src, ctx)
|
const html = await engine.parseAndRender(src, ctx)
|
||||||
return expect(html).to.match(/^\s+$/)
|
return expect(html).to.match(/^\s+$/)
|
||||||
})
|
})
|
||||||
|
|||||||
+2
-2
@@ -136,7 +136,7 @@ describe('xhr', () => {
|
|||||||
[200, { 'Content-Type': 'text/plain' }, 'foo2'])
|
[200, { 'Content-Type': 'text/plain' }, 'foo2'])
|
||||||
return engine.renderFile('foo.html')
|
return engine.renderFile('foo.html')
|
||||||
})
|
})
|
||||||
.then((html:string) => expect(html).to.equal('foo2'))
|
.then((html: string) => expect(html).to.equal('foo2'))
|
||||||
})
|
})
|
||||||
it('should respect cache=true option', () => {
|
it('should respect cache=true option', () => {
|
||||||
engine = new Liquid({
|
engine = new Liquid({
|
||||||
@@ -153,7 +153,7 @@ describe('xhr', () => {
|
|||||||
[200, { 'Content-Type': 'text/plain' }, 'foo2'])
|
[200, { 'Content-Type': 'text/plain' }, 'foo2'])
|
||||||
return engine.renderFile('foo.html')
|
return engine.renderFile('foo.html')
|
||||||
})
|
})
|
||||||
.then((html:string) => expect(html).to.equal('foo1'))
|
.then((html: string) => expect(html).to.equal('foo1'))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ describe('tags/include', function () {
|
|||||||
})
|
})
|
||||||
it('should support include: with as Liquid Drop', async function () {
|
it('should support include: with as Liquid Drop', async function () {
|
||||||
class ColorDrop extends Liquid.Types.Drop {
|
class ColorDrop extends Liquid.Types.Drop {
|
||||||
valueOf (): string {
|
public valueOf (): string {
|
||||||
return 'red!'
|
return 'red!'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -98,7 +98,7 @@ describe('tags/include', function () {
|
|||||||
})
|
})
|
||||||
it('should support include: with passed as Liquid Drop', async function () {
|
it('should support include: with passed as Liquid Drop', async function () {
|
||||||
class ColorDrop extends Liquid.Types.Drop {
|
class ColorDrop extends Liquid.Types.Drop {
|
||||||
valueOf (): string {
|
public valueOf (): string {
|
||||||
return 'red!'
|
return 'red!'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,22 +6,22 @@ describe('drop/drop', function () {
|
|||||||
before(() => (liquid = new Liquid()))
|
before(() => (liquid = new Liquid()))
|
||||||
|
|
||||||
class CustomDrop extends Liquid.Types.Drop {
|
class CustomDrop extends Liquid.Types.Drop {
|
||||||
name: string = 'NAME'
|
private name: string = 'NAME'
|
||||||
getName () {
|
public getName () {
|
||||||
return 'GET NAME'
|
return 'GET NAME'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class CustomDropWithMethodMissing extends CustomDrop {
|
class CustomDropWithMethodMissing extends CustomDrop {
|
||||||
liquidMethodMissing (key: string) {
|
public liquidMethodMissing (key: string) {
|
||||||
return key.toUpperCase()
|
return key.toUpperCase()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class PromiseDrop extends Liquid.Types.Drop {
|
class PromiseDrop extends Liquid.Types.Drop {
|
||||||
name = Promise.resolve('NAME')
|
private name = Promise.resolve('NAME')
|
||||||
async getName () {
|
public async getName () {
|
||||||
return 'GET NAME'
|
return 'GET NAME'
|
||||||
}
|
}
|
||||||
async liquidMethodMissing (key: string) {
|
public async liquidMethodMissing (key: string) {
|
||||||
return key.toUpperCase()
|
return key.toUpperCase()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-4
@@ -2,17 +2,20 @@ import { isString, forOwn } from '../../src/util/underscore'
|
|||||||
import fs from '../../src/fs/node'
|
import fs from '../../src/fs/node'
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'path'
|
||||||
|
|
||||||
type fileDescriptor = { mode: string, content: string }
|
interface FileDescriptor {
|
||||||
|
mode: string;
|
||||||
|
content: string;
|
||||||
|
}
|
||||||
|
|
||||||
let files: { [path: string]: fileDescriptor } = {}
|
let files: { [path: string]: FileDescriptor } = {}
|
||||||
const readFile = fs.readFile
|
const readFile = fs.readFile
|
||||||
const exists = fs.exists
|
const exists = fs.exists
|
||||||
|
|
||||||
export function mock (options: { [path: string]: (string | fileDescriptor) }) {
|
export function mock (options: { [path: string]: (string | FileDescriptor) }) {
|
||||||
forOwn(options, (val, key) => {
|
forOwn(options, (val, key) => {
|
||||||
files[resolve(key)] = isString(val)
|
files[resolve(key)] = isString(val)
|
||||||
? { mode: '33188', content: val }
|
? { mode: '33188', content: val }
|
||||||
: val as fileDescriptor
|
: val as FileDescriptor
|
||||||
})
|
})
|
||||||
fs.readFile = async function (path) {
|
fs.readFile = async function (path) {
|
||||||
const file = files[path]
|
const file = files[path]
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import * as chai from 'chai'
|
import * as chai from 'chai'
|
||||||
|
import { isRange } from '../../../src/parser/lexical'
|
||||||
|
|
||||||
const expect = chai.expect
|
const expect = chai.expect
|
||||||
const lexical = require('../../../src/parser/lexical')
|
|
||||||
|
|
||||||
describe('lexical', function () {
|
describe('lexical', function () {
|
||||||
it('should test range literal', function () {
|
it('should test range literal', function () {
|
||||||
expect(lexical.isRange('(12..32)')).to.equal(true)
|
expect(isRange('(12..32)')).to.equal(true)
|
||||||
expect(lexical.isRange('(12..foo)')).to.equal(true)
|
expect(isRange('(12..foo)')).to.equal(true)
|
||||||
expect(lexical.isRange('(foo.bar..foo)')).to.equal(true)
|
expect(isRange('(foo.bar..foo)')).to.equal(true)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user