@trustme24/flext 1.10.2 → 1.10.4
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/README.md +201 -24
- package/dist/engine.d.ts +66 -0
- package/dist/index.cjs +200 -331
- package/dist/index.cjs.map +4 -4
- package/dist/index.css +1 -1
- package/dist/index.d.ts +2 -54
- package/dist/index.js +20 -20
- package/dist/index.js.map +4 -4
- package/dist/lib/index.d.ts +1 -1
- package/package.json +13 -12
- package/src/engine.ts +414 -0
- package/src/index.ts +4 -381
- package/src/lib/index.ts +1 -1
package/README.md
CHANGED
|
@@ -1,64 +1,241 @@
|
|
|
1
|
-
|
|
1
|
+
# Flext
|
|
2
2
|
|
|
3
3
|
[](https://github.com/TrustMe-kz/flext)
|
|
4
|
-
[](https://www.npmjs.com/package/@trustme24/flext)
|
|
5
|
+
[](https://codesandbox.io/p/devbox/trustme24-flext-f5x2hy)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+

|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
- [Documentation: Available at TrustMe Wiki](https://trustmekz.atlassian.net/wiki/external/MTUwYzM5NjUzNDE4NDViMGJlMTliOWEzNzM1Y2RiZWE).
|
|
9
|
+
**Flext** is a technology for building reliable document templates.
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
In many systems, templates start simple and gradually become fragile: fields appear without documentation, rendering logic spreads across multiple layers, versions break compatibility, and debugging becomes difficult. Flext addresses this problem by allowing templates to describe the structure and requirements of the document itself.
|
|
12
|
+
|
|
13
|
+
A Flext template can contain Markup, Metadata, Modules, and rendering hints in a single artifact. This makes templates easier to reuse, validate, and embed into larger systems such as document pipelines, reporting services, or contract generation platforms.
|
|
14
|
+
|
|
15
|
+
- [GitHub: TrustMe-kz/flext](https://github.com/TrustMe-kz/flext)
|
|
16
|
+
- [NPM: @trustme24/flext](https://www.npmjs.com/package/@trustme24/flext)
|
|
17
|
+
- [Demo: Available at CodeSandbox](https://codesandbox.io/p/devbox/trustme24-flext-f5x2hy)
|
|
18
|
+
- [Documentation: Available at TrustMe Wiki](https://trustmekz.atlassian.net/wiki/external/MTUwYzM5NjUzNDE4NDViMGJlMTliOWEzNzM1Y2RiZWE)
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```shell
|
|
25
|
+
npm i @trustme24/flext tailwindcss
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Add the **CSS** import:
|
|
29
|
+
|
|
30
|
+
```css
|
|
31
|
+
@import "@trustme24/flext/index.css";
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
🎉 **That's It!**
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## The Problem
|
|
39
|
+
|
|
40
|
+
Document templating often looks simple at first. Over time it tends to accumulate hidden complexity.
|
|
41
|
+
|
|
42
|
+
Typical issues include: undocumented fields, incompatible template versions, duplicated rendering logic across services, fragile helper usage, and weak validation before rendering.
|
|
43
|
+
|
|
44
|
+

|
|
45
|
+
|
|
46
|
+
### A few common scenarios illustrate the problem:
|
|
47
|
+
|
|
48
|
+
1. **A template expects a field that is not provided at runtime. The result is either a broken document or silent incorrect output.**
|
|
49
|
+
Solution with Flext: The template can explicitly declare required fields using Metadata so missing data is detected early.
|
|
50
|
+
|
|
51
|
+
————————————
|
|
52
|
+
|
|
53
|
+
2. **Multiple services use the same template but apply different helper logic or formatting rules.**
|
|
54
|
+
Solution with Flext: Templates can declare Module dependencies so rendering logic is predictable and consistent.
|
|
55
|
+
|
|
56
|
+
————————————
|
|
57
|
+
|
|
58
|
+
3. **Templates evolve but older documents still rely on previous versions.**
|
|
59
|
+
Solution with Flext: Templates can carry explicit Version information and compatibility rules.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## What It Provides
|
|
64
|
+
|
|
65
|
+
**Flext** builds on top of [Handlebars](https://handlebarsjs.com/) and keeps its familiar syntax while adding a small metadata layer. The goal is not to replace existing template engines but to make document templates safer and easier to maintain.
|
|
66
|
+
|
|
67
|
+
Instead of treating templates as plain text files, Flext treats them as structured artifacts. A template can include Markup, Metadata directives, and Module dependencies, all stored together.
|
|
68
|
+
|
|
69
|
+
This approach helps systems understand what a template requires before rendering it.
|
|
70
|
+
|
|
71
|
+
### Quick Start:
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
import Flext from '@trustme24/flext';
|
|
75
|
+
|
|
76
|
+
const template = `
|
|
77
|
+
{{!-- @v "1.0.beta4" --}}
|
|
78
|
+
{{!-- @use "put" --}}
|
|
79
|
+
<p>{{ put name 'Unknown user...' }}</p>
|
|
80
|
+
`;
|
|
81
|
+
|
|
82
|
+
const flext = new Flext(template, { name: 'Anna' });
|
|
83
|
+
|
|
84
|
+
document.body.innerHTML = flext.html;
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Core Ideas
|
|
90
|
+
|
|
91
|
+
A **Flext** template contains three conceptual layers. The first layer is markup: HTML and standard Handlebars expressions. The second layer is Metadata written as directives such as `@v`, `@field`, or `@use`. The third layer is runtime behavior provided through Modules and helpers.
|
|
92
|
+
|
|
93
|
+
Keeping these elements close together makes templates easier to move between systems and reduces hidden assumptions.
|
|
94
|
+
|
|
95
|
+
Metadata directives can describe template Version, language, title, rendering parameters, and required fields. Modules provide reusable logic such as formatting numbers, inserting fallback values, or conditional rendering.
|
|
13
96
|
|
|
14
97
|
### Example
|
|
98
|
+
|
|
15
99
|
```ts
|
|
16
|
-
import
|
|
100
|
+
import Flext from '@trustme24/flext';
|
|
17
101
|
|
|
18
102
|
const template = `
|
|
19
103
|
{{!-- @v "1.0.beta4" --}}
|
|
20
104
|
{{!-- @use "put" --}}
|
|
105
|
+
{{!-- @group "data" --}}
|
|
106
|
+
{{!-- @field "data.someField" type="string" label="Message" required --}}
|
|
21
107
|
|
|
22
|
-
<
|
|
108
|
+
<p class="text-center text-red-500">
|
|
109
|
+
{{ put data.someField 'No hello world...' }}
|
|
110
|
+
</p>
|
|
23
111
|
`;
|
|
24
112
|
|
|
25
113
|
const flext = new Flext(template, {
|
|
26
|
-
data: {
|
|
114
|
+
data: { someField: 'Hello World!' },
|
|
27
115
|
});
|
|
28
116
|
|
|
29
|
-
|
|
117
|
+
console.log(flext.html); // <p class="...">Hello World!</p>
|
|
118
|
+
console.log(flext.model); // {"name":"data","$":[{"name":"someField"}]}
|
|
30
119
|
```
|
|
31
120
|
|
|
32
|
-
|
|
121
|
+
> 💡 **In this example** the template carries additional information: Version, Field definition, and Module usage. This allows runtime tools to build a Data Model, validate input, and render HTML predictably.
|
|
33
122
|
|
|
34
|
-
|
|
123
|
+
---
|
|
35
124
|
|
|
36
|
-
|
|
37
|
-
|
|
125
|
+
## Use Cases
|
|
126
|
+
|
|
127
|
+

|
|
128
|
+
|
|
129
|
+
**Flext** is intended for structured document generation. Common examples include contracts, invoices, reports, certificates, and internal document workflows. It is particularly useful when templates must be versioned, validated, reused across services, or rendered in multiple environments.
|
|
130
|
+
|
|
131
|
+
Flext can be used on its own, but it is also designed to serve as a core library inside larger systems. Related tools include [vue-flext](https://www.npmjs.com/package/vue-flext) for Vue integration, [flext2pdf](https://www.npmjs.com/package/flext2pdf) for HTML‑to‑PDF rendering, and some **Flext Convert Service** for running document rendering as a microservice.
|
|
132
|
+
|
|
133
|
+
Together these components allow Flext to power full document pipelines while remaining a lightweight core library.
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Writing Templates
|
|
138
|
+
|
|
139
|
+
Templates should stay declarative and focused on layout. Business logic is usually better handled in Modules or application code. Metadata directives such as `@field` help document required data and make validation possible.
|
|
140
|
+
|
|
141
|
+
### Example:
|
|
142
|
+
|
|
143
|
+
```handlebars
|
|
144
|
+
{{!-- @v "1.0.beta4" --}}
|
|
145
|
+
{{!-- @use "put" "date" --}}
|
|
146
|
+
{{!-- @group "data" --}
|
|
147
|
+
{{!-- @field "data.city" type="string" label="City" required --}}
|
|
148
|
+
{{!-- @field "data.date" type="date" label="Date" required --}}
|
|
149
|
+
|
|
150
|
+
<p>
|
|
151
|
+
{{ put data.city "City" }}, {{ put (date:text data.date "No date...") }}
|
|
152
|
+
</p>
|
|
38
153
|
```
|
|
39
154
|
|
|
40
|
-
|
|
155
|
+
### Best practices
|
|
41
156
|
|
|
42
|
-
|
|
43
|
-
|
|
157
|
+
Treat templates as versioned artifacts. Prefer explicit metadata over hidden assumptions. Keep helper usage predictable and document important data paths with `@field`. Test templates with realistic data and separate document layout from application business rules.
|
|
158
|
+
|
|
159
|
+
### Limitations
|
|
160
|
+
|
|
161
|
+
Flext is intentionally focused. It is not a full programming language, not a WYSIWYG editor, and not a complete document management system. Its role is to act as a reliable template core inside document generation workflows.
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## API
|
|
166
|
+
|
|
167
|
+
The main entry point is the `Flext` class.
|
|
168
|
+
|
|
169
|
+
### Constructor:
|
|
170
|
+
|
|
171
|
+
```ts
|
|
172
|
+
import Flext from '@trustme24/flext';
|
|
173
|
+
|
|
174
|
+
new Flext().setTemplate('...').setData({});
|
|
44
175
|
```
|
|
45
176
|
|
|
46
|
-
|
|
177
|
+
[More information about the API is available at TrustMe Wiki](https://trustmekz.atlassian.net/wiki/external/MTUwYzM5NjUzNDE4NDViMGJlMTliOWEzNzM1Y2RiZWE).
|
|
47
178
|
|
|
48
|
-
|
|
179
|
+
---
|
|
49
180
|
|
|
50
|
-
|
|
181
|
+
## Architecture
|
|
51
182
|
|
|
52
|
-
|
|
53
|
-
|
|
183
|
+
**Flext** operates as a simple pipeline.
|
|
184
|
+
|
|
185
|
+
```text
|
|
186
|
+
Template
|
|
187
|
+
v
|
|
188
|
+
Parser / AST
|
|
189
|
+
v
|
|
190
|
+
Directives / Modules
|
|
191
|
+
v
|
|
192
|
+
PDF / Preview / Data Model / Export
|
|
54
193
|
```
|
|
55
194
|
|
|
56
|
-
|
|
195
|
+
At runtime Flext parses the template, extracts Metadata, registers Modules, builds a Data Model, and generates preview. The output can then be passed to other tools to display, store, or generating PDF.
|
|
196
|
+
|
|
197
|
+
- [Repo: More information about the repo can be found in ARCHITECTURE.md](https://github.com/TrustMe-kz/flext/blob/main/ARCHITECTURE.md)
|
|
198
|
+
- [Documentation: More information about the API is available at TrustMe Wiki](https://trustmekz.atlassian.net/wiki/external/MTUwYzM5NjUzNDE4NDViMGJlMTliOWEzNzM1Y2RiZWE)
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Development
|
|
57
203
|
|
|
58
204
|
```shell
|
|
59
205
|
npm run test:app
|
|
60
206
|
```
|
|
61
207
|
|
|
208
|
+
Run **Tests**:
|
|
209
|
+
|
|
210
|
+
```shell
|
|
211
|
+
npm run test
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
[More information about the contribution can be found in CONTRIBUTING.md](https://github.com/TrustMe-kz/flext/blob/main/CONTRIBUTING.md).
|
|
215
|
+
|
|
62
216
|
---
|
|
217
|
+
|
|
218
|
+
## Roadmap
|
|
219
|
+
|
|
220
|
+
Future development focuses on improving reliability and adoption. Planned areas include stronger template validation, better parser and AST tooling, clearer compatibility rules, improved module authoring experience, richer documentation, ecosystem integrations, editor support, and a template corpus for regression testing.
|
|
221
|
+
|
|
222
|
+

|
|
223
|
+
|
|
224
|
+
- **Contributions** are welcome. Useful areas include documentation, example templates, modules, parser improvements, performance optimizations, and test coverage. Changes that affect the template syntax or core semantics should first be discussed in issues so architectural decisions remain consistent.
|
|
225
|
+
|
|
226
|
+
————————————
|
|
227
|
+
|
|
228
|
+
- **Governance:** Flext is maintained by [TrustMe](https://trustme24.com/). External contributions are encouraged while core design decisions remain centralized to keep the language and runtime coherent.
|
|
229
|
+
|
|
230
|
+
————————————
|
|
231
|
+
|
|
232
|
+
- **Security:** If you discover a security issue, please report it privately to [i.am@kennyromanov.com](mailto:i.am@kennyromanov.com) instead of opening a public issue
|
|
233
|
+
|
|
234
|
+
————————————
|
|
235
|
+
|
|
236
|
+
- **License:** Flext is released under the [MIT License](https://github.com/TrustMe-kz/flext/blob/main/LICENSE)
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
63
240
|
**Flext by Kenny Romanov**
|
|
64
241
|
TrustMe
|
package/dist/engine.d.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { AST } from '@handlebars/parser';
|
|
2
|
+
import * as types from './types';
|
|
3
|
+
import * as errors from './errors';
|
|
4
|
+
export declare const DEFAULT_HELPER_NAME = "__default";
|
|
5
|
+
export declare const DEFAULT_MODEL_DEPTH = 10;
|
|
6
|
+
export type MacrosData = {
|
|
7
|
+
version?: string | null;
|
|
8
|
+
lang?: string | null;
|
|
9
|
+
timeZone?: string | null;
|
|
10
|
+
title?: string | null;
|
|
11
|
+
moduleNames?: string[] | null;
|
|
12
|
+
lineHeight?: string | null;
|
|
13
|
+
fields?: types.Field[] | null;
|
|
14
|
+
};
|
|
15
|
+
export declare class SimpleFlext {
|
|
16
|
+
ast: AST.Program;
|
|
17
|
+
data: types.Obj;
|
|
18
|
+
helpers: types.Obj;
|
|
19
|
+
onGetProcessed: types.GetProcessedTemplateHandler;
|
|
20
|
+
onGetAst: types.GetTemplateAstHandler;
|
|
21
|
+
constructor(val?: string | null, data?: types.Obj, helpers?: types.Obj);
|
|
22
|
+
setTemplate(val: string): this;
|
|
23
|
+
setData(val: types.Obj): this;
|
|
24
|
+
setHelpers(val: types.Obj): this;
|
|
25
|
+
addHelper(name: string, val: any): this;
|
|
26
|
+
setOnGetProcessed(val: types.GetProcessedTemplateHandler): this;
|
|
27
|
+
setOnGetAst(val: types.GetTemplateAstHandler): this;
|
|
28
|
+
getHtml(data?: types.Obj | null, helpers?: types.Obj | null): string;
|
|
29
|
+
getCss(data?: types.Obj | null, options?: types.Obj): Promise<string>;
|
|
30
|
+
get html(): string;
|
|
31
|
+
}
|
|
32
|
+
export declare class Flext extends SimpleFlext {
|
|
33
|
+
version: string;
|
|
34
|
+
lang: string;
|
|
35
|
+
title: string;
|
|
36
|
+
timeZone: string;
|
|
37
|
+
lineHeight: number;
|
|
38
|
+
assets: types.Obj<Blob>;
|
|
39
|
+
fields: types.Field[];
|
|
40
|
+
onGetTitle: types.GetTemplateTitleHandler;
|
|
41
|
+
onGetMacro: types.GetTemplateMacroHandler;
|
|
42
|
+
constructor(val?: string | null, data?: types.Obj, helpers?: types.Obj);
|
|
43
|
+
useModule(...val: string[]): this;
|
|
44
|
+
setTemplate(val: string): this;
|
|
45
|
+
setVersion(val: string): this;
|
|
46
|
+
setLang(val: string): this;
|
|
47
|
+
setTitle(val: string): this;
|
|
48
|
+
setTimeZone(val: string): this;
|
|
49
|
+
setLineHeight(val: number): this;
|
|
50
|
+
setAssets(val: types.Obj<Blob>): this;
|
|
51
|
+
addAsset(name: string, val: Blob): this;
|
|
52
|
+
setFields(val: types.Field[]): this;
|
|
53
|
+
addModule(name: string, val: any): this;
|
|
54
|
+
setOnGetTitle(val: types.GetTemplateTitleHandler): this;
|
|
55
|
+
setOnGetMacro(val: types.GetTemplateMacroHandler): this;
|
|
56
|
+
getDataModel(depth?: number): types.MetadataModelNode[];
|
|
57
|
+
getValidationErrors(data?: types.Obj | null, depth?: number): errors.TemplateDataValidationError[];
|
|
58
|
+
getIsValid(data?: types.Obj | null, depth?: number): boolean;
|
|
59
|
+
get model(): types.MetadataModelNode[];
|
|
60
|
+
get validationErrors(): errors.TemplateDataValidationError[];
|
|
61
|
+
get errors(): errors.BaseError[];
|
|
62
|
+
get isValid(): boolean;
|
|
63
|
+
}
|
|
64
|
+
export declare function macrosToData(macros: types.Macro[]): MacrosData;
|
|
65
|
+
export declare function defaultGetProcessed(val: string): string;
|
|
66
|
+
export default Flext;
|