typebars 1.0.2 → 1.0.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.
Files changed (60) hide show
  1. package/dist/analyzer.d.ts +1 -1
  2. package/dist/analyzer.js +2 -4
  3. package/dist/analyzer.js.map +1 -9
  4. package/dist/compiled-template.d.ts +2 -2
  5. package/dist/compiled-template.js +2 -4
  6. package/dist/compiled-template.js.map +1 -9
  7. package/dist/errors.d.ts +1 -1
  8. package/dist/errors.js +2 -4
  9. package/dist/errors.js.map +1 -9
  10. package/dist/executor.d.ts +2 -2
  11. package/dist/executor.js +2 -4
  12. package/dist/executor.js.map +1 -9
  13. package/dist/helpers/helper-factory.d.ts +1 -1
  14. package/dist/helpers/helper-factory.js +2 -0
  15. package/dist/helpers/helper-factory.js.map +1 -0
  16. package/dist/helpers/index.d.ts +4 -4
  17. package/dist/helpers/index.js +2 -0
  18. package/dist/helpers/index.js.map +1 -0
  19. package/dist/helpers/logical-helpers.d.ts +2 -2
  20. package/dist/helpers/logical-helpers.js +2 -0
  21. package/dist/helpers/logical-helpers.js.map +1 -0
  22. package/dist/helpers/math-helpers.d.ts +2 -2
  23. package/dist/helpers/math-helpers.js +2 -0
  24. package/dist/helpers/math-helpers.js.map +1 -0
  25. package/dist/helpers/utils.js +2 -0
  26. package/dist/helpers/utils.js.map +1 -0
  27. package/dist/index.d.ts +3 -3
  28. package/dist/index.js +2 -4
  29. package/dist/index.js.map +1 -9
  30. package/dist/parser.js +2 -4
  31. package/dist/parser.js.map +1 -9
  32. package/dist/schema-resolver.js +2 -4
  33. package/dist/schema-resolver.js.map +1 -9
  34. package/dist/typebars.d.ts +2 -2
  35. package/dist/typebars.js +2 -4
  36. package/dist/typebars.js.map +1 -9
  37. package/dist/types.js +2 -4
  38. package/dist/types.js.map +1 -9
  39. package/dist/utils.d.ts +1 -1
  40. package/dist/utils.js +2 -4
  41. package/dist/utils.js.map +1 -9
  42. package/package.json +7 -5
  43. package/dist/chunk-6955jpr7.js +0 -5
  44. package/dist/chunk-6955jpr7.js.map +0 -10
  45. package/dist/chunk-ecs3yth2.js +0 -5
  46. package/dist/chunk-ecs3yth2.js.map +0 -10
  47. package/dist/chunk-efqd0598.js +0 -5
  48. package/dist/chunk-efqd0598.js.map +0 -10
  49. package/dist/chunk-jms1ndxn.js +0 -5
  50. package/dist/chunk-jms1ndxn.js.map +0 -10
  51. package/dist/chunk-p5efqsxw.js +0 -7
  52. package/dist/chunk-p5efqsxw.js.map +0 -10
  53. package/dist/chunk-rkrp4ysw.js +0 -5
  54. package/dist/chunk-rkrp4ysw.js.map +0 -10
  55. package/dist/chunk-t6n956qz.js +0 -4
  56. package/dist/chunk-t6n956qz.js.map +0 -10
  57. package/dist/chunk-xd2vmd03.js +0 -5
  58. package/dist/chunk-xd2vmd03.js.map +0 -14
  59. package/dist/chunk-zh1e0yhd.js +0 -7
  60. package/dist/chunk-zh1e0yhd.js.map +0 -10
@@ -1,5 +1,5 @@
1
1
  import type { JSONSchema7 } from "json-schema";
2
- import type { AnalysisResult, HelperDefinition, TemplateDiagnostic, TemplateInput } from "./types.ts";
2
+ import type { AnalysisResult, HelperDefinition, TemplateDiagnostic, TemplateInput } from "./types";
3
3
  /** Context passed recursively during AST traversal */
4
4
  interface AnalysisContext {
5
5
  /** Root schema (for resolving $refs) */
package/dist/analyzer.js CHANGED
@@ -1,4 +1,2 @@
1
- import{c as a,d as b,e as c}from"./chunk-t6n956qz.js";import"./chunk-6955jpr7.js";import"./chunk-rkrp4ysw.js";import"./chunk-jms1ndxn.js";import"./chunk-p5efqsxw.js";import"./chunk-zh1e0yhd.js";export{c as inferBlockType,b as analyzeFromAst,a as analyze};
2
-
3
- //# debugId=618AD80F85BF812A64756E2164756E21
4
- //# sourceMappingURL=analyzer.js.map
1
+ function _array_like_to_array(arr,len){if(len==null||len>arr.length)len=arr.length;for(var i=0,arr2=new Array(len);i<len;i++)arr2[i]=arr[i];return arr2}function _array_with_holes(arr){if(Array.isArray(arr))return arr}function _iterable_to_array_limit(arr,i){var _i=arr==null?null:typeof Symbol!=="undefined"&&arr[Symbol.iterator]||arr["@@iterator"];if(_i==null)return;var _arr=[];var _n=true;var _d=false;var _s,_e;try{for(_i=_i.call(arr);!(_n=(_s=_i.next()).done);_n=true){_arr.push(_s.value);if(i&&_arr.length===i)break}}catch(err){_d=true;_e=err}finally{try{if(!_n&&_i["return"]!=null)_i["return"]()}finally{if(_d)throw _e}}return _arr}function _non_iterable_rest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _sliced_to_array(arr,i){return _array_with_holes(arr)||_iterable_to_array_limit(arr,i)||_unsupported_iterable_to_array(arr,i)||_non_iterable_rest()}function _unsupported_iterable_to_array(o,minLen){if(!o)return;if(typeof o==="string")return _array_like_to_array(o,minLen);var n=Object.prototype.toString.call(o).slice(8,-1);if(n==="Object"&&o.constructor)n=o.constructor.name;if(n==="Map"||n==="Set")return Array.from(n);if(n==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return _array_like_to_array(o,minLen)}import{createMissingArgumentMessage,createPropertyNotFoundMessage,createTypeMismatchMessage,createUnanalyzableMessage,createUnknownHelperMessage}from"./errors";import{detectLiteralType,extractExpressionIdentifier,extractPathSegments,getEffectiveBody,getEffectivelySingleBlock,getEffectivelySingleExpression,isThisExpression,parse}from"./parser";import{assertNoConditionalSchema,resolveArrayItems,resolveSchemaPath,simplifySchema}from"./schema-resolver";import{inferPrimitiveSchema,isLiteralInput,isObjectInput}from"./types";import{aggregateObjectAnalysis,deepEqual,extractSourceSnippet,getSchemaPropertyNames}from"./utils";export function analyze(template,inputSchema,identifierSchemas){if(isObjectInput(template)){return analyzeObjectTemplate(template,inputSchema,identifierSchemas)}if(isLiteralInput(template)){return{valid:true,diagnostics:[],outputSchema:inferPrimitiveSchema(template)}}var ast=parse(template);return analyzeFromAst(ast,template,inputSchema,{identifierSchemas:identifierSchemas})}function analyzeObjectTemplate(template,inputSchema,identifierSchemas){return aggregateObjectAnalysis(Object.keys(template),function(key){return analyze(template[key],inputSchema,identifierSchemas)})}export function analyzeFromAst(ast,template,inputSchema,options){assertNoConditionalSchema(inputSchema);if(options===null||options===void 0?void 0:options.identifierSchemas){var _iteratorNormalCompletion=true,_didIteratorError=false,_iteratorError=undefined;try{for(var _iterator=Object.entries(options.identifierSchemas)[Symbol.iterator](),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var _step_value=_sliced_to_array(_step.value,2),id=_step_value[0],idSchema=_step_value[1];assertNoConditionalSchema(idSchema,"/identifierSchemas/".concat(id))}}catch(err){_didIteratorError=true;_iteratorError=err}finally{try{if(!_iteratorNormalCompletion&&_iterator.return!=null){_iterator.return()}}finally{if(_didIteratorError){throw _iteratorError}}}}var ctx={root:inputSchema,current:inputSchema,diagnostics:[],template:template,identifierSchemas:options===null||options===void 0?void 0:options.identifierSchemas,helpers:options===null||options===void 0?void 0:options.helpers};var outputSchema=inferProgramType(ast,ctx);var hasErrors=ctx.diagnostics.some(function(d){return d.severity==="error"});return{valid:!hasErrors,diagnostics:ctx.diagnostics,outputSchema:simplifySchema(outputSchema)}}function processStatement(stmt,ctx){switch(stmt.type){case"ContentStatement":case"CommentStatement":return undefined;case"MustacheStatement":return processMustache(stmt,ctx);case"BlockStatement":return inferBlockType(stmt,ctx);default:addDiagnostic(ctx,"UNANALYZABLE","warning",'Unsupported AST node type: "'.concat(stmt.type,'"'),stmt);return undefined}}function processMustache(stmt,ctx){var _resolveExpressionWithDiagnostics;if(stmt.path.type==="SubExpression"){addDiagnostic(ctx,"UNANALYZABLE","warning","Sub-expressions are not statically analyzable",stmt);return{}}if(stmt.params.length>0||stmt.hash){var _ctx_helpers;var helperName=getExpressionName(stmt.path);var helper=(_ctx_helpers=ctx.helpers)===null||_ctx_helpers===void 0?void 0:_ctx_helpers.get(helperName);if(helper){var _helper_returnType;var helperParams=helper.params;if(helperParams){var requiredCount=helperParams.filter(function(p){return!p.optional}).length;if(stmt.params.length<requiredCount){addDiagnostic(ctx,"MISSING_ARGUMENT","error",'Helper "'.concat(helperName,'" expects at least ').concat(requiredCount," argument(s), but got ").concat(stmt.params.length),stmt,{helperName:helperName,expected:"".concat(requiredCount," argument(s)"),actual:"".concat(stmt.params.length," argument(s)")})}}for(var i=0;i<stmt.params.length;i++){var resolvedSchema=resolveExpressionWithDiagnostics(stmt.params[i],ctx,stmt);var helperParam=helperParams===null||helperParams===void 0?void 0:helperParams[i];if(resolvedSchema&&(helperParam===null||helperParam===void 0?void 0:helperParam.type)){var expectedType=helperParam.type;if(!isParamTypeCompatible(resolvedSchema,expectedType)){var paramName=helperParam.name;addDiagnostic(ctx,"TYPE_MISMATCH","error",'Helper "'.concat(helperName,'" parameter "').concat(paramName,'" expects ').concat(schemaTypeLabel(expectedType),", but got ").concat(schemaTypeLabel(resolvedSchema)),stmt,{helperName:helperName,expected:schemaTypeLabel(expectedType),actual:schemaTypeLabel(resolvedSchema)})}}}return(_helper_returnType=helper.returnType)!==null&&_helper_returnType!==void 0?_helper_returnType:{type:"string"}}addDiagnostic(ctx,"UNKNOWN_HELPER","warning",'Unknown inline helper "'.concat(helperName,'" — cannot analyze statically'),stmt,{helperName:helperName});return{type:"string"}}return(_resolveExpressionWithDiagnostics=resolveExpressionWithDiagnostics(stmt.path,ctx,stmt))!==null&&_resolveExpressionWithDiagnostics!==void 0?_resolveExpressionWithDiagnostics:{}}function isParamTypeCompatible(resolved,expected){if(!expected.type||!resolved.type)return true;var expectedTypes=Array.isArray(expected.type)?expected.type:[expected.type];var resolvedTypes=Array.isArray(resolved.type)?resolved.type:[resolved.type];return resolvedTypes.some(function(rt){return expectedTypes.some(function(et){return rt===et||et==="number"&&rt==="integer"||et==="integer"&&rt==="number"})})}function inferProgramType(program,ctx){var effective=getEffectiveBody(program);if(effective.length===0){return{type:"string"}}var singleExpr=getEffectivelySingleExpression(program);if(singleExpr){return processMustache(singleExpr,ctx)}var singleBlock=getEffectivelySingleBlock(program);if(singleBlock){return inferBlockType(singleBlock,ctx)}var allContent=effective.every(function(s){return s.type==="ContentStatement"});if(allContent){var text=effective.map(function(s){return s.value}).join("").trim();if(text==="")return{type:"string"};var literalType=detectLiteralType(text);if(literalType)return{type:literalType}}var allBlocks=effective.every(function(s){return s.type==="BlockStatement"});if(allBlocks){var types=[];var _iteratorNormalCompletion=true,_didIteratorError=false,_iteratorError=undefined;try{for(var _iterator=effective[Symbol.iterator](),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var stmt=_step.value;var t=inferBlockType(stmt,ctx);if(t)types.push(t)}}catch(err){_didIteratorError=true;_iteratorError=err}finally{try{if(!_iteratorNormalCompletion&&_iterator.return!=null){_iterator.return()}}finally{if(_didIteratorError){throw _iteratorError}}}if(types.length===1)return types[0];if(types.length>1)return simplifySchema({oneOf:types});return{type:"string"}}var _iteratorNormalCompletion1=true,_didIteratorError1=false,_iteratorError1=undefined;try{for(var _iterator1=program.body[Symbol.iterator](),_step1;!(_iteratorNormalCompletion1=(_step1=_iterator1.next()).done);_iteratorNormalCompletion1=true){var stmt1=_step1.value;processStatement(stmt1,ctx)}}catch(err){_didIteratorError1=true;_iteratorError1=err}finally{try{if(!_iteratorNormalCompletion1&&_iterator1.return!=null){_iterator1.return()}}finally{if(_didIteratorError1){throw _iteratorError1}}}return{type:"string"}}function inferBlockType(stmt,ctx){var helperName=getBlockHelperName(stmt);switch(helperName){case"if":case"unless":{var arg=getBlockArgument(stmt);if(arg){resolveExpressionWithDiagnostics(arg,ctx,stmt)}else{addDiagnostic(ctx,"MISSING_ARGUMENT","error",createMissingArgumentMessage(helperName),stmt,{helperName:helperName})}var thenType=inferProgramType(stmt.program,ctx);if(stmt.inverse){var elseType=inferProgramType(stmt.inverse,ctx);if(deepEqual(thenType,elseType))return thenType;return simplifySchema({oneOf:[thenType,elseType]})}return thenType}case"each":{var arg1=getBlockArgument(stmt);if(!arg1){addDiagnostic(ctx,"MISSING_ARGUMENT","error",createMissingArgumentMessage("each"),stmt,{helperName:"each"});var saved=ctx.current;ctx.current={};inferProgramType(stmt.program,ctx);ctx.current=saved;if(stmt.inverse)inferProgramType(stmt.inverse,ctx);return{type:"string"}}var collectionSchema=resolveExpressionWithDiagnostics(arg1,ctx,stmt);if(!collectionSchema){var saved1=ctx.current;ctx.current={};inferProgramType(stmt.program,ctx);ctx.current=saved1;if(stmt.inverse)inferProgramType(stmt.inverse,ctx);return{type:"string"}}var itemSchema=resolveArrayItems(collectionSchema,ctx.root);if(!itemSchema){addDiagnostic(ctx,"TYPE_MISMATCH","error",createTypeMismatchMessage("each","an array",schemaTypeLabel(collectionSchema)),stmt,{helperName:"each",expected:"array",actual:schemaTypeLabel(collectionSchema)});var saved2=ctx.current;ctx.current={};inferProgramType(stmt.program,ctx);ctx.current=saved2;if(stmt.inverse)inferProgramType(stmt.inverse,ctx);return{type:"string"}}var saved3=ctx.current;ctx.current=itemSchema;inferProgramType(stmt.program,ctx);ctx.current=saved3;if(stmt.inverse)inferProgramType(stmt.inverse,ctx);return{type:"string"}}case"with":{var arg2=getBlockArgument(stmt);if(!arg2){addDiagnostic(ctx,"MISSING_ARGUMENT","error",createMissingArgumentMessage("with"),stmt,{helperName:"with"});var saved4=ctx.current;ctx.current={};var result=inferProgramType(stmt.program,ctx);ctx.current=saved4;if(stmt.inverse)inferProgramType(stmt.inverse,ctx);return result}var innerSchema=resolveExpressionWithDiagnostics(arg2,ctx,stmt);var saved5=ctx.current;ctx.current=innerSchema!==null&&innerSchema!==void 0?innerSchema:{};var result1=inferProgramType(stmt.program,ctx);ctx.current=saved5;if(stmt.inverse)inferProgramType(stmt.inverse,ctx);return result1}default:{var _ctx_helpers;var helper=(_ctx_helpers=ctx.helpers)===null||_ctx_helpers===void 0?void 0:_ctx_helpers.get(helperName);if(helper){var _helper_returnType;var _iteratorNormalCompletion=true,_didIteratorError=false,_iteratorError=undefined;try{for(var _iterator=stmt.params[Symbol.iterator](),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var param=_step.value;resolveExpressionWithDiagnostics(param,ctx,stmt)}}catch(err){_didIteratorError=true;_iteratorError=err}finally{try{if(!_iteratorNormalCompletion&&_iterator.return!=null){_iterator.return()}}finally{if(_didIteratorError){throw _iteratorError}}}inferProgramType(stmt.program,ctx);if(stmt.inverse)inferProgramType(stmt.inverse,ctx);return(_helper_returnType=helper.returnType)!==null&&_helper_returnType!==void 0?_helper_returnType:{type:"string"}}addDiagnostic(ctx,"UNKNOWN_HELPER","warning",createUnknownHelperMessage(helperName),stmt,{helperName:helperName});inferProgramType(stmt.program,ctx);if(stmt.inverse)inferProgramType(stmt.inverse,ctx);return{type:"string"}}}}function resolveExpressionWithDiagnostics(expr,ctx,parentNode){if(isThisExpression(expr)){return ctx.current}if(expr.type==="SubExpression"){return resolveSubExpression(expr,ctx,parentNode)}var segments=extractPathSegments(expr);if(segments.length===0){if(expr.type==="StringLiteral")return{type:"string"};if(expr.type==="NumberLiteral")return{type:"number"};if(expr.type==="BooleanLiteral")return{type:"boolean"};if(expr.type==="NullLiteral")return{type:"null"};if(expr.type==="UndefinedLiteral")return{};addDiagnostic(ctx,"UNANALYZABLE","warning",createUnanalyzableMessage(expr.type),parentNode!==null&&parentNode!==void 0?parentNode:expr);return undefined}var _extractExpressionIdentifier=extractExpressionIdentifier(segments),cleanSegments=_extractExpressionIdentifier.cleanSegments,identifier=_extractExpressionIdentifier.identifier;if(identifier!==null){return resolveWithIdentifier(cleanSegments,identifier,ctx,parentNode!==null&&parentNode!==void 0?parentNode:expr)}var resolved=resolveSchemaPath(ctx.current,cleanSegments);if(resolved===undefined){var fullPath=cleanSegments.join(".");var availableProperties=getSchemaPropertyNames(ctx.current);addDiagnostic(ctx,"UNKNOWN_PROPERTY","error",createPropertyNotFoundMessage(fullPath,availableProperties),parentNode!==null&&parentNode!==void 0?parentNode:expr,{path:fullPath,availableProperties:availableProperties});return undefined}return resolved}function resolveWithIdentifier(cleanSegments,identifier,ctx,node){var fullPath=cleanSegments.join(".");if(!ctx.identifierSchemas){addDiagnostic(ctx,"MISSING_IDENTIFIER_SCHEMAS","error",'Property "'.concat(fullPath,":").concat(identifier,'" uses an identifier but no identifier schemas were provided'),node,{path:"".concat(fullPath,":").concat(identifier),identifier:identifier});return undefined}var idSchema=ctx.identifierSchemas[identifier];if(!idSchema){addDiagnostic(ctx,"UNKNOWN_IDENTIFIER","error",'Property "'.concat(fullPath,":").concat(identifier,'" references identifier ').concat(identifier," but no schema exists for this identifier"),node,{path:"".concat(fullPath,":").concat(identifier),identifier:identifier});return undefined}var resolved=resolveSchemaPath(idSchema,cleanSegments);if(resolved===undefined){var availableProperties=getSchemaPropertyNames(idSchema);addDiagnostic(ctx,"IDENTIFIER_PROPERTY_NOT_FOUND","error",'Property "'.concat(fullPath,'" does not exist in the schema for identifier ').concat(identifier),node,{path:fullPath,identifier:identifier,availableProperties:availableProperties});return undefined}return resolved}function resolveSubExpression(expr,ctx,parentNode){var _helper_returnType;var _ctx_helpers;var helperName=getExpressionName(expr.path);var helper=(_ctx_helpers=ctx.helpers)===null||_ctx_helpers===void 0?void 0:_ctx_helpers.get(helperName);if(!helper){addDiagnostic(ctx,"UNKNOWN_HELPER","warning",'Unknown sub-expression helper "'.concat(helperName,'" — cannot analyze statically'),parentNode!==null&&parentNode!==void 0?parentNode:expr,{helperName:helperName});return{type:"string"}}var helperParams=helper.params;if(helperParams){var requiredCount=helperParams.filter(function(p){return!p.optional}).length;if(expr.params.length<requiredCount){addDiagnostic(ctx,"MISSING_ARGUMENT","error",'Helper "'.concat(helperName,'" expects at least ').concat(requiredCount," argument(s), but got ").concat(expr.params.length),parentNode!==null&&parentNode!==void 0?parentNode:expr,{helperName:helperName,expected:"".concat(requiredCount," argument(s)"),actual:"".concat(expr.params.length," argument(s)")})}}for(var i=0;i<expr.params.length;i++){var resolvedSchema=resolveExpressionWithDiagnostics(expr.params[i],ctx,parentNode!==null&&parentNode!==void 0?parentNode:expr);var helperParam=helperParams===null||helperParams===void 0?void 0:helperParams[i];if(resolvedSchema&&(helperParam===null||helperParam===void 0?void 0:helperParam.type)){var expectedType=helperParam.type;if(!isParamTypeCompatible(resolvedSchema,expectedType)){var paramName=helperParam.name;addDiagnostic(ctx,"TYPE_MISMATCH","error",'Helper "'.concat(helperName,'" parameter "').concat(paramName,'" expects ').concat(schemaTypeLabel(expectedType),", but got ").concat(schemaTypeLabel(resolvedSchema)),parentNode!==null&&parentNode!==void 0?parentNode:expr,{helperName:helperName,expected:schemaTypeLabel(expectedType),actual:schemaTypeLabel(resolvedSchema)})}}}return(_helper_returnType=helper.returnType)!==null&&_helper_returnType!==void 0?_helper_returnType:{type:"string"}}function getBlockArgument(stmt){return stmt.params[0]}function getBlockHelperName(stmt){if(stmt.path.type==="PathExpression"){return stmt.path.original}return""}function getExpressionName(expr){if(expr.type==="PathExpression"){return expr.original}return""}function addDiagnostic(ctx,code,severity,message,node,details){var diagnostic={severity:severity,code:code,message:message};if(node&&"loc"in node&&node.loc){diagnostic.loc={start:{line:node.loc.start.line,column:node.loc.start.column},end:{line:node.loc.end.line,column:node.loc.end.column}};diagnostic.source=extractSourceSnippet(ctx.template,diagnostic.loc)}if(details){diagnostic.details=details}ctx.diagnostics.push(diagnostic)}function schemaTypeLabel(schema){if(schema.type){return Array.isArray(schema.type)?schema.type.join(" | "):schema.type}if(schema.oneOf)return"oneOf(...)";if(schema.anyOf)return"anyOf(...)";if(schema.allOf)return"allOf(...)";if(schema.enum)return"enum";return"unknown"}export{inferBlockType};
2
+ //# sourceMappingURL=analyzer.js.map
@@ -1,9 +1 @@
1
- {
2
- "version": 3,
3
- "sources": [],
4
- "sourcesContent": [
5
- ],
6
- "mappings": "",
7
- "debugId": "618AD80F85BF812A64756E2164756E21",
8
- "names": []
9
- }
1
+ {"version":3,"sources":["../src/analyzer.ts"],"sourcesContent":["import type { JSONSchema7 } from \"json-schema\";\nimport {\n\tcreateMissingArgumentMessage,\n\tcreatePropertyNotFoundMessage,\n\tcreateTypeMismatchMessage,\n\tcreateUnanalyzableMessage,\n\tcreateUnknownHelperMessage,\n} from \"./errors\";\nimport {\n\tdetectLiteralType,\n\textractExpressionIdentifier,\n\textractPathSegments,\n\tgetEffectiveBody,\n\tgetEffectivelySingleBlock,\n\tgetEffectivelySingleExpression,\n\tisThisExpression,\n\tparse,\n} from \"./parser\";\nimport {\n\tassertNoConditionalSchema,\n\tresolveArrayItems,\n\tresolveSchemaPath,\n\tsimplifySchema,\n} from \"./schema-resolver\";\nimport type {\n\tAnalysisResult,\n\tDiagnosticCode,\n\tDiagnosticDetails,\n\tHelperDefinition,\n\tTemplateDiagnostic,\n\tTemplateInput,\n\tTemplateInputObject,\n} from \"./types\";\nimport { inferPrimitiveSchema, isLiteralInput, isObjectInput } from \"./types\";\nimport {\n\taggregateObjectAnalysis,\n\tdeepEqual,\n\textractSourceSnippet,\n\tgetSchemaPropertyNames,\n} from \"./utils\";\n\n// ─── Static Analyzer ─────────────────────────────────────────────────────────\n// Static analysis of a Handlebars template against a JSON Schema v7\n// describing the available context.\n//\n// Merged architecture (v2):\n// A single AST traversal performs both **validation** and **return type\n// inference** simultaneously. This eliminates duplication between the former\n// `validate*` and `infer*` functions and improves performance by avoiding\n// a double traversal.\n//\n// Context:\n// The analysis context uses a **save/restore** pattern instead of creating\n// new objects on each recursion (`{ ...ctx, current: X }`). This reduces\n// GC pressure for deeply nested templates.\n//\n// ─── Template Identifiers ────────────────────────────────────────────────────\n// The `{{key:N}}` syntax allows referencing a variable from a specific\n// schema, identified by an integer N. The optional `identifierSchemas`\n// parameter provides a mapping `{ [id]: JSONSchema7 }`.\n//\n// Resolution rules:\n// - `{{meetingId}}` → validated against `inputSchema` (standard behavior)\n// - `{{meetingId:1}}` → validated against `identifierSchemas[1]`\n// - `{{meetingId:1}}` without `identifierSchemas[1]` → error\n\n// ─── Internal Types ──────────────────────────────────────────────────────────\n\n/** Context passed recursively during AST traversal */\ninterface AnalysisContext {\n\t/** Root schema (for resolving $refs) */\n\troot: JSONSchema7;\n\t/** Current context schema (changes with #each, #with) — mutated via save/restore */\n\tcurrent: JSONSchema7;\n\t/** Diagnostics accumulator */\n\tdiagnostics: TemplateDiagnostic[];\n\t/** Full template source (for extracting error snippets) */\n\ttemplate: string;\n\t/** Schemas by template identifier (for the {{key:N}} syntax) */\n\tidentifierSchemas?: Record<number, JSONSchema7>;\n\t/** Registered custom helpers (for static analysis) */\n\thelpers?: Map<string, HelperDefinition>;\n}\n\n// ─── Public API ──────────────────────────────────────────────────────────────\n\n/**\n * Statically analyzes a template against a JSON Schema v7 describing the\n * available context.\n *\n * Backward-compatible version — parses the template internally.\n *\n * @param template - The template string (e.g. `\"Hello {{user.name}}\"`)\n * @param inputSchema - JSON Schema v7 describing the available variables\n * @param identifierSchemas - (optional) Schemas by identifier `{ [id]: JSONSchema7 }`\n * @returns An `AnalysisResult` containing validity, diagnostics, and the\n * inferred output schema.\n */\nexport function analyze(\n\ttemplate: TemplateInput,\n\tinputSchema: JSONSchema7,\n\tidentifierSchemas?: Record<number, JSONSchema7>,\n): AnalysisResult {\n\tif (isObjectInput(template)) {\n\t\treturn analyzeObjectTemplate(template, inputSchema, identifierSchemas);\n\t}\n\tif (isLiteralInput(template)) {\n\t\treturn {\n\t\t\tvalid: true,\n\t\t\tdiagnostics: [],\n\t\t\toutputSchema: inferPrimitiveSchema(template),\n\t\t};\n\t}\n\tconst ast = parse(template);\n\treturn analyzeFromAst(ast, template, inputSchema, { identifierSchemas });\n}\n\n/**\n * Analyzes an object template recursively (standalone version).\n * Each property is analyzed individually, diagnostics are merged,\n * and the `outputSchema` reflects the object structure.\n */\nfunction analyzeObjectTemplate(\n\ttemplate: TemplateInputObject,\n\tinputSchema: JSONSchema7,\n\tidentifierSchemas?: Record<number, JSONSchema7>,\n): AnalysisResult {\n\treturn aggregateObjectAnalysis(Object.keys(template), (key) =>\n\t\tanalyze(template[key] as TemplateInput, inputSchema, identifierSchemas),\n\t);\n}\n\n/**\n * Statically analyzes a template from an already-parsed AST.\n *\n * This is the internal function used by `Typebars.compile()` and\n * `CompiledTemplate.analyze()` to avoid costly re-parsing.\n *\n * @param ast - The already-parsed Handlebars AST\n * @param template - The template source (for error snippets)\n * @param inputSchema - JSON Schema v7 describing the available variables\n * @param options - Additional options\n * @returns An `AnalysisResult`\n */\nexport function analyzeFromAst(\n\tast: hbs.AST.Program,\n\ttemplate: string,\n\tinputSchema: JSONSchema7,\n\toptions?: {\n\t\tidentifierSchemas?: Record<number, JSONSchema7>;\n\t\thelpers?: Map<string, HelperDefinition>;\n\t},\n): AnalysisResult {\n\t// ── Reject unsupported schema features before analysis ────────────\n\t// Conditional schemas (if/then/else) are non-resolvable without runtime\n\t// data. Fail fast with a clear error rather than producing silently\n\t// incorrect results.\n\tassertNoConditionalSchema(inputSchema);\n\n\tif (options?.identifierSchemas) {\n\t\tfor (const [id, idSchema] of Object.entries(options.identifierSchemas)) {\n\t\t\tassertNoConditionalSchema(idSchema, `/identifierSchemas/${id}`);\n\t\t}\n\t}\n\n\tconst ctx: AnalysisContext = {\n\t\troot: inputSchema,\n\t\tcurrent: inputSchema,\n\t\tdiagnostics: [],\n\t\ttemplate,\n\t\tidentifierSchemas: options?.identifierSchemas,\n\t\thelpers: options?.helpers,\n\t};\n\n\t// Single pass: type inference + validation in one traversal.\n\tconst outputSchema = inferProgramType(ast, ctx);\n\n\tconst hasErrors = ctx.diagnostics.some((d) => d.severity === \"error\");\n\n\treturn {\n\t\tvalid: !hasErrors,\n\t\tdiagnostics: ctx.diagnostics,\n\t\toutputSchema: simplifySchema(outputSchema),\n\t};\n}\n\n// ─── Unified AST Traversal ───────────────────────────────────────────────────\n// A single set of functions handles both validation (emitting diagnostics)\n// and type inference (returning a JSONSchema7).\n//\n// Main functions:\n// - `inferProgramType` — entry point for a Program (template body or block)\n// - `processStatement` — dispatches a statement (validation side-effects)\n// - `processMustache` — handles a MustacheStatement (expression or inline helper)\n// - `inferBlockType` — handles a BlockStatement (if, each, with, custom…)\n\n/**\n * Dispatches the processing of an individual statement.\n *\n * Called by `inferProgramType` in the \"mixed template\" case to validate\n * each statement while ignoring the returned type (the result is always\n * `string` for a mixed template).\n *\n * @returns The inferred schema for this statement, or `undefined` for\n * statements with no semantics (ContentStatement, CommentStatement).\n */\nfunction processStatement(\n\tstmt: hbs.AST.Statement,\n\tctx: AnalysisContext,\n): JSONSchema7 | undefined {\n\tswitch (stmt.type) {\n\t\tcase \"ContentStatement\":\n\t\tcase \"CommentStatement\":\n\t\t\t// Static text or comment — nothing to validate, no type to infer\n\t\t\treturn undefined;\n\n\t\tcase \"MustacheStatement\":\n\t\t\treturn processMustache(stmt as hbs.AST.MustacheStatement, ctx);\n\n\t\tcase \"BlockStatement\":\n\t\t\treturn inferBlockType(stmt as hbs.AST.BlockStatement, ctx);\n\n\t\tdefault:\n\t\t\t// Unrecognized AST node — emit a warning rather than an error\n\t\t\t// to avoid blocking on future Handlebars extensions.\n\t\t\taddDiagnostic(\n\t\t\t\tctx,\n\t\t\t\t\"UNANALYZABLE\",\n\t\t\t\t\"warning\",\n\t\t\t\t`Unsupported AST node type: \"${stmt.type}\"`,\n\t\t\t\tstmt,\n\t\t\t);\n\t\t\treturn undefined;\n\t}\n}\n\n/**\n * Processes a MustacheStatement `{{expression}}` or `{{helper arg}}`.\n *\n * Distinguishes two cases:\n * 1. **Simple expression** (`{{name}}`, `{{user.age}}`) — resolution in the schema\n * 2. **Inline helper** (`{{uppercase name}}`) — params > 0 or hash present\n *\n * @returns The inferred schema for this expression\n */\nfunction processMustache(\n\tstmt: hbs.AST.MustacheStatement,\n\tctx: AnalysisContext,\n): JSONSchema7 {\n\t// Sub-expressions (nested helpers) are not supported for static\n\t// analysis — emit a warning.\n\tif (stmt.path.type === \"SubExpression\") {\n\t\taddDiagnostic(\n\t\t\tctx,\n\t\t\t\"UNANALYZABLE\",\n\t\t\t\"warning\",\n\t\t\t\"Sub-expressions are not statically analyzable\",\n\t\t\tstmt,\n\t\t);\n\t\treturn {};\n\t}\n\n\t// ── Inline helper detection ──────────────────────────────────────────────\n\t// If the MustacheStatement has parameters or a hash, it's a helper call\n\t// (e.g. `{{uppercase name}}`), not a simple expression.\n\tif (stmt.params.length > 0 || stmt.hash) {\n\t\tconst helperName = getExpressionName(stmt.path);\n\n\t\t// Check if the helper is registered\n\t\tconst helper = ctx.helpers?.get(helperName);\n\t\tif (helper) {\n\t\t\tconst helperParams = helper.params;\n\n\t\t\t// ── Check the number of required parameters ──────────────\n\t\t\tif (helperParams) {\n\t\t\t\tconst requiredCount = helperParams.filter((p) => !p.optional).length;\n\t\t\t\tif (stmt.params.length < requiredCount) {\n\t\t\t\t\taddDiagnostic(\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\t\"MISSING_ARGUMENT\",\n\t\t\t\t\t\t\"error\",\n\t\t\t\t\t\t`Helper \"${helperName}\" expects at least ${requiredCount} argument(s), but got ${stmt.params.length}`,\n\t\t\t\t\t\tstmt,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\thelperName,\n\t\t\t\t\t\t\texpected: `${requiredCount} argument(s)`,\n\t\t\t\t\t\t\tactual: `${stmt.params.length} argument(s)`,\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// ── Validate each parameter (existence + type) ───────────────\n\t\t\tfor (let i = 0; i < stmt.params.length; i++) {\n\t\t\t\tconst resolvedSchema = resolveExpressionWithDiagnostics(\n\t\t\t\t\tstmt.params[i] as hbs.AST.Expression,\n\t\t\t\t\tctx,\n\t\t\t\t\tstmt,\n\t\t\t\t);\n\n\t\t\t\t// Check type compatibility if the helper declares the\n\t\t\t\t// expected type for this parameter\n\t\t\t\tconst helperParam = helperParams?.[i];\n\t\t\t\tif (resolvedSchema && helperParam?.type) {\n\t\t\t\t\tconst expectedType = helperParam.type;\n\t\t\t\t\tif (!isParamTypeCompatible(resolvedSchema, expectedType)) {\n\t\t\t\t\t\tconst paramName = helperParam.name;\n\t\t\t\t\t\taddDiagnostic(\n\t\t\t\t\t\t\tctx,\n\t\t\t\t\t\t\t\"TYPE_MISMATCH\",\n\t\t\t\t\t\t\t\"error\",\n\t\t\t\t\t\t\t`Helper \"${helperName}\" parameter \"${paramName}\" expects ${schemaTypeLabel(expectedType)}, but got ${schemaTypeLabel(resolvedSchema)}`,\n\t\t\t\t\t\t\tstmt,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\thelperName,\n\t\t\t\t\t\t\t\texpected: schemaTypeLabel(expectedType),\n\t\t\t\t\t\t\t\tactual: schemaTypeLabel(resolvedSchema),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn helper.returnType ?? { type: \"string\" };\n\t\t}\n\n\t\t// Unknown inline helper — warning\n\t\taddDiagnostic(\n\t\t\tctx,\n\t\t\t\"UNKNOWN_HELPER\",\n\t\t\t\"warning\",\n\t\t\t`Unknown inline helper \"${helperName}\" — cannot analyze statically`,\n\t\t\tstmt,\n\t\t\t{ helperName },\n\t\t);\n\t\treturn { type: \"string\" };\n\t}\n\n\t// ── Simple expression ────────────────────────────────────────────────────\n\treturn resolveExpressionWithDiagnostics(stmt.path, ctx, stmt) ?? {};\n}\n\n/**\n * Checks whether a resolved type is compatible with the type expected\n * by a helper parameter.\n *\n * Compatibility rules:\n * - If either schema has no `type`, validation is not possible → compatible\n * - `integer` is compatible with `number` (integer ⊂ number)\n * - For multiple types (e.g. `[\"string\", \"number\"]`), at least one resolved\n * type must match one expected type\n */\nfunction isParamTypeCompatible(\n\tresolved: JSONSchema7,\n\texpected: JSONSchema7,\n): boolean {\n\t// If either has no type info, we cannot validate\n\tif (!expected.type || !resolved.type) return true;\n\n\tconst expectedTypes = Array.isArray(expected.type)\n\t\t? expected.type\n\t\t: [expected.type];\n\tconst resolvedTypes = Array.isArray(resolved.type)\n\t\t? resolved.type\n\t\t: [resolved.type];\n\n\t// At least one resolved type must be compatible with one expected type\n\treturn resolvedTypes.some((rt) =>\n\t\texpectedTypes.some(\n\t\t\t(et) =>\n\t\t\t\trt === et ||\n\t\t\t\t// integer is a subtype of number\n\t\t\t\t(et === \"number\" && rt === \"integer\") ||\n\t\t\t\t(et === \"integer\" && rt === \"number\"),\n\t\t),\n\t);\n}\n\n/**\n * Infers the output type of a `Program` (template body or block body).\n *\n * Handles 4 cases, from most specific to most general:\n *\n * 1. **Single expression** `{{expr}}` → type of the expression\n * 2. **Single block** `{{#if}}…{{/if}}` → type of the block\n * 3. **Pure text content** → literal detection (number, boolean, null)\n * 4. **Mixed template** → always `string` (concatenation)\n *\n * Validation is performed alongside inference: each expression and block\n * is validated during processing.\n */\nfunction inferProgramType(\n\tprogram: hbs.AST.Program,\n\tctx: AnalysisContext,\n): JSONSchema7 {\n\tconst effective = getEffectiveBody(program);\n\n\t// No significant statements → empty string\n\tif (effective.length === 0) {\n\t\treturn { type: \"string\" };\n\t}\n\n\t// ── Case 1: single expression {{expr}} ─────────────────────────────────\n\tconst singleExpr = getEffectivelySingleExpression(program);\n\tif (singleExpr) {\n\t\treturn processMustache(singleExpr, ctx);\n\t}\n\n\t// ── Case 2: single block {{#if}}, {{#each}}, {{#with}}, … ──────────────\n\tconst singleBlock = getEffectivelySingleBlock(program);\n\tif (singleBlock) {\n\t\treturn inferBlockType(singleBlock, ctx);\n\t}\n\n\t// ── Case 3: only ContentStatements (no expressions) ────────────────────\n\t// If the concatenated (trimmed) text is a typed literal (number, boolean,\n\t// null), we infer the corresponding type.\n\tconst allContent = effective.every((s) => s.type === \"ContentStatement\");\n\tif (allContent) {\n\t\tconst text = effective\n\t\t\t.map((s) => (s as hbs.AST.ContentStatement).value)\n\t\t\t.join(\"\")\n\t\t\t.trim();\n\n\t\tif (text === \"\") return { type: \"string\" };\n\n\t\tconst literalType = detectLiteralType(text);\n\t\tif (literalType) return { type: literalType };\n\t}\n\n\t// ── Case 4: multiple blocks only (no significant text between them) ────\n\t// When the effective body consists entirely of BlockStatements, collect\n\t// each block's inferred type and combine them via oneOf. This handles\n\t// templates like:\n\t// {{#if showName}}{{name}}{{/if}}\n\t// {{#if showAge}}{{age}}{{/if}}\n\t// where the output could be string OR number depending on which branch\n\t// is active.\n\tconst allBlocks = effective.every((s) => s.type === \"BlockStatement\");\n\tif (allBlocks) {\n\t\tconst types: JSONSchema7[] = [];\n\t\tfor (const stmt of effective) {\n\t\t\tconst t = inferBlockType(stmt as hbs.AST.BlockStatement, ctx);\n\t\t\tif (t) types.push(t);\n\t\t}\n\t\tif (types.length === 1) return types[0] as JSONSchema7;\n\t\tif (types.length > 1) return simplifySchema({ oneOf: types });\n\t\treturn { type: \"string\" };\n\t}\n\n\t// ── Case 5: mixed template (text + expressions, blocks…) ───────────────\n\t// Traverse all statements for validation (side-effects: diagnostics).\n\t// The result is always string (concatenation).\n\tfor (const stmt of program.body) {\n\t\tprocessStatement(stmt, ctx);\n\t}\n\treturn { type: \"string\" };\n}\n\n/**\n * Infers the output type of a BlockStatement and validates its content.\n *\n * Supports built-in helpers (`if`, `unless`, `each`, `with`) and custom\n * helpers registered via `Typebars.registerHelper()`.\n *\n * Uses the **save/restore** pattern for context: instead of creating a new\n * object `{ ...ctx, current: X }` on each recursion, we save `ctx.current`,\n * mutate it, process the body, then restore. This reduces GC pressure for\n * deeply nested templates.\n */\nfunction inferBlockType(\n\tstmt: hbs.AST.BlockStatement,\n\tctx: AnalysisContext,\n): JSONSchema7 {\n\tconst helperName = getBlockHelperName(stmt);\n\n\tswitch (helperName) {\n\t\t// ── if / unless ──────────────────────────────────────────────────────\n\t\t// Validate the condition argument, then infer types from both branches.\n\t\tcase \"if\":\n\t\tcase \"unless\": {\n\t\t\tconst arg = getBlockArgument(stmt);\n\t\t\tif (arg) {\n\t\t\t\tresolveExpressionWithDiagnostics(arg, ctx, stmt);\n\t\t\t} else {\n\t\t\t\taddDiagnostic(\n\t\t\t\t\tctx,\n\t\t\t\t\t\"MISSING_ARGUMENT\",\n\t\t\t\t\t\"error\",\n\t\t\t\t\tcreateMissingArgumentMessage(helperName),\n\t\t\t\t\tstmt,\n\t\t\t\t\t{ helperName },\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Infer the type of the \"then\" branch\n\t\t\tconst thenType = inferProgramType(stmt.program, ctx);\n\n\t\t\tif (stmt.inverse) {\n\t\t\t\tconst elseType = inferProgramType(stmt.inverse, ctx);\n\t\t\t\t// If both branches have the same type → single type\n\t\t\t\tif (deepEqual(thenType, elseType)) return thenType;\n\t\t\t\t// Otherwise → union of both types\n\t\t\t\treturn simplifySchema({ oneOf: [thenType, elseType] });\n\t\t\t}\n\n\t\t\t// No else branch → the result is the type of the then branch\n\t\t\t// (conceptually optional, but Handlebars returns \"\" for falsy)\n\t\t\treturn thenType;\n\t\t}\n\n\t\t// ── each ─────────────────────────────────────────────────────────────\n\t\t// Resolve the collection schema, then validate the body with the item\n\t\t// schema as the new context.\n\t\tcase \"each\": {\n\t\t\tconst arg = getBlockArgument(stmt);\n\t\t\tif (!arg) {\n\t\t\t\taddDiagnostic(\n\t\t\t\t\tctx,\n\t\t\t\t\t\"MISSING_ARGUMENT\",\n\t\t\t\t\t\"error\",\n\t\t\t\t\tcreateMissingArgumentMessage(\"each\"),\n\t\t\t\t\tstmt,\n\t\t\t\t\t{ helperName: \"each\" },\n\t\t\t\t);\n\t\t\t\t// Validate the body with an empty context (best-effort)\n\t\t\t\tconst saved = ctx.current;\n\t\t\t\tctx.current = {};\n\t\t\t\tinferProgramType(stmt.program, ctx);\n\t\t\t\tctx.current = saved;\n\t\t\t\tif (stmt.inverse) inferProgramType(stmt.inverse, ctx);\n\t\t\t\treturn { type: \"string\" };\n\t\t\t}\n\n\t\t\tconst collectionSchema = resolveExpressionWithDiagnostics(arg, ctx, stmt);\n\t\t\tif (!collectionSchema) {\n\t\t\t\t// The path could not be resolved — diagnostic already emitted.\n\t\t\t\tconst saved = ctx.current;\n\t\t\t\tctx.current = {};\n\t\t\t\tinferProgramType(stmt.program, ctx);\n\t\t\t\tctx.current = saved;\n\t\t\t\tif (stmt.inverse) inferProgramType(stmt.inverse, ctx);\n\t\t\t\treturn { type: \"string\" };\n\t\t\t}\n\n\t\t\t// Resolve the schema of the array elements\n\t\t\tconst itemSchema = resolveArrayItems(collectionSchema, ctx.root);\n\t\t\tif (!itemSchema) {\n\t\t\t\taddDiagnostic(\n\t\t\t\t\tctx,\n\t\t\t\t\t\"TYPE_MISMATCH\",\n\t\t\t\t\t\"error\",\n\t\t\t\t\tcreateTypeMismatchMessage(\n\t\t\t\t\t\t\"each\",\n\t\t\t\t\t\t\"an array\",\n\t\t\t\t\t\tschemaTypeLabel(collectionSchema),\n\t\t\t\t\t),\n\t\t\t\t\tstmt,\n\t\t\t\t\t{\n\t\t\t\t\t\thelperName: \"each\",\n\t\t\t\t\t\texpected: \"array\",\n\t\t\t\t\t\tactual: schemaTypeLabel(collectionSchema),\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\t// Validate the body with an empty context (best-effort)\n\t\t\t\tconst saved = ctx.current;\n\t\t\t\tctx.current = {};\n\t\t\t\tinferProgramType(stmt.program, ctx);\n\t\t\t\tctx.current = saved;\n\t\t\t\tif (stmt.inverse) inferProgramType(stmt.inverse, ctx);\n\t\t\t\treturn { type: \"string\" };\n\t\t\t}\n\n\t\t\t// Validate the body with the item schema as the new context\n\t\t\tconst saved = ctx.current;\n\t\t\tctx.current = itemSchema;\n\t\t\tinferProgramType(stmt.program, ctx);\n\t\t\tctx.current = saved;\n\n\t\t\t// The inverse branch ({{else}}) keeps the parent context\n\t\t\tif (stmt.inverse) inferProgramType(stmt.inverse, ctx);\n\n\t\t\t// An each concatenates renders → always string\n\t\t\treturn { type: \"string\" };\n\t\t}\n\n\t\t// ── with ─────────────────────────────────────────────────────────────\n\t\t// Resolve the inner schema, then validate the body with it as the\n\t\t// new context.\n\t\tcase \"with\": {\n\t\t\tconst arg = getBlockArgument(stmt);\n\t\t\tif (!arg) {\n\t\t\t\taddDiagnostic(\n\t\t\t\t\tctx,\n\t\t\t\t\t\"MISSING_ARGUMENT\",\n\t\t\t\t\t\"error\",\n\t\t\t\t\tcreateMissingArgumentMessage(\"with\"),\n\t\t\t\t\tstmt,\n\t\t\t\t\t{ helperName: \"with\" },\n\t\t\t\t);\n\t\t\t\t// Validate the body with an empty context\n\t\t\t\tconst saved = ctx.current;\n\t\t\t\tctx.current = {};\n\t\t\t\tconst result = inferProgramType(stmt.program, ctx);\n\t\t\t\tctx.current = saved;\n\t\t\t\tif (stmt.inverse) inferProgramType(stmt.inverse, ctx);\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\tconst innerSchema = resolveExpressionWithDiagnostics(arg, ctx, stmt);\n\n\t\t\tconst saved = ctx.current;\n\t\t\tctx.current = innerSchema ?? {};\n\t\t\tconst result = inferProgramType(stmt.program, ctx);\n\t\t\tctx.current = saved;\n\n\t\t\t// The inverse branch keeps the parent context\n\t\t\tif (stmt.inverse) inferProgramType(stmt.inverse, ctx);\n\n\t\t\treturn result;\n\t\t}\n\n\t\t// ── Custom or unknown helper ─────────────────────────────────────────\n\t\tdefault: {\n\t\t\tconst helper = ctx.helpers?.get(helperName);\n\t\t\tif (helper) {\n\t\t\t\t// Registered custom helper — validate parameters\n\t\t\t\tfor (const param of stmt.params) {\n\t\t\t\t\tresolveExpressionWithDiagnostics(\n\t\t\t\t\t\tparam as hbs.AST.Expression,\n\t\t\t\t\t\tctx,\n\t\t\t\t\t\tstmt,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\t// Validate the body with the current context\n\t\t\t\tinferProgramType(stmt.program, ctx);\n\t\t\t\tif (stmt.inverse) inferProgramType(stmt.inverse, ctx);\n\t\t\t\treturn helper.returnType ?? { type: \"string\" };\n\t\t\t}\n\n\t\t\t// Unknown helper — warning\n\t\t\taddDiagnostic(\n\t\t\t\tctx,\n\t\t\t\t\"UNKNOWN_HELPER\",\n\t\t\t\t\"warning\",\n\t\t\t\tcreateUnknownHelperMessage(helperName),\n\t\t\t\tstmt,\n\t\t\t\t{ helperName },\n\t\t\t);\n\t\t\t// Still validate the body with the current context (best-effort)\n\t\t\tinferProgramType(stmt.program, ctx);\n\t\t\tif (stmt.inverse) inferProgramType(stmt.inverse, ctx);\n\t\t\treturn { type: \"string\" };\n\t\t}\n\t}\n}\n\n// ─── Expression Resolution ───────────────────────────────────────────────────\n\n/**\n * Resolves an AST expression to a sub-schema, emitting a diagnostic\n * if the path cannot be resolved.\n *\n * Handles the `{{key:N}}` syntax:\n * - If the expression has an identifier N → resolution in `identifierSchemas[N]`\n * - If identifier N has no associated schema → error\n * - If no identifier → resolution in `ctx.current` (standard behavior)\n *\n * @returns The resolved sub-schema, or `undefined` if the path is invalid.\n */\nfunction resolveExpressionWithDiagnostics(\n\texpr: hbs.AST.Expression,\n\tctx: AnalysisContext,\n\t/** Parent AST node (for diagnostic location) */\n\tparentNode?: hbs.AST.Node,\n): JSONSchema7 | undefined {\n\t// Handle `this` / `.` → return the current context\n\tif (isThisExpression(expr)) {\n\t\treturn ctx.current;\n\t}\n\n\t// ── SubExpression (nested helper call, e.g. `(lt account.balance 500)`) ──\n\tif (expr.type === \"SubExpression\") {\n\t\treturn resolveSubExpression(expr as hbs.AST.SubExpression, ctx, parentNode);\n\t}\n\n\tconst segments = extractPathSegments(expr);\n\tif (segments.length === 0) {\n\t\t// Expression that is not a PathExpression (e.g. literal)\n\t\tif (expr.type === \"StringLiteral\") return { type: \"string\" };\n\t\tif (expr.type === \"NumberLiteral\") return { type: \"number\" };\n\t\tif (expr.type === \"BooleanLiteral\") return { type: \"boolean\" };\n\t\tif (expr.type === \"NullLiteral\") return { type: \"null\" };\n\t\tif (expr.type === \"UndefinedLiteral\") return {};\n\n\t\taddDiagnostic(\n\t\t\tctx,\n\t\t\t\"UNANALYZABLE\",\n\t\t\t\"warning\",\n\t\t\tcreateUnanalyzableMessage(expr.type),\n\t\t\tparentNode ?? expr,\n\t\t);\n\t\treturn undefined;\n\t}\n\n\t// ── Identifier extraction ──────────────────────────────────────────────\n\tconst { cleanSegments, identifier } = extractExpressionIdentifier(segments);\n\n\tif (identifier !== null) {\n\t\t// The expression uses the {{key:N}} syntax — resolve from\n\t\t// the schema of identifier N.\n\t\treturn resolveWithIdentifier(\n\t\t\tcleanSegments,\n\t\t\tidentifier,\n\t\t\tctx,\n\t\t\tparentNode ?? expr,\n\t\t);\n\t}\n\n\t// ── Standard resolution (no identifier) ────────────────────────────────\n\tconst resolved = resolveSchemaPath(ctx.current, cleanSegments);\n\tif (resolved === undefined) {\n\t\tconst fullPath = cleanSegments.join(\".\");\n\t\tconst availableProperties = getSchemaPropertyNames(ctx.current);\n\t\taddDiagnostic(\n\t\t\tctx,\n\t\t\t\"UNKNOWN_PROPERTY\",\n\t\t\t\"error\",\n\t\t\tcreatePropertyNotFoundMessage(fullPath, availableProperties),\n\t\t\tparentNode ?? expr,\n\t\t\t{ path: fullPath, availableProperties },\n\t\t);\n\t\treturn undefined;\n\t}\n\n\treturn resolved;\n}\n\n/**\n * Resolves an expression with identifier `{{key:N}}` by looking up the\n * schema associated with identifier N.\n *\n * Emits an error diagnostic if:\n * - No `identifierSchemas` were provided\n * - Identifier N has no associated schema\n * - The property does not exist in the identifier's schema\n */\nfunction resolveWithIdentifier(\n\tcleanSegments: string[],\n\tidentifier: number,\n\tctx: AnalysisContext,\n\tnode: hbs.AST.Node,\n): JSONSchema7 | undefined {\n\tconst fullPath = cleanSegments.join(\".\");\n\n\t// No identifierSchemas provided at all\n\tif (!ctx.identifierSchemas) {\n\t\taddDiagnostic(\n\t\t\tctx,\n\t\t\t\"MISSING_IDENTIFIER_SCHEMAS\",\n\t\t\t\"error\",\n\t\t\t`Property \"${fullPath}:${identifier}\" uses an identifier but no identifier schemas were provided`,\n\t\t\tnode,\n\t\t\t{ path: `${fullPath}:${identifier}`, identifier },\n\t\t);\n\t\treturn undefined;\n\t}\n\n\t// The identifier does not exist in the provided schemas\n\tconst idSchema = ctx.identifierSchemas[identifier];\n\tif (!idSchema) {\n\t\taddDiagnostic(\n\t\t\tctx,\n\t\t\t\"UNKNOWN_IDENTIFIER\",\n\t\t\t\"error\",\n\t\t\t`Property \"${fullPath}:${identifier}\" references identifier ${identifier} but no schema exists for this identifier`,\n\t\t\tnode,\n\t\t\t{ path: `${fullPath}:${identifier}`, identifier },\n\t\t);\n\t\treturn undefined;\n\t}\n\n\t// Resolve the path within the identifier's schema\n\tconst resolved = resolveSchemaPath(idSchema, cleanSegments);\n\tif (resolved === undefined) {\n\t\tconst availableProperties = getSchemaPropertyNames(idSchema);\n\t\taddDiagnostic(\n\t\t\tctx,\n\t\t\t\"IDENTIFIER_PROPERTY_NOT_FOUND\",\n\t\t\t\"error\",\n\t\t\t`Property \"${fullPath}\" does not exist in the schema for identifier ${identifier}`,\n\t\t\tnode,\n\t\t\t{\n\t\t\t\tpath: fullPath,\n\t\t\t\tidentifier,\n\t\t\t\tavailableProperties,\n\t\t\t},\n\t\t);\n\t\treturn undefined;\n\t}\n\n\treturn resolved;\n}\n\n// ─── Utilities ───────────────────────────────────────────────────────────────\n\n/**\n * Extracts the first argument of a BlockStatement.\n *\n * In the Handlebars AST, for `{{#if active}}`:\n * - `stmt.path` → PathExpression(\"if\") ← the helper name\n * - `stmt.params[0]` → PathExpression(\"active\") ← the actual argument\n *\n * @returns The argument expression, or `undefined` if the block has no argument.\n */\n// ─── SubExpression Resolution ────────────────────────────────────────────────\n\n/**\n * Resolves a SubExpression (nested helper call) such as `(lt account.balance 500)`.\n *\n * This mirrors the helper-call logic in `processMustache` but applies to\n * expressions used as arguments (e.g. inside `{{#if (lt a b)}}`).\n *\n * Steps:\n * 1. Extract the helper name from the SubExpression's path.\n * 2. Look up the helper in `ctx.helpers`.\n * 3. Validate argument count and types.\n * 4. Return the helper's declared `returnType` (defaults to `{ type: \"string\" }`).\n */\nfunction resolveSubExpression(\n\texpr: hbs.AST.SubExpression,\n\tctx: AnalysisContext,\n\tparentNode?: hbs.AST.Node,\n): JSONSchema7 | undefined {\n\tconst helperName = getExpressionName(expr.path);\n\n\tconst helper = ctx.helpers?.get(helperName);\n\tif (!helper) {\n\t\taddDiagnostic(\n\t\t\tctx,\n\t\t\t\"UNKNOWN_HELPER\",\n\t\t\t\"warning\",\n\t\t\t`Unknown sub-expression helper \"${helperName}\" — cannot analyze statically`,\n\t\t\tparentNode ?? expr,\n\t\t\t{ helperName },\n\t\t);\n\t\treturn { type: \"string\" };\n\t}\n\n\tconst helperParams = helper.params;\n\n\t// ── Check the number of required parameters ──────────────────────\n\tif (helperParams) {\n\t\tconst requiredCount = helperParams.filter((p) => !p.optional).length;\n\t\tif (expr.params.length < requiredCount) {\n\t\t\taddDiagnostic(\n\t\t\t\tctx,\n\t\t\t\t\"MISSING_ARGUMENT\",\n\t\t\t\t\"error\",\n\t\t\t\t`Helper \"${helperName}\" expects at least ${requiredCount} argument(s), but got ${expr.params.length}`,\n\t\t\t\tparentNode ?? expr,\n\t\t\t\t{\n\t\t\t\t\thelperName,\n\t\t\t\t\texpected: `${requiredCount} argument(s)`,\n\t\t\t\t\tactual: `${expr.params.length} argument(s)`,\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t}\n\n\t// ── Validate each parameter (existence + type) ───────────────────\n\tfor (let i = 0; i < expr.params.length; i++) {\n\t\tconst resolvedSchema = resolveExpressionWithDiagnostics(\n\t\t\texpr.params[i] as hbs.AST.Expression,\n\t\t\tctx,\n\t\t\tparentNode ?? expr,\n\t\t);\n\n\t\tconst helperParam = helperParams?.[i];\n\t\tif (resolvedSchema && helperParam?.type) {\n\t\t\tconst expectedType = helperParam.type;\n\t\t\tif (!isParamTypeCompatible(resolvedSchema, expectedType)) {\n\t\t\t\tconst paramName = helperParam.name;\n\t\t\t\taddDiagnostic(\n\t\t\t\t\tctx,\n\t\t\t\t\t\"TYPE_MISMATCH\",\n\t\t\t\t\t\"error\",\n\t\t\t\t\t`Helper \"${helperName}\" parameter \"${paramName}\" expects ${schemaTypeLabel(expectedType)}, but got ${schemaTypeLabel(resolvedSchema)}`,\n\t\t\t\t\tparentNode ?? expr,\n\t\t\t\t\t{\n\t\t\t\t\t\thelperName,\n\t\t\t\t\t\texpected: schemaTypeLabel(expectedType),\n\t\t\t\t\t\tactual: schemaTypeLabel(resolvedSchema),\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn helper.returnType ?? { type: \"string\" };\n}\n\nfunction getBlockArgument(\n\tstmt: hbs.AST.BlockStatement,\n): hbs.AST.Expression | undefined {\n\treturn stmt.params[0] as hbs.AST.Expression | undefined;\n}\n\n/**\n * Retrieves the helper name from a BlockStatement (e.g. \"if\", \"each\", \"with\").\n */\nfunction getBlockHelperName(stmt: hbs.AST.BlockStatement): string {\n\tif (stmt.path.type === \"PathExpression\") {\n\t\treturn (stmt.path as hbs.AST.PathExpression).original;\n\t}\n\treturn \"\";\n}\n\n/**\n * Retrieves the name of an expression (first segment of the PathExpression).\n * Used to identify inline helpers.\n */\nfunction getExpressionName(expr: hbs.AST.Expression): string {\n\tif (expr.type === \"PathExpression\") {\n\t\treturn (expr as hbs.AST.PathExpression).original;\n\t}\n\treturn \"\";\n}\n\n/**\n * Adds an enriched diagnostic to the analysis context.\n *\n * Each diagnostic includes:\n * - A machine-readable `code` for the frontend\n * - A human-readable `message` describing the problem\n * - A `source` snippet from the template (if the position is available)\n * - Structured `details` for debugging\n */\nfunction addDiagnostic(\n\tctx: AnalysisContext,\n\tcode: DiagnosticCode,\n\tseverity: \"error\" | \"warning\",\n\tmessage: string,\n\tnode?: hbs.AST.Node,\n\tdetails?: DiagnosticDetails,\n): void {\n\tconst diagnostic: TemplateDiagnostic = { severity, code, message };\n\n\t// Extract the position and source snippet if available\n\tif (node && \"loc\" in node && node.loc) {\n\t\tdiagnostic.loc = {\n\t\t\tstart: { line: node.loc.start.line, column: node.loc.start.column },\n\t\t\tend: { line: node.loc.end.line, column: node.loc.end.column },\n\t\t};\n\t\t// Extract the template fragment around the error\n\t\tdiagnostic.source = extractSourceSnippet(ctx.template, diagnostic.loc);\n\t}\n\n\tif (details) {\n\t\tdiagnostic.details = details;\n\t}\n\n\tctx.diagnostics.push(diagnostic);\n}\n\n/**\n * Returns a human-readable label for a schema's type (for error messages).\n */\nfunction schemaTypeLabel(schema: JSONSchema7): string {\n\tif (schema.type) {\n\t\treturn Array.isArray(schema.type) ? schema.type.join(\" | \") : schema.type;\n\t}\n\tif (schema.oneOf) return \"oneOf(...)\";\n\tif (schema.anyOf) return \"anyOf(...)\";\n\tif (schema.allOf) return \"allOf(...)\";\n\tif (schema.enum) return \"enum\";\n\treturn \"unknown\";\n}\n\n// ─── Export for Internal Use ─────────────────────────────────────────────────\n// `inferBlockType` is exported to allow targeted unit tests\n// on block type inference.\nexport { inferBlockType };\n"],"names":["createMissingArgumentMessage","createPropertyNotFoundMessage","createTypeMismatchMessage","createUnanalyzableMessage","createUnknownHelperMessage","detectLiteralType","extractExpressionIdentifier","extractPathSegments","getEffectiveBody","getEffectivelySingleBlock","getEffectivelySingleExpression","isThisExpression","parse","assertNoConditionalSchema","resolveArrayItems","resolveSchemaPath","simplifySchema","inferPrimitiveSchema","isLiteralInput","isObjectInput","aggregateObjectAnalysis","deepEqual","extractSourceSnippet","getSchemaPropertyNames","analyze","template","inputSchema","identifierSchemas","analyzeObjectTemplate","valid","diagnostics","outputSchema","ast","analyzeFromAst","Object","keys","key","options","entries","id","idSchema","ctx","root","current","helpers","inferProgramType","hasErrors","some","d","severity","processStatement","stmt","type","undefined","processMustache","inferBlockType","addDiagnostic","resolveExpressionWithDiagnostics","path","params","length","hash","helperName","getExpressionName","helper","get","helperParams","requiredCount","filter","p","optional","expected","actual","i","resolvedSchema","helperParam","expectedType","isParamTypeCompatible","paramName","name","schemaTypeLabel","returnType","resolved","expectedTypes","Array","isArray","resolvedTypes","rt","et","program","effective","singleExpr","singleBlock","allContent","every","s","text","map","value","join","trim","literalType","allBlocks","types","t","push","oneOf","body","getBlockHelperName","arg","getBlockArgument","thenType","inverse","elseType","saved","collectionSchema","itemSchema","result","innerSchema","param","expr","parentNode","resolveSubExpression","segments","cleanSegments","identifier","resolveWithIdentifier","fullPath","availableProperties","node","original","code","message","details","diagnostic","loc","start","line","column","end","source","schema","anyOf","allOf","enum"],"mappings":"01CACA,OACCA,4BAA4B,CAC5BC,6BAA6B,CAC7BC,yBAAyB,CACzBC,yBAAyB,CACzBC,0BAA0B,KACpB,UAAW,AAClB,QACCC,iBAAiB,CACjBC,2BAA2B,CAC3BC,mBAAmB,CACnBC,gBAAgB,CAChBC,yBAAyB,CACzBC,8BAA8B,CAC9BC,gBAAgB,CAChBC,KAAK,KACC,UAAW,AAClB,QACCC,yBAAyB,CACzBC,iBAAiB,CACjBC,iBAAiB,CACjBC,cAAc,KACR,mBAAoB,AAU3B,QAASC,oBAAoB,CAAEC,cAAc,CAAEC,aAAa,KAAQ,SAAU,AAC9E,QACCC,uBAAuB,CACvBC,SAAS,CACTC,oBAAoB,CACpBC,sBAAsB,KAChB,SAAU,AA2DjB,QAAO,SAASC,QACfC,QAAuB,CACvBC,WAAwB,CACxBC,iBAA+C,EAE/C,GAAIR,cAAcM,UAAW,CAC5B,OAAOG,sBAAsBH,SAAUC,YAAaC,kBACrD,CACA,GAAIT,eAAeO,UAAW,CAC7B,MAAO,CACNI,MAAO,KACPC,YAAa,EAAE,CACfC,aAAcd,qBAAqBQ,SACpC,CACD,CACA,IAAMO,IAAMpB,MAAMa,UAClB,OAAOQ,eAAeD,IAAKP,SAAUC,YAAa,CAAEC,kBAAAA,iBAAkB,EACvE,CAOA,SAASC,sBACRH,QAA6B,CAC7BC,WAAwB,CACxBC,iBAA+C,EAE/C,OAAOP,wBAAwBc,OAAOC,IAAI,CAACV,UAAW,SAACW,YACtDZ,QAAQC,QAAQ,CAACW,IAAI,CAAmBV,YAAaC,oBAEvD,CAcA,OAAO,SAASM,eACfD,GAAoB,CACpBP,QAAgB,CAChBC,WAAwB,CACxBW,OAGC,EAMDxB,0BAA0Ba,aAE1B,GAAIW,gBAAAA,wBAAAA,QAASV,iBAAiB,CAAE,KAC1B,+BAAA,wBAAA,6BAAL,QAAK,UAAwBO,OAAOI,OAAO,CAACD,QAAQV,iBAAiB,qBAAhE,QAAA,2BAAA,MAAA,wBAAA,+BAAmE,CAAnE,iCAAA,eAAOY,kBAAIC,wBACf3B,0BAA0B2B,SAAU,AAAC,sBAAwB,OAAHD,IAC3D,aAFK,uBAAA,mCAAA,2BAAA,wBAAA,+BAAA,yBAAA,iBAGN,CAEA,IAAME,IAAuB,CAC5BC,KAAMhB,YACNiB,QAASjB,YACTI,YAAa,EAAE,CACfL,SAAAA,SACAE,iBAAiB,CAAEU,gBAAAA,wBAAAA,QAASV,iBAAiB,CAC7CiB,OAAO,CAAEP,gBAAAA,wBAAAA,QAASO,OAAO,AAC1B,EAGA,IAAMb,aAAec,iBAAiBb,IAAKS,KAE3C,IAAMK,UAAYL,IAAIX,WAAW,CAACiB,IAAI,CAAC,SAACC,UAAMA,EAAEC,QAAQ,GAAK,UAE7D,MAAO,CACNpB,MAAO,CAACiB,UACRhB,YAAaW,IAAIX,WAAW,CAC5BC,aAAcf,eAAee,aAC9B,CACD,CAsBA,SAASmB,iBACRC,IAAuB,CACvBV,GAAoB,EAEpB,OAAQU,KAAKC,IAAI,EAChB,IAAK,mBACL,IAAK,mBAEJ,OAAOC,SAER,KAAK,oBACJ,OAAOC,gBAAgBH,KAAmCV,IAE3D,KAAK,iBACJ,OAAOc,eAAeJ,KAAgCV,IAEvD,SAGCe,cACCf,IACA,eACA,UACA,AAAC,+BAAwC,OAAVU,KAAKC,IAAI,CAAC,KACzCD,MAED,OAAOE,SACT,CACD,CAWA,SAASC,gBACRH,IAA+B,CAC/BV,GAAoB,MA4FbgB,kCAxFP,GAAIN,KAAKO,IAAI,CAACN,IAAI,GAAK,gBAAiB,CACvCI,cACCf,IACA,eACA,UACA,gDACAU,MAED,MAAO,CAAC,CACT,CAKA,GAAIA,KAAKQ,MAAM,CAACC,MAAM,CAAG,GAAKT,KAAKU,IAAI,CAAE,KAIzBpB,aAHf,IAAMqB,WAAaC,kBAAkBZ,KAAKO,IAAI,EAG9C,IAAMM,QAASvB,aAAAA,IAAIG,OAAO,UAAXH,6BAAAA,aAAawB,GAAG,CAACH,YAChC,GAAIE,OAAQ,KAqDJA,mBApDP,IAAME,aAAeF,OAAOL,MAAM,CAGlC,GAAIO,aAAc,CACjB,IAAMC,cAAgBD,aAAaE,MAAM,CAAC,SAACC,SAAM,CAACA,EAAEC,QAAQ,GAAEV,MAAM,CACpE,GAAIT,KAAKQ,MAAM,CAACC,MAAM,CAAGO,cAAe,CACvCX,cACCf,IACA,mBACA,QACA,AAAC,WAA0C0B,OAAhCL,WAAW,uBAA2DX,OAAtCgB,cAAc,0BAA2C,OAAnBhB,KAAKQ,MAAM,CAACC,MAAM,EACnGT,KACA,CACCW,WAAAA,WACAS,SAAU,AAAC,GAAgB,OAAdJ,cAAc,gBAC3BK,OAAQ,AAAC,GAAqB,OAAnBrB,KAAKQ,MAAM,CAACC,MAAM,CAAC,eAC/B,EAEF,CACD,CAGA,IAAK,IAAIa,EAAI,EAAGA,EAAItB,KAAKQ,MAAM,CAACC,MAAM,CAAEa,IAAK,CAC5C,IAAMC,eAAiBjB,iCACtBN,KAAKQ,MAAM,CAACc,EAAE,CACdhC,IACAU,MAKD,IAAMwB,YAAcT,qBAAAA,6BAAAA,YAAc,CAACO,EAAE,CACrC,GAAIC,iBAAkBC,oBAAAA,4BAAAA,YAAavB,IAAI,EAAE,CACxC,IAAMwB,aAAeD,YAAYvB,IAAI,CACrC,GAAI,CAACyB,sBAAsBH,eAAgBE,cAAe,CACzD,IAAME,UAAYH,YAAYI,IAAI,CAClCvB,cACCf,IACA,gBACA,QACA,AAAC,WAAoCqC,OAA1BhB,WAAW,iBAAqCkB,OAAtBF,UAAU,cAAsDE,OAA1CA,gBAAgBJ,cAAc,cAA4C,OAAhCI,gBAAgBN,iBACrHvB,KACA,CACCW,WAAAA,WACAS,SAAUS,gBAAgBJ,cAC1BJ,OAAQQ,gBAAgBN,eACzB,EAEF,CACD,CACD,CAEA,OAAOV,mBAAAA,OAAOiB,UAAU,UAAjBjB,4BAAAA,mBAAqB,CAAEZ,KAAM,QAAS,CAC9C,CAGAI,cACCf,IACA,iBACA,UACA,AAAC,0BAAoC,OAAXqB,WAAW,iCACrCX,KACA,CAAEW,WAAAA,UAAW,GAEd,MAAO,CAAEV,KAAM,QAAS,CACzB,CAGA,OAAOK,kCAAAA,iCAAiCN,KAAKO,IAAI,CAAEjB,IAAKU,eAAjDM,2CAAAA,kCAA0D,CAAC,CACnE,CAYA,SAASoB,sBACRK,QAAqB,CACrBX,QAAqB,EAGrB,GAAI,CAACA,SAASnB,IAAI,EAAI,CAAC8B,SAAS9B,IAAI,CAAE,OAAO,KAE7C,IAAM+B,cAAgBC,MAAMC,OAAO,CAACd,SAASnB,IAAI,EAC9CmB,SAASnB,IAAI,CACb,CAACmB,SAASnB,IAAI,CAAC,CAClB,IAAMkC,cAAgBF,MAAMC,OAAO,CAACH,SAAS9B,IAAI,EAC9C8B,SAAS9B,IAAI,CACb,CAAC8B,SAAS9B,IAAI,CAAC,CAGlB,OAAOkC,cAAcvC,IAAI,CAAC,SAACwC,WAC1BJ,cAAcpC,IAAI,CACjB,SAACyC,WACAD,KAAOC,IAENA,KAAO,UAAYD,KAAO,WAC1BC,KAAO,WAAaD,KAAO,YAGhC,CAeA,SAAS1C,iBACR4C,OAAwB,CACxBhD,GAAoB,EAEpB,IAAMiD,UAAYlF,iBAAiBiF,SAGnC,GAAIC,UAAU9B,MAAM,GAAK,EAAG,CAC3B,MAAO,CAAER,KAAM,QAAS,CACzB,CAGA,IAAMuC,WAAajF,+BAA+B+E,SAClD,GAAIE,WAAY,CACf,OAAOrC,gBAAgBqC,WAAYlD,IACpC,CAGA,IAAMmD,YAAcnF,0BAA0BgF,SAC9C,GAAIG,YAAa,CAChB,OAAOrC,eAAeqC,YAAanD,IACpC,CAKA,IAAMoD,WAAaH,UAAUI,KAAK,CAAC,SAACC,UAAMA,EAAE3C,IAAI,GAAK,qBACrD,GAAIyC,WAAY,CACf,IAAMG,KAAON,UACXO,GAAG,CAAC,SAACF,UAAM,AAACA,EAA+BG,KAAK,GAChDC,IAAI,CAAC,IACLC,IAAI,GAEN,GAAIJ,OAAS,GAAI,MAAO,CAAE5C,KAAM,QAAS,EAEzC,IAAMiD,YAAchG,kBAAkB2F,MACtC,GAAIK,YAAa,MAAO,CAAEjD,KAAMiD,WAAY,CAC7C,CAUA,IAAMC,UAAYZ,UAAUI,KAAK,CAAC,SAACC,UAAMA,EAAE3C,IAAI,GAAK,mBACpD,GAAIkD,UAAW,CACd,IAAMC,MAAuB,EAAE,KAC1B,+BAAA,wBAAA,6BAAL,QAAK,UAAcb,6BAAd,QAAA,2BAAA,MAAA,wBAAA,+BAAyB,CAAzB,IAAMvC,KAAN,YACJ,IAAMqD,EAAIjD,eAAeJ,KAAgCV,KACzD,GAAI+D,EAAGD,MAAME,IAAI,CAACD,EACnB,aAHK,uBAAA,mCAAA,2BAAA,wBAAA,+BAAA,yBAAA,iBAIL,GAAID,MAAM3C,MAAM,GAAK,EAAG,OAAO2C,KAAK,CAAC,EAAE,CACvC,GAAIA,MAAM3C,MAAM,CAAG,EAAG,OAAO5C,eAAe,CAAE0F,MAAOH,KAAM,GAC3D,MAAO,CAAEnD,KAAM,QAAS,CACzB,KAKK,gCAAA,yBAAA,8BAAL,QAAK,WAAcqC,QAAQkB,IAAI,oBAA1B,SAAA,4BAAA,OAAA,yBAAA,gCAA4B,CAA5B,IAAMxD,MAAN,aACJD,iBAAiBC,MAAMV,IACxB,aAFK,wBAAA,oCAAA,4BAAA,yBAAA,gCAAA,0BAAA,kBAGL,MAAO,CAAEW,KAAM,QAAS,CACzB,CAaA,SAASG,eACRJ,IAA4B,CAC5BV,GAAoB,EAEpB,IAAMqB,WAAa8C,mBAAmBzD,MAEtC,OAAQW,YAGP,IAAK,KACL,IAAK,SAAU,CACd,IAAM+C,IAAMC,iBAAiB3D,MAC7B,GAAI0D,IAAK,CACRpD,iCAAiCoD,IAAKpE,IAAKU,KAC5C,KAAO,CACNK,cACCf,IACA,mBACA,QACAzC,6BAA6B8D,YAC7BX,KACA,CAAEW,WAAAA,UAAW,EAEf,CAGA,IAAMiD,SAAWlE,iBAAiBM,KAAKsC,OAAO,CAAEhD,KAEhD,GAAIU,KAAK6D,OAAO,CAAE,CACjB,IAAMC,SAAWpE,iBAAiBM,KAAK6D,OAAO,CAAEvE,KAEhD,GAAIpB,UAAU0F,SAAUE,UAAW,OAAOF,SAE1C,OAAO/F,eAAe,CAAE0F,MAAO,CAACK,SAAUE,SAAS,AAAC,EACrD,CAIA,OAAOF,QACR,CAKA,IAAK,OAAQ,CACZ,IAAMF,KAAMC,iBAAiB3D,MAC7B,GAAI,CAAC0D,KAAK,CACTrD,cACCf,IACA,mBACA,QACAzC,6BAA6B,QAC7BmD,KACA,CAAEW,WAAY,MAAO,GAGtB,IAAMoD,MAAQzE,IAAIE,OAAO,AACzBF,CAAAA,IAAIE,OAAO,CAAG,CAAC,EACfE,iBAAiBM,KAAKsC,OAAO,CAAEhD,IAC/BA,CAAAA,IAAIE,OAAO,CAAGuE,MACd,GAAI/D,KAAK6D,OAAO,CAAEnE,iBAAiBM,KAAK6D,OAAO,CAAEvE,KACjD,MAAO,CAAEW,KAAM,QAAS,CACzB,CAEA,IAAM+D,iBAAmB1D,iCAAiCoD,KAAKpE,IAAKU,MACpE,GAAI,CAACgE,iBAAkB,CAEtB,IAAMD,OAAQzE,IAAIE,OAAO,AACzBF,CAAAA,IAAIE,OAAO,CAAG,CAAC,EACfE,iBAAiBM,KAAKsC,OAAO,CAAEhD,IAC/BA,CAAAA,IAAIE,OAAO,CAAGuE,OACd,GAAI/D,KAAK6D,OAAO,CAAEnE,iBAAiBM,KAAK6D,OAAO,CAAEvE,KACjD,MAAO,CAAEW,KAAM,QAAS,CACzB,CAGA,IAAMgE,WAAatG,kBAAkBqG,iBAAkB1E,IAAIC,IAAI,EAC/D,GAAI,CAAC0E,WAAY,CAChB5D,cACCf,IACA,gBACA,QACAvC,0BACC,OACA,WACA8E,gBAAgBmC,mBAEjBhE,KACA,CACCW,WAAY,OACZS,SAAU,QACVC,OAAQQ,gBAAgBmC,iBACzB,GAGD,IAAMD,OAAQzE,IAAIE,OAAO,AACzBF,CAAAA,IAAIE,OAAO,CAAG,CAAC,EACfE,iBAAiBM,KAAKsC,OAAO,CAAEhD,IAC/BA,CAAAA,IAAIE,OAAO,CAAGuE,OACd,GAAI/D,KAAK6D,OAAO,CAAEnE,iBAAiBM,KAAK6D,OAAO,CAAEvE,KACjD,MAAO,CAAEW,KAAM,QAAS,CACzB,CAGA,IAAM8D,OAAQzE,IAAIE,OAAO,AACzBF,CAAAA,IAAIE,OAAO,CAAGyE,WACdvE,iBAAiBM,KAAKsC,OAAO,CAAEhD,IAC/BA,CAAAA,IAAIE,OAAO,CAAGuE,OAGd,GAAI/D,KAAK6D,OAAO,CAAEnE,iBAAiBM,KAAK6D,OAAO,CAAEvE,KAGjD,MAAO,CAAEW,KAAM,QAAS,CACzB,CAKA,IAAK,OAAQ,CACZ,IAAMyD,KAAMC,iBAAiB3D,MAC7B,GAAI,CAAC0D,KAAK,CACTrD,cACCf,IACA,mBACA,QACAzC,6BAA6B,QAC7BmD,KACA,CAAEW,WAAY,MAAO,GAGtB,IAAMoD,OAAQzE,IAAIE,OAAO,AACzBF,CAAAA,IAAIE,OAAO,CAAG,CAAC,EACf,IAAM0E,OAASxE,iBAAiBM,KAAKsC,OAAO,CAAEhD,IAC9CA,CAAAA,IAAIE,OAAO,CAAGuE,OACd,GAAI/D,KAAK6D,OAAO,CAAEnE,iBAAiBM,KAAK6D,OAAO,CAAEvE,KACjD,OAAO4E,MACR,CAEA,IAAMC,YAAc7D,iCAAiCoD,KAAKpE,IAAKU,MAE/D,IAAM+D,OAAQzE,IAAIE,OAAO,AACzBF,CAAAA,IAAIE,OAAO,CAAG2E,oBAAAA,qBAAAA,YAAe,CAAC,EAC9B,IAAMD,QAASxE,iBAAiBM,KAAKsC,OAAO,CAAEhD,IAC9CA,CAAAA,IAAIE,OAAO,CAAGuE,OAGd,GAAI/D,KAAK6D,OAAO,CAAEnE,iBAAiBM,KAAK6D,OAAO,CAAEvE,KAEjD,OAAO4E,OACR,CAGA,QAAS,KACO5E,aAAf,IAAMuB,QAASvB,aAAAA,IAAIG,OAAO,UAAXH,6BAAAA,aAAawB,GAAG,CAACH,YAChC,GAAIE,OAAQ,KAYJA,uBAVF,+BAAA,wBAAA,6BAAL,QAAK,UAAeb,KAAKQ,MAAM,oBAA1B,QAAA,2BAAA,MAAA,wBAAA,+BAA4B,CAA5B,IAAM4D,MAAN,YACJ9D,iCACC8D,MACA9E,IACAU,KAEF,aANK,uBAAA,mCAAA,2BAAA,wBAAA,+BAAA,yBAAA,iBAQLN,iBAAiBM,KAAKsC,OAAO,CAAEhD,KAC/B,GAAIU,KAAK6D,OAAO,CAAEnE,iBAAiBM,KAAK6D,OAAO,CAAEvE,KACjD,OAAOuB,mBAAAA,OAAOiB,UAAU,UAAjBjB,4BAAAA,mBAAqB,CAAEZ,KAAM,QAAS,CAC9C,CAGAI,cACCf,IACA,iBACA,UACArC,2BAA2B0D,YAC3BX,KACA,CAAEW,WAAAA,UAAW,GAGdjB,iBAAiBM,KAAKsC,OAAO,CAAEhD,KAC/B,GAAIU,KAAK6D,OAAO,CAAEnE,iBAAiBM,KAAK6D,OAAO,CAAEvE,KACjD,MAAO,CAAEW,KAAM,QAAS,CACzB,CACD,CACD,CAeA,SAASK,iCACR+D,IAAwB,CACxB/E,GAAoB,CAEpBgF,UAAyB,EAGzB,GAAI9G,iBAAiB6G,MAAO,CAC3B,OAAO/E,IAAIE,OAAO,AACnB,CAGA,GAAI6E,KAAKpE,IAAI,GAAK,gBAAiB,CAClC,OAAOsE,qBAAqBF,KAA+B/E,IAAKgF,WACjE,CAEA,IAAME,SAAWpH,oBAAoBiH,MACrC,GAAIG,SAAS/D,MAAM,GAAK,EAAG,CAE1B,GAAI4D,KAAKpE,IAAI,GAAK,gBAAiB,MAAO,CAAEA,KAAM,QAAS,EAC3D,GAAIoE,KAAKpE,IAAI,GAAK,gBAAiB,MAAO,CAAEA,KAAM,QAAS,EAC3D,GAAIoE,KAAKpE,IAAI,GAAK,iBAAkB,MAAO,CAAEA,KAAM,SAAU,EAC7D,GAAIoE,KAAKpE,IAAI,GAAK,cAAe,MAAO,CAAEA,KAAM,MAAO,EACvD,GAAIoE,KAAKpE,IAAI,GAAK,mBAAoB,MAAO,CAAC,EAE9CI,cACCf,IACA,eACA,UACAtC,0BAA0BqH,KAAKpE,IAAI,EACnCqE,mBAAAA,oBAAAA,WAAcD,MAEf,OAAOnE,SACR,CAGA,IAAsC/C,6BAAAA,4BAA4BqH,UAA1DC,cAA8BtH,6BAA9BsH,cAAeC,WAAevH,6BAAfuH,WAEvB,GAAIA,aAAe,KAAM,CAGxB,OAAOC,sBACNF,cACAC,WACApF,IACAgF,mBAAAA,oBAAAA,WAAcD,KAEhB,CAGA,IAAMtC,SAAWnE,kBAAkB0B,IAAIE,OAAO,CAAEiF,eAChD,GAAI1C,WAAa7B,UAAW,CAC3B,IAAM0E,SAAWH,cAAczB,IAAI,CAAC,KACpC,IAAM6B,oBAAsBzG,uBAAuBkB,IAAIE,OAAO,EAC9Da,cACCf,IACA,mBACA,QACAxC,8BAA8B8H,SAAUC,qBACxCP,mBAAAA,oBAAAA,WAAcD,KACd,CAAE9D,KAAMqE,SAAUC,oBAAAA,mBAAoB,GAEvC,OAAO3E,SACR,CAEA,OAAO6B,QACR,CAWA,SAAS4C,sBACRF,aAAuB,CACvBC,UAAkB,CAClBpF,GAAoB,CACpBwF,IAAkB,EAElB,IAAMF,SAAWH,cAAczB,IAAI,CAAC,KAGpC,GAAI,CAAC1D,IAAId,iBAAiB,CAAE,CAC3B6B,cACCf,IACA,6BACA,QACA,AAAC,aAAwBoF,OAAZE,SAAS,KAAc,OAAXF,WAAW,gEACpCI,KACA,CAAEvE,KAAM,AAAC,GAAcmE,OAAZE,SAAS,KAAc,OAAXF,YAAcA,WAAAA,UAAW,GAEjD,OAAOxE,SACR,CAGA,IAAMb,SAAWC,IAAId,iBAAiB,CAACkG,WAAW,CAClD,GAAI,CAACrF,SAAU,CACdgB,cACCf,IACA,qBACA,QACA,AAAC,aAAwBoF,OAAZE,SAAS,KAAwCF,OAArCA,WAAW,4BAAqC,OAAXA,WAAW,6CACzEI,KACA,CAAEvE,KAAM,AAAC,GAAcmE,OAAZE,SAAS,KAAc,OAAXF,YAAcA,WAAAA,UAAW,GAEjD,OAAOxE,SACR,CAGA,IAAM6B,SAAWnE,kBAAkByB,SAAUoF,eAC7C,GAAI1C,WAAa7B,UAAW,CAC3B,IAAM2E,oBAAsBzG,uBAAuBiB,UACnDgB,cACCf,IACA,gCACA,QACA,AAAC,aAAqEoF,OAAzDE,SAAS,kDAA2D,OAAXF,YACtEI,KACA,CACCvE,KAAMqE,SACNF,WAAAA,WACAG,oBAAAA,mBACD,GAED,OAAO3E,SACR,CAEA,OAAO6B,QACR,CA2BA,SAASwC,qBACRF,IAA2B,CAC3B/E,GAAoB,CACpBgF,UAAyB,MAmElBzD,uBA/DQvB,aAFf,IAAMqB,WAAaC,kBAAkByD,KAAK9D,IAAI,EAE9C,IAAMM,QAASvB,aAAAA,IAAIG,OAAO,UAAXH,6BAAAA,aAAawB,GAAG,CAACH,YAChC,GAAI,CAACE,OAAQ,CACZR,cACCf,IACA,iBACA,UACA,AAAC,kCAA4C,OAAXqB,WAAW,iCAC7C2D,mBAAAA,oBAAAA,WAAcD,KACd,CAAE1D,WAAAA,UAAW,GAEd,MAAO,CAAEV,KAAM,QAAS,CACzB,CAEA,IAAMc,aAAeF,OAAOL,MAAM,CAGlC,GAAIO,aAAc,CACjB,IAAMC,cAAgBD,aAAaE,MAAM,CAAC,SAACC,SAAM,CAACA,EAAEC,QAAQ,GAAEV,MAAM,CACpE,GAAI4D,KAAK7D,MAAM,CAACC,MAAM,CAAGO,cAAe,CACvCX,cACCf,IACA,mBACA,QACA,AAAC,WAA0C0B,OAAhCL,WAAW,uBAA2D0D,OAAtCrD,cAAc,0BAA2C,OAAnBqD,KAAK7D,MAAM,CAACC,MAAM,EACnG6D,mBAAAA,oBAAAA,WAAcD,KACd,CACC1D,WAAAA,WACAS,SAAU,AAAC,GAAgB,OAAdJ,cAAc,gBAC3BK,OAAQ,AAAC,GAAqB,OAAnBgD,KAAK7D,MAAM,CAACC,MAAM,CAAC,eAC/B,EAEF,CACD,CAGA,IAAK,IAAIa,EAAI,EAAGA,EAAI+C,KAAK7D,MAAM,CAACC,MAAM,CAAEa,IAAK,CAC5C,IAAMC,eAAiBjB,iCACtB+D,KAAK7D,MAAM,CAACc,EAAE,CACdhC,IACAgF,mBAAAA,oBAAAA,WAAcD,MAGf,IAAM7C,YAAcT,qBAAAA,6BAAAA,YAAc,CAACO,EAAE,CACrC,GAAIC,iBAAkBC,oBAAAA,4BAAAA,YAAavB,IAAI,EAAE,CACxC,IAAMwB,aAAeD,YAAYvB,IAAI,CACrC,GAAI,CAACyB,sBAAsBH,eAAgBE,cAAe,CACzD,IAAME,UAAYH,YAAYI,IAAI,CAClCvB,cACCf,IACA,gBACA,QACA,AAAC,WAAoCqC,OAA1BhB,WAAW,iBAAqCkB,OAAtBF,UAAU,cAAsDE,OAA1CA,gBAAgBJ,cAAc,cAA4C,OAAhCI,gBAAgBN,iBACrH+C,mBAAAA,oBAAAA,WAAcD,KACd,CACC1D,WAAAA,WACAS,SAAUS,gBAAgBJ,cAC1BJ,OAAQQ,gBAAgBN,eACzB,EAEF,CACD,CACD,CAEA,OAAOV,mBAAAA,OAAOiB,UAAU,UAAjBjB,4BAAAA,mBAAqB,CAAEZ,KAAM,QAAS,CAC9C,CAEA,SAAS0D,iBACR3D,IAA4B,EAE5B,OAAOA,KAAKQ,MAAM,CAAC,EAAE,AACtB,CAKA,SAASiD,mBAAmBzD,IAA4B,EACvD,GAAIA,KAAKO,IAAI,CAACN,IAAI,GAAK,iBAAkB,CACxC,OAAO,AAACD,KAAKO,IAAI,CAA4BwE,QAAQ,AACtD,CACA,MAAO,EACR,CAMA,SAASnE,kBAAkByD,IAAwB,EAClD,GAAIA,KAAKpE,IAAI,GAAK,iBAAkB,CACnC,OAAO,AAACoE,KAAgCU,QAAQ,AACjD,CACA,MAAO,EACR,CAWA,SAAS1E,cACRf,GAAoB,CACpB0F,IAAoB,CACpBlF,QAA6B,CAC7BmF,OAAe,CACfH,IAAmB,CACnBI,OAA2B,EAE3B,IAAMC,WAAiC,CAAErF,SAAAA,SAAUkF,KAAAA,KAAMC,QAAAA,OAAQ,EAGjE,GAAIH,MAAQ,QAASA,MAAQA,KAAKM,GAAG,CAAE,CACtCD,WAAWC,GAAG,CAAG,CAChBC,MAAO,CAAEC,KAAMR,KAAKM,GAAG,CAACC,KAAK,CAACC,IAAI,CAAEC,OAAQT,KAAKM,GAAG,CAACC,KAAK,CAACE,MAAM,AAAC,EAClEC,IAAK,CAAEF,KAAMR,KAAKM,GAAG,CAACI,GAAG,CAACF,IAAI,CAAEC,OAAQT,KAAKM,GAAG,CAACI,GAAG,CAACD,MAAM,AAAC,CAC7D,CAEAJ,CAAAA,WAAWM,MAAM,CAAGtH,qBAAqBmB,IAAIhB,QAAQ,CAAE6G,WAAWC,GAAG,CACtE,CAEA,GAAIF,QAAS,CACZC,WAAWD,OAAO,CAAGA,OACtB,CAEA5F,IAAIX,WAAW,CAAC2E,IAAI,CAAC6B,WACtB,CAKA,SAAStD,gBAAgB6D,MAAmB,EAC3C,GAAIA,OAAOzF,IAAI,CAAE,CAChB,OAAOgC,MAAMC,OAAO,CAACwD,OAAOzF,IAAI,EAAIyF,OAAOzF,IAAI,CAAC+C,IAAI,CAAC,OAAS0C,OAAOzF,IAAI,AAC1E,CACA,GAAIyF,OAAOnC,KAAK,CAAE,MAAO,aACzB,GAAImC,OAAOC,KAAK,CAAE,MAAO,aACzB,GAAID,OAAOE,KAAK,CAAE,MAAO,aACzB,GAAIF,OAAOG,IAAI,CAAE,MAAO,OACxB,MAAO,SACR,CAKA,OAASzF,cAAc,CAAG"}
@@ -1,7 +1,7 @@
1
1
  import type Handlebars from "handlebars";
2
2
  import type { JSONSchema7 } from "json-schema";
3
- import type { AnalysisResult, ExecuteOptions, HelperDefinition, ValidationResult } from "./types.ts";
4
- import { type LRUCache } from "./utils.ts";
3
+ import type { AnalysisResult, ExecuteOptions, HelperDefinition, ValidationResult } from "./types";
4
+ import { type LRUCache } from "./utils";
5
5
  /** Internal options passed by Typebars during compilation */
6
6
  export interface CompiledTemplateOptions {
7
7
  /** Custom helpers registered on the engine */
@@ -1,4 +1,2 @@
1
- import{b as a}from"./chunk-ecs3yth2.js";import"./chunk-t6n956qz.js";import"./chunk-efqd0598.js";import"./chunk-6955jpr7.js";import"./chunk-rkrp4ysw.js";import"./chunk-jms1ndxn.js";import"./chunk-p5efqsxw.js";import"./chunk-zh1e0yhd.js";export{a as CompiledTemplate};
2
-
3
- //# debugId=771271DE7F3CA9FE64756E2164756E21
4
- //# sourceMappingURL=compiled-template.js.map
1
+ function _array_like_to_array(arr,len){if(len==null||len>arr.length)len=arr.length;for(var i=0,arr2=new Array(len);i<len;i++)arr2[i]=arr[i];return arr2}function _array_with_holes(arr){if(Array.isArray(arr))return arr}function _class_call_check(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}}function _defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor)}}function _create_class(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);return Constructor}function _define_property(obj,key,value){if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true})}else{obj[key]=value}return obj}function _iterable_to_array_limit(arr,i){var _i=arr==null?null:typeof Symbol!=="undefined"&&arr[Symbol.iterator]||arr["@@iterator"];if(_i==null)return;var _arr=[];var _n=true;var _d=false;var _s,_e;try{for(_i=_i.call(arr);!(_n=(_s=_i.next()).done);_n=true){_arr.push(_s.value);if(i&&_arr.length===i)break}}catch(err){_d=true;_e=err}finally{try{if(!_n&&_i["return"]!=null)_i["return"]()}finally{if(_d)throw _e}}return _arr}function _non_iterable_rest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _sliced_to_array(arr,i){return _array_with_holes(arr)||_iterable_to_array_limit(arr,i)||_unsupported_iterable_to_array(arr,i)||_non_iterable_rest()}function _unsupported_iterable_to_array(o,minLen){if(!o)return;if(typeof o==="string")return _array_like_to_array(o,minLen);var n=Object.prototype.toString.call(o).slice(8,-1);if(n==="Object"&&o.constructor)n=o.constructor.name;if(n==="Map"||n==="Set")return Array.from(n);if(n==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return _array_like_to_array(o,minLen)}import{analyzeFromAst}from"./analyzer";import{TemplateAnalysisError}from"./errors";import{executeFromAst}from"./executor";import{inferPrimitiveSchema}from"./types";import{aggregateObjectAnalysis,aggregateObjectAnalysisAndExecution}from"./utils";export var CompiledTemplate=/*#__PURE__*/function(){"use strict";function CompiledTemplate(state,options){_class_call_check(this,CompiledTemplate);_define_property(this,"state",void 0);_define_property(this,"options",void 0);_define_property(this,"hbsCompiled",null);this.state=state;this.options=options}_create_class(CompiledTemplate,[{key:"ast",get:function get(){return this.state.kind==="template"?this.state.ast:null}},{key:"template",get:function get(){return this.state.kind==="template"?this.state.source:""}},{key:"analyze",value:function analyze(inputSchema,identifierSchemas){switch(this.state.kind){case"object":{var children=this.state.children;return aggregateObjectAnalysis(Object.keys(children),function(key){var child=children[key];if(!child)throw new Error('unreachable: missing child "'.concat(key,'"'));return child.analyze(inputSchema,identifierSchemas)})}case"literal":return{valid:true,diagnostics:[],outputSchema:inferPrimitiveSchema(this.state.value)};case"template":return analyzeFromAst(this.state.ast,this.state.source,inputSchema,{identifierSchemas:identifierSchemas,helpers:this.options.helpers})}}},{key:"validate",value:function validate(inputSchema,identifierSchemas){var analysis=this.analyze(inputSchema,identifierSchemas);return{valid:analysis.valid,diagnostics:analysis.diagnostics}}},{key:"execute",value:function execute(data,options){switch(this.state.kind){case"object":{var children=this.state.children;var result={};var _iteratorNormalCompletion=true,_didIteratorError=false,_iteratorError=undefined;try{for(var _iterator=Object.entries(children)[Symbol.iterator](),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var _step_value=_sliced_to_array(_step.value,2),key=_step_value[0],child=_step_value[1];result[key]=child.execute(data,options)}}catch(err){_didIteratorError=true;_iteratorError=err}finally{try{if(!_iteratorNormalCompletion&&_iterator.return!=null){_iterator.return()}}finally{if(_didIteratorError){throw _iteratorError}}}return result}case"literal":return this.state.value;case"template":{if(options===null||options===void 0?void 0:options.schema){var analysis=this.analyze(options.schema,options.identifierSchemas);if(!analysis.valid){throw new TemplateAnalysisError(analysis.diagnostics)}}return executeFromAst(this.state.ast,this.state.source,data,this.buildExecutorContext(options))}}}},{key:"analyzeAndExecute",value:function analyzeAndExecute(inputSchema,data,options){switch(this.state.kind){case"object":{var children=this.state.children;return aggregateObjectAnalysisAndExecution(Object.keys(children),function(key){return children[key].analyzeAndExecute(inputSchema,data,options)})}case"literal":return{analysis:{valid:true,diagnostics:[],outputSchema:inferPrimitiveSchema(this.state.value)},value:this.state.value};case"template":{var analysis=this.analyze(inputSchema,options===null||options===void 0?void 0:options.identifierSchemas);if(!analysis.valid){return{analysis:analysis,value:undefined}}var value=executeFromAst(this.state.ast,this.state.source,data,this.buildExecutorContext({identifierData:options===null||options===void 0?void 0:options.identifierData}));return{analysis:analysis,value:value}}}}},{key:"buildExecutorContext",value:function buildExecutorContext(options){return{identifierData:options===null||options===void 0?void 0:options.identifierData,compiledTemplate:this.getOrCompileHbs(),hbs:this.options.hbs,compilationCache:this.options.compilationCache}}},{key:"getOrCompileHbs",value:function getOrCompileHbs(){if(!this.hbsCompiled){this.hbsCompiled=this.options.hbs.compile(this.template,{noEscape:true,strict:false})}return this.hbsCompiled}}],[{key:"fromTemplate",value:function fromTemplate(ast,source,options){return new CompiledTemplate({kind:"template",ast:ast,source:source},options)}},{key:"fromLiteral",value:function fromLiteral(value,options){return new CompiledTemplate({kind:"literal",value:value},options)}},{key:"fromObject",value:function fromObject(children,options){return new CompiledTemplate({kind:"object",children:children},options)}}]);return CompiledTemplate}();
2
+ //# sourceMappingURL=compiled-template.js.map
@@ -1,9 +1 @@
1
- {
2
- "version": 3,
3
- "sources": [],
4
- "sourcesContent": [
5
- ],
6
- "mappings": "",
7
- "debugId": "771271DE7F3CA9FE64756E2164756E21",
8
- "names": []
9
- }
1
+ {"version":3,"sources":["../src/compiled-template.ts"],"sourcesContent":["import type Handlebars from \"handlebars\";\nimport type { JSONSchema7 } from \"json-schema\";\nimport { analyzeFromAst } from \"./analyzer\";\nimport { TemplateAnalysisError } from \"./errors\";\nimport { type ExecutorContext, executeFromAst } from \"./executor\";\nimport type {\n\tAnalysisResult,\n\tExecuteOptions,\n\tHelperDefinition,\n\tValidationResult,\n} from \"./types\";\nimport { inferPrimitiveSchema } from \"./types\";\nimport {\n\taggregateObjectAnalysis,\n\taggregateObjectAnalysisAndExecution,\n\ttype LRUCache,\n} from \"./utils\";\n\n// ─── CompiledTemplate ────────────────────────────────────────────────────────\n// Pre-parsed template ready to be executed or analyzed without re-parsing.\n//\n// The compile-once / execute-many pattern avoids the cost of Handlebars\n// parsing on every call. The AST is parsed once at compile time, and the\n// Handlebars template is lazily compiled on the first `execute()`.\n//\n// Usage:\n// const tpl = engine.compile(\"Hello {{name}}\");\n// tpl.execute({ name: \"Alice\" }); // no re-parsing\n// tpl.execute({ name: \"Bob\" }); // no re-parsing or recompilation\n// tpl.analyze(schema); // no re-parsing\n//\n// ─── Internal State (TemplateState) ──────────────────────────────────────────\n// CompiledTemplate operates in 3 exclusive modes, modeled by a discriminated\n// union `TemplateState`:\n//\n// - `\"template\"` — parsed Handlebars template (AST + source string)\n// - `\"literal\"` — primitive passthrough value (number, boolean, null)\n// - `\"object\"` — object where each property is a child CompiledTemplate\n//\n// This design eliminates optional fields and `!` assertions in favor of\n// natural TypeScript narrowing via `switch (this.state.kind)`.\n//\n// ─── Advantages Over the Direct API ──────────────────────────────────────────\n// - **Performance**: parsing and compilation happen only once\n// - **Simplified API**: no need to re-pass the template string on each call\n// - **Consistency**: the same AST is used for both analysis and execution\n\n// ─── Internal Types ──────────────────────────────────────────────────────────\n\n/** Internal options passed by Typebars during compilation */\nexport interface CompiledTemplateOptions {\n\t/** Custom helpers registered on the engine */\n\thelpers: Map<string, HelperDefinition>;\n\t/** Isolated Handlebars environment (with registered helpers) */\n\thbs: typeof Handlebars;\n\t/** Compilation cache shared by the engine */\n\tcompilationCache: LRUCache<string, HandlebarsTemplateDelegate>;\n}\n\n/** Discriminated internal state of the CompiledTemplate */\ntype TemplateState =\n\t| {\n\t\t\treadonly kind: \"template\";\n\t\t\treadonly ast: hbs.AST.Program;\n\t\t\treadonly source: string;\n\t }\n\t| { readonly kind: \"literal\"; readonly value: number | boolean | null }\n\t| {\n\t\t\treadonly kind: \"object\";\n\t\t\treadonly children: Record<string, CompiledTemplate>;\n\t };\n\n// ─── Public Class ────────────────────────────────────────────────────────────\n\nexport class CompiledTemplate {\n\t/** Discriminated internal state */\n\tprivate readonly state: TemplateState;\n\n\t/** Options inherited from the parent Typebars instance */\n\tprivate readonly options: CompiledTemplateOptions;\n\n\t/** Compiled Handlebars template (lazy — created on the first `execute()` that needs it) */\n\tprivate hbsCompiled: HandlebarsTemplateDelegate | null = null;\n\n\t// ─── Public Accessors (backward-compatible) ──────────────────────────\n\n\t/** The pre-parsed Handlebars AST — `null` in literal or object mode */\n\tget ast(): hbs.AST.Program | null {\n\t\treturn this.state.kind === \"template\" ? this.state.ast : null;\n\t}\n\n\t/** The original template source — empty string in literal or object mode */\n\tget template(): string {\n\t\treturn this.state.kind === \"template\" ? this.state.source : \"\";\n\t}\n\n\t// ─── Construction ────────────────────────────────────────────────────\n\n\tprivate constructor(state: TemplateState, options: CompiledTemplateOptions) {\n\t\tthis.state = state;\n\t\tthis.options = options;\n\t}\n\n\t/**\n\t * Creates a CompiledTemplate for a parsed Handlebars template.\n\t *\n\t * @param ast - The pre-parsed Handlebars AST\n\t * @param source - The original template source\n\t * @param options - Options inherited from Typebars\n\t */\n\tstatic fromTemplate(\n\t\tast: hbs.AST.Program,\n\t\tsource: string,\n\t\toptions: CompiledTemplateOptions,\n\t): CompiledTemplate {\n\t\treturn new CompiledTemplate({ kind: \"template\", ast, source }, options);\n\t}\n\n\t/**\n\t * Creates a CompiledTemplate in passthrough mode for a literal value\n\t * (number, boolean, null). No parsing or compilation is performed.\n\t *\n\t * @param value - The primitive value\n\t * @param options - Options inherited from Typebars\n\t * @returns A CompiledTemplate that always returns `value`\n\t */\n\tstatic fromLiteral(\n\t\tvalue: number | boolean | null,\n\t\toptions: CompiledTemplateOptions,\n\t): CompiledTemplate {\n\t\treturn new CompiledTemplate({ kind: \"literal\", value }, options);\n\t}\n\n\t/**\n\t * Creates a CompiledTemplate in object mode, where each property is a\n\t * child CompiledTemplate. All operations are recursively delegated\n\t * to the children.\n\t *\n\t * @param children - The compiled child templates `{ [key]: CompiledTemplate }`\n\t * @param options - Options inherited from Typebars\n\t * @returns A CompiledTemplate that delegates to children\n\t */\n\tstatic fromObject(\n\t\tchildren: Record<string, CompiledTemplate>,\n\t\toptions: CompiledTemplateOptions,\n\t): CompiledTemplate {\n\t\treturn new CompiledTemplate({ kind: \"object\", children }, options);\n\t}\n\n\t// ─── Static Analysis ─────────────────────────────────────────────────\n\n\t/**\n\t * Statically analyzes this template against a JSON Schema v7.\n\t *\n\t * Returns an `AnalysisResult` containing:\n\t * - `valid` — `true` if no errors\n\t * - `diagnostics` — list of diagnostics (errors + warnings)\n\t * - `outputSchema` — JSON Schema describing the return type\n\t *\n\t * Since the AST is pre-parsed, this method never re-parses the template.\n\t *\n\t * @param inputSchema - JSON Schema describing the available variables\n\t * @param identifierSchemas - (optional) Schemas by identifier `{ [id]: JSONSchema7 }`\n\t */\n\tanalyze(\n\t\tinputSchema: JSONSchema7,\n\t\tidentifierSchemas?: Record<number, JSONSchema7>,\n\t): AnalysisResult {\n\t\tswitch (this.state.kind) {\n\t\t\tcase \"object\": {\n\t\t\t\tconst { children } = this.state;\n\t\t\t\treturn aggregateObjectAnalysis(Object.keys(children), (key) => {\n\t\t\t\t\tconst child = children[key];\n\t\t\t\t\tif (!child) throw new Error(`unreachable: missing child \"${key}\"`);\n\t\t\t\t\treturn child.analyze(inputSchema, identifierSchemas);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tcase \"literal\":\n\t\t\t\treturn {\n\t\t\t\t\tvalid: true,\n\t\t\t\t\tdiagnostics: [],\n\t\t\t\t\toutputSchema: inferPrimitiveSchema(this.state.value),\n\t\t\t\t};\n\n\t\t\tcase \"template\":\n\t\t\t\treturn analyzeFromAst(this.state.ast, this.state.source, inputSchema, {\n\t\t\t\t\tidentifierSchemas,\n\t\t\t\t\thelpers: this.options.helpers,\n\t\t\t\t});\n\t\t}\n\t}\n\n\t// ─── Validation ──────────────────────────────────────────────────────\n\n\t/**\n\t * Validates the 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 inputSchema - JSON Schema describing the available variables\n\t * @param identifierSchemas - (optional) Schemas by identifier\n\t */\n\tvalidate(\n\t\tinputSchema: JSONSchema7,\n\t\tidentifierSchemas?: Record<number, JSONSchema7>,\n\t): ValidationResult {\n\t\tconst analysis = this.analyze(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// ─── Execution ───────────────────────────────────────────────────────\n\n\t/**\n\t * Executes this template with the provided data.\n\t *\n\t * The return type depends on the template structure:\n\t * - Single expression `{{expr}}` → raw value (number, boolean, object…)\n\t * - Mixed template or with blocks → `string`\n\t * - Primitive literal → the value as-is\n\t * - Object template → object with resolved values\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 data - The context data for rendering\n\t * @param options - Execution options (schema, identifierData, etc.)\n\t * @returns The execution result\n\t */\n\texecute(data: Record<string, unknown>, options?: ExecuteOptions): unknown {\n\t\tswitch (this.state.kind) {\n\t\t\tcase \"object\": {\n\t\t\t\tconst { children } = this.state;\n\t\t\t\tconst result: Record<string, unknown> = {};\n\t\t\t\tfor (const [key, child] of Object.entries(children)) {\n\t\t\t\t\tresult[key] = child.execute(data, options);\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\tcase \"literal\":\n\t\t\t\treturn this.state.value;\n\n\t\t\tcase \"template\": {\n\t\t\t\t// Pre-execution static validation if a schema is provided\n\t\t\t\tif (options?.schema) {\n\t\t\t\t\tconst analysis = this.analyze(\n\t\t\t\t\t\toptions.schema,\n\t\t\t\t\t\toptions.identifierSchemas,\n\t\t\t\t\t);\n\t\t\t\t\tif (!analysis.valid) {\n\t\t\t\t\t\tthrow new TemplateAnalysisError(analysis.diagnostics);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn executeFromAst(\n\t\t\t\t\tthis.state.ast,\n\t\t\t\t\tthis.state.source,\n\t\t\t\t\tdata,\n\t\t\t\t\tthis.buildExecutorContext(options),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t// ─── Combined Shortcuts ──────────────────────────────────────────────\n\n\t/**\n\t * Analyzes and executes the template in a single call.\n\t *\n\t * Returns both the analysis result and the executed value.\n\t * If analysis fails, `value` is `undefined`.\n\t *\n\t * @param inputSchema - JSON Schema describing the available variables\n\t * @param data - The context data for rendering\n\t * @param options - Additional options\n\t * @returns `{ analysis, value }`\n\t */\n\tanalyzeAndExecute(\n\t\tinputSchema: JSONSchema7,\n\t\tdata: Record<string, unknown>,\n\t\toptions?: {\n\t\t\tidentifierSchemas?: Record<number, JSONSchema7>;\n\t\t\tidentifierData?: Record<number, Record<string, unknown>>;\n\t\t},\n\t): { analysis: AnalysisResult; value: unknown } {\n\t\tswitch (this.state.kind) {\n\t\t\tcase \"object\": {\n\t\t\t\tconst { children } = this.state;\n\t\t\t\treturn aggregateObjectAnalysisAndExecution(\n\t\t\t\t\tObject.keys(children),\n\t\t\t\t\t// biome-ignore lint/style/noNonNullAssertion: key comes from Object.keys(children), access is guaranteed\n\t\t\t\t\t(key) => children[key]!.analyzeAndExecute(inputSchema, data, options),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tcase \"literal\":\n\t\t\t\treturn {\n\t\t\t\t\tanalysis: {\n\t\t\t\t\t\tvalid: true,\n\t\t\t\t\t\tdiagnostics: [],\n\t\t\t\t\t\toutputSchema: inferPrimitiveSchema(this.state.value),\n\t\t\t\t\t},\n\t\t\t\t\tvalue: this.state.value,\n\t\t\t\t};\n\n\t\t\tcase \"template\": {\n\t\t\t\tconst analysis = this.analyze(inputSchema, options?.identifierSchemas);\n\n\t\t\t\tif (!analysis.valid) {\n\t\t\t\t\treturn { analysis, value: undefined };\n\t\t\t\t}\n\n\t\t\t\tconst value = executeFromAst(\n\t\t\t\t\tthis.state.ast,\n\t\t\t\t\tthis.state.source,\n\t\t\t\t\tdata,\n\t\t\t\t\tthis.buildExecutorContext({\n\t\t\t\t\t\tidentifierData: options?.identifierData,\n\t\t\t\t\t}),\n\t\t\t\t);\n\n\t\t\t\treturn { analysis, value };\n\t\t\t}\n\t\t}\n\t}\n\n\t// ─── Internals ───────────────────────────────────────────────────────\n\n\t/**\n\t * Builds the execution context for `executeFromAst`.\n\t *\n\t * Uses lazy Handlebars compilation: the template is only compiled\n\t * on the first call that needs it (not for single expressions).\n\t */\n\tprivate buildExecutorContext(options?: ExecuteOptions): ExecutorContext {\n\t\treturn {\n\t\t\tidentifierData: options?.identifierData,\n\t\t\tcompiledTemplate: this.getOrCompileHbs(),\n\t\t\thbs: this.options.hbs,\n\t\t\tcompilationCache: this.options.compilationCache,\n\t\t};\n\t}\n\n\t/**\n\t * Lazily compiles the Handlebars template and caches it.\n\t *\n\t * Compilation happens only once — subsequent calls return the\n\t * in-memory compiled template.\n\t *\n\t * Precondition: this method is only called from \"template\" mode.\n\t */\n\tprivate getOrCompileHbs(): HandlebarsTemplateDelegate {\n\t\tif (!this.hbsCompiled) {\n\t\t\t// In \"template\" mode, `this.template` returns the source string\n\t\t\tthis.hbsCompiled = this.options.hbs.compile(this.template, {\n\t\t\t\tnoEscape: true,\n\t\t\t\tstrict: false,\n\t\t\t});\n\t\t}\n\t\treturn this.hbsCompiled;\n\t}\n}\n"],"names":["analyzeFromAst","TemplateAnalysisError","executeFromAst","inferPrimitiveSchema","aggregateObjectAnalysis","aggregateObjectAnalysisAndExecution","CompiledTemplate","state","options","hbsCompiled","ast","kind","template","source","analyze","inputSchema","identifierSchemas","children","Object","keys","key","child","Error","valid","diagnostics","outputSchema","value","helpers","validate","analysis","execute","data","result","entries","schema","buildExecutorContext","analyzeAndExecute","undefined","identifierData","compiledTemplate","getOrCompileHbs","hbs","compilationCache","compile","noEscape","strict","fromTemplate","fromLiteral","fromObject"],"mappings":"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"}
package/dist/errors.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { TemplateDiagnostic } from "./types.ts";
1
+ import type { TemplateDiagnostic } from "./types";
2
2
  export declare class TemplateError extends Error {
3
3
  constructor(message: string);
4
4
  /**
package/dist/errors.js CHANGED
@@ -1,4 +1,2 @@
1
- import{K as a,L as b,M as c,N as d,O as e,P as f,Q as g,R as h,S as i,T as j}from"./chunk-zh1e0yhd.js";export{i as createUnknownHelperMessage,j as createUnanalyzableMessage,g as createTypeMismatchMessage,f as createPropertyNotFoundMessage,h as createMissingArgumentMessage,e as UnsupportedSchemaError,d as TemplateRuntimeError,b as TemplateParseError,a as TemplateError,c as TemplateAnalysisError};
2
-
3
- //# debugId=5F99984E8843AC9E64756E2164756E21
4
- //# sourceMappingURL=errors.js.map
1
+ function _assert_this_initialized(self){if(self===void 0){throw new ReferenceError("this hasn't been initialised - super() hasn't been called")}return self}function _call_super(_this,derived,args){derived=_get_prototype_of(derived);return _possible_constructor_return(_this,_is_native_reflect_construct()?Reflect.construct(derived,args||[],_get_prototype_of(_this).constructor):derived.apply(_this,args))}function _class_call_check(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}}function _construct(Parent,args,Class){if(_is_native_reflect_construct()){_construct=Reflect.construct}else{_construct=function construct(Parent,args,Class){var a=[null];a.push.apply(a,args);var Constructor=Function.bind.apply(Parent,a);var instance=new Constructor;if(Class)_set_prototype_of(instance,Class.prototype);return instance}}return _construct.apply(null,arguments)}function _defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor)}}function _create_class(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);return Constructor}function _define_property(obj,key,value){if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true})}else{obj[key]=value}return obj}function _get_prototype_of(o){_get_prototype_of=Object.setPrototypeOf?Object.getPrototypeOf:function getPrototypeOf(o){return o.__proto__||Object.getPrototypeOf(o)};return _get_prototype_of(o)}function _inherits(subClass,superClass){if(typeof superClass!=="function"&&superClass!==null){throw new TypeError("Super expression must either be null or a function")}subClass.prototype=Object.create(superClass&&superClass.prototype,{constructor:{value:subClass,writable:true,configurable:true}});if(superClass)_set_prototype_of(subClass,superClass)}function _is_native_function(fn){return Function.toString.call(fn).indexOf("[native code]")!==-1}function _possible_constructor_return(self,call){if(call&&(_type_of(call)==="object"||typeof call==="function")){return call}return _assert_this_initialized(self)}function _set_prototype_of(o,p){_set_prototype_of=Object.setPrototypeOf||function setPrototypeOf(o,p){o.__proto__=p;return o};return _set_prototype_of(o,p)}function _type_of(obj){"@swc/helpers - typeof";return obj&&typeof Symbol!=="undefined"&&obj.constructor===Symbol?"symbol":typeof obj}function _wrap_native_super(Class){var _cache=typeof Map==="function"?new Map:undefined;_wrap_native_super=function wrapNativeSuper(Class){if(Class===null||!_is_native_function(Class))return Class;if(typeof Class!=="function"){throw new TypeError("Super expression must either be null or a function")}if(typeof _cache!=="undefined"){if(_cache.has(Class))return _cache.get(Class);_cache.set(Class,Wrapper)}function Wrapper(){return _construct(Class,arguments,_get_prototype_of(this).constructor)}Wrapper.prototype=Object.create(Class.prototype,{constructor:{value:Wrapper,enumerable:false,writable:true,configurable:true}});return _set_prototype_of(Wrapper,Class)};return _wrap_native_super(Class)}function _is_native_reflect_construct(){try{var result=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch(_){}return(_is_native_reflect_construct=function(){return!!result})()}export var TemplateError=/*#__PURE__*/function(Error1){"use strict";_inherits(TemplateError,Error1);function TemplateError(message){_class_call_check(this,TemplateError);var _this;_this=_call_super(this,TemplateError,[message]);_this.name="TemplateError";return _this}_create_class(TemplateError,[{key:"toJSON",value:function toJSON(){return{name:this.name,message:this.message}}}]);return TemplateError}(_wrap_native_super(Error));export var TemplateParseError=/*#__PURE__*/function(TemplateError){"use strict";_inherits(TemplateParseError,TemplateError);function TemplateParseError(message,loc,source){_class_call_check(this,TemplateParseError);var _this;_this=_call_super(this,TemplateParseError,["Parse error: ".concat(message)]),_define_property(_this,"loc",void 0),_define_property(_this,"source",void 0),_this.loc=loc,_this.source=source;_this.name="TemplateParseError";return _this}_create_class(TemplateParseError,[{key:"toJSON",value:function toJSON(){return{name:this.name,message:this.message,loc:this.loc,source:this.source}}}]);return TemplateParseError}(TemplateError);export var TemplateAnalysisError=/*#__PURE__*/function(TemplateError){"use strict";_inherits(TemplateAnalysisError,TemplateError);function TemplateAnalysisError(diagnostics){_class_call_check(this,TemplateAnalysisError);var _this;var errors=diagnostics.filter(function(d){return d.severity==="error"});var warnings=diagnostics.filter(function(d){return d.severity==="warning"});var summary=errors.map(function(d){return formatDiagnosticLine(d)}).join("\n");_this=_call_super(this,TemplateAnalysisError,["Static analysis failed with ".concat(errors.length," error(s):\n").concat(summary)]),_define_property(_this,"diagnostics",void 0),_define_property(_this,"errors",void 0),_define_property(_this,"warnings",void 0),_define_property(_this,"errorCount",void 0),_define_property(_this,"warningCount",void 0);_this.name="TemplateAnalysisError";_this.diagnostics=diagnostics;_this.errors=errors;_this.warnings=warnings;_this.errorCount=errors.length;_this.warningCount=warnings.length;return _this}_create_class(TemplateAnalysisError,[{key:"toJSON",value:function toJSON(){return{name:this.name,message:this.message,errorCount:this.errorCount,warningCount:this.warningCount,diagnostics:this.diagnostics}}}]);return TemplateAnalysisError}(TemplateError);export var TemplateRuntimeError=/*#__PURE__*/function(TemplateError){"use strict";_inherits(TemplateRuntimeError,TemplateError);function TemplateRuntimeError(message){_class_call_check(this,TemplateRuntimeError);var _this;_this=_call_super(this,TemplateRuntimeError,["Runtime error: ".concat(message)]);_this.name="TemplateRuntimeError";return _this}return TemplateRuntimeError}(TemplateError);export var UnsupportedSchemaError=/*#__PURE__*/function(TemplateError){"use strict";_inherits(UnsupportedSchemaError,TemplateError);function UnsupportedSchemaError(keyword,schemaPath){_class_call_check(this,UnsupportedSchemaError);var _this;_this=_call_super(this,UnsupportedSchemaError,['Unsupported JSON Schema feature: "'.concat(keyword,'" at "').concat(schemaPath,'". ')+"Conditional schemas (if/then/else) cannot be resolved during static analysis "+"because they depend on runtime data. Consider using oneOf/anyOf combinators instead."]),_define_property(_this,"keyword",void 0),_define_property(_this,"schemaPath",void 0),_this.keyword=keyword,_this.schemaPath=schemaPath;_this.name="UnsupportedSchemaError";return _this}_create_class(UnsupportedSchemaError,[{key:"toJSON",value:function toJSON(){return{name:this.name,message:this.message,keyword:this.keyword,schemaPath:this.schemaPath}}}]);return UnsupportedSchemaError}(TemplateError);function formatDiagnosticLine(diag){var parts=[" • [".concat(diag.code,"] ").concat(diag.message)];if(diag.loc){parts.push("(at ".concat(diag.loc.start.line,":").concat(diag.loc.start.column,")"))}return parts.join(" ")}export function createPropertyNotFoundMessage(path,availableProperties){var base='Property "'.concat(path,'" does not exist in the context schema');if(availableProperties.length===0)return base;return"".concat(base,". Available properties: ").concat(availableProperties.join(", "))}export function createTypeMismatchMessage(helperName,expected,actual){return'"{{#'.concat(helperName,'}}" expects ').concat(expected,', but resolved schema has type "').concat(actual,'"')}export function createMissingArgumentMessage(helperName){return'"{{#'.concat(helperName,'}}" requires an argument')}export function createUnknownHelperMessage(helperName){return'Unknown block helper "{{#'.concat(helperName,'}}" — cannot analyze statically')}export function createUnanalyzableMessage(nodeType){return'Expression of type "'.concat(nodeType,'" cannot be statically analyzed')}
2
+ //# sourceMappingURL=errors.js.map
@@ -1,9 +1 @@
1
- {
2
- "version": 3,
3
- "sources": [],
4
- "sourcesContent": [
5
- ],
6
- "mappings": "",
7
- "debugId": "5F99984E8843AC9E64756E2164756E21",
8
- "names": []
9
- }
1
+ {"version":3,"sources":["../src/errors.ts"],"sourcesContent":["import type { TemplateDiagnostic } from \"./types\";\n\n// ─── Base Class ──────────────────────────────────────────────────────────────\n// All template engine errors extend this class, enabling targeted catch blocks:\n// `catch (e) { if (e instanceof TemplateError) … }`\n// Subclasses:\n// - `TemplateParseError` — invalid template syntax\n// - `TemplateAnalysisError` — static analysis failures (diagnostics)\n// - `TemplateRuntimeError` — execution failures\n// - `UnsupportedSchemaError` — schema uses unsupported JSON Schema features\n\nexport class TemplateError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"TemplateError\";\n\t}\n\n\t/**\n\t * Serializes the error into a JSON-compatible object, suitable for sending\n\t * to a frontend or a structured logging system.\n\t */\n\ttoJSON(): Record<string, unknown> {\n\t\treturn {\n\t\t\tname: this.name,\n\t\t\tmessage: this.message,\n\t\t};\n\t}\n}\n\n// ─── Parse Error ─────────────────────────────────────────────────────────────\n// Thrown when Handlebars fails to parse the template (invalid syntax).\n\nexport class TemplateParseError extends TemplateError {\n\tconstructor(\n\t\tmessage: string,\n\t\t/** Approximate position of the error in the source */\n\t\tpublic readonly loc?: { line: number; column: number },\n\t\t/** Fragment of the template source around the error */\n\t\tpublic readonly source?: string,\n\t) {\n\t\tsuper(`Parse error: ${message}`);\n\t\tthis.name = \"TemplateParseError\";\n\t}\n\n\toverride toJSON(): Record<string, unknown> {\n\t\treturn {\n\t\t\tname: this.name,\n\t\t\tmessage: this.message,\n\t\t\tloc: this.loc,\n\t\t\tsource: this.source,\n\t\t};\n\t}\n}\n\n// ─── Static Analysis Error ───────────────────────────────────────────────────\n// Thrown in strict mode when the analysis produces at least one error.\n// Contains the full list of diagnostics for detailed inspection.\n\nexport class TemplateAnalysisError extends TemplateError {\n\t/** Full list of diagnostics (errors + warnings) */\n\tpublic readonly diagnostics: TemplateDiagnostic[];\n\n\t/** Only diagnostics with \"error\" severity */\n\tpublic readonly errors: TemplateDiagnostic[];\n\n\t/** Only diagnostics with \"warning\" severity */\n\tpublic readonly warnings: TemplateDiagnostic[];\n\n\t/** Total number of errors */\n\tpublic readonly errorCount: number;\n\n\t/** Total number of warnings */\n\tpublic readonly warningCount: number;\n\n\tconstructor(diagnostics: TemplateDiagnostic[]) {\n\t\tconst errors = diagnostics.filter((d) => d.severity === \"error\");\n\t\tconst warnings = diagnostics.filter((d) => d.severity === \"warning\");\n\n\t\tconst summary = errors.map((d) => formatDiagnosticLine(d)).join(\"\\n\");\n\t\tsuper(`Static analysis failed with ${errors.length} error(s):\\n${summary}`);\n\n\t\tthis.name = \"TemplateAnalysisError\";\n\t\tthis.diagnostics = diagnostics;\n\t\tthis.errors = errors;\n\t\tthis.warnings = warnings;\n\t\tthis.errorCount = errors.length;\n\t\tthis.warningCount = warnings.length;\n\t}\n\n\t/**\n\t * Serializes the analysis error into a JSON-compatible object.\n\t *\n\t * Designed for direct use in API responses:\n\t * ```\n\t * res.status(400).json(error.toJSON());\n\t * ```\n\t *\n\t * Returned structure:\n\t * ```\n\t * {\n\t * name: \"TemplateAnalysisError\",\n\t * message: \"Static analysis failed with 2 error(s): ...\",\n\t * errorCount: 2,\n\t * warningCount: 0,\n\t * diagnostics: [\n\t * {\n\t * severity: \"error\",\n\t * code: \"UNKNOWN_PROPERTY\",\n\t * message: \"Property \\\"foo\\\" does not exist...\",\n\t * loc: { start: { line: 1, column: 0 }, end: { line: 1, column: 7 } },\n\t * source: \"{{foo}}\",\n\t * details: { path: \"foo\", availableProperties: [\"name\", \"age\"] }\n\t * }\n\t * ]\n\t * }\n\t * ```\n\t */\n\toverride toJSON(): Record<string, unknown> {\n\t\treturn {\n\t\t\tname: this.name,\n\t\t\tmessage: this.message,\n\t\t\terrorCount: this.errorCount,\n\t\t\twarningCount: this.warningCount,\n\t\t\tdiagnostics: this.diagnostics,\n\t\t};\n\t}\n}\n\n// ─── Runtime Error ───────────────────────────────────────────────────────────\n// Thrown when template execution fails (accessing a non-existent property\n// in strict mode, unexpected type, etc.).\n\nexport class TemplateRuntimeError extends TemplateError {\n\tconstructor(message: string) {\n\t\tsuper(`Runtime error: ${message}`);\n\t\tthis.name = \"TemplateRuntimeError\";\n\t}\n}\n\n// ─── Unsupported Schema Error ────────────────────────────────────────────────\n// Thrown when the provided JSON Schema uses features that cannot be handled\n// by static analysis (e.g. `if/then/else` conditional schemas).\n//\n// These features are data-dependent and fundamentally non-resolvable without\n// runtime values. Rather than silently ignoring them (which would produce\n// incorrect analysis results), we fail fast with a clear error message.\n\nexport class UnsupportedSchemaError extends TemplateError {\n\tconstructor(\n\t\t/** The unsupported keyword(s) detected (e.g. `\"if/then/else\"`) */\n\t\tpublic readonly keyword: string,\n\t\t/** JSON pointer path to the location in the schema (e.g. `\"/properties/user\"`) */\n\t\tpublic readonly schemaPath: string,\n\t) {\n\t\tsuper(\n\t\t\t`Unsupported JSON Schema feature: \"${keyword}\" at \"${schemaPath}\". ` +\n\t\t\t\t\"Conditional schemas (if/then/else) cannot be resolved during static analysis \" +\n\t\t\t\t\"because they depend on runtime data. Consider using oneOf/anyOf combinators instead.\",\n\t\t);\n\t\tthis.name = \"UnsupportedSchemaError\";\n\t}\n\n\toverride toJSON(): Record<string, unknown> {\n\t\treturn {\n\t\t\tname: this.name,\n\t\t\tmessage: this.message,\n\t\t\tkeyword: this.keyword,\n\t\t\tschemaPath: this.schemaPath,\n\t\t};\n\t}\n}\n\n// ─── Internal Utilities ──────────────────────────────────────────────────────\n\n/**\n * Formats a single diagnostic line for the summary message\n * of a `TemplateAnalysisError`.\n *\n * Produces a human-readable format:\n * ` • [UNKNOWN_PROPERTY] Property \"foo\" does not exist (at 1:0)`\n */\nfunction formatDiagnosticLine(diag: TemplateDiagnostic): string {\n\tconst parts: string[] = [` • [${diag.code}] ${diag.message}`];\n\n\tif (diag.loc) {\n\t\tparts.push(`(at ${diag.loc.start.line}:${diag.loc.start.column})`);\n\t}\n\n\treturn parts.join(\" \");\n}\n\n// ─── Common Error Factories ──────────────────────────────────────────────────\n// These functions simplify the creation of typed errors across the codebase.\n\n/**\n * Creates a structured diagnostic message for a missing property.\n * Used by the analyzer to produce enriched error messages with suggestions.\n */\nexport function createPropertyNotFoundMessage(\n\tpath: string,\n\tavailableProperties: string[],\n): string {\n\tconst base = `Property \"${path}\" does not exist in the context schema`;\n\tif (availableProperties.length === 0) return base;\n\treturn `${base}. Available properties: ${availableProperties.join(\", \")}`;\n}\n\n/**\n * Creates a message for a type mismatch on a block helper.\n */\nexport function createTypeMismatchMessage(\n\thelperName: string,\n\texpected: string,\n\tactual: string,\n): string {\n\treturn `\"{{#${helperName}}}\" expects ${expected}, but resolved schema has type \"${actual}\"`;\n}\n\n/**\n * Creates a message for a missing argument on a block helper.\n */\nexport function createMissingArgumentMessage(helperName: string): string {\n\treturn `\"{{#${helperName}}}\" requires an argument`;\n}\n\n/**\n * Creates a message for an unknown block helper.\n */\nexport function createUnknownHelperMessage(helperName: string): string {\n\treturn `Unknown block helper \"{{#${helperName}}}\" — cannot analyze statically`;\n}\n\n/**\n * Creates a message for an expression that cannot be statically analyzed.\n */\nexport function createUnanalyzableMessage(nodeType: string): string {\n\treturn `Expression of type \"${nodeType}\" cannot be statically analyzed`;\n}\n"],"names":["TemplateError","message","name","toJSON","Error","TemplateParseError","loc","source","TemplateAnalysisError","diagnostics","errors","filter","d","severity","warnings","summary","map","formatDiagnosticLine","join","length","errorCount","warningCount","TemplateRuntimeError","UnsupportedSchemaError","keyword","schemaPath","diag","parts","code","push","start","line","column","createPropertyNotFoundMessage","path","availableProperties","base","createTypeMismatchMessage","helperName","expected","actual","createMissingArgumentMessage","createUnknownHelperMessage","createUnanalyzableMessage","nodeType"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import Handlebars from "handlebars";
2
- import type { TemplateInput } from "./types.ts";
3
- import { LRUCache } from "./utils.ts";
2
+ import type { TemplateInput } from "./types";
3
+ import { LRUCache } from "./utils";
4
4
  /** Optional context for execution (used by Typebars/CompiledTemplate) */
5
5
  export interface ExecutorContext {
6
6
  /** Data by identifier `{ [id]: { key: value } }` */
package/dist/executor.js CHANGED
@@ -1,4 +1,2 @@
1
- import{f as a,g as b,h as c,i as d}from"./chunk-efqd0598.js";import"./chunk-6955jpr7.js";import"./chunk-rkrp4ysw.js";import"./chunk-p5efqsxw.js";import"./chunk-zh1e0yhd.js";export{c as resolveDataPath,b as executeFromAst,a as execute,d as clearCompilationCache};
2
-
3
- //# debugId=E439EBF232D2886264756E2164756E21
4
- //# sourceMappingURL=executor.js.map
1
+ function _array_like_to_array(arr,len){if(len==null||len>arr.length)len=arr.length;for(var i=0,arr2=new Array(len);i<len;i++)arr2[i]=arr[i];return arr2}function _array_with_holes(arr){if(Array.isArray(arr))return arr}function _define_property(obj,key,value){if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true})}else{obj[key]=value}return obj}function _instanceof(left,right){if(right!=null&&typeof Symbol!=="undefined"&&right[Symbol.hasInstance]){return!!right[Symbol.hasInstance](left)}else{return left instanceof right}}function _iterable_to_array_limit(arr,i){var _i=arr==null?null:typeof Symbol!=="undefined"&&arr[Symbol.iterator]||arr["@@iterator"];if(_i==null)return;var _arr=[];var _n=true;var _d=false;var _s,_e;try{for(_i=_i.call(arr);!(_n=(_s=_i.next()).done);_n=true){_arr.push(_s.value);if(i&&_arr.length===i)break}}catch(err){_d=true;_e=err}finally{try{if(!_n&&_i["return"]!=null)_i["return"]()}finally{if(_d)throw _e}}return _arr}function _non_iterable_rest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _object_spread(target){for(var i=1;i<arguments.length;i++){var source=arguments[i]!=null?arguments[i]:{};var ownKeys=Object.keys(source);if(typeof Object.getOwnPropertySymbols==="function"){ownKeys=ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym){return Object.getOwnPropertyDescriptor(source,sym).enumerable}))}ownKeys.forEach(function(key){_define_property(target,key,source[key])})}return target}function _sliced_to_array(arr,i){return _array_with_holes(arr)||_iterable_to_array_limit(arr,i)||_unsupported_iterable_to_array(arr,i)||_non_iterable_rest()}function _type_of(obj){"@swc/helpers - typeof";return obj&&typeof Symbol!=="undefined"&&obj.constructor===Symbol?"symbol":typeof obj}function _unsupported_iterable_to_array(o,minLen){if(!o)return;if(typeof o==="string")return _array_like_to_array(o,minLen);var n=Object.prototype.toString.call(o).slice(8,-1);if(n==="Object"&&o.constructor)n=o.constructor.name;if(n==="Map"||n==="Set")return Array.from(n);if(n==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return _array_like_to_array(o,minLen)}import Handlebars from"handlebars";import{TemplateRuntimeError}from"./errors";import{canUseFastPath,coerceLiteral,extractExpressionIdentifier,extractPathSegments,getEffectivelySingleBlock,getEffectivelySingleExpression,isSingleExpression,isThisExpression,parse}from"./parser";import{isLiteralInput,isObjectInput}from"./types";import{LRUCache}from"./utils";var globalCompilationCache=new LRUCache(128);export function execute(template,data,identifierData){if(isObjectInput(template)){return executeObjectTemplate(template,data,identifierData)}if(isLiteralInput(template))return template;var ast=parse(template);return executeFromAst(ast,template,data,{identifierData:identifierData})}function executeObjectTemplate(template,data,identifierData){var result={};var _iteratorNormalCompletion=true,_didIteratorError=false,_iteratorError=undefined;try{for(var _iterator=Object.entries(template)[Symbol.iterator](),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var _step_value=_sliced_to_array(_step.value,2),key=_step_value[0],value=_step_value[1];result[key]=execute(value,data,identifierData)}}catch(err){_didIteratorError=true;_iteratorError=err}finally{try{if(!_iteratorNormalCompletion&&_iterator.return!=null){_iterator.return()}}finally{if(_didIteratorError){throw _iteratorError}}}return result}export function executeFromAst(ast,template,data,ctx){var identifierData=ctx===null||ctx===void 0?void 0:ctx.identifierData;if(isSingleExpression(ast)){var stmt=ast.body[0];if(stmt.params.length===0&&!stmt.hash){return resolveExpression(stmt.path,data,identifierData)}}var singleExpr=getEffectivelySingleExpression(ast);if(singleExpr&&singleExpr.params.length===0&&!singleExpr.hash){return resolveExpression(singleExpr.path,data,identifierData)}if(singleExpr&&(singleExpr.params.length>0||singleExpr.hash)){var merged=mergeDataWithIdentifiers(data,identifierData);var raw=renderWithHandlebars(template,merged,ctx);return coerceLiteral(raw)}if(canUseFastPath(ast)&&ast.body.length>1){return executeFastPath(ast,data,identifierData)}var singleBlock=getEffectivelySingleBlock(ast);if(singleBlock){var merged1=mergeDataWithIdentifiers(data,identifierData);var raw1=renderWithHandlebars(template,merged1,ctx);return coerceLiteral(raw1)}var merged2=mergeDataWithIdentifiers(data,identifierData);return renderWithHandlebars(template,merged2,ctx)}function executeFastPath(ast,data,identifierData){var result="";var _iteratorNormalCompletion=true,_didIteratorError=false,_iteratorError=undefined;try{for(var _iterator=ast.body[Symbol.iterator](),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var stmt=_step.value;if(stmt.type==="ContentStatement"){result+=stmt.value}else if(stmt.type==="MustacheStatement"){var value=resolveExpression(stmt.path,data,identifierData);if(value!=null){result+=String(value)}}}}catch(err){_didIteratorError=true;_iteratorError=err}finally{try{if(!_iteratorNormalCompletion&&_iterator.return!=null){_iterator.return()}}finally{if(_didIteratorError){throw _iteratorError}}}return result}function resolveExpression(expr,data,identifierData){if(isThisExpression(expr)){return data}if(expr.type==="StringLiteral")return expr.value;if(expr.type==="NumberLiteral")return expr.value;if(expr.type==="BooleanLiteral")return expr.value;if(expr.type==="NullLiteral")return null;if(expr.type==="UndefinedLiteral")return undefined;var segments=extractPathSegments(expr);if(segments.length===0){throw new TemplateRuntimeError('Cannot resolve expression of type "'.concat(expr.type,'"'))}var _extractExpressionIdentifier=extractExpressionIdentifier(segments),cleanSegments=_extractExpressionIdentifier.cleanSegments,identifier=_extractExpressionIdentifier.identifier;if(identifier!==null&&identifierData){var source=identifierData[identifier];if(source){return resolveDataPath(source,cleanSegments)}return undefined}if(identifier!==null&&!identifierData){return undefined}return resolveDataPath(data,cleanSegments)}export function resolveDataPath(data,segments){var current=data;var _iteratorNormalCompletion=true,_didIteratorError=false,_iteratorError=undefined;try{for(var _iterator=segments[Symbol.iterator](),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var segment=_step.value;if(current===null||current===undefined){return undefined}if((typeof current==="undefined"?"undefined":_type_of(current))!=="object"){return undefined}current=current[segment]}}catch(err){_didIteratorError=true;_iteratorError=err}finally{try{if(!_iteratorNormalCompletion&&_iterator.return!=null){_iterator.return()}}finally{if(_didIteratorError){throw _iteratorError}}}return current}function mergeDataWithIdentifiers(data,identifierData){if(!identifierData)return data;var merged=_object_spread({},data);var _iteratorNormalCompletion=true,_didIteratorError=false,_iteratorError=undefined;try{for(var _iterator=Object.entries(identifierData)[Symbol.iterator](),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var _step_value=_sliced_to_array(_step.value,2),id=_step_value[0],idData=_step_value[1];var _iteratorNormalCompletion1=true,_didIteratorError1=false,_iteratorError1=undefined;try{for(var _iterator1=Object.entries(idData)[Symbol.iterator](),_step1;!(_iteratorNormalCompletion1=(_step1=_iterator1.next()).done);_iteratorNormalCompletion1=true){var _step_value1=_sliced_to_array(_step1.value,2),key=_step_value1[0],value=_step_value1[1];merged["".concat(key,":").concat(id)]=value}}catch(err){_didIteratorError1=true;_iteratorError1=err}finally{try{if(!_iteratorNormalCompletion1&&_iterator1.return!=null){_iterator1.return()}}finally{if(_didIteratorError1){throw _iteratorError1}}}}}catch(err){_didIteratorError=true;_iteratorError=err}finally{try{if(!_iteratorNormalCompletion&&_iterator.return!=null){_iterator.return()}}finally{if(_didIteratorError){throw _iteratorError}}}return merged}function renderWithHandlebars(template,data,ctx){try{var _ref,_ref1;if(ctx===null||ctx===void 0?void 0:ctx.compiledTemplate){return ctx.compiledTemplate(data)}var cache=(_ref=ctx===null||ctx===void 0?void 0:ctx.compilationCache)!==null&&_ref!==void 0?_ref:globalCompilationCache;var hbs=(_ref1=ctx===null||ctx===void 0?void 0:ctx.hbs)!==null&&_ref1!==void 0?_ref1:Handlebars;var compiled=cache.get(template);if(!compiled){compiled=hbs.compile(template,{noEscape:true,strict:false});cache.set(template,compiled)}return compiled(data)}catch(error){var message=_instanceof(error,Error)?error.message:String(error);throw new TemplateRuntimeError(message)}}export function clearCompilationCache(){globalCompilationCache.clear()}
2
+ //# sourceMappingURL=executor.js.map
@@ -1,9 +1 @@
1
- {
2
- "version": 3,
3
- "sources": [],
4
- "sourcesContent": [
5
- ],
6
- "mappings": "",
7
- "debugId": "E439EBF232D2886264756E2164756E21",
8
- "names": []
9
- }
1
+ {"version":3,"sources":["../src/executor.ts"],"sourcesContent":["import Handlebars from \"handlebars\";\nimport { TemplateRuntimeError } from \"./errors\";\nimport {\n\tcanUseFastPath,\n\tcoerceLiteral,\n\textractExpressionIdentifier,\n\textractPathSegments,\n\tgetEffectivelySingleBlock,\n\tgetEffectivelySingleExpression,\n\tisSingleExpression,\n\tisThisExpression,\n\tparse,\n} from \"./parser\";\nimport type { TemplateInput, TemplateInputObject } from \"./types\";\nimport { isLiteralInput, isObjectInput } from \"./types\";\nimport { LRUCache } from \"./utils\";\n\n// ─── Template Executor ───────────────────────────────────────────────────────\n// Executes a Handlebars template with real data.\n//\n// Four execution modes (from fastest to most general):\n//\n// 1. **Single expression** (`{{value}}` or ` {{value}} `) → returns the raw\n// value without converting to string. This preserves the original type\n// (number, boolean, object, array, null).\n//\n// 2. **Fast-path** (text + simple expressions, no blocks or helpers) →\n// direct concatenation without going through Handlebars.compile(). Up to\n// 10-100x faster for simple templates like `Hello {{name}}`.\n//\n// 3. **Single block** (`{{#if x}}10{{else}}20{{/if}}` possibly surrounded\n// by whitespace) → rendered via Handlebars then intelligently coerced\n// (detecting number, boolean, null literals).\n//\n// 4. **Mixed template** (text + multiple blocks, helpers, …) →\n// delegates to Handlebars which always produces a string.\n//\n// ─── Caching ─────────────────────────────────────────────────────────────────\n// Handlebars-compiled templates are cached in an LRU cache to avoid costly\n// recompilation on repeated calls.\n//\n// Two cache levels:\n// - **Global cache** (module-level) for standalone `execute()` calls\n// - **Instance cache** for `Typebars` (passed via `ExecutorContext`)\n//\n// ─── Template Identifiers ────────────────────────────────────────────────────\n// The `{{key:N}}` syntax allows resolving a variable from a specific data\n// source, identified by an integer N. The optional `identifierData` parameter\n// provides a mapping `{ [id]: { key: value, ... } }`.\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n/** Optional context for execution (used by Typebars/CompiledTemplate) */\nexport interface ExecutorContext {\n\t/** Data by identifier `{ [id]: { key: value } }` */\n\tidentifierData?: Record<number, Record<string, unknown>>;\n\t/** Pre-compiled Handlebars template (for CompiledTemplate) */\n\tcompiledTemplate?: HandlebarsTemplateDelegate;\n\t/** Isolated Handlebars environment (for custom helpers) */\n\thbs?: typeof Handlebars;\n\t/** Compilation cache shared by the engine */\n\tcompilationCache?: LRUCache<string, HandlebarsTemplateDelegate>;\n}\n\n// ─── Global Compilation Cache ────────────────────────────────────────────────\n// Used by the standalone `execute()` function and `renderWithHandlebars()`.\n// `Typebars` instances use their own cache.\nconst globalCompilationCache = new LRUCache<string, HandlebarsTemplateDelegate>(\n\t128,\n);\n\n// ─── Public API (backward-compatible) ────────────────────────────────────────\n\n/**\n * Executes a template with the provided data and returns the result.\n *\n * The return type depends on the template structure:\n * - Single expression `{{expr}}` → raw value (any)\n * - Single block → coerced value (number, boolean, null, or string)\n * - Mixed template → `string`\n *\n * @param template - The template string\n * @param data - The main context data\n * @param identifierData - (optional) Data by identifier `{ [id]: { key: value } }`\n */\nexport function execute(\n\ttemplate: TemplateInput,\n\tdata: Record<string, unknown>,\n\tidentifierData?: Record<number, Record<string, unknown>>,\n): unknown {\n\tif (isObjectInput(template)) {\n\t\treturn executeObjectTemplate(template, data, identifierData);\n\t}\n\tif (isLiteralInput(template)) return template;\n\tconst ast = parse(template);\n\treturn executeFromAst(ast, template, data, { identifierData });\n}\n\n/**\n * Executes an object template recursively (standalone version).\n * Each property is executed individually and the result is an object\n * with the same structure but resolved values.\n */\nfunction executeObjectTemplate(\n\ttemplate: TemplateInputObject,\n\tdata: Record<string, unknown>,\n\tidentifierData?: Record<number, Record<string, unknown>>,\n): Record<string, unknown> {\n\tconst result: Record<string, unknown> = {};\n\tfor (const [key, value] of Object.entries(template)) {\n\t\tresult[key] = execute(value, data, identifierData);\n\t}\n\treturn result;\n}\n\n// ─── Internal API (for Typebars / CompiledTemplate) ──────────────────────\n\n/**\n * Executes a template from an already-parsed AST.\n *\n * This function is the core of execution. It is used by:\n * - `execute()` (backward-compatible wrapper)\n * - `CompiledTemplate.execute()` (with pre-parsed AST and cache)\n * - `Typebars.execute()` (with cache and helpers)\n *\n * @param ast - The already-parsed Handlebars AST\n * @param template - The template source (for Handlebars compilation if needed)\n * @param data - The main context data\n * @param ctx - Optional execution context\n */\nexport function executeFromAst(\n\tast: hbs.AST.Program,\n\ttemplate: string,\n\tdata: Record<string, unknown>,\n\tctx?: ExecutorContext,\n): unknown {\n\tconst identifierData = ctx?.identifierData;\n\n\t// ── Case 1: strict single expression `{{expr}}` ──────────────────────\n\t// Exclude helper calls (params > 0 or hash) because they must go\n\t// through Handlebars for correct execution.\n\tif (isSingleExpression(ast)) {\n\t\tconst stmt = ast.body[0] as hbs.AST.MustacheStatement;\n\t\tif (stmt.params.length === 0 && !stmt.hash) {\n\t\t\treturn resolveExpression(stmt.path, data, identifierData);\n\t\t}\n\t}\n\n\t// ── Case 1b: single expression with surrounding whitespace ` {{expr}} `\n\tconst singleExpr = getEffectivelySingleExpression(ast);\n\tif (singleExpr && singleExpr.params.length === 0 && !singleExpr.hash) {\n\t\treturn resolveExpression(singleExpr.path, data, identifierData);\n\t}\n\n\t// ── Case 1c: single expression with helper (params > 0) ──────────────\n\t// E.g. `{{ divide accountIds.length 10 }}` or `{{ math a \"+\" b }}`\n\t// The helper returns a typed value but Handlebars converts it to a\n\t// string. We render via Handlebars then coerce the result to recover\n\t// the original type (number, boolean, null).\n\tif (singleExpr && (singleExpr.params.length > 0 || singleExpr.hash)) {\n\t\tconst merged = mergeDataWithIdentifiers(data, identifierData);\n\t\tconst raw = renderWithHandlebars(template, merged, ctx);\n\t\treturn coerceLiteral(raw);\n\t}\n\n\t// ── Case 2: fast-path for simple templates (text + expressions) ──────\n\t// If the template only contains text and simple expressions (no blocks,\n\t// no helpers with parameters), we can do direct concatenation without\n\t// going through Handlebars.compile().\n\tif (canUseFastPath(ast) && ast.body.length > 1) {\n\t\treturn executeFastPath(ast, data, identifierData);\n\t}\n\n\t// ── Case 3: single block (possibly surrounded by whitespace) ─────────\n\t// Render via Handlebars then attempt to coerce the result to the\n\t// detected literal type (number, boolean, null).\n\tconst singleBlock = getEffectivelySingleBlock(ast);\n\tif (singleBlock) {\n\t\tconst merged = mergeDataWithIdentifiers(data, identifierData);\n\t\tconst raw = renderWithHandlebars(template, merged, ctx);\n\t\treturn coerceLiteral(raw);\n\t}\n\n\t// ── Case 4: mixed template → string ──────────────────────────────────\n\tconst merged = mergeDataWithIdentifiers(data, identifierData);\n\treturn renderWithHandlebars(template, merged, ctx);\n}\n\n// ─── Fast-Path Execution ─────────────────────────────────────────────────────\n// For templates consisting only of text and simple expressions (no blocks,\n// no helpers), we bypass Handlebars and do direct concatenation.\n// This is significantly faster.\n\n/**\n * Executes a template via the fast-path (direct concatenation).\n *\n * Precondition: `canUseFastPath(ast)` must return `true`.\n *\n * @param ast - The template AST (only ContentStatement and simple MustacheStatement)\n * @param data - The context data\n * @param identifierData - Data by identifier (optional)\n * @returns The resulting string\n */\nfunction executeFastPath(\n\tast: hbs.AST.Program,\n\tdata: Record<string, unknown>,\n\tidentifierData?: Record<number, Record<string, unknown>>,\n): string {\n\tlet result = \"\";\n\n\tfor (const stmt of ast.body) {\n\t\tif (stmt.type === \"ContentStatement\") {\n\t\t\tresult += (stmt as hbs.AST.ContentStatement).value;\n\t\t} else if (stmt.type === \"MustacheStatement\") {\n\t\t\tconst value = resolveExpression(\n\t\t\t\t(stmt as hbs.AST.MustacheStatement).path,\n\t\t\t\tdata,\n\t\t\t\tidentifierData,\n\t\t\t);\n\t\t\t// Handlebars converts values to strings for rendering.\n\t\t\t// We replicate this behavior: null/undefined → \"\", otherwise String(value).\n\t\t\tif (value != null) {\n\t\t\t\tresult += String(value);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result;\n}\n\n// ─── Direct Expression Resolution ────────────────────────────────────────────\n// Used for single-expression templates and the fast-path, to return the raw\n// value without going through the Handlebars engine.\n\n/**\n * Resolves an AST expression by following the path through the data.\n *\n * If the expression contains an identifier (e.g. `meetingId:1`), resolution\n * is performed in `identifierData[1]` instead of `data`.\n *\n * @param expr - The AST expression to resolve\n * @param data - The main data context\n * @param identifierData - Data by identifier (optional)\n * @returns The raw value pointed to by the expression\n */\nfunction resolveExpression(\n\texpr: hbs.AST.Expression,\n\tdata: Record<string, unknown>,\n\tidentifierData?: Record<number, Record<string, unknown>>,\n): unknown {\n\t// this / . → return the entire context\n\tif (isThisExpression(expr)) {\n\t\treturn data;\n\t}\n\n\t// Literals\n\tif (expr.type === \"StringLiteral\")\n\t\treturn (expr as hbs.AST.StringLiteral).value;\n\tif (expr.type === \"NumberLiteral\")\n\t\treturn (expr as hbs.AST.NumberLiteral).value;\n\tif (expr.type === \"BooleanLiteral\")\n\t\treturn (expr as hbs.AST.BooleanLiteral).value;\n\tif (expr.type === \"NullLiteral\") return null;\n\tif (expr.type === \"UndefinedLiteral\") return undefined;\n\n\t// PathExpression — navigate through segments in the data object\n\tconst segments = extractPathSegments(expr);\n\tif (segments.length === 0) {\n\t\tthrow new TemplateRuntimeError(\n\t\t\t`Cannot resolve expression of type \"${expr.type}\"`,\n\t\t);\n\t}\n\n\t// Extract the potential identifier from the last segment\n\tconst { cleanSegments, identifier } = extractExpressionIdentifier(segments);\n\n\tif (identifier !== null && identifierData) {\n\t\tconst source = identifierData[identifier];\n\t\tif (source) {\n\t\t\treturn resolveDataPath(source, cleanSegments);\n\t\t}\n\t\t// Source does not exist → undefined (like a missing key)\n\t\treturn undefined;\n\t}\n\n\tif (identifier !== null && !identifierData) {\n\t\t// Template uses an identifier but no identifierData was provided\n\t\treturn undefined;\n\t}\n\n\treturn resolveDataPath(data, cleanSegments);\n}\n\n/**\n * Navigates through a data object by following a path of segments.\n *\n * @param data - The data object\n * @param segments - The path segments (e.g. `[\"user\", \"address\", \"city\"]`)\n * @returns The value at the end of the path, or `undefined` if an\n * intermediate segment is null/undefined\n */\nexport function resolveDataPath(data: unknown, segments: string[]): unknown {\n\tlet current: unknown = data;\n\n\tfor (const segment of segments) {\n\t\tif (current === null || current === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif (typeof current !== \"object\") {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tcurrent = (current as Record<string, unknown>)[segment];\n\t}\n\n\treturn current;\n}\n\n// ─── Data Merging ────────────────────────────────────────────────────────────\n// For Handlebars rendering (mixed templates / blocks), we cannot intercept\n// resolution on a per-expression basis. Instead, we merge identifier data\n// into the main object using the format `\"key:N\"`.\n//\n// Handlebars parses `{{meetingId:1}}` as a PathExpression with a single\n// segment `\"meetingId:1\"`, so it looks up the key `\"meetingId:1\"` in the\n// data object — which matches our flattened format exactly.\n\n/**\n * Merges the main data with identifier data.\n *\n * @param data - Main data\n * @param identifierData - Data by identifier\n * @returns A merged object where identifier data appears as `\"key:N\"` keys\n *\n * @example\n * ```\n * mergeDataWithIdentifiers(\n * { name: \"Alice\" },\n * { 1: { meetingId: \"val1\" }, 2: { meetingId: \"val2\" } }\n * )\n * // → { name: \"Alice\", \"meetingId:1\": \"val1\", \"meetingId:2\": \"val2\" }\n * ```\n */\nfunction mergeDataWithIdentifiers(\n\tdata: Record<string, unknown>,\n\tidentifierData?: Record<number, Record<string, unknown>>,\n): Record<string, unknown> {\n\tif (!identifierData) return data;\n\n\tconst merged: Record<string, unknown> = { ...data };\n\n\tfor (const [id, idData] of Object.entries(identifierData)) {\n\t\tfor (const [key, value] of Object.entries(idData)) {\n\t\t\tmerged[`${key}:${id}`] = value;\n\t\t}\n\t}\n\n\treturn merged;\n}\n\n// ─── Handlebars Rendering ────────────────────────────────────────────────────\n// For complex templates (blocks, helpers), we delegate to Handlebars.\n// Compilation is cached to avoid costly recompilations.\n\n/**\n * Compiles and executes a template via Handlebars.\n *\n * Uses a compilation cache (LRU) to avoid recompiling the same template\n * on repeated calls. The cache is either:\n * - The global cache (for the standalone `execute()` function)\n * - The instance cache provided via `ExecutorContext` (for `Typebars`)\n *\n * @param template - The template string\n * @param data - The context data\n * @param ctx - Optional execution context (cache, Handlebars env)\n * @returns Always a string\n */\nfunction renderWithHandlebars(\n\ttemplate: string,\n\tdata: Record<string, unknown>,\n\tctx?: ExecutorContext,\n): string {\n\ttry {\n\t\t// 1. Use the pre-compiled template if available (CompiledTemplate)\n\t\tif (ctx?.compiledTemplate) {\n\t\t\treturn ctx.compiledTemplate(data);\n\t\t}\n\n\t\t// 2. Look up in the cache (instance or global)\n\t\tconst cache = ctx?.compilationCache ?? globalCompilationCache;\n\t\tconst hbs = ctx?.hbs ?? Handlebars;\n\n\t\tlet compiled = cache.get(template);\n\t\tif (!compiled) {\n\t\t\tcompiled = hbs.compile(template, {\n\t\t\t\t// Disable HTML-escaping by default — this engine is not\n\t\t\t\t// HTML-specific, we want raw values.\n\t\t\t\tnoEscape: true,\n\t\t\t\t// Strict mode: throws if a path does not exist in the data.\n\t\t\t\tstrict: false,\n\t\t\t});\n\t\t\tcache.set(template, compiled);\n\t\t}\n\n\t\treturn compiled(data);\n\t} catch (error: unknown) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tthrow new TemplateRuntimeError(message);\n\t}\n}\n\n/**\n * Clears the global Handlebars compilation cache.\n * Useful for tests or to free memory.\n */\nexport function clearCompilationCache(): void {\n\tglobalCompilationCache.clear();\n}\n"],"names":["Handlebars","TemplateRuntimeError","canUseFastPath","coerceLiteral","extractExpressionIdentifier","extractPathSegments","getEffectivelySingleBlock","getEffectivelySingleExpression","isSingleExpression","isThisExpression","parse","isLiteralInput","isObjectInput","LRUCache","globalCompilationCache","execute","template","data","identifierData","executeObjectTemplate","ast","executeFromAst","result","Object","entries","key","value","ctx","stmt","body","params","length","hash","resolveExpression","path","singleExpr","merged","mergeDataWithIdentifiers","raw","renderWithHandlebars","executeFastPath","singleBlock","type","String","expr","undefined","segments","cleanSegments","identifier","source","resolveDataPath","current","segment","id","idData","compiledTemplate","cache","compilationCache","hbs","compiled","get","compile","noEscape","strict","set","error","message","Error","clearCompilationCache","clear"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { HelperDefinition } from "../types.ts";
1
+ import type { HelperDefinition } from "../types";
2
2
  /** Minimal registration interface — avoids tight coupling with Typebars */
3
3
  export interface HelperRegistry {
4
4
  registerHelper(name: string, definition: HelperDefinition): unknown;
@@ -0,0 +1,2 @@
1
+ function _array_like_to_array(arr,len){if(len==null||len>arr.length)len=arr.length;for(var i=0,arr2=new Array(len);i<len;i++)arr2[i]=arr[i];return arr2}function _array_with_holes(arr){if(Array.isArray(arr))return arr}function _array_without_holes(arr){if(Array.isArray(arr))return _array_like_to_array(arr)}function _class_call_check(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}}function _defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor)}}function _create_class(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);return Constructor}function _define_property(obj,key,value){if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true})}else{obj[key]=value}return obj}function _iterable_to_array(iter){if(typeof Symbol!=="undefined"&&iter[Symbol.iterator]!=null||iter["@@iterator"]!=null)return Array.from(iter)}function _iterable_to_array_limit(arr,i){var _i=arr==null?null:typeof Symbol!=="undefined"&&arr[Symbol.iterator]||arr["@@iterator"];if(_i==null)return;var _arr=[];var _n=true;var _d=false;var _s,_e;try{for(_i=_i.call(arr);!(_n=(_s=_i.next()).done);_n=true){_arr.push(_s.value);if(i&&_arr.length===i)break}}catch(err){_d=true;_e=err}finally{try{if(!_n&&_i["return"]!=null)_i["return"]()}finally{if(_d)throw _e}}return _arr}function _non_iterable_rest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _non_iterable_spread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _sliced_to_array(arr,i){return _array_with_holes(arr)||_iterable_to_array_limit(arr,i)||_unsupported_iterable_to_array(arr,i)||_non_iterable_rest()}function _to_consumable_array(arr){return _array_without_holes(arr)||_iterable_to_array(arr)||_unsupported_iterable_to_array(arr)||_non_iterable_spread()}function _unsupported_iterable_to_array(o,minLen){if(!o)return;if(typeof o==="string")return _array_like_to_array(o,minLen);var n=Object.prototype.toString.call(o).slice(8,-1);if(n==="Object"&&o.constructor)n=o.constructor.name;if(n==="Map"||n==="Set")return Array.from(n);if(n==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return _array_like_to_array(o,minLen)}export var HelperFactory=/*#__PURE__*/function(){"use strict";function HelperFactory(){_class_call_check(this,HelperFactory);_define_property(this,"_definitions",null);_define_property(this,"_helperNames",null);_define_property(this,"_helperNamesSet",null)}_create_class(HelperFactory,[{key:"getDefinitions",value:function getDefinitions(){if(!this._definitions){this._definitions=new Map;this.buildDefinitions(this._definitions)}return this._definitions}},{key:"getHelperNames",value:function getHelperNames(){if(!this._helperNames){this._helperNames=_to_consumable_array(this.getDefinitions().keys())}return this._helperNames}},{key:"isHelper",value:function isHelper(name){if(!this._helperNamesSet){this._helperNamesSet=new Set(this.getHelperNames())}return this._helperNamesSet.has(name)}},{key:"register",value:function register(registry){var _iteratorNormalCompletion=true,_didIteratorError=false,_iteratorError=undefined;try{for(var _iterator=this.getDefinitions()[Symbol.iterator](),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var _step_value=_sliced_to_array(_step.value,2),name=_step_value[0],def=_step_value[1];registry.registerHelper(name,def)}}catch(err){_didIteratorError=true;_iteratorError=err}finally{try{if(!_iteratorNormalCompletion&&_iterator.return!=null){_iterator.return()}}finally{if(_didIteratorError){throw _iteratorError}}}}},{key:"unregister",value:function unregister(registry){var _iteratorNormalCompletion=true,_didIteratorError=false,_iteratorError=undefined;try{for(var _iterator=this.getHelperNames()[Symbol.iterator](),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var name=_step.value;registry.unregisterHelper(name)}}catch(err){_didIteratorError=true;_iteratorError=err}finally{try{if(!_iteratorNormalCompletion&&_iterator.return!=null){_iterator.return()}}finally{if(_didIteratorError){throw _iteratorError}}}}}]);return HelperFactory}();
2
+ //# sourceMappingURL=helper-factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/helpers/helper-factory.ts"],"sourcesContent":["import type { HelperDefinition } from \"../types\";\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"],"names":["HelperFactory","_definitions","_helperNames","_helperNamesSet","getDefinitions","Map","buildDefinitions","getHelperNames","keys","isHelper","name","Set","has","register","registry","def","registerHelper","unregister","unregisterHelper"],"mappings":"ssFAwBA,OAAO,IAAA,AAAeA,2BAAf,iCAAeA,uCAAAA,eAErB,sBAAQC,eAAqD,MAC7D,sBAAQC,eAAyC,MACjD,sBAAQC,kBAA8C,oBAJjCH,gBAmCrBI,IAAAA,uBAAAA,SAAAA,iBACC,GAAI,CAAC,IAAI,CAACH,YAAY,CAAE,CACvB,IAAI,CAACA,YAAY,CAAG,IAAII,IACxB,IAAI,CAACC,gBAAgB,CAAC,IAAI,CAACL,YAAY,CACxC,CACA,OAAO,IAAI,CAACA,YAAY,AACzB,IAKAM,IAAAA,uBAAAA,SAAAA,iBACC,GAAI,CAAC,IAAI,CAACL,YAAY,CAAE,CACvB,IAAI,CAACA,YAAY,CAAI,qBAAG,IAAI,CAACE,cAAc,GAAGI,IAAI,GACnD,CACA,OAAO,IAAI,CAACN,YAAY,AACzB,IAOAO,IAAAA,iBAAAA,SAAAA,SAASC,IAAY,EACpB,GAAI,CAAC,IAAI,CAACP,eAAe,CAAE,CAC1B,IAAI,CAACA,eAAe,CAAG,IAAIQ,IAAI,IAAI,CAACJ,cAAc,GACnD,CACA,OAAO,IAAI,CAACJ,eAAe,CAACS,GAAG,CAACF,KACjC,IAOAG,IAAAA,iBAAAA,SAAAA,SAASC,QAAwB,MAC3B,+BAAA,wBAAA,6BAAL,QAAK,UAAqB,IAAI,CAACV,cAAc,sBAAxC,QAAA,2BAAA,MAAA,wBAAA,+BAA4C,CAA5C,iCAAA,eAAOM,oBAAMK,mBACjBD,SAASE,cAAc,CAACN,KAAMK,IAC/B,aAFK,uBAAA,mCAAA,2BAAA,wBAAA,+BAAA,yBAAA,iBAGN,IAOAE,IAAAA,mBAAAA,SAAAA,WAAWH,QAAwB,MAC7B,+BAAA,wBAAA,6BAAL,QAAK,UAAc,IAAI,CAACP,cAAc,sBAAjC,QAAA,2BAAA,MAAA,wBAAA,+BAAqC,CAArC,IAAMG,KAAN,YACJI,SAASI,gBAAgB,CAACR,KAC3B,aAFK,uBAAA,mCAAA,2BAAA,wBAAA,+BAAA,yBAAA,iBAGN,YArFqBV,gBAsFrB"}
@@ -1,4 +1,4 @@
1
- export { HelperFactory, type HelperRegistry } from "./helper-factory.ts";
2
- export { LogicalHelpers } from "./logical-helpers.ts";
3
- export { MathHelpers } from "./math-helpers.ts";
4
- export { toNumber } from "./utils.ts";
1
+ export { HelperFactory, type HelperRegistry } from "./helper-factory";
2
+ export { LogicalHelpers } from "./logical-helpers";
3
+ export { MathHelpers } from "./math-helpers";
4
+ export { toNumber } from "./utils";
@@ -0,0 +1,2 @@
1
+ export{HelperFactory}from"./helper-factory";export{LogicalHelpers}from"./logical-helpers";export{MathHelpers}from"./math-helpers";export{toNumber}from"./utils";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/helpers/index.ts"],"sourcesContent":["export { HelperFactory, type HelperRegistry } from \"./helper-factory\";\nexport { LogicalHelpers } from \"./logical-helpers\";\nexport { MathHelpers } from \"./math-helpers\";\nexport { toNumber } from \"./utils\";\n"],"names":["HelperFactory","LogicalHelpers","MathHelpers","toNumber"],"mappings":"AAAA,OAASA,aAAa,KAA6B,kBAAmB,AACtE,QAASC,cAAc,KAAQ,mBAAoB,AACnD,QAASC,WAAW,KAAQ,gBAAiB,AAC7C,QAASC,QAAQ,KAAQ,SAAU"}
@@ -1,5 +1,5 @@
1
- import type { HelperDefinition } from "../types.ts";
2
- import { HelperFactory } from "./helper-factory.ts";
1
+ import type { HelperDefinition } from "../types";
2
+ import { HelperFactory } from "./helper-factory";
3
3
  export declare class LogicalHelpers extends HelperFactory {
4
4
  protected buildDefinitions(defs: Map<string, HelperDefinition>): void;
5
5
  /** Registers eq, ne / neq */
@@ -0,0 +1,2 @@
1
+ function _array_like_to_array(arr,len){if(len==null||len>arr.length)len=arr.length;for(var i=0,arr2=new Array(len);i<len;i++)arr2[i]=arr[i];return arr2}function _array_without_holes(arr){if(Array.isArray(arr))return _array_like_to_array(arr)}function _assert_this_initialized(self){if(self===void 0){throw new ReferenceError("this hasn't been initialised - super() hasn't been called")}return self}function _call_super(_this,derived,args){derived=_get_prototype_of(derived);return _possible_constructor_return(_this,_is_native_reflect_construct()?Reflect.construct(derived,args||[],_get_prototype_of(_this).constructor):derived.apply(_this,args))}function _class_call_check(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}}function _defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor)}}function _create_class(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);return Constructor}function _get_prototype_of(o){_get_prototype_of=Object.setPrototypeOf?Object.getPrototypeOf:function getPrototypeOf(o){return o.__proto__||Object.getPrototypeOf(o)};return _get_prototype_of(o)}function _inherits(subClass,superClass){if(typeof superClass!=="function"&&superClass!==null){throw new TypeError("Super expression must either be null or a function")}subClass.prototype=Object.create(superClass&&superClass.prototype,{constructor:{value:subClass,writable:true,configurable:true}});if(superClass)_set_prototype_of(subClass,superClass)}function _iterable_to_array(iter){if(typeof Symbol!=="undefined"&&iter[Symbol.iterator]!=null||iter["@@iterator"]!=null)return Array.from(iter)}function _non_iterable_spread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _possible_constructor_return(self,call){if(call&&(_type_of(call)==="object"||typeof call==="function")){return call}return _assert_this_initialized(self)}function _set_prototype_of(o,p){_set_prototype_of=Object.setPrototypeOf||function setPrototypeOf(o,p){o.__proto__=p;return o};return _set_prototype_of(o,p)}function _to_consumable_array(arr){return _array_without_holes(arr)||_iterable_to_array(arr)||_unsupported_iterable_to_array(arr)||_non_iterable_spread()}function _type_of(obj){"@swc/helpers - typeof";return obj&&typeof Symbol!=="undefined"&&obj.constructor===Symbol?"symbol":typeof obj}function _unsupported_iterable_to_array(o,minLen){if(!o)return;if(typeof o==="string")return _array_like_to_array(o,minLen);var n=Object.prototype.toString.call(o).slice(8,-1);if(n==="Object"&&o.constructor)n=o.constructor.name;if(n==="Map"||n==="Set")return Array.from(n);if(n==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return _array_like_to_array(o,minLen)}function _is_native_reflect_construct(){try{var result=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch(_){}return(_is_native_reflect_construct=function(){return!!result})()}import{HelperFactory}from"./helper-factory";import{toNumber}from"./utils";var SUPPORTED_OPERATORS=new Set(["==","===","!=","!==","<","<=",">",">="]);function applyOperator(a,op,b){switch(op){case"==":return a==b;case"===":return a===b;case"!=":return a!=b;case"!==":return a!==b;case"<":return toNumber(a)<toNumber(b);case"<=":return toNumber(a)<=toNumber(b);case">":return toNumber(a)>toNumber(b);case">=":return toNumber(a)>=toNumber(b)}}function isHandlebarsOptions(value){return value!==null&&(typeof value==="undefined"?"undefined":_type_of(value))==="object"&&"hash"in value&&"name"in value}export var LogicalHelpers=/*#__PURE__*/function(HelperFactory){"use strict";_inherits(LogicalHelpers,HelperFactory);function LogicalHelpers(){_class_call_check(this,LogicalHelpers);return _call_super(this,LogicalHelpers,arguments)}_create_class(LogicalHelpers,[{key:"buildDefinitions",value:function buildDefinitions(defs){this.registerEquality(defs);this.registerComparison(defs);this.registerLogicalOperators(defs);this.registerCollectionHelpers(defs);this.registerGenericCompare(defs)}},{key:"registerEquality",value:function registerEquality(defs){defs.set("eq",{fn:function fn(a,b){return a===b},params:[{name:"a",description:"Left value"},{name:"b",description:"Right value"}],returnType:{type:"boolean"},description:"Returns true if a is strictly equal to b: {{#if (eq a b)}}"});var neDef={fn:function fn(a,b){return a!==b},params:[{name:"a",description:"Left value"},{name:"b",description:"Right value"}],returnType:{type:"boolean"},description:"Returns true if a is not strictly equal to b: {{#if (ne a b)}}"};defs.set("ne",neDef);defs.set("neq",neDef)}},{key:"registerComparison",value:function registerComparison(defs){defs.set("lt",{fn:function fn(a,b){return toNumber(a)<toNumber(b)},params:[{name:"a",type:{type:"number"},description:"Left operand"},{name:"b",type:{type:"number"},description:"Right operand"}],returnType:{type:"boolean"},description:"Returns true if a < b: {{#if (lt a b)}}"});var lteDef={fn:function fn(a,b){return toNumber(a)<=toNumber(b)},params:[{name:"a",type:{type:"number"},description:"Left operand"},{name:"b",type:{type:"number"},description:"Right operand"}],returnType:{type:"boolean"},description:"Returns true if a <= b: {{#if (lte a b)}}"};defs.set("lte",lteDef);defs.set("le",lteDef);defs.set("gt",{fn:function fn(a,b){return toNumber(a)>toNumber(b)},params:[{name:"a",type:{type:"number"},description:"Left operand"},{name:"b",type:{type:"number"},description:"Right operand"}],returnType:{type:"boolean"},description:"Returns true if a > b: {{#if (gt a b)}}"});var gteDef={fn:function fn(a,b){return toNumber(a)>=toNumber(b)},params:[{name:"a",type:{type:"number"},description:"Left operand"},{name:"b",type:{type:"number"},description:"Right operand"}],returnType:{type:"boolean"},description:"Returns true if a >= b: {{#if (gte a b)}}"};defs.set("gte",gteDef);defs.set("ge",gteDef)}},{key:"registerLogicalOperators",value:function registerLogicalOperators(defs){defs.set("not",{fn:function fn(value){return!value},params:[{name:"value",description:"Value to negate"}],returnType:{type:"boolean"},description:"Returns true if the value is falsy: {{#if (not active)}}"});defs.set("and",{fn:function fn(a,b){return!!a&&!!b},params:[{name:"a",description:"First condition"},{name:"b",description:"Second condition"}],returnType:{type:"boolean"},description:"Returns true if both values are truthy: {{#if (and a b)}}"});defs.set("or",{fn:function fn(a,b){return!!a||!!b},params:[{name:"a",description:"First condition"},{name:"b",description:"Second condition"}],returnType:{type:"boolean"},description:"Returns true if at least one value is truthy: {{#if (or a b)}}"})}},{key:"registerCollectionHelpers",value:function registerCollectionHelpers(defs){defs.set("contains",{fn:function fn(haystack,needle){if(typeof haystack==="string"){return haystack.includes(String(needle))}if(Array.isArray(haystack)){return haystack.includes(needle)}return false},params:[{name:"haystack",description:"String or array to search in"},{name:"needle",description:"Value to search for"}],returnType:{type:"boolean"},description:'Checks if a string contains a substring or an array contains an element: {{#if (contains name "ali")}}'});defs.set("in",{fn:function fn(){for(var _len=arguments.length,args=new Array(_len),_key=0;_key<_len;_key++){args[_key]=arguments[_key]}if(args.length<2)return false;var value=args[0];var candidates=args.slice(1).filter(function(a){return!isHandlebarsOptions(a)});return candidates.some(function(c){return c===value})},params:[{name:"value",description:"Value to look for"},{name:"candidates",description:'One or more candidate values (variadic): {{#if (in status "active" "pending")}}'}],returnType:{type:"boolean"},description:'Checks if a value is one of the provided options: {{#if (in status "active" "pending" "draft")}}'})}},{key:"registerGenericCompare",value:function registerGenericCompare(defs){defs.set("compare",{fn:function fn(a,operator,b){var op=String(operator);if(!SUPPORTED_OPERATORS.has(op)){throw new Error('[compare helper] Unknown operator "'.concat(op,'". ')+"Supported: ".concat(_to_consumable_array(SUPPORTED_OPERATORS).join(", ")," "))}return applyOperator(a,op,b)},params:[{name:"a",description:"Left operand"},{name:"operator",type:{type:"string",enum:["==","===","!=","!==","<","<=",">",">="]},description:'Comparison operator: "==", "===", "!=", "!==", "<", "<=", ">", ">="'},{name:"b",description:"Right operand"}],returnType:{type:"boolean"},description:'Generic comparison helper with operator as parameter: {{#if (compare a "<" b)}}. '+"Supported operators: ==, ===, !=, !==, <, <=, >, >="})}}]);return LogicalHelpers}(HelperFactory);
2
+ //# sourceMappingURL=logical-helpers.js.map