typebars 1.0.2 → 1.0.3

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.
Files changed (40) hide show
  1. package/dist/analyzer.js +2 -2
  2. package/dist/analyzer.js.map +1 -1
  3. package/dist/{chunk-jms1ndxn.js → chunk-5znsrn10.js} +4 -4
  4. package/dist/{chunk-jms1ndxn.js.map → chunk-5znsrn10.js.map} +1 -1
  5. package/dist/{chunk-ecs3yth2.js → chunk-867xywnk.js} +4 -4
  6. package/dist/{chunk-ecs3yth2.js.map → chunk-867xywnk.js.map} +1 -1
  7. package/dist/{chunk-6955jpr7.js → chunk-8xza8tca.js} +3 -3
  8. package/dist/{chunk-6955jpr7.js.map → chunk-8xza8tca.js.map} +1 -1
  9. package/dist/{chunk-p5efqsxw.js → chunk-9jxzj2h4.js} +3 -3
  10. package/dist/{chunk-p5efqsxw.js.map → chunk-9jxzj2h4.js.map} +1 -1
  11. package/dist/chunk-dpffacsy.js +4 -0
  12. package/dist/{chunk-t6n956qz.js.map → chunk-dpffacsy.js.map} +2 -2
  13. package/dist/{chunk-zh1e0yhd.js → chunk-gayk9ew1.js} +3 -3
  14. package/dist/{chunk-zh1e0yhd.js.map → chunk-gayk9ew1.js.map} +1 -1
  15. package/dist/{chunk-rkrp4ysw.js → chunk-s96k41p3.js} +4 -4
  16. package/dist/{chunk-rkrp4ysw.js.map → chunk-s96k41p3.js.map} +1 -1
  17. package/dist/{chunk-efqd0598.js → chunk-wvnn9g55.js} +4 -4
  18. package/dist/{chunk-efqd0598.js.map → chunk-wvnn9g55.js.map} +1 -1
  19. package/dist/compiled-template.js +2 -2
  20. package/dist/compiled-template.js.map +1 -1
  21. package/dist/errors.js +2 -2
  22. package/dist/errors.js.map +1 -1
  23. package/dist/executor.js +2 -2
  24. package/dist/executor.js.map +1 -1
  25. package/dist/index.js +2 -2
  26. package/dist/index.js.map +1 -1
  27. package/dist/parser.js +2 -2
  28. package/dist/parser.js.map +1 -1
  29. package/dist/schema-resolver.js +2 -2
  30. package/dist/schema-resolver.js.map +1 -1
  31. package/dist/typebars.js +2 -2
  32. package/dist/typebars.js.map +8 -3
  33. package/dist/types.js +2 -2
  34. package/dist/types.js.map +1 -1
  35. package/dist/utils.js +2 -2
  36. package/dist/utils.js.map +1 -1
  37. package/package.json +2 -2
  38. package/dist/chunk-t6n956qz.js +0 -4
  39. package/dist/chunk-xd2vmd03.js +0 -5
  40. package/dist/chunk-xd2vmd03.js.map +0 -14
@@ -1,14 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/typebars.ts", "../src/helpers/helper-factory.ts", "../src/helpers/utils.ts", "../src/helpers/logical-helpers.ts", "../src/helpers/math-helpers.ts"],
4
- "sourcesContent": [
5
- "import Handlebars from \"handlebars\";\nimport type { JSONSchema7 } from \"json-schema\";\nimport { analyzeFromAst } from \"./analyzer.ts\";\nimport {\n\tCompiledTemplate,\n\ttype CompiledTemplateOptions,\n} from \"./compiled-template.ts\";\nimport { TemplateAnalysisError } from \"./errors.ts\";\nimport { executeFromAst } from \"./executor.ts\";\nimport { LogicalHelpers, MathHelpers } from \"./helpers/index.ts\";\nimport { parse } from \"./parser.ts\";\nimport type {\n\tAnalysisResult,\n\tAnalyzeAndExecuteOptions,\n\tExecuteOptions,\n\tHelperDefinition,\n\tTemplateEngineOptions,\n\tTemplateInput,\n\tValidationResult,\n} from \"./types.ts\";\nimport {\n\tinferPrimitiveSchema,\n\tisLiteralInput,\n\tisObjectInput,\n} from \"./types.ts\";\nimport {\n\taggregateObjectAnalysis,\n\taggregateObjectAnalysisAndExecution,\n\tLRUCache,\n} from \"./utils.ts\";\n\n// ─── Typebars ────────────────────────────────────────────────────────────────\n// Public entry point of the template engine. Orchestrates three phases:\n//\n// 1. **Parsing** — transforms the template string into an AST (via Handlebars)\n// 2. **Analysis** — static validation + return type inference\n// 3. **Execution** — renders the template with real data\n//\n// ─── Architecture v2 ─────────────────────────────────────────────────────────\n// - **LRU cache** for parsed ASTs and compiled Handlebars templates\n// - **Isolated Handlebars environment** per instance (custom helpers)\n// - **`compile()` pattern**: parse-once / execute-many\n// - **`validate()` method**: API shortcut without `outputSchema`\n// - **`registerHelper()`**: custom helpers with static typing\n// - **`ExecuteOptions`**: options object for `execute()`\n//\n// ─── Template Identifiers ────────────────────────────────────────────────────\n// The `{{key:N}}` syntax allows referencing variables from specific data\n// sources, identified by an integer N.\n//\n// - `identifierSchemas`: mapping `{ [id]: JSONSchema7 }` for static analysis\n// - `identifierData`: mapping `{ [id]: Record<string, unknown> }` for execution\n//\n// Usage:\n// engine.execute(\"{{meetingId:1}}\", data, { identifierData: { 1: node1Data } });\n// engine.analyze(\"{{meetingId:1}}\", schema, { 1: node1Schema });\n\n// ─── Main Class ──────────────────────────────────────────────────────────────\n\nexport class Typebars {\n\t/** Isolated Handlebars environment — each engine has its own helpers */\n\tprivate readonly hbs: typeof Handlebars;\n\n\t/** LRU cache of parsed ASTs (avoids re-parsing) */\n\tprivate readonly astCache: LRUCache<string, hbs.AST.Program>;\n\n\t/** LRU cache of compiled Handlebars templates (avoids recompilation) */\n\tprivate readonly compilationCache: LRUCache<\n\t\tstring,\n\t\tHandlebarsTemplateDelegate\n\t>;\n\n\t/** Custom helpers registered on this instance */\n\tprivate readonly helpers = new Map<string, HelperDefinition>();\n\n\tconstructor(options: TemplateEngineOptions = {}) {\n\t\tthis.hbs = Handlebars.create();\n\t\tthis.astCache = new LRUCache(options.astCacheSize ?? 256);\n\t\tthis.compilationCache = new LRUCache(options.compilationCacheSize ?? 256);\n\n\t\t// ── Built-in helpers ─────────────────────────────────────────────\n\t\tnew MathHelpers().register(this);\n\t\tnew LogicalHelpers().register(this);\n\n\t\t// ── Custom helpers via options ───────────────────────────────────\n\t\tif (options.helpers) {\n\t\t\tfor (const helper of options.helpers) {\n\t\t\t\tconst { name, ...definition } = helper;\n\t\t\t\tthis.registerHelper(name, definition);\n\t\t\t}\n\t\t}\n\t}\n\n\t// ─── Compilation ───────────────────────────────────────────────────────\n\n\t/**\n\t * Compiles a template and returns a `CompiledTemplate` ready to be\n\t * executed or analyzed without re-parsing.\n\t *\n\t * Accepts a `TemplateInput`: string, number, boolean, null, or object.\n\t * For objects, each property is compiled recursively.\n\t *\n\t * @param template - The template to compile\n\t * @returns A reusable `CompiledTemplate`\n\t */\n\tcompile(template: TemplateInput): CompiledTemplate {\n\t\tif (isObjectInput(template)) {\n\t\t\tconst children: Record<string, CompiledTemplate> = {};\n\t\t\tfor (const [key, value] of Object.entries(template)) {\n\t\t\t\tchildren[key] = this.compile(value);\n\t\t\t}\n\t\t\treturn CompiledTemplate.fromObject(children, {\n\t\t\t\thelpers: this.helpers,\n\t\t\t\thbs: this.hbs,\n\t\t\t\tcompilationCache: this.compilationCache,\n\t\t\t});\n\t\t}\n\t\tif (isLiteralInput(template)) {\n\t\t\treturn CompiledTemplate.fromLiteral(template, {\n\t\t\t\thelpers: this.helpers,\n\t\t\t\thbs: this.hbs,\n\t\t\t\tcompilationCache: this.compilationCache,\n\t\t\t});\n\t\t}\n\t\tconst ast = this.getCachedAst(template);\n\t\tconst options: CompiledTemplateOptions = {\n\t\t\thelpers: this.helpers,\n\t\t\thbs: this.hbs,\n\t\t\tcompilationCache: this.compilationCache,\n\t\t};\n\t\treturn CompiledTemplate.fromTemplate(ast, template, options);\n\t}\n\n\t// ─── Static Analysis ─────────────────────────────────────────────────────\n\n\t/**\n\t * Statically analyzes a template against a JSON Schema v7 describing\n\t * the available context.\n\t *\n\t * Accepts a `TemplateInput`: string, number, boolean, null, or object.\n\t * For objects, each property is analyzed recursively and the\n\t * `outputSchema` reflects the object structure with resolved types.\n\t *\n\t * @param template - The template to analyze\n\t * @param inputSchema - JSON Schema v7 describing the available variables\n\t * @param identifierSchemas - (optional) Schemas by identifier `{ [id]: JSONSchema7 }`\n\t */\n\tanalyze(\n\t\ttemplate: TemplateInput,\n\t\tinputSchema: JSONSchema7,\n\t\tidentifierSchemas?: Record<number, JSONSchema7>,\n\t): AnalysisResult {\n\t\tif (isObjectInput(template)) {\n\t\t\treturn aggregateObjectAnalysis(Object.keys(template), (key) =>\n\t\t\t\tthis.analyze(\n\t\t\t\t\ttemplate[key] as TemplateInput,\n\t\t\t\t\tinputSchema,\n\t\t\t\t\tidentifierSchemas,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\tif (isLiteralInput(template)) {\n\t\t\treturn {\n\t\t\t\tvalid: true,\n\t\t\t\tdiagnostics: [],\n\t\t\t\toutputSchema: inferPrimitiveSchema(template),\n\t\t\t};\n\t\t}\n\t\tconst ast = this.getCachedAst(template);\n\t\treturn analyzeFromAst(ast, template, inputSchema, {\n\t\t\tidentifierSchemas,\n\t\t\thelpers: this.helpers,\n\t\t});\n\t}\n\n\t// ─── Validation ──────────────────────────────────────────────────────────\n\n\t/**\n\t * Validates a template against a schema without returning the output type.\n\t *\n\t * This is an API shortcut for `analyze()` that only returns `valid` and\n\t * `diagnostics`, without `outputSchema`. The full analysis (including type\n\t * inference) is executed internally — this method provides no performance\n\t * gain, only a simplified API.\n\t *\n\t * @param template - The template to validate\n\t * @param inputSchema - JSON Schema v7 describing the available variables\n\t * @param identifierSchemas - (optional) Schemas by identifier\n\t */\n\tvalidate(\n\t\ttemplate: TemplateInput,\n\t\tinputSchema: JSONSchema7,\n\t\tidentifierSchemas?: Record<number, JSONSchema7>,\n\t): ValidationResult {\n\t\tconst analysis = this.analyze(template, inputSchema, identifierSchemas);\n\t\treturn {\n\t\t\tvalid: analysis.valid,\n\t\t\tdiagnostics: analysis.diagnostics,\n\t\t};\n\t}\n\n\t// ─── Syntax Validation ───────────────────────────────────────────────────\n\n\t/**\n\t * Checks only that the template syntax is valid (parsing).\n\t * Does not require a schema — useful for quick feedback in an editor.\n\t *\n\t * For objects, recursively checks each property.\n\t *\n\t * @param template - The template to validate\n\t * @returns `true` if the template is syntactically correct\n\t */\n\tisValidSyntax(template: TemplateInput): boolean {\n\t\tif (isObjectInput(template)) {\n\t\t\treturn Object.values(template).every((v) => this.isValidSyntax(v));\n\t\t}\n\t\tif (isLiteralInput(template)) return true;\n\t\ttry {\n\t\t\tthis.getCachedAst(template);\n\t\t\treturn true;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t// ─── Execution ───────────────────────────────────────────────────────────\n\n\t/**\n\t * Executes a template with the provided data.\n\t *\n\t * Accepts a `TemplateInput`: string, number, boolean, null, or object.\n\t * For objects, each property is executed recursively and an object with\n\t * resolved values is returned.\n\t *\n\t * If a `schema` is provided in options, static analysis is performed\n\t * before execution. A `TemplateAnalysisError` is thrown on errors.\n\t *\n\t * @param template - The template to execute\n\t * @param data - The context data for rendering\n\t * @param options - Execution options (schema, identifierData, identifierSchemas)\n\t * @returns The execution result\n\t */\n\texecute(\n\t\ttemplate: TemplateInput,\n\t\tdata: Record<string, unknown>,\n\t\toptions?: ExecuteOptions,\n\t): unknown {\n\t\t// ── Object template → recursive execution ────────────────────────────\n\t\tif (isObjectInput(template)) {\n\t\t\tconst result: Record<string, unknown> = {};\n\t\t\tfor (const [key, value] of Object.entries(template)) {\n\t\t\t\tresult[key] = this.execute(value, data, options);\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\t// ── Passthrough for literal values ────────────────────────────────────\n\t\tif (isLiteralInput(template)) return template;\n\n\t\t// ── Parse once ───────────────────────────────────────────────────────\n\t\tconst ast = this.getCachedAst(template);\n\n\t\t// ── Pre-execution static validation ──────────────────────────────────\n\t\tif (options?.schema) {\n\t\t\tconst analysis = analyzeFromAst(ast, template, options.schema, {\n\t\t\t\tidentifierSchemas: options.identifierSchemas,\n\t\t\t\thelpers: this.helpers,\n\t\t\t});\n\t\t\tif (!analysis.valid) {\n\t\t\t\tthrow new TemplateAnalysisError(analysis.diagnostics);\n\t\t\t}\n\t\t}\n\n\t\t// ── Execution ────────────────────────────────────────────────────────\n\t\treturn executeFromAst(ast, template, data, {\n\t\t\tidentifierData: options?.identifierData,\n\t\t\thbs: this.hbs,\n\t\t\tcompilationCache: this.compilationCache,\n\t\t});\n\t}\n\n\t// ─── Combined Shortcuts ──────────────────────────────────────────────────\n\n\t/**\n\t * Analyzes a template and, if valid, executes it with the provided data.\n\t * Returns both the analysis result and the executed value.\n\t *\n\t * For objects, each property is analyzed and executed recursively.\n\t * The entire object is considered invalid if at least one property is.\n\t *\n\t * @param template - The template\n\t * @param inputSchema - JSON Schema v7 describing the available variables\n\t * @param data - The context data for rendering\n\t * @param options - (optional) Options for template identifiers\n\t * @returns An object `{ analysis, value }` where `value` is `undefined`\n\t * if analysis failed.\n\t */\n\tanalyzeAndExecute(\n\t\ttemplate: TemplateInput,\n\t\tinputSchema: JSONSchema7,\n\t\tdata: Record<string, unknown>,\n\t\toptions?: AnalyzeAndExecuteOptions,\n\t): { analysis: AnalysisResult; value: unknown } {\n\t\tif (isObjectInput(template)) {\n\t\t\treturn aggregateObjectAnalysisAndExecution(Object.keys(template), (key) =>\n\t\t\t\tthis.analyzeAndExecute(\n\t\t\t\t\ttemplate[key] as TemplateInput,\n\t\t\t\t\tinputSchema,\n\t\t\t\t\tdata,\n\t\t\t\t\toptions,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tif (isLiteralInput(template)) {\n\t\t\treturn {\n\t\t\t\tanalysis: {\n\t\t\t\t\tvalid: true,\n\t\t\t\t\tdiagnostics: [],\n\t\t\t\t\toutputSchema: inferPrimitiveSchema(template),\n\t\t\t\t},\n\t\t\t\tvalue: template,\n\t\t\t};\n\t\t}\n\n\t\tconst ast = this.getCachedAst(template);\n\t\tconst analysis = analyzeFromAst(ast, template, inputSchema, {\n\t\t\tidentifierSchemas: options?.identifierSchemas,\n\t\t\thelpers: this.helpers,\n\t\t});\n\n\t\tif (!analysis.valid) {\n\t\t\treturn { analysis, value: undefined };\n\t\t}\n\n\t\tconst value = executeFromAst(ast, template, data, {\n\t\t\tidentifierData: options?.identifierData,\n\t\t\thbs: this.hbs,\n\t\t\tcompilationCache: this.compilationCache,\n\t\t});\n\t\treturn { analysis, value };\n\t}\n\n\t// ─── Custom Helper Management ──────────────────────────────────────────\n\n\t/**\n\t * Registers a custom helper on this engine instance.\n\t *\n\t * The helper is available for both execution (via Handlebars) and\n\t * static analysis (via its declared `returnType`).\n\t *\n\t * @param name - Helper name (e.g. `\"uppercase\"`)\n\t * @param definition - Helper definition (implementation + return type)\n\t * @returns `this` to allow chaining\n\t */\n\tregisterHelper(name: string, definition: HelperDefinition): this {\n\t\tthis.helpers.set(name, definition);\n\t\tthis.hbs.registerHelper(name, definition.fn);\n\n\t\t// Invalidate the compilation cache because helpers have changed\n\t\tthis.compilationCache.clear();\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Removes a custom helper from this engine instance.\n\t *\n\t * @param name - Name of the helper to remove\n\t * @returns `this` to allow chaining\n\t */\n\tunregisterHelper(name: string): this {\n\t\tthis.helpers.delete(name);\n\t\tthis.hbs.unregisterHelper(name);\n\n\t\t// Invalidate the compilation cache\n\t\tthis.compilationCache.clear();\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Checks whether a helper is registered on this instance.\n\t *\n\t * @param name - Helper name\n\t * @returns `true` if the helper is registered\n\t */\n\thasHelper(name: string): boolean {\n\t\treturn this.helpers.has(name);\n\t}\n\n\t// ─── Cache Management ──────────────────────────────────────────────────\n\n\t/**\n\t * Clears all internal caches (AST + compilation).\n\t *\n\t * Useful after a configuration change or to free memory.\n\t */\n\tclearCaches(): void {\n\t\tthis.astCache.clear();\n\t\tthis.compilationCache.clear();\n\t}\n\n\t// ─── Internals ─────────────────────────────────────────────────────────\n\n\t/**\n\t * Retrieves the AST of a template from the cache, or parses and caches it.\n\t */\n\tprivate getCachedAst(template: string): hbs.AST.Program {\n\t\tlet ast = this.astCache.get(template);\n\t\tif (!ast) {\n\t\t\tast = parse(template);\n\t\t\tthis.astCache.set(template, ast);\n\t\t}\n\t\treturn ast;\n\t}\n}\n",
6
- "import type { HelperDefinition } from \"../types.ts\";\n\n// ─── HelperFactory ───────────────────────────────────────────────────────────\n// Abstract base class that enforces a consistent pattern for creating,\n// registering, and managing groups of related helpers.\n//\n// Every helper factory (MathHelpers, LogicalHelpers, …) must extend this class\n// and implement the `buildDefinitions()` method to populate its helpers.\n//\n// The base class provides:\n// - Lazy-cached definitions, helper names, and name set\n// - `register()` / `unregister()` for any `HelperRegistry`\n// - `getHelperNames()` / `isHelper()` for introspection\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n/** Minimal registration interface — avoids tight coupling with Typebars */\nexport interface HelperRegistry {\n\tregisterHelper(name: string, definition: HelperDefinition): unknown;\n\tunregisterHelper(name: string): unknown;\n}\n\n// ─── Abstract Base Class ─────────────────────────────────────────────────────\n\nexport abstract class HelperFactory {\n\t// ── Lazy caches (populated on first access) ──────────────────────────\n\tprivate _definitions: Map<string, HelperDefinition> | null = null;\n\tprivate _helperNames: readonly string[] | null = null;\n\tprivate _helperNamesSet: ReadonlySet<string> | null = null;\n\n\t// ── Abstract method — must be implemented by each factory ────────────\n\n\t/**\n\t * Populates the `defs` map with all helper definitions.\n\t *\n\t * Subclasses implement this method to register their helpers:\n\t * ```\n\t * protected buildDefinitions(defs: Map<string, HelperDefinition>): void {\n\t * defs.set(\"myHelper\", {\n\t * fn: (a: unknown) => String(a).toUpperCase(),\n\t * params: [{ name: \"a\", type: { type: \"string\" } }],\n\t * returnType: { type: \"string\" },\n\t * description: \"Converts to uppercase\",\n\t * });\n\t * }\n\t * ```\n\t *\n\t * @param defs - The map to populate with `[name, HelperDefinition]` entries\n\t */\n\tprotected abstract buildDefinitions(\n\t\tdefs: Map<string, HelperDefinition>,\n\t): void;\n\n\t// ── Public API ───────────────────────────────────────────────────────\n\n\t/**\n\t * Returns all definitions as a `Map<name, HelperDefinition>`.\n\t * The map is lazily built and cached on first access.\n\t */\n\tgetDefinitions(): Map<string, HelperDefinition> {\n\t\tif (!this._definitions) {\n\t\t\tthis._definitions = new Map();\n\t\t\tthis.buildDefinitions(this._definitions);\n\t\t}\n\t\treturn this._definitions;\n\t}\n\n\t/**\n\t * Returns the list of all helper names provided by this factory.\n\t */\n\tgetHelperNames(): readonly string[] {\n\t\tif (!this._helperNames) {\n\t\t\tthis._helperNames = [...this.getDefinitions().keys()];\n\t\t}\n\t\treturn this._helperNames;\n\t}\n\n\t/**\n\t * Checks whether a helper name belongs to this factory.\n\t *\n\t * @param name - The helper name to check\n\t */\n\tisHelper(name: string): boolean {\n\t\tif (!this._helperNamesSet) {\n\t\t\tthis._helperNamesSet = new Set(this.getHelperNames());\n\t\t}\n\t\treturn this._helperNamesSet.has(name);\n\t}\n\n\t/**\n\t * Registers all helpers from this factory on the given registry.\n\t *\n\t * @param registry - The engine or target registry\n\t */\n\tregister(registry: HelperRegistry): void {\n\t\tfor (const [name, def] of this.getDefinitions()) {\n\t\t\tregistry.registerHelper(name, def);\n\t\t}\n\t}\n\n\t/**\n\t * Removes all helpers from this factory from the given registry.\n\t *\n\t * @param registry - The engine or target registry\n\t */\n\tunregister(registry: HelperRegistry): void {\n\t\tfor (const name of this.getHelperNames()) {\n\t\t\tregistry.unregisterHelper(name);\n\t\t}\n\t}\n}\n",
7
- "// ─── Shared Helper Utilities ─────────────────────────────────────────────────\n// Common utilities used across helper packs (MathHelpers, LogicalHelpers, …).\n\n/**\n * Converts an unknown value to a number.\n *\n * Conversion rules:\n * - `number` → returned as-is\n * - `string` → parsed via `Number()`; returns `fallback` if result is `NaN`\n * - `boolean` → `true` → `1`, `false` → `0`\n * - anything else → `fallback`\n *\n * The `fallback` parameter lets each consumer choose the right semantics:\n * - **Math helpers** pass `0` so that invalid inputs silently become zero\n * (e.g. `add(\"abc\", 5)` → `5`).\n * - **Logical helpers** pass `NaN` (the default) so that invalid comparisons\n * evaluate to `false` (e.g. `lt(\"abc\", 5)` → `false`).\n *\n * @param value - The value to convert\n * @param fallback - Value returned when conversion fails (default: `NaN`)\n */\nexport function toNumber(value: unknown, fallback: number = NaN): number {\n\tif (typeof value === \"number\") return value;\n\tif (typeof value === \"string\") {\n\t\tconst n = Number(value);\n\t\treturn Number.isNaN(n) ? fallback : n;\n\t}\n\tif (typeof value === \"boolean\") return value ? 1 : 0;\n\treturn fallback;\n}\n",
8
- "import type { HelperDefinition } from \"../types.ts\";\nimport { HelperFactory } from \"./helper-factory.ts\";\nimport { toNumber } from \"./utils.ts\";\n\n// ─── LogicalHelpers ──────────────────────────────────────────────────────────\n// Aggregates all logical / comparison helpers for the template engine.\n//\n// Provides two kinds of helpers:\n//\n// 1. **Named helpers** — one helper per operation (`eq`, `lt`, `not`, …)\n// Usage: `{{#if (eq status \"active\")}}`, `{{#if (lt price 100)}}`\n//\n// 2. **Generic `compare` helper** — single helper with the operator as a param\n// Usage: `{{#if (compare a \"<\" b)}}`, `{{#if (compare name \"==\" \"Alice\")}}`\n//\n// ─── Registration ────────────────────────────────────────────────────────────\n// LogicalHelpers are automatically pre-registered by the `Typebars` constructor.\n// They can also be registered manually on any object implementing\n// `HelperRegistry`:\n//\n// const factory = new LogicalHelpers();\n// factory.register(engine); // registers all helpers\n// factory.unregister(engine); // removes all helpers\n//\n// ─── Supported operators (generic `compare` helper) ──────────────────────────\n// == Loose equality\n// === Strict equality\n// != Loose inequality\n// !== Strict inequality\n// < Less than\n// <= Less than or equal\n// > Greater than\n// >= Greater than or equal\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n/** Operators supported by the generic `compare` helper */\ntype CompareOperator = \"==\" | \"===\" | \"!=\" | \"!==\" | \"<\" | \"<=\" | \">\" | \">=\";\n\nconst SUPPORTED_OPERATORS = new Set<string>([\n\t\"==\",\n\t\"===\",\n\t\"!=\",\n\t\"!==\",\n\t\"<\",\n\t\"<=\",\n\t\">\",\n\t\">=\",\n]);\n\n// ─── Internal utilities ─────────────────────────────────────────────────────\n\n/**\n * Applies a comparison operator to two operands.\n */\nfunction applyOperator(a: unknown, op: CompareOperator, b: unknown): boolean {\n\tswitch (op) {\n\t\tcase \"==\":\n\t\t\t// biome-ignore lint/suspicious/noDoubleEquals: intentional loose equality\n\t\t\treturn a == b;\n\t\tcase \"===\":\n\t\t\treturn a === b;\n\t\tcase \"!=\":\n\t\t\t// biome-ignore lint/suspicious/noDoubleEquals: intentional loose inequality\n\t\t\treturn a != b;\n\t\tcase \"!==\":\n\t\t\treturn a !== b;\n\t\tcase \"<\":\n\t\t\treturn toNumber(a) < toNumber(b);\n\t\tcase \"<=\":\n\t\t\treturn toNumber(a) <= toNumber(b);\n\t\tcase \">\":\n\t\t\treturn toNumber(a) > toNumber(b);\n\t\tcase \">=\":\n\t\t\treturn toNumber(a) >= toNumber(b);\n\t}\n}\n\n/**\n * Checks whether a value is a Handlebars options object.\n * Handlebars always passes an options object as the last argument to helpers.\n */\nfunction isHandlebarsOptions(value: unknown): boolean {\n\treturn (\n\t\tvalue !== null &&\n\t\ttypeof value === \"object\" &&\n\t\t\"hash\" in (value as Record<string, unknown>) &&\n\t\t\"name\" in (value as Record<string, unknown>)\n\t);\n}\n\n// ─── Main class ─────────────────────────────────────────────────────────────\n\nexport class LogicalHelpers extends HelperFactory {\n\t// ─── buildDefinitions (required by HelperFactory) ──────────────────\n\n\tprotected buildDefinitions(defs: Map<string, HelperDefinition>): void {\n\t\tthis.registerEquality(defs);\n\t\tthis.registerComparison(defs);\n\t\tthis.registerLogicalOperators(defs);\n\t\tthis.registerCollectionHelpers(defs);\n\t\tthis.registerGenericCompare(defs);\n\t}\n\n\t// ── Equality helpers ─────────────────────────────────────────────\n\n\t/** Registers eq, ne / neq */\n\tprivate registerEquality(defs: Map<string, HelperDefinition>): void {\n\t\t// eq — Strict equality: {{#if (eq a b)}}\n\t\tdefs.set(\"eq\", {\n\t\t\tfn: (a: unknown, b: unknown) => a === b,\n\t\t\tparams: [\n\t\t\t\t{ name: \"a\", description: \"Left value\" },\n\t\t\t\t{ name: \"b\", description: \"Right value\" },\n\t\t\t],\n\t\t\treturnType: { type: \"boolean\" },\n\t\t\tdescription: \"Returns true if a is strictly equal to b: {{#if (eq a b)}}\",\n\t\t});\n\n\t\t// ne / neq — Strict inequality: {{#if (ne a b)}}\n\t\tconst neDef: HelperDefinition = {\n\t\t\tfn: (a: unknown, b: unknown) => a !== b,\n\t\t\tparams: [\n\t\t\t\t{ name: \"a\", description: \"Left value\" },\n\t\t\t\t{ name: \"b\", description: \"Right value\" },\n\t\t\t],\n\t\t\treturnType: { type: \"boolean\" },\n\t\t\tdescription:\n\t\t\t\t\"Returns true if a is not strictly equal to b: {{#if (ne a b)}}\",\n\t\t};\n\t\tdefs.set(\"ne\", neDef);\n\t\tdefs.set(\"neq\", neDef);\n\t}\n\n\t// ── Comparison helpers ───────────────────────────────────────────\n\n\t/** Registers lt, lte / le, gt, gte / ge */\n\tprivate registerComparison(defs: Map<string, HelperDefinition>): void {\n\t\t// lt — Less than: {{#if (lt a b)}}\n\t\tdefs.set(\"lt\", {\n\t\t\tfn: (a: unknown, b: unknown) => toNumber(a) < toNumber(b),\n\t\t\tparams: [\n\t\t\t\t{ name: \"a\", type: { type: \"number\" }, description: \"Left operand\" },\n\t\t\t\t{ name: \"b\", type: { type: \"number\" }, description: \"Right operand\" },\n\t\t\t],\n\t\t\treturnType: { type: \"boolean\" },\n\t\t\tdescription: \"Returns true if a < b: {{#if (lt a b)}}\",\n\t\t});\n\n\t\t// lte / le — Less than or equal: {{#if (lte a b)}}\n\t\tconst lteDef: HelperDefinition = {\n\t\t\tfn: (a: unknown, b: unknown) => toNumber(a) <= toNumber(b),\n\t\t\tparams: [\n\t\t\t\t{ name: \"a\", type: { type: \"number\" }, description: \"Left operand\" },\n\t\t\t\t{ name: \"b\", type: { type: \"number\" }, description: \"Right operand\" },\n\t\t\t],\n\t\t\treturnType: { type: \"boolean\" },\n\t\t\tdescription: \"Returns true if a <= b: {{#if (lte a b)}}\",\n\t\t};\n\t\tdefs.set(\"lte\", lteDef);\n\t\tdefs.set(\"le\", lteDef);\n\n\t\t// gt — Greater than: {{#if (gt a b)}}\n\t\tdefs.set(\"gt\", {\n\t\t\tfn: (a: unknown, b: unknown) => toNumber(a) > toNumber(b),\n\t\t\tparams: [\n\t\t\t\t{ name: \"a\", type: { type: \"number\" }, description: \"Left operand\" },\n\t\t\t\t{ name: \"b\", type: { type: \"number\" }, description: \"Right operand\" },\n\t\t\t],\n\t\t\treturnType: { type: \"boolean\" },\n\t\t\tdescription: \"Returns true if a > b: {{#if (gt a b)}}\",\n\t\t});\n\n\t\t// gte / ge — Greater than or equal: {{#if (gte a b)}}\n\t\tconst gteDef: HelperDefinition = {\n\t\t\tfn: (a: unknown, b: unknown) => toNumber(a) >= toNumber(b),\n\t\t\tparams: [\n\t\t\t\t{ name: \"a\", type: { type: \"number\" }, description: \"Left operand\" },\n\t\t\t\t{ name: \"b\", type: { type: \"number\" }, description: \"Right operand\" },\n\t\t\t],\n\t\t\treturnType: { type: \"boolean\" },\n\t\t\tdescription: \"Returns true if a >= b: {{#if (gte a b)}}\",\n\t\t};\n\t\tdefs.set(\"gte\", gteDef);\n\t\tdefs.set(\"ge\", gteDef);\n\t}\n\n\t// ── Logical operators ────────────────────────────────────────────\n\n\t/** Registers not, and, or */\n\tprivate registerLogicalOperators(defs: Map<string, HelperDefinition>): void {\n\t\t// not — Logical negation: {{#if (not active)}}\n\t\tdefs.set(\"not\", {\n\t\t\tfn: (value: unknown) => !value,\n\t\t\tparams: [{ name: \"value\", description: \"Value to negate\" }],\n\t\t\treturnType: { type: \"boolean\" },\n\t\t\tdescription: \"Returns true if the value is falsy: {{#if (not active)}}\",\n\t\t});\n\n\t\t// and — Logical AND: {{#if (and a b)}}\n\t\tdefs.set(\"and\", {\n\t\t\tfn: (a: unknown, b: unknown) => !!a && !!b,\n\t\t\tparams: [\n\t\t\t\t{ name: \"a\", description: \"First condition\" },\n\t\t\t\t{ name: \"b\", description: \"Second condition\" },\n\t\t\t],\n\t\t\treturnType: { type: \"boolean\" },\n\t\t\tdescription: \"Returns true if both values are truthy: {{#if (and a b)}}\",\n\t\t});\n\n\t\t// or — Logical OR: {{#if (or a b)}}\n\t\tdefs.set(\"or\", {\n\t\t\tfn: (a: unknown, b: unknown) => !!a || !!b,\n\t\t\tparams: [\n\t\t\t\t{ name: \"a\", description: \"First condition\" },\n\t\t\t\t{ name: \"b\", description: \"Second condition\" },\n\t\t\t],\n\t\t\treturnType: { type: \"boolean\" },\n\t\t\tdescription:\n\t\t\t\t\"Returns true if at least one value is truthy: {{#if (or a b)}}\",\n\t\t});\n\t}\n\n\t// ── Collection / String helpers ──────────────────────────────────\n\n\t/** Registers contains, in */\n\tprivate registerCollectionHelpers(defs: Map<string, HelperDefinition>): void {\n\t\t// contains — Checks if a string contains a substring or an array contains an element\n\t\t// Usage: {{#if (contains name \"ali\")}} or {{#if (contains tags \"admin\")}}\n\t\tdefs.set(\"contains\", {\n\t\t\tfn: (haystack: unknown, needle: unknown) => {\n\t\t\t\tif (typeof haystack === \"string\") {\n\t\t\t\t\treturn haystack.includes(String(needle));\n\t\t\t\t}\n\t\t\t\tif (Array.isArray(haystack)) {\n\t\t\t\t\treturn haystack.includes(needle);\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\tparams: [\n\t\t\t\t{\n\t\t\t\t\tname: \"haystack\",\n\t\t\t\t\tdescription: \"String or array to search in\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: \"needle\",\n\t\t\t\t\tdescription: \"Value to search for\",\n\t\t\t\t},\n\t\t\t],\n\t\t\treturnType: { type: \"boolean\" },\n\t\t\tdescription:\n\t\t\t\t'Checks if a string contains a substring or an array contains an element: {{#if (contains name \"ali\")}}',\n\t\t});\n\n\t\t// in — Checks if a value is one of the provided options (variadic)\n\t\t// Usage: {{#if (in status \"active\" \"pending\" \"draft\")}}\n\t\tdefs.set(\"in\", {\n\t\t\tfn: (...args: unknown[]) => {\n\t\t\t\t// Handlebars always passes an options object as the last argument.\n\t\t\t\t// We need to exclude it from the candidate list.\n\t\t\t\tif (args.length < 2) return false;\n\n\t\t\t\tconst value = args[0];\n\t\t\t\t// Filter out the trailing Handlebars options object\n\t\t\t\tconst candidates = args.slice(1).filter((a) => !isHandlebarsOptions(a));\n\n\t\t\t\treturn candidates.some((c) => c === value);\n\t\t\t},\n\t\t\tparams: [\n\t\t\t\t{\n\t\t\t\t\tname: \"value\",\n\t\t\t\t\tdescription: \"Value to look for\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: \"candidates\",\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t'One or more candidate values (variadic): {{#if (in status \"active\" \"pending\")}}',\n\t\t\t\t},\n\t\t\t],\n\t\t\treturnType: { type: \"boolean\" },\n\t\t\tdescription:\n\t\t\t\t'Checks if a value is one of the provided options: {{#if (in status \"active\" \"pending\" \"draft\")}}',\n\t\t});\n\t}\n\n\t// ── Generic helper ───────────────────────────────────────────────\n\n\t/** Registers the generic `compare` helper with operator as a parameter */\n\tprivate registerGenericCompare(defs: Map<string, HelperDefinition>): void {\n\t\t// Usage: {{#if (compare a \"<\" b)}}, {{#if (compare name \"===\" \"Alice\")}}\n\t\tdefs.set(\"compare\", {\n\t\t\tfn: (a: unknown, operator: unknown, b: unknown) => {\n\t\t\t\tconst op = String(operator);\n\t\t\t\tif (!SUPPORTED_OPERATORS.has(op)) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`[compare helper] Unknown operator \"${op}\". ` +\n\t\t\t\t\t\t\t`Supported: ${[...SUPPORTED_OPERATORS].join(\", \")} `,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn applyOperator(a, op as CompareOperator, b);\n\t\t\t},\n\t\t\tparams: [\n\t\t\t\t{ name: \"a\", description: \"Left operand\" },\n\t\t\t\t{\n\t\t\t\t\tname: \"operator\",\n\t\t\t\t\ttype: {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tenum: [\"==\", \"===\", \"!=\", \"!==\", \"<\", \"<=\", \">\", \">=\"],\n\t\t\t\t\t},\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t'Comparison operator: \"==\", \"===\", \"!=\", \"!==\", \"<\", \"<=\", \">\", \">=\"',\n\t\t\t\t},\n\t\t\t\t{ name: \"b\", description: \"Right operand\" },\n\t\t\t],\n\t\t\treturnType: { type: \"boolean\" },\n\t\t\tdescription:\n\t\t\t\t'Generic comparison helper with operator as parameter: {{#if (compare a \"<\" b)}}. ' +\n\t\t\t\t\"Supported operators: ==, ===, !=, !==, <, <=, >, >=\",\n\t\t});\n\t}\n}\n",
9
- "import type { HelperDefinition } from \"../types.ts\";\nimport { HelperFactory } from \"./helper-factory.ts\";\nimport { toNumber } from \"./utils.ts\";\n\n// ─── MathHelpers ─────────────────────────────────────────────────────────────\n// Aggregates all math-related helpers for the template engine.\n//\n// Provides two kinds of helpers:\n//\n// 1. **Named helpers** — one helper per operation (`add`, `subtract`, `divide`, …)\n// Usage: `{{ add a b }}`, `{{ abs value }}`, `{{ round value 2 }}`\n//\n// 2. **Generic `math` helper** — single helper with the operator as a parameter\n// Usage: `{{ math a \"+\" b }}`, `{{ math a \"/\" b }}`, `{{ math a \"**\" b }}`\n//\n// ─── Registration ────────────────────────────────────────────────────────────\n// MathHelpers are automatically pre-registered by the `Typebars` constructor.\n// They can also be registered manually on any object implementing\n// `HelperRegistry`:\n//\n// const factory = new MathHelpers();\n// factory.register(engine); // registers all helpers\n// factory.unregister(engine); // removes all helpers\n//\n// ─── Supported operators (generic `math` helper) ─────────────────────────────\n// + Addition\n// - Subtraction\n// * Multiplication\n// / Division\n// % Modulo\n// ** Exponentiation\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n/** Operators supported by the generic `math` helper */\ntype MathOperator = \"+\" | \"-\" | \"*\" | \"/\" | \"%\" | \"**\";\n\nconst SUPPORTED_OPERATORS = new Set<string>([\"+\", \"-\", \"*\", \"/\", \"%\", \"**\"]);\n\n// ─── Internal utilities ─────────────────────────────────────────────────────\n\n/** Converts a value to a number with a fallback of `0` for math operations. */\nconst num = (value: unknown): number => toNumber(value, 0);\n\n/**\n * Applies a binary operator to two operands.\n */\nfunction applyOperator(a: number, op: MathOperator, b: number): number {\n\tswitch (op) {\n\t\tcase \"+\":\n\t\t\treturn a + b;\n\t\tcase \"-\":\n\t\t\treturn a - b;\n\t\tcase \"*\":\n\t\t\treturn a * b;\n\t\tcase \"/\":\n\t\t\treturn b === 0 ? Infinity : a / b;\n\t\tcase \"%\":\n\t\t\treturn b === 0 ? NaN : a % b;\n\t\tcase \"**\":\n\t\t\treturn a ** b;\n\t}\n}\n\n// ─── Main class ─────────────────────────────────────────────────────────────\n\nexport class MathHelpers extends HelperFactory {\n\t// ─── buildDefinitions (required by HelperFactory) ──────────────────\n\n\tprotected buildDefinitions(defs: Map<string, HelperDefinition>): void {\n\t\tthis.registerBinaryOperators(defs);\n\t\tthis.registerUnaryFunctions(defs);\n\t\tthis.registerMinMax(defs);\n\t\tthis.registerGenericMath(defs);\n\t}\n\n\t// ── Binary operators ─────────────────────────────────────────────\n\n\t/** Registers add, subtract/sub, multiply/mul, divide/div, modulo/mod, pow */\n\tprivate registerBinaryOperators(defs: Map<string, HelperDefinition>): void {\n\t\t// add — Addition : {{ add a b }}\n\t\tconst addDef: HelperDefinition = {\n\t\t\tfn: (a: unknown, b: unknown) => num(a) + num(b),\n\t\t\tparams: [\n\t\t\t\t{ name: \"a\", type: { type: \"number\" }, description: \"First operand\" },\n\t\t\t\t{ name: \"b\", type: { type: \"number\" }, description: \"Second operand\" },\n\t\t\t],\n\t\t\treturnType: { type: \"number\" },\n\t\t\tdescription: \"Adds two numbers: {{ add a b }}\",\n\t\t};\n\t\tdefs.set(\"add\", addDef);\n\n\t\t// subtract / sub — Subtraction: {{ subtract a b }} or {{ sub a b }}\n\t\tconst subtractDef: HelperDefinition = {\n\t\t\tfn: (a: unknown, b: unknown) => num(a) - num(b),\n\t\t\tparams: [\n\t\t\t\t{\n\t\t\t\t\tname: \"a\",\n\t\t\t\t\ttype: { type: \"number\" },\n\t\t\t\t\tdescription: \"Value to subtract from\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: \"b\",\n\t\t\t\t\ttype: { type: \"number\" },\n\t\t\t\t\tdescription: \"Value to subtract\",\n\t\t\t\t},\n\t\t\t],\n\t\t\treturnType: { type: \"number\" },\n\t\t\tdescription: \"Subtracts b from a: {{ subtract a b }}\",\n\t\t};\n\t\tdefs.set(\"subtract\", subtractDef);\n\t\tdefs.set(\"sub\", subtractDef);\n\n\t\t// multiply / mul — Multiplication: {{ multiply a b }} or {{ mul a b }}\n\t\tconst multiplyDef: HelperDefinition = {\n\t\t\tfn: (a: unknown, b: unknown) => num(a) * num(b),\n\t\t\tparams: [\n\t\t\t\t{ name: \"a\", type: { type: \"number\" }, description: \"First factor\" },\n\t\t\t\t{ name: \"b\", type: { type: \"number\" }, description: \"Second factor\" },\n\t\t\t],\n\t\t\treturnType: { type: \"number\" },\n\t\t\tdescription: \"Multiplies two numbers: {{ multiply a b }}\",\n\t\t};\n\t\tdefs.set(\"multiply\", multiplyDef);\n\t\tdefs.set(\"mul\", multiplyDef);\n\n\t\t// divide / div — Division: {{ divide a b }} or {{ div a b }}\n\t\tconst divideDef: HelperDefinition = {\n\t\t\tfn: (a: unknown, b: unknown) => {\n\t\t\t\tconst divisor = num(b);\n\t\t\t\treturn divisor === 0 ? Infinity : num(a) / divisor;\n\t\t\t},\n\t\t\tparams: [\n\t\t\t\t{ name: \"a\", type: { type: \"number\" }, description: \"Dividend\" },\n\t\t\t\t{ name: \"b\", type: { type: \"number\" }, description: \"Divisor\" },\n\t\t\t],\n\t\t\treturnType: { type: \"number\" },\n\t\t\tdescription:\n\t\t\t\t\"Divides a by b: {{ divide a b }}. Returns Infinity if b is 0.\",\n\t\t};\n\t\tdefs.set(\"divide\", divideDef);\n\t\tdefs.set(\"div\", divideDef);\n\n\t\t// modulo / mod — Modulo: {{ modulo a b }} or {{ mod a b }}\n\t\tconst moduloDef: HelperDefinition = {\n\t\t\tfn: (a: unknown, b: unknown) => {\n\t\t\t\tconst divisor = num(b);\n\t\t\t\treturn divisor === 0 ? NaN : num(a) % divisor;\n\t\t\t},\n\t\t\tparams: [\n\t\t\t\t{ name: \"a\", type: { type: \"number\" }, description: \"Dividend\" },\n\t\t\t\t{ name: \"b\", type: { type: \"number\" }, description: \"Divisor\" },\n\t\t\t],\n\t\t\treturnType: { type: \"number\" },\n\t\t\tdescription: \"Returns the remainder of a divided by b: {{ modulo a b }}\",\n\t\t};\n\t\tdefs.set(\"modulo\", moduloDef);\n\t\tdefs.set(\"mod\", moduloDef);\n\n\t\t// pow — Exponentiation : {{ pow base exponent }}\n\t\tdefs.set(\"pow\", {\n\t\t\tfn: (base: unknown, exponent: unknown) => num(base) ** num(exponent),\n\t\t\tparams: [\n\t\t\t\t{ name: \"base\", type: { type: \"number\" }, description: \"The base\" },\n\t\t\t\t{\n\t\t\t\t\tname: \"exponent\",\n\t\t\t\t\ttype: { type: \"number\" },\n\t\t\t\t\tdescription: \"The exponent\",\n\t\t\t\t},\n\t\t\t],\n\t\t\treturnType: { type: \"number\" },\n\t\t\tdescription:\n\t\t\t\t\"Raises base to the power of exponent: {{ pow base exponent }}\",\n\t\t});\n\t}\n\n\t// ── Unary functions ──────────────────────────────────────────────\n\n\t/** Registers abs, ceil, floor, round, sqrt */\n\tprivate registerUnaryFunctions(defs: Map<string, HelperDefinition>): void {\n\t\t// abs — Absolute value: {{ abs value }}\n\t\tdefs.set(\"abs\", {\n\t\t\tfn: (value: unknown) => Math.abs(num(value)),\n\t\t\tparams: [\n\t\t\t\t{ name: \"value\", type: { type: \"number\" }, description: \"The number\" },\n\t\t\t],\n\t\t\treturnType: { type: \"number\" },\n\t\t\tdescription: \"Returns the absolute value: {{ abs value }}\",\n\t\t});\n\n\t\t// ceil — Round up: {{ ceil value }}\n\t\tdefs.set(\"ceil\", {\n\t\t\tfn: (value: unknown) => Math.ceil(num(value)),\n\t\t\tparams: [\n\t\t\t\t{\n\t\t\t\t\tname: \"value\",\n\t\t\t\t\ttype: { type: \"number\" },\n\t\t\t\t\tdescription: \"The number to round up\",\n\t\t\t\t},\n\t\t\t],\n\t\t\treturnType: { type: \"number\" },\n\t\t\tdescription: \"Rounds up to the nearest integer: {{ ceil value }}\",\n\t\t});\n\n\t\t// floor — Round down: {{ floor value }}\n\t\tdefs.set(\"floor\", {\n\t\t\tfn: (value: unknown) => Math.floor(num(value)),\n\t\t\tparams: [\n\t\t\t\t{\n\t\t\t\t\tname: \"value\",\n\t\t\t\t\ttype: { type: \"number\" },\n\t\t\t\t\tdescription: \"The number to round down\",\n\t\t\t\t},\n\t\t\t],\n\t\t\treturnType: { type: \"number\" },\n\t\t\tdescription: \"Rounds down to the nearest integer: {{ floor value }}\",\n\t\t});\n\n\t\t// round — Rounding: {{ round value }} or {{ round value precision }}\n\t\t// With precision: {{ round 3.14159 2 }} → 3.14\n\t\tdefs.set(\"round\", {\n\t\t\tfn: (value: unknown, precision: unknown) => {\n\t\t\t\tconst n = num(value);\n\t\t\t\t// If precision is a Handlebars options object (not a number),\n\t\t\t\t// it means the second parameter was not provided.\n\t\t\t\tif (\n\t\t\t\t\tprecision === undefined ||\n\t\t\t\t\tprecision === null ||\n\t\t\t\t\ttypeof precision === \"object\"\n\t\t\t\t) {\n\t\t\t\t\treturn Math.round(n);\n\t\t\t\t}\n\t\t\t\tconst p = num(precision);\n\t\t\t\tconst factor = 10 ** p;\n\t\t\t\treturn Math.round(n * factor) / factor;\n\t\t\t},\n\t\t\tparams: [\n\t\t\t\t{\n\t\t\t\t\tname: \"value\",\n\t\t\t\t\ttype: { type: \"number\" },\n\t\t\t\t\tdescription: \"The number to round\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: \"precision\",\n\t\t\t\t\ttype: { type: \"number\" },\n\t\t\t\t\tdescription: \"Number of decimal places (default: 0)\",\n\t\t\t\t\toptional: true,\n\t\t\t\t},\n\t\t\t],\n\t\t\treturnType: { type: \"number\" },\n\t\t\tdescription:\n\t\t\t\t\"Rounds to the nearest integer or to a given precision: {{ round value }} or {{ round value 2 }}\",\n\t\t});\n\n\t\t// sqrt — Square root: {{ sqrt value }}\n\t\tdefs.set(\"sqrt\", {\n\t\t\tfn: (value: unknown) => Math.sqrt(num(value)),\n\t\t\tparams: [\n\t\t\t\t{ name: \"value\", type: { type: \"number\" }, description: \"The number\" },\n\t\t\t],\n\t\t\treturnType: { type: \"number\" },\n\t\t\tdescription: \"Returns the square root: {{ sqrt value }}\",\n\t\t});\n\t}\n\n\t// ── Min / Max ────────────────────────────────────────────────────\n\n\t/** Registers min and max */\n\tprivate registerMinMax(defs: Map<string, HelperDefinition>): void {\n\t\t// min — Minimum : {{ min a b }}\n\t\tdefs.set(\"min\", {\n\t\t\tfn: (a: unknown, b: unknown) => Math.min(num(a), num(b)),\n\t\t\tparams: [\n\t\t\t\t{ name: \"a\", type: { type: \"number\" }, description: \"First number\" },\n\t\t\t\t{ name: \"b\", type: { type: \"number\" }, description: \"Second number\" },\n\t\t\t],\n\t\t\treturnType: { type: \"number\" },\n\t\t\tdescription: \"Returns the smaller of two numbers: {{ min a b }}\",\n\t\t});\n\n\t\t// max — Maximum : {{ max a b }}\n\t\tdefs.set(\"max\", {\n\t\t\tfn: (a: unknown, b: unknown) => Math.max(num(a), num(b)),\n\t\t\tparams: [\n\t\t\t\t{ name: \"a\", type: { type: \"number\" }, description: \"First number\" },\n\t\t\t\t{ name: \"b\", type: { type: \"number\" }, description: \"Second number\" },\n\t\t\t],\n\t\t\treturnType: { type: \"number\" },\n\t\t\tdescription: \"Returns the larger of two numbers: {{ max a b }}\",\n\t\t});\n\t}\n\n\t// ── Generic helper ───────────────────────────────────────────────\n\n\t/** Registers the generic `math` helper with operator as a parameter */\n\tprivate registerGenericMath(defs: Map<string, HelperDefinition>): void {\n\t\t// Usage : {{ math a \"+\" b }}, {{ math a \"/\" b }}, {{ math a \"**\" b }}\n\t\tdefs.set(\"math\", {\n\t\t\tfn: (a: unknown, operator: unknown, b: unknown) => {\n\t\t\t\tconst op = String(operator);\n\t\t\t\tif (!SUPPORTED_OPERATORS.has(op)) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`[math helper] Unknown operator \"${op}\". ` +\n\t\t\t\t\t\t\t`Supported: ${[...SUPPORTED_OPERATORS].join(\", \")} `,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn applyOperator(num(a), op as MathOperator, num(b));\n\t\t\t},\n\t\t\tparams: [\n\t\t\t\t{ name: \"a\", type: { type: \"number\" }, description: \"Left operand\" },\n\t\t\t\t{\n\t\t\t\t\tname: \"operator\",\n\t\t\t\t\ttype: { type: \"string\", enum: [\"+\", \"-\", \"*\", \"/\", \"%\", \"**\"] },\n\t\t\t\t\tdescription: 'Arithmetic operator: \"+\", \"-\", \"*\", \"/\", \"%\", \"**\"',\n\t\t\t\t},\n\t\t\t\t{ name: \"b\", type: { type: \"number\" }, description: \"Right operand\" },\n\t\t\t],\n\t\t\treturnType: { type: \"number\" },\n\t\t\tdescription:\n\t\t\t\t'Generic math helper with operator as parameter: {{ math a \"+\" b }}, {{ math a \"/\" b }}. ' +\n\t\t\t\t\"Supported operators: +, -, *, /, %, **\",\n\t\t});\n\t}\n}\n"
10
- ],
11
- "mappings": "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",
12
- "debugId": "2517AB2E996B3F7E64756E2164756E21",
13
- "names": []
14
- }