@peter.naydenov/morph 3.0.0 → 3.1.0

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/Changelog.md CHANGED
@@ -2,6 +2,23 @@
2
2
 
3
3
 
4
4
 
5
+ ### 3.1.0 (2025-08-19)
6
+ - [x] Helper named argument 'full'. Gives access to full template data. Use it create mixed conditions among many different parameters, not only the iteration data;
7
+
8
+
9
+
10
+ ### 3.0.1 ( 2025-06-14)
11
+ - [x] Fix: Bad full render after call of snippets;
12
+
13
+
14
+
15
+ ### 3.0.0 ( 2025-06-12)
16
+ - [x] Render selected snippets;
17
+ - [x] Commands and instructions terms;
18
+ - [x] Bug: Bad full render after call of snippets;
19
+
20
+
21
+
5
22
  ### 2.2.0 ( 2025-06-06)
6
23
  - [x] New: Source property can contains a symbol '/';
7
24
 
package/README.md CHANGED
@@ -10,13 +10,13 @@
10
10
 
11
11
  ## What's new in version 3.x.x
12
12
 
13
- In version 3, you can choose to render only certain placeholders or groups of placeholders from a template. This lets you use templates as collections of reusable templates, so you can extract and use just the parts you need without having to render the whole template. This makes it easier to create and manage reusable template libraries for your project.
13
+ In version 3 introduced `snippets`, you can choose to render only certain placeholders or groups of placeholders from the template. This lets you use templates as collections of reusable templates, so you can extract and use just the parts you need without having to render the whole template. This makes it easier to create and manage reusable template libraries for your project or rerender only the parts that need to be updated.
14
14
 
15
15
  The `render` function now takes a command as its first argument. Available commands are: `render`, `debug`, and `snippets`. Other arguments have no changes. Just shifted right. The second argument becomes the data, the third is dependencies, and the fourth is a list of post-processing functions.
16
16
 
17
17
  In version 3.x.x, the data is always the second argument. It can be a string, as in version 2.x.x. The term "command" is no longer used for this argument; instead, it is called "instructions". Available instructions include: `raw`, `demo`, `handshake`, and `placeholders`.
18
18
 
19
- How to migrate to version 3.x.x, please read the [Migration guide](./Migration.guide.md). Read more about snippets down below.
19
+ How to migrate to version 3.x.x, please read the [Migration guide](./Migration.guide.md). Read more about `snippets` down below.
20
20
 
21
21
 
22
22
 
package/dist/morph.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var e=require("@peter.naydenov/walk"),t=require("@peter.naydenov/stack");function r(e){return function t(r){const{TG_PRX:a,TG_SFX:o,TG_SIZE_P:s,TG_SIZE_S:i}=e;let l,c,u,d=[];if("string"!=typeof r)return n("notAString");if(0==r.length)return[];if(l=r.indexOf(a),0<l&&d.push(r.slice(0,l)),-1==l)return d.push(r),d;{if(u=r.indexOf(a,l+s),c=r.indexOf(o),-1==c)return n("missingClosing");if(c<l)return n("closedBeforeOpened");if(c+=i,-1!=u&&u<c)return n("newBeforeClosed");d.push(r.slice(l,c));let e=t(r.slice(c));return d.concat(e)}}}function n(e){switch(e){case"notAString":return"Error: Template is not a string.";case"missingClosing":return"Error: Placeholder with missing closing tag.";case"closedBeforeOpened":return"Error: Placeholder closing tag without starting one.";case"newBeforeClosed":return"Error: Nested placeholders. Close placeholder before open new one.";default:return"Error: Unknown template error."}}var a={TG_PRX:"{{",TG_SFX:"}}",TG_SIZE_P:2,TG_SIZE_S:2};function o(e){return null==e?"null":"string"==typeof e||"number"==typeof e||"boolean"==typeof e?"primitive":"function"==typeof e?"function":e instanceof Array?"array":e instanceof Object?"object":void 0}function s(e,t,n,...o){e instanceof Object&&Object.entries(e).forEach((([t,r])=>{r instanceof Object&&(e[t]=r.text),r instanceof Array&&(e[t]=r[0])}));const s="function"==typeof n[t];return e=function(e={}){return"string"==typeof e?{text:e}:e}(e),s?n[t](e,...o):function(e,t){if(null==t)return null;const n=r(a)(e),o=a;return n.forEach(((e,r)=>{if(e.includes(o.TG_PRX)){const a=e.replace(o.TG_PRX,"").replace(o.TG_SFX,"").trim();t.hasOwnProperty(a)&&null!=t[a]&&(n[r]=t[a])}})),n.join("")}(n[t],e)}function i(n,i=!1,l={}){let{hasError:c,placeholders:u,chop:d,helpers:f,handshake:p,snippets:h}=function(e){const{template:t,helpers:n={},handshake:o}=e,{TG_PRX:s,TG_SFX:i}=a,l=[],c={},u="string"==typeof t?t.replace(/<!--[\s\S]*?-->/g,"").replace(/\s{2,}/g," "):t;let d=null;const f=r(a)(u);return"string"==typeof f?d=f:f.forEach(((e,t)=>{const r=RegExp(s+"\\s*(.*?)\\s*(?::\\s*(.*?)\\s*)?(?::\\s*(.*?)\\s*)?"+i,"g");if(e.includes(s)){const a=r.exec(e);if(!a)return;let o={index:t,data:(n=a[1],n||null),action:a[2]?a[2].split(",").map((e=>e.trim())):null,name:a[3]?a[3].trim():null};l.push(o),c[l.length-1]=o,o.name&&(c[o.name]=o)}var n})),l.forEach((e=>{e.action&&e.action.every((e=>"#"===e||"^^"===e||!(!e.startsWith("^")||"^^"===e)||(e.startsWith("?")&&(e=e.replace("?","")),e.startsWith("+")&&(e=e.replace("+","")),e.startsWith("[]")&&(e=e.replace("[]","")),e.startsWith(">")&&(e=e.replace(">","")),""===e||!!n[e]||(d=`Error: Missing helper: ${e}`,!1))))})),{hasError:d,placeholders:l,chop:f,helpers:n,handshake:o,snippets:c}}(n);if(c){function m(){return c}return i?[!1,m]:m}{let b=structuredClone(d);function y(r="render",n={},a={},...i){let c=!1;if(!["render","debug","snippets"].includes(r)&&!r.startsWith("snippets"))return`Error: Wrong command "${r}". Available commands: render, debug, snippets.`;if(r.startsWith("snippets")&&r.includes(":")){c=!0;let e=r.split(":").slice(1)[0].trim().split(",").map((e=>e.trim()));u=e.map((e=>h[e]))}else"snippets"===r&&(c=!0);if("string"==typeof n)switch(n){case"raw":return b.join("");case"demo":if(!p)return"Error: No handshake data.";n=p;break;case"handshake":return p?structuredClone(p):"Error: No handshake data.";case"placeholders":return u.map((e=>b[e.index])).join(", ");default:return`Error: Wrong instruction "${n}". Available instructions: raw, demo, handshake, placeholders.`}const d=[],m={};let y=o(n),g={...l,...a};return n=e({data:n}),"null"===y?b.join(""):("array"!==y&&(n=[n]),"null"===y?b.join(""):(n.forEach((r=>{u.forEach((n=>{const{index:a,data:i,action:l}=n,c=!l&&i,u=structuredClone(m),d={dependencies:g,memory:u};let p=r;if(i&&i.includes("/")?p.hasOwnProperty(i)?p=p[i]:i.split("/").forEach((e=>{p=p.hasOwnProperty(e)?p[e]:[]})):"@all"===i||null===i||"@root"===i?p=r:i&&(p=p[i]),c){switch(o(p)){case"function":return void(b[a]=p());case"primitive":return void(b[a]=p);case"array":return void("primitive"===o(p[0])&&(b[a]=p[0]));case"object":return void(p.text&&(b[a]=p.text))}}else{let{dataDeepLevel:n,nestedData:i}=function(t,r){const n=[];let a=0;if(t instanceof Function)return{dataDeepLevel:0,nestedData:[[t()]]};if(null==t)return{dataDeepLevel:0,nestedData:[null]};if("string"==typeof t)return{dataDeepLevel:0,nestedData:[[t]]};const o=structuredClone(t);return r.includes("#")?(e({data:o,objectCallback:function({key:e,value:t,breadcrumbs:r}){return e===r?(n[0]=[t],t):(a=r.split("/").length-1,n[a]||(n[a]=[]),n[a].push(t),t)}}),{dataDeepLevel:a,nestedData:n}):(n.push([o]),{dataDeepLevel:0,nestedData:n})}(p,l),c=function*(e,r){let n=t({type:"LIFO"});for(let t=0;t<=r;t++)n.push(e[t]);for(;n&&!n.isEmpty();){let e=yield n.pull();e&&n.push(e)}}(function(e,t=10){let r={},n=[...e],a=0,o=0,s=0;n.forEach((e=>{"#"===e&&s++})),s<t&&console.error(`Error: Not enough level markers (#) for data with depth level ${t}. Found ${s} level markers in actions: ${e.join(", ")}`);do{r[o]=[],o++}while(o<=t);return n.every((e=>"#"===e?(a++,!(a>t)):e.startsWith("?")?(r[a].push({type:"route",name:e.replace("?",""),level:a}),!0):e.startsWith("^")&&"^^"!==e?(r[a].push({type:"save",name:e.replace("^",""),level:a}),!0):"^^"===e?(r[a].push({type:"overwrite",name:"none",level:a}),!0):e.startsWith("+")?(r[a].push({type:"extendedRender",name:e.replace("+",""),level:a}),!0):e.startsWith("[]")?(r[a].push({type:"mix",name:e.replace("[]",""),level:a}),!0):e.startsWith(">")?(r[a].push({type:"data",name:e.replace(">",""),level:a}),!0):(""===e||r[a].push({type:"render",name:e,level:a}),!0))),r}(l,n),n);for(let t of c){let{type:n,name:a,level:l}=t;(i[l]||[]).forEach(((t,c)=>{let u=o(t);switch(n){case"route":switch(u){case"array":t.forEach(((e,r)=>{if(null==e)return;const n=o(e),i=f[a]({data:e,...d});null!=i&&("object"===n?t[r].text=s(e,i,f,g):t[r]=s(e,i,f,g))}));break;case"object":t.text=s(t,a,f,g)}break;case"save":m[a]=structuredClone(t);break;case"overwrite":r=structuredClone(t);break;case"data":switch(u){case"array":t.forEach(((e,r)=>t[r]=e instanceof Function?f[a]({data:e(),...d}):f[a]({data:e,...d})));break;case"object":i[l]=[f[a]({data:t,...d})];break;case"function":i[l]=[f[a]({data:t(),...d})];break;case"primitive":i[l]=f[a]({data:t,...d})}break;case"render":const p="function"==typeof f[a];switch(u){case"array":p?t.forEach(((e,r)=>{if(null==e)return;const n=o(e),s=f[a]({data:e,...d});null==s&&(t[r]=null),"object"===n?e.text=s:t[r]=s})):t.forEach(((e,r)=>{if(null==e)return;const n=o(e),i=s(e,a,f,g);null==i?t[r]=null:"object"===n?e.text=i:t[r]=i}));break;case"function":i[l]=f[a]({data:t(),...d});break;case"primitive":i[l]=p?f[a]({data:t,...d}):s(t,a,f,g);break;case"object":p?i[l][c].text=f[a]({data:t,...d}):t.text=s(t,a,f,g)}break;case"extendedRender":"function"==typeof f[a]&&i[0].forEach(((e,t)=>i[0][t]=f[a]({data:e,...d})));break;case"mix":if(""===a)switch(u){case"object":Object.keys(t).find((e=>e.includes("/")))?Object.entries(t).forEach((([e,t])=>i[l][e]=t.text)):i[l]=t.text;for(let b=l-1;b>=0;b--)i[b]=e({data:i[b],objectCallback:h});function h({value:e,breadcrumbs:t}){return i[l][t]?i[l][t]:e}break;case"array":t.forEach(((e,r)=>{if(r>0){let n=o(e);if(null==e)return;t[0]+="object"===n?`${e.text}`:`${e}`,t.toSpliced(r,1)}else{let r=o(e);if(t[0]="",null===r)return;t[0]="object"===r?`${e.text}`:`${e}`}})),t.length=1}else{let y=f[a]({data:t,...d}),v=o(y);switch(t.forEach(((e,r)=>t.splice(r,1))),t.length=0,v){case"primitive":t[0]=y;break;case"array":t.push(...y)}}}}))}if(i instanceof Array&&1===i.length&&i[0]instanceof Array&&(i=i[0]),null==i[0])return;let u=o(i[0]),h=i[0];switch(u){case"primitive":if(null==h)return;b[a]=h;break;case"object":if(null==h.text)return;b[a]=h.text;break;case"array":const e=o(h[0]);b[a]="object"===e?h.map((e=>e.text)).join(""):h.join("")}}})),c?d.push(u.map((e=>b[e.index])).join("<~>")):d.push(b.join(""))})),"array"===y?d:i?i.reduce(((e,t)=>"function"!=typeof t?e:t(e,g)),d.join("")):d.join("")))}return i?[!0,y]:y}}const l={default:{}};const c={build:i,get:function(e){if(!(e instanceof Array))return function(){return'Error: Argument "location" is a string. Should be an array. E.g. ["templateName", "storageName"].'};const[t,r="default"]=e;return l[r]?l[r][t]?l[r][t]:function(){return`Error: Template "${t}" does not exist in storage "${r}".`}:function(){return`Error: Storage "${r}" does not exist.`}},add:function(e,t,...r){const[n,a="default"]=e;if(null==t)return void console.warn(`Warning: Template ${a}/${n} is not added to storage. The template is null.`);let o=t,s=!0;if(l[a]||(l[a]={}),"function"!=typeof t){let e=i(t,!0,...r);s=e[0],o=e[1]}s?l[a][n]=o:console.error(`Error: Template "${n}" looks broken and is not added to storage.`)},list:function(e=["default"]){return e.map((e=>l[e]?Object.keys(l[e]):[])).flat()},clear:function(){Object.keys(l).forEach((e=>{"default"!=e?delete l[e]:l.default={}}))},remove:function(e){const[t,r="default"]=e;return l[r]?l[r][t]?void delete l[r][t]:`Error: Template "${t}" does not exist in storage "${r}".`:`Error: Storage "${r}" does not exist.`}};module.exports=c;
1
+ "use strict";var e=require("@peter.naydenov/walk"),t=require("@peter.naydenov/stack");function r(e){return function t(r){const{TG_PRX:a,TG_SFX:o,TG_SIZE_P:s,TG_SIZE_S:i}=e;let l,c,u,d=[];if("string"!=typeof r)return n("notAString");if(0==r.length)return[];if(l=r.indexOf(a),0<l&&d.push(r.slice(0,l)),-1==l)return d.push(r),d;{if(u=r.indexOf(a,l+s),c=r.indexOf(o),-1==c)return n("missingClosing");if(c<l)return n("closedBeforeOpened");if(c+=i,-1!=u&&u<c)return n("newBeforeClosed");d.push(r.slice(l,c));let e=t(r.slice(c));return d.concat(e)}}}function n(e){switch(e){case"notAString":return"Error: Template is not a string.";case"missingClosing":return"Error: Placeholder with missing closing tag.";case"closedBeforeOpened":return"Error: Placeholder closing tag without starting one.";case"newBeforeClosed":return"Error: Nested placeholders. Close placeholder before open new one.";default:return"Error: Unknown template error."}}var a={TG_PRX:"{{",TG_SFX:"}}",TG_SIZE_P:2,TG_SIZE_S:2};function o(e){return null==e?"null":"string"==typeof e||"number"==typeof e||"boolean"==typeof e?"primitive":"function"==typeof e?"function":e instanceof Array?"array":e instanceof Object?"object":void 0}function s(e,t,n,...o){e instanceof Object&&Object.entries(e).forEach((([t,r])=>{r instanceof Object&&(e[t]=r.text),r instanceof Array&&(e[t]=r[0])}));const s="function"==typeof n[t];return e=function(e={}){return"string"==typeof e?{text:e}:e}(e),s?n[t](e,...o):function(e,t){if(null==t)return null;const n=r(a)(e),o=a;return n.forEach(((e,r)=>{if(e.includes(o.TG_PRX)){const a=e.replace(o.TG_PRX,"").replace(o.TG_SFX,"").trim();t.hasOwnProperty(a)&&null!=t[a]&&(n[r]=t[a])}})),n.join("")}(n[t],e)}function i(n,i=!1,l={}){let{hasError:c,placeholders:u,chop:d,helpers:f,handshake:p,snippets:h}=function(e){const{template:t,helpers:n={},handshake:o}=e,{TG_PRX:s,TG_SFX:i}=a,l=[],c={},u="string"==typeof t?t.replace(/<!--[\s\S]*?-->/g,"").replace(/\s{2,}/g," "):t;let d=null;const f=r(a)(u);return"string"==typeof f?d=f:f.forEach(((e,t)=>{const r=RegExp(s+"\\s*(.*?)\\s*(?::\\s*(.*?)\\s*)?(?::\\s*(.*?)\\s*)?"+i,"g");if(e.includes(s)){const a=r.exec(e);if(!a)return;let o={index:t,data:(n=a[1],n||null),action:a[2]?a[2].split(",").map((e=>e.trim())):null,name:a[3]?a[3].trim():null};l.push(o),c[l.length-1]=o,o.name&&(c[o.name]=o)}var n})),l.forEach((e=>{e.action&&e.action.every((e=>"#"===e||"^^"===e||!(!e.startsWith("^")||"^^"===e)||(e.startsWith("?")&&(e=e.replace("?","")),e.startsWith("+")&&(e=e.replace("+","")),e.startsWith("[]")&&(e=e.replace("[]","")),e.startsWith(">")&&(e=e.replace(">","")),""===e||!!n[e]||(d=`Error: Missing helper: ${e}`,!1))))})),{hasError:d,placeholders:l,chop:f,helpers:n,handshake:o,snippets:c}}(n);if(c){function m(){return c}return i?[!1,m]:m}{const b=structuredClone(u);function y(r="render",n={},a={},...i){const c=structuredClone(d);let m=!1;if(!["render","debug","snippets"].includes(r)&&!r.startsWith("snippets"))return`Error: Wrong command "${r}". Available commands: render, debug, snippets.`;if(r.startsWith("snippets")&&r.includes(":")){m=!0;let e=r.split(":").slice(1)[0].trim().split(",").map((e=>e.trim()));u=e.map((e=>h[e]))}else"snippets"===r?m=!0:u=structuredClone(b);if("string"==typeof n)switch(n){case"raw":return c.join("");case"demo":if(!p)return"Error: No handshake data.";n=p;break;case"handshake":return p?structuredClone(p):"Error: No handshake data.";case"placeholders":return u.map((e=>c[e.index])).join(", ");default:return`Error: Wrong instruction "${n}". Available instructions: raw, demo, handshake, placeholders.`}const y=[],g={};let v=o(n),E={...l,...a};return n=e({data:n}),"null"===v?c.join(""):("array"!==v&&(n=[n]),"null"===v?c.join(""):(n.forEach((r=>{u.forEach((n=>{const{index:a,data:i,action:l}=n,u=!l&&i,d=structuredClone(g),p={dependencies:E,memory:d};let h=r;if(i&&i.includes("/")?h.hasOwnProperty(i)?h=h[i]:i.split("/").forEach((e=>{h=h.hasOwnProperty(e)?h[e]:[]})):"@all"===i||null===i||"@root"===i?h=r:i&&(h=h[i]),u){switch(o(h)){case"function":return void(c[a]=h());case"primitive":return void(c[a]=h);case"array":return void("primitive"===o(h[0])&&(c[a]=h[0]));case"object":return void(h.text&&(c[a]=h.text))}}else{let{dataDeepLevel:n,nestedData:i}=function(t,r){const n=[];let a=0;if(t instanceof Function)return{dataDeepLevel:0,nestedData:[[t()]]};if(null==t)return{dataDeepLevel:0,nestedData:[null]};if("string"==typeof t)return{dataDeepLevel:0,nestedData:[[t]]};const o=structuredClone(t);return r.includes("#")?(e({data:o,objectCallback:function({key:e,value:t,breadcrumbs:r}){return e===r?(n[0]=[t],t):(a=r.split("/").length-1,n[a]||(n[a]=[]),n[a].push(t),t)}}),{dataDeepLevel:a,nestedData:n}):(n.push([o]),{dataDeepLevel:0,nestedData:n})}(h,l),u=function*(e,r){let n=t({type:"LIFO"});for(let t=0;t<=r;t++)n.push(e[t]);for(;n&&!n.isEmpty();){let e=yield n.pull();e&&n.push(e)}}(function(e,t=10){let r={},n=[...e],a=0,o=0,s=0;n.forEach((e=>{"#"===e&&s++})),s<t&&console.error(`Error: Not enough level markers (#) for data with depth level ${t}. Found ${s} level markers in actions: ${e.join(", ")}`);do{r[o]=[],o++}while(o<=t);return n.every((e=>"#"===e?(a++,!(a>t)):e.startsWith("?")?(r[a].push({type:"route",name:e.replace("?",""),level:a}),!0):e.startsWith("^")&&"^^"!==e?(r[a].push({type:"save",name:e.replace("^",""),level:a}),!0):"^^"===e?(r[a].push({type:"overwrite",name:"none",level:a}),!0):e.startsWith("+")?(r[a].push({type:"extendedRender",name:e.replace("+",""),level:a}),!0):e.startsWith("[]")?(r[a].push({type:"mix",name:e.replace("[]",""),level:a}),!0):e.startsWith(">")?(r[a].push({type:"data",name:e.replace(">",""),level:a}),!0):(""===e||r[a].push({type:"render",name:e,level:a}),!0))),r}(l,n),n);for(let t of u){let{type:n,name:a,level:l}=t;(i[l]||[]).forEach(((t,c)=>{let u=o(t);switch(n){case"route":switch(u){case"array":t.forEach(((e,r)=>{if(null==e)return;const n=o(e),i=f[a]({data:e,...p});null!=i&&("object"===n?t[r].text=s(e,i,f,E):t[r]=s(e,i,f,E))}));break;case"object":t.text=s(t,a,f,E)}break;case"save":g[a]=structuredClone(t);break;case"overwrite":r=structuredClone(t);break;case"data":switch(u){case"array":t.forEach(((e,r)=>t[r]=e instanceof Function?f[a]({data:e(),...p}):f[a]({data:e,...p})));break;case"object":i[l]=[f[a]({data:t,...p})];break;case"function":i[l]=[f[a]({data:t(),...p})];break;case"primitive":i[l]=f[a]({data:t,...p})}break;case"render":const d="function"==typeof f[a];switch(u){case"array":d?t.forEach(((e,r)=>{if(null==e)return;const n=o(e),s=f[a]({data:e,...p});null==s&&(t[r]=null),"object"===n?e.text=s:t[r]=s})):t.forEach(((e,r)=>{if(null==e)return;const n=o(e),i=s(e,a,f,E);null==i?t[r]=null:"object"===n?e.text=i:t[r]=i}));break;case"function":i[l]=f[a]({data:t(),...p});break;case"primitive":i[l]=d?f[a]({data:t,...p}):s(t,a,f,E);break;case"object":d?i[l][c].text=f[a]({data:t,...p}):t.text=s(t,a,f,E)}break;case"extendedRender":"function"==typeof f[a]&&i[0].forEach(((e,t)=>i[0][t]=f[a]({data:e,...p})));break;case"mix":if(""===a)switch(u){case"object":Object.keys(t).find((e=>e.includes("/")))?Object.entries(t).forEach((([e,t])=>i[l][e]=t.text)):i[l]=t.text;for(let m=l-1;m>=0;m--)i[m]=e({data:i[m],objectCallback:h});function h({value:e,breadcrumbs:t}){return i[l][t]?i[l][t]:e}break;case"array":t.forEach(((e,r)=>{if(r>0){let n=o(e);if(null==e)return;t[0]+="object"===n?`${e.text}`:`${e}`,t.toSpliced(r,1)}else{let r=o(e);if(t[0]="",null===r)return;t[0]="object"===r?`${e.text}`:`${e}`}})),t.length=1}else{let b=f[a]({data:t,...p}),y=o(b);switch(t.forEach(((e,r)=>t.splice(r,1))),t.length=0,y){case"primitive":t[0]=b;break;case"array":t.push(...b)}}}}))}if(i instanceof Array&&1===i.length&&i[0]instanceof Array&&(i=i[0]),null==i[0])return;let d=o(i[0]),m=i[0];switch(d){case"primitive":if(null==m)return;c[a]=m;break;case"object":if(null==m.text)return;c[a]=m.text;break;case"array":const e=o(m[0]);c[a]="object"===e?m.map((e=>e.text)).join(""):m.join("")}}})),m?y.push(u.map((e=>c[e.index])).join("<~>")):y.push(c.join(""))})),"array"===v?y:i?i.reduce(((e,t)=>"function"!=typeof t?e:t(e,E)),y.join("")):y.join("")))}return i?[!0,y]:y}}const l={default:{}};const c={build:i,get:function(e){if(!(e instanceof Array))return function(){return'Error: Argument "location" is a string. Should be an array. E.g. ["templateName", "storageName"].'};const[t,r="default"]=e;return l[r]?l[r][t]?l[r][t]:function(){return`Error: Template "${t}" does not exist in storage "${r}".`}:function(){return`Error: Storage "${r}" does not exist.`}},add:function(e,t,...r){const[n,a="default"]=e;if(null==t)return void console.warn(`Warning: Template ${a}/${n} is not added to storage. The template is null.`);let o=t,s=!0;if(l[a]||(l[a]={}),"function"!=typeof t){let e=i(t,!0,...r);s=e[0],o=e[1]}s?l[a][n]=o:console.error(`Error: Template "${n}" looks broken and is not added to storage.`)},list:function(e=["default"]){return e.map((e=>l[e]?Object.keys(l[e]):[])).flat()},clear:function(){Object.keys(l).forEach((e=>{"default"!=e?delete l[e]:l.default={}}))},remove:function(e){const[t,r="default"]=e;return l[r]?l[r][t]?void delete l[r][t]:`Error: Template "${t}" does not exist in storage "${r}".`:`Error: Storage "${r}" does not exist.`}};module.exports=c;
@@ -1 +1 @@
1
- import e from"@peter.naydenov/walk";import t from"@peter.naydenov/stack";function r(e){return function t(r){const{TG_PRX:a,TG_SFX:o,TG_SIZE_P:s,TG_SIZE_S:i}=e;let l,c,u,d=[];if("string"!=typeof r)return n("notAString");if(0==r.length)return[];if(l=r.indexOf(a),0<l&&d.push(r.slice(0,l)),-1==l)return d.push(r),d;{if(u=r.indexOf(a,l+s),c=r.indexOf(o),-1==c)return n("missingClosing");if(c<l)return n("closedBeforeOpened");if(c+=i,-1!=u&&u<c)return n("newBeforeClosed");d.push(r.slice(l,c));let e=t(r.slice(c));return d.concat(e)}}}function n(e){switch(e){case"notAString":return"Error: Template is not a string.";case"missingClosing":return"Error: Placeholder with missing closing tag.";case"closedBeforeOpened":return"Error: Placeholder closing tag without starting one.";case"newBeforeClosed":return"Error: Nested placeholders. Close placeholder before open new one.";default:return"Error: Unknown template error."}}var a={TG_PRX:"{{",TG_SFX:"}}",TG_SIZE_P:2,TG_SIZE_S:2};function o(e){return null==e?"null":"string"==typeof e||"number"==typeof e||"boolean"==typeof e?"primitive":"function"==typeof e?"function":e instanceof Array?"array":e instanceof Object?"object":void 0}function s(e,t,n,...o){e instanceof Object&&Object.entries(e).forEach((([t,r])=>{r instanceof Object&&(e[t]=r.text),r instanceof Array&&(e[t]=r[0])}));const s="function"==typeof n[t];return e=function(e={}){return"string"==typeof e?{text:e}:e}(e),s?n[t](e,...o):function(e,t){if(null==t)return null;const n=r(a)(e),o=a;return n.forEach(((e,r)=>{if(e.includes(o.TG_PRX)){const a=e.replace(o.TG_PRX,"").replace(o.TG_SFX,"").trim();t.hasOwnProperty(a)&&null!=t[a]&&(n[r]=t[a])}})),n.join("")}(n[t],e)}function i(n,i=!1,l={}){let{hasError:c,placeholders:u,chop:d,helpers:f,handshake:p,snippets:h}=function(e){const{template:t,helpers:n={},handshake:o}=e,{TG_PRX:s,TG_SFX:i}=a,l=[],c={},u="string"==typeof t?t.replace(/<!--[\s\S]*?-->/g,"").replace(/\s{2,}/g," "):t;let d=null;const f=r(a)(u);return"string"==typeof f?d=f:f.forEach(((e,t)=>{const r=RegExp(s+"\\s*(.*?)\\s*(?::\\s*(.*?)\\s*)?(?::\\s*(.*?)\\s*)?"+i,"g");if(e.includes(s)){const a=r.exec(e);if(!a)return;let o={index:t,data:(n=a[1],n||null),action:a[2]?a[2].split(",").map((e=>e.trim())):null,name:a[3]?a[3].trim():null};l.push(o),c[l.length-1]=o,o.name&&(c[o.name]=o)}var n})),l.forEach((e=>{e.action&&e.action.every((e=>"#"===e||"^^"===e||!(!e.startsWith("^")||"^^"===e)||(e.startsWith("?")&&(e=e.replace("?","")),e.startsWith("+")&&(e=e.replace("+","")),e.startsWith("[]")&&(e=e.replace("[]","")),e.startsWith(">")&&(e=e.replace(">","")),""===e||!!n[e]||(d=`Error: Missing helper: ${e}`,!1))))})),{hasError:d,placeholders:l,chop:f,helpers:n,handshake:o,snippets:c}}(n);if(c){function m(){return c}return i?[!1,m]:m}{let b=structuredClone(d);function y(r="render",n={},a={},...i){let c=!1;if(!["render","debug","snippets"].includes(r)&&!r.startsWith("snippets"))return`Error: Wrong command "${r}". Available commands: render, debug, snippets.`;if(r.startsWith("snippets")&&r.includes(":")){c=!0;let e=r.split(":").slice(1)[0].trim().split(",").map((e=>e.trim()));u=e.map((e=>h[e]))}else"snippets"===r&&(c=!0);if("string"==typeof n)switch(n){case"raw":return b.join("");case"demo":if(!p)return"Error: No handshake data.";n=p;break;case"handshake":return p?structuredClone(p):"Error: No handshake data.";case"placeholders":return u.map((e=>b[e.index])).join(", ");default:return`Error: Wrong instruction "${n}". Available instructions: raw, demo, handshake, placeholders.`}const d=[],m={};let y=o(n),g={...l,...a};return n=e({data:n}),"null"===y?b.join(""):("array"!==y&&(n=[n]),"null"===y?b.join(""):(n.forEach((r=>{u.forEach((n=>{const{index:a,data:i,action:l}=n,c=!l&&i,u=structuredClone(m),d={dependencies:g,memory:u};let p=r;if(i&&i.includes("/")?p.hasOwnProperty(i)?p=p[i]:i.split("/").forEach((e=>{p=p.hasOwnProperty(e)?p[e]:[]})):"@all"===i||null===i||"@root"===i?p=r:i&&(p=p[i]),c){switch(o(p)){case"function":return void(b[a]=p());case"primitive":return void(b[a]=p);case"array":return void("primitive"===o(p[0])&&(b[a]=p[0]));case"object":return void(p.text&&(b[a]=p.text))}}else{let{dataDeepLevel:n,nestedData:i}=function(t,r){const n=[];let a=0;if(t instanceof Function)return{dataDeepLevel:0,nestedData:[[t()]]};if(null==t)return{dataDeepLevel:0,nestedData:[null]};if("string"==typeof t)return{dataDeepLevel:0,nestedData:[[t]]};const o=structuredClone(t);return r.includes("#")?(e({data:o,objectCallback:function({key:e,value:t,breadcrumbs:r}){return e===r?(n[0]=[t],t):(a=r.split("/").length-1,n[a]||(n[a]=[]),n[a].push(t),t)}}),{dataDeepLevel:a,nestedData:n}):(n.push([o]),{dataDeepLevel:0,nestedData:n})}(p,l),c=function*(e,r){let n=t({type:"LIFO"});for(let t=0;t<=r;t++)n.push(e[t]);for(;n&&!n.isEmpty();){let e=yield n.pull();e&&n.push(e)}}(function(e,t=10){let r={},n=[...e],a=0,o=0,s=0;n.forEach((e=>{"#"===e&&s++})),s<t&&console.error(`Error: Not enough level markers (#) for data with depth level ${t}. Found ${s} level markers in actions: ${e.join(", ")}`);do{r[o]=[],o++}while(o<=t);return n.every((e=>"#"===e?(a++,!(a>t)):e.startsWith("?")?(r[a].push({type:"route",name:e.replace("?",""),level:a}),!0):e.startsWith("^")&&"^^"!==e?(r[a].push({type:"save",name:e.replace("^",""),level:a}),!0):"^^"===e?(r[a].push({type:"overwrite",name:"none",level:a}),!0):e.startsWith("+")?(r[a].push({type:"extendedRender",name:e.replace("+",""),level:a}),!0):e.startsWith("[]")?(r[a].push({type:"mix",name:e.replace("[]",""),level:a}),!0):e.startsWith(">")?(r[a].push({type:"data",name:e.replace(">",""),level:a}),!0):(""===e||r[a].push({type:"render",name:e,level:a}),!0))),r}(l,n),n);for(let t of c){let{type:n,name:a,level:l}=t;(i[l]||[]).forEach(((t,c)=>{let u=o(t);switch(n){case"route":switch(u){case"array":t.forEach(((e,r)=>{if(null==e)return;const n=o(e),i=f[a]({data:e,...d});null!=i&&("object"===n?t[r].text=s(e,i,f,g):t[r]=s(e,i,f,g))}));break;case"object":t.text=s(t,a,f,g)}break;case"save":m[a]=structuredClone(t);break;case"overwrite":r=structuredClone(t);break;case"data":switch(u){case"array":t.forEach(((e,r)=>t[r]=e instanceof Function?f[a]({data:e(),...d}):f[a]({data:e,...d})));break;case"object":i[l]=[f[a]({data:t,...d})];break;case"function":i[l]=[f[a]({data:t(),...d})];break;case"primitive":i[l]=f[a]({data:t,...d})}break;case"render":const p="function"==typeof f[a];switch(u){case"array":p?t.forEach(((e,r)=>{if(null==e)return;const n=o(e),s=f[a]({data:e,...d});null==s&&(t[r]=null),"object"===n?e.text=s:t[r]=s})):t.forEach(((e,r)=>{if(null==e)return;const n=o(e),i=s(e,a,f,g);null==i?t[r]=null:"object"===n?e.text=i:t[r]=i}));break;case"function":i[l]=f[a]({data:t(),...d});break;case"primitive":i[l]=p?f[a]({data:t,...d}):s(t,a,f,g);break;case"object":p?i[l][c].text=f[a]({data:t,...d}):t.text=s(t,a,f,g)}break;case"extendedRender":"function"==typeof f[a]&&i[0].forEach(((e,t)=>i[0][t]=f[a]({data:e,...d})));break;case"mix":if(""===a)switch(u){case"object":Object.keys(t).find((e=>e.includes("/")))?Object.entries(t).forEach((([e,t])=>i[l][e]=t.text)):i[l]=t.text;for(let b=l-1;b>=0;b--)i[b]=e({data:i[b],objectCallback:h});function h({value:e,breadcrumbs:t}){return i[l][t]?i[l][t]:e}break;case"array":t.forEach(((e,r)=>{if(r>0){let n=o(e);if(null==e)return;t[0]+="object"===n?`${e.text}`:`${e}`,t.toSpliced(r,1)}else{let r=o(e);if(t[0]="",null===r)return;t[0]="object"===r?`${e.text}`:`${e}`}})),t.length=1}else{let y=f[a]({data:t,...d}),v=o(y);switch(t.forEach(((e,r)=>t.splice(r,1))),t.length=0,v){case"primitive":t[0]=y;break;case"array":t.push(...y)}}}}))}if(i instanceof Array&&1===i.length&&i[0]instanceof Array&&(i=i[0]),null==i[0])return;let u=o(i[0]),h=i[0];switch(u){case"primitive":if(null==h)return;b[a]=h;break;case"object":if(null==h.text)return;b[a]=h.text;break;case"array":const e=o(h[0]);b[a]="object"===e?h.map((e=>e.text)).join(""):h.join("")}}})),c?d.push(u.map((e=>b[e.index])).join("<~>")):d.push(b.join(""))})),"array"===y?d:i?i.reduce(((e,t)=>"function"!=typeof t?e:t(e,g)),d.join("")):d.join("")))}return i?[!0,y]:y}}const l={default:{}};const c={build:i,get:function(e){if(!(e instanceof Array))return function(){return'Error: Argument "location" is a string. Should be an array. E.g. ["templateName", "storageName"].'};const[t,r="default"]=e;return l[r]?l[r][t]?l[r][t]:function(){return`Error: Template "${t}" does not exist in storage "${r}".`}:function(){return`Error: Storage "${r}" does not exist.`}},add:function(e,t,...r){const[n,a="default"]=e;if(null==t)return void console.warn(`Warning: Template ${a}/${n} is not added to storage. The template is null.`);let o=t,s=!0;if(l[a]||(l[a]={}),"function"!=typeof t){let e=i(t,!0,...r);s=e[0],o=e[1]}s?l[a][n]=o:console.error(`Error: Template "${n}" looks broken and is not added to storage.`)},list:function(e=["default"]){return e.map((e=>l[e]?Object.keys(l[e]):[])).flat()},clear:function(){Object.keys(l).forEach((e=>{"default"!=e?delete l[e]:l.default={}}))},remove:function(e){const[t,r="default"]=e;return l[r]?l[r][t]?void delete l[r][t]:`Error: Template "${t}" does not exist in storage "${r}".`:`Error: Storage "${r}" does not exist.`}};export{c as default};
1
+ import e from"@peter.naydenov/walk";import t from"@peter.naydenov/stack";function r(e){return function t(r){const{TG_PRX:a,TG_SFX:o,TG_SIZE_P:s,TG_SIZE_S:i}=e;let l,c,u,d=[];if("string"!=typeof r)return n("notAString");if(0==r.length)return[];if(l=r.indexOf(a),0<l&&d.push(r.slice(0,l)),-1==l)return d.push(r),d;{if(u=r.indexOf(a,l+s),c=r.indexOf(o),-1==c)return n("missingClosing");if(c<l)return n("closedBeforeOpened");if(c+=i,-1!=u&&u<c)return n("newBeforeClosed");d.push(r.slice(l,c));let e=t(r.slice(c));return d.concat(e)}}}function n(e){switch(e){case"notAString":return"Error: Template is not a string.";case"missingClosing":return"Error: Placeholder with missing closing tag.";case"closedBeforeOpened":return"Error: Placeholder closing tag without starting one.";case"newBeforeClosed":return"Error: Nested placeholders. Close placeholder before open new one.";default:return"Error: Unknown template error."}}var a={TG_PRX:"{{",TG_SFX:"}}",TG_SIZE_P:2,TG_SIZE_S:2};function o(e){return null==e?"null":"string"==typeof e||"number"==typeof e||"boolean"==typeof e?"primitive":"function"==typeof e?"function":e instanceof Array?"array":e instanceof Object?"object":void 0}function s(e,t,n,...o){e instanceof Object&&Object.entries(e).forEach((([t,r])=>{r instanceof Object&&(e[t]=r.text),r instanceof Array&&(e[t]=r[0])}));const s="function"==typeof n[t];return e=function(e={}){return"string"==typeof e?{text:e}:e}(e),s?n[t](e,...o):function(e,t){if(null==t)return null;const n=r(a)(e),o=a;return n.forEach(((e,r)=>{if(e.includes(o.TG_PRX)){const a=e.replace(o.TG_PRX,"").replace(o.TG_SFX,"").trim();t.hasOwnProperty(a)&&null!=t[a]&&(n[r]=t[a])}})),n.join("")}(n[t],e)}function i(n,i=!1,l={}){let{hasError:c,placeholders:u,chop:d,helpers:f,handshake:p,snippets:h}=function(e){const{template:t,helpers:n={},handshake:o}=e,{TG_PRX:s,TG_SFX:i}=a,l=[],c={},u="string"==typeof t?t.replace(/<!--[\s\S]*?-->/g,"").replace(/\s{2,}/g," "):t;let d=null;const f=r(a)(u);return"string"==typeof f?d=f:f.forEach(((e,t)=>{const r=RegExp(s+"\\s*(.*?)\\s*(?::\\s*(.*?)\\s*)?(?::\\s*(.*?)\\s*)?"+i,"g");if(e.includes(s)){const a=r.exec(e);if(!a)return;let o={index:t,data:(n=a[1],n||null),action:a[2]?a[2].split(",").map((e=>e.trim())):null,name:a[3]?a[3].trim():null};l.push(o),c[l.length-1]=o,o.name&&(c[o.name]=o)}var n})),l.forEach((e=>{e.action&&e.action.every((e=>"#"===e||"^^"===e||!(!e.startsWith("^")||"^^"===e)||(e.startsWith("?")&&(e=e.replace("?","")),e.startsWith("+")&&(e=e.replace("+","")),e.startsWith("[]")&&(e=e.replace("[]","")),e.startsWith(">")&&(e=e.replace(">","")),""===e||!!n[e]||(d=`Error: Missing helper: ${e}`,!1))))})),{hasError:d,placeholders:l,chop:f,helpers:n,handshake:o,snippets:c}}(n);if(c){function m(){return c}return i?[!1,m]:m}{const b=structuredClone(u);function y(r="render",n={},a={},...i){const c=structuredClone(d);let m=!1;if(!["render","debug","snippets"].includes(r)&&!r.startsWith("snippets"))return`Error: Wrong command "${r}". Available commands: render, debug, snippets.`;if(r.startsWith("snippets")&&r.includes(":")){m=!0;let e=r.split(":").slice(1)[0].trim().split(",").map((e=>e.trim()));u=e.map((e=>h[e]))}else"snippets"===r?m=!0:u=structuredClone(b);if("string"==typeof n)switch(n){case"raw":return c.join("");case"demo":if(!p)return"Error: No handshake data.";n=p;break;case"handshake":return p?structuredClone(p):"Error: No handshake data.";case"placeholders":return u.map((e=>c[e.index])).join(", ");default:return`Error: Wrong instruction "${n}". Available instructions: raw, demo, handshake, placeholders.`}const y=[],g={};let v=o(n),E={...l,...a};return n=e({data:n}),"null"===v?c.join(""):("array"!==v&&(n=[n]),"null"===v?c.join(""):(n.forEach((r=>{u.forEach((n=>{const{index:a,data:i,action:l}=n,u=!l&&i,d=structuredClone(g),p={dependencies:E,memory:d};let h=r;if(i&&i.includes("/")?h.hasOwnProperty(i)?h=h[i]:i.split("/").forEach((e=>{h=h.hasOwnProperty(e)?h[e]:[]})):"@all"===i||null===i||"@root"===i?h=r:i&&(h=h[i]),u){switch(o(h)){case"function":return void(c[a]=h());case"primitive":return void(c[a]=h);case"array":return void("primitive"===o(h[0])&&(c[a]=h[0]));case"object":return void(h.text&&(c[a]=h.text))}}else{let{dataDeepLevel:n,nestedData:i}=function(t,r){const n=[];let a=0;if(t instanceof Function)return{dataDeepLevel:0,nestedData:[[t()]]};if(null==t)return{dataDeepLevel:0,nestedData:[null]};if("string"==typeof t)return{dataDeepLevel:0,nestedData:[[t]]};const o=structuredClone(t);return r.includes("#")?(e({data:o,objectCallback:function({key:e,value:t,breadcrumbs:r}){return e===r?(n[0]=[t],t):(a=r.split("/").length-1,n[a]||(n[a]=[]),n[a].push(t),t)}}),{dataDeepLevel:a,nestedData:n}):(n.push([o]),{dataDeepLevel:0,nestedData:n})}(h,l),u=function*(e,r){let n=t({type:"LIFO"});for(let t=0;t<=r;t++)n.push(e[t]);for(;n&&!n.isEmpty();){let e=yield n.pull();e&&n.push(e)}}(function(e,t=10){let r={},n=[...e],a=0,o=0,s=0;n.forEach((e=>{"#"===e&&s++})),s<t&&console.error(`Error: Not enough level markers (#) for data with depth level ${t}. Found ${s} level markers in actions: ${e.join(", ")}`);do{r[o]=[],o++}while(o<=t);return n.every((e=>"#"===e?(a++,!(a>t)):e.startsWith("?")?(r[a].push({type:"route",name:e.replace("?",""),level:a}),!0):e.startsWith("^")&&"^^"!==e?(r[a].push({type:"save",name:e.replace("^",""),level:a}),!0):"^^"===e?(r[a].push({type:"overwrite",name:"none",level:a}),!0):e.startsWith("+")?(r[a].push({type:"extendedRender",name:e.replace("+",""),level:a}),!0):e.startsWith("[]")?(r[a].push({type:"mix",name:e.replace("[]",""),level:a}),!0):e.startsWith(">")?(r[a].push({type:"data",name:e.replace(">",""),level:a}),!0):(""===e||r[a].push({type:"render",name:e,level:a}),!0))),r}(l,n),n);for(let t of u){let{type:n,name:a,level:l}=t;(i[l]||[]).forEach(((t,c)=>{let u=o(t);switch(n){case"route":switch(u){case"array":t.forEach(((e,r)=>{if(null==e)return;const n=o(e),i=f[a]({data:e,...p});null!=i&&("object"===n?t[r].text=s(e,i,f,E):t[r]=s(e,i,f,E))}));break;case"object":t.text=s(t,a,f,E)}break;case"save":g[a]=structuredClone(t);break;case"overwrite":r=structuredClone(t);break;case"data":switch(u){case"array":t.forEach(((e,r)=>t[r]=e instanceof Function?f[a]({data:e(),...p}):f[a]({data:e,...p})));break;case"object":i[l]=[f[a]({data:t,...p})];break;case"function":i[l]=[f[a]({data:t(),...p})];break;case"primitive":i[l]=f[a]({data:t,...p})}break;case"render":const d="function"==typeof f[a];switch(u){case"array":d?t.forEach(((e,r)=>{if(null==e)return;const n=o(e),s=f[a]({data:e,...p});null==s&&(t[r]=null),"object"===n?e.text=s:t[r]=s})):t.forEach(((e,r)=>{if(null==e)return;const n=o(e),i=s(e,a,f,E);null==i?t[r]=null:"object"===n?e.text=i:t[r]=i}));break;case"function":i[l]=f[a]({data:t(),...p});break;case"primitive":i[l]=d?f[a]({data:t,...p}):s(t,a,f,E);break;case"object":d?i[l][c].text=f[a]({data:t,...p}):t.text=s(t,a,f,E)}break;case"extendedRender":"function"==typeof f[a]&&i[0].forEach(((e,t)=>i[0][t]=f[a]({data:e,...p})));break;case"mix":if(""===a)switch(u){case"object":Object.keys(t).find((e=>e.includes("/")))?Object.entries(t).forEach((([e,t])=>i[l][e]=t.text)):i[l]=t.text;for(let m=l-1;m>=0;m--)i[m]=e({data:i[m],objectCallback:h});function h({value:e,breadcrumbs:t}){return i[l][t]?i[l][t]:e}break;case"array":t.forEach(((e,r)=>{if(r>0){let n=o(e);if(null==e)return;t[0]+="object"===n?`${e.text}`:`${e}`,t.toSpliced(r,1)}else{let r=o(e);if(t[0]="",null===r)return;t[0]="object"===r?`${e.text}`:`${e}`}})),t.length=1}else{let b=f[a]({data:t,...p}),y=o(b);switch(t.forEach(((e,r)=>t.splice(r,1))),t.length=0,y){case"primitive":t[0]=b;break;case"array":t.push(...b)}}}}))}if(i instanceof Array&&1===i.length&&i[0]instanceof Array&&(i=i[0]),null==i[0])return;let d=o(i[0]),m=i[0];switch(d){case"primitive":if(null==m)return;c[a]=m;break;case"object":if(null==m.text)return;c[a]=m.text;break;case"array":const e=o(m[0]);c[a]="object"===e?m.map((e=>e.text)).join(""):m.join("")}}})),m?y.push(u.map((e=>c[e.index])).join("<~>")):y.push(c.join(""))})),"array"===v?y:i?i.reduce(((e,t)=>"function"!=typeof t?e:t(e,E)),y.join("")):y.join("")))}return i?[!0,y]:y}}const l={default:{}};const c={build:i,get:function(e){if(!(e instanceof Array))return function(){return'Error: Argument "location" is a string. Should be an array. E.g. ["templateName", "storageName"].'};const[t,r="default"]=e;return l[r]?l[r][t]?l[r][t]:function(){return`Error: Template "${t}" does not exist in storage "${r}".`}:function(){return`Error: Storage "${r}" does not exist.`}},add:function(e,t,...r){const[n,a="default"]=e;if(null==t)return void console.warn(`Warning: Template ${a}/${n} is not added to storage. The template is null.`);let o=t,s=!0;if(l[a]||(l[a]={}),"function"!=typeof t){let e=i(t,!0,...r);s=e[0],o=e[1]}s?l[a][n]=o:console.error(`Error: Template "${n}" looks broken and is not added to storage.`)},list:function(e=["default"]){return e.map((e=>l[e]?Object.keys(l[e]):[])).flat()},clear:function(){Object.keys(l).forEach((e=>{"default"!=e?delete l[e]:l.default={}}))},remove:function(e){const[t,r="default"]=e;return l[r]?l[r][t]?void delete l[r][t]:`Error: Template "${t}" does not exist in storage "${r}".`:`Error: Storage "${r}" does not exist.`}};export{c as default};
package/dist/morph.umd.js CHANGED
@@ -1 +1 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("@peter.naydenov/walk")):"function"==typeof define&&define.amd?define(["@peter.naydenov/walk"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).morph=t(e.walk)}(this,(function(e){"use strict";function t(e){return function t(n){const{TG_PRX:a,TG_SFX:o,TG_SIZE_P:s,TG_SIZE_S:i}=e;let l,c,u,f=[];if("string"!=typeof n)return r("notAString");if(0==n.length)return[];if(l=n.indexOf(a),0<l&&f.push(n.slice(0,l)),-1==l)return f.push(n),f;{if(u=n.indexOf(a,l+s),c=n.indexOf(o),-1==c)return r("missingClosing");if(c<l)return r("closedBeforeOpened");if(c+=i,-1!=u&&u<c)return r("newBeforeClosed");f.push(n.slice(l,c));let e=t(n.slice(c));return f.concat(e)}}}function r(e){switch(e){case"notAString":return"Error: Template is not a string.";case"missingClosing":return"Error: Placeholder with missing closing tag.";case"closedBeforeOpened":return"Error: Placeholder closing tag without starting one.";case"newBeforeClosed":return"Error: Nested placeholders. Close placeholder before open new one.";default:return"Error: Unknown template error."}}function*n(e,t){let r=function(e={}){let t=[],{type:r,limit:n,onLimit:a}=Object.assign({},{type:"FIFO",limit:!1,onLimit:"update"},e),o="LIFO"===r.toUpperCase(),s=!1;function i(e=1,r=0){let n=[];return r>0&&Array.from({length:r}).map((()=>t.pop())),1==e?t.pop():(Array.from({length:e}).map((()=>{let e=t.pop();null!=e&&n.push(e)})),n)}function l(e=1,r=0){let n=[],a=t.length-r;return e>1&&Array.from({length:e}).map((()=>{null!=t[a-1]&&n.push(t[a-1]),a--})),1==e?t[t.length-1]:n}function c(){}return c.prototype={pull:i,pullReverse:function(e=1,t=0){let r=i(e,t);return r instanceof Array?r.reverse():r},peek:l,peekReverse:function(e=1,t=0){const r=l(e,t);return r instanceof Array?r.reverse():r},getSize:()=>t.length,isEmpty:()=>0==t.length,reset:()=>(t=[],!0),debug:()=>[...t]},c.prototype.push=o?function(e){const r=e instanceof Array,o=r?e.length:1;let l=!1;if("full"!==a||!s){if(n&&r&&o>n&&(e=e.slice(0,-o+n)),n){const o=(r?e.length:1)+t.length;o>=n&&"full"===a&&(e=e.slice(0,-(o-n))),o>=n&&"update"===a&&(l=i(o-n))}return t=e instanceof Array?t.concat(e):t.concat([e]),s=!!n&&t.length===n,l||void 0}}:function(e){const r=e instanceof Array,o=r?e.length:1;let l=!1;if("full"!==a||!s){if(n&&r&&o>n&&(e=e.slice(o-n)),n){const o=(r?e.length:1)+t.length;o>=n&&"full"===a&&(e=e.slice(0,-(o-n))),o>=n&&"update"===a&&(l=i(o-n))}return t=r?e.reduce(((e,t)=>[t,...e]),t):[e].reduce(((e,t)=>[t,...e]),t),s=!!n&&t.length===n,l||void 0}},new c}({type:"LIFO"});for(let n=0;n<=t;n++)r.push(e[n]);for(;r&&!r.isEmpty();){let e=yield r.pull();e&&r.push(e)}}var a={TG_PRX:"{{",TG_SFX:"}}",TG_SIZE_P:2,TG_SIZE_S:2};function o(e){return null==e?"null":"string"==typeof e||"number"==typeof e||"boolean"==typeof e?"primitive":"function"==typeof e?"function":e instanceof Array?"array":e instanceof Object?"object":void 0}function s(e,r,n,...o){e instanceof Object&&Object.entries(e).forEach((([t,r])=>{r instanceof Object&&(e[t]=r.text),r instanceof Array&&(e[t]=r[0])}));const s="function"==typeof n[r];return e=function(e={}){return"string"==typeof e?{text:e}:e}(e),s?n[r](e,...o):function(e,r){if(null==r)return null;const n=t(a)(e),o=a;return n.forEach(((e,t)=>{if(e.includes(o.TG_PRX)){const a=e.replace(o.TG_PRX,"").replace(o.TG_SFX,"").trim();r.hasOwnProperty(a)&&null!=r[a]&&(n[t]=r[a])}})),n.join("")}(n[r],e)}function i(r,i=!1,l={}){let{hasError:c,placeholders:u,chop:f,helpers:p,handshake:d,snippets:h}=function(e){const{template:r,helpers:n={},handshake:o}=e,{TG_PRX:s,TG_SFX:i}=a,l=[],c={},u="string"==typeof r?r.replace(/<!--[\s\S]*?-->/g,"").replace(/\s{2,}/g," "):r;let f=null;const p=t(a)(u);return"string"==typeof p?f=p:p.forEach(((e,t)=>{const r=RegExp(s+"\\s*(.*?)\\s*(?::\\s*(.*?)\\s*)?(?::\\s*(.*?)\\s*)?"+i,"g");if(e.includes(s)){const a=r.exec(e);if(!a)return;let o={index:t,data:(n=a[1],n||null),action:a[2]?a[2].split(",").map((e=>e.trim())):null,name:a[3]?a[3].trim():null};l.push(o),c[l.length-1]=o,o.name&&(c[o.name]=o)}var n})),l.forEach((e=>{e.action&&e.action.every((e=>"#"===e||"^^"===e||!(!e.startsWith("^")||"^^"===e)||(e.startsWith("?")&&(e=e.replace("?","")),e.startsWith("+")&&(e=e.replace("+","")),e.startsWith("[]")&&(e=e.replace("[]","")),e.startsWith(">")&&(e=e.replace(">","")),""===e||!!n[e]||(f=`Error: Missing helper: ${e}`,!1))))})),{hasError:f,placeholders:l,chop:p,helpers:n,handshake:o,snippets:c}}(r);if(c){function m(){return c}return i?[!1,m]:m}{let y=structuredClone(f);function g(t="render",r={},a={},...i){let c=!1;if(!["render","debug","snippets"].includes(t)&&!t.startsWith("snippets"))return`Error: Wrong command "${t}". Available commands: render, debug, snippets.`;if(t.startsWith("snippets")&&t.includes(":")){c=!0;let e=t.split(":").slice(1)[0].trim().split(",").map((e=>e.trim()));u=e.map((e=>h[e]))}else"snippets"===t&&(c=!0);if("string"==typeof r)switch(r){case"raw":return y.join("");case"demo":if(!d)return"Error: No handshake data.";r=d;break;case"handshake":return d?structuredClone(d):"Error: No handshake data.";case"placeholders":return u.map((e=>y[e.index])).join(", ");default:return`Error: Wrong instruction "${r}". Available instructions: raw, demo, handshake, placeholders.`}const f=[],m={};let g=o(r),b={...l,...a};return r=e({data:r}),"null"===g?y.join(""):("array"!==g&&(r=[r]),"null"===g?y.join(""):(r.forEach((t=>{u.forEach((r=>{const{index:a,data:i,action:l}=r,c=!l&&i,u=structuredClone(m),f={dependencies:b,memory:u};let d=t;if(i&&i.includes("/")?d.hasOwnProperty(i)?d=d[i]:i.split("/").forEach((e=>{d=d.hasOwnProperty(e)?d[e]:[]})):"@all"===i||null===i||"@root"===i?d=t:i&&(d=d[i]),c){switch(o(d)){case"function":return void(y[a]=d());case"primitive":return void(y[a]=d);case"array":return void("primitive"===o(d[0])&&(y[a]=d[0]));case"object":return void(d.text&&(y[a]=d.text))}}else{let{dataDeepLevel:r,nestedData:i}=function(t,r){const n=[];let a=0;if(t instanceof Function)return{dataDeepLevel:0,nestedData:[[t()]]};if(null==t)return{dataDeepLevel:0,nestedData:[null]};if("string"==typeof t)return{dataDeepLevel:0,nestedData:[[t]]};const o=structuredClone(t);return r.includes("#")?(e({data:o,objectCallback:function({key:e,value:t,breadcrumbs:r}){return e===r?(n[0]=[t],t):(a=r.split("/").length-1,n[a]||(n[a]=[]),n[a].push(t),t)}}),{dataDeepLevel:a,nestedData:n}):(n.push([o]),{dataDeepLevel:0,nestedData:n})}(d,l),c=n(function(e,t=10){let r={},n=[...e],a=0,o=0,s=0;n.forEach((e=>{"#"===e&&s++})),s<t&&console.error(`Error: Not enough level markers (#) for data with depth level ${t}. Found ${s} level markers in actions: ${e.join(", ")}`);do{r[o]=[],o++}while(o<=t);return n.every((e=>"#"===e?(a++,!(a>t)):e.startsWith("?")?(r[a].push({type:"route",name:e.replace("?",""),level:a}),!0):e.startsWith("^")&&"^^"!==e?(r[a].push({type:"save",name:e.replace("^",""),level:a}),!0):"^^"===e?(r[a].push({type:"overwrite",name:"none",level:a}),!0):e.startsWith("+")?(r[a].push({type:"extendedRender",name:e.replace("+",""),level:a}),!0):e.startsWith("[]")?(r[a].push({type:"mix",name:e.replace("[]",""),level:a}),!0):e.startsWith(">")?(r[a].push({type:"data",name:e.replace(">",""),level:a}),!0):(""===e||r[a].push({type:"render",name:e,level:a}),!0))),r}(l,r),r);for(let r of c){let{type:n,name:a,level:l}=r;(i[l]||[]).forEach(((r,c)=>{let u=o(r);switch(n){case"route":switch(u){case"array":r.forEach(((e,t)=>{if(null==e)return;const n=o(e),i=p[a]({data:e,...f});null!=i&&("object"===n?r[t].text=s(e,i,p,b):r[t]=s(e,i,p,b))}));break;case"object":r.text=s(r,a,p,b)}break;case"save":m[a]=structuredClone(r);break;case"overwrite":t=structuredClone(r);break;case"data":switch(u){case"array":r.forEach(((e,t)=>r[t]=e instanceof Function?p[a]({data:e(),...f}):p[a]({data:e,...f})));break;case"object":i[l]=[p[a]({data:r,...f})];break;case"function":i[l]=[p[a]({data:r(),...f})];break;case"primitive":i[l]=p[a]({data:r,...f})}break;case"render":const d="function"==typeof p[a];switch(u){case"array":d?r.forEach(((e,t)=>{if(null==e)return;const n=o(e),s=p[a]({data:e,...f});null==s&&(r[t]=null),"object"===n?e.text=s:r[t]=s})):r.forEach(((e,t)=>{if(null==e)return;const n=o(e),i=s(e,a,p,b);null==i?r[t]=null:"object"===n?e.text=i:r[t]=i}));break;case"function":i[l]=p[a]({data:r(),...f});break;case"primitive":i[l]=d?p[a]({data:r,...f}):s(r,a,p,b);break;case"object":d?i[l][c].text=p[a]({data:r,...f}):r.text=s(r,a,p,b)}break;case"extendedRender":"function"==typeof p[a]&&i[0].forEach(((e,t)=>i[0][t]=p[a]({data:e,...f})));break;case"mix":if(""===a)switch(u){case"object":Object.keys(r).find((e=>e.includes("/")))?Object.entries(r).forEach((([e,t])=>i[l][e]=t.text)):i[l]=r.text;for(let y=l-1;y>=0;y--)i[y]=e({data:i[y],objectCallback:h});function h({value:e,breadcrumbs:t}){return i[l][t]?i[l][t]:e}break;case"array":r.forEach(((e,t)=>{if(t>0){let n=o(e);if(null==e)return;r[0]+="object"===n?`${e.text}`:`${e}`,r.toSpliced(t,1)}else{let t=o(e);if(r[0]="",null===t)return;r[0]="object"===t?`${e.text}`:`${e}`}})),r.length=1}else{let g=p[a]({data:r,...f}),v=o(g);switch(r.forEach(((e,t)=>r.splice(t,1))),r.length=0,v){case"primitive":r[0]=g;break;case"array":r.push(...g)}}}}))}if(i instanceof Array&&1===i.length&&i[0]instanceof Array&&(i=i[0]),null==i[0])return;let u=o(i[0]),h=i[0];switch(u){case"primitive":if(null==h)return;y[a]=h;break;case"object":if(null==h.text)return;y[a]=h.text;break;case"array":const e=o(h[0]);y[a]="object"===e?h.map((e=>e.text)).join(""):h.join("")}}})),c?f.push(u.map((e=>y[e.index])).join("<~>")):f.push(y.join(""))})),"array"===g?f:i?i.reduce(((e,t)=>"function"!=typeof t?e:t(e,b)),f.join("")):f.join("")))}return i?[!0,g]:g}}const l={default:{}};return{build:i,get:function(e){if(!(e instanceof Array))return function(){return'Error: Argument "location" is a string. Should be an array. E.g. ["templateName", "storageName"].'};const[t,r="default"]=e;return l[r]?l[r][t]?l[r][t]:function(){return`Error: Template "${t}" does not exist in storage "${r}".`}:function(){return`Error: Storage "${r}" does not exist.`}},add:function(e,t,...r){const[n,a="default"]=e;if(null==t)return void console.warn(`Warning: Template ${a}/${n} is not added to storage. The template is null.`);let o=t,s=!0;if(l[a]||(l[a]={}),"function"!=typeof t){let e=i(t,!0,...r);s=e[0],o=e[1]}s?l[a][n]=o:console.error(`Error: Template "${n}" looks broken and is not added to storage.`)},list:function(e=["default"]){return e.map((e=>l[e]?Object.keys(l[e]):[])).flat()},clear:function(){Object.keys(l).forEach((e=>{"default"!=e?delete l[e]:l.default={}}))},remove:function(e){const[t,r="default"]=e;return l[r]?l[r][t]?void delete l[r][t]:`Error: Template "${t}" does not exist in storage "${r}".`:`Error: Storage "${r}" does not exist.`}}}));
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("@peter.naydenov/walk")):"function"==typeof define&&define.amd?define(["@peter.naydenov/walk"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).morph=t(e.walk)}(this,(function(e){"use strict";function t(e){return function t(n){const{TG_PRX:a,TG_SFX:o,TG_SIZE_P:s,TG_SIZE_S:l}=e;let i,c,u,f=[];if("string"!=typeof n)return r("notAString");if(0==n.length)return[];if(i=n.indexOf(a),0<i&&f.push(n.slice(0,i)),-1==i)return f.push(n),f;{if(u=n.indexOf(a,i+s),c=n.indexOf(o),-1==c)return r("missingClosing");if(c<i)return r("closedBeforeOpened");if(c+=l,-1!=u&&u<c)return r("newBeforeClosed");f.push(n.slice(i,c));let e=t(n.slice(c));return f.concat(e)}}}function r(e){switch(e){case"notAString":return"Error: Template is not a string.";case"missingClosing":return"Error: Placeholder with missing closing tag.";case"closedBeforeOpened":return"Error: Placeholder closing tag without starting one.";case"newBeforeClosed":return"Error: Nested placeholders. Close placeholder before open new one.";default:return"Error: Unknown template error."}}function*n(e,t){let r=function(e={}){let t=[],{type:r,limit:n,onLimit:a}=Object.assign({},{type:"FIFO",limit:!1,onLimit:"update"},e),o="LIFO"===r.toUpperCase(),s=!1;function l(e=1,r=0){let n=[];return r>0&&Array.from({length:r}).map((()=>t.pop())),1==e?t.pop():(Array.from({length:e}).map((()=>{let e=t.pop();null!=e&&n.push(e)})),n)}function i(e=1,r=0){let n=[],a=t.length-r;return e>1&&Array.from({length:e}).map((()=>{null!=t[a-1]&&n.push(t[a-1]),a--})),1==e?t[t.length-1]:n}function c(){}return c.prototype={pull:l,pullReverse:function(e=1,t=0){let r=l(e,t);return r instanceof Array?r.reverse():r},peek:i,peekReverse:function(e=1,t=0){const r=i(e,t);return r instanceof Array?r.reverse():r},getSize:()=>t.length,isEmpty:()=>0==t.length,reset:()=>(t=[],!0),debug:()=>[...t]},c.prototype.push=o?function(e){const r=e instanceof Array,o=r?e.length:1;let i=!1;if("full"!==a||!s){if(n&&r&&o>n&&(e=e.slice(0,-o+n)),n){const o=(r?e.length:1)+t.length;o>=n&&"full"===a&&(e=e.slice(0,-(o-n))),o>=n&&"update"===a&&(i=l(o-n))}return t=e instanceof Array?t.concat(e):t.concat([e]),s=!!n&&t.length===n,i||void 0}}:function(e){const r=e instanceof Array,o=r?e.length:1;let i=!1;if("full"!==a||!s){if(n&&r&&o>n&&(e=e.slice(o-n)),n){const o=(r?e.length:1)+t.length;o>=n&&"full"===a&&(e=e.slice(0,-(o-n))),o>=n&&"update"===a&&(i=l(o-n))}return t=r?e.reduce(((e,t)=>[t,...e]),t):[e].reduce(((e,t)=>[t,...e]),t),s=!!n&&t.length===n,i||void 0}},new c}({type:"LIFO"});for(let n=0;n<=t;n++)r.push(e[n]);for(;r&&!r.isEmpty();){let e=yield r.pull();e&&r.push(e)}}var a={TG_PRX:"{{",TG_SFX:"}}",TG_SIZE_P:2,TG_SIZE_S:2};function o(e){return null==e?"null":"string"==typeof e||"number"==typeof e||"boolean"==typeof e?"primitive":"function"==typeof e?"function":e instanceof Array?"array":e instanceof Object?"object":void 0}function s(e,r,n,...o){e instanceof Object&&Object.entries(e).forEach((([t,r])=>{r instanceof Object&&(e[t]=r.text),r instanceof Array&&(e[t]=r[0])}));const s="function"==typeof n[r];return e=function(e={}){return"string"==typeof e?{text:e}:e}(e),s?n[r](e,...o):function(e,r){if(null==r)return null;const n=t(a)(e),o=a;return n.forEach(((e,t)=>{if(e.includes(o.TG_PRX)){const a=e.replace(o.TG_PRX,"").replace(o.TG_SFX,"").trim();r.hasOwnProperty(a)&&null!=r[a]&&(n[t]=r[a])}})),n.join("")}(n[r],e)}function l(r,l=!1,i={}){let{hasError:c,placeholders:u,chop:f,helpers:p,handshake:d,snippets:h}=function(e){const{template:r,helpers:n={},handshake:o}=e,{TG_PRX:s,TG_SFX:l}=a,i=[],c={},u="string"==typeof r?r.replace(/<!--[\s\S]*?-->/g,"").replace(/\s{2,}/g," "):r;let f=null;const p=t(a)(u);return"string"==typeof p?f=p:p.forEach(((e,t)=>{const r=RegExp(s+"\\s*(.*?)\\s*(?::\\s*(.*?)\\s*)?(?::\\s*(.*?)\\s*)?"+l,"g");if(e.includes(s)){const a=r.exec(e);if(!a)return;let o={index:t,data:(n=a[1],n||null),action:a[2]?a[2].split(",").map((e=>e.trim())):null,name:a[3]?a[3].trim():null};i.push(o),c[i.length-1]=o,o.name&&(c[o.name]=o)}var n})),i.forEach((e=>{e.action&&e.action.every((e=>"#"===e||"^^"===e||!(!e.startsWith("^")||"^^"===e)||(e.startsWith("?")&&(e=e.replace("?","")),e.startsWith("+")&&(e=e.replace("+","")),e.startsWith("[]")&&(e=e.replace("[]","")),e.startsWith(">")&&(e=e.replace(">","")),""===e||!!n[e]||(f=`Error: Missing helper: ${e}`,!1))))})),{hasError:f,placeholders:i,chop:p,helpers:n,handshake:o,snippets:c}}(r);if(c){function m(){return c}return l?[!1,m]:m}{const y=structuredClone(u);function g(t="render",r={},a={},...l){const c=structuredClone(f);let m=!1;if(!["render","debug","snippets"].includes(t)&&!t.startsWith("snippets"))return`Error: Wrong command "${t}". Available commands: render, debug, snippets.`;if(t.startsWith("snippets")&&t.includes(":")){m=!0;let e=t.split(":").slice(1)[0].trim().split(",").map((e=>e.trim()));u=e.map((e=>h[e]))}else"snippets"===t?m=!0:u=structuredClone(y);if("string"==typeof r)switch(r){case"raw":return c.join("");case"demo":if(!d)return"Error: No handshake data.";r=d;break;case"handshake":return d?structuredClone(d):"Error: No handshake data.";case"placeholders":return u.map((e=>c[e.index])).join(", ");default:return`Error: Wrong instruction "${r}". Available instructions: raw, demo, handshake, placeholders.`}const g=[],b={};let v=o(r),E={...i,...a};return r=e({data:r}),"null"===v?c.join(""):("array"!==v&&(r=[r]),"null"===v?c.join(""):(r.forEach((t=>{u.forEach((r=>{const{index:a,data:l,action:i}=r,u=!i&&l,f=structuredClone(b),d={dependencies:E,memory:f};let h=t;if(l&&l.includes("/")?h.hasOwnProperty(l)?h=h[l]:l.split("/").forEach((e=>{h=h.hasOwnProperty(e)?h[e]:[]})):"@all"===l||null===l||"@root"===l?h=t:l&&(h=h[l]),u){switch(o(h)){case"function":return void(c[a]=h());case"primitive":return void(c[a]=h);case"array":return void("primitive"===o(h[0])&&(c[a]=h[0]));case"object":return void(h.text&&(c[a]=h.text))}}else{let{dataDeepLevel:r,nestedData:l}=function(t,r){const n=[];let a=0;if(t instanceof Function)return{dataDeepLevel:0,nestedData:[[t()]]};if(null==t)return{dataDeepLevel:0,nestedData:[null]};if("string"==typeof t)return{dataDeepLevel:0,nestedData:[[t]]};const o=structuredClone(t);return r.includes("#")?(e({data:o,objectCallback:function({key:e,value:t,breadcrumbs:r}){return e===r?(n[0]=[t],t):(a=r.split("/").length-1,n[a]||(n[a]=[]),n[a].push(t),t)}}),{dataDeepLevel:a,nestedData:n}):(n.push([o]),{dataDeepLevel:0,nestedData:n})}(h,i),u=n(function(e,t=10){let r={},n=[...e],a=0,o=0,s=0;n.forEach((e=>{"#"===e&&s++})),s<t&&console.error(`Error: Not enough level markers (#) for data with depth level ${t}. Found ${s} level markers in actions: ${e.join(", ")}`);do{r[o]=[],o++}while(o<=t);return n.every((e=>"#"===e?(a++,!(a>t)):e.startsWith("?")?(r[a].push({type:"route",name:e.replace("?",""),level:a}),!0):e.startsWith("^")&&"^^"!==e?(r[a].push({type:"save",name:e.replace("^",""),level:a}),!0):"^^"===e?(r[a].push({type:"overwrite",name:"none",level:a}),!0):e.startsWith("+")?(r[a].push({type:"extendedRender",name:e.replace("+",""),level:a}),!0):e.startsWith("[]")?(r[a].push({type:"mix",name:e.replace("[]",""),level:a}),!0):e.startsWith(">")?(r[a].push({type:"data",name:e.replace(">",""),level:a}),!0):(""===e||r[a].push({type:"render",name:e,level:a}),!0))),r}(i,r),r);for(let r of u){let{type:n,name:a,level:i}=r;(l[i]||[]).forEach(((r,c)=>{let u=o(r);switch(n){case"route":switch(u){case"array":r.forEach(((e,t)=>{if(null==e)return;const n=o(e),l=p[a]({data:e,...d});null!=l&&("object"===n?r[t].text=s(e,l,p,E):r[t]=s(e,l,p,E))}));break;case"object":r.text=s(r,a,p,E)}break;case"save":b[a]=structuredClone(r);break;case"overwrite":t=structuredClone(r);break;case"data":switch(u){case"array":r.forEach(((e,t)=>r[t]=e instanceof Function?p[a]({data:e(),...d}):p[a]({data:e,...d})));break;case"object":l[i]=[p[a]({data:r,...d})];break;case"function":l[i]=[p[a]({data:r(),...d})];break;case"primitive":l[i]=p[a]({data:r,...d})}break;case"render":const f="function"==typeof p[a];switch(u){case"array":f?r.forEach(((e,t)=>{if(null==e)return;const n=o(e),s=p[a]({data:e,...d});null==s&&(r[t]=null),"object"===n?e.text=s:r[t]=s})):r.forEach(((e,t)=>{if(null==e)return;const n=o(e),l=s(e,a,p,E);null==l?r[t]=null:"object"===n?e.text=l:r[t]=l}));break;case"function":l[i]=p[a]({data:r(),...d});break;case"primitive":l[i]=f?p[a]({data:r,...d}):s(r,a,p,E);break;case"object":f?l[i][c].text=p[a]({data:r,...d}):r.text=s(r,a,p,E)}break;case"extendedRender":"function"==typeof p[a]&&l[0].forEach(((e,t)=>l[0][t]=p[a]({data:e,...d})));break;case"mix":if(""===a)switch(u){case"object":Object.keys(r).find((e=>e.includes("/")))?Object.entries(r).forEach((([e,t])=>l[i][e]=t.text)):l[i]=r.text;for(let m=i-1;m>=0;m--)l[m]=e({data:l[m],objectCallback:h});function h({value:e,breadcrumbs:t}){return l[i][t]?l[i][t]:e}break;case"array":r.forEach(((e,t)=>{if(t>0){let n=o(e);if(null==e)return;r[0]+="object"===n?`${e.text}`:`${e}`,r.toSpliced(t,1)}else{let t=o(e);if(r[0]="",null===t)return;r[0]="object"===t?`${e.text}`:`${e}`}})),r.length=1}else{let y=p[a]({data:r,...d}),g=o(y);switch(r.forEach(((e,t)=>r.splice(t,1))),r.length=0,g){case"primitive":r[0]=y;break;case"array":r.push(...y)}}}}))}if(l instanceof Array&&1===l.length&&l[0]instanceof Array&&(l=l[0]),null==l[0])return;let f=o(l[0]),m=l[0];switch(f){case"primitive":if(null==m)return;c[a]=m;break;case"object":if(null==m.text)return;c[a]=m.text;break;case"array":const e=o(m[0]);c[a]="object"===e?m.map((e=>e.text)).join(""):m.join("")}}})),m?g.push(u.map((e=>c[e.index])).join("<~>")):g.push(c.join(""))})),"array"===v?g:l?l.reduce(((e,t)=>"function"!=typeof t?e:t(e,E)),g.join("")):g.join("")))}return l?[!0,g]:g}}const i={default:{}};return{build:l,get:function(e){if(!(e instanceof Array))return function(){return'Error: Argument "location" is a string. Should be an array. E.g. ["templateName", "storageName"].'};const[t,r="default"]=e;return i[r]?i[r][t]?i[r][t]:function(){return`Error: Template "${t}" does not exist in storage "${r}".`}:function(){return`Error: Storage "${r}" does not exist.`}},add:function(e,t,...r){const[n,a="default"]=e;if(null==t)return void console.warn(`Warning: Template ${a}/${n} is not added to storage. The template is null.`);let o=t,s=!0;if(i[a]||(i[a]={}),"function"!=typeof t){let e=l(t,!0,...r);s=e[0],o=e[1]}s?i[a][n]=o:console.error(`Error: Template "${n}" looks broken and is not added to storage.`)},list:function(e=["default"]){return e.map((e=>i[e]?Object.keys(i[e]):[])).flat()},clear:function(){Object.keys(i).forEach((e=>{"default"!=e?delete i[e]:i.default={}}))},remove:function(e){const[t,r="default"]=e;return i[r]?i[r][t]?void delete i[r][t]:`Error: Template "${t}" does not exist in storage "${r}".`:`Error: Storage "${r}" does not exist.`}}}));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@peter.naydenov/morph",
3
3
  "description": "Template engine",
4
- "version": "3.0.0",
4
+ "version": "3.1.0",
5
5
  "license": "MIT",
6
6
  "author": "Peter Naydenov",
7
7
  "main": "./src/main.js",
@@ -27,13 +27,13 @@
27
27
  "@peter.naydenov/walk": "^5.0.1"
28
28
  },
29
29
  "devDependencies": {
30
- "@rollup/plugin-commonjs": "^28.0.3",
30
+ "@rollup/plugin-commonjs": "^28.0.6",
31
31
  "@rollup/plugin-node-resolve": "^16.0.1",
32
32
  "@rollup/plugin-terser": "^0.4.4",
33
33
  "c8": "^10.1.3",
34
- "chai": "5.2.0",
35
- "mocha": "11.6.0",
36
- "rollup": "^4.43.0"
34
+ "chai": "5.3.1",
35
+ "mocha": "11.7.1",
36
+ "rollup": "^4.46.3"
37
37
  },
38
38
  "repository": {
39
39
  "type": "git",
@@ -34,13 +34,15 @@ import walk from '@peter.naydenov/walk'
34
34
  */
35
35
  function build ( tpl, extra=false, buildDependencies={} ) {
36
36
  let { hasError, placeholders, chop, helpers, handshake, snippets } = _readTemplate ( tpl );
37
+
38
+
37
39
 
38
40
  if ( hasError ) {
39
41
  function fail () { return hasError }
40
42
  return extra ? [ false, fail ] : fail
41
43
  }
42
44
  else { // If NO Error:
43
- let cuts = structuredClone ( chop );
45
+ const originalPlaceholders = structuredClone ( placeholders );
44
46
  // *** Template recognition complete. Start building the rendering function -->
45
47
  /**
46
48
  * Processes template rendering commands with provided data, dependencies, and optional post-processing functions.
@@ -68,7 +70,9 @@ function build ( tpl, extra=false, buildDependencies={} ) {
68
70
  * success('snippets:header,footer', { ... });
69
71
  */
70
72
  function success ( command='render', d={}, dependencies={}, ...args ) {
73
+ const cuts = structuredClone ( chop )
71
74
  let onlySnippets = false;
75
+
72
76
  if ( ![ 'render', 'debug', 'snippets'].includes ( command ) && !command.startsWith('snippets') ) return `Error: Wrong command "${command}". Available commands: render, debug, snippets.`
73
77
 
74
78
  if ( command.startsWith ( 'snippets') && command.includes ( ':' ) ) {
@@ -83,6 +87,7 @@ function build ( tpl, extra=false, buildDependencies={} ) {
83
87
  else if ( command === 'snippets' ) {
84
88
  onlySnippets = true
85
89
  }
90
+ else placeholders = structuredClone ( originalPlaceholders ) // Reset placeholders if not snippets
86
91
 
87
92
  if ( typeof d === 'string' ) {
88
93
  switch ( d ) {
@@ -116,8 +121,6 @@ function build ( tpl, extra=false, buildDependencies={} ) {
116
121
 
117
122
  d.forEach ( dElement => {
118
123
  placeholders.forEach ( holder => { // Placeholders
119
-
120
-
121
124
  const
122
125
  { index, data, action } = holder // index - placeholder index, data - key of data, action - list of operations
123
126
  , dataOnly = !action && data
@@ -183,7 +186,7 @@ function build ( tpl, extra=false, buildDependencies={} ) {
183
186
  theData.forEach ( (d,i) => {
184
187
  if ( d == null ) return
185
188
  const dType = _defineDataType ( d )
186
- const routeName = helpers[name]( {data:d, ...extendArguments});
189
+ const routeName = helpers[name]( {data:d, ...extendArguments, full: theData });
187
190
  if ( routeName == null ) return
188
191
  if ( dType === 'object' ) theData[i]['text'] = render ( d, routeName, helpers, deps )
189
192
  else theData[i] = render ( d, routeName, helpers, deps )
@@ -203,16 +206,16 @@ function build ( tpl, extra=false, buildDependencies={} ) {
203
206
  case 'data':
204
207
  switch ( dataType ) {
205
208
  case 'array':
206
- theData.forEach ( (d,i) => theData[i] = ( d instanceof Function ) ? helpers[name]({ data:d(), ...extendArguments }) : helpers[name]( {data:d, ...extendArguments} ) )
209
+ theData.forEach ( (d,i) => theData[i] = ( d instanceof Function ) ? helpers[name]({ data:d(), ...extendArguments, full: theData }) : helpers[name]( {data:d, ...extendArguments, full: theData}) )
207
210
  break
208
211
  case 'object':
209
- nestedData[level] = [helpers[name]( {data:theData,...extendArguments} )]
212
+ nestedData[level] = [helpers[name]( {data:theData,...extendArguments, full: theData } )]
210
213
  break
211
214
  case 'function':
212
- nestedData[level] = [helpers[name]( {data:theData(),...extendArguments} )]
215
+ nestedData[level] = [helpers[name]( {data:theData(),...extendArguments, full: theData } )]
213
216
  break
214
217
  case 'primitive':
215
- nestedData[level] = helpers[name]( {data:theData,...extendArguments} )
218
+ nestedData[level] = helpers[name]( {data:theData,...extendArguments, full: theData } )
216
219
  break
217
220
  } // switch dataType
218
221
 
@@ -224,7 +227,7 @@ function build ( tpl, extra=false, buildDependencies={} ) {
224
227
  if ( isRenderFunction ) theData.forEach ( (d,i) => {
225
228
  if ( d == null ) return
226
229
  const dType = _defineDataType ( d );
227
- const text = helpers[name]( {data:d, ...extendArguments });
230
+ const text = helpers[name]( {data:d, ...extendArguments, full: theData });
228
231
 
229
232
  if ( text == null ) theData[i] = null
230
233
  if ( dType === 'object' ) d['text'] = text
@@ -242,14 +245,14 @@ function build ( tpl, extra=false, buildDependencies={} ) {
242
245
  })
243
246
  break
244
247
  case 'function':
245
- nestedData[level] = helpers[name]( {data:theData(), ...extendArguments} )
248
+ nestedData[level] = helpers[name]( {data:theData(), ...extendArguments, full: theData} )
246
249
  break
247
250
  case 'primitive':
248
- if ( isRenderFunction ) nestedData[level] = helpers[name]({ data:theData, ...extendArguments} )
251
+ if ( isRenderFunction ) nestedData[level] = helpers[name]({ data:theData, ...extendArguments, full: theData} )
249
252
  else nestedData[level] = render ( theData, name, helpers, deps )
250
253
  break
251
254
  case 'object':
252
- if ( isRenderFunction ) nestedData[level][iData]['text'] = helpers[name]({ data:theData, ...extendArguments} )
255
+ if ( isRenderFunction ) nestedData[level][iData]['text'] = helpers[name]({ data:theData, ...extendArguments, full: theData })
253
256
  else {
254
257
  theData [ 'text' ] = render ( theData, name, helpers, deps )
255
258
  }
@@ -260,7 +263,7 @@ function build ( tpl, extra=false, buildDependencies={} ) {
260
263
  // TODO: Test extendedRender
261
264
  const isValid = typeof helpers[name] === 'function'; // Render could be a function and template.
262
265
  if ( isValid ) {
263
- nestedData[0].forEach ( (d,i) => nestedData[0][i] = helpers[name]( {data:d, ...extendArguments} ) )
266
+ nestedData[0].forEach ( (d,i) => nestedData[0][i] = helpers[name]({ data:d, ...extendArguments, full: theData }) )
264
267
  }
265
268
  else {
266
269
  // TODO: Error...
@@ -358,7 +361,7 @@ function build ( tpl, extra=false, buildDependencies={} ) {
358
361
  if ( onlySnippets ) endData.push ( placeholders.map ( x => cuts[x.index] ).join ( '<~>' ) )
359
362
  else endData.push ( cuts.join ( '' ))
360
363
  }) // forEach d
361
-
364
+
362
365
  if ( topLevelType === 'array' ) return endData
363
366
  // Execute postprocess functions
364
367
  if (args) return args.reduce ( (acc, fn) => {
@@ -366,10 +369,9 @@ function build ( tpl, extra=false, buildDependencies={} ) {
366
369
  return fn ( acc, deps )
367
370
  }, endData.join ( '' ) )
368
371
  else return endData.join ( '' )
369
-
370
372
  } // success func.
371
373
  return extra ? [ true, success ] : success
372
- }
374
+ } // if no error
373
375
  } // build func.
374
376
 
375
377