chore(TypeScript): fix linting and generate .d.ts

This commit is contained in:
harttle
2019-02-17 18:20:04 +08:00
parent 7ee87008c7
commit fc9ebdb90f
79 changed files with 809 additions and 820 deletions
+1 -1
View File
@@ -25,5 +25,5 @@ export default {
'escape': escape,
'escape_once': str => escape(unescape(str)),
'newline_to_br': v => v.replace(/\n/g, '<br />'),
'strip_html': v => String(v).replace(/<script.*?<\/script>|<!--.*?-->|<style.*?<\/style>|<.*?>/g, ''),
'strip_html': v => String(v).replace(/<script.*?<\/script>|<!--.*?-->|<style.*?<\/style>|<.*?>/g, '')
}
+1 -1
View File
@@ -10,7 +10,7 @@ export default {
return Math.round(v * amp) / amp
},
'plus': bindFixed((v, arg) => Number(v) + Number(arg)),
'times': (v, arg) => v * arg,
'times': (v, arg) => v * arg
}
function getFixed (v) {
+1 -1
View File
@@ -28,5 +28,5 @@ export default {
let ret = arr.slice(0, l).join(' ')
if (arr.length > l) ret += o
return ret
},
}
}
+1 -1
View File
@@ -1,7 +1,7 @@
import { RenderBreakError } from 'src/util/error'
export default {
render: async function (scope) {
render: async function () {
throw new RenderBreakError('break')
}
}
+7 -4
View File
@@ -1,11 +1,14 @@
import assert from 'src/util/assert'
import { identifier } from 'src/parser/lexical'
import { CaptureScope } from 'src/scope/scopes'
import TagToken from 'src/parser/tag-token'
import Token from 'src/parser/token'
import Scope from 'src/scope/scope'
const re = new RegExp(`(${identifier.source})`)
export default {
parse: function (tagToken, remainTokens) {
parse: function (tagToken: TagToken, remainTokens: Token[]) {
const match = tagToken.args.match(re)
assert(match, `${tagToken.args} not valid identifier`)
@@ -13,14 +16,14 @@ export default {
this.templates = []
const stream = this.liquid.parser.parseStream(remainTokens)
stream.on('tag:endcapture', token => stream.stop())
stream.on('tag:endcapture', () => stream.stop())
.on('template', tpl => this.templates.push(tpl))
.on('end', x => {
.on('end', () => {
throw new Error(`tag ${tagToken.raw} not closed`)
})
stream.start()
},
render: async function (scope, hash) {
render: async function (scope: Scope) {
const html = await this.liquid.renderer.renderTemplates(this.templates, scope)
const ctx = new CaptureScope()
ctx[this.variable] = html
+3 -3
View File
@@ -15,16 +15,16 @@ export default {
})
})
.on('tag:else', () => (p = this.elseTemplates))
.on('tag:endcase', token => stream.stop())
.on('tag:endcase', () => stream.stop())
.on('template', tpl => p.push(tpl))
.on('end', x => {
.on('end', () => {
throw new Error(`tag ${tagToken.raw} not closed`)
})
stream.start()
},
render: function (scope, hash) {
render: function (scope) {
for (let i = 0; i < this.cases.length; i++) {
const branch = this.cases[i]
const val = evalExp(branch.val, scope)
+1 -1
View File
@@ -5,7 +5,7 @@ export default {
.on('token', token => {
if (token.name === 'endcomment') stream.stop()
})
.on('end', x => {
.on('end', () => {
throw new Error(`tag ${tagToken.raw} not closed`)
})
stream.start()
+1 -1
View File
@@ -1,7 +1,7 @@
import { RenderBreakError } from 'src/util/error'
export default {
render: async function (scope) {
render: async function () {
throw new RenderBreakError('continue')
}
}
+2 -2
View File
@@ -6,7 +6,7 @@ const groupRE = new RegExp(`^(?:(${rValue.source})\\s*:\\s*)?(.*)$`)
const candidatesRE = new RegExp(rValue.source, 'g')
export default {
parse: function (tagToken, remainTokens) {
parse: function (tagToken) {
let match = groupRE.exec(tagToken.args)
assert(match, `illegal tag: ${tagToken.raw}`)
@@ -21,7 +21,7 @@ export default {
assert(this.candidates.length, `empty candidates: ${tagToken.raw}`)
},
render: function (scope, hash) {
render: function (scope) {
const group = evalValue(this.group, scope)
const fingerprint = `cycle:${group}:` + this.candidates.join(',')
+4 -2
View File
@@ -1,14 +1,16 @@
import assert from 'src/util/assert'
import { identifier } from 'src/parser/lexical'
import { CaptureScope, AssignScope, DecrementScope } from 'src/scope/scopes'
import TagToken from 'src/parser/tag-token'
import Scope from 'src/scope/scope'
export default {
parse: function (token) {
parse: function (token: TagToken) {
const match = token.args.match(identifier)
assert(match, `illegal identifier ${token.args}`)
this.variable = match[0]
},
render: function (scope, hash) {
render: function (scope: Scope) {
let context = scope.findContextFor(
this.variable,
ctx => {
+3 -3
View File
@@ -18,16 +18,16 @@ export default {
})
})
.on('tag:else', () => (p = this.elseTemplates))
.on('tag:endif', token => stream.stop())
.on('tag:endif', () => stream.stop())
.on('template', tpl => p.push(tpl))
.on('end', x => {
.on('end', () => {
throw new Error(`tag ${tagToken.raw} not closed`)
})
stream.start()
},
render: function (scope, hash) {
render: function (scope) {
for (const branch of this.branches) {
const cond = evalExp(branch.cond, scope)
if (isTruthy(cond)) {
+1 -1
View File
@@ -8,7 +8,7 @@ export default {
assert(match, `illegal identifier ${token.args}`)
this.variable = match[0]
},
render: function (scope, hash) {
render: function (scope) {
let context = scope.findContextFor(
this.variable,
ctx => {
+4 -1
View File
@@ -15,7 +15,10 @@ import tablerow from './tablerow'
import unless from './unless'
import Break from './break'
import Continue from './continue'
import ITagImplOptions from 'src/template/tag/itag-impl-options'
export default {
const tags: { [key: string]: ITagImplOptions } = {
assign, 'for': For, capture, 'case': Case, comment, include, decrement, increment, cycle, 'if': If, layout, block, raw, tablerow, unless, 'break': Break, 'continue': Continue
}
export default tags
+1 -1
View File
@@ -13,7 +13,7 @@ export default {
})
stream.start()
},
render: function (scope, hash) {
render: function () {
return this.tokens.map(token => token.raw).join('')
}
}
+2 -2
View File
@@ -19,7 +19,7 @@ export default {
let p
const stream = this.liquid.parser.parseStream(remainTokens)
.on('start', () => (p = this.templates))
.on('tag:endtablerow', token => stream.stop())
.on('tag:endtablerow', () => stream.stop())
.on('template', tpl => p.push(tpl))
.on('end', () => {
throw new Error(`tag ${tagToken.raw} not closed`)
@@ -35,7 +35,7 @@ export default {
collection = collection.slice(offset, offset + limit)
const cols = hash.cols || collection.length
const contexts = collection.map((item, i) => {
const contexts = collection.map(item => {
const ctx = {}
ctx[this.variable] = item
return ctx
+4 -4
View File
@@ -6,21 +6,21 @@ export default {
this.elseTemplates = []
let p
const stream = this.liquid.parser.parseStream(remainTokens)
.on('start', x => {
.on('start', () => {
p = this.templates
this.cond = tagToken.args
})
.on('tag:else', () => (p = this.elseTemplates))
.on('tag:endunless', token => stream.stop())
.on('tag:endunless', () => stream.stop())
.on('template', tpl => p.push(tpl))
.on('end', x => {
.on('end', () => {
throw new Error(`tag ${tagToken.raw} not closed`)
})
stream.start()
},
render: function (scope, hash) {
render: function (scope) {
const cond = evalExp(this.cond, scope)
return isFalsy(cond)
? this.liquid.renderer.renderTemplates(this.templates, scope)
+7 -7
View File
@@ -1,5 +1,5 @@
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[]
/** `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
@@ -8,17 +8,17 @@ export interface LiquidOptions {
/** `dynamicPartials`: if set, treat `<filepath>` parameter in `{%include filepath %}`, `{%layout filepath%}` as a variable, otherwise as a literal value. Defaults to `true`. */
dynamicPartials?: boolean
/** `strict_filters` 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`. */
strict_filters?: boolean
strict_filters?: boolean // eslint-disable-line
/** `strict_variables` 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`. */
strict_variables?: boolean
strict_variables?: boolean // eslint-disable-line
/** `trim_tag_right` is used to strip blank characters (including ` `, `\t`, and `\r`) from the right of tags (`{% %}`) until `\n` (inclusive). Defaults to `false`. */
trim_tag_right?: boolean
trim_tag_right?: boolean // eslint-disable-line
/** `trim_tag_left` is similar to `trim_tag_right`, whereas the `\n` is exclusive. Defaults to `false`. See Whitespace Control for details. */
trim_tag_left?: boolean
trim_tag_left?: boolean // eslint-disable-line
/** ``trim_value_right` is used to strip blank characters (including ` `, `\t`, and `\r`) from the right of values (`{{ }}`) until `\n` (inclusive). Defaults to `false`. */
trim_value_right?: boolean
trim_value_right?: boolean // eslint-disable-line
/** `trim_value_left` is similar to `trim_value_right`, whereas the `\n` is exclusive. Defaults to `false`. See Whitespace Control for details. */
trim_value_left?: boolean
trim_value_left?: boolean // eslint-disable-line
/** `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
}
+9 -7
View File
@@ -3,7 +3,7 @@ import * as Types from './types'
import * as template from 'template'
import * as _ from './util/underscore'
import ITemplate from './template/itemplate'
import * as tokenizer from './parser/tokenizer'
import Tokenizer from './parser/tokenizer'
import Render from './render/render'
import Tag from './template/tag/tag'
import Filter from './template/filter'
@@ -20,6 +20,7 @@ export default class Liquid {
private cache: object
private parser: Parser
private renderer: Render
private tokenizer: Tokenizer
constructor (options: LiquidOptions = {}) {
options = _.assign({}, defaultOptions, options)
@@ -31,31 +32,32 @@ export default class Liquid {
this.options = options
this.parser = new Parser(this)
this.renderer = new Render()
this.tokenizer = new Tokenizer(this.options)
_.forOwn(builtinTags, (conf, name) => this.registerTag(name, conf))
_.forOwn(builtinFilters, (handler, name) => this.registerFilter(name, handler))
}
parse(html: string, filepath?: string) {
const tokens = tokenizer.parse(html, filepath, this.options)
parse (html: string, filepath?: string) {
const tokens = this.tokenizer.tokenize(html, filepath)
return this.parser.parse(tokens)
}
render(tpl: Array<ITemplate>, ctx?: object, opts?: LiquidOptions) {
render (tpl: Array<ITemplate>, ctx?: object, opts?: LiquidOptions) {
opts = _.assign({}, this.options, opts)
const scope = new Scope(ctx, opts)
return this.renderer.renderTemplates(tpl, scope)
}
async parseAndRender(html: string, ctx?: object, opts?: LiquidOptions) {
async parseAndRender (html: string, ctx?: object, opts?: LiquidOptions) {
const tpl = await this.parse(html)
return this.render(tpl, ctx, opts)
}
async getTemplate(file, root) {
async getTemplate (file, root) {
const filepath = await template.resolve(file, root, this.options)
return this.respectCache(filepath, async () => {
const str = await template.read(filepath)
return this.parse(str, filepath)
})
}
async renderFile(file, ctx?: object, opts?: LiquidOptions) {
async renderFile (file, ctx?: object, opts?: LiquidOptions) {
opts = _.assign({}, opts)
const templates = await this.getTemplate(file, opts.root)
return this.render(templates, ctx, opts)
+6 -6
View File
@@ -1,12 +1,12 @@
import Token from './token'
export default class DelimitedToken extends Token {
trim_left: boolean
trim_right: boolean
constructor(raw, pos, input, file, line) {
trimLeft: boolean
trimRight: boolean
constructor (raw, pos, input, file, line) {
super(raw, pos, input, file, line)
this.trim_left = raw[2] === '-'
this.trim_right = raw[raw.length - 3] === '-'
this.value = raw.slice(this.trim_left ? 3 : 2, this.trim_right ? -3 : -2).trim()
this.trimLeft = raw[2] === '-'
this.trimRight = raw[raw.length - 3] === '-'
this.value = raw.slice(this.trimLeft ? 3 : 2, this.trimRight ? -3 : -2).trim()
}
}
+1 -1
View File
@@ -1,7 +1,7 @@
import Token from './token'
export default class HTMLToken extends Token {
constructor(str, begin, input, file, line) {
constructor (str, begin, input, file, line) {
super(str, begin, input, file, line)
this.type = 'html'
this.value = str
+1 -1
View File
@@ -1,7 +1,7 @@
import DelimitedToken from './delimited-token'
export default class OutputToken extends DelimitedToken {
constructor(raw, pos, input, file, line) {
constructor (raw, pos, input, file, line) {
super(raw, pos, input, file, line)
this.type = 'output'
}
+4 -6
View File
@@ -2,18 +2,16 @@ import { ParseError } from '../util/error'
import Liquid from 'src/liquid'
import ParseStream from './parse-stream'
import Token from './token'
import Tag from 'src/template/tag/tag'
import HTMLToken from './html-token'
import TagToken from './tag-token'
import OutputToken from './output-token'
import Tag from 'src/template/tag/tag'
import Output from 'src/template/output'
import HTML from 'src/template/html'
import Value from 'src/template/value'
export default class Parser {
liquid: Liquid
constructor(liquid: Liquid) {
constructor (liquid: Liquid) {
this.liquid = liquid
}
parse (tokens: Array<Token>) {
@@ -27,10 +25,10 @@ export default class Parser {
parseToken (token: Token, remainTokens: Array<Token>) {
try {
if (token.type === 'tag') {
return new Tag(token, remainTokens, this.liquid)
return new Tag(token as TagToken, remainTokens, this.liquid)
}
if (token.type === 'output') {
return new Output(token, this.liquid.options.strict_filters)
return new Output(token as OutputToken, this.liquid.options.strict_filters)
}
return new HTML(token)
} catch (e) {
+1 -1
View File
@@ -5,7 +5,7 @@ import * as lexical from './lexical'
export default class TagToken extends DelimitedToken {
name: string
args: string
constructor(raw, pos, input, file, line) {
constructor (raw, pos, input, file, line) {
super(raw, pos, input, file, line)
this.type = 'tag'
const match = this.value.match(lexical.tagLine)
+1 -1
View File
@@ -5,7 +5,7 @@ export default class Token {
input: string
file: string
value: string
constructor(raw, pos, input, file, line) {
constructor (raw, pos, input, file, line) {
this.line = line
this.raw = raw
this.input = input
+44 -39
View File
@@ -2,52 +2,57 @@ import whiteSpaceCtrl from './whitespace-ctrl'
import HTMLToken from './html-token'
import TagToken from './tag-token'
import OutputToken from './output-token'
import { LiquidOptions, defaultOptions } from 'src/liquid-options'
enum ParseState { HTML, OUTPUT, TAG }
export function parse (input: string, file?: string, options?) {
const tokens = []
let p = 0
let line = 1
let state = ParseState.HTML
let buffer = ''
let bufferBegin = 0
export default class Tokenizer {
options: LiquidOptions
constructor (options: LiquidOptions = defaultOptions) {
this.options = options
}
tokenize (input: string, file?: string) {
const tokens = []
let p = 0
let line = 1
let state = ParseState.HTML
let buffer = ''
let bufferBegin = 0
while(p < input.length) {
if (input[p] === '\n') line++
const bin = input.substr(p, 2)
if (state === ParseState.HTML) {
if (bin === '{{' || bin === '{%') {
if (buffer) tokens.push(new HTMLToken(buffer, bufferBegin, input, file, line))
buffer = bin
bufferBegin = p
while (p < input.length) {
if (input[p] === '\n') line++
const bin = input.substr(p, 2)
if (state === ParseState.HTML) {
if (bin === '{{' || bin === '{%') {
if (buffer) tokens.push(new HTMLToken(buffer, bufferBegin, input, file, line))
buffer = bin
bufferBegin = p
p += 2
state = bin === '{{' ? ParseState.OUTPUT : ParseState.TAG
continue
}
} else if (state === ParseState.OUTPUT && bin === '}}') {
buffer += '}}'
tokens.push(new OutputToken(buffer, bufferBegin, input, file, line))
p += 2
state = bin === '{{' ? ParseState.OUTPUT : ParseState.TAG
buffer = ''
bufferBegin = p
state = ParseState.HTML
continue
} else if (bin === '%}') {
buffer += '%}'
tokens.push(new TagToken(buffer, bufferBegin, input, file, line))
p += 2
buffer = ''
bufferBegin = p
state = ParseState.HTML
continue
}
buffer += input[p++]
}
else if (state === ParseState.OUTPUT && bin === '}}') {
buffer += '}}'
tokens.push(new OutputToken(buffer, bufferBegin, input, file, line))
p += 2
buffer = ''
bufferBegin = p
state = ParseState.HTML
continue
}
else if (bin === '%}') {
buffer += '%}'
tokens.push(new TagToken(buffer, bufferBegin, input, file, line))
p += 2
buffer = ''
bufferBegin = p
state = ParseState.HTML
continue
}
buffer += input[p++]
}
if (buffer) tokens.push(new HTMLToken(buffer, bufferBegin, input, file, line))
if (buffer) tokens.push(new HTMLToken(buffer, bufferBegin, input, file, line))
whiteSpaceCtrl(tokens, options)
return tokens
whiteSpaceCtrl(tokens, this.options)
return tokens
}
}
+18 -17
View File
@@ -1,46 +1,47 @@
import { assign } from 'src/util/underscore'
import TagToken from './tag-token'
import OutputToken from './output-token'
import HTMLToken from './html-token'
import DelimitedToken from 'src/parser/delimited-token'
import Token from 'src/parser/token'
import TagToken from 'src/parser/tag-token'
import { LiquidOptions } from 'src/liquid-options'
export default function whiteSpaceCtrl (tokens, options) {
export default function whiteSpaceCtrl (tokens: Token[], options: LiquidOptions) {
options = assign({ greedy: true }, options)
let inRaw = false
tokens.forEach((token, i) => {
if (shouldTrimLeft(token, inRaw, options)) {
tokens.forEach((token: Token, i: number) => {
if (shouldTrimLeft(token as DelimitedToken, inRaw, options)) {
trimLeft(tokens[i - 1], options.greedy)
}
if (token.type === 'tag' && token.name === 'raw') inRaw = true
if (token.type === 'tag' && token.name === 'endraw') inRaw = false
if (token.type === 'tag' && (token as TagToken).name === 'raw') inRaw = true
if (token.type === 'tag' && (token as TagToken).name === 'endraw') inRaw = false
if (shouldTrimRight(token, inRaw, options)) {
if (shouldTrimRight(token as DelimitedToken, inRaw, options)) {
trimRight(tokens[i + 1], options.greedy)
}
})
}
function shouldTrimLeft (token, inRaw, options) {
function shouldTrimLeft (token: DelimitedToken, inRaw: boolean, options) {
if (inRaw) return false
if (token.type === 'tag') return token.trim_left || options.trim_tag_left
if (token.type === 'output') return token.trim_left || options.trim_value_left
if (token.type === 'tag') return token.trimLeft || options.trim_tag_left
if (token.type === 'output') return token.trimLeft || options.trim_value_left
}
function shouldTrimRight (token, inRaw, options) {
function shouldTrimRight (token: DelimitedToken, inRaw: boolean, options) {
if (inRaw) return false
if (token.type === 'tag') return token.trim_right || options.trim_tag_right
if (token.type === 'output') return token.trim_right || options.trim_value_right
if (token.type === 'tag') return token.trimRight || options.trim_tag_right
if (token.type === 'output') return token.trimRight || options.trim_value_right
}
function trimLeft (token, greedy) {
function trimLeft (token: Token, greedy: boolean) {
if (!token || token.type !== 'html') return
const rLeft = greedy ? /\s+$/g : /[\t\r ]*$/g
token.value = token.value.replace(rLeft, '')
}
function trimRight (token, greedy) {
function trimRight (token: Token, greedy: boolean) {
if (!token || token.type !== 'html') return
const rRight = greedy ? /^\s+/g : /^[\t\r ]*\n?/g
-2
View File
@@ -1,7 +1,5 @@
import { stringify, create } from 'src/util/underscore'
import { RenderBreakError, RenderError } from 'src/util/error'
import assert from 'src/util/assert'
import Scope from 'src/scope/scope'
export default class Render {
async renderTemplates (templates, scope) {
+2 -2
View File
@@ -15,7 +15,7 @@ export default class Scope {
strict_variables: false,
strict_filters: false,
root: []
} , opts)
}, opts)
this.contexts = [ctx || {}]
}
getAll () {
@@ -59,7 +59,7 @@ export default class Scope {
}
return this.contexts.splice(i, 1)[0]
}
findContextFor (key: string, filter = (arg => true)) {
findContextFor (key: string, filter: ((conttext: object) => boolean) = () => true) {
for (let i = this.contexts.length - 1; i >= 0; i--) {
const candidate = this.contexts[i]
if (!filter(candidate)) continue
+5 -5
View File
@@ -13,21 +13,21 @@ export default class Filter {
args: string[]
private static impls: {[key: string]: impl} = {}
constructor (str: string, strict_filters: boolean = false) {
let match = lexical.filterLine.exec(str)
constructor (str: string, strictFilters: boolean = false) {
const match = lexical.filterLine.exec(str)
assert(match, 'illegal filter: ' + str)
const name = match[1]
const argList = match[2] || ''
const impl = Filter.impls[name]
if (!impl && strict_filters) throw new TypeError(`undefined filter: ${name}`)
if (!impl && strictFilters) throw new TypeError(`undefined filter: ${name}`)
this.name = name
this.impl = impl || (x => x)
this.args = this.parseArgs(argList)
}
parseArgs (argList: string): string[] {
let match, args = []
let match; const args = []
while ((match = valueRE.exec(argList.trim()))) {
const v = match[0]
const re = new RegExp(`${v}\\s*:`, 'g')
@@ -42,7 +42,7 @@ export default class Filter {
args.unshift(value)
return this.impl.apply(null, args)
}
static register(name, filter) {
static register (name, filter) {
Filter.impls[name] = filter
}
static clear () {
+2 -3
View File
@@ -1,15 +1,14 @@
import Template from 'src/template/template'
import Scope from 'src/scope/scope'
import ITemplate from 'src/template/itemplate'
import Token from 'src/parser/token'
export default class extends Template implements ITemplate {
str: string
constructor(token: Token) {
constructor (token: Token) {
super(token)
this.str = token.value
}
async render(scope: Scope): Promise<string> {
async render (): Promise<string> {
return this.str
}
}
+4 -3
View File
@@ -3,14 +3,15 @@ import { stringify } from 'src/util/underscore'
import Template from 'src/template/template'
import ITemplate from 'src/template/itemplate'
import Scope from 'src/scope/scope'
import OutputToken from 'src/parser/output-token'
export default class Output extends Template implements ITemplate {
value: Value
constructor(token, strict_filters?) {
constructor (token: OutputToken, strictFilters?: boolean) {
super(token)
this.value = new Value(token.value, strict_filters)
this.value = new Value(token.value, strictFilters)
}
async render(scope: Scope) {
async render (scope: Scope): Promise<string> {
const html = await this.value.value(scope)
return stringify(html)
}
+1 -1
View File
@@ -9,7 +9,7 @@ import { evalValue } from 'src/render/syntax'
*/
export default class Hash {
[key: string]: any
constructor(markup, scope) {
constructor (markup, scope) {
let match
hashCapture.lastIndex = 0
while ((match = hashCapture.exec(markup))) {
+1 -1
View File
@@ -6,5 +6,5 @@ import ITagImpl from './itag-impl'
export default interface ITagImplOptions {
parse?: (this: ITagImpl, token: TagToken, remainingTokens: Array<Token>) => void
render?: (this: ITagImpl, scope: Scope, hash: Hash) => string | Promise<string>
render?: (this: ITagImpl, scope: Scope, hash: Hash) => any | Promise<any>
}
+7 -6
View File
@@ -1,6 +1,6 @@
import { create } from 'src/util/underscore'
import { stringify } from 'src/util/underscore'
import { create, stringify } from 'src/util/underscore'
import assert from 'src/util/assert'
import Scope from 'src/scope/scope'
import ITagImpl from './itag-impl'
import ITagImplOptions from './itag-impl-options'
import Liquid from 'src/liquid'
@@ -8,26 +8,27 @@ import Hash from './hash'
import Template from 'src/template/template'
import ITemplate from 'src/template/itemplate'
import TagToken from 'src/parser/tag-token'
import Token from 'src/parser/token'
export default class Tag extends Template implements ITemplate {
name: string
token: TagToken
private impl: ITagImpl
static impls: object = {}
static impls: { [key: string]: ITagImplOptions } = {}
constructor (token, tokens, liquid: Liquid) {
constructor (token: TagToken, tokens: Token[], liquid: Liquid) {
super(token)
this.name = token.name
const impl = Tag.impls[token.name]
assert(impl, `tag ${token.name} not found`)
this.impl = create(impl)
this.impl = create<ITagImplOptions, ITagImpl>(impl)
this.impl.liquid = liquid
if (this.impl.parse) {
this.impl.parse(token, tokens)
}
}
async render (scope) {
async render (scope: Scope) {
const hash = new Hash(this.token.args, scope)
const impl = this.impl
if (typeof impl.render !== 'function') {
+2 -2
View File
@@ -2,7 +2,7 @@ import Token from 'src/parser/token'
export default class Template {
token: Token;
constructor(token) {
this.token = token;
constructor (token) {
this.token = token
}
}
+3 -3
View File
@@ -7,7 +7,7 @@ import Scope from 'src/scope/scope'
export default class {
initial: any
filters: Array<any>
constructor(str: string, strict_filters?: boolean) {
constructor (str: string, strictFilters?: boolean) {
let match = lexical.matchValue(str)
assert(match, `illegal value string: ${str}`)
@@ -20,9 +20,9 @@ export default class {
}
this.initial = initial
this.filters = filters.map(str => new Filter(str, strict_filters))
this.filters = filters.map(str => new Filter(str, strictFilters))
}
value(scope: Scope) {
value (scope: Scope) {
return this.filters.reduce(
(prev, filter) => filter.render(prev, scope),
evalExp(this.initial, scope))
+11 -11
View File
@@ -16,14 +16,14 @@ abstract class LiquidError {
private input: string
private token: Token
private originalError: Error
constructor(err, token) {
constructor (err, token) {
this.input = token.input
this.line = token.line
this.file = token.file
this.originalError = err
this.token = token
}
captureStackTrace(obj) {
captureStackTrace (obj) {
this.name = obj.constructor.name
captureStack.call(obj)
@@ -37,32 +37,32 @@ abstract class LiquidError {
}
export class TokenizationError extends LiquidError {
constructor(message, token) {
super({message}, token)
constructor (message, token) {
super({ message }, token)
super.captureStackTrace(this)
}
}
TokenizationError.prototype = _.create(Error.prototype)
TokenizationError.prototype = _.create(Error.prototype) as any
TokenizationError.prototype.constructor = TokenizationError
export class ParseError extends LiquidError {
constructor(err, token) {
constructor (err, token) {
super(err, token)
_.assign(this, err)
super.captureStackTrace(this)
}
}
ParseError.prototype = _.create(Error.prototype)
ParseError.prototype = _.create(Error.prototype) as any
ParseError.prototype.constructor = ParseError
export class RenderError extends LiquidError {
constructor(err, tpl) {
constructor (err, tpl) {
super(err, tpl.token)
_.assign(this, err)
super.captureStackTrace(this)
}
}
RenderError.prototype = _.create(Error.prototype)
RenderError.prototype = _.create(Error.prototype) as any
RenderError.prototype.constructor = RenderError
export class RenderBreakError {
@@ -73,7 +73,7 @@ export class RenderBreakError {
this.message = message + ''
}
}
RenderBreakError.prototype = _.create(Error.prototype)
RenderBreakError.prototype = _.create(Error.prototype) as any
RenderBreakError.prototype.constructor = RenderBreakError
export class AssertionError {
@@ -83,7 +83,7 @@ export class AssertionError {
this.message = message + ''
}
}
AssertionError.prototype = _.create(Error.prototype)
AssertionError.prototype = _.create(Error.prototype) as any
AssertionError.prototype.constructor = AssertionError
function mkContext (input, targetLine) {
+1 -1
View File
@@ -7,7 +7,7 @@
export function anySeries (iterable, iteratee) {
let ret: Promise<any> = Promise.reject(new Error('init'))
iterable.forEach(function (item, idx) {
ret = ret.catch(e => iteratee(item, idx, iterable))
ret = ret.catch(() => iteratee(item, idx, iterable))
})
return ret
}
+1 -1
View File
@@ -159,7 +159,7 @@ const formatCodes = {
}
};
(formatCodes as any).h = formatCodes.b;
(formatCodes as any).N = formatCodes.L;
(formatCodes as any).N = formatCodes.L
export default function (d, format) {
let output = ''
+18 -17
View File
@@ -6,11 +6,11 @@ const arrToStr = Array.prototype.toString
* @param {any} value The value to check.
* @return {Boolean} Returns true if value is a string, else false.
*/
export function isString (value) {
export function isString (value: any) {
return toStr.call(value) === '[object String]'
}
export function isFunction (value) {
export function isFunction (value: any) {
return typeof value === 'function'
}
@@ -24,7 +24,7 @@ export function promisify (fn) {
}
}
export function stringify (value) {
export function stringify (value: any): string {
if (isNil(value)) return ''
if (isFunction(value.to_liquid)) return stringify(value.to_liquid())
if (isFunction(value.toLiquid)) return stringify(value.toLiquid())
@@ -34,7 +34,7 @@ export function stringify (value) {
return toStr.call(value)
}
function defaultToString (value) {
function defaultToString (value: any): string {
const cache = []
return JSON.stringify(value, (key, value) => {
if (isObject(value)) {
@@ -47,20 +47,20 @@ function defaultToString (value) {
})
}
export function create (proto) {
export function create<T1 extends object, T2 extends T1 = T1> (proto: T1): T2 {
return Object.create(proto)
}
export function isNil (value) {
export function isNil (value: any): boolean {
return value === null || value === undefined
}
export function isArray (value) {
export function isArray (value: any): boolean {
// be compatible with IE 8
return toStr.call(value) === '[object Array]'
}
export function isError (value) {
export function isError (value: any): boolean {
const signature = toStr.call(value)
// [object XXXError]
return signature.substr(-6, 5) === 'Error' ||
@@ -75,7 +75,7 @@ export function isError (value) {
* @param {Function} iteratee The function invoked per iteration.
* @return {Object} Returns object.
*/
export function forOwn (object, iteratee) {
export function forOwn (object, iteratee: ((val: any, key: string, obj: object) => boolean | void)) {
object = object || {}
for (const k in object) {
if (object.hasOwnProperty(k)) {
@@ -96,21 +96,22 @@ export function forOwn (object, iteratee) {
* @param {...Object} sources The source objects.
* @return {Object} Returns object.
*/
export function assign (obj, ...srcs) {
export function assign (obj: object, ...srcs: object[]): object {
obj = isObject(obj) ? obj : {}
srcs.forEach(src => binaryAssign(obj, src))
return obj
}
function binaryAssign(target, src) {
for(let key in src) if (src.hasOwnProperty(key)) target[key] = src[key]
function binaryAssign (target: object, src: object): object {
for (const key in src) if (src.hasOwnProperty(key)) target[key] = src[key]
return target
}
export function last (arr) {
export function last (arr: any[]): any {
return arr[arr.length - 1]
}
export function uniq (arr) {
export function uniq (arr: any[]): any[] {
const u = {}
const a = []
for (let i = 0, l = arr.length; i < l; ++i) {
@@ -129,7 +130,7 @@ export function uniq (arr) {
* @param {any} value The value to check.
* @return {Boolean} Returns true if value is an object, else false.
*/
export function isObject (value) {
export function isObject (value: any): boolean {
const type = typeof value
return value !== null && (type === 'object' || type === 'function')
}
@@ -156,9 +157,9 @@ export function range (start: number, stop?: number, step?: number) {
return arr
}
export function padStart(str: any, length: number, ch: string = ' ') {
export function padStart (str: any, length: number, ch: string = ' ') {
str = String(str)
let n = length - str.length
while(n-- > 0) str = ch + str
while (n-- > 0) str = ch + str
return str
}