Skip to content

Commit

Permalink
Merge pull request #205 from jmclean-cnexus/master
Browse files Browse the repository at this point in the history
  • Loading branch information
nebrelbug committed Sep 11, 2020
2 parents 4fd4a57 + 93d2997 commit 81c09e9
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 78 deletions.
5 changes: 3 additions & 2 deletions .all-contributorsrc
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,12 @@
},
{
"login": "jmclean-cnexus",
"name": "jmclean-cnexus",
"name": "Jon McLean",
"avatar_url": "https://avatars3.githubusercontent.com/u/64215359?v=4",
"profile": "https://github.com/jmclean-cnexus",
"contributions": [
"code"
"code",
"test"
]
}
],
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ compiled
.rpt2_cache
docs
build
package-lock.json
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ Made with ❤ by [@nebrelbug](https://github.com/nebrelbug) and all these wonder
<td align="center"><a href="https://github.com/clitetailor"><img src="https://avatars1.githubusercontent.com/u/16368559?v=4" width="100px;" alt=""/><br /><sub><b>Clite Tailor</b></sub></a><br /><a href="#ideas-clitetailor" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/squirrellyjs/squirrelly/commits?author=clitetailor" title="Code">💻</a></td>
<td align="center"><a href="https://twitter.com/ioan_chiriac"><img src="https://avatars2.githubusercontent.com/u/173203?v=4" width="100px;" alt=""/><br /><sub><b>Ioan CHIRIAC</b></sub></a><br /><a href="https://github.com/squirrellyjs/squirrelly/commits?author=ichiriac" title="Code">💻</a> <a href="#ideas-ichiriac" title="Ideas, Planning, & Feedback">🤔</a></td>
<td align="center"><a href="https://futurelucas4502.co.uk"><img src="https://avatars1.githubusercontent.com/u/48055553?v=4" width="100px;" alt=""/><br /><sub><b>Lucas Wilson</b></sub></a><br /><a href="https://github.com/squirrellyjs/squirrelly/issues?q=author%3Afuturelucas4502" title="Bug reports">🐛</a> <a href="https://github.com/squirrellyjs/squirrelly/commits?author=futurelucas4502" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/jmclean-cnexus"><img src="https://avatars3.githubusercontent.com/u/64215359?v=4" width="100px;" alt=""/><br /><sub><b>jmclean-cnexus</b></sub></a><br /><a href="https://github.com/squirrellyjs/squirrelly/commits?author=jmclean-cnexus" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/jmclean-cnexus"><img src="https://avatars3.githubusercontent.com/u/64215359?v=4" width="100px;" alt=""/><br /><sub><b>Jon McLean</b></sub></a><br /><a href="https://github.com/squirrellyjs/squirrelly/commits?author=jmclean-cnexus" title="Code">💻</a> <a href="https://github.com/squirrellyjs/squirrelly/commits?author=jmclean-cnexus" title="Tests">⚠️</a></td>
</tr>
</table>

Expand Down
76 changes: 76 additions & 0 deletions src/container-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import SqrlErr from './err'

export function errWithBlocksOrFilters(
name: string,
blocks: Array<any> | false, // false means don't check
filters: Array<any> | false,
native?: boolean
) {
if (blocks && blocks.length > 0) {
throw SqrlErr((native ? 'Native' : '') + "Helper '" + name + "' doesn't accept blocks")
}
if (filters && filters.length > 0) {
throw SqrlErr((native ? 'Native' : '') + "Helper '" + name + "' doesn't accept filters")
}
}

/* ASYNC LOOP FNs */
export function asyncArrLoop(arr: Array<any>, index: number, fn: Function, res: string, cb: Function) {
fn(arr[index], index).then(function (val: string) {
res += val
if (index === arr.length - 1) {
cb(res)
} else {
asyncArrLoop(arr, index + 1, fn, res, cb)
}
})
}

export function asyncObjLoop(
obj: { [index: string]: any },
keys: Array<string>,
index: number,
fn: Function,
res: string,
cb: Function
) {
fn(keys[index], obj[keys[index]]).then(function (val: string) {
res += val
if (index === keys.length - 1) {
cb(res)
} else {
asyncObjLoop(obj, keys, index + 1, fn, res, cb)
}
})
}

export function replaceChar(s: string): string {
const escMap: EscapeMap = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#39;'
}
return escMap[s]
}

export function XMLEscape(str: unknown) {
// To deal with XSS. Based on Escape implementations of Mustache.JS and Marko, then customized.
var newStr = String(str)
if (/[&<>"']/.test(newStr)) {
return newStr.replace(/[&<>"']/g, replaceChar)
} else {
return newStr
}
}

/* INTERFACES */
interface EscapeMap {
'&': '&amp;'
'<': '&lt;'
'>': '&gt;'
'"': '&quot;'
"'": '&#39;'
[index: string]: string
}
76 changes: 1 addition & 75 deletions src/containers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Cacher } from './storage'
import SqrlErr from './err'
import { compileScope, compileScopeIntoFunction } from './compile-string'
import { hasOwnProp } from './utils'
import { errWithBlocksOrFilters, asyncArrLoop, asyncObjLoop, XMLEscape } from './container-utils'

/* TYPES */

Expand All @@ -27,15 +28,6 @@ export type HelperFunction = (

export type FilterFunction = (...args: any[]) => any | Promise<any>

interface EscapeMap {
'&': '&amp;'
'<': '&lt;'
'>': '&gt;'
'"': '&quot;'
"'": '&#39;'
[index: string]: string
}

interface IncludeHelperContent extends HelperContent {
params: [string, object]
}
Expand All @@ -48,50 +40,6 @@ interface GenericData {

var templates = new Cacher<TemplateFunction>({})

function errWithBlocksOrFilters (
name: string,
blocks: Array<any> | false, // false means don't check
filters: Array<any> | false,
native?: boolean
) {
if (blocks && blocks.length > 0) {
throw SqrlErr((native ? 'Native' : '') + "Helper '" + name + "' doesn't accept blocks")
}
if (filters && filters.length > 0) {
throw SqrlErr((native ? 'Native' : '') + "Helper '" + name + "' doesn't accept filters")
}
}

/* ASYNC LOOP FNs */
function asyncArrLoop (arr: Array<any>, index: number, fn: Function, res: string, cb: Function) {
fn(arr[index], index).then(function (val: string) {
res += val
if (index === arr.length - 1) {
cb(res)
} else {
asyncArrLoop(arr, index + 1, fn, res, cb)
}
})
}

function asyncObjLoop (
obj: { [index: string]: any },
keys: Array<string>,
index: number,
fn: Function,
res: string,
cb: Function
) {
fn(keys[index], obj[keys[index]]).then(function (val: string) {
res += val
if (index === keys.length - 1) {
cb(res)
} else {
asyncObjLoop(obj, keys, index + 1, fn, res, cb)
}
})
}

/* ASYNC LOOP FNs */

var helpers = new Cacher<HelperFunction>({
Expand Down Expand Up @@ -222,28 +170,6 @@ var nativeHelpers = new Cacher<Function>({
}
})

var escMap: EscapeMap = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#39;'
}

function replaceChar (s: string): string {
return escMap[s]
}

function XMLEscape (str: unknown) {
// To deal with XSS. Based on Escape implementations of Mustache.JS and Marko, then customized.
var newStr = String(str)
if (/[&<>"']/.test(newStr)) {
return newStr.replace(/[&<>"']/g, replaceChar)
} else {
return newStr
}
}

var filters = new Cacher<FilterFunction>({ e: XMLEscape })

export { templates, helpers, nativeHelpers, filters }
50 changes: 50 additions & 0 deletions test/container-utils.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import * as utils from '../src/container-utils'
import SqrlErr from '../src/err'

describe('replaceChar', () => {
it('should replace & with &amp;', () => {
let res = utils.replaceChar("&")
expect(res).toEqual("&amp;")
})
it('should replace < with &lt;', () => {
let res = utils.replaceChar("<")
expect(res).toEqual("&lt;")
})
it('should replace > with &gt;', () => {
let res = utils.replaceChar(">")
expect(res).toEqual("&gt;")
})
it('should replace " with &quot;', () => {
let res = utils.replaceChar("\"")
expect(res).toEqual("&quot;")
})
it('should replace \' with &#39;', () => {
let res = utils.replaceChar("'")
expect(res).toEqual("&#39;")
})
})

describe('errWithBlocksOrFilters', () => {
it('should throw error if array of blosk is supplied', (done) => {
try {
utils.errWithBlocksOrFilters("testHelper", ["block"], false)
done("An error should have thrown")
} catch (e) {
expect(e).toBeInstanceOf(SqrlErr)
expect(e.message).toEqual("Helper 'testHelper' doesn't accept blocks")
done()
}
})

it('should throw error if array of filters is supplied', (done) => {
try {
utils.errWithBlocksOrFilters("testHelper",false , ["filter"])
done("An error should have thrown")
} catch (e) {
expect(e).toBeInstanceOf(SqrlErr)
expect(e.message).toEqual("Helper 'testHelper' doesn't accept filters")
done()
}
})

})

0 comments on commit 81c09e9

Please sign in to comment.