UNPKG

jsoi-lib

Version:

A minimalistic, zero dependency javascript library that can perform string interpolation recursively over javascript objects preserving types. Great for dynamic configuration loading, supports asynchronous loading of objects with user-defined callbacks in

3 lines (2 loc) 23.8 kB
var JSOI=function(t){"use strict";class e extends Error{constructor(t){super(t)}}const s=Object.freeze({OPERAND_NUMBERS:"-*\\d+(\\.\\d*)*",OPERAND_STRING:"(?:'|\")[^'\"]*(?:'|\")",OPERAND_LOGICAL_TRUE:"true",OPERAND_LOGICAL_FALSE:"false",OPERAND_POS_INFINITY:"Infinity",OPERAND_NEG_INFINITY:"-Infinity",MATH_OPERATORS:"\\+|\\-|\\*|\\/|\\^|\\(|\\)",TERNARY_OPERATORS:"\\?|\\:",LOGICAL_OPERATORS:"\\|\\||&&|==|!=|!",EQUALITY_OPERATORS:">=|<=|>|<"});class r{constructor(){this._values=[]}get size(){return this._values.length}empty(){return 0===this.size}peek(){return this.empty()?void 0:this._values[this._values.length-1]}push(t){this._values.push(t)}pop(){return this.empty()?void 0:this._values.pop()}popN(t){const e=[];if(this.size>=t)for(let s=0;s<t;s++)e.unshift(this.pop());return e}}function n(t){const s=parseFloat(t);if(isNaN(s))throw new e(`Failed to convert ${t} to number`);return s}function i(t){if("true"===t||!0===t)return!0;if("false"===t||!1===t)return!1;throw new e(`Failed to convert ${t} to boolean`)}function o(t){try{return n(t)}catch(s){try{return i(t)}catch(s){return function(t){function s(t){return"'"===t||'"'===t}let r=t.trim();if(!(r.length>1))throw new e(`Failed to convert ${t} to number`);{const n=r[0],i=r[r.length-1];if(!s(n)&&!s(i))throw new e(`String expression ${t} must be enclosed in single quotes`)}return r}(t)}}}function a(t,s){const r=o(t),n=o(s);if(typeof r==typeof n)return[r,n];throw new e(`Cannot operate on parameters with different types ${t} <??> ${s}`)}const c={"?":{precedence:0,associativity:"R",NArgs:0,f:function(){throw new e("Ternary if mismatched")}},":":{precedence:0,associativity:"R",NArgs:2,f:function(){throw new e("Ternary else if mismatched")}},"?:":{precedence:1,associativity:"R",NArgs:3,f:function(t,e,s){return i(t)?o(e):o(s)}},"^":{precedence:2,associativity:"R",NArgs:2,f:function(t,e){return n(t)**n(e)}},"+":{precedence:4,associativity:"L",NArgs:2,f:function(t,e){return n(t)+n(e)}},"-":{precedence:4,associativity:"L",NArgs:2,f:function(t,e){return n(t)-n(e)}},"*":{precedence:3,associativity:"L",NArgs:2,f:function(t,e){return n(t)*n(e)}},"/":{precedence:3,associativity:"L",NArgs:2,f:function(t,e){return n(t)/n(e)}},"==":{precedence:7,associativity:"L",NArgs:2,f:function(t,e){const[s,r]=a(t,e);return s===r}},"!=":{precedence:7,associativity:"L",NArgs:2,f:function(t,e){const[s,r]=a(t,e);return s!==r}},"!":{precedence:2,associativity:"R",NArgs:1,f:function(t){return!i(t)}},"&&":{precedence:11,associativity:"L",NArgs:2,f:function(t,e){return i(t)&&i(e)}},"||":{precedence:12,associativity:"L",NArgs:2,f:function(t,e){return i(t)||i(e)}},">=":{precedence:6,associativity:"L",NArgs:2,f:function(t,e){return n(t)>=n(e)}},"<=":{precedence:6,associativity:"L",NArgs:2,f:function(t,e){return n(t)<=n(e)}},">":{precedence:6,associativity:"L",NArgs:2,f:function(t,e){return n(t)>n(e)}},"<":{precedence:6,associativity:"L",NArgs:2,f:function(t,e){return n(t)<n(e)}}},h=Object.keys(c);class l{constructor(t){this._expression=t,this._isOperand=new RegExp(`^${s.OPERAND_STRING}$|^${s.OPERAND_NUMBERS}$|^${s.OPERAND_LOGICAL_TRUE}$|^${s.OPERAND_LOGICAL_FALSE}$|^${s.OPERAND_POS_INFINITY}$|^${s.OPERAND_NEG_INFINITY}$`),this._regXParseExpression=new RegExp(`${s.OPERAND_STRING}|${s.OPERAND_LOGICAL_TRUE}|${s.OPERAND_LOGICAL_FALSE}|${s.OPERAND_POS_INFINITY}|${s.OPERAND_NEG_INFINITY}|${s.OPERAND_NUMBERS}|${s.MATH_OPERATORS}|${s.LOGICAL_OPERATORS}|${s.EQUALITY_OPERATORS}|${s.TERNARY_OPERATORS}`,"g")}isOperator(t){return h.includes(t)}getOperator(t){return c[t]}isAssociative(t,e){return this.getOperator(t).associativity===e}comparePrecedence(t,e){return this.getOperator(t).precedence-this.getOperator(e).precedence}hasHigherPrecedence(t,e){return this.comparePrecedence(t,e)<0}hasLowerPrecedence(t,e){return this.comparePrecedence(t,e)>0}hasSamePrecedence(t,e){return 0===this.comparePrecedence(t,e)}tokenize(){return this._expression.match(this._regXParseExpression)}isOperand(t){return this._isOperand.test(t)}toPostfix(){const t=[],s=this.tokenize();if(!Array.isArray(s))throw new e("Parsing expression resulted in an empty parse");{const n=new r;for(s.forEach((s=>{if(this.isOperand(s))t.push(s);else if("("===s)n.push(s);else if(")"===s){for(;n.size>0&&"("!==n.peek();)t.push(n.pop());if(!(n.size>0&&"("===n.peek()))throw new e("Missing open parenthesis in expression");n.pop()}else if(this.isOperator(s)){let r=n.peek();if(n.empty()||"("===r||"?"===s)n.push(s);else if(":"===s){let s=null;for(;!n.empty();){if(s=n.pop(),"?"===s){n.push("?:");break}t.push(s)}if("?"!==s)throw new e("Missing ternary ? symbol")}else if(this.hasHigherPrecedence(s,r)||this.hasSamePrecedence(s,r)&&this.isAssociative(s,"R"))n.push(s);else{for(;r&&"("!==r&&(this.hasLowerPrecedence(s,r)||this.hasSamePrecedence(s,r)&&this.isAssociative(s,"L"));)t.push(n.pop()),r=n.peek();n.push(s)}}}));n.size>0;){const s=n.pop();if("("===s)throw new e("Missing closing parenthesis in expression");t.push(s)}}return t}}class p extends l{constructor(t){super(t)}evaluate(){const t=this.toPostfix(),s=new r;for(let r=0;r<t.length;r++){const n=t[r];if(this.isOperator(n)){const t=this.getOperator(n);if(!(s.size>=t.NArgs))throw new e(`Not enough args for operator ${n}`);{const e=s.popN(t.NArgs),r=t.f(...e);s.push(r)}}else s.push(n)}if(1===s.size){let t=o(s.pop());return"string"==typeof t&&(t=(n=t).slice(1,n.length-1)),t}throw new e(`Resulting stack appears incorrect with size ${s.size}`);var n}}const u=Object.freeze({FUNCTION_TAG:"^\\s*->\\s*(.*)",CMD_KEY_QUEUE_DEL_CHILD_OBJ_IF_EMPTY:"^(<-\\s*false\\s*)|(<--\\s*false\\s*)$",CMD_KEY_COPY_INTO_OBJ:"^(<-\\s*true\\s*)|(<-\\s*)$",CMD_KEY_COPY_INTO_PARENT_OBJ:"^(<--\\s*true\\s*)|(<--\\s*)$",CMD_KEY_IF_BLOCK_START:"^(<--|<-)\\s*(IF\\().*",CMD_KEY_ELSE_BLOCK:"^(<--|<-)\\s*(ELSE)$"});class d extends Error{constructor(){super("Interpolation value not Found")}}class y{static isWhitespace(t){return/\s/.test(t)}static isOpen(t){return"("===t}static isClose(t){return")"===t}static isCurlyOpen(t){return"{"===t}static isCurlyClose(t){return"}"===t}static isArgSeparate(t){return","===t}static isSquareOpen(t){return"["===t}static isSquareClose(t){return"]"===t}static isGroupTokenBegin(t){return"'"===t||'"'===t||"["===t||"{"===t}static isMatchingGroupTokenEnd(t,e){return"'"===t?"'"===e:'"'===t?'"'===e:"["===t?"]"===e:"{"===t?"}"===e:void 0}constructor(t){this._expression=t,this._index=0}notifyParseStart(){this._index=0}notifyParseComplete(t){}getI(){return this._index}getExpr(){return this._expression}cAtI(t=0){return this.getExpr()[this._index+t]}cAtIIsWhite(){return y.isWhitespace(this.cAtI())}skip(t=1){return this._index+=t}hasChars(t=1){return this.getExpr().length-this._index>=t}cAtIisCurlyOpen(){return y.isCurlyOpen(this.cAtI())}cAtIisCurlyClose(){return y.isCurlyClose(this.cAtI())}cAtIOIsOpen(){return y.isOpen(this.cAtI())}cAtIOIsClose(){return y.isClose(this.cAtI())}cAtIIsArgSeporator(){return y.isArgSeparate(this.cAtI())}cAtIIsGroupTokenEnd(t){return y.isMatchingGroupTokenEnd(t,this.cAtI())}cAtIIsTag(t){let e=!1;const s=t.length;if(this.hasChars(s)){let r=0;for(let e=0;e<t.length;e++)this.cAtI(e)===t[e]&&r++;e=r===s}return e}skipWhitespace(){for(;this.hasChars()&&this.cAtIIsWhite();)this.skip()}}class _ extends y{constructor(t,e={}){super(t),this._options=e,this._startTag="{{",this._endTag="}}",this._ignoreEnclosed={Opens:["{"],Closes:["}"]},this._curlyBracketStack=[],this._replacementEdits=[],this._options.TrackCurlyBrackets=void 0!==this._options.TrackCurlyBrackets&&this._options.TrackCurlyBrackets}getTrackCurlyBrackets(){return this._options.TrackCurlyBrackets}createTemplateKey(t){return`${this._startTag}${t}${this._endTag}`}cAtIIsBeginTag(){return this.cAtIIsTag(this._startTag)}cAtIIsEndTag(){let t=!1;return 0===this._curlyBracketStack.length&&(t=this.cAtIIsTag(this._endTag)),t}cAtIisOpen(){let t;const e=this._ignoreEnclosed.Opens.indexOf(this.cAtI());return-1!==e&&(t=this._ignoreEnclosed.Closes[e]),t}cAtIisClosing(){let t=!1;if(this._curlyBracketStack.length>0){const e=this._curlyBracketStack[this._curlyBracketStack.length-1];this.cAtI()===e&&(t=!0)}return t}trackEnclosedChars(){if(this.getTrackCurlyBrackets()){const t=this.cAtIisOpen();void 0!==t?this._curlyBracketStack.push(t):this.cAtIisClosing()&&this._curlyBracketStack.pop()}}parseToken(){let t,e=-1,s=-1,r=-1,n=-1;for(;this.hasChars();)if(this.cAtIIsBeginTag())r=this.getI(),this.skip(this._startTag.length),e=this.getI();else{if(-1!==e&&this.cAtIIsEndTag()){s=this.getI(),n=s+this._endTag.length,t=this.getExpr().slice(e,s),this.skip(this._endTag.length);break}this.trackEnclosedChars(),this.skip()}return void 0!==t?{Match:this.createTemplateKey(t),Key:t,IStartToken:r,IEndToken:n}:void 0}applyReplacementEdits(){return g.customStringReplacer(this.getExpr(),this._replacementEdits)}}class f extends _{constructor(t,e={}){super(t,e)}has(){this.notifyParseStart();let t=this.parseToken();return this.notifyParseComplete(t),void 0!==t}}class g extends _{static customStringReplacer(t,e){let s="",r=0;for(let n=0;n<e.length;n++){const{ReplaceWith:i,IStartToken:o,IEndToken:a}=e[n];s+=t.slice(r,o),s+=i,r=a}return s+=t.slice(r),s}constructor(t,e,s={}){super(t,s),this._cb=e}notifyParseResult(t){const e=t.Match,s=t.Key,r=t.IStartToken;t.ReplaceWith=this._cb(this,e,s,r,this.getExpr()),this._replacementEdits.push(t)}applyReplacementEdits(){return g.customStringReplacer(this.getExpr(),this._replacementEdits)}replace(){this.notifyParseStart();let t=this.parseToken();for(;void 0!==t;)this.notifyParseResult(t),t=this.parseToken();if(this._curlyBracketStack.length>0)throw new Error(`Match Error - unbalanced symbols missing: ${this._curlyBracketStack.join(",")}`);return this.notifyParseComplete(t),this.applyReplacementEdits()}}class O{static isPromise(t){let e=!1;return null!==t&&"object"==typeof t&&"function"==typeof t.then&&(e=!0),e}constructor(){this._promises=[],this._promiseKeys=[],this._matchedOn=[],this._nextKeyId=0}hasPromises(){return this._promises.length>0}allSettled(){return Promise.allSettled(this._promises)}async processPromises(){let t;if(this.hasPromises()){t={NResolved:0,NRejected:0};const e=await this.allSettled();for(let s=0;s<e.length;s++){const r=this._promiseKeys[s],n=e[s];"fulfilled"===n.status?(t[r]=n.value,t.NResolved++):"rejected"===n.status&&(t[r]=this._matchedOn[s],t.NRejected++)}}return t}getNextPromiseKey(){const t=`${this._nextKeyId}__@uniquePKey@__${this._nextKeyId}`;return this._nextKeyId++,t}add(t,e){let s;return O.isPromise(e)&&(this._matchedOn.push(t),this._promises.push(e),s=this.getNextPromiseKey(),this._promiseKeys.push(s)),s}}const I=Object.freeze({CovertValueToType:!0});class A{constructor(t){this._keyValues=t}getKeyValues(){return this._keyValues}get(t){return this._keyValues[t]}}class C{constructor(t,e,s={}){this._templateStr=t,this._keyValuesI=e instanceof A?e:new A(e),this._options=s,this._options.CovertValueToType=void 0===this._options.CovertValueToType?I.CovertValueToType:this._options.CovertValueToType,this._options.ReplaceNotFoundHandler=void 0!==this._options.ReplaceNotFoundHandler?this._options.ReplaceNotFoundHandler:(t,e)=>t}getOptionConvertType(){return this._options.CovertValueToType}getOptionReplaceNotFoundHandler(){return this._options.ReplaceNotFoundHandler}getValueInMap(t){return this._keyValuesI.get(t)}async doReplaces(t,e){let s;const r=new O,n=new g(t,((t,n,i,o,a)=>{let c=e.getValueInMap(i.trim());void 0===c&&e.canInvokeNotFoundHandler()&&(c=this.getOptionReplaceNotFoundHandler()(n,i));const h=r.add(n,c);return void 0!==h?c=t.createTemplateKey(h):this.getOptionConvertType()&&n===a?s=c:null!==c&&"object"==typeof c&&(c=JSON.stringify(c)),c}),this._options).replace();let i;const o=await r.processPromises();return void 0!==o&&(i=await this.doReplaces(n,{getValueInMap:t=>o[t],canInvokeNotFoundHandler:()=>!1})),i=i||(void 0!==s?s:n),i}async sInterpolate(){let t=this._templateStr;return"string"==typeof t&&(t=await this.doReplaces(t,{getValueInMap:t=>this.getValueInMap(t),canInvokeNotFoundHandler:()=>!0})),t}}const E=Object.freeze({ACTION_NONE:Symbol("ACTION_NONE"),ACTION_DELETE:Symbol("ACTION_DELETE"),ACTION_THROW:Symbol("ACTION_THROW"),isValidAction:function(t){let e=!1;return t&&(e=t===E.ACTION_NONE||t===E.ACTION_DELETE||t===E.ACTION_THROW),e}});class m{constructor(){this._action=E.ACTION_NONE}getAction(){return this._action}setAction(t){let e=!1;return E.isValidAction(t)&&(this._action=t,e=!0),e}}const T=Object.freeze({KeyCmdNone:0,KeyCmdCopyIntoObject:1,KeyCmdCopyIntoParentObject:2,KeyCmdDelKey:3,KeyCmdQueueDelChildObjectIfEmpty:4});class N{static isKeyCmd(t,e){return-1!==t.search(new RegExp(e))}static containsTemplateVar(t){return!(!t||"string"!=typeof t)&&new f(t).has()}static dupWithoutVars(t){const e={...t};for(const[s,r]of Object.entries(t))N.containsTemplateVar(r)&&delete e[s];return e}static mergeInto(t,e){Array.isArray(t)&&Array.isArray(e)?t.splice(0,t.length,...e):Object.assign(t,e)}static*iterateObjStrings(t,e=[],s=[]){let r=!1;if(t){0===s.length&&(s.push(t),r=!0);const n=Array.isArray(t.__ProcessKeys__)?t.__ProcessKeys__:Object.keys(t);for(let r=0;r<n.length;r++){const i=n[r],o=t[i];if("object"==typeof o&&null!==o)Array.isArray(o)||(yield[t,i,o,e,s]),e.push(i),s.push(o),yield*N.iterateObjStrings(o,e,s),e.pop(),s.pop();else if("string"==typeof o){yield[t,i,o.trim(),e,s];const r=/^__DEBUG__\d*$/;!!i.match(r)&&(console.log(t[i]),delete t[i])}}r&&s.pop()}}static createPathDotNotation(t,e){return t.length>0?t.join("¤")+"¤"+e:e}static createObjectPath(t){return t.split("¤")}static dup(t){return JSON.parse(JSON.stringify(t))}constructor(t,e,s={}){this._options=s,this._options.CopyObj=void 0!==this._options.CopyObj&&this._options.CopyObj,this._obj=this.getCopyObj()?N.dup(t):t,this._keyValues=e,this._options.ActionOnNotFound=E.isValidAction(this._options.ActionOnNotFound)?this._options.ActionOnNotFound:E.ACTION_NONE,this._options.KeyValueContextI=void 0!==this._options.KeyValueContextI?this._options.KeyValueContextI:A,this._nPass=3}getObj(){return this._obj}getOptions(){return this._options}getActionOnNotFound(){return this._options.ActionOnNotFound}getOptionKeyValueContextI(){return this._options.KeyValueContextI}getOptionKeyValueContextSeparator(){return this._options.KeyValueContextSeparator||"."}getCopyObj(){return this._options.CopyObj}notifyReplaceNotFound(t,e,s,r,n){let i=e;if(r){const t=r(e,s);n(t)||(i=t)}else n(this.getActionOnNotFound());return i}getKeyInterpolator(t,e,s,r){return null}async doInterpolateKey(t,e,s,r){let n={nReplacedKeys:0,key:s};const i=this.getKeyInterpolator(t,e,s,r);return i&&(n=await i.interpolate()),n}async doInterpolateObj(t,e,s,r){let n=0,i=r;const o=this._options.ReplaceNotFoundHandler;for(let r=0;r<this._nPass;r++){const r=new m,a=new C(i,t,{TrackCurlyBrackets:!0,...this._options,ReplaceNotFoundHandler:(e,s)=>this.notifyReplaceNotFound(t,e,s,o,(t=>r.setAction(t)))});let c=await a.sInterpolate();if(r.getAction()===E.ACTION_NONE){if(i===c)break;e[s]=c,n++,i=c}else{if(r.getAction()===E.ACTION_DELETE){delete e[s];break}if(r.getAction()===E.ACTION_THROW)throw new d}}return n}getCmdInKey(t){let e=T.KeyCmdNone;return N.isKeyCmd(t,u.CMD_KEY_QUEUE_DEL_CHILD_OBJ_IF_EMPTY)?e=T.KeyCmdQueueDelChildObjectIfEmpty:N.isKeyCmd(t,u.CMD_KEY_COPY_INTO_OBJ)?e=T.KeyCmdCopyIntoObject:N.isKeyCmd(t,u.CMD_KEY_COPY_INTO_PARENT_OBJ)&&(e=T.KeyCmdCopyIntoParentObject),e}processDeletes(t){t.forEach((t=>{const e=N.createObjectPath(t);let s=this._obj,r=null,n="",i=null,o="";for(let t=0;t<e.length;t++)t===e.length-1&&(n=o,r=i),o=e[t],i=s,s=s[o];i&&"object"==typeof i&&o&&delete i[o],r&&"object"==typeof r&&n&&0===Object.keys(r[n]).length&&(Array.isArray(r)?r.splice(n,1):delete r[n])}))}addFlattenPaths(t,e){let s=this._obj,r=[];Array.isArray(s)&&r.push(s);for(let t=0;t<e.length;t++){s=s[e[t]],Array.isArray(s)?r.push(s):r=[]}for(let e=r.length-1;e>=0;e--){const s=r[e];t.has(s)||t.add(s)}}createKeyValueContextI(t){return new(this.getOptionKeyValueContextI())(t,this.getOptionKeyValueContextSeparator())}async interpolate(){let t=0;const e=[],s=new Set,r=new Set;for(const[n,i,o,a,c]of N.iterateObjStrings(this._obj)){const h=this.createKeyValueContextI({...this._keyValues,...N.dupWithoutVars(n)}),l=await this.doInterpolateKey(h,n,i,o);t+=l.nReplacedKeys;const p=this.getCmdInKey(l.key);if(p===T.KeyCmdNone||p===T.KeyCmdCopyIntoObject||p===T.KeyCmdCopyIntoParentObject)if(t+=await this.doInterpolateObj(h,n,i,o),p===T.KeyCmdCopyIntoObject){const t=n[i];"object"==typeof t&&null!==t&&(Object.assign(n,t),delete n[i])}else if(p===T.KeyCmdCopyIntoParentObject){const t=c.length>1?c[c.length-2]:null,o=a.length>0?a[a.length-1]:"";if(!t||!o)throw new Error("No parent object to merge");{const c=n[i];if(void 0!==c){s.has(t[o])&&Array.isArray(c)?t[o].push(...c):Array.isArray(t)?(t[o]=c,Array.isArray(c)&&s.add(t[o])):(N.mergeInto(t,c),e.push(N.createPathDotNotation(a,i))),Array.isArray(t)&&this.addFlattenPaths(r,a)}}}else l.nReplacedKeys>0&&(n[l.key]=n[i],delete n[i]);else p===T.KeyCmdQueueDelChildObjectIfEmpty&&e.push(N.createPathDotNotation(a,i))}for(const t of r)N.mergeInto(t,t.flat());return this.processDeletes(e),{obj:this.getObj(),nReplacedKeys:t}}}class k extends y{constructor(t,e){super(t),this._options=e,this._options.OptionStringArgQuoted=void 0!==this._options.OptionStringArgQuoted&&this._options.OptionStringArgQuoted}getOptionStringArgQuoted(){return this._options.OptionStringArgQuoted}skipGroupedChars(){let t=this.cAtI();if(y.isGroupTokenBegin(t)){let e=[];for(e.push(t);this.hasChars()&&e.length>0;)for(t=e[e.length-1],this.skip();this.hasChars();){if(this.cAtIIsGroupTokenEnd(t)){e.pop();break}{const s=this.cAtI();if(y.isGroupTokenBegin(s)){t=s,e.push(s);break}}this.skip()}if(e.length>0)throw new Error(`Parse error - mismatch on some ending symbols: [${e.map((t=>`'${t}'`)).join(",")}]`)}}skipNonSpecialChars(){for(;this.hasChars()&&!this.cAtIIsWhite()&&!this.cAtIOIsOpen()&&!this.cAtIOIsClose()&&!this.cAtIIsArgSeporator();)this.skip()}readToken(){let t;if(this.skipWhitespace(),this.cAtIOIsOpen()||this.cAtIOIsClose())throw new Error("Parse error - Unexpected '(' or ')' missing function name");{const e=this.getI();this.skipGroupedChars(),this.skipNonSpecialChars();const s=this.getI();t=this.getExpr().slice(e,s)}return t}parseArguments(){let t=[];for(;this.hasChars()&&!this.cAtIOIsClose();)t.push(this.parseExpression()),this.skipWhitespace(),this.cAtIIsArgSeporator()&&this.skip();return t}parseExpression(){let t=this.readToken();if(/^true|false$/.test(t));else if(/^null$/.test(t));else if(/^[a-zA-Z_ƒ][\w]*$/.test(t)){if(this.skipWhitespace(),this.cAtIOIsOpen()){let e=t;this.skip();let s=this.parseArguments();if(this.skipWhitespace(),!this.cAtIOIsClose())throw new Error(`Parse error - Expected '(' after function name ${e}`);return this.skip(),{type:"FunctionCall",name:e,arguments:s}}if(this.getOptionStringArgQuoted())throw new Error(`Parse error - Expected '(' after function name ${t}`);t=`'${t}'`}return{type:"Literal",value:t}}parse(){this.notifyParseStart();const t=this.parseExpression();return this.notifyParseComplete(t),t}}class R extends k{static convertNum(t){let e;if("string"==typeof t&&""!==t){const s=Number(t);isNaN(s)||(e=s)}return e}static convertString(t){let e;const s=t.match(/^['"](.*)['"]$/);return Array.isArray(s)&&2===s.length&&(e=s[1]),e}static convertBool(t){let e;const s=t.match(/^(true|false)$/);return Array.isArray(s)&&2===s.length&&(e="true"===s[1]),e}static convertNull(t){let e;const s=t.match(/^(null)$/);return Array.isArray(s)&&2===s.length&&(e="null"===s[1]?null:void 0),e}static convertObj(t){let e;try{e=JSON.parse(t)}catch(t){throw new Error("Failed to convert value to Json object")}return e}static convertToLiteral(t){let e=t;const s=R.convertNum(t);if(void 0!==s)e=s;else{const s=R.convertString(t);if(void 0!==s)e=s;else{const s=R.convertBool(t);if(void 0!==s)e=s;else{const s=R.convertNull(t);if(void 0!==s)e=s;else try{const s=R.convertObj(t);void 0!==s&&(e=s)}catch(e){if("string"==typeof t)return t;throw new Error("Invalid type in convertToLiteral")}}}}return e}static invokeParsedFunction(t,e,s){if("Literal"===e.type)return R.convertToLiteral(e.value);if("FunctionCall"===e.type){const r=s[e.name];if("function"!=typeof r)throw new Error(`Function ${e.name} is not defined in the context`);const n=e.arguments.map((e=>R.invokeParsedFunction(t,e,s)));return r(t,...n)}throw new Error("Unknown AST node type")}constructor(t,e,s,r,n={}){super(e,n),this._parent=t,this._keyValueContext=s,this._fContext=r,this._asTree=null}getParent(){return this._parent}getKeyValueContext(){return this._keyValueContext}parse(){this._asTree=super.parse();return R.invokeParsedFunction(this,this._asTree,this._fContext)}}class v extends N{static convertToString(t){let e=t;return"number"==typeof t||"bigint"==typeof t||"boolean"==typeof t||"string"==typeof t?e=t.toString():null===t?e="null":void 0===t?e=void 0:Array.isArray(t)?e=JSON.stringify(t):console.error("Failed to convert to primitive type"),e}static processExpression(t){return new p(t).evaluate()}static getFunctionExpression(t){let e="";if(t){const s=new RegExp(u.FUNCTION_TAG).exec(t);Array.isArray(s)&&2===s.length&&(e=s[1])}return e}constructor(t,e,s,r={}){super(t,e,r),this._parseFContext=s||{},this._buildInFContext={"ƒ":(t,e)=>v.processExpression(e),Exp:(t,e)=>v.processExpression(e),_:(t,e)=>v.convertToString(e)}}getKeyInterpolator(t,e,s,r){return new S(s,t,{},{ChildObj:e})}notifyReplaceNotFound(t,e,s,r,n){const i=v.getFunctionExpression(s);if(this._parseFContext&&i){return new R(this,i,t,{...this._parseFContext,...this._buildInFContext}).parse()}return super.notifyReplaceNotFound(t,e,s,r,n)}}class K{static validateTransformMatch(t){return Array.isArray(t)&&3===t.length}constructor(t,e){this._key=t,this._childObj=e}transformFromIf(t,e,s,r=!1){let n="",i="";const o=t.lastIndexOf(")"),a=e.indexOf("(");if(o===e.length-1&&-1!==a){const e=t.slice(a+1,o);t=`{{->ƒ( "${r?`!(${e})`:e}" ) }}`,i=u.CMD_KEY_IF_BLOCK_START,n=s}return{CmdType:i,Cmd:n,Key:t}}reverseTransformFirstIfKey(t,e,s){let r=null;for(const[t,e]of Object.entries(this._childObj)){const e=t.match(new RegExp(u.CMD_KEY_IF_BLOCK_START,"i"));if(K.validateTransformMatch(e)){r=this.transformFromIf(t,e[0],e[1],!0);break}}return null!==r?r:{CmdType:u.CMD_KEY_ELSE_BLOCK,Cmd:s,Key:"false"}}transformElse(t,e,s){const r=this.reverseTransformFirstIfKey(t,e,s),n=r?r.Cmd:"",i=r?r.Key:t;return{CmdType:u.CMD_KEY_ELSE_BLOCK,Cmd:n,Key:i}}transform(){const t=this._key.trim();let e={CmdType:"",Cmd:"",Key:t};const s=t.match(new RegExp(u.CMD_KEY_IF_BLOCK_START,"i"));if(K.validateTransformMatch(s))e=this.transformFromIf(t,s[0],s[1]);else{const s=t.match(new RegExp(u.CMD_KEY_ELSE_BLOCK,"i"));K.validateTransformMatch(s)&&(e=this.transformElse(t,s[0],s[1]))}return e}}class S extends v{constructor(t,e,s,r={}){const n=new K(t,r.ChildObj).transform();super({Key:n.Key},e.getKeyValues(),s,r),this._cmdType=n.CmdType,this._cmd=n.Cmd,this._originalKey=t}getChildObj(){return this.getOptions().ChildObj}getKeyInterpolator(t,e,s,r){return null}async interpolate(){const t=await super.interpolate();let e;return e=this._cmd?`${this._cmd}${t.obj.Key}`:t.obj.Key,{nReplacedKeys:t.nReplacedKeys,key:e}}}return t.InterpolationValueNotFoundError=d,t.KeyValueContextI=A,t.ObjectInterpolator=v,t.ObjectInterpolatorBase=N,t.QueryObjKeyValueContextI=class extends A{constructor(t,e="."){super(t),this._useSeparator=e}get(t){function e(t,e,s){const r=e.slice(0,s?-1:e.length);return e?t[r]:t}try{return t.split(this._useSeparator).reduce((function(t,s){return s?s.split("[").reduce(e,t):t}),this.getKeyValues())}catch(t){return}}},t.ReplaceObjectAction=E,t.SimpleTagParser=f,t.SinglePassTagReplacer=g,t.StringInterpolator=C,t}({}); //# sourceMappingURL=interpolation_objects.gs.min.js.map