@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 +17 -0
- package/README.md +2 -2
- package/dist/morph.cjs +1 -1
- package/dist/morph.esm.mjs +1 -1
- package/dist/morph.umd.js +1 -1
- package/package.json +5 -5
- package/src/methods/build.js +18 -16
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
|
|
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}{
|
|
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;
|
package/dist/morph.esm.mjs
CHANGED
|
@@ -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}{
|
|
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.
|
|
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.
|
|
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.
|
|
35
|
-
"mocha": "11.
|
|
36
|
-
"rollup": "^4.
|
|
34
|
+
"chai": "5.3.1",
|
|
35
|
+
"mocha": "11.7.1",
|
|
36
|
+
"rollup": "^4.46.3"
|
|
37
37
|
},
|
|
38
38
|
"repository": {
|
|
39
39
|
"type": "git",
|
package/src/methods/build.js
CHANGED
|
@@ -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
|
-
|
|
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](
|
|
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
|
|