@arikajs/view 0.1.0
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.
Potentially problematic release.
This version of @arikajs/view might be problematic. Click here for more details.
- package/LICENSE +21 -0
- package/README.md +246 -0
- package/dist/Compiler.d.ts +13 -0
- package/dist/Compiler.d.ts.map +1 -0
- package/dist/Compiler.js +78 -0
- package/dist/Compiler.js.map +1 -0
- package/dist/Directives/For.d.ts +5 -0
- package/dist/Directives/For.d.ts.map +1 -0
- package/dist/Directives/For.js +18 -0
- package/dist/Directives/For.js.map +1 -0
- package/dist/Directives/If.d.ts +6 -0
- package/dist/Directives/If.d.ts.map +1 -0
- package/dist/Directives/If.js +26 -0
- package/dist/Directives/If.js.map +1 -0
- package/dist/Directives/Include.d.ts +5 -0
- package/dist/Directives/Include.d.ts.map +1 -0
- package/dist/Directives/Include.js +15 -0
- package/dist/Directives/Include.js.map +1 -0
- package/dist/Directives/Section.d.ts +5 -0
- package/dist/Directives/Section.d.ts.map +1 -0
- package/dist/Directives/Section.js +28 -0
- package/dist/Directives/Section.js.map +1 -0
- package/dist/Engine.d.ts +33 -0
- package/dist/Engine.d.ts.map +1 -0
- package/dist/Engine.js +144 -0
- package/dist/Engine.js.map +1 -0
- package/dist/Template.d.ts +14 -0
- package/dist/Template.d.ts.map +1 -0
- package/dist/Template.js +63 -0
- package/dist/Template.js.map +1 -0
- package/dist/View.d.ts +14 -0
- package/dist/View.d.ts.map +1 -0
- package/dist/View.js +23 -0
- package/dist/View.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/package.json +45 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ArikaJs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
## Arika View
|
|
2
|
+
|
|
3
|
+
`@arikajs/view` is the server-side rendering (SSR) and template engine for the ArikaJS framework.
|
|
4
|
+
|
|
5
|
+
It allows developers to render dynamic HTML using a clean, expressive template syntax inspired by modern server frameworks — while remaining lightweight, secure, and framework-agnostic.
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { View } from '@arikajs/view';
|
|
9
|
+
|
|
10
|
+
const view = new View({
|
|
11
|
+
viewsPath: './views',
|
|
12
|
+
cachePath: './storage/views',
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
const html = await view.render('home', {
|
|
16
|
+
title: 'Welcome to ArikaJS',
|
|
17
|
+
});
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The View package enables presentation logic in ArikaJS, transforming templates into clean HTML output with safe escaping and high performance.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
### Status
|
|
25
|
+
|
|
26
|
+
- **Stage**: Experimental / v0.x
|
|
27
|
+
- **Scope (v0.x)**:
|
|
28
|
+
- Template compilation & rendering
|
|
29
|
+
- Layout & section management
|
|
30
|
+
- Basic control structures (`@if`, `@for`)
|
|
31
|
+
- Safe output escaping
|
|
32
|
+
- Template caching
|
|
33
|
+
- **Out of scope (for this package)**:
|
|
34
|
+
- HTTP request/response handling (see `@arikajs/http`)
|
|
35
|
+
- Route matching (see `@arikajs/router`)
|
|
36
|
+
- Authentication logic
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 🎯 Purpose
|
|
41
|
+
|
|
42
|
+
The View package is the presentation layer of the ArikaJS ecosystem. It is responsible for:
|
|
43
|
+
- Rendering templates into HTML
|
|
44
|
+
- Managing layouts and partials
|
|
45
|
+
- Escaping output safely
|
|
46
|
+
- Supporting control structures
|
|
47
|
+
- Providing a foundation for Web views, Email templates, and Error pages.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## 🧠 Responsibilities
|
|
52
|
+
|
|
53
|
+
### ✅ What Arika View Does
|
|
54
|
+
- Compile templates into renderable functions
|
|
55
|
+
- Render templates with dynamic data
|
|
56
|
+
- Support layouts, sections, and includes
|
|
57
|
+
- Provide basic control structures (`if`, `for`)
|
|
58
|
+
- Escape output by default
|
|
59
|
+
- Cache compiled templates for performance
|
|
60
|
+
|
|
61
|
+
### ❌ What Arika View Does NOT Do
|
|
62
|
+
- Handle HTTP requests or responses
|
|
63
|
+
- Match routes
|
|
64
|
+
- Manage authentication
|
|
65
|
+
- Execute business logic
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## 🧬 Rendering Flow
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
Controller
|
|
73
|
+
↓
|
|
74
|
+
View.render()
|
|
75
|
+
↓
|
|
76
|
+
Template Compiler
|
|
77
|
+
↓
|
|
78
|
+
Compiled Template
|
|
79
|
+
↓
|
|
80
|
+
HTML Output
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Features
|
|
86
|
+
|
|
87
|
+
- **Simple, expressive template syntax**
|
|
88
|
+
- Clean tags for logic and output.
|
|
89
|
+
- **Layout & section support**
|
|
90
|
+
- Powerful inheritance model for UI consistency.
|
|
91
|
+
- **Partial / include support**
|
|
92
|
+
- Modularize your templates into reusable components.
|
|
93
|
+
- **Safe output escaping**
|
|
94
|
+
- Protection against XSS by default.
|
|
95
|
+
- **Custom directives**
|
|
96
|
+
- Extend the engine with your own syntax.
|
|
97
|
+
- **Template caching**
|
|
98
|
+
- High-performance rendering via pre-compiled templates.
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Installation
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
npm install @arikajs/view
|
|
106
|
+
# or
|
|
107
|
+
yarn add @arikajs/view
|
|
108
|
+
# or
|
|
109
|
+
pnpm add @arikajs/view
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## 🧩 Template Syntax
|
|
115
|
+
|
|
116
|
+
### Variable Output
|
|
117
|
+
```html
|
|
118
|
+
<h1>{{ title }}</h1>
|
|
119
|
+
```
|
|
120
|
+
*Escaped by default.*
|
|
121
|
+
|
|
122
|
+
### Raw Output
|
|
123
|
+
```html
|
|
124
|
+
{!! html !!}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Conditionals
|
|
128
|
+
```html
|
|
129
|
+
@if (user)
|
|
130
|
+
<p>Welcome, {{ user.name }}</p>
|
|
131
|
+
@endif
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Loops
|
|
135
|
+
```html
|
|
136
|
+
@for (item in items)
|
|
137
|
+
<li>{{ item }}</li>
|
|
138
|
+
@endfor
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Includes
|
|
142
|
+
```html
|
|
143
|
+
@include('partials.header')
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Layouts & Sections
|
|
147
|
+
|
|
148
|
+
**layout.html**
|
|
149
|
+
```html
|
|
150
|
+
<html>
|
|
151
|
+
<body>
|
|
152
|
+
@yield('content')
|
|
153
|
+
</body>
|
|
154
|
+
</html>
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**page.html**
|
|
158
|
+
```html
|
|
159
|
+
@extends('layout')
|
|
160
|
+
|
|
161
|
+
@section('content')
|
|
162
|
+
<h1>Hello World</h1>
|
|
163
|
+
@endsection
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## 🔌 Usage
|
|
169
|
+
|
|
170
|
+
### Basic Rendering
|
|
171
|
+
```ts
|
|
172
|
+
import { View } from '@arikajs/view';
|
|
173
|
+
|
|
174
|
+
const view = new View({
|
|
175
|
+
viewsPath: './views',
|
|
176
|
+
cachePath: './storage/views',
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
const html = await view.render('home', {
|
|
180
|
+
title: 'Welcome to ArikaJS',
|
|
181
|
+
});
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Controller Integration
|
|
185
|
+
*(Typically provided by the HTTP Kernel)*
|
|
186
|
+
```ts
|
|
187
|
+
return view('dashboard', {
|
|
188
|
+
user,
|
|
189
|
+
});
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## ⚙️ Configuration Options
|
|
195
|
+
|
|
196
|
+
```ts
|
|
197
|
+
{
|
|
198
|
+
viewsPath: string; // Directory containing templates
|
|
199
|
+
cachePath?: string; // Directory for compiled templates
|
|
200
|
+
extension?: '.html' | '.ark'; // Template file extension
|
|
201
|
+
cache?: boolean; // Enable/disable caching
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## 🧱 Project Structure
|
|
208
|
+
|
|
209
|
+
- `src/`
|
|
210
|
+
- `View.ts` – Main entry point
|
|
211
|
+
- `Engine.ts` – Execution context
|
|
212
|
+
- `Compiler.ts` – Template string to JS compiler
|
|
213
|
+
- `Template.ts` – Template resolution and state
|
|
214
|
+
- `Directives/` – Built-in controls
|
|
215
|
+
- `If.ts`, `For.ts`, `Include.ts`, `Section.ts`
|
|
216
|
+
- `index.ts` – Public exports
|
|
217
|
+
- `tests/` – Unit and integration tests
|
|
218
|
+
- `package.json`
|
|
219
|
+
- `tsconfig.json`
|
|
220
|
+
- `README.md`
|
|
221
|
+
- `LICENSE`
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## Versioning & Stability
|
|
226
|
+
|
|
227
|
+
- While in **v0.x**, the API may change between minor versions.
|
|
228
|
+
- Once the API stabilizes, `@arikajs/view` will move to **v1.0** and follow **semver** strictly.
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## Contributing
|
|
233
|
+
|
|
234
|
+
Contributions are welcome! Please ensure all pull requests include tests and follow the project's coding standards.
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## License
|
|
239
|
+
|
|
240
|
+
`@arikajs/view` is open-sourced software licensed under the **MIT license**.
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## 🧠 Philosophy
|
|
245
|
+
|
|
246
|
+
> “Presentation is a reflection of logic, not a home for it.”
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Directive } from './Directives/If';
|
|
2
|
+
export declare class Compiler {
|
|
3
|
+
private directives;
|
|
4
|
+
/**
|
|
5
|
+
* Add a custom directive to the compiler.
|
|
6
|
+
*/
|
|
7
|
+
addDirective(directive: Directive): void;
|
|
8
|
+
/**
|
|
9
|
+
* Compile a template string into a executable JavaScript function body.
|
|
10
|
+
*/
|
|
11
|
+
compile(content: string): string;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=Compiler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Compiler.d.ts","sourceRoot":"","sources":["../src/Compiler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAe,MAAM,iBAAiB,CAAC;AAKzD,qBAAa,QAAQ;IACjB,OAAO,CAAC,UAAU,CAKhB;IAEF;;OAEG;IACI,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI;IAI/C;;OAEG;IACI,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;CAyD1C"}
|
package/dist/Compiler.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Compiler = void 0;
|
|
4
|
+
const If_1 = require("./Directives/If");
|
|
5
|
+
const For_1 = require("./Directives/For");
|
|
6
|
+
const Include_1 = require("./Directives/Include");
|
|
7
|
+
const Section_1 = require("./Directives/Section");
|
|
8
|
+
class Compiler {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.directives = [
|
|
11
|
+
If_1.IfDirective,
|
|
12
|
+
For_1.ForDirective,
|
|
13
|
+
Include_1.IncludeDirective,
|
|
14
|
+
Section_1.SectionDirective
|
|
15
|
+
];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Add a custom directive to the compiler.
|
|
19
|
+
*/
|
|
20
|
+
addDirective(directive) {
|
|
21
|
+
this.directives.unshift(directive);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Compile a template string into a executable JavaScript function body.
|
|
25
|
+
*/
|
|
26
|
+
compile(content) {
|
|
27
|
+
let jsCode = 'let _output = "";\n';
|
|
28
|
+
jsCode += 'const _escape = (val) => String(val ?? "").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/\'/g, "'");\n';
|
|
29
|
+
jsCode += 'with (_data) {\n';
|
|
30
|
+
const escapedContent = content
|
|
31
|
+
.replace(/\\/g, '\\\\')
|
|
32
|
+
.replace(/`/g, '\\`')
|
|
33
|
+
.replace(/\$\{/g, '\\${');
|
|
34
|
+
const regex = /(@\w+\s*\(.*?\)|@\w+|\{\{.*?\}\}|\{!!.*?!!\})/sg;
|
|
35
|
+
let lastIndex = 0;
|
|
36
|
+
let match;
|
|
37
|
+
while ((match = regex.exec(escapedContent)) !== null) {
|
|
38
|
+
const text = escapedContent.substring(lastIndex, match.index);
|
|
39
|
+
if (text) {
|
|
40
|
+
jsCode += `_output += \`${text}\`;\n`;
|
|
41
|
+
}
|
|
42
|
+
const tag = match[0];
|
|
43
|
+
if (tag.startsWith('{!!')) {
|
|
44
|
+
const expr = tag.substring(3, tag.length - 3).trim().replace(/\\\\/g, '\\');
|
|
45
|
+
jsCode += `_output += (${expr});\n`;
|
|
46
|
+
}
|
|
47
|
+
else if (tag.startsWith('{{')) {
|
|
48
|
+
const expr = tag.substring(2, tag.length - 2).trim().replace(/\\\\/g, '\\');
|
|
49
|
+
jsCode += `_output += _escape(${expr});\n`;
|
|
50
|
+
}
|
|
51
|
+
else if (tag.startsWith('@')) {
|
|
52
|
+
let processed = false;
|
|
53
|
+
for (const directive of this.directives) {
|
|
54
|
+
const result = directive.handle(tag);
|
|
55
|
+
if (result) {
|
|
56
|
+
jsCode += result;
|
|
57
|
+
processed = true;
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (!processed) {
|
|
62
|
+
// If no directive handled it, treat as literal (escaping the @)
|
|
63
|
+
jsCode += `_output += \`@\`;\n`;
|
|
64
|
+
regex.lastIndex = match.index + 1;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
lastIndex = regex.lastIndex;
|
|
68
|
+
}
|
|
69
|
+
const remaining = escapedContent.substring(lastIndex);
|
|
70
|
+
if (remaining) {
|
|
71
|
+
jsCode += `_output += \`${remaining}\`;\n`;
|
|
72
|
+
}
|
|
73
|
+
jsCode += '}\nreturn _output;';
|
|
74
|
+
return jsCode;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
exports.Compiler = Compiler;
|
|
78
|
+
//# sourceMappingURL=Compiler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Compiler.js","sourceRoot":"","sources":["../src/Compiler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"For.d.ts","sourceRoot":"","sources":["../../src/Directives/For.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY;;oBAEL,MAAM,GAAG,MAAM;CAWlC,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ForDirective = void 0;
|
|
4
|
+
exports.ForDirective = {
|
|
5
|
+
name: 'for',
|
|
6
|
+
handle(content) {
|
|
7
|
+
if (content.startsWith('@for')) {
|
|
8
|
+
const match = content.match(/@for\s*\((.*)\)/);
|
|
9
|
+
const loop = match && match[1] ? match[1] : '';
|
|
10
|
+
return `for (let ${loop}) {\n`;
|
|
11
|
+
}
|
|
12
|
+
if (content === '@endfor') {
|
|
13
|
+
return `}\n`;
|
|
14
|
+
}
|
|
15
|
+
return '';
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=For.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"For.js","sourceRoot":"","sources":["../../src/Directives/For.ts"],"names":[],"mappings":";;;AAAa,QAAA,YAAY,GAAG;IACxB,IAAI,EAAE,KAAK;IACX,MAAM,CAAC,OAAe;QAClB,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;YAC/C,MAAM,IAAI,GAAG,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/C,OAAO,YAAY,IAAI,OAAO,CAAC;QACnC,CAAC;QACD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,OAAO,EAAE,CAAC;IACd,CAAC;CACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"If.d.ts","sourceRoot":"","sources":["../../src/Directives/If.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;CACnC;AAED,eAAO,MAAM,WAAW,EAAE,SAqBzB,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.IfDirective = void 0;
|
|
4
|
+
exports.IfDirective = {
|
|
5
|
+
name: 'if',
|
|
6
|
+
handle(content) {
|
|
7
|
+
if (content.startsWith('@if')) {
|
|
8
|
+
const match = content.match(/@if\s*\((.*)\)/);
|
|
9
|
+
const condition = match && match[1] ? match[1] : 'true';
|
|
10
|
+
return `if (${condition}) {\n`;
|
|
11
|
+
}
|
|
12
|
+
if (content === '@else') {
|
|
13
|
+
return `} else {\n`;
|
|
14
|
+
}
|
|
15
|
+
if (content.startsWith('@elseif')) {
|
|
16
|
+
const match = content.match(/@elseif\s*\((.*)\)/);
|
|
17
|
+
const condition = match && match[1] ? match[1] : 'true';
|
|
18
|
+
return `} else if (${condition}) {\n`;
|
|
19
|
+
}
|
|
20
|
+
if (content === '@endif') {
|
|
21
|
+
return `}\n`;
|
|
22
|
+
}
|
|
23
|
+
return '';
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=If.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"If.js","sourceRoot":"","sources":["../../src/Directives/If.ts"],"names":[],"mappings":";;;AAKa,QAAA,WAAW,GAAc;IAClC,IAAI,EAAE,IAAI;IACV,MAAM,CAAC,OAAe;QAClB,IAAI,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;YAC9C,MAAM,SAAS,GAAG,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YACxD,OAAO,OAAO,SAAS,OAAO,CAAC;QACnC,CAAC;QACD,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;YACtB,OAAO,YAAY,CAAC;QACxB,CAAC;QACD,IAAI,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAChC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;YAClD,MAAM,SAAS,GAAG,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YACxD,OAAO,cAAc,SAAS,OAAO,CAAC;QAC1C,CAAC;QACD,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;YACvB,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,OAAO,EAAE,CAAC;IACd,CAAC;CACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Include.d.ts","sourceRoot":"","sources":["../../src/Directives/Include.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB;;oBAET,MAAM,GAAG,MAAM;CAQlC,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.IncludeDirective = void 0;
|
|
4
|
+
exports.IncludeDirective = {
|
|
5
|
+
name: 'include',
|
|
6
|
+
handle(content) {
|
|
7
|
+
if (!content.startsWith('@include')) {
|
|
8
|
+
return '';
|
|
9
|
+
}
|
|
10
|
+
const match = content.match(/@include\s*\((.*)\)/);
|
|
11
|
+
const template = match && match[1] ? match[1] : '""';
|
|
12
|
+
return `_output += await _engine.render(${template}, _data);\n`;
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=Include.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Include.js","sourceRoot":"","sources":["../../src/Directives/Include.ts"],"names":[],"mappings":";;;AAAa,QAAA,gBAAgB,GAAG;IAC5B,IAAI,EAAE,SAAS;IACf,MAAM,CAAC,OAAe;QAClB,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAClC,OAAO,EAAE,CAAC;QACd,CAAC;QACD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;QACnD,MAAM,QAAQ,GAAG,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACrD,OAAO,mCAAmC,QAAQ,aAAa,CAAC;IACpE,CAAC;CACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Section.d.ts","sourceRoot":"","sources":["../../src/Directives/Section.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB;;oBAET,MAAM,GAAG,MAAM;CAqBlC,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SectionDirective = void 0;
|
|
4
|
+
exports.SectionDirective = {
|
|
5
|
+
name: 'section',
|
|
6
|
+
handle(content) {
|
|
7
|
+
if (content.startsWith('@section')) {
|
|
8
|
+
const match = content.match(/@section\s*\(([^)]*)\)/);
|
|
9
|
+
const name = match && match[1] ? match[1].replace(/['"]/g, '') : '';
|
|
10
|
+
return `_engine.startSection("${name}", _output);\n_output = "";\n`;
|
|
11
|
+
}
|
|
12
|
+
if (content === '@endsection') {
|
|
13
|
+
return `_output = _engine.popSection(_output);\n`;
|
|
14
|
+
}
|
|
15
|
+
if (content.startsWith('@yield')) {
|
|
16
|
+
const match = content.match(/@yield\s*\(([^)]*)\)/);
|
|
17
|
+
const name = match && match[1] ? match[1] : '""';
|
|
18
|
+
return `_output += _engine.yield(${name});\n`;
|
|
19
|
+
}
|
|
20
|
+
if (content.startsWith('@extends')) {
|
|
21
|
+
const match = content.match(/@extends\s*\((.*)\)/);
|
|
22
|
+
const parent = match && match[1] ? match[1] : '""';
|
|
23
|
+
return `_engine.extend(${parent});\n`;
|
|
24
|
+
}
|
|
25
|
+
return '';
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=Section.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Section.js","sourceRoot":"","sources":["../../src/Directives/Section.ts"],"names":[],"mappings":";;;AAAa,QAAA,gBAAgB,GAAG;IAC5B,IAAI,EAAE,SAAS;IACf,MAAM,CAAC,OAAe;QAClB,IAAI,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YACjC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;YACtD,MAAM,IAAI,GAAG,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACpE,OAAO,yBAAyB,IAAI,+BAA+B,CAAC;QACxE,CAAC;QACD,IAAI,OAAO,KAAK,aAAa,EAAE,CAAC;YAC5B,OAAO,0CAA0C,CAAC;QACtD,CAAC;QACD,IAAI,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC/B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;YACpD,MAAM,IAAI,GAAG,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACjD,OAAO,4BAA4B,IAAI,MAAM,CAAC;QAClD,CAAC;QACD,IAAI,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YACjC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;YACnD,MAAM,MAAM,GAAG,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACnD,OAAO,kBAAkB,MAAM,MAAM,CAAC;QAC1C,CAAC;QACD,OAAO,EAAE,CAAC;IACd,CAAC;CACJ,CAAC"}
|
package/dist/Engine.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export interface ViewConfig {
|
|
2
|
+
viewsPath: string;
|
|
3
|
+
cachePath?: string;
|
|
4
|
+
extension?: string;
|
|
5
|
+
cache?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare class Engine {
|
|
8
|
+
private config;
|
|
9
|
+
private sections;
|
|
10
|
+
private sectionStack;
|
|
11
|
+
private parentTemplate;
|
|
12
|
+
private compiler;
|
|
13
|
+
private templateLoader;
|
|
14
|
+
private compiledFunctions;
|
|
15
|
+
constructor(config: ViewConfig);
|
|
16
|
+
/**
|
|
17
|
+
* Add a custom directive to the template compiler.
|
|
18
|
+
*/
|
|
19
|
+
addDirective(directive: any): void;
|
|
20
|
+
/**
|
|
21
|
+
* Render a template file.
|
|
22
|
+
*/
|
|
23
|
+
render(template: string, data?: Record<string, any>, isInternal?: boolean): Promise<string>;
|
|
24
|
+
/**
|
|
25
|
+
* Internal render logic.
|
|
26
|
+
*/
|
|
27
|
+
private renderTemplate;
|
|
28
|
+
extend(parent: string): void;
|
|
29
|
+
startSection(name: string, previousOutput: string): void;
|
|
30
|
+
popSection(content: string): string;
|
|
31
|
+
yield(name: string): string;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=Engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Engine.d.ts","sourceRoot":"","sources":["../src/Engine.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,UAAU;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,qBAAa,MAAM;IAQH,OAAO,CAAC,MAAM;IAP1B,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,YAAY,CAAkD;IACtE,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,cAAc,CAAW;IACjC,OAAO,CAAC,iBAAiB,CAAoC;gBAEzC,MAAM,EAAE,UAAU;IAKtC;;OAEG;IACI,YAAY,CAAC,SAAS,EAAE,GAAG,GAAG,IAAI;IAIzC;;OAEG;IACU,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,EAAE,UAAU,UAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IAiB1G;;OAEG;YACW,cAAc;IAwDrB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI5B,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,IAAI;IAIxD,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IASnC,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CAGrC"}
|
package/dist/Engine.js
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.Engine = void 0;
|
|
37
|
+
const fs = __importStar(require("node:fs"));
|
|
38
|
+
const path = __importStar(require("node:path"));
|
|
39
|
+
const Compiler_1 = require("./Compiler");
|
|
40
|
+
const Template_1 = require("./Template");
|
|
41
|
+
class Engine {
|
|
42
|
+
constructor(config) {
|
|
43
|
+
this.config = config;
|
|
44
|
+
this.sections = {};
|
|
45
|
+
this.sectionStack = [];
|
|
46
|
+
this.parentTemplate = null;
|
|
47
|
+
this.compiledFunctions = new Map();
|
|
48
|
+
this.compiler = new Compiler_1.Compiler();
|
|
49
|
+
this.templateLoader = new Template_1.Template(config);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Add a custom directive to the template compiler.
|
|
53
|
+
*/
|
|
54
|
+
addDirective(directive) {
|
|
55
|
+
this.compiler.addDirective(directive);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Render a template file.
|
|
59
|
+
*/
|
|
60
|
+
async render(template, data = {}, isInternal = false) {
|
|
61
|
+
if (!isInternal) {
|
|
62
|
+
this.sections = {};
|
|
63
|
+
}
|
|
64
|
+
this.parentTemplate = null;
|
|
65
|
+
const content = await this.renderTemplate(template, data);
|
|
66
|
+
if (this.parentTemplate) {
|
|
67
|
+
const parent = this.parentTemplate;
|
|
68
|
+
this.parentTemplate = null;
|
|
69
|
+
return this.render(parent, data, true);
|
|
70
|
+
}
|
|
71
|
+
return content;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Internal render logic.
|
|
75
|
+
*/
|
|
76
|
+
async renderTemplate(templateName, data) {
|
|
77
|
+
// 1. Check In-Memory Cache
|
|
78
|
+
if (this.config.cache && this.compiledFunctions.has(templateName)) {
|
|
79
|
+
return await this.compiledFunctions.get(templateName)(this, data);
|
|
80
|
+
}
|
|
81
|
+
const cacheFile = this.config.cachePath
|
|
82
|
+
? path.join(this.config.cachePath, templateName.replace(/[\.\/\\]/g, '_') + '.js')
|
|
83
|
+
: null;
|
|
84
|
+
let jsCode = null;
|
|
85
|
+
// 2. Check Disk Cache
|
|
86
|
+
if (this.config.cache && cacheFile && fs.existsSync(cacheFile)) {
|
|
87
|
+
try {
|
|
88
|
+
jsCode = fs.readFileSync(cacheFile, 'utf8');
|
|
89
|
+
}
|
|
90
|
+
catch (e) {
|
|
91
|
+
// Fail silently and recompile
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// 3. Compile if not found in cache
|
|
95
|
+
if (!jsCode) {
|
|
96
|
+
const rawContent = this.templateLoader.read(templateName);
|
|
97
|
+
jsCode = this.compiler.compile(rawContent);
|
|
98
|
+
// Save to Disk Cache
|
|
99
|
+
if (this.config.cache && cacheFile) {
|
|
100
|
+
try {
|
|
101
|
+
if (!fs.existsSync(this.config.cachePath)) {
|
|
102
|
+
fs.mkdirSync(this.config.cachePath, { recursive: true });
|
|
103
|
+
}
|
|
104
|
+
fs.writeFileSync(cacheFile, jsCode);
|
|
105
|
+
}
|
|
106
|
+
catch (e) {
|
|
107
|
+
console.error(`View Cache Warning: Failed to write to ${this.config.cachePath}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// 4. Create Function and Save to Memory Cache
|
|
112
|
+
const AsyncFunction = Object.getPrototypeOf(async function () { }).constructor;
|
|
113
|
+
const renderFunc = new AsyncFunction('_engine', '_data', jsCode);
|
|
114
|
+
if (this.config.cache) {
|
|
115
|
+
this.compiledFunctions.set(templateName, renderFunc);
|
|
116
|
+
}
|
|
117
|
+
try {
|
|
118
|
+
return await renderFunc(this, data);
|
|
119
|
+
}
|
|
120
|
+
catch (e) {
|
|
121
|
+
throw new Error(`Error rendering template "${templateName}": ${e.message}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// Methods called from compiled templates
|
|
125
|
+
extend(parent) {
|
|
126
|
+
this.parentTemplate = parent;
|
|
127
|
+
}
|
|
128
|
+
startSection(name, previousOutput) {
|
|
129
|
+
this.sectionStack.push({ name, previousOutput });
|
|
130
|
+
}
|
|
131
|
+
popSection(content) {
|
|
132
|
+
const section = this.sectionStack.pop();
|
|
133
|
+
if (section) {
|
|
134
|
+
this.sections[section.name] = content;
|
|
135
|
+
return section.previousOutput;
|
|
136
|
+
}
|
|
137
|
+
return content;
|
|
138
|
+
}
|
|
139
|
+
yield(name) {
|
|
140
|
+
return this.sections[name] || '';
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
exports.Engine = Engine;
|
|
144
|
+
//# sourceMappingURL=Engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Engine.js","sourceRoot":"","sources":["../src/Engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ViewConfig } from './Engine';
|
|
2
|
+
export declare class Template {
|
|
3
|
+
private config;
|
|
4
|
+
constructor(config: ViewConfig);
|
|
5
|
+
/**
|
|
6
|
+
* Resolve and read template content.
|
|
7
|
+
*/
|
|
8
|
+
read(template: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Resolve template name to file path.
|
|
11
|
+
*/
|
|
12
|
+
private resolvePath;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=Template.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Template.d.ts","sourceRoot":"","sources":["../src/Template.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC,qBAAa,QAAQ;IACL,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,UAAU;IAEtC;;OAEG;IACI,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAQrC;;OAEG;IACH,OAAO,CAAC,WAAW;CAKtB"}
|
package/dist/Template.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.Template = void 0;
|
|
37
|
+
const fs = __importStar(require("node:fs"));
|
|
38
|
+
const path = __importStar(require("node:path"));
|
|
39
|
+
class Template {
|
|
40
|
+
constructor(config) {
|
|
41
|
+
this.config = config;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Resolve and read template content.
|
|
45
|
+
*/
|
|
46
|
+
read(template) {
|
|
47
|
+
const filePath = this.resolvePath(template);
|
|
48
|
+
if (!fs.existsSync(filePath)) {
|
|
49
|
+
throw new Error(`View template not found: ${filePath}`);
|
|
50
|
+
}
|
|
51
|
+
return fs.readFileSync(filePath, 'utf8');
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Resolve template name to file path.
|
|
55
|
+
*/
|
|
56
|
+
resolvePath(template) {
|
|
57
|
+
const ext = this.config.extension || '.html';
|
|
58
|
+
const fileName = template.replace(/\./g, path.sep) + ext;
|
|
59
|
+
return path.join(this.config.viewsPath, fileName);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
exports.Template = Template;
|
|
63
|
+
//# sourceMappingURL=Template.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Template.js","sourceRoot":"","sources":["../src/Template.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,4CAA8B;AAC9B,gDAAkC;AAGlC,MAAa,QAAQ;IACjB,YAAoB,MAAkB;QAAlB,WAAM,GAAN,MAAM,CAAY;IAAI,CAAC;IAE3C;;OAEG;IACI,IAAI,CAAC,QAAgB;QACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QAC5C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,4BAA4B,QAAQ,EAAE,CAAC,CAAC;QAC5D,CAAC;QACD,OAAO,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC7C,CAAC;IAED;;OAEG;IACK,WAAW,CAAC,QAAgB;QAChC,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,OAAO,CAAC;QAC7C,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;QACzD,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACtD,CAAC;CACJ;AAtBD,4BAsBC"}
|
package/dist/View.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ViewConfig } from './Engine';
|
|
2
|
+
export declare class View {
|
|
3
|
+
private engine;
|
|
4
|
+
constructor(config: ViewConfig);
|
|
5
|
+
/**
|
|
6
|
+
* Add a custom directive to the template compiler.
|
|
7
|
+
*/
|
|
8
|
+
addDirective(directive: any): void;
|
|
9
|
+
/**
|
|
10
|
+
* Render a template with data.
|
|
11
|
+
*/
|
|
12
|
+
render(template: string, data?: Record<string, any>): Promise<string>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=View.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"View.d.ts","sourceRoot":"","sources":["../src/View.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,UAAU,EAAE,MAAM,UAAU,CAAC;AAE9C,qBAAa,IAAI;IACb,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,UAAU;IAI9B;;OAEG;IACI,YAAY,CAAC,SAAS,EAAE,GAAG,GAAG,IAAI;IAIzC;;OAEG;IACU,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAGzF"}
|
package/dist/View.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.View = void 0;
|
|
4
|
+
const Engine_1 = require("./Engine");
|
|
5
|
+
class View {
|
|
6
|
+
constructor(config) {
|
|
7
|
+
this.engine = new Engine_1.Engine(config);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Add a custom directive to the template compiler.
|
|
11
|
+
*/
|
|
12
|
+
addDirective(directive) {
|
|
13
|
+
this.engine.addDirective(directive);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Render a template with data.
|
|
17
|
+
*/
|
|
18
|
+
async render(template, data = {}) {
|
|
19
|
+
return this.engine.render(template, data);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
exports.View = View;
|
|
23
|
+
//# sourceMappingURL=View.js.map
|
package/dist/View.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"View.js","sourceRoot":"","sources":["../src/View.ts"],"names":[],"mappings":";;;AAAA,qCAA8C;AAE9C,MAAa,IAAI;IAGb,YAAY,MAAkB;QAC1B,IAAI,CAAC,MAAM,GAAG,IAAI,eAAM,CAAC,MAAM,CAAC,CAAC;IACrC,CAAC;IAED;;OAEG;IACI,YAAY,CAAC,SAAc;QAC9B,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,MAAM,CAAC,QAAgB,EAAE,OAA4B,EAAE;QAChE,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC9C,CAAC;CACJ;AApBD,oBAoBC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./View"), exports);
|
|
18
|
+
__exportStar(require("./Engine"), exports);
|
|
19
|
+
__exportStar(require("./Compiler"), exports);
|
|
20
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,yCAAuB;AACvB,2CAAyB;AACzB,6CAA2B"}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@arikajs/view",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Server-side rendering and template engine for the ArikaJS framework.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "tsc -p tsconfig.json",
|
|
10
|
+
"build:tests": "tsc -p tsconfig.test.json",
|
|
11
|
+
"clean": "rm -rf dist",
|
|
12
|
+
"prepare": "echo skip",
|
|
13
|
+
"test": "npm run build && npm run build:tests && node scripts/fix-test-imports.js && node --test 'dist/tests/**/*.test.js'",
|
|
14
|
+
"test:watch": "npm run build && npm run build:tests && node --test --watch 'dist/tests/**/*.test.js'"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"keywords": [
|
|
20
|
+
"arika",
|
|
21
|
+
"arika-js",
|
|
22
|
+
"framework",
|
|
23
|
+
"view",
|
|
24
|
+
"template",
|
|
25
|
+
"ssr",
|
|
26
|
+
"renderer"
|
|
27
|
+
],
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=20.0.0"
|
|
30
|
+
},
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "git+https://github.com/arikajs/view.git"
|
|
34
|
+
},
|
|
35
|
+
"bugs": {
|
|
36
|
+
"url": "https://github.com/arikajs/view/issues"
|
|
37
|
+
},
|
|
38
|
+
"homepage": "https://github.com/arikajs/view#readme",
|
|
39
|
+
"dependencies": {},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@types/node": "^20.11.24",
|
|
42
|
+
"typescript": "^5.3.3"
|
|
43
|
+
},
|
|
44
|
+
"author": "Prakash Tank"
|
|
45
|
+
}
|