Skip to content
This repository was archived by the owner on Sep 13, 2023. It is now read-only.

Commit dcfa75d

Browse files
committed
BREAKING CHANGE, allowRequire: true is necc to use require in template
1 parent 969310f commit dcfa75d

7 files changed

Lines changed: 94 additions & 52 deletions

File tree

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
# Changelog
22

3+
## v0.1.10
4+
- **BREAKING CHANGE**, **SECURITY UPDATE**
5+
To use `require()` in the template, user will have to pass `allowRequire: true` in option. This option is by default set to false.
6+
```js
7+
const newHTMLTemplate = abellRenderer.render(
8+
myAbellTemplate,
9+
mySandbox,
10+
{allowRequire: true}
11+
);
12+
```
13+
314
## v0.1.9
415
- Fix to recursively find and create nested `.abell` files
516

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ You can use JavaScript Array methods to loop over array. Other JavaScript Array
9292
<h2>${user.name}</h2>
9393
<span>Age: ${user.age}</span>
9494
</div>
95-
`)
95+
`).join('')
9696
}}
9797
</main>
9898

@@ -113,6 +113,8 @@ Ouputs:
113113
```
114114
115115
### ⤵️ Import JS/JSON/NPM Modules
116+
*NOTE: Starting v0.1.10 require() can only be used when `allowRequire: true` is passed from options or `--allow-require` flag is passed in CLI*
117+
116118
With Abell you can import your Native NodeJS Modules, NPM Modules, JS Files (should export data), and JSON Files with `require()`
117119
118120
@@ -196,6 +198,7 @@ Outputs:
196198
`template`: Abell template in String
197199
`sandbox`: Object over which the scripts execute, Can define variables and inject them into script.
198200
`options.basePath`: basePath which is prefixed on `require()` paths in abellTemplate.
201+
`options.allowRequire`: Passing `true` allows using `require()` in templates. Default is `false`.
199202

200203

201204
## 🤗 Contributing

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "abell-renderer",
3-
"version": "0.1.9",
3+
"version": "0.1.10",
44
"description": "A wrapper arround Mustache that adds some additional features and some syntatic sugar required for abell",
55
"main": "dist/index.js",
66
"bin": {
@@ -14,8 +14,8 @@
1414
"test": "mocha --recursive \"./tests/*.js\"",
1515
"build": "node build/build.main.js",
1616
"dev": "node src/example/example.js",
17-
"dev:cli": "node src/bin.js build --input src/example/templates/cli_example.abell --output src/example/out/cli_example.html",
18-
"dev:cli-dir": "node src/bin.js build --input src/example/templates/loop_example --output src/example/out/loop_example",
17+
"dev:cli": "node src/bin.js build --input src/example/templates/cli_example.abell --output src/example/out/cli_example.html --allow-require",
18+
"dev:cli-dir": "node src/bin.js build --input src/example/templates/loop_example --output src/example/out/loop_example --allow-require",
1919
"cli": "npm run dev:cli",
2020
"eslint": "eslint .",
2121
"prepublishOnly": "npm run eslint && npm test && npm run build"

src/bin.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,15 @@ function build() {
7070
const outputPath = (indexOfOutput > -1)
7171
? path.join(cwd, args[indexOfOutput + 1])
7272
: inputPath.replace('.abell', '.html'); // file name of input
73+
const allowRequire = args.includes('--allow-require');
7374

7475
const basePath = path.dirname(inputPath);
7576

7677
console.log(`${ green('-') } Rendering started ✨ \n`);
7778

7879
if (!fs.statSync(inputPath).isDirectory()) {
7980
// If input is a file
80-
generateHTMLFromAbell(inputPath, outputPath, {basePath});
81+
generateHTMLFromAbell(inputPath, outputPath, {basePath, allowRequire});
8182
} else {
8283
// If input is a directory
8384
const relativePaths = recursiveFind(inputPath, '.abell')
@@ -87,7 +88,7 @@ function build() {
8788
generateHTMLFromAbell(
8889
path.join(inputPath, filepath),
8990
path.join(outputPath, filepath.replace('.abell', '.html')),
90-
{basePath: path.dirname(path.join(inputPath, filepath))}
91+
{basePath: path.dirname(path.join(inputPath, filepath)), allowRequire}
9192
);
9293
}
9394
}

src/index.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ const execRegexOnAll = (regex, template) => {
4242
* @param {object} options additional options e.g ({basePath})
4343
* @return {string} htmlTemplate
4444
*/
45-
function render(abellTemplate, sandbox, options = {basePath: ''}) {
45+
function render(abellTemplate, sandbox, options = {basePath: '', allowRequire: false}) {
4646
// Finds all the JS expressions to be executed.
4747
const {matches, input} = execRegexOnAll(/\\?{{(.+?)}}/gs, abellTemplate);
4848
let renderedHTML = '';
@@ -54,6 +54,9 @@ function render(abellTemplate, sandbox, options = {basePath: ''}) {
5454
// Ignore the match that starts with slash '\' and return the same value without slash
5555
value = match[0].slice(1);
5656
} else if (match[1].includes('require(')) {
57+
if (!options.allowRequire) {
58+
throw new Error('require() is not allowed in the script');
59+
}
5760
// the js block is trying to require (e.g const module1 = require('module1'))
5861
const lines = match[1]
5962
.trim()

tests/execute.spec.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
const path = require('path');
2+
const expect = require('chai').expect;
3+
4+
const {
5+
execute,
6+
executeRequireStatement
7+
} = require('../src/execute.js');
8+
9+
10+
describe('execute() - Executes JavaScript passed to it as string', () => {
11+
it('should output added value when addition is performed on two values', () => {
12+
expect(
13+
execute('24 + 12', {}).value
14+
).to.equal(36);
15+
});
16+
17+
it('should update value of a to new value', () => {
18+
expect(
19+
execute('a = 22 + 22', {a: 4}).sandbox.a
20+
).to.equal(44);
21+
});
22+
23+
it('should not update value that is inside string', () => {
24+
expect(
25+
execute('(() => \'a = b\')()').value
26+
).to.equal('a = b');
27+
});
28+
});
29+
30+
31+
describe('executeRequireStatement() - executes the code with require() in its string', () => {
32+
it('should add path native object when required', () => {
33+
expect(
34+
executeRequireStatement('const path = require(\'path\')')
35+
.path.join('test', 'path')
36+
).to.equal(path.join('test', 'path'));
37+
});
38+
39+
it('should handle the case of require(\'module\').property', () => {
40+
expect(
41+
executeRequireStatement('const testPath = require(\'path\').join(\'test\',\'path\')')
42+
.testPath
43+
).to.equal(path.join('test', 'path'));
44+
});
45+
});

tests/index.spec.js

Lines changed: 24 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,6 @@ const fs = require('fs');
22
const path = require('path');
33
const expect = require('chai').expect;
44

5-
const {
6-
execute,
7-
executeRequireStatement
8-
} = require('../src/execute.js');
9-
105
const abellRenderer = require('../src/index.js');
116

127
describe('render() - renders abellTemplate into HTML Text', () => {
@@ -33,7 +28,10 @@ describe('render() - renders abellTemplate into HTML Text', () => {
3328
.render(
3429
abellTemplate,
3530
sampleSandbox,
36-
{basePath: path.join(__dirname, 'resources')}
31+
{
32+
basePath: path.join(__dirname, 'resources'),
33+
allowRequire: true
34+
}
3735
)
3836
).to.equal(htmlTemplate);
3937
});
@@ -79,11 +77,30 @@ describe('render() - renders abellTemplate into HTML Text', () => {
7977
expect(
8078
abellRenderer.render(
8179
abellTemplate,
82-
{}
80+
{},
81+
{allowRequire: true}
8382
).trim()
8483
).to.equal('<div>8 hi/hello hi/hello</div>');
8584
});
8685

86+
it('should throw an error if require() is used without allowRequire: true option', () => {
87+
const abellTemplate = `
88+
{{
89+
const path = require('path');
90+
const hiHelloPath = require('path').join('hi', 'hello');
91+
}}
92+
<div>{{ path.join('hi', 'hello') }} {{ hiHelloPath }}</div>
93+
`;
94+
95+
expect(
96+
() =>
97+
abellRenderer.render(
98+
abellTemplate,
99+
{},
100+
)
101+
).to.throw('require() is not allowed in the script');
102+
});
103+
87104
it('should not throw error and return same value if blank brackets passed', () => {
88105
expect(
89106
abellRenderer.render(
@@ -102,41 +119,3 @@ describe('render() - renders abellTemplate into HTML Text', () => {
102119
).to.equal('{{ This is ignored }}');
103120
});
104121
});
105-
106-
107-
describe('execute() - Executes JavaScript passed to it as string', () => {
108-
it('should output added value when addition is performed on two values', () => {
109-
expect(
110-
execute('24 + 12', {}).value
111-
).to.equal(36);
112-
});
113-
114-
it('should update value of a to new value', () => {
115-
expect(
116-
execute('a = 22 + 22', {a: 4}).sandbox.a
117-
).to.equal(44);
118-
});
119-
120-
it('should not update value that is inside string', () => {
121-
expect(
122-
execute('(() => \'a = b\')()').value
123-
).to.equal('a = b');
124-
});
125-
});
126-
127-
128-
describe('executeRequireStatement() - executes the code with require() in its string', () => {
129-
it('should add path native object when required', () => {
130-
expect(
131-
executeRequireStatement('const path = require(\'path\')')
132-
.path.join('test', 'path')
133-
).to.equal(path.join('test', 'path'));
134-
});
135-
136-
it('should handle the case of require(\'module\').property', () => {
137-
expect(
138-
executeRequireStatement('const testPath = require(\'path\').join(\'test\',\'path\')')
139-
.testPath
140-
).to.equal(path.join('test', 'path'));
141-
});
142-
});

0 commit comments

Comments
 (0)