mirror of
https://github.com/harttle/liquidjs.git
synced 2026-09-15 04:10:40 -07:00
chore(typescript): ship to TypeScript
This commit is contained in:
+4
-4
@@ -1,7 +1,7 @@
|
||||
import * as lexical from './lexical.js'
|
||||
import { evalValue } from './syntax.js'
|
||||
import assert from './util/assert.js'
|
||||
import { assign, create } from './util/underscore.js'
|
||||
import * as lexical from './lexical'
|
||||
import { evalValue } from './syntax'
|
||||
import assert from './util/assert'
|
||||
import { assign, create } from './util/underscore'
|
||||
|
||||
const valueRE = new RegExp(`${lexical.value.source}`, 'g')
|
||||
|
||||
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
import strftime from './util/strftime.js'
|
||||
import * as _ from './util/underscore.js'
|
||||
import { isTruthy } from './syntax.js'
|
||||
import strftime from './util/strftime'
|
||||
import * as _ from './util/underscore'
|
||||
import { isTruthy } from './syntax'
|
||||
|
||||
const escapeMap = {
|
||||
'&': '&',
|
||||
@@ -132,7 +132,7 @@ function isValidDate (date) {
|
||||
return date instanceof Date && !isNaN(date.getTime())
|
||||
}
|
||||
|
||||
export default function registerAll (liquid) {
|
||||
export default function registerAll (liquid, Liquid) {
|
||||
return _.forOwn(filters, (func, name) => liquid.registerFilter(name, func))
|
||||
}
|
||||
|
||||
|
||||
Vendored
-69
@@ -1,69 +0,0 @@
|
||||
export as namespace Liquid;
|
||||
|
||||
export function isTruthy(val: any): boolean;
|
||||
export function isFalsy(val: any): boolean;
|
||||
export function evalExp(exp: string, scope: any): any;
|
||||
export function evalValue(str: string, scope: any): any;
|
||||
|
||||
export default class Liquid {
|
||||
constructor(options?: Options);
|
||||
private init(tag, filter, options): Liquid;
|
||||
private respectCache(key, getter): Promise<any>
|
||||
parse(html: string, filepath?: string): Liquid.Template
|
||||
render(tpl: Template, ctx: any, opts?: Options): Promise<string>
|
||||
parseAndRender(html: string, ctx: any, opts?: Options): Promise<string>
|
||||
renderFile(file: string, ctx: any, opts?: Options): Promise<string>
|
||||
getTemplate(file: string, root: string): Promise<Liquid.Template>
|
||||
registerFilter(name: string, filter: Filter): void
|
||||
registerTag(name: string, tag: Tag): void
|
||||
express(opts: Options): any
|
||||
}
|
||||
|
||||
export interface Options {
|
||||
/** `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
|
||||
/** `cache` indicates whether or not to cache resolved templates. Defaults to `false`. */
|
||||
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?: 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
|
||||
/** `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_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_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_left` is similar to `trim_value_right`, whereas the `\n` is exclusive. Defaults to `false`. See Whitespace Control for details. */
|
||||
trim_value_left?: boolean
|
||||
/** `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
|
||||
}
|
||||
|
||||
export interface Template { }
|
||||
|
||||
export interface Tag {
|
||||
parse(this: any, tagToken: any, remainTokens: any): void
|
||||
render(this: any, scope: any, hash: any): void
|
||||
}
|
||||
export type Filter = (...args: any) => string
|
||||
|
||||
declare namespace Types {
|
||||
class LiquidError extends Error {
|
||||
input: string
|
||||
line: number
|
||||
file: string
|
||||
}
|
||||
class ParseError extends LiquidError {
|
||||
originalError: Error
|
||||
}
|
||||
class TokenizationError extends LiquidError {}
|
||||
class RenderBreakError extends LiquidError {}
|
||||
class AssertionError extends LiquidError {}
|
||||
class AssignScope {}
|
||||
class CaptureScope {}
|
||||
class IncrementScope {}
|
||||
class DecrementScope {}
|
||||
}
|
||||
+12
-13
@@ -1,17 +1,16 @@
|
||||
import 'regenerator-runtime/runtime'
|
||||
import * as Scope from './scope'
|
||||
import Scope from './scope'
|
||||
import * as template from './template'
|
||||
import * as _ from './util/underscore.js'
|
||||
import assert from './util/assert.js'
|
||||
import * as tokenizer from './tokenizer.js'
|
||||
import Render from './render.js'
|
||||
import Tag from './tag.js'
|
||||
import Filter from './filter.js'
|
||||
import * as _ from './util/underscore'
|
||||
import assert from './util/assert'
|
||||
import * as tokenizer from './tokenizer'
|
||||
import Render from './render'
|
||||
import Tag from './tag'
|
||||
import Filter from './filter'
|
||||
import Parser from './parser'
|
||||
import { isTruthy, isFalsy, evalExp, evalValue } from './syntax.js'
|
||||
import { ParseError, TokenizationError, RenderBreakError, AssertionError } from './util/error.js'
|
||||
import tags from './tags/index.js'
|
||||
import filters from './filters.js'
|
||||
import { isTruthy, isFalsy, evalExp, evalValue } from './syntax'
|
||||
import { ParseError, TokenizationError, RenderBreakError, AssertionError } from './util/error'
|
||||
import tags from './tags/index'
|
||||
import filters from './filters'
|
||||
|
||||
const _engine = {
|
||||
init: function (tag, filter, options) {
|
||||
@@ -35,7 +34,7 @@ const _engine = {
|
||||
},
|
||||
render: function (tpl, ctx, opts) {
|
||||
opts = _.assign({}, this.options, opts)
|
||||
const scope = Scope.factory(ctx, opts)
|
||||
const scope = new Scope(ctx, opts)
|
||||
return this.renderer.renderTemplates(tpl, scope)
|
||||
},
|
||||
parseAndRender: async function (html, ctx, opts) {
|
||||
@@ -1,27 +1,28 @@
|
||||
import * as lexical from './lexical.js'
|
||||
import { create } from './util/underscore.js'
|
||||
import { ParseError } from './util/error.js'
|
||||
import assert from './util/assert.js'
|
||||
import * as lexical from './lexical'
|
||||
import { ParseError } from './util/error'
|
||||
import assert from './util/assert'
|
||||
|
||||
export default function (Tag, Filter) {
|
||||
const stream = {
|
||||
init: function (tokens) {
|
||||
class ParseStream {
|
||||
tokens: Array<any>
|
||||
handlers: object
|
||||
stopRequested: boolean
|
||||
constructor (tokens) {
|
||||
this.tokens = tokens
|
||||
this.handlers = {}
|
||||
return this
|
||||
},
|
||||
on: function (name, cb) {
|
||||
}
|
||||
on (name, cb) {
|
||||
this.handlers[name] = cb
|
||||
return this
|
||||
},
|
||||
trigger: function (event, arg) {
|
||||
}
|
||||
trigger (event: string, arg?: any) {
|
||||
const h = this.handlers[event]
|
||||
if (typeof h === 'function') {
|
||||
h(arg)
|
||||
return true
|
||||
}
|
||||
},
|
||||
start: function () {
|
||||
}
|
||||
start () {
|
||||
this.trigger('start')
|
||||
let token
|
||||
while (!this.stopRequested && (token = this.tokens.shift())) {
|
||||
@@ -35,8 +36,8 @@ export default function (Tag, Filter) {
|
||||
}
|
||||
if (!this.stopRequested) this.trigger('end')
|
||||
return this
|
||||
},
|
||||
stop: function () {
|
||||
}
|
||||
stop () {
|
||||
this.stopRequested = true
|
||||
return this
|
||||
}
|
||||
@@ -93,8 +94,7 @@ export default function (Tag, Filter) {
|
||||
}
|
||||
|
||||
function parseStream (tokens) {
|
||||
const s = create(stream)
|
||||
return s.init(tokens)
|
||||
return new ParseStream(tokens)
|
||||
}
|
||||
|
||||
return {
|
||||
+5
-5
@@ -1,7 +1,7 @@
|
||||
import { evalExp } from './syntax.js'
|
||||
import { RenderBreakError, RenderError } from './util/error.js'
|
||||
import { stringify, create } from './util/underscore.js'
|
||||
import assert from './util/assert.js'
|
||||
import { evalExp } from './syntax'
|
||||
import { RenderBreakError, RenderError } from './util/error'
|
||||
import { stringify, create } from './util/underscore'
|
||||
import assert from './util/assert'
|
||||
|
||||
const render = {
|
||||
renderTemplates: async function (templates, scope) {
|
||||
@@ -16,7 +16,7 @@ const render = {
|
||||
e.resolvedHTML = html
|
||||
throw e
|
||||
}
|
||||
throw new RenderError(e, tpl)
|
||||
throw e instanceof RenderError ? e : new RenderError(e, tpl)
|
||||
}
|
||||
}
|
||||
return html
|
||||
|
||||
+42
-36
@@ -1,17 +1,38 @@
|
||||
import * as _ from './util/underscore.js'
|
||||
import * as lexical from './lexical.js'
|
||||
import assert from './util/assert.js'
|
||||
import * as _ from './util/underscore'
|
||||
import * as lexical from './lexical'
|
||||
import assert from './util/assert'
|
||||
|
||||
const Scope = {
|
||||
getAll: function () {
|
||||
interface ScopeOptions {
|
||||
dynamicPartials: boolean
|
||||
strict_variables: boolean
|
||||
strict_filters: boolean
|
||||
blocks: object
|
||||
root: Array<string>
|
||||
}
|
||||
|
||||
export default class Scope {
|
||||
opts: ScopeOptions
|
||||
contexts: Array<object>
|
||||
constructor (ctx = {}, opts?: any) {
|
||||
const defaultOptions: ScopeOptions = {
|
||||
dynamicPartials: true,
|
||||
strict_variables: false,
|
||||
strict_filters: false,
|
||||
blocks: {},
|
||||
root: []
|
||||
}
|
||||
this.opts = _.assign(defaultOptions, opts)
|
||||
this.contexts = [ctx || {}]
|
||||
}
|
||||
getAll () {
|
||||
return this.contexts.reduce((ctx, val) => _.assign(ctx, val), _.create(null))
|
||||
},
|
||||
get: function (path) {
|
||||
}
|
||||
get (path) {
|
||||
const paths = this.propertyAccessSeq(path)
|
||||
const scope = this.findContextFor(paths[0]) || _.last(this.contexts)
|
||||
return paths.reduce((value, key) => this.readProperty(value, key), scope)
|
||||
},
|
||||
set: function (path, v) {
|
||||
}
|
||||
set (path, v) {
|
||||
const paths = this.propertyAccessSeq(path)
|
||||
let scope = this.findContextFor(paths[0]) || _.last(this.contexts)
|
||||
paths.some((key, i) => {
|
||||
@@ -27,14 +48,14 @@ const Scope = {
|
||||
}
|
||||
scope = scope[key]
|
||||
})
|
||||
},
|
||||
unshift: function (ctx) {
|
||||
}
|
||||
unshift (ctx) {
|
||||
return this.contexts.unshift(ctx)
|
||||
},
|
||||
push: function (ctx) {
|
||||
}
|
||||
push (ctx) {
|
||||
return this.contexts.push(ctx)
|
||||
},
|
||||
pop: function (ctx) {
|
||||
}
|
||||
pop (ctx) {
|
||||
if (!arguments.length) {
|
||||
return this.contexts.pop()
|
||||
}
|
||||
@@ -43,9 +64,8 @@ const Scope = {
|
||||
throw new TypeError('scope not found, cannot pop')
|
||||
}
|
||||
return this.contexts.splice(i, 1)[0]
|
||||
},
|
||||
findContextFor: function (key, filter) {
|
||||
filter = filter || (() => true)
|
||||
}
|
||||
findContextFor (key, filter = (arg => true)) {
|
||||
for (let i = this.contexts.length - 1; i >= 0; i--) {
|
||||
const candidate = this.contexts[i]
|
||||
if (!filter(candidate)) continue
|
||||
@@ -54,8 +74,8 @@ const Scope = {
|
||||
}
|
||||
}
|
||||
return null
|
||||
},
|
||||
readProperty: function (obj, key) {
|
||||
}
|
||||
readProperty (obj, key) {
|
||||
let val
|
||||
if (_.isNil(obj)) {
|
||||
val = undefined
|
||||
@@ -70,7 +90,7 @@ const Scope = {
|
||||
throw new TypeError(`undefined variable: ${key}`)
|
||||
}
|
||||
return val
|
||||
},
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse property access sequence from access string
|
||||
@@ -80,7 +100,7 @@ const Scope = {
|
||||
* accessSeq("foo['b]r']") // ['foo', 'b]r']
|
||||
* accessSeq("foo[bar.coo]") // ['foo', 'bar'], for bar.coo == 'bar'
|
||||
*/
|
||||
propertyAccessSeq: function (str) {
|
||||
propertyAccessSeq (str) {
|
||||
str = String(str)
|
||||
const seq = []
|
||||
let name = ''
|
||||
@@ -163,17 +183,3 @@ function matchRightBracket (str, begin) {
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
export function factory (ctx, opts) {
|
||||
const defaultOptions = {
|
||||
dynamicPartials: true,
|
||||
strict_variables: false,
|
||||
strict_filters: false,
|
||||
blocks: {},
|
||||
root: []
|
||||
}
|
||||
const scope = _.create(Scope)
|
||||
scope.opts = _.assign(defaultOptions, opts)
|
||||
scope.contexts = [ctx || {}]
|
||||
return scope
|
||||
}
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
import Operators from './operators.js'
|
||||
import * as lexical from './lexical.js'
|
||||
import assert from './util/assert.js'
|
||||
import Operators from './operators'
|
||||
import * as lexical from './lexical'
|
||||
import assert from './util/assert'
|
||||
|
||||
const operators = Operators(isTruthy)
|
||||
|
||||
|
||||
+4
-4
@@ -1,7 +1,7 @@
|
||||
import { hashCapture } from './lexical.js'
|
||||
import { create } from './util/underscore.js'
|
||||
import { evalValue } from './syntax.js'
|
||||
import assert from './util/assert.js'
|
||||
import { hashCapture } from './lexical'
|
||||
import { create } from './util/underscore'
|
||||
import { evalValue } from './syntax'
|
||||
import assert from './util/assert'
|
||||
|
||||
function hash (markup, scope) {
|
||||
const obj = {}
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
import assert from '../util/assert.js'
|
||||
import { identifier } from '../lexical.js'
|
||||
import { create } from '../util/underscore.js'
|
||||
import assert from '../util/assert'
|
||||
import { identifier } from '../lexical'
|
||||
import { create } from '../util/underscore'
|
||||
|
||||
export default function (liquid, Liquid) {
|
||||
const re = new RegExp(`(${identifier.source})\\s*=([^]*)`)
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
import assert from '../util/assert.js'
|
||||
import { create } from '../util/underscore.js'
|
||||
import { identifier } from '../lexical.js'
|
||||
import assert from '../util/assert'
|
||||
import { create } from '../util/underscore'
|
||||
import { identifier } from '../lexical'
|
||||
|
||||
export default function (liquid, Liquid) {
|
||||
const re = new RegExp(`(${identifier.source})`)
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
import assert from '../util/assert.js'
|
||||
import { value as rValue } from '../lexical.js'
|
||||
import assert from '../util/assert'
|
||||
import { value as rValue } from '../lexical'
|
||||
|
||||
export default function (liquid, Liquid) {
|
||||
const groupRE = new RegExp(`^(?:(${rValue.source})\\s*:\\s*)?(.*)$`)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { create } from '../util/underscore.js'
|
||||
import assert from '../util/assert.js'
|
||||
import { identifier } from '../lexical.js'
|
||||
import { create } from '../util/underscore'
|
||||
import assert from '../util/assert'
|
||||
import { identifier } from '../lexical'
|
||||
|
||||
export default function (liquid, Liquid) {
|
||||
const { CaptureScope, AssignScope, DecrementScope } = Liquid.Types
|
||||
|
||||
+4
-4
@@ -1,7 +1,7 @@
|
||||
import { mapSeries } from '../util/promise.js'
|
||||
import { isString, isObject, isArray } from '../util/underscore.js'
|
||||
import assert from '../util/assert.js'
|
||||
import { identifier, value, hash } from '../lexical.js'
|
||||
import { mapSeries } from '../util/promise'
|
||||
import { isString, isObject, isArray } from '../util/underscore'
|
||||
import assert from '../util/assert'
|
||||
import { identifier, value, hash } from '../lexical'
|
||||
|
||||
export default function (liquid, Liquid) {
|
||||
const RenderBreakError = Liquid.Types.RenderBreakError
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
import assert from '../util/assert.js'
|
||||
import { value, quotedLine } from '../lexical.js'
|
||||
import assert from '../util/assert'
|
||||
import { value, quotedLine } from '../lexical'
|
||||
|
||||
const staticFileRE = /[^\s,]+/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import assert from '../util/assert.js'
|
||||
import { create } from '../util/underscore.js'
|
||||
import { identifier } from '../lexical.js'
|
||||
import assert from '../util/assert'
|
||||
import { create } from '../util/underscore'
|
||||
import { identifier } from '../lexical'
|
||||
|
||||
export default function (liquid, Liquid) {
|
||||
const { CaptureScope, AssignScope, IncrementScope } = Liquid.Types
|
||||
|
||||
+14
-14
@@ -1,17 +1,17 @@
|
||||
import For from './for.js'
|
||||
import Assign from './assign.js'
|
||||
import Capture from './capture.js'
|
||||
import Case from './case.js'
|
||||
import Comment from './comment.js'
|
||||
import Include from './include.js'
|
||||
import Decrement from './decrement.js'
|
||||
import Cycle from './cycle.js'
|
||||
import If from './if.js'
|
||||
import Increment from './increment.js'
|
||||
import Layout from './layout.js'
|
||||
import Raw from './raw.js'
|
||||
import Tablerow from './tablerow.js'
|
||||
import Unless from './unless.js'
|
||||
import For from './for'
|
||||
import Assign from './assign'
|
||||
import Capture from './capture'
|
||||
import Case from './case'
|
||||
import Comment from './comment'
|
||||
import Include from './include'
|
||||
import Decrement from './decrement'
|
||||
import Cycle from './cycle'
|
||||
import If from './if'
|
||||
import Increment from './increment'
|
||||
import Layout from './layout'
|
||||
import Raw from './raw'
|
||||
import Tablerow from './tablerow'
|
||||
import Unless from './unless'
|
||||
|
||||
export default function (engine, Liquid) {
|
||||
Assign(engine, Liquid)
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
import assert from '../util/assert.js'
|
||||
import { value as rValue } from '../lexical.js'
|
||||
import assert from '../util/assert'
|
||||
import { value as rValue } from '../lexical'
|
||||
|
||||
/*
|
||||
* blockMode:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { mapSeries } from '../util/promise.js'
|
||||
import assert from '../util/assert.js'
|
||||
import { identifier, value, hash } from '../lexical.js'
|
||||
import { mapSeries } from '../util/promise'
|
||||
import assert from '../util/assert'
|
||||
import { identifier, value, hash } from '../lexical'
|
||||
|
||||
export default function (liquid, Liquid) {
|
||||
const re = new RegExp(`^(${identifier.source})\\s+in\\s+` +
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as _ from './util/underscore.js'
|
||||
import path from 'path'
|
||||
import { anySeries } from './util/promise.js'
|
||||
import fs from 'fs'
|
||||
import * as _ from './util/underscore'
|
||||
import * as path from 'path'
|
||||
import { anySeries } from './util/promise'
|
||||
import * as fs from 'fs'
|
||||
|
||||
const statFileAsync = _.promisify(fs.stat)
|
||||
const readFileAsync = _.promisify(fs.readFile)
|
||||
+6
-6
@@ -1,10 +1,10 @@
|
||||
import * as lexical from './lexical.js'
|
||||
import { TokenizationError } from './util/error.js'
|
||||
import * as _ from './util/underscore.js'
|
||||
import assert from './util/assert.js'
|
||||
import whiteSpaceCtrl from './whitespace-ctrl.js'
|
||||
import * as lexical from './lexical'
|
||||
import { TokenizationError } from './util/error'
|
||||
import * as _ from './util/underscore'
|
||||
import assert from './util/assert'
|
||||
import whiteSpaceCtrl from './whitespace-ctrl'
|
||||
|
||||
export { default as whiteSpaceCtrl } from './whitespace-ctrl.js'
|
||||
export { default as whiteSpaceCtrl } from './whitespace-ctrl'
|
||||
|
||||
export function parse (input, file, options) {
|
||||
assert(_.isString(input), 'illegal input')
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { AssertionError } from './error.js'
|
||||
import { AssertionError } from './error'
|
||||
|
||||
export default function (predicate, message) {
|
||||
export default function (predicate: any, message: string) {
|
||||
if (!predicate) {
|
||||
message = message || `expect ${predicate} to be true`
|
||||
throw new AssertionError(message)
|
||||
@@ -1,100 +0,0 @@
|
||||
import * as _ from './underscore.js'
|
||||
|
||||
function initError () {
|
||||
this.name = this.constructor.name
|
||||
if (Error.captureStackTrace) {
|
||||
Error.captureStackTrace(this, this.constructor)
|
||||
}
|
||||
}
|
||||
|
||||
function initLiquidError (err, token) {
|
||||
initError.call(this)
|
||||
|
||||
this.input = token.input
|
||||
this.line = token.line
|
||||
this.file = token.file
|
||||
|
||||
const context = mkContext(token.input, token.line)
|
||||
this.message = mkMessage(err.message, token)
|
||||
this.stack = context +
|
||||
'\n' + (this.stack || this.message) +
|
||||
(err.stack ? '\nFrom ' + err.stack : '')
|
||||
}
|
||||
|
||||
export function TokenizationError (message, token) {
|
||||
initLiquidError.call(this, { message: message }, token)
|
||||
}
|
||||
TokenizationError.prototype = _.create(Error.prototype)
|
||||
TokenizationError.prototype.constructor = TokenizationError
|
||||
|
||||
export function ParseError (e, token) {
|
||||
_.assign(this, e)
|
||||
this.originalError = e
|
||||
|
||||
initLiquidError.call(this, e, token)
|
||||
}
|
||||
ParseError.prototype = _.create(Error.prototype)
|
||||
ParseError.prototype.constructor = ParseError
|
||||
|
||||
export function RenderError (e, tpl) {
|
||||
// return the original render error
|
||||
if (e instanceof RenderError) {
|
||||
return e
|
||||
}
|
||||
_.assign(this, e)
|
||||
this.originalError = e
|
||||
|
||||
initLiquidError.call(this, e, tpl.token)
|
||||
}
|
||||
RenderError.prototype = _.create(Error.prototype)
|
||||
RenderError.prototype.constructor = RenderError
|
||||
|
||||
export function RenderBreakError (message) {
|
||||
initError.call(this)
|
||||
this.message = message + ''
|
||||
}
|
||||
RenderBreakError.prototype = _.create(Error.prototype)
|
||||
RenderBreakError.prototype.constructor = RenderBreakError
|
||||
|
||||
export function AssertionError (message) {
|
||||
initError.call(this)
|
||||
this.message = message + ''
|
||||
}
|
||||
AssertionError.prototype = _.create(Error.prototype)
|
||||
AssertionError.prototype.constructor = AssertionError
|
||||
|
||||
function mkContext (input, line) {
|
||||
const lines = input.split('\n')
|
||||
const begin = Math.max(line - 2, 1)
|
||||
const end = Math.min(line + 3, lines.length)
|
||||
|
||||
const context = _
|
||||
.range(begin, end + 1)
|
||||
.map(l => [
|
||||
(l === line) ? '>> ' : ' ',
|
||||
align(l, end),
|
||||
'| ',
|
||||
lines[l - 1]
|
||||
].join(''))
|
||||
.join('\n')
|
||||
|
||||
return context
|
||||
}
|
||||
|
||||
function align (n, max) {
|
||||
const length = (max + '').length
|
||||
const str = n + ''
|
||||
const blank = Array(length - str.length).join(' ')
|
||||
return blank + str
|
||||
}
|
||||
|
||||
function mkMessage (msg, token) {
|
||||
msg = msg || ''
|
||||
if (token.file) {
|
||||
msg += ', file:' + token.file
|
||||
}
|
||||
if (token.line) {
|
||||
msg += ', line:' + token.line
|
||||
}
|
||||
return msg
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
import * as _ from './underscore'
|
||||
|
||||
function captureStack () {
|
||||
if (Error.captureStackTrace) {
|
||||
Error.captureStackTrace(this, this.constructor)
|
||||
}
|
||||
}
|
||||
|
||||
abstract class LiquidError {
|
||||
input: string
|
||||
line: string
|
||||
file: string
|
||||
message: string
|
||||
name: string
|
||||
stack: string
|
||||
token: any
|
||||
originalError: any
|
||||
constructor(err, token) {
|
||||
this.input = token.input
|
||||
this.line = token.line
|
||||
this.file = token.file
|
||||
this.originalError = err
|
||||
this.token = token
|
||||
}
|
||||
captureStackTrace(obj) {
|
||||
this.name = obj.constructor.name
|
||||
|
||||
captureStack.call(obj)
|
||||
const err = this.originalError
|
||||
const context = mkContext(this.input, this.line)
|
||||
this.message = mkMessage(err.message, this.token)
|
||||
this.stack = context +
|
||||
'\n' + (this.stack || this.message) +
|
||||
(err.stack ? '\nFrom ' + err.stack : '')
|
||||
}
|
||||
}
|
||||
|
||||
export class TokenizationError extends LiquidError {
|
||||
constructor(message, token) {
|
||||
super({message}, token)
|
||||
super.captureStackTrace(this)
|
||||
}
|
||||
}
|
||||
TokenizationError.prototype = _.create(Error.prototype)
|
||||
TokenizationError.prototype.constructor = TokenizationError
|
||||
|
||||
export class ParseError extends LiquidError {
|
||||
constructor(err, token) {
|
||||
super(err, token)
|
||||
_.assign(this, err)
|
||||
super.captureStackTrace(this)
|
||||
}
|
||||
}
|
||||
ParseError.prototype = _.create(Error.prototype)
|
||||
ParseError.prototype.constructor = ParseError
|
||||
|
||||
export class RenderError extends LiquidError {
|
||||
constructor(err, tpl) {
|
||||
super(err, tpl.token)
|
||||
_.assign(this, err)
|
||||
super.captureStackTrace(this)
|
||||
}
|
||||
}
|
||||
RenderError.prototype = _.create(Error.prototype)
|
||||
RenderError.prototype.constructor = RenderError
|
||||
|
||||
export class RenderBreakError {
|
||||
message: string
|
||||
constructor (message) {
|
||||
captureStack.call(this)
|
||||
this.message = message + ''
|
||||
}
|
||||
}
|
||||
RenderBreakError.prototype = _.create(Error.prototype)
|
||||
RenderBreakError.prototype.constructor = RenderBreakError
|
||||
|
||||
export class AssertionError {
|
||||
message: string
|
||||
constructor (message) {
|
||||
captureStack.call(this)
|
||||
this.message = message + ''
|
||||
}
|
||||
}
|
||||
AssertionError.prototype = _.create(Error.prototype)
|
||||
AssertionError.prototype.constructor = AssertionError
|
||||
|
||||
function mkContext (input, targetLine) {
|
||||
const lines = input.split('\n')
|
||||
const begin = Math.max(targetLine - 2, 1)
|
||||
const end = Math.min(targetLine + 3, lines.length)
|
||||
|
||||
const context = _
|
||||
.range(begin, end + 1)
|
||||
.map(lineNumber => {
|
||||
const indicator = (lineNumber === targetLine) ? '>> ' : ' '
|
||||
const num = padStart(String(end).length, lineNumber)
|
||||
const text = lines[lineNumber - 1]
|
||||
return `${indicator}${num}| ${text}`
|
||||
})
|
||||
.join('\n')
|
||||
|
||||
return context
|
||||
}
|
||||
|
||||
function mkMessage (msg, token) {
|
||||
msg = msg || ''
|
||||
if (token.file) {
|
||||
msg += ', file:' + token.file
|
||||
}
|
||||
if (token.line) {
|
||||
msg += ', line:' + token.line
|
||||
}
|
||||
return msg
|
||||
}
|
||||
|
||||
function padStart (length, str) {
|
||||
str = String(str)
|
||||
const blank = Array(length - str.length).join(' ')
|
||||
return blank + str
|
||||
}
|
||||
@@ -15,9 +15,9 @@ export function isFunction (value) {
|
||||
}
|
||||
|
||||
export function promisify (fn) {
|
||||
return function () {
|
||||
return function (...args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
fn(...arguments, (err, result) => {
|
||||
fn(...args, (err, result) => {
|
||||
err ? reject(err) : resolve(result)
|
||||
})
|
||||
})
|
||||
@@ -96,11 +96,14 @@ export function forOwn (object, iteratee) {
|
||||
* @param {...Object} sources The source objects.
|
||||
* @return {Object} Returns object.
|
||||
*/
|
||||
export function assign (object) {
|
||||
object = isObject(object) ? object : {}
|
||||
const srcs = Array.prototype.slice.call(arguments, 1)
|
||||
srcs.forEach((src) => Object.assign(object, src))
|
||||
return object
|
||||
export function assign (obj, ...srcs) {
|
||||
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]
|
||||
}
|
||||
|
||||
export function last (arr) {
|
||||
@@ -139,7 +142,7 @@ export function isObject (value) {
|
||||
* Note that ranges that stop before they start are considered to be zero-length instead of
|
||||
* negative — if you'd like a negative range, use a negative step.
|
||||
*/
|
||||
export function range (start, stop, step) {
|
||||
export function range (start: number, stop: number, step?: number) {
|
||||
if (arguments.length === 1) {
|
||||
stop = start
|
||||
start = 0
|
||||
@@ -1,4 +1,4 @@
|
||||
import { assign } from './util/underscore.js'
|
||||
import { assign } from './util/underscore'
|
||||
|
||||
export default function whiteSpaceCtrl (tokens, options) {
|
||||
options = assign({ greedy: true }, options)
|
||||
|
||||
Reference in New Issue
Block a user