Initial Commit

This commit is contained in:
2026-05-27 23:47:53 +01:00
parent fbc70f96e6
commit 9b28db724f
18103 changed files with 1600554 additions and 0 deletions

View File

@@ -0,0 +1,81 @@
# standard preset
## Purpose
Provides a comprehensive `PluginPreset` suitable for the majority of production use cases. It bundles all non-loop plugins in a single call, covering control-flow (conditional blocks), dynamic variables (counter, datetime, uuid), string transforms (string-split, regex, case-transform), and variable resolution (array-index, dot-notation). Use this preset when you want a batteries-included template engine without the complexity of wiring loop support, which requires injecting the engine's internal render function.
## Features
- **Conditional blocks**: `{if:condition}...{/if}` with truthy, negation, and operator-based expressions.
- **Counter**: `{_counter}`, named counters, custom start values, zero-padding.
- **Date/time**: `{_date}`, `{_time}`, `{_datetime}`, `{_timestamp}` with custom format strings.
- **UUID/nano-ID**: `{_uuid}`, `{_nanoid:N}`.
- **String split**: `{path:delimiter[index]}` with negative-index support.
- **Regex**: `{path:/pattern/flags}`, `{path:/pattern/flags:replace:str}`, capture group extraction.
- **Case transform**: `{key:upper|lower|title|camel|pascal|snake|kebab|constant}`.
- **Variable resolution**: dot-notation and bracket-notation array indexing.
## Usage: Basic Example
```ts
import { TemplateEngine, standardPreset } from "@suaveplan/templates";
const engine = new TemplateEngine().usePreset(standardPreset());
engine.parse("Hello, {name:title}!", { name: "alice smith" });
// → "Hello, Alice Smith!"
engine.parse("{if:active}Active{/if}", { active: true });
// → "Active"
```
## Usage: Advanced Example
```ts
import { TemplateEngine, standardPreset } from "@suaveplan/templates";
const engine = new TemplateEngine().usePreset(standardPreset());
const ctx = {
users: ["alice smith", "bob jones"],
stats: { count: 42 },
tag: "hello-world",
};
engine.parse(
"Count: {stats.count} | Tag: {tag:pascal} | {if:stats.count:gt:10}High{/if}",
ctx
);
// → "Count: 42 | Tag: HelloWorld | High"
// Row numbers using counter and array access
engine.parse("{users[0]:title} is user #{_counter}", ctx);
// → "Alice Smith is user #1"
```
## API Reference
### `standardPreset<TContext>(): PluginPreset<TContext>`
Returns a `PluginPreset` with:
- `name: "standard"`
- `plugins`: array of nine plugin instances in priority-appropriate insertion order
Plugins included (listed by priority, descending):
1. `createConditionalPlugin()` — CRITICAL (95)
2. `createCounterPlugin()` — HIGH (80)
3. `createDateTimePlugin()` — HIGH (80)
4. `createUuidPlugin()` — HIGH (80)
5. `createStringSplitPlugin()` — MEDIUM (50)
6. `createRegexPlugin()` — MEDIUM (50)
7. `createCaseTransformPlugin()` — MEDIUM (50)
8. `createArrayIndexPlugin()` — LOW (20)
9. `createDotNotationPlugin()` — LOW (20)
## Implementation Notes
- All plugins in this preset use their default options (no injectable clock, no injectable RNG). To override defaults (e.g. deterministic datetime in tests), use `engine.use(createDateTimePlugin({ clock: fixedClock }))` separately instead of relying on the preset.
- Because `usePreset` skips plugins whose name is already registered, you can safely call `engine.usePreset(standardPreset())` on an engine that already has individual plugins registered — only the missing ones will be added.
- The loop plugin is intentionally excluded because it requires a `parseFunction` reference that creates a circular dependency at construction time. Use `fullPresetWithLoops` or add the loop plugin manually when loop support is needed.