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,69 @@
import type {
Plugin,
PluginMatch,
TemplateContext,
} from "../../types/index.js";
import { PluginPriority, SKIP_PLUGIN } from "../../types/index.js";
import { getNestedValue } from "../../utils/nested-value.js";
/**
* Regex transformation plugin.
*
* Syntax:
* - `{text:/pattern/flags}` — return first match
* - `{text:/pattern/flags:replace:replacement}` — replace all matches
* - `{text:/pattern/flags:0}` — return capture group 0 (full match)
* - `{text:/pattern/flags:1}` — return capture group 1
* - `{phone:/\\D/g:replace:}` — remove all non-digits
*
* Variables starting with `_` are skipped.
*/
export function createRegexPlugin<
TContext extends TemplateContext = TemplateContext,
>(): Plugin<TContext> {
return {
name: "regex",
priority: PluginPriority.MEDIUM,
pattern:
/\{([a-zA-Z_$][\w.$]*):\/([^/]+)\/([gimsuy]*)?(?::(\w+)(?::([^}]*))?)?\}/g,
transform(
match: PluginMatch,
context: TContext
): string | typeof SKIP_PLUGIN {
const path = match.groups?.[1];
const pattern = match.groups?.[2];
const flags = match.groups?.[3] ?? "";
const operation = match.groups?.[4];
const param = match.groups?.[5];
if (!path || !pattern) return SKIP_PLUGIN;
if (path.startsWith("_")) return SKIP_PLUGIN;
const value = getNestedValue(context, path);
if (value === undefined || value === null) return "";
const str = String(value);
try {
const regex = new RegExp(pattern, flags);
if (operation === "replace") {
return str.replace(regex, param ?? "");
}
if (operation !== undefined && /^\d+$/.test(operation)) {
const groupIndex = Number.parseInt(operation, 10);
const matches = str.match(regex);
if (!matches || groupIndex >= matches.length) return "";
return matches[groupIndex] ?? "";
}
// Default: return first match
return str.match(regex)?.[0] ?? "";
} catch {
return match.match;
}
},
};
}