edgexpress 3.0.0 → 3.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/eslint.config.cjs +6 -0
- package/examples/index.js +41 -0
- package/examples/views/components/layout/main.edge +26 -0
- package/examples/views/components/modal.edge +27 -0
- package/examples/views/home.edge +84 -0
- package/examples/views/partials/button.edge +1 -0
- package/examples/views/partials/home-footer.edge +49 -0
- package/examples/views/partials/home-header.edge +61 -0
- package/examples/views/welcome.edge +22 -0
- package/index.d.ts +7 -0
- package/package.json +12 -4
- package/src/cache_manager.d.ts +28 -0
- package/src/cache_manager.js +58 -0
- package/src/compiler.d.ts +73 -0
- package/src/compiler.js +319 -0
- package/src/component/props.d.ts +53 -0
- package/src/component/props.js +110 -0
- package/src/edge/globals.d.ts +5 -0
- package/src/edge/globals.js +95 -0
- package/src/edge/main.d.ts +192 -0
- package/src/edge/main.js +334 -0
- package/src/edge/renderer.d.ts +44 -0
- package/src/edge/renderer.js +85 -0
- package/src/edge/stacks.d.ts +22 -0
- package/src/edge/stacks.js +98 -0
- package/src/loader.d.ts +138 -0
- package/src/loader.js +347 -0
- package/src/migrate/globals.d.ts +1 -0
- package/src/migrate/globals.js +100 -0
- package/src/migrate/plugin.d.ts +2 -0
- package/src/migrate/plugin.js +58 -0
- package/src/migrate/props.d.ts +66 -0
- package/src/migrate/props.js +129 -0
- package/src/migrate/tags/layout.d.ts +6 -0
- package/src/migrate/tags/layout.js +25 -0
- package/src/migrate/tags/main.d.ts +4 -0
- package/src/migrate/tags/main.js +19 -0
- package/src/migrate/tags/section.d.ts +6 -0
- package/src/migrate/tags/section.js +23 -0
- package/src/migrate/tags/set.d.ts +26 -0
- package/src/migrate/tags/set.js +104 -0
- package/src/migrate/tags/super.d.ts +9 -0
- package/src/migrate/tags/super.js +31 -0
- package/src/plugins/supercharged.d.ts +4 -0
- package/src/plugins/supercharged.js +88 -0
- package/src/processor.d.ts +42 -0
- package/src/processor.js +86 -0
- package/src/tags/assign.d.ts +5 -0
- package/src/tags/assign.js +42 -0
- package/src/tags/component.d.ts +6 -0
- package/src/tags/component.js +299 -0
- package/src/tags/debugger.d.ts +5 -0
- package/src/tags/debugger.js +26 -0
- package/src/tags/each.d.ts +20 -0
- package/src/tags/each.js +185 -0
- package/src/tags/else.d.ts +2 -0
- package/src/tags/else.js +22 -0
- package/src/tags/else_if.d.ts +7 -0
- package/src/tags/else_if.js +39 -0
- package/src/tags/eval.d.ts +7 -0
- package/src/tags/eval.js +30 -0
- package/src/tags/if.d.ts +5 -0
- package/src/tags/if.js +45 -0
- package/src/tags/include.d.ts +27 -0
- package/src/tags/include.js +78 -0
- package/src/tags/include_if.d.ts +10 -0
- package/src/tags/include_if.js +61 -0
- package/src/tags/inject.d.ts +6 -0
- package/src/tags/inject.js +40 -0
- package/src/tags/let.d.ts +6 -0
- package/src/tags/let.js +69 -0
- package/src/tags/main.d.ts +18 -0
- package/src/tags/main.js +47 -0
- package/src/tags/new_error.d.ts +6 -0
- package/src/tags/new_error.js +47 -0
- package/src/tags/push_once_to.d.ts +13 -0
- package/src/tags/push_once_to.js +65 -0
- package/src/tags/push_to.d.ts +7 -0
- package/src/tags/push_to.js +62 -0
- package/src/tags/slot.d.ts +6 -0
- package/src/tags/slot.js +29 -0
- package/src/tags/stack.d.ts +5 -0
- package/src/tags/stack.js +38 -0
- package/src/tags/unless.d.ts +12 -0
- package/src/tags/unless.js +52 -0
- package/src/template.d.ts +127 -0
- package/src/template.js +203 -0
- package/src/types.d.ts +144 -0
- package/src/types.js +10 -0
- package/src/utils.d.ts +96 -0
- package/src/utils.js +297 -0
- package/tsconfig.json +16 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* edge.js
|
|
4
|
+
*
|
|
5
|
+
* (c) Harminder Virk
|
|
6
|
+
*
|
|
7
|
+
* For the full copyright and license information, please view the LICENSE
|
|
8
|
+
* file that was distributed with this source code.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.pushOnceToTag = void 0;
|
|
12
|
+
const edge_error_1 = require("edge-error");
|
|
13
|
+
const edge_parser_1 = require("edge-parser");
|
|
14
|
+
const utils_js_1 = require("../utils.js");
|
|
15
|
+
/**
|
|
16
|
+
* Stack tag to define stack placeholders
|
|
17
|
+
*/
|
|
18
|
+
exports.pushOnceToTag = {
|
|
19
|
+
tagName: 'pushOnceTo',
|
|
20
|
+
block: true,
|
|
21
|
+
seekable: true,
|
|
22
|
+
noNewLine: true,
|
|
23
|
+
generateId() {
|
|
24
|
+
return `stack_${(0, utils_js_1.nanoid)()}`;
|
|
25
|
+
},
|
|
26
|
+
compile(parser, buffer, token) {
|
|
27
|
+
const parsed = parser.utils.transformAst(parser.utils.generateAST(token.properties.jsArg, token.loc, token.filename), token.filename, parser);
|
|
28
|
+
/**
|
|
29
|
+
* Disallow sequence expressions
|
|
30
|
+
*/
|
|
31
|
+
if (edge_parser_1.expressions.SequenceExpression.includes(parsed.type)) {
|
|
32
|
+
throw new edge_error_1.EdgeError(`"${token.properties.jsArg}" is not a valid argument type for the "@pushOnceTo" tag`, 'E_UNALLOWED_EXPRESSION', {
|
|
33
|
+
...parser.utils.getExpressionLoc(parsed),
|
|
34
|
+
filename: token.filename,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Each stack must be unique
|
|
39
|
+
*/
|
|
40
|
+
const stackId = this.generateId();
|
|
41
|
+
/**
|
|
42
|
+
* Create a custom buffer for the stack. Since we do not want to the write
|
|
43
|
+
* to the main buffer
|
|
44
|
+
*/
|
|
45
|
+
const stackBuffer = buffer.create(token.filename, { outputVar: stackId });
|
|
46
|
+
/**
|
|
47
|
+
* Process children
|
|
48
|
+
*/
|
|
49
|
+
for (let child of token.children) {
|
|
50
|
+
parser.processToken(child, stackBuffer);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Flush the stack buffer content to the main buffer
|
|
54
|
+
*/
|
|
55
|
+
buffer.writeStatement(stackBuffer
|
|
56
|
+
.disableFileAndLineVariables()
|
|
57
|
+
.disableReturnStatement()
|
|
58
|
+
.disableTryCatchBlock()
|
|
59
|
+
.flush(), token.filename, token.loc.start.line);
|
|
60
|
+
const { line, col } = token.loc.start;
|
|
61
|
+
const normalizedFileName = token.filename.replace(/\\|\//g, '_');
|
|
62
|
+
const sourceId = `${normalizedFileName}-${line}-${col}`;
|
|
63
|
+
buffer.writeExpression(`template.stacks.pushOnceTo(${parser.utils.stringify(parsed)}, '${sourceId}', ${stackId})`, token.filename, line);
|
|
64
|
+
},
|
|
65
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* edge.js
|
|
4
|
+
*
|
|
5
|
+
* (c) Harminder Virk
|
|
6
|
+
*
|
|
7
|
+
* For the full copyright and license information, please view the LICENSE
|
|
8
|
+
* file that was distributed with this source code.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.pushToTag = void 0;
|
|
12
|
+
const edge_error_1 = require("edge-error");
|
|
13
|
+
const edge_parser_1 = require("edge-parser");
|
|
14
|
+
const utils_js_1 = require("../utils.js");
|
|
15
|
+
/**
|
|
16
|
+
* Stack tag to define stack placeholders
|
|
17
|
+
*/
|
|
18
|
+
exports.pushToTag = {
|
|
19
|
+
tagName: 'pushTo',
|
|
20
|
+
block: true,
|
|
21
|
+
seekable: true,
|
|
22
|
+
noNewLine: true,
|
|
23
|
+
generateId() {
|
|
24
|
+
return `stack_${(0, utils_js_1.nanoid)()}`;
|
|
25
|
+
},
|
|
26
|
+
compile(parser, buffer, token) {
|
|
27
|
+
const parsed = parser.utils.transformAst(parser.utils.generateAST(token.properties.jsArg, token.loc, token.filename), token.filename, parser);
|
|
28
|
+
/**
|
|
29
|
+
* Disallow sequence expressions
|
|
30
|
+
*/
|
|
31
|
+
if (edge_parser_1.expressions.SequenceExpression.includes(parsed.type)) {
|
|
32
|
+
throw new edge_error_1.EdgeError(`"${token.properties.jsArg}" is not a valid argument type for the "@pushTo" tag`, 'E_UNALLOWED_EXPRESSION', {
|
|
33
|
+
...parser.utils.getExpressionLoc(parsed),
|
|
34
|
+
filename: token.filename,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Each stack must be unique
|
|
39
|
+
*/
|
|
40
|
+
const stackId = this.generateId();
|
|
41
|
+
/**
|
|
42
|
+
* Create a custom buffer for the stack. Since we do not want to the write
|
|
43
|
+
* to the main buffer
|
|
44
|
+
*/
|
|
45
|
+
const stackBuffer = buffer.create(token.filename, { outputVar: stackId });
|
|
46
|
+
/**
|
|
47
|
+
* Process children
|
|
48
|
+
*/
|
|
49
|
+
for (let child of token.children) {
|
|
50
|
+
parser.processToken(child, stackBuffer);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Flush the stack buffer content to the main buffer
|
|
54
|
+
*/
|
|
55
|
+
buffer.writeStatement(stackBuffer
|
|
56
|
+
.disableFileAndLineVariables()
|
|
57
|
+
.disableReturnStatement()
|
|
58
|
+
.disableTryCatchBlock()
|
|
59
|
+
.flush(), token.filename, token.loc.start.line);
|
|
60
|
+
buffer.writeExpression(`template.stacks.pushTo(${parser.utils.stringify(parsed)}, ${stackId})`, token.filename, token.loc.start.line);
|
|
61
|
+
},
|
|
62
|
+
};
|
package/src/tags/slot.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* edge.js
|
|
4
|
+
*
|
|
5
|
+
* (c) EdgeJS
|
|
6
|
+
*
|
|
7
|
+
* For the full copyright and license information, please view the LICENSE
|
|
8
|
+
* file that was distributed with this source code.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.slotTag = void 0;
|
|
12
|
+
const edge_error_1 = require("edge-error");
|
|
13
|
+
/**
|
|
14
|
+
* Slot tag is used to define the slots of a given component. Slots cannot be
|
|
15
|
+
* nested and must appear as top level children inside a component.
|
|
16
|
+
*/
|
|
17
|
+
exports.slotTag = {
|
|
18
|
+
block: true,
|
|
19
|
+
seekable: true,
|
|
20
|
+
tagName: 'slot',
|
|
21
|
+
noNewLine: true,
|
|
22
|
+
compile(_, __, token) {
|
|
23
|
+
throw new edge_error_1.EdgeError('@slot tag must appear as top level tag inside the @component tag', 'E_ORPHAN_SLOT_TAG', {
|
|
24
|
+
line: token.loc.start.line,
|
|
25
|
+
col: token.loc.start.col,
|
|
26
|
+
filename: token.filename,
|
|
27
|
+
});
|
|
28
|
+
},
|
|
29
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* edge.js
|
|
4
|
+
*
|
|
5
|
+
* (c) Harminder Virk
|
|
6
|
+
*
|
|
7
|
+
* For the full copyright and license information, please view the LICENSE
|
|
8
|
+
* file that was distributed with this source code.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.stackTag = void 0;
|
|
12
|
+
const edge_error_1 = require("edge-error");
|
|
13
|
+
const edge_parser_1 = require("edge-parser");
|
|
14
|
+
/**
|
|
15
|
+
* Stack tag to define stack placeholders
|
|
16
|
+
*/
|
|
17
|
+
exports.stackTag = {
|
|
18
|
+
tagName: 'stack',
|
|
19
|
+
block: false,
|
|
20
|
+
seekable: true,
|
|
21
|
+
noNewLine: false,
|
|
22
|
+
compile(parser, buffer, token) {
|
|
23
|
+
const parsed = parser.utils.transformAst(parser.utils.generateAST(token.properties.jsArg, token.loc, token.filename), token.filename, parser);
|
|
24
|
+
/**
|
|
25
|
+
* Disallow sequence expressions
|
|
26
|
+
*/
|
|
27
|
+
if (edge_parser_1.expressions.SequenceExpression.includes(parsed.type)) {
|
|
28
|
+
throw new edge_error_1.EdgeError(`"${token.properties.jsArg}" is not a valid argument type for the "@stack" tag`, 'E_UNALLOWED_EXPRESSION', {
|
|
29
|
+
...parser.utils.getExpressionLoc(parsed),
|
|
30
|
+
filename: token.filename,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Create stack
|
|
35
|
+
*/
|
|
36
|
+
buffer.outputExpression(`template.stacks.create(${parser.utils.stringify(parsed)})`, token.filename, token.loc.start.line, false);
|
|
37
|
+
},
|
|
38
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type TagContract } from '../types.js'
|
|
2
|
+
/**
|
|
3
|
+
* Inverse of the `if` condition. The term `unless` is more readable and logical
|
|
4
|
+
* vs using `@if(!expression)`.
|
|
5
|
+
*
|
|
6
|
+
* ```edge
|
|
7
|
+
* @unless(auth.user)
|
|
8
|
+
* <a href="/login"> Login </a>
|
|
9
|
+
* @endunless
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
export declare const unlessTag: TagContract
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* edge.js
|
|
4
|
+
*
|
|
5
|
+
* (c) EdgeJS
|
|
6
|
+
*
|
|
7
|
+
* For the full copyright and license information, please view the LICENSE
|
|
8
|
+
* file that was distributed with this source code.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.unlessTag = void 0;
|
|
12
|
+
const edge_parser_1 = require("edge-parser");
|
|
13
|
+
const utils_js_1 = require("../utils.js");
|
|
14
|
+
/**
|
|
15
|
+
* Inverse of the `if` condition. The term `unless` is more readable and logical
|
|
16
|
+
* vs using `@if(!expression)`.
|
|
17
|
+
*
|
|
18
|
+
* ```edge
|
|
19
|
+
* @unless(auth.user)
|
|
20
|
+
* <a href="/login"> Login </a>
|
|
21
|
+
* @endunless
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
exports.unlessTag = {
|
|
25
|
+
block: true,
|
|
26
|
+
seekable: true,
|
|
27
|
+
tagName: 'unless',
|
|
28
|
+
/**
|
|
29
|
+
* Compiles the if block node to a Javascript if statement
|
|
30
|
+
*/
|
|
31
|
+
compile(parser, buffer, token) {
|
|
32
|
+
const parsed = (0, utils_js_1.parseJsArg)(parser, token);
|
|
33
|
+
/**
|
|
34
|
+
* Disallow sequence expressions
|
|
35
|
+
*/
|
|
36
|
+
(0, utils_js_1.isNotSubsetOf)(parsed, [edge_parser_1.expressions.SequenceExpression], () => {
|
|
37
|
+
(0, utils_js_1.unallowedExpression)(`"${token.properties.jsArg}" is not a valid argument type for the @unless tag`, token.filename, parser.utils.getExpressionLoc(parsed));
|
|
38
|
+
});
|
|
39
|
+
/**
|
|
40
|
+
* Start if block
|
|
41
|
+
*/
|
|
42
|
+
buffer.writeStatement(`if (!${parser.utils.stringify(parsed)}) {`, token.filename, token.loc.start.line);
|
|
43
|
+
/**
|
|
44
|
+
* Process of all children recursively
|
|
45
|
+
*/
|
|
46
|
+
token.children.forEach((child) => parser.processToken(child, buffer));
|
|
47
|
+
/**
|
|
48
|
+
* Close if block
|
|
49
|
+
*/
|
|
50
|
+
buffer.writeStatement('}', token.filename, -1);
|
|
51
|
+
},
|
|
52
|
+
};
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import Macroable from '@poppinss/macroable'
|
|
2
|
+
import type Stacks from './edge/stacks.js'
|
|
3
|
+
import { type Compiler } from './compiler.js'
|
|
4
|
+
import { type Processor } from './processor.js'
|
|
5
|
+
import { type Props } from './migrate/props.js'
|
|
6
|
+
import type { CompiledTemplate } from './types.js'
|
|
7
|
+
import { type ComponentProps } from './component/props.js'
|
|
8
|
+
/**
|
|
9
|
+
* An instance of this class passed to the escape
|
|
10
|
+
* method ensures that underlying value is never
|
|
11
|
+
* escaped.
|
|
12
|
+
*/
|
|
13
|
+
declare class SafeValue {
|
|
14
|
+
value: any
|
|
15
|
+
constructor(value: any)
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Escapes a given string
|
|
19
|
+
*/
|
|
20
|
+
export declare function escape(input: any): string
|
|
21
|
+
/**
|
|
22
|
+
* Mark value as safe and not to be escaped
|
|
23
|
+
*/
|
|
24
|
+
export declare function htmlSafe(value: string): SafeValue
|
|
25
|
+
/**
|
|
26
|
+
* The template is used to compile and run templates. Also the instance
|
|
27
|
+
* of template is passed during runtime to render `dynamic partials`
|
|
28
|
+
* and `dynamic components`.
|
|
29
|
+
*/
|
|
30
|
+
export declare class Template extends Macroable {
|
|
31
|
+
#private
|
|
32
|
+
/**
|
|
33
|
+
* Template stacks holds a collection of placeholders
|
|
34
|
+
* and their content to be filled before returning
|
|
35
|
+
* the output.
|
|
36
|
+
*/
|
|
37
|
+
stacks: Stacks
|
|
38
|
+
constructor(compiler: Compiler, globals: any, locals: any, processor: Processor)
|
|
39
|
+
/**
|
|
40
|
+
* Render a partial
|
|
41
|
+
*
|
|
42
|
+
* ```js
|
|
43
|
+
* const partialFn = template.compilePartial('includes/user')
|
|
44
|
+
*
|
|
45
|
+
* // render and use output
|
|
46
|
+
* partialFn(template, state, ctx)
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
compilePartial(templatePath: string, ...localVariables: string[]): CompiledTemplate
|
|
50
|
+
/**
|
|
51
|
+
* Render a component
|
|
52
|
+
*
|
|
53
|
+
* ```js
|
|
54
|
+
* const componentFn = template.compileComponent('components/button')
|
|
55
|
+
*
|
|
56
|
+
* // render and use output
|
|
57
|
+
* componentFn(template, template.getComponentState(props, slots, caller), ctx)
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
compileComponent(templatePath: string): CompiledTemplate
|
|
61
|
+
/**
|
|
62
|
+
* Returns the isolated state for a given component
|
|
63
|
+
*/
|
|
64
|
+
getComponentState(
|
|
65
|
+
props: {
|
|
66
|
+
[key: string]: any
|
|
67
|
+
},
|
|
68
|
+
slots: {
|
|
69
|
+
[key: string]: any
|
|
70
|
+
},
|
|
71
|
+
caller: {
|
|
72
|
+
filename: string
|
|
73
|
+
line: number
|
|
74
|
+
col: number
|
|
75
|
+
}
|
|
76
|
+
): {
|
|
77
|
+
$slots: {
|
|
78
|
+
[key: string]: any
|
|
79
|
+
}
|
|
80
|
+
$caller: {
|
|
81
|
+
filename: string
|
|
82
|
+
line: number
|
|
83
|
+
col: number
|
|
84
|
+
}
|
|
85
|
+
$props: ComponentProps | Props
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Render a template with it's state.
|
|
89
|
+
*
|
|
90
|
+
* ```js
|
|
91
|
+
* template.render('welcome', { key: 'value' })
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
render<T extends Promise<string> | string>(template: string, state: any): T
|
|
95
|
+
/**
|
|
96
|
+
* Render template from a raw string
|
|
97
|
+
*
|
|
98
|
+
* ```js
|
|
99
|
+
* template.renderRaw('Hello {{ username }}', { username: 'virk' })
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
renderRaw<T extends Promise<string> | string>(
|
|
103
|
+
contents: string,
|
|
104
|
+
state: any,
|
|
105
|
+
templatePath?: string
|
|
106
|
+
): T
|
|
107
|
+
/**
|
|
108
|
+
* Escapes the value to be HTML safe. Only strings are escaped
|
|
109
|
+
* and rest all values will be returned as it is.
|
|
110
|
+
*/
|
|
111
|
+
escape(input: any): string
|
|
112
|
+
/**
|
|
113
|
+
* Creates an instance of the EdgeError
|
|
114
|
+
*/
|
|
115
|
+
createError(errorMessage: string, filename: string, lineNumber: number, column: number): any
|
|
116
|
+
/**
|
|
117
|
+
* Throws EdgeError. Use "createError" to create a new
|
|
118
|
+
* error instance
|
|
119
|
+
*/
|
|
120
|
+
newError(errorMessage: string, filename: string, lineNumber: number, column: number): void
|
|
121
|
+
/**
|
|
122
|
+
* Rethrows the runtime exception by re-constructing the error message
|
|
123
|
+
* to point back to the original filename
|
|
124
|
+
*/
|
|
125
|
+
reThrow(error: any, filename: string, lineNumber: number): never
|
|
126
|
+
}
|
|
127
|
+
export {}
|
package/src/template.js
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* edge.js
|
|
4
|
+
*
|
|
5
|
+
* (c) EdgeJS
|
|
6
|
+
*
|
|
7
|
+
* For the full copyright and license information, please view the LICENSE
|
|
8
|
+
* file that was distributed with this source code.
|
|
9
|
+
*/
|
|
10
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
11
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.Template = void 0;
|
|
15
|
+
exports.escape = escape;
|
|
16
|
+
exports.htmlSafe = htmlSafe;
|
|
17
|
+
const he_1 = __importDefault(require("he"));
|
|
18
|
+
const edge_error_1 = require("edge-error");
|
|
19
|
+
const lodash_1 = __importDefault(require("@poppinss/utils/lodash"));
|
|
20
|
+
const macroable_1 = __importDefault(require("@poppinss/macroable"));
|
|
21
|
+
const stacks_js_1 = __importDefault(require("./edge/stacks.js"));
|
|
22
|
+
const props_js_1 = require("./migrate/props.js");
|
|
23
|
+
const props_js_2 = require("./component/props.js");
|
|
24
|
+
/**
|
|
25
|
+
* An instance of this class passed to the escape
|
|
26
|
+
* method ensures that underlying value is never
|
|
27
|
+
* escaped.
|
|
28
|
+
*/
|
|
29
|
+
class SafeValue {
|
|
30
|
+
value;
|
|
31
|
+
constructor(value) {
|
|
32
|
+
this.value = value;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Escapes a given string
|
|
37
|
+
*/
|
|
38
|
+
function escape(input) {
|
|
39
|
+
return input instanceof SafeValue ? input.value : he_1.default.escape(String(input));
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Mark value as safe and not to be escaped
|
|
43
|
+
*/
|
|
44
|
+
function htmlSafe(value) {
|
|
45
|
+
return new SafeValue(value);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The template is used to compile and run templates. Also the instance
|
|
49
|
+
* of template is passed during runtime to render `dynamic partials`
|
|
50
|
+
* and `dynamic components`.
|
|
51
|
+
*/
|
|
52
|
+
class Template extends macroable_1.default {
|
|
53
|
+
#compiler;
|
|
54
|
+
#processor;
|
|
55
|
+
/**
|
|
56
|
+
* The shared state is used to hold the globals and locals,
|
|
57
|
+
* since it is shared with components too.
|
|
58
|
+
*/
|
|
59
|
+
#sharedState;
|
|
60
|
+
/**
|
|
61
|
+
* Template stacks holds a collection of placeholders
|
|
62
|
+
* and their content to be filled before returning
|
|
63
|
+
* the output.
|
|
64
|
+
*/
|
|
65
|
+
stacks = new stacks_js_1.default();
|
|
66
|
+
constructor(compiler, globals, locals, processor) {
|
|
67
|
+
super();
|
|
68
|
+
this.#compiler = compiler;
|
|
69
|
+
this.#processor = processor;
|
|
70
|
+
this.#sharedState = compiler.compat
|
|
71
|
+
? lodash_1.default.merge({}, globals, locals)
|
|
72
|
+
: {
|
|
73
|
+
...globals,
|
|
74
|
+
...locals,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Trims top and bottom new lines from the content
|
|
79
|
+
*/
|
|
80
|
+
#trimTopBottomNewLines(value) {
|
|
81
|
+
return value.replace(/^\n|^\r\n/, '').replace(/\n$|\r\n$/, '');
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Render a compiled template with state
|
|
85
|
+
*/
|
|
86
|
+
#renderCompiled(compiledTemplate, state) {
|
|
87
|
+
const templateState = { ...this.#sharedState, ...state };
|
|
88
|
+
const $context = {};
|
|
89
|
+
/**
|
|
90
|
+
* Process template as a promise.
|
|
91
|
+
*/
|
|
92
|
+
if (this.#compiler.async) {
|
|
93
|
+
return compiledTemplate(this, templateState, $context).then((output) => {
|
|
94
|
+
output = this.#trimTopBottomNewLines(output);
|
|
95
|
+
output = this.stacks.fillPlaceholders(output);
|
|
96
|
+
return this.#processor.executeOutput({ output, template: this, state: templateState });
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
let output = this.#trimTopBottomNewLines(compiledTemplate(this, templateState, $context));
|
|
100
|
+
output = this.stacks.fillPlaceholders(output);
|
|
101
|
+
return this.#processor.executeOutput({ output, template: this, state: templateState });
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Render a partial
|
|
105
|
+
*
|
|
106
|
+
* ```js
|
|
107
|
+
* const partialFn = template.compilePartial('includes/user')
|
|
108
|
+
*
|
|
109
|
+
* // render and use output
|
|
110
|
+
* partialFn(template, state, ctx)
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
compilePartial(templatePath, ...localVariables) {
|
|
114
|
+
return this.#compiler.compile(templatePath, localVariables);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Render a component
|
|
118
|
+
*
|
|
119
|
+
* ```js
|
|
120
|
+
* const componentFn = template.compileComponent('components/button')
|
|
121
|
+
*
|
|
122
|
+
* // render and use output
|
|
123
|
+
* componentFn(template, template.getComponentState(props, slots, caller), ctx)
|
|
124
|
+
* ```
|
|
125
|
+
*/
|
|
126
|
+
compileComponent(templatePath) {
|
|
127
|
+
return this.#compiler.compile(templatePath);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Returns the isolated state for a given component
|
|
131
|
+
*/
|
|
132
|
+
getComponentState(props, slots, caller) {
|
|
133
|
+
return {
|
|
134
|
+
...this.#sharedState,
|
|
135
|
+
...props,
|
|
136
|
+
$slots: slots,
|
|
137
|
+
$caller: caller,
|
|
138
|
+
$props: this.#compiler.compat ? new props_js_1.Props(props) : new props_js_2.ComponentProps(props),
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Render a template with it's state.
|
|
143
|
+
*
|
|
144
|
+
* ```js
|
|
145
|
+
* template.render('welcome', { key: 'value' })
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
148
|
+
render(template, state) {
|
|
149
|
+
let compiledTemplate = this.#compiler.compile(template);
|
|
150
|
+
return this.#renderCompiled(compiledTemplate, state);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Render template from a raw string
|
|
154
|
+
*
|
|
155
|
+
* ```js
|
|
156
|
+
* template.renderRaw('Hello {{ username }}', { username: 'virk' })
|
|
157
|
+
* ```
|
|
158
|
+
*/
|
|
159
|
+
renderRaw(contents, state, templatePath) {
|
|
160
|
+
let compiledTemplate = this.#compiler.compileRaw(contents, templatePath);
|
|
161
|
+
return this.#renderCompiled(compiledTemplate, state);
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Escapes the value to be HTML safe. Only strings are escaped
|
|
165
|
+
* and rest all values will be returned as it is.
|
|
166
|
+
*/
|
|
167
|
+
escape(input) {
|
|
168
|
+
return escape(input);
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Creates an instance of the EdgeError
|
|
172
|
+
*/
|
|
173
|
+
createError(errorMessage, filename, lineNumber, column) {
|
|
174
|
+
return new edge_error_1.EdgeError(errorMessage, 'E_RUNTIME_EXCEPTION', {
|
|
175
|
+
filename: filename,
|
|
176
|
+
line: lineNumber,
|
|
177
|
+
col: column,
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Throws EdgeError. Use "createError" to create a new
|
|
182
|
+
* error instance
|
|
183
|
+
*/
|
|
184
|
+
newError(errorMessage, filename, lineNumber, column) {
|
|
185
|
+
throw this.createError(errorMessage, filename, lineNumber, column);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Rethrows the runtime exception by re-constructing the error message
|
|
189
|
+
* to point back to the original filename
|
|
190
|
+
*/
|
|
191
|
+
reThrow(error, filename, lineNumber) {
|
|
192
|
+
if (error instanceof edge_error_1.EdgeError) {
|
|
193
|
+
throw error;
|
|
194
|
+
}
|
|
195
|
+
const message = error.message.replace(/state\./, '');
|
|
196
|
+
throw new edge_error_1.EdgeError(message, 'E_RUNTIME_EXCEPTION', {
|
|
197
|
+
filename: filename,
|
|
198
|
+
line: lineNumber,
|
|
199
|
+
col: 0,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
exports.Template = Template;
|