Skip to content

Commit

Permalink
move the default values to a separate file. Fix #85
Browse files Browse the repository at this point in the history
  • Loading branch information
alexewerlof committed Aug 17, 2020
1 parent 3264a85 commit 41fa81c
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 13 deletions.
20 changes: 20 additions & 0 deletions src/defaults.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* The default value for the `maxPathLen` option
*/
export const MAX_PATH_LEN = 1000

/**
* The default value for the `maxRefDepth` option
*/
export const MAX_REF_DEPTH = 10

/**
* The default value for the `tags` option
*/
export const TAGS = Object.freeze(['{{', '}}'])

/**
* @internal
* The size of the tokenize cache
*/
export const CACHE_SIZE = 100
3 changes: 2 additions & 1 deletion src/get.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { tokenizePath, Ref, TokenizePathOptions } from './tokenize'
import { isObj, isProp, isNum, isArr } from './utils'
import { MAX_REF_DEPTH } from './defaults'

export interface Scope {
[key: string]: Scope | any
Expand Down Expand Up @@ -63,7 +64,7 @@ export function refGet(ref: Ref, scope: Scope, options: GetOptions = {}): any {
throw new TypeError(`Expected an array ref. Got ${ref}`)
}

const { maxRefDepth = 10 } = options
const { maxRefDepth = MAX_REF_DEPTH } = options
if (!isNum(maxRefDepth) || maxRefDepth <= 0) {
throw new RangeError(`Expected a positive number for maxRefDepth. Got ${maxRefDepth}`)
}
Expand Down
5 changes: 3 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export * from './compile'
export * from './defaults'
export * from './get'
export * from './parse'
export * from './tokenize'
export * from './compile'
export * from './render'
export * from './tokenize'
export * from './transform'
25 changes: 19 additions & 6 deletions src/parse.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { isStr, isArr, isObj, isNum } from './utils'
import { TAGS, MAX_PATH_LEN } from './defaults'

/**
* The result of the parsing the template
Expand All @@ -21,20 +22,32 @@ export interface ParsedTemplate<T> {
}

/**
* The options that goes to the template parsing algorithm
* The tags are an array of exactly two strings (that should be different and mutually exclusive)
*/
export type Tags = [string, string]

/**
* The options for the [[parseTemplate]] function
*/
export interface ParseTemplateOptions {
/**
* Maximum allowed path. Set this to a safe value to prevent a bad template from blocking
* the template parsing unnecessarily
* Maximum allowed length for the path string.
* Set this to a safe value to throw for paths that are longer than expected.
*
* @default defaults.MAX_PATH_LEN
*
* @example `path = 'a.b'`, depth = 3
* @example `path = 'a.b.c'`, depth = 5
* @example `path = 'a['b'].c'`, depth = 8
*/
maxPathLen?: number
/**
* The string symbols that mark the opening and closing of a path in the template.
* It should be an array of exactly two distinct strings otherwise an error is thrown.
* It defaults to `['{{', '}}']`
*
* @default defaults.TAGS
*/
tags?: [string, string]
tags?: Tags
}

export function isParsedTemplate(x: unknown): x is ParsedTemplate<any> {
Expand Down Expand Up @@ -152,7 +165,7 @@ export function parseTemplate(
throw new TypeError(`Options should be an object. Got a ${typeof options}`)
}

const { tags = ['{{', '}}'], maxPathLen = 1000 } = options
const { tags = TAGS, maxPathLen = MAX_PATH_LEN } = options

if (!isArr(tags) || tags.length !== 2) {
throw TypeError(`tags should be an array of two elements. Got ${String(tags)}`)
Expand Down
15 changes: 11 additions & 4 deletions src/tokenize.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { isObj, isStr } from './utils'
import { MAX_REF_DEPTH, CACHE_SIZE } from './defaults'

/**
* The options for the [[tokenizePath]] function
Expand All @@ -9,7 +10,13 @@ export interface TokenizePathOptions {
* computation. Therefore you can set a value of how deep you are expecting a template to go and
* if the nesting is deeper than that, the computation stops with an error.
* This prevents a malicious or erroneous template with deep nesting to block the JavaScript event
* loop. The default is 10.
* loop.
*
* @default defaults.MAX_REF_DEPTH
*
* @example `path = 'a.b'`, depth = 2
* @example `path = 'a.b.c'`, depth = 3
* @example `path = 'a['b'].c'`, depth = 3
*/
readonly maxRefDepth?: number
}
Expand Down Expand Up @@ -66,7 +73,7 @@ export function tokenizePath(path: string, options: TokenizePathOptions = {}): R
throw new TypeError(`tokenizePath() expected an options object. Got ${options}`)
}

const { maxRefDepth = 10 } = options
const { maxRefDepth = MAX_REF_DEPTH } = options

const ref: Ref = []

Expand All @@ -91,7 +98,7 @@ export function tokenizePath(path: string, options: TokenizePathOptions = {}): R
ref.push((searchResult as RegExpWithNameGroup).groups.name)
if (ref.length > maxRefDepth) {
throw new RangeError(
`The reference depth for "${path}" exceeds the configured limit of ${maxRefDepth}`
`The reference depth for "${path}" exceeds the defaultsured limit of ${maxRefDepth}`
)
}

Expand All @@ -116,7 +123,7 @@ export function tokenizePath(path: string, options: TokenizePathOptions = {}): R
* time.
* If the cache is full, we start removing older paths one at a time.
*/
const cacheSize = 1000
const cacheSize = CACHE_SIZE

/**
* @internal
Expand Down

0 comments on commit 41fa81c

Please sign in to comment.