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.
- package/dist/analyzer.d.ts +1 -1
- package/dist/analyzer.js +2 -4
- package/dist/analyzer.js.map +1 -9
- package/dist/compiled-template.d.ts +2 -2
- package/dist/compiled-template.js +2 -4
- package/dist/compiled-template.js.map +1 -9
- package/dist/errors.d.ts +1 -1
- package/dist/errors.js +2 -4
- package/dist/errors.js.map +1 -9
- package/dist/executor.d.ts +2 -2
- package/dist/executor.js +2 -4
- package/dist/executor.js.map +1 -9
- package/dist/helpers/helper-factory.d.ts +1 -1
- package/dist/helpers/helper-factory.js +2 -0
- package/dist/helpers/helper-factory.js.map +1 -0
- package/dist/helpers/index.d.ts +4 -4
- package/dist/helpers/index.js +2 -0
- package/dist/helpers/index.js.map +1 -0
- package/dist/helpers/logical-helpers.d.ts +2 -2
- package/dist/helpers/logical-helpers.js +2 -0
- package/dist/helpers/logical-helpers.js.map +1 -0
- package/dist/helpers/math-helpers.d.ts +2 -2
- package/dist/helpers/math-helpers.js +2 -0
- package/dist/helpers/math-helpers.js.map +1 -0
- package/dist/helpers/utils.js +2 -0
- package/dist/helpers/utils.js.map +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -4
- package/dist/index.js.map +1 -9
- package/dist/parser.js +2 -4
- package/dist/parser.js.map +1 -9
- package/dist/schema-resolver.js +2 -4
- package/dist/schema-resolver.js.map +1 -9
- package/dist/typebars.d.ts +2 -2
- package/dist/typebars.js +2 -4
- package/dist/typebars.js.map +1 -9
- package/dist/types.js +2 -4
- package/dist/types.js.map +1 -9
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +2 -4
- package/dist/utils.js.map +1 -9
- package/package.json +7 -5
- package/dist/chunk-6955jpr7.js +0 -5
- package/dist/chunk-6955jpr7.js.map +0 -10
- package/dist/chunk-ecs3yth2.js +0 -5
- package/dist/chunk-ecs3yth2.js.map +0 -10
- package/dist/chunk-efqd0598.js +0 -5
- package/dist/chunk-efqd0598.js.map +0 -10
- package/dist/chunk-jms1ndxn.js +0 -5
- package/dist/chunk-jms1ndxn.js.map +0 -10
- package/dist/chunk-p5efqsxw.js +0 -7
- package/dist/chunk-p5efqsxw.js.map +0 -10
- package/dist/chunk-rkrp4ysw.js +0 -5
- package/dist/chunk-rkrp4ysw.js.map +0 -10
- package/dist/chunk-t6n956qz.js +0 -4
- package/dist/chunk-t6n956qz.js.map +0 -10
- package/dist/chunk-xd2vmd03.js +0 -5
- package/dist/chunk-xd2vmd03.js.map +0 -14
- package/dist/chunk-zh1e0yhd.js +0 -7
- package/dist/chunk-zh1e0yhd.js.map +0 -10
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/helpers/logical-helpers.ts"],"sourcesContent":["import type { HelperDefinition } from \"../types\";\nimport { HelperFactory } from \"./helper-factory\";\nimport { toNumber } from \"./utils\";\n\n// ─── LogicalHelpers ──────────────────────────────────────────────────────────\n// Aggregates all logical / comparison helpers for the template engine.\n//\n// Provides two kinds of helpers:\n//\n// 1. **Named helpers** — one helper per operation (`eq`, `lt`, `not`, …)\n// Usage: `{{#if (eq status \"active\")}}`, `{{#if (lt price 100)}}`\n//\n// 2. **Generic `compare` helper** — single helper with the operator as a param\n// Usage: `{{#if (compare a \"<\" b)}}`, `{{#if (compare name \"==\" \"Alice\")}}`\n//\n// ─── Registration ────────────────────────────────────────────────────────────\n// LogicalHelpers are automatically pre-registered by the `Typebars` constructor.\n// They can also be registered manually on any object implementing\n// `HelperRegistry`:\n//\n// const factory = new LogicalHelpers();\n// factory.register(engine); // registers all helpers\n// factory.unregister(engine); // removes all helpers\n//\n// ─── Supported operators (generic `compare` helper) ──────────────────────────\n// == Loose equality\n// === Strict equality\n// != Loose inequality\n// !== Strict inequality\n// < Less than\n// <= Less than or equal\n// > Greater than\n// >= Greater than or equal\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n/** Operators supported by the generic `compare` helper */\ntype CompareOperator = \"==\" | \"===\" | \"!=\" | \"!==\" | \"<\" | \"<=\" | \">\" | \">=\";\n\nconst SUPPORTED_OPERATORS = new Set<string>([\n\t\"==\",\n\t\"===\",\n\t\"!=\",\n\t\"!==\",\n\t\"<\",\n\t\"<=\",\n\t\">\",\n\t\">=\",\n]);\n\n// ─── Internal utilities ─────────────────────────────────────────────────────\n\n/**\n * Applies a comparison operator to two operands.\n */\nfunction applyOperator(a: unknown, op: CompareOperator, b: unknown): boolean {\n\tswitch (op) {\n\t\tcase \"==\":\n\t\t\t// biome-ignore lint/suspicious/noDoubleEquals: intentional loose equality\n\t\t\treturn a == b;\n\t\tcase \"===\":\n\t\t\treturn a === b;\n\t\tcase \"!=\":\n\t\t\t// biome-ignore lint/suspicious/noDoubleEquals: intentional loose inequality\n\t\t\treturn a != b;\n\t\tcase \"!==\":\n\t\t\treturn a !== b;\n\t\tcase \"<\":\n\t\t\treturn toNumber(a) < toNumber(b);\n\t\tcase \"<=\":\n\t\t\treturn toNumber(a) <= toNumber(b);\n\t\tcase \">\":\n\t\t\treturn toNumber(a) > toNumber(b);\n\t\tcase \">=\":\n\t\t\treturn toNumber(a) >= toNumber(b);\n\t}\n}\n\n/**\n * Checks whether a value is a Handlebars options object.\n * Handlebars always passes an options object as the last argument to helpers.\n */\nfunction isHandlebarsOptions(value: unknown): boolean {\n\treturn (\n\t\tvalue !== null &&\n\t\ttypeof value === \"object\" &&\n\t\t\"hash\" in (value as Record<string, unknown>) &&\n\t\t\"name\" in (value as Record<string, unknown>)\n\t);\n}\n\n// ─── Main class ─────────────────────────────────────────────────────────────\n\nexport class LogicalHelpers extends HelperFactory {\n\t// ─── buildDefinitions (required by HelperFactory) ──────────────────\n\n\tprotected buildDefinitions(defs: Map<string, HelperDefinition>): void {\n\t\tthis.registerEquality(defs);\n\t\tthis.registerComparison(defs);\n\t\tthis.registerLogicalOperators(defs);\n\t\tthis.registerCollectionHelpers(defs);\n\t\tthis.registerGenericCompare(defs);\n\t}\n\n\t// ── Equality helpers ─────────────────────────────────────────────\n\n\t/** Registers eq, ne / neq */\n\tprivate registerEquality(defs: Map<string, HelperDefinition>): void {\n\t\t// eq — Strict equality: {{#if (eq a b)}}\n\t\tdefs.set(\"eq\", {\n\t\t\tfn: (a: unknown, b: unknown) => a === b,\n\t\t\tparams: [\n\t\t\t\t{ name: \"a\", description: \"Left value\" },\n\t\t\t\t{ name: \"b\", description: \"Right value\" },\n\t\t\t],\n\t\t\treturnType: { type: \"boolean\" },\n\t\t\tdescription: \"Returns true if a is strictly equal to b: {{#if (eq a b)}}\",\n\t\t});\n\n\t\t// ne / neq — Strict inequality: {{#if (ne a b)}}\n\t\tconst neDef: HelperDefinition = {\n\t\t\tfn: (a: unknown, b: unknown) => a !== b,\n\t\t\tparams: [\n\t\t\t\t{ name: \"a\", description: \"Left value\" },\n\t\t\t\t{ name: \"b\", description: \"Right value\" },\n\t\t\t],\n\t\t\treturnType: { type: \"boolean\" },\n\t\t\tdescription:\n\t\t\t\t\"Returns true if a is not strictly equal to b: {{#if (ne a b)}}\",\n\t\t};\n\t\tdefs.set(\"ne\", neDef);\n\t\tdefs.set(\"neq\", neDef);\n\t}\n\n\t// ── Comparison helpers ───────────────────────────────────────────\n\n\t/** Registers lt, lte / le, gt, gte / ge */\n\tprivate registerComparison(defs: Map<string, HelperDefinition>): void {\n\t\t// lt — Less than: {{#if (lt a b)}}\n\t\tdefs.set(\"lt\", {\n\t\t\tfn: (a: unknown, b: unknown) => toNumber(a) < toNumber(b),\n\t\t\tparams: [\n\t\t\t\t{ name: \"a\", type: { type: \"number\" }, description: \"Left operand\" },\n\t\t\t\t{ name: \"b\", type: { type: \"number\" }, description: \"Right operand\" },\n\t\t\t],\n\t\t\treturnType: { type: \"boolean\" },\n\t\t\tdescription: \"Returns true if a < b: {{#if (lt a b)}}\",\n\t\t});\n\n\t\t// lte / le — Less than or equal: {{#if (lte a b)}}\n\t\tconst lteDef: HelperDefinition = {\n\t\t\tfn: (a: unknown, b: unknown) => toNumber(a) <= toNumber(b),\n\t\t\tparams: [\n\t\t\t\t{ name: \"a\", type: { type: \"number\" }, description: \"Left operand\" },\n\t\t\t\t{ name: \"b\", type: { type: \"number\" }, description: \"Right operand\" },\n\t\t\t],\n\t\t\treturnType: { type: \"boolean\" },\n\t\t\tdescription: \"Returns true if a <= b: {{#if (lte a b)}}\",\n\t\t};\n\t\tdefs.set(\"lte\", lteDef);\n\t\tdefs.set(\"le\", lteDef);\n\n\t\t// gt — Greater than: {{#if (gt a b)}}\n\t\tdefs.set(\"gt\", {\n\t\t\tfn: (a: unknown, b: unknown) => toNumber(a) > toNumber(b),\n\t\t\tparams: [\n\t\t\t\t{ name: \"a\", type: { type: \"number\" }, description: \"Left operand\" },\n\t\t\t\t{ name: \"b\", type: { type: \"number\" }, description: \"Right operand\" },\n\t\t\t],\n\t\t\treturnType: { type: \"boolean\" },\n\t\t\tdescription: \"Returns true if a > b: {{#if (gt a b)}}\",\n\t\t});\n\n\t\t// gte / ge — Greater than or equal: {{#if (gte a b)}}\n\t\tconst gteDef: HelperDefinition = {\n\t\t\tfn: (a: unknown, b: unknown) => toNumber(a) >= toNumber(b),\n\t\t\tparams: [\n\t\t\t\t{ name: \"a\", type: { type: \"number\" }, description: \"Left operand\" },\n\t\t\t\t{ name: \"b\", type: { type: \"number\" }, description: \"Right operand\" },\n\t\t\t],\n\t\t\treturnType: { type: \"boolean\" },\n\t\t\tdescription: \"Returns true if a >= b: {{#if (gte a b)}}\",\n\t\t};\n\t\tdefs.set(\"gte\", gteDef);\n\t\tdefs.set(\"ge\", gteDef);\n\t}\n\n\t// ── Logical operators ────────────────────────────────────────────\n\n\t/** Registers not, and, or */\n\tprivate registerLogicalOperators(defs: Map<string, HelperDefinition>): void {\n\t\t// not — Logical negation: {{#if (not active)}}\n\t\tdefs.set(\"not\", {\n\t\t\tfn: (value: unknown) => !value,\n\t\t\tparams: [{ name: \"value\", description: \"Value to negate\" }],\n\t\t\treturnType: { type: \"boolean\" },\n\t\t\tdescription: \"Returns true if the value is falsy: {{#if (not active)}}\",\n\t\t});\n\n\t\t// and — Logical AND: {{#if (and a b)}}\n\t\tdefs.set(\"and\", {\n\t\t\tfn: (a: unknown, b: unknown) => !!a && !!b,\n\t\t\tparams: [\n\t\t\t\t{ name: \"a\", description: \"First condition\" },\n\t\t\t\t{ name: \"b\", description: \"Second condition\" },\n\t\t\t],\n\t\t\treturnType: { type: \"boolean\" },\n\t\t\tdescription: \"Returns true if both values are truthy: {{#if (and a b)}}\",\n\t\t});\n\n\t\t// or — Logical OR: {{#if (or a b)}}\n\t\tdefs.set(\"or\", {\n\t\t\tfn: (a: unknown, b: unknown) => !!a || !!b,\n\t\t\tparams: [\n\t\t\t\t{ name: \"a\", description: \"First condition\" },\n\t\t\t\t{ name: \"b\", description: \"Second condition\" },\n\t\t\t],\n\t\t\treturnType: { type: \"boolean\" },\n\t\t\tdescription:\n\t\t\t\t\"Returns true if at least one value is truthy: {{#if (or a b)}}\",\n\t\t});\n\t}\n\n\t// ── Collection / String helpers ──────────────────────────────────\n\n\t/** Registers contains, in */\n\tprivate registerCollectionHelpers(defs: Map<string, HelperDefinition>): void {\n\t\t// contains — Checks if a string contains a substring or an array contains an element\n\t\t// Usage: {{#if (contains name \"ali\")}} or {{#if (contains tags \"admin\")}}\n\t\tdefs.set(\"contains\", {\n\t\t\tfn: (haystack: unknown, needle: unknown) => {\n\t\t\t\tif (typeof haystack === \"string\") {\n\t\t\t\t\treturn haystack.includes(String(needle));\n\t\t\t\t}\n\t\t\t\tif (Array.isArray(haystack)) {\n\t\t\t\t\treturn haystack.includes(needle);\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\tparams: [\n\t\t\t\t{\n\t\t\t\t\tname: \"haystack\",\n\t\t\t\t\tdescription: \"String or array to search in\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: \"needle\",\n\t\t\t\t\tdescription: \"Value to search for\",\n\t\t\t\t},\n\t\t\t],\n\t\t\treturnType: { type: \"boolean\" },\n\t\t\tdescription:\n\t\t\t\t'Checks if a string contains a substring or an array contains an element: {{#if (contains name \"ali\")}}',\n\t\t});\n\n\t\t// in — Checks if a value is one of the provided options (variadic)\n\t\t// Usage: {{#if (in status \"active\" \"pending\" \"draft\")}}\n\t\tdefs.set(\"in\", {\n\t\t\tfn: (...args: unknown[]) => {\n\t\t\t\t// Handlebars always passes an options object as the last argument.\n\t\t\t\t// We need to exclude it from the candidate list.\n\t\t\t\tif (args.length < 2) return false;\n\n\t\t\t\tconst value = args[0];\n\t\t\t\t// Filter out the trailing Handlebars options object\n\t\t\t\tconst candidates = args.slice(1).filter((a) => !isHandlebarsOptions(a));\n\n\t\t\t\treturn candidates.some((c) => c === value);\n\t\t\t},\n\t\t\tparams: [\n\t\t\t\t{\n\t\t\t\t\tname: \"value\",\n\t\t\t\t\tdescription: \"Value to look for\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: \"candidates\",\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t'One or more candidate values (variadic): {{#if (in status \"active\" \"pending\")}}',\n\t\t\t\t},\n\t\t\t],\n\t\t\treturnType: { type: \"boolean\" },\n\t\t\tdescription:\n\t\t\t\t'Checks if a value is one of the provided options: {{#if (in status \"active\" \"pending\" \"draft\")}}',\n\t\t});\n\t}\n\n\t// ── Generic helper ───────────────────────────────────────────────\n\n\t/** Registers the generic `compare` helper with operator as a parameter */\n\tprivate registerGenericCompare(defs: Map<string, HelperDefinition>): void {\n\t\t// Usage: {{#if (compare a \"<\" b)}}, {{#if (compare name \"===\" \"Alice\")}}\n\t\tdefs.set(\"compare\", {\n\t\t\tfn: (a: unknown, operator: unknown, b: unknown) => {\n\t\t\t\tconst op = String(operator);\n\t\t\t\tif (!SUPPORTED_OPERATORS.has(op)) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`[compare helper] Unknown operator \"${op}\". ` +\n\t\t\t\t\t\t\t`Supported: ${[...SUPPORTED_OPERATORS].join(\", \")} `,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn applyOperator(a, op as CompareOperator, b);\n\t\t\t},\n\t\t\tparams: [\n\t\t\t\t{ name: \"a\", description: \"Left operand\" },\n\t\t\t\t{\n\t\t\t\t\tname: \"operator\",\n\t\t\t\t\ttype: {\n\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\tenum: [\"==\", \"===\", \"!=\", \"!==\", \"<\", \"<=\", \">\", \">=\"],\n\t\t\t\t\t},\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t'Comparison operator: \"==\", \"===\", \"!=\", \"!==\", \"<\", \"<=\", \">\", \">=\"',\n\t\t\t\t},\n\t\t\t\t{ name: \"b\", description: \"Right operand\" },\n\t\t\t],\n\t\t\treturnType: { type: \"boolean\" },\n\t\t\tdescription:\n\t\t\t\t'Generic comparison helper with operator as parameter: {{#if (compare a \"<\" b)}}. ' +\n\t\t\t\t\"Supported operators: ==, ===, !=, !==, <, <=, >, >=\",\n\t\t});\n\t}\n}\n"],"names":["HelperFactory","toNumber","SUPPORTED_OPERATORS","Set","applyOperator","a","op","b","isHandlebarsOptions","value","LogicalHelpers","buildDefinitions","defs","registerEquality","registerComparison","registerLogicalOperators","registerCollectionHelpers","registerGenericCompare","set","fn","params","name","description","returnType","type","neDef","lteDef","gteDef","haystack","needle","includes","String","Array","isArray","args","length","candidates","slice","filter","some","c","operator","has","Error","join","enum"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { HelperDefinition } from "../types
|
|
2
|
-
import { HelperFactory } from "./helper-factory
|
|
1
|
+
import type { HelperDefinition } from "../types";
|
|
2
|
+
import { HelperFactory } from "./helper-factory";
|
|
3
3
|
export declare class MathHelpers extends HelperFactory {
|
|
4
4
|
protected buildDefinitions(defs: Map<string, HelperDefinition>): void;
|
|
5
5
|
/** Registers add, subtract/sub, multiply/mul, divide/div, modulo/mod, pow */
|
|
@@ -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(["+","-","*","/","%","**"]);var num=function num(value){return toNumber(value,0)};function applyOperator(a,op,b){switch(op){case"+":return a+b;case"-":return a-b;case"*":return a*b;case"/":return b===0?Infinity:a/b;case"%":return b===0?NaN:a%b;case"**":return Math.pow(a,b)}}export var MathHelpers=/*#__PURE__*/function(HelperFactory){"use strict";_inherits(MathHelpers,HelperFactory);function MathHelpers(){_class_call_check(this,MathHelpers);return _call_super(this,MathHelpers,arguments)}_create_class(MathHelpers,[{key:"buildDefinitions",value:function buildDefinitions(defs){this.registerBinaryOperators(defs);this.registerUnaryFunctions(defs);this.registerMinMax(defs);this.registerGenericMath(defs)}},{key:"registerBinaryOperators",value:function registerBinaryOperators(defs){var addDef={fn:function fn(a,b){return num(a)+num(b)},params:[{name:"a",type:{type:"number"},description:"First operand"},{name:"b",type:{type:"number"},description:"Second operand"}],returnType:{type:"number"},description:"Adds two numbers: {{ add a b }}"};defs.set("add",addDef);var subtractDef={fn:function fn(a,b){return num(a)-num(b)},params:[{name:"a",type:{type:"number"},description:"Value to subtract from"},{name:"b",type:{type:"number"},description:"Value to subtract"}],returnType:{type:"number"},description:"Subtracts b from a: {{ subtract a b }}"};defs.set("subtract",subtractDef);defs.set("sub",subtractDef);var multiplyDef={fn:function fn(a,b){return num(a)*num(b)},params:[{name:"a",type:{type:"number"},description:"First factor"},{name:"b",type:{type:"number"},description:"Second factor"}],returnType:{type:"number"},description:"Multiplies two numbers: {{ multiply a b }}"};defs.set("multiply",multiplyDef);defs.set("mul",multiplyDef);var divideDef={fn:function fn(a,b){var divisor=num(b);return divisor===0?Infinity:num(a)/divisor},params:[{name:"a",type:{type:"number"},description:"Dividend"},{name:"b",type:{type:"number"},description:"Divisor"}],returnType:{type:"number"},description:"Divides a by b: {{ divide a b }}. Returns Infinity if b is 0."};defs.set("divide",divideDef);defs.set("div",divideDef);var moduloDef={fn:function fn(a,b){var divisor=num(b);return divisor===0?NaN:num(a)%divisor},params:[{name:"a",type:{type:"number"},description:"Dividend"},{name:"b",type:{type:"number"},description:"Divisor"}],returnType:{type:"number"},description:"Returns the remainder of a divided by b: {{ modulo a b }}"};defs.set("modulo",moduloDef);defs.set("mod",moduloDef);defs.set("pow",{fn:function fn(base,exponent){return Math.pow(num(base),num(exponent))},params:[{name:"base",type:{type:"number"},description:"The base"},{name:"exponent",type:{type:"number"},description:"The exponent"}],returnType:{type:"number"},description:"Raises base to the power of exponent: {{ pow base exponent }}"})}},{key:"registerUnaryFunctions",value:function registerUnaryFunctions(defs){defs.set("abs",{fn:function fn(value){return Math.abs(num(value))},params:[{name:"value",type:{type:"number"},description:"The number"}],returnType:{type:"number"},description:"Returns the absolute value: {{ abs value }}"});defs.set("ceil",{fn:function fn(value){return Math.ceil(num(value))},params:[{name:"value",type:{type:"number"},description:"The number to round up"}],returnType:{type:"number"},description:"Rounds up to the nearest integer: {{ ceil value }}"});defs.set("floor",{fn:function fn(value){return Math.floor(num(value))},params:[{name:"value",type:{type:"number"},description:"The number to round down"}],returnType:{type:"number"},description:"Rounds down to the nearest integer: {{ floor value }}"});defs.set("round",{fn:function fn(value,precision){var n=num(value);if(precision===undefined||precision===null||(typeof precision==="undefined"?"undefined":_type_of(precision))==="object"){return Math.round(n)}var p=num(precision);var factor=Math.pow(10,p);return Math.round(n*factor)/factor},params:[{name:"value",type:{type:"number"},description:"The number to round"},{name:"precision",type:{type:"number"},description:"Number of decimal places (default: 0)",optional:true}],returnType:{type:"number"},description:"Rounds to the nearest integer or to a given precision: {{ round value }} or {{ round value 2 }}"});defs.set("sqrt",{fn:function fn(value){return Math.sqrt(num(value))},params:[{name:"value",type:{type:"number"},description:"The number"}],returnType:{type:"number"},description:"Returns the square root: {{ sqrt value }}"})}},{key:"registerMinMax",value:function registerMinMax(defs){defs.set("min",{fn:function fn(a,b){return Math.min(num(a),num(b))},params:[{name:"a",type:{type:"number"},description:"First number"},{name:"b",type:{type:"number"},description:"Second number"}],returnType:{type:"number"},description:"Returns the smaller of two numbers: {{ min a b }}"});defs.set("max",{fn:function fn(a,b){return Math.max(num(a),num(b))},params:[{name:"a",type:{type:"number"},description:"First number"},{name:"b",type:{type:"number"},description:"Second number"}],returnType:{type:"number"},description:"Returns the larger of two numbers: {{ max a b }}"})}},{key:"registerGenericMath",value:function registerGenericMath(defs){defs.set("math",{fn:function fn(a,operator,b){var op=String(operator);if(!SUPPORTED_OPERATORS.has(op)){throw new Error('[math helper] Unknown operator "'.concat(op,'". ')+"Supported: ".concat(_to_consumable_array(SUPPORTED_OPERATORS).join(", ")," "))}return applyOperator(num(a),op,num(b))},params:[{name:"a",type:{type:"number"},description:"Left operand"},{name:"operator",type:{type:"string",enum:["+","-","*","/","%","**"]},description:'Arithmetic operator: "+", "-", "*", "/", "%", "**"'},{name:"b",type:{type:"number"},description:"Right operand"}],returnType:{type:"number"},description:'Generic math helper with operator as parameter: {{ math a "+" b }}, {{ math a "/" b }}. '+"Supported operators: +, -, *, /, %, **"})}}]);return MathHelpers}(HelperFactory);
|
|
2
|
+
//# sourceMappingURL=math-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/helpers/math-helpers.ts"],"sourcesContent":["import type { HelperDefinition } from \"../types\";\nimport { HelperFactory } from \"./helper-factory\";\nimport { toNumber } from \"./utils\";\n\n// ─── MathHelpers ─────────────────────────────────────────────────────────────\n// Aggregates all math-related helpers for the template engine.\n//\n// Provides two kinds of helpers:\n//\n// 1. **Named helpers** — one helper per operation (`add`, `subtract`, `divide`, …)\n// Usage: `{{ add a b }}`, `{{ abs value }}`, `{{ round value 2 }}`\n//\n// 2. **Generic `math` helper** — single helper with the operator as a parameter\n// Usage: `{{ math a \"+\" b }}`, `{{ math a \"/\" b }}`, `{{ math a \"**\" b }}`\n//\n// ─── Registration ────────────────────────────────────────────────────────────\n// MathHelpers are automatically pre-registered by the `Typebars` constructor.\n// They can also be registered manually on any object implementing\n// `HelperRegistry`:\n//\n// const factory = new MathHelpers();\n// factory.register(engine); // registers all helpers\n// factory.unregister(engine); // removes all helpers\n//\n// ─── Supported operators (generic `math` helper) ─────────────────────────────\n// + Addition\n// - Subtraction\n// * Multiplication\n// / Division\n// % Modulo\n// ** Exponentiation\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n/** Operators supported by the generic `math` helper */\ntype MathOperator = \"+\" | \"-\" | \"*\" | \"/\" | \"%\" | \"**\";\n\nconst SUPPORTED_OPERATORS = new Set<string>([\"+\", \"-\", \"*\", \"/\", \"%\", \"**\"]);\n\n// ─── Internal utilities ─────────────────────────────────────────────────────\n\n/** Converts a value to a number with a fallback of `0` for math operations. */\nconst num = (value: unknown): number => toNumber(value, 0);\n\n/**\n * Applies a binary operator to two operands.\n */\nfunction applyOperator(a: number, op: MathOperator, b: number): number {\n\tswitch (op) {\n\t\tcase \"+\":\n\t\t\treturn a + b;\n\t\tcase \"-\":\n\t\t\treturn a - b;\n\t\tcase \"*\":\n\t\t\treturn a * b;\n\t\tcase \"/\":\n\t\t\treturn b === 0 ? Infinity : a / b;\n\t\tcase \"%\":\n\t\t\treturn b === 0 ? NaN : a % b;\n\t\tcase \"**\":\n\t\t\treturn a ** b;\n\t}\n}\n\n// ─── Main class ─────────────────────────────────────────────────────────────\n\nexport class MathHelpers extends HelperFactory {\n\t// ─── buildDefinitions (required by HelperFactory) ──────────────────\n\n\tprotected buildDefinitions(defs: Map<string, HelperDefinition>): void {\n\t\tthis.registerBinaryOperators(defs);\n\t\tthis.registerUnaryFunctions(defs);\n\t\tthis.registerMinMax(defs);\n\t\tthis.registerGenericMath(defs);\n\t}\n\n\t// ── Binary operators ─────────────────────────────────────────────\n\n\t/** Registers add, subtract/sub, multiply/mul, divide/div, modulo/mod, pow */\n\tprivate registerBinaryOperators(defs: Map<string, HelperDefinition>): void {\n\t\t// add — Addition : {{ add a b }}\n\t\tconst addDef: HelperDefinition = {\n\t\t\tfn: (a: unknown, b: unknown) => num(a) + num(b),\n\t\t\tparams: [\n\t\t\t\t{ name: \"a\", type: { type: \"number\" }, description: \"First operand\" },\n\t\t\t\t{ name: \"b\", type: { type: \"number\" }, description: \"Second operand\" },\n\t\t\t],\n\t\t\treturnType: { type: \"number\" },\n\t\t\tdescription: \"Adds two numbers: {{ add a b }}\",\n\t\t};\n\t\tdefs.set(\"add\", addDef);\n\n\t\t// subtract / sub — Subtraction: {{ subtract a b }} or {{ sub a b }}\n\t\tconst subtractDef: HelperDefinition = {\n\t\t\tfn: (a: unknown, b: unknown) => num(a) - num(b),\n\t\t\tparams: [\n\t\t\t\t{\n\t\t\t\t\tname: \"a\",\n\t\t\t\t\ttype: { type: \"number\" },\n\t\t\t\t\tdescription: \"Value to subtract from\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: \"b\",\n\t\t\t\t\ttype: { type: \"number\" },\n\t\t\t\t\tdescription: \"Value to subtract\",\n\t\t\t\t},\n\t\t\t],\n\t\t\treturnType: { type: \"number\" },\n\t\t\tdescription: \"Subtracts b from a: {{ subtract a b }}\",\n\t\t};\n\t\tdefs.set(\"subtract\", subtractDef);\n\t\tdefs.set(\"sub\", subtractDef);\n\n\t\t// multiply / mul — Multiplication: {{ multiply a b }} or {{ mul a b }}\n\t\tconst multiplyDef: HelperDefinition = {\n\t\t\tfn: (a: unknown, b: unknown) => num(a) * num(b),\n\t\t\tparams: [\n\t\t\t\t{ name: \"a\", type: { type: \"number\" }, description: \"First factor\" },\n\t\t\t\t{ name: \"b\", type: { type: \"number\" }, description: \"Second factor\" },\n\t\t\t],\n\t\t\treturnType: { type: \"number\" },\n\t\t\tdescription: \"Multiplies two numbers: {{ multiply a b }}\",\n\t\t};\n\t\tdefs.set(\"multiply\", multiplyDef);\n\t\tdefs.set(\"mul\", multiplyDef);\n\n\t\t// divide / div — Division: {{ divide a b }} or {{ div a b }}\n\t\tconst divideDef: HelperDefinition = {\n\t\t\tfn: (a: unknown, b: unknown) => {\n\t\t\t\tconst divisor = num(b);\n\t\t\t\treturn divisor === 0 ? Infinity : num(a) / divisor;\n\t\t\t},\n\t\t\tparams: [\n\t\t\t\t{ name: \"a\", type: { type: \"number\" }, description: \"Dividend\" },\n\t\t\t\t{ name: \"b\", type: { type: \"number\" }, description: \"Divisor\" },\n\t\t\t],\n\t\t\treturnType: { type: \"number\" },\n\t\t\tdescription:\n\t\t\t\t\"Divides a by b: {{ divide a b }}. Returns Infinity if b is 0.\",\n\t\t};\n\t\tdefs.set(\"divide\", divideDef);\n\t\tdefs.set(\"div\", divideDef);\n\n\t\t// modulo / mod — Modulo: {{ modulo a b }} or {{ mod a b }}\n\t\tconst moduloDef: HelperDefinition = {\n\t\t\tfn: (a: unknown, b: unknown) => {\n\t\t\t\tconst divisor = num(b);\n\t\t\t\treturn divisor === 0 ? NaN : num(a) % divisor;\n\t\t\t},\n\t\t\tparams: [\n\t\t\t\t{ name: \"a\", type: { type: \"number\" }, description: \"Dividend\" },\n\t\t\t\t{ name: \"b\", type: { type: \"number\" }, description: \"Divisor\" },\n\t\t\t],\n\t\t\treturnType: { type: \"number\" },\n\t\t\tdescription: \"Returns the remainder of a divided by b: {{ modulo a b }}\",\n\t\t};\n\t\tdefs.set(\"modulo\", moduloDef);\n\t\tdefs.set(\"mod\", moduloDef);\n\n\t\t// pow — Exponentiation : {{ pow base exponent }}\n\t\tdefs.set(\"pow\", {\n\t\t\tfn: (base: unknown, exponent: unknown) => num(base) ** num(exponent),\n\t\t\tparams: [\n\t\t\t\t{ name: \"base\", type: { type: \"number\" }, description: \"The base\" },\n\t\t\t\t{\n\t\t\t\t\tname: \"exponent\",\n\t\t\t\t\ttype: { type: \"number\" },\n\t\t\t\t\tdescription: \"The exponent\",\n\t\t\t\t},\n\t\t\t],\n\t\t\treturnType: { type: \"number\" },\n\t\t\tdescription:\n\t\t\t\t\"Raises base to the power of exponent: {{ pow base exponent }}\",\n\t\t});\n\t}\n\n\t// ── Unary functions ──────────────────────────────────────────────\n\n\t/** Registers abs, ceil, floor, round, sqrt */\n\tprivate registerUnaryFunctions(defs: Map<string, HelperDefinition>): void {\n\t\t// abs — Absolute value: {{ abs value }}\n\t\tdefs.set(\"abs\", {\n\t\t\tfn: (value: unknown) => Math.abs(num(value)),\n\t\t\tparams: [\n\t\t\t\t{ name: \"value\", type: { type: \"number\" }, description: \"The number\" },\n\t\t\t],\n\t\t\treturnType: { type: \"number\" },\n\t\t\tdescription: \"Returns the absolute value: {{ abs value }}\",\n\t\t});\n\n\t\t// ceil — Round up: {{ ceil value }}\n\t\tdefs.set(\"ceil\", {\n\t\t\tfn: (value: unknown) => Math.ceil(num(value)),\n\t\t\tparams: [\n\t\t\t\t{\n\t\t\t\t\tname: \"value\",\n\t\t\t\t\ttype: { type: \"number\" },\n\t\t\t\t\tdescription: \"The number to round up\",\n\t\t\t\t},\n\t\t\t],\n\t\t\treturnType: { type: \"number\" },\n\t\t\tdescription: \"Rounds up to the nearest integer: {{ ceil value }}\",\n\t\t});\n\n\t\t// floor — Round down: {{ floor value }}\n\t\tdefs.set(\"floor\", {\n\t\t\tfn: (value: unknown) => Math.floor(num(value)),\n\t\t\tparams: [\n\t\t\t\t{\n\t\t\t\t\tname: \"value\",\n\t\t\t\t\ttype: { type: \"number\" },\n\t\t\t\t\tdescription: \"The number to round down\",\n\t\t\t\t},\n\t\t\t],\n\t\t\treturnType: { type: \"number\" },\n\t\t\tdescription: \"Rounds down to the nearest integer: {{ floor value }}\",\n\t\t});\n\n\t\t// round — Rounding: {{ round value }} or {{ round value precision }}\n\t\t// With precision: {{ round 3.14159 2 }} → 3.14\n\t\tdefs.set(\"round\", {\n\t\t\tfn: (value: unknown, precision: unknown) => {\n\t\t\t\tconst n = num(value);\n\t\t\t\t// If precision is a Handlebars options object (not a number),\n\t\t\t\t// it means the second parameter was not provided.\n\t\t\t\tif (\n\t\t\t\t\tprecision === undefined ||\n\t\t\t\t\tprecision === null ||\n\t\t\t\t\ttypeof precision === \"object\"\n\t\t\t\t) {\n\t\t\t\t\treturn Math.round(n);\n\t\t\t\t}\n\t\t\t\tconst p = num(precision);\n\t\t\t\tconst factor = 10 ** p;\n\t\t\t\treturn Math.round(n * factor) / factor;\n\t\t\t},\n\t\t\tparams: [\n\t\t\t\t{\n\t\t\t\t\tname: \"value\",\n\t\t\t\t\ttype: { type: \"number\" },\n\t\t\t\t\tdescription: \"The number to round\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: \"precision\",\n\t\t\t\t\ttype: { type: \"number\" },\n\t\t\t\t\tdescription: \"Number of decimal places (default: 0)\",\n\t\t\t\t\toptional: true,\n\t\t\t\t},\n\t\t\t],\n\t\t\treturnType: { type: \"number\" },\n\t\t\tdescription:\n\t\t\t\t\"Rounds to the nearest integer or to a given precision: {{ round value }} or {{ round value 2 }}\",\n\t\t});\n\n\t\t// sqrt — Square root: {{ sqrt value }}\n\t\tdefs.set(\"sqrt\", {\n\t\t\tfn: (value: unknown) => Math.sqrt(num(value)),\n\t\t\tparams: [\n\t\t\t\t{ name: \"value\", type: { type: \"number\" }, description: \"The number\" },\n\t\t\t],\n\t\t\treturnType: { type: \"number\" },\n\t\t\tdescription: \"Returns the square root: {{ sqrt value }}\",\n\t\t});\n\t}\n\n\t// ── Min / Max ────────────────────────────────────────────────────\n\n\t/** Registers min and max */\n\tprivate registerMinMax(defs: Map<string, HelperDefinition>): void {\n\t\t// min — Minimum : {{ min a b }}\n\t\tdefs.set(\"min\", {\n\t\t\tfn: (a: unknown, b: unknown) => Math.min(num(a), num(b)),\n\t\t\tparams: [\n\t\t\t\t{ name: \"a\", type: { type: \"number\" }, description: \"First number\" },\n\t\t\t\t{ name: \"b\", type: { type: \"number\" }, description: \"Second number\" },\n\t\t\t],\n\t\t\treturnType: { type: \"number\" },\n\t\t\tdescription: \"Returns the smaller of two numbers: {{ min a b }}\",\n\t\t});\n\n\t\t// max — Maximum : {{ max a b }}\n\t\tdefs.set(\"max\", {\n\t\t\tfn: (a: unknown, b: unknown) => Math.max(num(a), num(b)),\n\t\t\tparams: [\n\t\t\t\t{ name: \"a\", type: { type: \"number\" }, description: \"First number\" },\n\t\t\t\t{ name: \"b\", type: { type: \"number\" }, description: \"Second number\" },\n\t\t\t],\n\t\t\treturnType: { type: \"number\" },\n\t\t\tdescription: \"Returns the larger of two numbers: {{ max a b }}\",\n\t\t});\n\t}\n\n\t// ── Generic helper ───────────────────────────────────────────────\n\n\t/** Registers the generic `math` helper with operator as a parameter */\n\tprivate registerGenericMath(defs: Map<string, HelperDefinition>): void {\n\t\t// Usage : {{ math a \"+\" b }}, {{ math a \"/\" b }}, {{ math a \"**\" b }}\n\t\tdefs.set(\"math\", {\n\t\t\tfn: (a: unknown, operator: unknown, b: unknown) => {\n\t\t\t\tconst op = String(operator);\n\t\t\t\tif (!SUPPORTED_OPERATORS.has(op)) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`[math helper] Unknown operator \"${op}\". ` +\n\t\t\t\t\t\t\t`Supported: ${[...SUPPORTED_OPERATORS].join(\", \")} `,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn applyOperator(num(a), op as MathOperator, num(b));\n\t\t\t},\n\t\t\tparams: [\n\t\t\t\t{ name: \"a\", type: { type: \"number\" }, description: \"Left operand\" },\n\t\t\t\t{\n\t\t\t\t\tname: \"operator\",\n\t\t\t\t\ttype: { type: \"string\", enum: [\"+\", \"-\", \"*\", \"/\", \"%\", \"**\"] },\n\t\t\t\t\tdescription: 'Arithmetic operator: \"+\", \"-\", \"*\", \"/\", \"%\", \"**\"',\n\t\t\t\t},\n\t\t\t\t{ name: \"b\", type: { type: \"number\" }, description: \"Right operand\" },\n\t\t\t],\n\t\t\treturnType: { type: \"number\" },\n\t\t\tdescription:\n\t\t\t\t'Generic math helper with operator as parameter: {{ math a \"+\" b }}, {{ math a \"/\" b }}. ' +\n\t\t\t\t\"Supported operators: +, -, *, /, %, **\",\n\t\t});\n\t}\n}\n"],"names":["HelperFactory","toNumber","SUPPORTED_OPERATORS","Set","num","value","applyOperator","a","op","b","Infinity","NaN","MathHelpers","buildDefinitions","defs","registerBinaryOperators","registerUnaryFunctions","registerMinMax","registerGenericMath","addDef","fn","params","name","type","description","returnType","set","subtractDef","multiplyDef","divideDef","divisor","moduloDef","base","exponent","Math","abs","ceil","floor","precision","n","undefined","round","p","factor","optional","sqrt","min","max","operator","String","has","Error","join","enum"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export function toNumber(value){var fallback=arguments.length>1&&arguments[1]!==void 0?arguments[1]:NaN;if(typeof value==="number")return value;if(typeof value==="string"){var n=Number(value);return Number.isNaN(n)?fallback:n}if(typeof value==="boolean")return value?1:0;return fallback}
|
|
2
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/helpers/utils.ts"],"sourcesContent":["// ─── Shared Helper Utilities ─────────────────────────────────────────────────\n// Common utilities used across helper packs (MathHelpers, LogicalHelpers, …).\n\n/**\n * Converts an unknown value to a number.\n *\n * Conversion rules:\n * - `number` → returned as-is\n * - `string` → parsed via `Number()`; returns `fallback` if result is `NaN`\n * - `boolean` → `true` → `1`, `false` → `0`\n * - anything else → `fallback`\n *\n * The `fallback` parameter lets each consumer choose the right semantics:\n * - **Math helpers** pass `0` so that invalid inputs silently become zero\n * (e.g. `add(\"abc\", 5)` → `5`).\n * - **Logical helpers** pass `NaN` (the default) so that invalid comparisons\n * evaluate to `false` (e.g. `lt(\"abc\", 5)` → `false`).\n *\n * @param value - The value to convert\n * @param fallback - Value returned when conversion fails (default: `NaN`)\n */\nexport function toNumber(value: unknown, fallback: number = NaN): number {\n\tif (typeof value === \"number\") return value;\n\tif (typeof value === \"string\") {\n\t\tconst n = Number(value);\n\t\treturn Number.isNaN(n) ? fallback : n;\n\t}\n\tif (typeof value === \"boolean\") return value ? 1 : 0;\n\treturn fallback;\n}\n"],"names":["toNumber","value","fallback","NaN","n","Number","isNaN"],"mappings":"AAqBA,OAAO,SAASA,SAASC,KAAc,MAAEC,SAAAA,uDAAmBC,IAC3D,GAAI,OAAOF,QAAU,SAAU,OAAOA,MACtC,GAAI,OAAOA,QAAU,SAAU,CAC9B,IAAMG,EAAIC,OAAOJ,OACjB,OAAOI,OAAOC,KAAK,CAACF,GAAKF,SAAWE,CACrC,CACA,GAAI,OAAOH,QAAU,UAAW,OAAOA,MAAQ,EAAI,EACnD,OAAOC,QACR"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from "./errors
|
|
2
|
-
export { Typebars } from "./typebars
|
|
3
|
-
export { defineHelper } from "./types
|
|
1
|
+
export * from "./errors";
|
|
2
|
+
export { Typebars } from "./typebars";
|
|
3
|
+
export { defineHelper } from "./types";
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
//# debugId=907E45F8A123358764756E2164756E21
|
|
4
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
export*from"./errors";export{Typebars}from"./typebars";export{defineHelper}from"./types";
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1,9 +1 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": [],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
],
|
|
6
|
-
"mappings": "",
|
|
7
|
-
"debugId": "907E45F8A123358764756E2164756E21",
|
|
8
|
-
"names": []
|
|
9
|
-
}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from \"./errors\";\nexport { Typebars } from \"./typebars\";\nexport { defineHelper } from \"./types\";\n"],"names":["Typebars","defineHelper"],"mappings":"AAAA,WAAc,UAAW,AACzB,QAASA,QAAQ,KAAQ,YAAa,AACtC,QAASC,YAAY,KAAQ,SAAU"}
|
package/dist/parser.js
CHANGED
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
//# debugId=238977E59328291964756E2164756E21
|
|
4
|
-
//# sourceMappingURL=parser.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_without_holes(arr){if(Array.isArray(arr))return _array_like_to_array(arr)}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(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 _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)}import Handlebars from"handlebars";import{TemplateParseError}from"./errors";var IDENTIFIER_RE=/^(.+):(\d+)$/;var NUMERIC_LITERAL_RE=/^-?\d+(\.\d+)?$/;export function parse(template){try{return Handlebars.parse(template)}catch(error){var _locMatch_,_locMatch_1;var message=_instanceof(error,Error)?error.message:String(error);var locMatch=message.match(/line\s+(\d+).*?column\s+(\d+)/i);var loc=locMatch?{line:parseInt((_locMatch_=locMatch[1])!==null&&_locMatch_!==void 0?_locMatch_:"0",10),column:parseInt((_locMatch_1=locMatch[2])!==null&&_locMatch_1!==void 0?_locMatch_1:"0",10)}:undefined;throw new TemplateParseError(message,loc)}}export function isSingleExpression(ast){var _body_;var body=ast.body;return body.length===1&&((_body_=body[0])===null||_body_===void 0?void 0:_body_.type)==="MustacheStatement"}export function extractPathSegments(expr){if(expr.type==="PathExpression"){return expr.parts}return[]}export function isThisExpression(expr){if(expr.type!=="PathExpression")return false;var path=expr;return path.original==="this"||path.original==="."}export function getEffectiveBody(program){return program.body.filter(function(s){return!(s.type==="ContentStatement"&&s.value.trim()==="")})}export function getEffectivelySingleBlock(program){var _effective_;var effective=getEffectiveBody(program);if(effective.length===1&&((_effective_=effective[0])===null||_effective_===void 0?void 0:_effective_.type)==="BlockStatement"){return effective[0]}return null}export function getEffectivelySingleExpression(program){var _effective_;var effective=getEffectiveBody(program);if(effective.length===1&&((_effective_=effective[0])===null||_effective_===void 0?void 0:_effective_.type)==="MustacheStatement"){return effective[0]}return null}export function canUseFastPath(ast){return ast.body.every(function(s){return s.type==="ContentStatement"||s.type==="MustacheStatement"&&s.params.length===0&&!s.hash})}export function detectLiteralType(text){if(NUMERIC_LITERAL_RE.test(text))return"number";if(text==="true"||text==="false")return"boolean";if(text==="null")return"null";return null}export function coerceLiteral(raw){var trimmed=raw.trim();var type=detectLiteralType(trimmed);if(type==="number")return Number(trimmed);if(type==="boolean")return trimmed==="true";if(type==="null")return null;return raw}export function parseIdentifier(segment){var match=segment.match(IDENTIFIER_RE);if(match){var _match_,_match_1;return{key:(_match_=match[1])!==null&&_match_!==void 0?_match_:segment,identifier:parseInt((_match_1=match[2])!==null&&_match_1!==void 0?_match_1:"0",10)}}return{key:segment,identifier:null}}export function extractExpressionIdentifier(segments){if(segments.length===0){return{cleanSegments:[],identifier:null}}var lastSegment=segments[segments.length-1];var parsed=parseIdentifier(lastSegment);if(parsed.identifier!==null){var cleanSegments=_to_consumable_array(segments.slice(0,-1)).concat([parsed.key]);return{cleanSegments:cleanSegments,identifier:parsed.identifier}}return{cleanSegments:segments,identifier:null}}
|
|
2
|
+
//# sourceMappingURL=parser.js.map
|
package/dist/parser.js.map
CHANGED
|
@@ -1,9 +1 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": [],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
],
|
|
6
|
-
"mappings": "",
|
|
7
|
-
"debugId": "238977E59328291964756E2164756E21",
|
|
8
|
-
"names": []
|
|
9
|
-
}
|
|
1
|
+
{"version":3,"sources":["../src/parser.ts"],"sourcesContent":["import Handlebars from \"handlebars\";\nimport { TemplateParseError } from \"./errors\";\n\n// ─── Regex for detecting a template identifier (e.g. \"meetingId:1\") ──────────\n// The identifier is always a positive integer or zero, separated from the\n// variable name by a `:`. The `:` and number are on the **last** segment\n// of the path (Handlebars splits on `.`).\nconst IDENTIFIER_RE = /^(.+):(\\d+)$/;\n\n// ─── Template Parser ─────────────────────────────────────────────────────────\n// Thin wrapper around the Handlebars parser. Centralizing the parser call\n// here allows us to:\n// 1. Wrap errors into our own hierarchy (`TemplateParseError`)\n// 2. Expose AST introspection helpers (e.g. `isSingleExpression`)\n// 3. Isolate the direct Handlebars dependency from the rest of the codebase\n//\n// AST caching is handled at the `Typebars` instance level (via its own\n// configurable LRU cache), not here. This module only parses and wraps errors.\n\n// ─── Regex for detecting a numeric literal (integer or decimal, signed) ──────\n// Intentionally conservative: no scientific notation (1e5), no hex (0xFF),\n// no separators (1_000). We only want to recognize what a human would write\n// as a numeric value in a template.\nconst NUMERIC_LITERAL_RE = /^-?\\d+(\\.\\d+)?$/;\n\n/**\n * Parses a template string and returns the Handlebars AST.\n *\n * This function does not cache results — caching is managed at the\n * `Typebars` instance level via its own configurable LRU cache.\n *\n * @param template - The template string to parse (e.g. `\"Hello {{name}}\"`)\n * @returns The root AST node (`hbs.AST.Program`)\n * @throws {TemplateParseError} if the template syntax is invalid\n */\nexport function parse(template: string): hbs.AST.Program {\n\ttry {\n\t\treturn Handlebars.parse(template);\n\t} catch (error: unknown) {\n\t\t// Handlebars throws a plain Error with a descriptive message.\n\t\t// We transform it into a TemplateParseError for uniform handling.\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\n\t\t// Handlebars sometimes includes the position in the message —\n\t\t// attempt to extract it to enrich our error.\n\t\tconst locMatch = message.match(/line\\s+(\\d+).*?column\\s+(\\d+)/i);\n\t\tconst loc = locMatch\n\t\t\t? {\n\t\t\t\t\tline: parseInt(locMatch[1] ?? \"0\", 10),\n\t\t\t\t\tcolumn: parseInt(locMatch[2] ?? \"0\", 10),\n\t\t\t\t}\n\t\t\t: undefined;\n\n\t\tthrow new TemplateParseError(message, loc);\n\t}\n}\n\n/**\n * Determines whether the AST represents a template consisting of a single\n * expression `{{expression}}` with no text content around it.\n *\n * This matters for return type inference:\n * - Template `{{value}}` → returns the raw type of `value` (number, object…)\n * - Template `Hello {{name}}` → always returns `string` (concatenation)\n *\n * @param ast - The parsed AST of the template\n * @returns `true` if the template is a single expression\n */\nexport function isSingleExpression(ast: hbs.AST.Program): boolean {\n\tconst { body } = ast;\n\n\t// Exactly one node, and it's a MustacheStatement (not a block, not text)\n\treturn body.length === 1 && body[0]?.type === \"MustacheStatement\";\n}\n\n/**\n * Extracts the path segments from a Handlebars `PathExpression`.\n *\n * Handlebars decomposes `user.address.city` into `{ parts: [\"user\", \"address\", \"city\"] }`.\n * This function safely extracts those segments.\n *\n * @param expr - The expression to extract the path from\n * @returns The path segments, or an empty array if the expression is not\n * a `PathExpression`\n */\nexport function extractPathSegments(expr: hbs.AST.Expression): string[] {\n\tif (expr.type === \"PathExpression\") {\n\t\treturn (expr as hbs.AST.PathExpression).parts;\n\t}\n\treturn [];\n}\n\n/**\n * Checks whether an AST expression is a `PathExpression` pointing to `this`\n * (used inside `{{#each}}` blocks).\n */\nexport function isThisExpression(expr: hbs.AST.Expression): boolean {\n\tif (expr.type !== \"PathExpression\") return false;\n\tconst path = expr as hbs.AST.PathExpression;\n\treturn path.original === \"this\" || path.original === \".\";\n}\n\n// ─── Filtering Semantically Significant Nodes ───────────────────────────────\n// In a Handlebars AST, formatting (newlines, indentation) produces\n// `ContentStatement` nodes whose value is purely whitespace. These nodes\n// have no semantic impact and must be ignored during type inference to\n// correctly detect \"effectively a single block\" or \"effectively a single\n// expression\" cases.\n\n/**\n * Returns the semantically significant statements of a Program by\n * filtering out `ContentStatement` nodes that contain only whitespace.\n */\nexport function getEffectiveBody(\n\tprogram: hbs.AST.Program,\n): hbs.AST.Statement[] {\n\treturn program.body.filter(\n\t\t(s) =>\n\t\t\t!(\n\t\t\t\ts.type === \"ContentStatement\" &&\n\t\t\t\t(s as hbs.AST.ContentStatement).value.trim() === \"\"\n\t\t\t),\n\t);\n}\n\n/**\n * Determines whether a Program effectively consists of a single\n * `BlockStatement` (ignoring surrounding whitespace).\n *\n * Recognized examples:\n * ```\n * {{#if x}}...{{/if}}\n *\n * {{#each items}}...{{/each}}\n * ```\n *\n * @returns The single `BlockStatement`, or `null` if the program contains\n * other significant nodes.\n */\nexport function getEffectivelySingleBlock(\n\tprogram: hbs.AST.Program,\n): hbs.AST.BlockStatement | null {\n\tconst effective = getEffectiveBody(program);\n\tif (effective.length === 1 && effective[0]?.type === \"BlockStatement\") {\n\t\treturn effective[0] as hbs.AST.BlockStatement;\n\t}\n\treturn null;\n}\n\n/**\n * Determines whether a Program effectively consists of a single\n * `MustacheStatement` (ignoring surrounding whitespace).\n *\n * Example: ` {{age}} ` → true\n */\nexport function getEffectivelySingleExpression(\n\tprogram: hbs.AST.Program,\n): hbs.AST.MustacheStatement | null {\n\tconst effective = getEffectiveBody(program);\n\tif (effective.length === 1 && effective[0]?.type === \"MustacheStatement\") {\n\t\treturn effective[0] as hbs.AST.MustacheStatement;\n\t}\n\treturn null;\n}\n\n// ─── Fast-Path Detection ─────────────────────────────────────────────────────\n// For templates consisting only of text and simple expressions (no blocks,\n// no helpers with parameters), we can bypass Handlebars entirely and perform\n// a simple variable replacement via string concatenation.\n\n/**\n * Determines whether an AST can be executed via the fast-path (direct\n * concatenation without going through `Handlebars.compile()`).\n *\n * The fast-path is possible when the template only contains:\n * - `ContentStatement` nodes (static text)\n * - Simple `MustacheStatement` nodes (no params, no hash)\n *\n * This excludes:\n * - Block helpers (`{{#if}}`, `{{#each}}`, etc.)\n * - Inline helpers (`{{uppercase name}}`)\n * - Sub-expressions\n *\n * @param ast - The parsed AST of the template\n * @returns `true` if the template can use the fast-path\n */\nexport function canUseFastPath(ast: hbs.AST.Program): boolean {\n\treturn ast.body.every(\n\t\t(s) =>\n\t\t\ts.type === \"ContentStatement\" ||\n\t\t\t(s.type === \"MustacheStatement\" &&\n\t\t\t\t(s as hbs.AST.MustacheStatement).params.length === 0 &&\n\t\t\t\t!(s as hbs.AST.MustacheStatement).hash),\n\t);\n}\n\n// ─── Literal Detection in Text Content ───────────────────────────────────────\n// When a program contains only ContentStatements (no expressions), we try\n// to detect whether the concatenated and trimmed text is a typed literal\n// (number, boolean, null). This enables correct type inference for branches\n// like `{{#if x}} 42 {{/if}}`.\n\n/**\n * Attempts to detect the type of a raw text literal.\n *\n * @param text - The trimmed text from a ContentStatement or group of ContentStatements\n * @returns The detected JSON Schema type, or `null` if it's free-form text (string).\n */\nexport function detectLiteralType(\n\ttext: string,\n): \"number\" | \"boolean\" | \"null\" | null {\n\tif (NUMERIC_LITERAL_RE.test(text)) return \"number\";\n\tif (text === \"true\" || text === \"false\") return \"boolean\";\n\tif (text === \"null\") return \"null\";\n\treturn null;\n}\n\n/**\n * Coerces a raw string from Handlebars rendering to its actual type\n * if it represents a literal (number, boolean, null).\n * Returns the raw (untrimmed) string otherwise.\n */\nexport function coerceLiteral(raw: string): unknown {\n\tconst trimmed = raw.trim();\n\tconst type = detectLiteralType(trimmed);\n\tif (type === \"number\") return Number(trimmed);\n\tif (type === \"boolean\") return trimmed === \"true\";\n\tif (type === \"null\") return null;\n\t// Not a typed literal — return the raw string without trimming,\n\t// as whitespace may be significant (e.g. output of an #each block).\n\treturn raw;\n}\n\n// ─── Template Identifier Parsing ─────────────────────────────────────────────\n// Syntax `{{key:N}}` where N is a positive integer or zero.\n// The identifier allows resolving a variable from a specific data source\n// (e.g. a workflow node identified by its number).\n\n/** Result of parsing a path segment with a potential identifier */\nexport interface ParsedIdentifier {\n\t/** The variable name, without the `:N` suffix */\n\tkey: string;\n\t/** The numeric identifier, or `null` if absent */\n\tidentifier: number | null;\n}\n\n/**\n * Parses an individual path segment to extract the key and optional identifier.\n *\n * @param segment - A raw path segment (e.g. `\"meetingId:1\"` or `\"meetingId\"`)\n * @returns An object `{ key, identifier }`\n *\n * @example\n * ```\n * parseIdentifier(\"meetingId:1\") // → { key: \"meetingId\", identifier: 1 }\n * parseIdentifier(\"meetingId\") // → { key: \"meetingId\", identifier: null }\n * parseIdentifier(\"meetingId:0\") // → { key: \"meetingId\", identifier: 0 }\n * ```\n */\nexport function parseIdentifier(segment: string): ParsedIdentifier {\n\tconst match = segment.match(IDENTIFIER_RE);\n\tif (match) {\n\t\treturn {\n\t\t\tkey: match[1] ?? segment,\n\t\t\tidentifier: parseInt(match[2] ?? \"0\", 10),\n\t\t};\n\t}\n\treturn { key: segment, identifier: null };\n}\n\n/** Result of extracting the identifier from a complete expression */\nexport interface ExpressionIdentifier {\n\t/** Cleaned path segments (without the `:N` suffix on the last one) */\n\tcleanSegments: string[];\n\t/** The numeric identifier extracted from the last segment, or `null` */\n\tidentifier: number | null;\n}\n\n/**\n * Extracts the identifier from a complete expression (array of segments).\n *\n * The identifier is always on the **last** segment of the path, because\n * Handlebars splits on `.` before the `:`.\n *\n * @param segments - The raw path segments (e.g. `[\"user\", \"name:1\"]`)\n * @returns An object `{ cleanSegments, identifier }`\n *\n * @example\n * ```\n * extractExpressionIdentifier([\"meetingId:1\"])\n * // → { cleanSegments: [\"meetingId\"], identifier: 1 }\n *\n * extractExpressionIdentifier([\"user\", \"name:1\"])\n * // → { cleanSegments: [\"user\", \"name\"], identifier: 1 }\n *\n * extractExpressionIdentifier([\"meetingId\"])\n * // → { cleanSegments: [\"meetingId\"], identifier: null }\n * ```\n */\nexport function extractExpressionIdentifier(\n\tsegments: string[],\n): ExpressionIdentifier {\n\tif (segments.length === 0) {\n\t\treturn { cleanSegments: [], identifier: null };\n\t}\n\n\tconst lastSegment = segments[segments.length - 1] as string;\n\tconst parsed = parseIdentifier(lastSegment);\n\n\tif (parsed.identifier !== null) {\n\t\tconst cleanSegments = [...segments.slice(0, -1), parsed.key];\n\t\treturn { cleanSegments, identifier: parsed.identifier };\n\t}\n\n\treturn { cleanSegments: segments, identifier: null };\n}\n"],"names":["Handlebars","TemplateParseError","IDENTIFIER_RE","NUMERIC_LITERAL_RE","parse","template","error","locMatch","message","Error","String","match","loc","line","parseInt","column","undefined","isSingleExpression","ast","body","length","type","extractPathSegments","expr","parts","isThisExpression","path","original","getEffectiveBody","program","filter","s","value","trim","getEffectivelySingleBlock","effective","getEffectivelySingleExpression","canUseFastPath","every","params","hash","detectLiteralType","text","test","coerceLiteral","raw","trimmed","Number","parseIdentifier","segment","key","identifier","extractExpressionIdentifier","segments","cleanSegments","lastSegment","parsed","slice"],"mappings":"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"}
|
package/dist/schema-resolver.js
CHANGED
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
import{A as b,B as c,C as d,D as e,z as a}from"./chunk-jms1ndxn.js";import"./chunk-p5efqsxw.js";import"./chunk-zh1e0yhd.js";export{e as simplifySchema,c as resolveSchemaPath,b as resolveRef,d as resolveArrayItems,a as assertNoConditionalSchema};
|
|
2
|
-
|
|
3
|
-
//# debugId=EA8E60A23E3E11CC64756E2164756E21
|
|
4
|
-
//# sourceMappingURL=schema-resolver.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 _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 ownKeys(object,enumerableOnly){var keys=Object.keys(object);if(Object.getOwnPropertySymbols){var symbols=Object.getOwnPropertySymbols(object);if(enumerableOnly){symbols=symbols.filter(function(sym){return Object.getOwnPropertyDescriptor(object,sym).enumerable})}keys.push.apply(keys,symbols)}return keys}function _object_spread_props(target,source){source=source!=null?source:{};if(Object.getOwnPropertyDescriptors){Object.defineProperties(target,Object.getOwnPropertyDescriptors(source))}else{ownKeys(Object(source)).forEach(function(key){Object.defineProperty(target,key,Object.getOwnPropertyDescriptor(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{UnsupportedSchemaError}from"./errors";import{deepEqual}from"./utils";export function assertNoConditionalSchema(schema){var path=arguments.length>1&&arguments[1]!==void 0?arguments[1]:"",visited=arguments.length>2&&arguments[2]!==void 0?arguments[2]:new Set;if(visited.has(schema))return;visited.add(schema);if(schema.if!==undefined){throw new UnsupportedSchemaError("if/then/else",path||"/")}if(schema.then!==undefined){throw new UnsupportedSchemaError("if/then/else",path||"/")}if(schema.else!==undefined){throw new UnsupportedSchemaError("if/then/else",path||"/")}if(schema.properties){var _iteratorNormalCompletion=true,_didIteratorError=false,_iteratorError=undefined;try{for(var _iterator=Object.entries(schema.properties)[Symbol.iterator](),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var _step_value=_sliced_to_array(_step.value,2),key=_step_value[0],prop=_step_value[1];if(prop&&typeof prop!=="boolean"){assertNoConditionalSchema(prop,"".concat(path,"/properties/").concat(key),visited)}}}catch(err){_didIteratorError=true;_iteratorError=err}finally{try{if(!_iteratorNormalCompletion&&_iterator.return!=null){_iterator.return()}}finally{if(_didIteratorError){throw _iteratorError}}}}if(schema.additionalProperties&&_type_of(schema.additionalProperties)==="object"){assertNoConditionalSchema(schema.additionalProperties,"".concat(path,"/additionalProperties"),visited)}if(schema.items){if(Array.isArray(schema.items)){for(var i=0;i<schema.items.length;i++){var item=schema.items[i];if(item&&typeof item!=="boolean"){assertNoConditionalSchema(item,"".concat(path,"/items/").concat(i),visited)}}}else if(typeof schema.items!=="boolean"){assertNoConditionalSchema(schema.items,"".concat(path,"/items"),visited)}}for(var _i=0,_iter=["allOf","anyOf","oneOf"];_i<_iter.length;_i++){var keyword=_iter[_i];var branches=schema[keyword];if(branches){for(var i1=0;i1<branches.length;i1++){var branch=branches[i1];if(branch&&typeof branch!=="boolean"){assertNoConditionalSchema(branch,"".concat(path,"/").concat(keyword,"/").concat(i1),visited)}}}}if(schema.not&&typeof schema.not!=="boolean"){assertNoConditionalSchema(schema.not,"".concat(path,"/not"),visited)}for(var _i1=0,_iter1=["definitions","$defs"];_i1<_iter1.length;_i1++){var defsKey=_iter1[_i1];var defs=schema[defsKey];if(defs){var _iteratorNormalCompletion1=true,_didIteratorError1=false,_iteratorError1=undefined;try{for(var _iterator1=Object.entries(defs)[Symbol.iterator](),_step1;!(_iteratorNormalCompletion1=(_step1=_iterator1.next()).done);_iteratorNormalCompletion1=true){var _step_value1=_sliced_to_array(_step1.value,2),name=_step_value1[0],def=_step_value1[1];if(def&&typeof def!=="boolean"){assertNoConditionalSchema(def,"".concat(path,"/").concat(defsKey,"/").concat(name),visited)}}}catch(err){_didIteratorError1=true;_iteratorError1=err}finally{try{if(!_iteratorNormalCompletion1&&_iterator1.return!=null){_iterator1.return()}}finally{if(_didIteratorError1){throw _iteratorError1}}}}}}export function resolveRef(schema,root){var _match_;if(!schema.$ref)return schema;var ref=schema.$ref;var match=ref.match(/^#\/(definitions|\$defs)\/(.+)$/);if(!match){throw new Error('Unsupported $ref format: "'.concat(ref,'". Only internal #/definitions/ references are supported.'))}var defsKey=match[1];var name=(_match_=match[2])!==null&&_match_!==void 0?_match_:"";var defs=defsKey==="definitions"?root.definitions:root.$defs;if(!defs||!(name in defs)){throw new Error('Cannot resolve $ref "'.concat(ref,'": definition "').concat(name,'" not found.'))}var def=defs[name];if(!def||typeof def==="boolean"){throw new Error('Cannot resolve $ref "'.concat(ref,'": definition "').concat(name,'" not found.'))}return resolveRef(def,root)}function resolveSegment(schema,segment,root){var resolved=resolveRef(schema,root);if(resolved.properties&&segment in resolved.properties){var prop=resolved.properties[segment];if(prop&&typeof prop!=="boolean")return resolveRef(prop,root);if(prop===true)return{}}if(resolved.additionalProperties!==undefined&&resolved.additionalProperties!==false){if(resolved.additionalProperties===true){return{}}return resolveRef(resolved.additionalProperties,root)}var schemaType=resolved.type;var isArray=schemaType==="array"||Array.isArray(schemaType)&&schemaType.includes("array");if(isArray&&segment==="length"){return{type:"integer"}}var combinatorResult=resolveInCombinators(resolved,segment,root);if(combinatorResult)return combinatorResult;return undefined}function resolveInCombinators(schema,segment,root){if(schema.allOf){var matches=schema.allOf.filter(function(b){return typeof b!=="boolean"}).map(function(branch){return resolveSegment(branch,segment,root)}).filter(function(s){return s!==undefined});if(matches.length===1)return matches[0];if(matches.length>1)return{allOf:matches}}for(var _i=0,_iter=["anyOf","oneOf"];_i<_iter.length;_i++){var key=_iter[_i];if(!schema[key])continue;var matches1=schema[key].filter(function(b){return typeof b!=="boolean"}).map(function(branch){return resolveSegment(branch,segment,root)}).filter(function(s){return s!==undefined});if(matches1.length===1)return matches1[0];if(matches1.length>1)return _define_property({},key,matches1)}return undefined}export function resolveSchemaPath(schema,path){if(path.length===0)return resolveRef(schema,schema);var current=resolveRef(schema,schema);var root=schema;var _iteratorNormalCompletion=true,_didIteratorError=false,_iteratorError=undefined;try{for(var _iterator=path[Symbol.iterator](),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var segment=_step.value;var next=resolveSegment(current,segment,root);if(next===undefined)return undefined;current=next}}catch(err){_didIteratorError=true;_iteratorError=err}finally{try{if(!_iteratorNormalCompletion&&_iterator.return!=null){_iterator.return()}}finally{if(_didIteratorError){throw _iteratorError}}}return current}export function resolveArrayItems(schema,root){var resolved=resolveRef(schema,root);var schemaType=resolved.type;var isArray=schemaType==="array"||Array.isArray(schemaType)&&schemaType.includes("array");if(!isArray&&resolved.items===undefined){return undefined}if(resolved.items===undefined){return{}}if(typeof resolved.items==="boolean"){return{}}if(Array.isArray(resolved.items)){var schemas=resolved.items.filter(function(item){return typeof item!=="boolean"}).map(function(item){return resolveRef(item,root)});if(schemas.length===0)return{};return{oneOf:schemas}}return resolveRef(resolved.items,root)}export function simplifySchema(schema){for(var _i=0,_iter=["oneOf","anyOf"];_i<_iter.length;_i++){var key=_iter[_i];var arr=schema[key];if(arr&&arr.length===1){var first=arr[0];if(first!==undefined&&typeof first!=="boolean")return simplifySchema(first)}}if(schema.allOf&&schema.allOf.length===1){var first1=schema.allOf[0];if(first1!==undefined&&typeof first1!=="boolean")return simplifySchema(first1)}for(var _i1=0,_iter1=["oneOf","anyOf"];_i1<_iter1.length;_i1++){var key1=_iter1[_i1];var arr1=schema[key1];if(arr1&&arr1.length>1){var unique=[];var _iteratorNormalCompletion=true,_didIteratorError=false,_iteratorError=undefined;try{var _loop=function(){var entry=_step.value;if(typeof entry==="boolean")return"continue";var isDuplicate=unique.some(function(existing){return deepEqual(existing,entry)});if(!isDuplicate){unique.push(simplifySchema(entry))}};for(var _iterator=arr1[Symbol.iterator](),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true)_loop()}catch(err){_didIteratorError=true;_iteratorError=err}finally{try{if(!_iteratorNormalCompletion&&_iterator.return!=null){_iterator.return()}}finally{if(_didIteratorError){throw _iteratorError}}}if(unique.length===1)return unique[0];return _object_spread_props(_object_spread({},schema),_define_property({},key1,unique))}}return schema}
|
|
2
|
+
//# sourceMappingURL=schema-resolver.js.map
|
|
@@ -1,9 +1 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": [],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
],
|
|
6
|
-
"mappings": "",
|
|
7
|
-
"debugId": "EA8E60A23E3E11CC64756E2164756E21",
|
|
8
|
-
"names": []
|
|
9
|
-
}
|
|
1
|
+
{"version":3,"sources":["../src/schema-resolver.ts"],"sourcesContent":["import type { JSONSchema7 } from \"json-schema\";\nimport { UnsupportedSchemaError } from \"./errors\";\nimport { deepEqual } from \"./utils\";\n\n// ─── JSON Schema Resolver ────────────────────────────────────────────────────\n// Utility for navigating a JSON Schema Draft v7 by following a property path\n// (e.g. [\"user\", \"address\", \"city\"]).\n//\n// Handles:\n// - `$ref` resolution (internal references #/definitions/...)\n// - Navigation through `properties`\n// - Navigation through `items` (array elements)\n// - Combinators `allOf`, `anyOf`, `oneOf` (searches each branch)\n// - `additionalProperties` when the property is not explicitly declared\n//\n// Rejects:\n// - Conditional schemas (`if/then/else`) — non-resolvable without runtime data\n\n// ─── Conditional Schema Detection ────────────────────────────────────────────\n// JSON Schema Draft v7 introduced `if/then/else` conditional schemas.\n// These are fundamentally non-resolvable during static analysis because\n// they depend on runtime data values. Rather than silently ignoring them\n// (which would produce incorrect results — missing properties, wrong types),\n// we fail fast with a clear error pointing to the exact location in the schema.\n\n/**\n * Recursively validates that a JSON Schema does not contain `if/then/else`\n * conditional keywords. Throws an `UnsupportedSchemaError` if any are found.\n *\n * This check traverses the entire schema tree, including:\n * - `properties` values\n * - `additionalProperties` (when it's a schema)\n * - `items` (single schema or tuple)\n * - `allOf`, `anyOf`, `oneOf` branches\n * - `not`\n * - `definitions` / `$defs` values\n *\n * A `Set<object>` is used to track visited schemas and prevent infinite loops\n * from circular structures.\n *\n * @param schema - The JSON Schema to validate\n * @param path - The current JSON pointer path (for error reporting)\n * @param visited - Set of already-visited schema objects (cycle protection)\n *\n * @throws {UnsupportedSchemaError} if `if`, `then`, or `else` is found\n *\n * @example\n * ```\n * // Throws UnsupportedSchemaError:\n * assertNoConditionalSchema({\n * type: \"object\",\n * if: { properties: { kind: { const: \"a\" } } },\n * then: { properties: { a: { type: \"string\" } } },\n * });\n *\n * // OK — no conditional keywords:\n * assertNoConditionalSchema({\n * type: \"object\",\n * properties: { name: { type: \"string\" } },\n * });\n * ```\n */\nexport function assertNoConditionalSchema(\n\tschema: JSONSchema7,\n\tpath = \"\",\n\tvisited: Set<object> = new Set(),\n): void {\n\t// Cycle protection — avoid infinite loops on circular schema structures\n\tif (visited.has(schema)) return;\n\tvisited.add(schema);\n\n\t// ── Detect if/then/else at the current level ─────────────────────────\n\tif (schema.if !== undefined) {\n\t\tthrow new UnsupportedSchemaError(\"if/then/else\", path || \"/\");\n\t}\n\t// `then` or `else` without `if` is unusual but still unsupported\n\tif (schema.then !== undefined) {\n\t\tthrow new UnsupportedSchemaError(\"if/then/else\", path || \"/\");\n\t}\n\tif (schema.else !== undefined) {\n\t\tthrow new UnsupportedSchemaError(\"if/then/else\", path || \"/\");\n\t}\n\n\t// ── Recurse into properties ──────────────────────────────────────────\n\tif (schema.properties) {\n\t\tfor (const [key, prop] of Object.entries(schema.properties)) {\n\t\t\tif (prop && typeof prop !== \"boolean\") {\n\t\t\t\tassertNoConditionalSchema(prop, `${path}/properties/${key}`, visited);\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── Recurse into additionalProperties ────────────────────────────────\n\tif (\n\t\tschema.additionalProperties &&\n\t\ttypeof schema.additionalProperties === \"object\"\n\t) {\n\t\tassertNoConditionalSchema(\n\t\t\tschema.additionalProperties,\n\t\t\t`${path}/additionalProperties`,\n\t\t\tvisited,\n\t\t);\n\t}\n\n\t// ── Recurse into items ───────────────────────────────────────────────\n\tif (schema.items) {\n\t\tif (Array.isArray(schema.items)) {\n\t\t\tfor (let i = 0; i < schema.items.length; i++) {\n\t\t\t\tconst item = schema.items[i];\n\t\t\t\tif (item && typeof item !== \"boolean\") {\n\t\t\t\t\tassertNoConditionalSchema(item, `${path}/items/${i}`, visited);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (typeof schema.items !== \"boolean\") {\n\t\t\tassertNoConditionalSchema(schema.items, `${path}/items`, visited);\n\t\t}\n\t}\n\n\t// ── Recurse into combinators ─────────────────────────────────────────\n\tfor (const keyword of [\"allOf\", \"anyOf\", \"oneOf\"] as const) {\n\t\tconst branches = schema[keyword];\n\t\tif (branches) {\n\t\t\tfor (let i = 0; i < branches.length; i++) {\n\t\t\t\tconst branch = branches[i];\n\t\t\t\tif (branch && typeof branch !== \"boolean\") {\n\t\t\t\t\tassertNoConditionalSchema(branch, `${path}/${keyword}/${i}`, visited);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// ── Recurse into not ─────────────────────────────────────────────────\n\tif (schema.not && typeof schema.not !== \"boolean\") {\n\t\tassertNoConditionalSchema(schema.not, `${path}/not`, visited);\n\t}\n\n\t// ── Recurse into definitions / $defs ─────────────────────────────────\n\tfor (const defsKey of [\"definitions\", \"$defs\"] as const) {\n\t\tconst defs = schema[defsKey];\n\t\tif (defs) {\n\t\t\tfor (const [name, def] of Object.entries(defs)) {\n\t\t\t\tif (def && typeof def !== \"boolean\") {\n\t\t\t\t\tassertNoConditionalSchema(def, `${path}/${defsKey}/${name}`, visited);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n// ─── $ref Resolution ─────────────────────────────────────────────────────────\n// Only supports internal references in the format `#/definitions/Foo`\n// or `#/$defs/Foo` (JSON Schema Draft 2019+). Remote $refs (URLs) are\n// not supported — that is outside the scope of a template engine.\n\n/**\n * Recursively resolves `$ref` in a schema using the root schema as the\n * source of definitions.\n */\nexport function resolveRef(\n\tschema: JSONSchema7,\n\troot: JSONSchema7,\n): JSONSchema7 {\n\tif (!schema.$ref) return schema;\n\n\tconst ref = schema.$ref;\n\n\t// Expected format: #/definitions/Name or #/$defs/Name\n\tconst match = ref.match(/^#\\/(definitions|\\$defs)\\/(.+)$/);\n\tif (!match) {\n\t\tthrow new Error(\n\t\t\t`Unsupported $ref format: \"${ref}\". Only internal #/definitions/ references are supported.`,\n\t\t);\n\t}\n\n\tconst defsKey = match[1] as \"definitions\" | \"$defs\";\n\tconst name = match[2] ?? \"\";\n\n\tconst defs = defsKey === \"definitions\" ? root.definitions : root.$defs;\n\n\tif (!defs || !(name in defs)) {\n\t\tthrow new Error(\n\t\t\t`Cannot resolve $ref \"${ref}\": definition \"${name}\" not found.`,\n\t\t);\n\t}\n\n\t// Recursive resolution in case the definition itself contains a $ref\n\tconst def = defs[name];\n\tif (!def || typeof def === \"boolean\") {\n\t\tthrow new Error(\n\t\t\t`Cannot resolve $ref \"${ref}\": definition \"${name}\" not found.`,\n\t\t);\n\t}\n\treturn resolveRef(def, root);\n}\n\n// ─── Single-Segment Path Navigation ─────────────────────────────────────────\n\n/**\n * Resolves a single path segment (a property name) within a schema.\n * Returns the corresponding sub-schema, or `undefined` if the path is invalid.\n *\n * @param schema - The current schema (already resolved, no $ref)\n * @param segment - The property name to resolve\n * @param root - The root schema (for resolving any internal $refs)\n */\nfunction resolveSegment(\n\tschema: JSONSchema7,\n\tsegment: string,\n\troot: JSONSchema7,\n): JSONSchema7 | undefined {\n\tconst resolved = resolveRef(schema, root);\n\n\t// 1. Explicit properties\n\tif (resolved.properties && segment in resolved.properties) {\n\t\tconst prop = resolved.properties[segment];\n\t\tif (prop && typeof prop !== \"boolean\") return resolveRef(prop, root);\n\t\tif (prop === true) return {};\n\t}\n\n\t// 2. additionalProperties (when the property is not declared)\n\tif (\n\t\tresolved.additionalProperties !== undefined &&\n\t\tresolved.additionalProperties !== false\n\t) {\n\t\tif (resolved.additionalProperties === true) {\n\t\t\t// additionalProperties: true → type is unknown\n\t\t\treturn {};\n\t\t}\n\t\treturn resolveRef(resolved.additionalProperties, root);\n\t}\n\n\t// 3. Intrinsic array properties (e.g. `.length`)\n\tconst schemaType = resolved.type;\n\tconst isArray =\n\t\tschemaType === \"array\" ||\n\t\t(Array.isArray(schemaType) && schemaType.includes(\"array\"));\n\n\tif (isArray && segment === \"length\") {\n\t\treturn { type: \"integer\" };\n\t}\n\n\t// 4. Combinators — search within each branch\n\tconst combinatorResult = resolveInCombinators(resolved, segment, root);\n\tif (combinatorResult) return combinatorResult;\n\n\treturn undefined;\n}\n\n/**\n * Searches for a segment within `allOf`, `anyOf`, `oneOf` branches.\n * Returns the first matching sub-schema, or `undefined`.\n * For `allOf`, found results are merged into a single `allOf`.\n */\nfunction resolveInCombinators(\n\tschema: JSONSchema7,\n\tsegment: string,\n\troot: JSONSchema7,\n): JSONSchema7 | undefined {\n\t// allOf: the property can be defined in any branch, and all constraints\n\t// apply simultaneously.\n\tif (schema.allOf) {\n\t\tconst matches = schema.allOf\n\t\t\t.filter((b): b is JSONSchema7 => typeof b !== \"boolean\")\n\t\t\t.map((branch) => resolveSegment(branch, segment, root))\n\t\t\t.filter((s): s is JSONSchema7 => s !== undefined);\n\n\t\tif (matches.length === 1) return matches[0] as JSONSchema7;\n\t\tif (matches.length > 1) return { allOf: matches };\n\t}\n\n\t// anyOf / oneOf: the property can come from any branch.\n\tfor (const key of [\"anyOf\", \"oneOf\"] as const) {\n\t\tif (!schema[key]) continue;\n\t\tconst matches = schema[key]\n\t\t\t.filter((b): b is JSONSchema7 => typeof b !== \"boolean\")\n\t\t\t.map((branch) => resolveSegment(branch, segment, root))\n\t\t\t.filter((s): s is JSONSchema7 => s !== undefined);\n\n\t\tif (matches.length === 1) return matches[0] as JSONSchema7;\n\t\tif (matches.length > 1) return { [key]: matches };\n\t}\n\n\treturn undefined;\n}\n\n// ─── Public API ──────────────────────────────────────────────────────────────\n\n/**\n * Resolves a full path (e.g. [\"user\", \"address\", \"city\"]) within a JSON\n * Schema and returns the corresponding sub-schema.\n *\n * @param schema - The root schema describing the template context\n * @param path - Array of segments (property names)\n * @returns The sub-schema at the end of the path, or `undefined` if the path\n * cannot be resolved.\n *\n * @example\n * ```\n * const schema = {\n * type: \"object\",\n * properties: {\n * user: {\n * type: \"object\",\n * properties: {\n * name: { type: \"string\" }\n * }\n * }\n * }\n * };\n * resolveSchemaPath(schema, [\"user\", \"name\"]);\n * // → { type: \"string\" }\n * ```\n */\nexport function resolveSchemaPath(\n\tschema: JSONSchema7,\n\tpath: string[],\n): JSONSchema7 | undefined {\n\tif (path.length === 0) return resolveRef(schema, schema);\n\n\tlet current: JSONSchema7 = resolveRef(schema, schema);\n\tconst root = schema;\n\n\tfor (const segment of path) {\n\t\tconst next = resolveSegment(current, segment, root);\n\t\tif (next === undefined) return undefined;\n\t\tcurrent = next;\n\t}\n\n\treturn current;\n}\n\n/**\n * Resolves the item schema of an array.\n * If the schema is not of type `array` or has no `items`, returns `undefined`.\n *\n * @param schema - The array schema\n * @param root - The root schema (for resolving $refs)\n */\nexport function resolveArrayItems(\n\tschema: JSONSchema7,\n\troot: JSONSchema7,\n): JSONSchema7 | undefined {\n\tconst resolved = resolveRef(schema, root);\n\n\t// Verify that it's actually an array\n\tconst schemaType = resolved.type;\n\tconst isArray =\n\t\tschemaType === \"array\" ||\n\t\t(Array.isArray(schemaType) && schemaType.includes(\"array\"));\n\n\tif (!isArray && resolved.items === undefined) {\n\t\treturn undefined;\n\t}\n\n\tif (resolved.items === undefined) {\n\t\t// array without items → element type is unknown\n\t\treturn {};\n\t}\n\n\t// items can be a boolean (true = anything, false = nothing)\n\tif (typeof resolved.items === \"boolean\") {\n\t\treturn {};\n\t}\n\n\t// items can be a single schema or a tuple (array of schemas).\n\t// For template loops, we handle the single-schema case.\n\tif (Array.isArray(resolved.items)) {\n\t\t// Tuple: create a oneOf of all possible types\n\t\tconst schemas = resolved.items\n\t\t\t.filter((item): item is JSONSchema7 => typeof item !== \"boolean\")\n\t\t\t.map((item) => resolveRef(item, root));\n\t\tif (schemas.length === 0) return {};\n\t\treturn { oneOf: schemas };\n\t}\n\n\treturn resolveRef(resolved.items, root);\n}\n\n/**\n * Simplifies an output schema to avoid unnecessarily complex constructs\n * (e.g. `oneOf` with a single element, duplicates, etc.).\n *\n * Uses `deepEqual` for deduplication — more robust and performant than\n * `JSON.stringify` (independent of key order, no intermediate string\n * allocations).\n */\nexport function simplifySchema(schema: JSONSchema7): JSONSchema7 {\n\t// oneOf / anyOf with a single element → unwrap\n\tfor (const key of [\"oneOf\", \"anyOf\"] as const) {\n\t\tconst arr = schema[key];\n\t\tif (arr && arr.length === 1) {\n\t\t\tconst first = arr[0];\n\t\t\tif (first !== undefined && typeof first !== \"boolean\")\n\t\t\t\treturn simplifySchema(first);\n\t\t}\n\t}\n\n\t// allOf with a single element → unwrap\n\tif (schema.allOf && schema.allOf.length === 1) {\n\t\tconst first = schema.allOf[0];\n\t\tif (first !== undefined && typeof first !== \"boolean\")\n\t\t\treturn simplifySchema(first);\n\t}\n\n\t// Deduplicate identical entries in oneOf/anyOf\n\tfor (const key of [\"oneOf\", \"anyOf\"] as const) {\n\t\tconst arr = schema[key];\n\t\tif (arr && arr.length > 1) {\n\t\t\tconst unique: JSONSchema7[] = [];\n\t\t\tfor (const entry of arr) {\n\t\t\t\tif (typeof entry === \"boolean\") continue;\n\t\t\t\t// Use deepEqual instead of JSON.stringify for structural\n\t\t\t\t// comparison — more robust (key order independent) and\n\t\t\t\t// more performant (no string allocations).\n\t\t\t\tconst isDuplicate = unique.some((existing) =>\n\t\t\t\t\tdeepEqual(existing, entry),\n\t\t\t\t);\n\t\t\t\tif (!isDuplicate) {\n\t\t\t\t\tunique.push(simplifySchema(entry));\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (unique.length === 1) return unique[0] as JSONSchema7;\n\t\t\treturn { ...schema, [key]: unique };\n\t\t}\n\t}\n\n\treturn schema;\n}\n"],"names":["UnsupportedSchemaError","deepEqual","assertNoConditionalSchema","schema","path","visited","Set","has","add","if","undefined","then","else","properties","Object","entries","key","prop","additionalProperties","items","Array","isArray","i","length","item","keyword","branches","branch","not","defsKey","defs","name","def","resolveRef","root","match","$ref","ref","Error","definitions","$defs","resolveSegment","segment","resolved","schemaType","type","includes","combinatorResult","resolveInCombinators","allOf","matches","filter","b","map","s","resolveSchemaPath","current","next","resolveArrayItems","schemas","oneOf","simplifySchema","arr","first","unique","entry","isDuplicate","some","existing","push"],"mappings":"ssFACA,OAASA,sBAAsB,KAAQ,UAAW,AAClD,QAASC,SAAS,KAAQ,SAAU,AA4DpC,QAAO,SAASC,0BACfC,MAAmB,MACnBC,KAAAA,uDAAO,GACPC,QAAAA,uDAAuB,IAAIC,IAG3B,GAAID,QAAQE,GAAG,CAACJ,QAAS,OACzBE,QAAQG,GAAG,CAACL,QAGZ,GAAIA,OAAOM,EAAE,GAAKC,UAAW,CAC5B,MAAM,IAAIV,uBAAuB,eAAgBI,MAAQ,IAC1D,CAEA,GAAID,OAAOQ,IAAI,GAAKD,UAAW,CAC9B,MAAM,IAAIV,uBAAuB,eAAgBI,MAAQ,IAC1D,CACA,GAAID,OAAOS,IAAI,GAAKF,UAAW,CAC9B,MAAM,IAAIV,uBAAuB,eAAgBI,MAAQ,IAC1D,CAGA,GAAID,OAAOU,UAAU,CAAE,KACjB,+BAAA,wBAAA,6BAAL,QAAK,UAAqBC,OAAOC,OAAO,CAACZ,OAAOU,UAAU,qBAArD,QAAA,2BAAA,MAAA,wBAAA,+BAAwD,CAAxD,iCAAA,eAAOG,mBAAKC,oBAChB,GAAIA,MAAQ,OAAOA,OAAS,UAAW,CACtCf,0BAA0Be,KAAM,AAAC,GAAqBD,OAAnBZ,KAAK,gBAAkB,OAAJY,KAAOX,QAC9D,CACD,aAJK,uBAAA,mCAAA,2BAAA,wBAAA,+BAAA,yBAAA,iBAKN,CAGA,GACCF,OAAOe,oBAAoB,EAC3B,SAAOf,OAAOe,oBAAoB,IAAK,SACtC,CACDhB,0BACCC,OAAOe,oBAAoB,CAC3B,AAAC,GAAO,OAALd,KAAK,yBACRC,QAEF,CAGA,GAAIF,OAAOgB,KAAK,CAAE,CACjB,GAAIC,MAAMC,OAAO,CAAClB,OAAOgB,KAAK,EAAG,CAChC,IAAK,IAAIG,EAAI,EAAGA,EAAInB,OAAOgB,KAAK,CAACI,MAAM,CAAED,IAAK,CAC7C,IAAME,KAAOrB,OAAOgB,KAAK,CAACG,EAAE,CAC5B,GAAIE,MAAQ,OAAOA,OAAS,UAAW,CACtCtB,0BAA0BsB,KAAM,AAAC,GAAgBF,OAAdlB,KAAK,WAAW,OAAFkB,GAAKjB,QACvD,CACD,CACD,MAAO,GAAI,OAAOF,OAAOgB,KAAK,GAAK,UAAW,CAC7CjB,0BAA0BC,OAAOgB,KAAK,CAAE,AAAC,GAAO,OAALf,KAAK,UAASC,QAC1D,CACD,CAGA,aAAsB,MAAA,CAAC,QAAS,QAAS,QAAQ,IAA3B,kBAAsC,KAAjDoB,QAAW,UACrB,IAAMC,SAAWvB,MAAM,CAACsB,QAAQ,CAChC,GAAIC,SAAU,CACb,IAAK,IAAIJ,GAAI,EAAGA,GAAII,SAASH,MAAM,CAAED,KAAK,CACzC,IAAMK,OAASD,QAAQ,CAACJ,GAAE,CAC1B,GAAIK,QAAU,OAAOA,SAAW,UAAW,CAC1CzB,0BAA0ByB,OAAQ,AAAC,GAAUF,OAARrB,KAAK,KAAckB,OAAXG,QAAQ,KAAK,OAAFH,IAAKjB,QAC9D,CACD,CACD,CACD,CAGA,GAAIF,OAAOyB,GAAG,EAAI,OAAOzB,OAAOyB,GAAG,GAAK,UAAW,CAClD1B,0BAA0BC,OAAOyB,GAAG,CAAE,AAAC,GAAO,OAALxB,KAAK,QAAOC,QACtD,CAGA,cAAsB,OAAA,CAAC,cAAe,QAAQ,KAAxB,oBAAmC,KAA9CwB,QAAW,YACrB,IAAMC,KAAO3B,MAAM,CAAC0B,QAAQ,CAC5B,GAAIC,KAAM,KACJ,gCAAA,yBAAA,8BAAL,QAAK,WAAqBhB,OAAOC,OAAO,CAACe,yBAApC,SAAA,4BAAA,OAAA,yBAAA,gCAA2C,CAA3C,kCAAA,gBAAOC,qBAAMC,oBACjB,GAAIA,KAAO,OAAOA,MAAQ,UAAW,CACpC9B,0BAA0B8B,IAAK,AAAC,GAAUH,OAARzB,KAAK,KAAc2B,OAAXF,QAAQ,KAAQ,OAALE,MAAQ1B,QAC9D,CACD,aAJK,wBAAA,oCAAA,4BAAA,yBAAA,gCAAA,0BAAA,kBAKN,CACD,CACD,CAWA,OAAO,SAAS4B,WACf9B,MAAmB,CACnB+B,IAAiB,MAeJC,QAbb,GAAI,CAAChC,OAAOiC,IAAI,CAAE,OAAOjC,OAEzB,IAAMkC,IAAMlC,OAAOiC,IAAI,CAGvB,IAAMD,MAAQE,IAAIF,KAAK,CAAC,mCACxB,GAAI,CAACA,MAAO,CACX,MAAM,IAAIG,MACT,AAAC,6BAAgC,OAAJD,IAAI,6DAEnC,CAEA,IAAMR,QAAUM,KAAK,CAAC,EAAE,CACxB,IAAMJ,MAAOI,QAAAA,KAAK,CAAC,EAAE,UAARA,iBAAAA,QAAY,GAEzB,IAAML,KAAOD,UAAY,cAAgBK,KAAKK,WAAW,CAAGL,KAAKM,KAAK,CAEtE,GAAI,CAACV,MAAQ,CAAEC,CAAAA,QAAQD,IAAG,EAAI,CAC7B,MAAM,IAAIQ,MACT,AAAC,wBAA4CP,OAArBM,IAAI,mBAAsB,OAALN,KAAK,gBAEpD,CAGA,IAAMC,IAAMF,IAAI,CAACC,KAAK,CACtB,GAAI,CAACC,KAAO,OAAOA,MAAQ,UAAW,CACrC,MAAM,IAAIM,MACT,AAAC,wBAA4CP,OAArBM,IAAI,mBAAsB,OAALN,KAAK,gBAEpD,CACA,OAAOE,WAAWD,IAAKE,KACxB,CAYA,SAASO,eACRtC,MAAmB,CACnBuC,OAAe,CACfR,IAAiB,EAEjB,IAAMS,SAAWV,WAAW9B,OAAQ+B,MAGpC,GAAIS,SAAS9B,UAAU,EAAI6B,WAAWC,SAAS9B,UAAU,CAAE,CAC1D,IAAMI,KAAO0B,SAAS9B,UAAU,CAAC6B,QAAQ,CACzC,GAAIzB,MAAQ,OAAOA,OAAS,UAAW,OAAOgB,WAAWhB,KAAMiB,MAC/D,GAAIjB,OAAS,KAAM,MAAO,CAAC,CAC5B,CAGA,GACC0B,SAASzB,oBAAoB,GAAKR,WAClCiC,SAASzB,oBAAoB,GAAK,MACjC,CACD,GAAIyB,SAASzB,oBAAoB,GAAK,KAAM,CAE3C,MAAO,CAAC,CACT,CACA,OAAOe,WAAWU,SAASzB,oBAAoB,CAAEgB,KAClD,CAGA,IAAMU,WAAaD,SAASE,IAAI,CAChC,IAAMxB,QACLuB,aAAe,SACdxB,MAAMC,OAAO,CAACuB,aAAeA,WAAWE,QAAQ,CAAC,SAEnD,GAAIzB,SAAWqB,UAAY,SAAU,CACpC,MAAO,CAAEG,KAAM,SAAU,CAC1B,CAGA,IAAME,iBAAmBC,qBAAqBL,SAAUD,QAASR,MACjE,GAAIa,iBAAkB,OAAOA,iBAE7B,OAAOrC,SACR,CAOA,SAASsC,qBACR7C,MAAmB,CACnBuC,OAAe,CACfR,IAAiB,EAIjB,GAAI/B,OAAO8C,KAAK,CAAE,CACjB,IAAMC,QAAU/C,OAAO8C,KAAK,CAC1BE,MAAM,CAAC,SAACC,UAAwB,OAAOA,IAAM,YAC7CC,GAAG,CAAC,SAAC1B,eAAWc,eAAed,OAAQe,QAASR,QAChDiB,MAAM,CAAC,SAACG,UAAwBA,IAAM5C,YAExC,GAAIwC,QAAQ3B,MAAM,GAAK,EAAG,OAAO2B,OAAO,CAAC,EAAE,CAC3C,GAAIA,QAAQ3B,MAAM,CAAG,EAAG,MAAO,CAAE0B,MAAOC,OAAQ,CACjD,CAGA,aAAkB,MAAA,CAAC,QAAS,QAAQ,IAAlB,kBAA6B,KAApClC,IAAO,UACjB,GAAI,CAACb,MAAM,CAACa,IAAI,CAAE,SAClB,IAAMkC,SAAU/C,MAAM,CAACa,IAAI,CACzBmC,MAAM,CAAC,SAACC,UAAwB,OAAOA,IAAM,YAC7CC,GAAG,CAAC,SAAC1B,eAAWc,eAAed,OAAQe,QAASR,QAChDiB,MAAM,CAAC,SAACG,UAAwBA,IAAM5C,YAExC,GAAIwC,SAAQ3B,MAAM,GAAK,EAAG,OAAO2B,QAAO,CAAC,EAAE,CAC3C,GAAIA,SAAQ3B,MAAM,CAAG,EAAG,OAAS,oBAACP,IAAMkC,SACzC,CAEA,OAAOxC,SACR,CA8BA,OAAO,SAAS6C,kBACfpD,MAAmB,CACnBC,IAAc,EAEd,GAAIA,KAAKmB,MAAM,GAAK,EAAG,OAAOU,WAAW9B,OAAQA,QAEjD,IAAIqD,QAAuBvB,WAAW9B,OAAQA,QAC9C,IAAM+B,KAAO/B,WAER,+BAAA,wBAAA,6BAAL,QAAK,UAAiBC,wBAAjB,QAAA,2BAAA,MAAA,wBAAA,+BAAuB,CAAvB,IAAMsC,QAAN,YACJ,IAAMe,KAAOhB,eAAee,QAASd,QAASR,MAC9C,GAAIuB,OAAS/C,UAAW,OAAOA,UAC/B8C,QAAUC,IACX,aAJK,uBAAA,mCAAA,2BAAA,wBAAA,+BAAA,yBAAA,iBAML,OAAOD,OACR,CASA,OAAO,SAASE,kBACfvD,MAAmB,CACnB+B,IAAiB,EAEjB,IAAMS,SAAWV,WAAW9B,OAAQ+B,MAGpC,IAAMU,WAAaD,SAASE,IAAI,CAChC,IAAMxB,QACLuB,aAAe,SACdxB,MAAMC,OAAO,CAACuB,aAAeA,WAAWE,QAAQ,CAAC,SAEnD,GAAI,CAACzB,SAAWsB,SAASxB,KAAK,GAAKT,UAAW,CAC7C,OAAOA,SACR,CAEA,GAAIiC,SAASxB,KAAK,GAAKT,UAAW,CAEjC,MAAO,CAAC,CACT,CAGA,GAAI,OAAOiC,SAASxB,KAAK,GAAK,UAAW,CACxC,MAAO,CAAC,CACT,CAIA,GAAIC,MAAMC,OAAO,CAACsB,SAASxB,KAAK,EAAG,CAElC,IAAMwC,QAAUhB,SAASxB,KAAK,CAC5BgC,MAAM,CAAC,SAAC3B,aAA8B,OAAOA,OAAS,YACtD6B,GAAG,CAAC,SAAC7B,aAASS,WAAWT,KAAMU,QACjC,GAAIyB,QAAQpC,MAAM,GAAK,EAAG,MAAO,CAAC,EAClC,MAAO,CAAEqC,MAAOD,OAAQ,CACzB,CAEA,OAAO1B,WAAWU,SAASxB,KAAK,CAAEe,KACnC,CAUA,OAAO,SAAS2B,eAAe1D,MAAmB,EAEjD,aAAkB,MAAA,CAAC,QAAS,QAAQ,IAAlB,kBAA6B,KAApCa,IAAO,UACjB,IAAM8C,IAAM3D,MAAM,CAACa,IAAI,CACvB,GAAI8C,KAAOA,IAAIvC,MAAM,GAAK,EAAG,CAC5B,IAAMwC,MAAQD,GAAG,CAAC,EAAE,CACpB,GAAIC,QAAUrD,WAAa,OAAOqD,QAAU,UAC3C,OAAOF,eAAeE,MACxB,CACD,CAGA,GAAI5D,OAAO8C,KAAK,EAAI9C,OAAO8C,KAAK,CAAC1B,MAAM,GAAK,EAAG,CAC9C,IAAMwC,OAAQ5D,OAAO8C,KAAK,CAAC,EAAE,CAC7B,GAAIc,SAAUrD,WAAa,OAAOqD,SAAU,UAC3C,OAAOF,eAAeE,OACxB,CAGA,cAAkB,OAAA,CAAC,QAAS,QAAQ,KAAlB,oBAA6B,KAApC/C,KAAO,YACjB,IAAM8C,KAAM3D,MAAM,CAACa,KAAI,CACvB,GAAI8C,MAAOA,KAAIvC,MAAM,CAAG,EAAG,CAC1B,IAAMyC,OAAwB,EAAE,KAC3B,+BAAA,wBAAA,kDAAA,IAAMC,MAAN,YACJ,GAAI,OAAOA,QAAU,UAAW,MAAA,WAIhC,IAAMC,YAAcF,OAAOG,IAAI,CAAC,SAACC,iBAChCnE,UAAUmE,SAAUH,SAErB,GAAI,CAACC,YAAa,CACjBF,OAAOK,IAAI,CAACR,eAAeI,OAC5B,CACD,EAXA,QAAK,UAAeH,wBAAf,QAAA,2BAAA,MAAA,wBAAA,kDAAA,uBAAA,mCAAA,2BAAA,wBAAA,+BAAA,yBAAA,iBAYL,GAAIE,OAAOzC,MAAM,GAAK,EAAG,OAAOyC,MAAM,CAAC,EAAE,CACzC,OAAO,uCAAK7D,QAAQ,oBAACa,KAAMgD,QAC5B,CACD,CAEA,OAAO7D,MACR"}
|
package/dist/typebars.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { JSONSchema7 } from "json-schema";
|
|
2
|
-
import { CompiledTemplate } from "./compiled-template
|
|
3
|
-
import type { AnalysisResult, AnalyzeAndExecuteOptions, ExecuteOptions, HelperDefinition, TemplateEngineOptions, TemplateInput, ValidationResult } from "./types
|
|
2
|
+
import { CompiledTemplate } from "./compiled-template";
|
|
3
|
+
import type { AnalysisResult, AnalyzeAndExecuteOptions, ExecuteOptions, HelperDefinition, TemplateEngineOptions, TemplateInput, ValidationResult } from "./types";
|
|
4
4
|
export declare class Typebars {
|
|
5
5
|
/** Isolated Handlebars environment — each engine has its own helpers */
|
|
6
6
|
private readonly hbs;
|
package/dist/typebars.js
CHANGED
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
import{a}from"./chunk-xd2vmd03.js";import"./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 Typebars};
|
|
2
|
-
|
|
3
|
-
//# debugId=AADE9F1482151B2C64756E2164756E21
|
|
4
|
-
//# sourceMappingURL=typebars.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 _object_without_properties(source,excluded){if(source==null)return{};var target={},sourceKeys,key,i;if(typeof Reflect!=="undefined"&&Reflect.ownKeys){sourceKeys=Reflect.ownKeys(Object(source));for(i=0;i<sourceKeys.length;i++){key=sourceKeys[i];if(excluded.indexOf(key)>=0)continue;if(!Object.prototype.propertyIsEnumerable.call(source,key))continue;target[key]=source[key]}return target}target=_object_without_properties_loose(source,excluded);if(Object.getOwnPropertySymbols){sourceKeys=Object.getOwnPropertySymbols(source);for(i=0;i<sourceKeys.length;i++){key=sourceKeys[i];if(excluded.indexOf(key)>=0)continue;if(!Object.prototype.propertyIsEnumerable.call(source,key))continue;target[key]=source[key]}}return target}function _object_without_properties_loose(source,excluded){if(source==null)return{};var target={},sourceKeys=Object.getOwnPropertyNames(source),key,i;for(i=0;i<sourceKeys.length;i++){key=sourceKeys[i];if(excluded.indexOf(key)>=0)continue;if(!Object.prototype.propertyIsEnumerable.call(source,key))continue;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 _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{analyzeFromAst}from"./analyzer";import{CompiledTemplate}from"./compiled-template";import{TemplateAnalysisError}from"./errors";import{executeFromAst}from"./executor";import{LogicalHelpers,MathHelpers}from"./helpers/index";import{parse}from"./parser";import{inferPrimitiveSchema,isLiteralInput,isObjectInput}from"./types";import{aggregateObjectAnalysis,aggregateObjectAnalysisAndExecution,LRUCache}from"./utils";export var Typebars=/*#__PURE__*/function(){"use strict";function Typebars(){var options=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};_class_call_check(this,Typebars);var _options_astCacheSize,_options_compilationCacheSize;_define_property(this,"hbs",void 0);_define_property(this,"astCache",void 0);_define_property(this,"compilationCache",void 0);_define_property(this,"helpers",new Map);this.hbs=Handlebars.create();this.astCache=new LRUCache((_options_astCacheSize=options.astCacheSize)!==null&&_options_astCacheSize!==void 0?_options_astCacheSize:256);this.compilationCache=new LRUCache((_options_compilationCacheSize=options.compilationCacheSize)!==null&&_options_compilationCacheSize!==void 0?_options_compilationCacheSize:256);new MathHelpers().register(this);new LogicalHelpers().register(this);if(options.helpers){var _iteratorNormalCompletion=true,_didIteratorError=false,_iteratorError=undefined;try{for(var _iterator=options.helpers[Symbol.iterator](),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var helper=_step.value;var name=helper.name,definition=_object_without_properties(helper,["name"]);this.registerHelper(name,definition)}}catch(err){_didIteratorError=true;_iteratorError=err}finally{try{if(!_iteratorNormalCompletion&&_iterator.return!=null){_iterator.return()}}finally{if(_didIteratorError){throw _iteratorError}}}}}_create_class(Typebars,[{key:"compile",value:function compile(template){if(isObjectInput(template)){var children={};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];children[key]=this.compile(value)}}catch(err){_didIteratorError=true;_iteratorError=err}finally{try{if(!_iteratorNormalCompletion&&_iterator.return!=null){_iterator.return()}}finally{if(_didIteratorError){throw _iteratorError}}}return CompiledTemplate.fromObject(children,{helpers:this.helpers,hbs:this.hbs,compilationCache:this.compilationCache})}if(isLiteralInput(template)){return CompiledTemplate.fromLiteral(template,{helpers:this.helpers,hbs:this.hbs,compilationCache:this.compilationCache})}var ast=this.getCachedAst(template);var options={helpers:this.helpers,hbs:this.hbs,compilationCache:this.compilationCache};return CompiledTemplate.fromTemplate(ast,template,options)}},{key:"analyze",value:function analyze(template,inputSchema,identifierSchemas){var _this=this;if(isObjectInput(template)){return aggregateObjectAnalysis(Object.keys(template),function(key){return _this.analyze(template[key],inputSchema,identifierSchemas)})}if(isLiteralInput(template)){return{valid:true,diagnostics:[],outputSchema:inferPrimitiveSchema(template)}}var ast=this.getCachedAst(template);return analyzeFromAst(ast,template,inputSchema,{identifierSchemas:identifierSchemas,helpers:this.helpers})}},{key:"validate",value:function validate(template,inputSchema,identifierSchemas){var analysis=this.analyze(template,inputSchema,identifierSchemas);return{valid:analysis.valid,diagnostics:analysis.diagnostics}}},{key:"isValidSyntax",value:function isValidSyntax(template){var _this=this;if(isObjectInput(template)){return Object.values(template).every(function(v){return _this.isValidSyntax(v)})}if(isLiteralInput(template))return true;try{this.getCachedAst(template);return true}catch(unused){return false}}},{key:"execute",value:function execute(template,data,options){if(isObjectInput(template)){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]=this.execute(value,data,options)}}catch(err){_didIteratorError=true;_iteratorError=err}finally{try{if(!_iteratorNormalCompletion&&_iterator.return!=null){_iterator.return()}}finally{if(_didIteratorError){throw _iteratorError}}}return result}if(isLiteralInput(template))return template;var ast=this.getCachedAst(template);if(options===null||options===void 0?void 0:options.schema){var analysis=analyzeFromAst(ast,template,options.schema,{identifierSchemas:options.identifierSchemas,helpers:this.helpers});if(!analysis.valid){throw new TemplateAnalysisError(analysis.diagnostics)}}return executeFromAst(ast,template,data,{identifierData:options===null||options===void 0?void 0:options.identifierData,hbs:this.hbs,compilationCache:this.compilationCache})}},{key:"analyzeAndExecute",value:function analyzeAndExecute(template,inputSchema,data,options){var _this=this;if(isObjectInput(template)){return aggregateObjectAnalysisAndExecution(Object.keys(template),function(key){return _this.analyzeAndExecute(template[key],inputSchema,data,options)})}if(isLiteralInput(template)){return{analysis:{valid:true,diagnostics:[],outputSchema:inferPrimitiveSchema(template)},value:template}}var ast=this.getCachedAst(template);var analysis=analyzeFromAst(ast,template,inputSchema,{identifierSchemas:options===null||options===void 0?void 0:options.identifierSchemas,helpers:this.helpers});if(!analysis.valid){return{analysis:analysis,value:undefined}}var value=executeFromAst(ast,template,data,{identifierData:options===null||options===void 0?void 0:options.identifierData,hbs:this.hbs,compilationCache:this.compilationCache});return{analysis:analysis,value:value}}},{key:"registerHelper",value:function registerHelper(name,definition){this.helpers.set(name,definition);this.hbs.registerHelper(name,definition.fn);this.compilationCache.clear();return this}},{key:"unregisterHelper",value:function unregisterHelper(name){this.helpers.delete(name);this.hbs.unregisterHelper(name);this.compilationCache.clear();return this}},{key:"hasHelper",value:function hasHelper(name){return this.helpers.has(name)}},{key:"clearCaches",value:function clearCaches(){this.astCache.clear();this.compilationCache.clear()}},{key:"getCachedAst",value:function getCachedAst(template){var ast=this.astCache.get(template);if(!ast){ast=parse(template);this.astCache.set(template,ast)}return ast}}]);return Typebars}();
|
|
2
|
+
//# sourceMappingURL=typebars.js.map
|
package/dist/typebars.js.map
CHANGED
|
@@ -1,9 +1 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": [],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
],
|
|
6
|
-
"mappings": "",
|
|
7
|
-
"debugId": "AADE9F1482151B2C64756E2164756E21",
|
|
8
|
-
"names": []
|
|
9
|
-
}
|
|
1
|
+
{"version":3,"sources":["../src/typebars.ts"],"sourcesContent":["import Handlebars from \"handlebars\";\nimport type { JSONSchema7 } from \"json-schema\";\nimport { analyzeFromAst } from \"./analyzer\";\nimport {\n\tCompiledTemplate,\n\ttype CompiledTemplateOptions,\n} from \"./compiled-template\";\nimport { TemplateAnalysisError } from \"./errors\";\nimport { executeFromAst } from \"./executor\";\nimport { LogicalHelpers, MathHelpers } from \"./helpers/index\";\nimport { parse } from \"./parser\";\nimport type {\n\tAnalysisResult,\n\tAnalyzeAndExecuteOptions,\n\tExecuteOptions,\n\tHelperDefinition,\n\tTemplateEngineOptions,\n\tTemplateInput,\n\tValidationResult,\n} from \"./types\";\nimport { inferPrimitiveSchema, isLiteralInput, isObjectInput } from \"./types\";\nimport {\n\taggregateObjectAnalysis,\n\taggregateObjectAnalysisAndExecution,\n\tLRUCache,\n} from \"./utils\";\n\n// ─── Typebars ────────────────────────────────────────────────────────────────\n// Public entry point of the template engine. Orchestrates three phases:\n//\n// 1. **Parsing** — transforms the template string into an AST (via Handlebars)\n// 2. **Analysis** — static validation + return type inference\n// 3. **Execution** — renders the template with real data\n//\n// ─── Architecture v2 ─────────────────────────────────────────────────────────\n// - **LRU cache** for parsed ASTs and compiled Handlebars templates\n// - **Isolated Handlebars environment** per instance (custom helpers)\n// - **`compile()` pattern**: parse-once / execute-many\n// - **`validate()` method**: API shortcut without `outputSchema`\n// - **`registerHelper()`**: custom helpers with static typing\n// - **`ExecuteOptions`**: options object for `execute()`\n//\n// ─── Template Identifiers ────────────────────────────────────────────────────\n// The `{{key:N}}` syntax allows referencing variables from specific data\n// sources, identified by an integer N.\n//\n// - `identifierSchemas`: mapping `{ [id]: JSONSchema7 }` for static analysis\n// - `identifierData`: mapping `{ [id]: Record<string, unknown> }` for execution\n//\n// Usage:\n// engine.execute(\"{{meetingId:1}}\", data, { identifierData: { 1: node1Data } });\n// engine.analyze(\"{{meetingId:1}}\", schema, { 1: node1Schema });\n\n// ─── Main Class ──────────────────────────────────────────────────────────────\n\nexport class Typebars {\n\t/** Isolated Handlebars environment — each engine has its own helpers */\n\tprivate readonly hbs: typeof Handlebars;\n\n\t/** LRU cache of parsed ASTs (avoids re-parsing) */\n\tprivate readonly astCache: LRUCache<string, hbs.AST.Program>;\n\n\t/** LRU cache of compiled Handlebars templates (avoids recompilation) */\n\tprivate readonly compilationCache: LRUCache<\n\t\tstring,\n\t\tHandlebarsTemplateDelegate\n\t>;\n\n\t/** Custom helpers registered on this instance */\n\tprivate readonly helpers = new Map<string, HelperDefinition>();\n\n\tconstructor(options: TemplateEngineOptions = {}) {\n\t\tthis.hbs = Handlebars.create();\n\t\tthis.astCache = new LRUCache(options.astCacheSize ?? 256);\n\t\tthis.compilationCache = new LRUCache(options.compilationCacheSize ?? 256);\n\n\t\t// ── Built-in helpers ─────────────────────────────────────────────\n\t\tnew MathHelpers().register(this);\n\t\tnew LogicalHelpers().register(this);\n\n\t\t// ── Custom helpers via options ───────────────────────────────────\n\t\tif (options.helpers) {\n\t\t\tfor (const helper of options.helpers) {\n\t\t\t\tconst { name, ...definition } = helper;\n\t\t\t\tthis.registerHelper(name, definition);\n\t\t\t}\n\t\t}\n\t}\n\n\t// ─── Compilation ───────────────────────────────────────────────────────\n\n\t/**\n\t * Compiles a template and returns a `CompiledTemplate` ready to be\n\t * executed or analyzed without re-parsing.\n\t *\n\t * Accepts a `TemplateInput`: string, number, boolean, null, or object.\n\t * For objects, each property is compiled recursively.\n\t *\n\t * @param template - The template to compile\n\t * @returns A reusable `CompiledTemplate`\n\t */\n\tcompile(template: TemplateInput): CompiledTemplate {\n\t\tif (isObjectInput(template)) {\n\t\t\tconst children: Record<string, CompiledTemplate> = {};\n\t\t\tfor (const [key, value] of Object.entries(template)) {\n\t\t\t\tchildren[key] = this.compile(value);\n\t\t\t}\n\t\t\treturn CompiledTemplate.fromObject(children, {\n\t\t\t\thelpers: this.helpers,\n\t\t\t\thbs: this.hbs,\n\t\t\t\tcompilationCache: this.compilationCache,\n\t\t\t});\n\t\t}\n\t\tif (isLiteralInput(template)) {\n\t\t\treturn CompiledTemplate.fromLiteral(template, {\n\t\t\t\thelpers: this.helpers,\n\t\t\t\thbs: this.hbs,\n\t\t\t\tcompilationCache: this.compilationCache,\n\t\t\t});\n\t\t}\n\t\tconst ast = this.getCachedAst(template);\n\t\tconst options: CompiledTemplateOptions = {\n\t\t\thelpers: this.helpers,\n\t\t\thbs: this.hbs,\n\t\t\tcompilationCache: this.compilationCache,\n\t\t};\n\t\treturn CompiledTemplate.fromTemplate(ast, template, options);\n\t}\n\n\t// ─── Static Analysis ─────────────────────────────────────────────────────\n\n\t/**\n\t * Statically analyzes a template against a JSON Schema v7 describing\n\t * the available context.\n\t *\n\t * Accepts a `TemplateInput`: string, number, boolean, null, or object.\n\t * For objects, each property is analyzed recursively and the\n\t * `outputSchema` reflects the object structure with resolved types.\n\t *\n\t * @param template - The template to analyze\n\t * @param inputSchema - JSON Schema v7 describing the available variables\n\t * @param identifierSchemas - (optional) Schemas by identifier `{ [id]: JSONSchema7 }`\n\t */\n\tanalyze(\n\t\ttemplate: TemplateInput,\n\t\tinputSchema: JSONSchema7,\n\t\tidentifierSchemas?: Record<number, JSONSchema7>,\n\t): AnalysisResult {\n\t\tif (isObjectInput(template)) {\n\t\t\treturn aggregateObjectAnalysis(Object.keys(template), (key) =>\n\t\t\t\tthis.analyze(\n\t\t\t\t\ttemplate[key] as TemplateInput,\n\t\t\t\t\tinputSchema,\n\t\t\t\t\tidentifierSchemas,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\tif (isLiteralInput(template)) {\n\t\t\treturn {\n\t\t\t\tvalid: true,\n\t\t\t\tdiagnostics: [],\n\t\t\t\toutputSchema: inferPrimitiveSchema(template),\n\t\t\t};\n\t\t}\n\t\tconst ast = this.getCachedAst(template);\n\t\treturn analyzeFromAst(ast, template, inputSchema, {\n\t\t\tidentifierSchemas,\n\t\t\thelpers: this.helpers,\n\t\t});\n\t}\n\n\t// ─── Validation ──────────────────────────────────────────────────────────\n\n\t/**\n\t * Validates a template against a schema without returning the output type.\n\t *\n\t * This is an API shortcut for `analyze()` that only returns `valid` and\n\t * `diagnostics`, without `outputSchema`. The full analysis (including type\n\t * inference) is executed internally — this method provides no performance\n\t * gain, only a simplified API.\n\t *\n\t * @param template - The template to validate\n\t * @param inputSchema - JSON Schema v7 describing the available variables\n\t * @param identifierSchemas - (optional) Schemas by identifier\n\t */\n\tvalidate(\n\t\ttemplate: TemplateInput,\n\t\tinputSchema: JSONSchema7,\n\t\tidentifierSchemas?: Record<number, JSONSchema7>,\n\t): ValidationResult {\n\t\tconst analysis = this.analyze(template, inputSchema, identifierSchemas);\n\t\treturn {\n\t\t\tvalid: analysis.valid,\n\t\t\tdiagnostics: analysis.diagnostics,\n\t\t};\n\t}\n\n\t// ─── Syntax Validation ───────────────────────────────────────────────────\n\n\t/**\n\t * Checks only that the template syntax is valid (parsing).\n\t * Does not require a schema — useful for quick feedback in an editor.\n\t *\n\t * For objects, recursively checks each property.\n\t *\n\t * @param template - The template to validate\n\t * @returns `true` if the template is syntactically correct\n\t */\n\tisValidSyntax(template: TemplateInput): boolean {\n\t\tif (isObjectInput(template)) {\n\t\t\treturn Object.values(template).every((v) => this.isValidSyntax(v));\n\t\t}\n\t\tif (isLiteralInput(template)) return true;\n\t\ttry {\n\t\t\tthis.getCachedAst(template);\n\t\t\treturn true;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t// ─── Execution ───────────────────────────────────────────────────────────\n\n\t/**\n\t * Executes a template with the provided data.\n\t *\n\t * Accepts a `TemplateInput`: string, number, boolean, null, or object.\n\t * For objects, each property is executed recursively and an object with\n\t * resolved values is returned.\n\t *\n\t * If a `schema` is provided in options, static analysis is performed\n\t * before execution. A `TemplateAnalysisError` is thrown on errors.\n\t *\n\t * @param template - The template to execute\n\t * @param data - The context data for rendering\n\t * @param options - Execution options (schema, identifierData, identifierSchemas)\n\t * @returns The execution result\n\t */\n\texecute(\n\t\ttemplate: TemplateInput,\n\t\tdata: Record<string, unknown>,\n\t\toptions?: ExecuteOptions,\n\t): unknown {\n\t\t// ── Object template → recursive execution ────────────────────────────\n\t\tif (isObjectInput(template)) {\n\t\t\tconst result: Record<string, unknown> = {};\n\t\t\tfor (const [key, value] of Object.entries(template)) {\n\t\t\t\tresult[key] = this.execute(value, data, options);\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\t// ── Passthrough for literal values ────────────────────────────────────\n\t\tif (isLiteralInput(template)) return template;\n\n\t\t// ── Parse once ───────────────────────────────────────────────────────\n\t\tconst ast = this.getCachedAst(template);\n\n\t\t// ── Pre-execution static validation ──────────────────────────────────\n\t\tif (options?.schema) {\n\t\t\tconst analysis = analyzeFromAst(ast, template, options.schema, {\n\t\t\t\tidentifierSchemas: options.identifierSchemas,\n\t\t\t\thelpers: this.helpers,\n\t\t\t});\n\t\t\tif (!analysis.valid) {\n\t\t\t\tthrow new TemplateAnalysisError(analysis.diagnostics);\n\t\t\t}\n\t\t}\n\n\t\t// ── Execution ────────────────────────────────────────────────────────\n\t\treturn executeFromAst(ast, template, data, {\n\t\t\tidentifierData: options?.identifierData,\n\t\t\thbs: this.hbs,\n\t\t\tcompilationCache: this.compilationCache,\n\t\t});\n\t}\n\n\t// ─── Combined Shortcuts ──────────────────────────────────────────────────\n\n\t/**\n\t * Analyzes a template and, if valid, executes it with the provided data.\n\t * Returns both the analysis result and the executed value.\n\t *\n\t * For objects, each property is analyzed and executed recursively.\n\t * The entire object is considered invalid if at least one property is.\n\t *\n\t * @param template - The template\n\t * @param inputSchema - JSON Schema v7 describing the available variables\n\t * @param data - The context data for rendering\n\t * @param options - (optional) Options for template identifiers\n\t * @returns An object `{ analysis, value }` where `value` is `undefined`\n\t * if analysis failed.\n\t */\n\tanalyzeAndExecute(\n\t\ttemplate: TemplateInput,\n\t\tinputSchema: JSONSchema7,\n\t\tdata: Record<string, unknown>,\n\t\toptions?: AnalyzeAndExecuteOptions,\n\t): { analysis: AnalysisResult; value: unknown } {\n\t\tif (isObjectInput(template)) {\n\t\t\treturn aggregateObjectAnalysisAndExecution(Object.keys(template), (key) =>\n\t\t\t\tthis.analyzeAndExecute(\n\t\t\t\t\ttemplate[key] as TemplateInput,\n\t\t\t\t\tinputSchema,\n\t\t\t\t\tdata,\n\t\t\t\t\toptions,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tif (isLiteralInput(template)) {\n\t\t\treturn {\n\t\t\t\tanalysis: {\n\t\t\t\t\tvalid: true,\n\t\t\t\t\tdiagnostics: [],\n\t\t\t\t\toutputSchema: inferPrimitiveSchema(template),\n\t\t\t\t},\n\t\t\t\tvalue: template,\n\t\t\t};\n\t\t}\n\n\t\tconst ast = this.getCachedAst(template);\n\t\tconst analysis = analyzeFromAst(ast, template, inputSchema, {\n\t\t\tidentifierSchemas: options?.identifierSchemas,\n\t\t\thelpers: this.helpers,\n\t\t});\n\n\t\tif (!analysis.valid) {\n\t\t\treturn { analysis, value: undefined };\n\t\t}\n\n\t\tconst value = executeFromAst(ast, template, data, {\n\t\t\tidentifierData: options?.identifierData,\n\t\t\thbs: this.hbs,\n\t\t\tcompilationCache: this.compilationCache,\n\t\t});\n\t\treturn { analysis, value };\n\t}\n\n\t// ─── Custom Helper Management ──────────────────────────────────────────\n\n\t/**\n\t * Registers a custom helper on this engine instance.\n\t *\n\t * The helper is available for both execution (via Handlebars) and\n\t * static analysis (via its declared `returnType`).\n\t *\n\t * @param name - Helper name (e.g. `\"uppercase\"`)\n\t * @param definition - Helper definition (implementation + return type)\n\t * @returns `this` to allow chaining\n\t */\n\tregisterHelper(name: string, definition: HelperDefinition): this {\n\t\tthis.helpers.set(name, definition);\n\t\tthis.hbs.registerHelper(name, definition.fn);\n\n\t\t// Invalidate the compilation cache because helpers have changed\n\t\tthis.compilationCache.clear();\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Removes a custom helper from this engine instance.\n\t *\n\t * @param name - Name of the helper to remove\n\t * @returns `this` to allow chaining\n\t */\n\tunregisterHelper(name: string): this {\n\t\tthis.helpers.delete(name);\n\t\tthis.hbs.unregisterHelper(name);\n\n\t\t// Invalidate the compilation cache\n\t\tthis.compilationCache.clear();\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Checks whether a helper is registered on this instance.\n\t *\n\t * @param name - Helper name\n\t * @returns `true` if the helper is registered\n\t */\n\thasHelper(name: string): boolean {\n\t\treturn this.helpers.has(name);\n\t}\n\n\t// ─── Cache Management ──────────────────────────────────────────────────\n\n\t/**\n\t * Clears all internal caches (AST + compilation).\n\t *\n\t * Useful after a configuration change or to free memory.\n\t */\n\tclearCaches(): void {\n\t\tthis.astCache.clear();\n\t\tthis.compilationCache.clear();\n\t}\n\n\t// ─── Internals ─────────────────────────────────────────────────────────\n\n\t/**\n\t * Retrieves the AST of a template from the cache, or parses and caches it.\n\t */\n\tprivate getCachedAst(template: string): hbs.AST.Program {\n\t\tlet ast = this.astCache.get(template);\n\t\tif (!ast) {\n\t\t\tast = parse(template);\n\t\t\tthis.astCache.set(template, ast);\n\t\t}\n\t\treturn ast;\n\t}\n}\n"],"names":["Handlebars","analyzeFromAst","CompiledTemplate","TemplateAnalysisError","executeFromAst","LogicalHelpers","MathHelpers","parse","inferPrimitiveSchema","isLiteralInput","isObjectInput","aggregateObjectAnalysis","aggregateObjectAnalysisAndExecution","LRUCache","Typebars","options","hbs","astCache","compilationCache","helpers","Map","create","astCacheSize","compilationCacheSize","register","helper","name","definition","registerHelper","compile","template","children","Object","entries","key","value","fromObject","fromLiteral","ast","getCachedAst","fromTemplate","analyze","inputSchema","identifierSchemas","keys","valid","diagnostics","outputSchema","validate","analysis","isValidSyntax","values","every","v","execute","data","result","schema","identifierData","analyzeAndExecute","undefined","set","fn","clear","unregisterHelper","delete","hasHelper","has","clearCaches","get"],"mappings":"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"}
|
package/dist/types.js
CHANGED
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
//# debugId=9DCD2B51206A921264756E2164756E21
|
|
4
|
-
//# sourceMappingURL=types.js.map
|
|
1
|
+
function _type_of(obj){"@swc/helpers - typeof";return obj&&typeof Symbol!=="undefined"&&obj.constructor===Symbol?"symbol":typeof obj}export function isLiteralInput(input){return input===null||typeof input!=="string"&&(typeof input==="undefined"?"undefined":_type_of(input))!=="object"}export function isObjectInput(input){return input!==null&&(typeof input==="undefined"?"undefined":_type_of(input))==="object"}export function inferPrimitiveSchema(value){if(value===null)return{type:"null"};if(typeof value==="boolean")return{type:"boolean"};if(typeof value==="number"){return Number.isInteger(value)?{type:"integer"}:{type:"number"}}value;return{type:"null"}}export function defineHelper(config){return config}
|
|
2
|
+
//# sourceMappingURL=types.js.map
|
package/dist/types.js.map
CHANGED
|
@@ -1,9 +1 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": [],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
],
|
|
6
|
-
"mappings": "",
|
|
7
|
-
"debugId": "9DCD2B51206A921264756E2164756E21",
|
|
8
|
-
"names": []
|
|
9
|
-
}
|
|
1
|
+
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { JSONSchema7 } from \"json-schema\";\nimport type { FromSchema, JSONSchema } from \"json-schema-to-ts\";\n\n// ─── Template Input ──────────────────────────────────────────────────────────\n// The engine accepts primitive values in addition to template strings.\n// When a non-string value is passed, it is treated as a literal passthrough:\n// analysis returns the inferred type, and execution returns the value as-is.\n\n/**\n * Object where each property is a `TemplateInput` (recursive).\n *\n * Allows passing an entire structure as a template:\n * ```\n * engine.analyze({\n * userName: \"{{name}}\",\n * userAge: \"{{age}}\",\n * nested: { x: \"{{foo}}\" },\n * }, inputSchema);\n * ```\n */\nexport interface TemplateInputObject {\n\t[key: string]: TemplateInput;\n}\n\n/**\n * Input type accepted by the template engine.\n *\n * - `string` → standard Handlebars template (parsed and executed)\n * - `number` → numeric literal (passthrough)\n * - `boolean` → boolean literal (passthrough)\n * - `null` → null literal (passthrough)\n * - `TemplateInputObject` → object where each property is a `TemplateInput`\n */\nexport type TemplateInput =\n\t| string\n\t| number\n\t| boolean\n\t| null\n\t| TemplateInputObject;\n\n/**\n * Checks whether a value is a non-string primitive literal (number, boolean, null).\n * These values are treated as passthrough by the engine.\n *\n * Note: objects (`TemplateInputObject`) are NOT literals.\n */\nexport function isLiteralInput(\n\tinput: TemplateInput,\n): input is number | boolean | null {\n\treturn (\n\t\tinput === null || (typeof input !== \"string\" && typeof input !== \"object\")\n\t);\n}\n\n/**\n * Checks whether a value is a template object (`TemplateInputObject`).\n * Template objects are processed recursively by the engine:\n * each property is analyzed/executed individually.\n */\nexport function isObjectInput(\n\tinput: TemplateInput,\n): input is TemplateInputObject {\n\treturn input !== null && typeof input === \"object\";\n}\n\n/**\n * Infers the JSON Schema of a non-string primitive value.\n *\n * @param value - The primitive value (number, boolean, null)\n * @returns The corresponding JSON Schema\n *\n * @example\n * ```\n * inferPrimitiveSchema(42) // → { type: \"number\" }\n * inferPrimitiveSchema(true) // → { type: \"boolean\" }\n * inferPrimitiveSchema(null) // → { type: \"null\" }\n * ```\n */\nexport function inferPrimitiveSchema(\n\tvalue: number | boolean | null,\n): JSONSchema7 {\n\tif (value === null) return { type: \"null\" };\n\tif (typeof value === \"boolean\") return { type: \"boolean\" };\n\tif (typeof value === \"number\") {\n\t\treturn Number.isInteger(value) ? { type: \"integer\" } : { type: \"number\" };\n\t}\n\t// Exhaustiveness check — all branches are covered above.\n\t// If the type of `value` changes, TypeScript will raise an error here.\n\tvalue satisfies never;\n\treturn { type: \"null\" };\n}\n\n// ─── Diagnostic Codes ────────────────────────────────────────────────────────\n// Machine-readable codes for each error/warning type, enabling the frontend\n// to react programmatically without parsing the human-readable message.\n\nexport type DiagnosticCode =\n\t/** The referenced property does not exist in the context schema */\n\t| \"UNKNOWN_PROPERTY\"\n\t/** Type mismatch (e.g. #each on a non-array) */\n\t| \"TYPE_MISMATCH\"\n\t/** A block helper is used without a required argument */\n\t| \"MISSING_ARGUMENT\"\n\t/** Unknown block helper (neither built-in nor registered) */\n\t| \"UNKNOWN_HELPER\"\n\t/** The expression cannot be statically analyzed */\n\t| \"UNANALYZABLE\"\n\t/** The {{key:N}} syntax is used but no identifierSchemas were provided */\n\t| \"MISSING_IDENTIFIER_SCHEMAS\"\n\t/** The identifier N does not exist in the provided identifierSchemas */\n\t| \"UNKNOWN_IDENTIFIER\"\n\t/** The property does not exist in the identifier's schema */\n\t| \"IDENTIFIER_PROPERTY_NOT_FOUND\"\n\t/** Syntax error in the template */\n\t| \"PARSE_ERROR\";\n\n// ─── Diagnostic Details ──────────────────────────────────────────────────────\n// Supplementary information to understand the exact cause of the error.\n// Designed to be easily JSON-serializable and consumable by a frontend.\n\nexport interface DiagnosticDetails {\n\t/** Path of the expression that caused the error (e.g. `\"user.name.foo\"`) */\n\tpath?: string;\n\t/** Name of the helper involved (for helper-related errors) */\n\thelperName?: string;\n\t/** What was expected (e.g. `\"array\"`, `\"property to exist\"`) */\n\texpected?: string;\n\t/** What was found (e.g. `\"string\"`, `\"undefined\"`) */\n\tactual?: string;\n\t/** Available properties in the current schema (for suggestions) */\n\tavailableProperties?: string[];\n\t/** Template identifier number (for `{{key:N}}` errors) */\n\tidentifier?: number;\n}\n\n// ─── Static Analysis Result ──────────────────────────────────────────────────\n\n/** Diagnostic produced by the static analyzer */\nexport interface TemplateDiagnostic {\n\t/** \"error\" blocks execution, \"warning\" is informational */\n\tseverity: \"error\" | \"warning\";\n\n\t/** Machine-readable code identifying the error type */\n\tcode: DiagnosticCode;\n\n\t/** Human-readable message describing the problem */\n\tmessage: string;\n\n\t/** Position in the template source (if available from the AST) */\n\tloc?: {\n\t\tstart: { line: number; column: number };\n\t\tend: { line: number; column: number };\n\t};\n\n\t/** Fragment of the template source around the error */\n\tsource?: string;\n\n\t/** Structured information for debugging and frontend display */\n\tdetails?: DiagnosticDetails;\n}\n\n/** Complete result of the static analysis */\nexport interface AnalysisResult {\n\t/** true if no errors (warnings are tolerated) */\n\tvalid: boolean;\n\t/** List of diagnostics (errors + warnings) */\n\tdiagnostics: TemplateDiagnostic[];\n\t/** JSON Schema describing the template's return type */\n\toutputSchema: JSONSchema7;\n}\n\n/** Lightweight validation result (without output type inference) */\nexport interface ValidationResult {\n\t/** true if no errors (warnings are tolerated) */\n\tvalid: boolean;\n\t/** List of diagnostics (errors + warnings) */\n\tdiagnostics: TemplateDiagnostic[];\n}\n\n// ─── Public Engine Options ───────────────────────────────────────────────────\n\nexport interface TemplateEngineOptions {\n\t/**\n\t * Capacity of the parsed AST cache. Each parsed template is cached\n\t * to avoid costly re-parsing on repeated calls.\n\t * @default 256\n\t */\n\tastCacheSize?: number;\n\n\t/**\n\t * Capacity of the compiled Handlebars template cache.\n\t * @default 256\n\t */\n\tcompilationCacheSize?: number;\n\n\t/**\n\t * Custom helpers to register during engine construction.\n\t *\n\t * Each entry describes a helper with its name, implementation,\n\t * expected parameters, and return type.\n\t *\n\t * @example\n\t * ```\n\t * const engine = new Typebars({\n\t * helpers: [\n\t * {\n\t * name: \"uppercase\",\n\t * description: \"Converts a string to uppercase\",\n\t * fn: (value: string) => String(value).toUpperCase(),\n\t * params: [\n\t * { name: \"value\", type: { type: \"string\" }, description: \"The string to convert\" },\n\t * ],\n\t * returnType: { type: \"string\" },\n\t * },\n\t * ],\n\t * });\n\t * ```\n\t */\n\thelpers?: HelperConfig[];\n}\n\n// ─── Execution Options ───────────────────────────────────────────────────────\n// Optional options object for `execute()`, replacing multiple positional\n// parameters for better ergonomics.\n\nexport interface ExecuteOptions {\n\t/** JSON Schema for pre-execution static validation */\n\tschema?: JSONSchema7;\n\t/** Data by identifier `{ [id]: { key: value } }` */\n\tidentifierData?: Record<number, Record<string, unknown>>;\n\t/** Schemas by identifier (for static validation with identifiers) */\n\tidentifierSchemas?: Record<number, JSONSchema7>;\n}\n\n// ─── Combined Analyze-and-Execute Options ────────────────────────────────────\n// Optional options object for `analyzeAndExecute()`, grouping parameters\n// related to template identifiers.\n\nexport interface AnalyzeAndExecuteOptions {\n\t/** Schemas by identifier `{ [id]: JSONSchema7 }` for static analysis */\n\tidentifierSchemas?: Record<number, JSONSchema7>;\n\t/** Data by identifier `{ [id]: { key: value } }` for execution */\n\tidentifierData?: Record<number, Record<string, unknown>>;\n}\n\n// ─── Custom Helpers ──────────────────────────────────────────────────────────\n// Allows registering custom helpers with their type signature for static\n// analysis support.\n\n/** Describes a parameter expected by a helper */\nexport interface HelperParam {\n\t/** Parameter name (for documentation / introspection) */\n\tname: string;\n\n\t/**\n\t * JSON Schema describing the expected type for this parameter.\n\t * Used for documentation and static validation.\n\t */\n\ttype?: JSONSchema7;\n\n\t/** Human-readable description of the parameter */\n\tdescription?: string;\n\n\t/**\n\t * Whether the parameter is optional.\n\t * @default false\n\t */\n\toptional?: boolean;\n}\n\n/**\n * Definition of a helper registerable via `registerHelper()`.\n *\n * Contains the runtime implementation and typing metadata\n * for static analysis.\n */\nexport interface HelperDefinition {\n\t/**\n\t * Runtime implementation of the helper — will be registered with Handlebars.\n\t *\n\t * For an inline helper `{{uppercase name}}`:\n\t * `(value: string) => string`\n\t *\n\t * For a block helper `{{#repeat count}}...{{/repeat}}`:\n\t * `function(this: any, count: number, options: Handlebars.HelperOptions) { ... }`\n\t */\n\t// biome-ignore lint/suspicious/noExplicitAny: Handlebars helper signatures are inherently dynamic\n\tfn: (...args: any[]) => unknown;\n\n\t/**\n\t * Parameters expected by the helper (for documentation and analysis).\n\t *\n\t * @example\n\t * ```\n\t * params: [\n\t * { name: \"value\", type: { type: \"number\" }, description: \"The value to round\" },\n\t * { name: \"precision\", type: { type: \"number\" }, description: \"Decimal places\", optional: true },\n\t * ]\n\t * ```\n\t */\n\tparams?: HelperParam[];\n\n\t/**\n\t * JSON Schema describing the helper's return type for static analysis.\n\t * @default { type: \"string\" }\n\t */\n\treturnType?: JSONSchema7;\n\n\t/** Human-readable description of the helper */\n\tdescription?: string;\n}\n\n/**\n * Full helper configuration for registration via the `Typebars({ helpers: [...] })`\n * constructor options.\n *\n * Extends `HelperDefinition` with a required `name`.\n *\n * @example\n * ```\n * const config: HelperConfig = {\n * name: \"round\",\n * description: \"Rounds a number to a given precision\",\n * fn: (value: number, precision?: number) => { ... },\n * params: [\n * { name: \"value\", type: { type: \"number\" } },\n * { name: \"precision\", type: { type: \"number\" }, optional: true },\n * ],\n * returnType: { type: \"number\" },\n * };\n * ```\n */\nexport interface HelperConfig extends HelperDefinition {\n\t/** Name of the helper as used in templates (e.g. `\"uppercase\"`) */\n\tname: string;\n}\n\n// ─── Automatic Type Inference via json-schema-to-ts ──────────────────────────\n// Allows `defineHelper()` to infer TypeScript types for `fn` arguments\n// from the JSON Schemas declared in `params`.\n\n/**\n * Param definition used for type inference.\n * Accepts `JSONSchema` from `json-schema-to-ts` to allow `FromSchema`\n * to resolve literal types.\n */\ntype TypedHelperParam = {\n\treadonly name: string;\n\treadonly type?: JSONSchema;\n\treadonly description?: string;\n\treadonly optional?: boolean;\n};\n\n/**\n * Infers the TypeScript type of a single parameter from its JSON Schema.\n * - If `optional: true`, the resolved type is unioned with `undefined`.\n * - If `type` is not provided, the type is `unknown`.\n */\ntype InferParamType<P> = P extends {\n\treadonly type: infer S extends JSONSchema;\n\treadonly optional: true;\n}\n\t? FromSchema<S> | undefined\n\t: P extends { readonly type: infer S extends JSONSchema }\n\t\t? FromSchema<S>\n\t\t: unknown;\n\n/**\n * Maps a tuple of `TypedHelperParam` to a tuple of inferred TypeScript types,\n * usable as the `fn` signature.\n *\n * @example\n * ```\n * type Args = InferArgs<readonly [\n * { name: \"a\"; type: { type: \"string\" } },\n * { name: \"b\"; type: { type: \"number\" }; optional: true },\n * ]>;\n * // => [string, number | undefined]\n * ```\n */\ntype InferArgs<P extends readonly TypedHelperParam[]> = {\n\t[K in keyof P]: InferParamType<P[K]>;\n};\n\n/**\n * Helper configuration with generic parameter inference.\n * Used exclusively by `defineHelper()`.\n */\ninterface TypedHelperConfig<P extends readonly TypedHelperParam[]> {\n\tname: string;\n\tdescription?: string;\n\tparams: P;\n\tfn: (...args: InferArgs<P>) => unknown;\n\treturnType?: JSONSchema;\n}\n\n/**\n * Creates a `HelperConfig` with automatic type inference for `fn` arguments\n * based on the JSON Schemas declared in `params`.\n *\n * The generic parameter `const P` preserves schema literal types\n * (equivalent of `as const`), enabling `FromSchema` to resolve the\n * corresponding TypeScript types.\n *\n * @example\n * ```\n * const helper = defineHelper({\n * name: \"concat\",\n * description: \"Concatenates two strings\",\n * params: [\n * { name: \"a\", type: { type: \"string\" }, description: \"First string\" },\n * { name: \"b\", type: { type: \"string\" }, description: \"Second string\" },\n * { name: \"sep\", type: { type: \"string\" }, description: \"Separator\", optional: true },\n * ],\n * fn: (a, b, sep) => {\n * // a: string, b: string, sep: string | undefined\n * const separator = sep ?? \"\";\n * return `${a}${separator}${b}`;\n * },\n * returnType: { type: \"string\" },\n * });\n * ```\n */\nexport function defineHelper<const P extends readonly TypedHelperParam[]>(\n\tconfig: TypedHelperConfig<P>,\n): HelperConfig {\n\treturn config as unknown as HelperConfig;\n}\n"],"names":["isLiteralInput","input","isObjectInput","inferPrimitiveSchema","value","type","Number","isInteger","defineHelper","config"],"mappings":"qIA8CA,OAAO,SAASA,eACfC,KAAoB,EAEpB,OACCA,QAAU,MAAS,OAAOA,QAAU,UAAY,CAAA,OAAOA,gCAAP,SAAOA,MAAI,IAAM,QAEnE,CAOA,OAAO,SAASC,cACfD,KAAoB,EAEpB,OAAOA,QAAU,MAAQ,CAAA,OAAOA,gCAAP,SAAOA,MAAI,IAAM,QAC3C,CAeA,OAAO,SAASE,qBACfC,KAA8B,EAE9B,GAAIA,QAAU,KAAM,MAAO,CAAEC,KAAM,MAAO,EAC1C,GAAI,OAAOD,QAAU,UAAW,MAAO,CAAEC,KAAM,SAAU,EACzD,GAAI,OAAOD,QAAU,SAAU,CAC9B,OAAOE,OAAOC,SAAS,CAACH,OAAS,CAAEC,KAAM,SAAU,EAAI,CAAEA,KAAM,QAAS,CACzE,CAGAD,MACA,MAAO,CAAEC,KAAM,MAAO,CACvB,CA6UA,OAAO,SAASG,aACfC,MAA4B,EAE5B,OAAOA,MACR"}
|
package/dist/utils.d.ts
CHANGED
package/dist/utils.js
CHANGED
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
//# debugId=6C8BFE07B8FFC81B64756E2164756E21
|
|
4
|
-
//# sourceMappingURL=utils.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_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 _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 _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)}export function deepEqual(a,b){if(a===b)return true;if(a===null||b===null)return false;if((typeof a==="undefined"?"undefined":_type_of(a))!==(typeof b==="undefined"?"undefined":_type_of(b)))return false;if(Array.isArray(a)){if(!Array.isArray(b))return false;if(a.length!==b.length)return false;for(var i=0;i<a.length;i++){if(!deepEqual(a[i],b[i]))return false}return true}if((typeof a==="undefined"?"undefined":_type_of(a))==="object"){var objA=a;var objB=b;var keysA=Object.keys(objA);var keysB=Object.keys(objB);if(keysA.length!==keysB.length)return false;var _iteratorNormalCompletion=true,_didIteratorError=false,_iteratorError=undefined;try{for(var _iterator=keysA[Symbol.iterator](),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var key=_step.value;if(!(key in objB)||!deepEqual(objA[key],objB[key]))return false}}catch(err){_didIteratorError=true;_iteratorError=err}finally{try{if(!_iteratorNormalCompletion&&_iterator.return!=null){_iterator.return()}}finally{if(_didIteratorError){throw _iteratorError}}}return true}return false}export var LRUCache=/*#__PURE__*/function(){"use strict";function LRUCache(capacity){_class_call_check(this,LRUCache);_define_property(this,"capacity",void 0);_define_property(this,"cache",void 0);this.capacity=capacity;this.cache=new Map;if(capacity<1){throw new Error("LRUCache capacity must be at least 1")}}_create_class(LRUCache,[{key:"get",value:function get(key){if(!this.cache.has(key))return undefined;var value=this.cache.get(key);this.cache.delete(key);this.cache.set(key,value);return value}},{key:"set",value:function set(key,value){if(this.cache.has(key)){this.cache.delete(key)}else if(this.cache.size>=this.capacity){var oldestKey=this.cache.keys().next().value;if(oldestKey!==undefined){this.cache.delete(oldestKey)}}this.cache.set(key,value)}},{key:"has",value:function has(key){return this.cache.has(key)}},{key:"delete",value:function _delete(key){return this.cache.delete(key)}},{key:"clear",value:function clear(){this.cache.clear()}},{key:"size",get:function get(){return this.cache.size}}]);return LRUCache}();export function extractSourceSnippet(template,loc){var lines=template.split("\n");var startLine=loc.start.line-1;var endLine=loc.end.line-1;if(startLine<0||startLine>=lines.length)return"";if(startLine===endLine){var _lines_startLine;var line=(_lines_startLine=lines[startLine])!==null&&_lines_startLine!==void 0?_lines_startLine:"";return line.trim()}var clampedEnd=Math.min(endLine,lines.length-1);return lines.slice(startLine,clampedEnd+1).map(function(l){return l.trimEnd()}).join("\n").trim()}export function getSchemaPropertyNames(schema){var names=new Set;if(schema.properties){var _iteratorNormalCompletion=true,_didIteratorError=false,_iteratorError=undefined;try{for(var _iterator=Object.keys(schema.properties)[Symbol.iterator](),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var key=_step.value;names.add(key)}}catch(err){_didIteratorError=true;_iteratorError=err}finally{try{if(!_iteratorNormalCompletion&&_iterator.return!=null){_iterator.return()}}finally{if(_didIteratorError){throw _iteratorError}}}}for(var _i=0,_iter=["allOf","anyOf","oneOf"];_i<_iter.length;_i++){var combinator=_iter[_i];var branches=schema[combinator];if(branches){var _iteratorNormalCompletion1=true,_didIteratorError1=false,_iteratorError1=undefined;try{for(var _iterator1=branches[Symbol.iterator](),_step1;!(_iteratorNormalCompletion1=(_step1=_iterator1.next()).done);_iteratorNormalCompletion1=true){var branch=_step1.value;if(typeof branch==="boolean")continue;if(branch.properties){var _iteratorNormalCompletion2=true,_didIteratorError2=false,_iteratorError2=undefined;try{for(var _iterator2=Object.keys(branch.properties)[Symbol.iterator](),_step2;!(_iteratorNormalCompletion2=(_step2=_iterator2.next()).done);_iteratorNormalCompletion2=true){var key1=_step2.value;names.add(key1)}}catch(err){_didIteratorError2=true;_iteratorError2=err}finally{try{if(!_iteratorNormalCompletion2&&_iterator2.return!=null){_iterator2.return()}}finally{if(_didIteratorError2){throw _iteratorError2}}}}}}catch(err){_didIteratorError1=true;_iteratorError1=err}finally{try{if(!_iteratorNormalCompletion1&&_iterator1.return!=null){_iterator1.return()}}finally{if(_didIteratorError1){throw _iteratorError1}}}}}return Array.from(names).sort()}export function aggregateObjectAnalysis(keys,analyzeEntry){var allDiagnostics=[];var properties={};var allValid=true;var _iteratorNormalCompletion=true,_didIteratorError=false,_iteratorError=undefined;try{for(var _iterator=keys[Symbol.iterator](),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var key=_step.value;var _allDiagnostics;var child=analyzeEntry(key);if(!child.valid)allValid=false;(_allDiagnostics=allDiagnostics).push.apply(_allDiagnostics,_to_consumable_array(child.diagnostics));properties[key]=child.outputSchema}}catch(err){_didIteratorError=true;_iteratorError=err}finally{try{if(!_iteratorNormalCompletion&&_iterator.return!=null){_iterator.return()}}finally{if(_didIteratorError){throw _iteratorError}}}return{valid:allValid,diagnostics:allDiagnostics,outputSchema:{type:"object",properties:properties,required:keys}}}export function aggregateObjectAnalysisAndExecution(keys,processEntry){var allDiagnostics=[];var properties={};var resultValues={};var allValid=true;var _iteratorNormalCompletion=true,_didIteratorError=false,_iteratorError=undefined;try{for(var _iterator=keys[Symbol.iterator](),_step;!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=true){var key=_step.value;var _allDiagnostics;var child=processEntry(key);if(!child.analysis.valid)allValid=false;(_allDiagnostics=allDiagnostics).push.apply(_allDiagnostics,_to_consumable_array(child.analysis.diagnostics));properties[key]=child.analysis.outputSchema;resultValues[key]=child.value}}catch(err){_didIteratorError=true;_iteratorError=err}finally{try{if(!_iteratorNormalCompletion&&_iterator.return!=null){_iterator.return()}}finally{if(_didIteratorError){throw _iteratorError}}}var analysis={valid:allValid,diagnostics:allDiagnostics,outputSchema:{type:"object",properties:properties,required:keys}};return{analysis:analysis,value:allValid?resultValues:undefined}}
|
|
2
|
+
//# sourceMappingURL=utils.js.map
|