@peter.naydenov/morph 2.0.1 → 2.1.1
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 +13 -1
- package/README.md +61 -0
- package/dist/morph.cjs +1 -1
- package/dist/morph.esm.mjs +1 -1
- package/dist/morph.umd.js +1 -1
- package/package.json +3 -3
- package/src/methods/_renderHolder.js +2 -2
- package/src/methods/build.js +19 -6
- package/src/methods/render.js +0 -1
package/Changelog.md
CHANGED
|
@@ -2,8 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
5
|
+
### 2.1.1 ( 2025-04-11 )
|
|
6
|
+
- [x] Fix: Value '0' is not rendered in helper templates;
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### 2.1.0 (2025-04-01)
|
|
11
|
+
- [x] Feature: Access a deep property as a breadcrumbs;
|
|
12
|
+
- [ ] Bug: Value '0' is not rendered in helper templates;
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
5
16
|
### 2.0.1 (2025-03-25)
|
|
6
17
|
- [x] Fix: Deep data render index;
|
|
18
|
+
- [ ] Bug: Value '0' is not rendered in helper templates;
|
|
7
19
|
|
|
8
20
|
|
|
9
21
|
|
|
@@ -12,7 +24,7 @@
|
|
|
12
24
|
- [x] Change in arguments format for helper functions;
|
|
13
25
|
- [x] Overwrite action introduced - when change in data should be available for all placeholders;
|
|
14
26
|
- [ ] Bug: Fix: Deep data render index;
|
|
15
|
-
|
|
27
|
+
- [ ] Bug: Value '0' is not rendered in helper templates;
|
|
16
28
|
|
|
17
29
|
|
|
18
30
|
### 1.2.3 (2025-03-17)
|
package/README.md
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
- Arguments for helper functions are named arguments;
|
|
14
14
|
- Memory action introduced - memory is available in helper functions as a named argument;
|
|
15
15
|
- Overwrite action introduced - when change in data should be available for all placeholders;
|
|
16
|
+
- Deep data-sources ( after version 2.1.0 );
|
|
16
17
|
|
|
17
18
|
|
|
18
19
|
|
|
@@ -204,6 +205,30 @@ Template placeholders can contain data-source and actions separated by ':'. Data
|
|
|
204
205
|
`{{ :someAction}}` // no data, but the result of the action will fill the placeholder
|
|
205
206
|
`{{ @all : someAction }}` // provide all the data to the action 'someAction'
|
|
206
207
|
```
|
|
208
|
+
### Deep data-sources ( after version 2.1.0 )
|
|
209
|
+
|
|
210
|
+
Setup a deep data-source by using breadcrumbs.
|
|
211
|
+
```js
|
|
212
|
+
const myTpl = {
|
|
213
|
+
template : `Profile: {{ me/stats : line }}.` // data-source will be data.me.stats
|
|
214
|
+
, helpers: {
|
|
215
|
+
line: `({{ height}}cm,{{ weight}}kg)`
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
const data = {
|
|
219
|
+
me : {
|
|
220
|
+
name: 'Peter'
|
|
221
|
+
, stats : {
|
|
222
|
+
age: 50
|
|
223
|
+
, height: 180
|
|
224
|
+
, weight: 66
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
const templateFn = morph.build ( myTpl );
|
|
229
|
+
const result = templateFn ( data );
|
|
230
|
+
// ---> Profile: (180cm,66kg).
|
|
231
|
+
```
|
|
207
232
|
|
|
208
233
|
|
|
209
234
|
|
|
@@ -251,6 +276,42 @@ Helpers are templates and functions that are used by actions to decorate the dat
|
|
|
251
276
|
|
|
252
277
|
|
|
253
278
|
|
|
279
|
+
## Good Practices and Examples
|
|
280
|
+
|
|
281
|
+
### Modify root data before start rendering
|
|
282
|
+
Sometimes we need to modify data and modification should be valid for all placeholders. Add in the begining of the template a placeholder like `{{ : blank, ^^, >myModification }}`, where myModification is a helper function that will modify the data, `^^` is overwrite action and `blank` is a render helper function that will return an empty string (placeholder disapears ). Look at the example here:
|
|
283
|
+
|
|
284
|
+
```js
|
|
285
|
+
const myTemplateDescription = {
|
|
286
|
+
template: `
|
|
287
|
+
{{ : blank, ^^ , >myModification }}
|
|
288
|
+
<h1>{{title}}</h1>
|
|
289
|
+
{{list: ul,[],li,a}}
|
|
290
|
+
`
|
|
291
|
+
, helpers: {
|
|
292
|
+
myModification : ({data}) => { // Modify original input data
|
|
293
|
+
data.list.forEach ( (item,i) => item.count = i )
|
|
294
|
+
return data
|
|
295
|
+
}
|
|
296
|
+
, blank : () => `` // use this helper function to remove the placeholder
|
|
297
|
+
, a: `<a href="{{href}}">{{ count }}.{{text}}</a>`
|
|
298
|
+
, li: `<li>{{text}}</li>`
|
|
299
|
+
, ul: `<ul>{{text}}</ul>`
|
|
300
|
+
}
|
|
301
|
+
, handshake: {
|
|
302
|
+
title: 'My title'
|
|
303
|
+
, list: [
|
|
304
|
+
{ text: 'Item 1', href: 'item1.com' }
|
|
305
|
+
, { text: 'Item 2', href: 'item2.com' }
|
|
306
|
+
, { text: 'Item 3', href: 'item3.com' }
|
|
307
|
+
]
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
const templateFn = morph.build ( myTemplateDescription );
|
|
311
|
+
const result = templateFn ( 'demo' );
|
|
312
|
+
// result ---> '<h1>My title</h1><ul><li><a href="item1.com">0.Item 1</a></li><li><a href="item2.com">1.Item 2</a></li><li><a href="item3.com">2.Item 3</a></li></ul>'
|
|
313
|
+
```
|
|
314
|
+
|
|
254
315
|
|
|
255
316
|
## Links
|
|
256
317
|
- [Release history](Changelog.md)
|
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:c}=e;let i,
|
|
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:c}=e;let l,i,u,f=[];if("string"!=typeof r)return n("notAString");if(0==r.length)return[];if(l=r.indexOf(a),0<l&&f.push(r.slice(0,l)),-1==l)return f.push(r),f;{if(u=r.indexOf(a,l+s),i=r.indexOf(o),-1==i)return n("missingClosing");if(i<l)return n("closedBeforeOpened");if(i+=c,-1!=u&&u<i)return n("newBeforeClosed");f.push(r.slice(l,i));let e=t(r.slice(i));return f.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)&&(n[r]=t[a])}})),n.join("")}(n[t],e)}function c(n,c=!1,l={}){const{hasError:i,placeholders:u,chop:f,helpers:d,handshake:p}=function(e){const{template:t,helpers:n={},handshake:o}=e,{TG_PRX:s,TG_SFX:c}=a,l=[],i="string"==typeof t?t.replace(/<!--[\s\S]*?-->/g,"").replace(/\s{2,}/g," "):t;let u=null;const f=r(a)(i);return"string"==typeof f?u=f:f.forEach(((e,t)=>{const r=RegExp(s+"\\s*(.*?)\\s*(?::\\s*(.*?)\\s*)?"+c,"g");if(e.includes(s)){const a=r.exec(e);l.push({index:t,data:(n=a[1],n||null),action:a[2]?a[2].split(",").map((e=>e.trim())):null})}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]||(u=`Error: Missing helper: ${e}`,!1))))})),{hasError:u,placeholders:l,chop:f,helpers:n,handshake:o}}(n);if(i){function h(){return i}return c?[!1,h]:h}{let b=structuredClone(f);function m(r={},n={},...a){const c=[],i={};let f=o(r),h={...l,...n};if(r=e({data:r}),"null"===f)return b.join("");if("string"==typeof r)switch(r){case"raw":return b.join("");case"demo":if(!p)return"Error: No handshake data.";f=o(r=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 command "${r}". Available commands: raw, demo, handshake, placeholders.`}return"array"!==f&&(r=[r]),"null"===f?b.join(""):(r.forEach((r=>{u.forEach((n=>{const{index:a,data:c,action:l}=n,u=!l&&c,f=structuredClone(i),p={dependencies:h,memory:f};let m=r;if(c&&c.includes("/")?c.split("/").forEach((e=>{m=m.hasOwnProperty(e)?m[e]:[]})):"@all"===c||null===c||"@root"===c?m=r:c&&(m=m[c]),u){switch(o(m)){case"function":return void(b[a]=m());case"primitive":return void(b[a]=m);case"array":return void("primitive"===o(m[0])&&(b[a]=m[0]));case"object":return void(m.text&&(b[a]=m.text))}}else{let{dataDeepLevel:n,nestedData:c}=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})}(m,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;(c[l]||[]).forEach(((t,u)=>{let f=o(t);switch(n){case"route":switch(f){case"array":t.forEach(((e,r)=>{if(null==e)return;const n=o(e),c=d[a]({data:e,...p});null!=c&&("object"===n?t[r].text=s(e,c,d,h):t[r]=s(e,c,d,h))}));break;case"object":t.text=s(t,a,d,h)}break;case"save":i[a]=structuredClone(t);break;case"overwrite":r=structuredClone(t);break;case"data":switch(f){case"array":t.forEach(((e,r)=>t[r]=e instanceof Function?d[a]({data:e(),...p}):d[a]({data:e,...p})));break;case"object":c[l]=[d[a]({data:t,...p})];break;case"function":c[l]=[d[a]({data:t(),...p})];break;case"primitive":c[l]=d[a]({data:t,...p})}break;case"render":const b="function"==typeof d[a];switch(f){case"array":b?t.forEach(((e,r)=>{if(null==e)return;const n=o(e),s=d[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),c=s(e,a,d,h);null==c?t[r]=null:"object"===n?e.text=c:t[r]=c}));break;case"function":c[l]=d[a]({data:t(),...p});break;case"primitive":c[l]=s(t,a,d,h);break;case"object":b?c[l][u].text=d[a]({data:t,...p}):t.text=s(t,a,d,h)}break;case"extendedRender":"function"==typeof d[a]&&c[0].forEach(((e,t)=>c[0][t]=d[a]({data:e,...p})));break;case"mix":if(""===a)switch(f){case"object":Object.keys(t).find((e=>e.includes("/")))?Object.entries(t).forEach((([e,t])=>c[l][e]=t.text)):c[l]=t.text;for(let y=l-1;y>=0;y--)c[y]=e({data:c[y],objectCallback:m});function m({value:e,breadcrumbs:t}){return c[l][t]?c[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 v=d[a]({data:t,...p}),g=o(v);switch(t.forEach(((e,r)=>t.splice(r,1))),t.length=0,g){case"primitive":t[0]=v;break;case"array":t.push(...v)}}}}))}if(c instanceof Array&&1===c.length&&c[0]instanceof Array&&(c=c[0]),null==c[0])return;let f=o(c[0]),y=c[0];switch(f){case"primitive":if(null==y)return;b[a]=y;break;case"object":if(null==y.text)return;b[a]=y.text;break;case"array":const e=o(y[0]);b[a]="object"===e?y.map((e=>e.text)).join(""):y.join("")}}})),c.push(b.join(""))})),"array"===f?c:a?a.reduce(((e,t)=>"function"!=typeof t?e:t(e,h)),c.join("")):c.join(""))}return c?[!0,m]:m}}const l={default:{}};const i={build:c,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=c(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=i;
|
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:c}=e;let i,
|
|
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:c}=e;let l,i,u,f=[];if("string"!=typeof r)return n("notAString");if(0==r.length)return[];if(l=r.indexOf(a),0<l&&f.push(r.slice(0,l)),-1==l)return f.push(r),f;{if(u=r.indexOf(a,l+s),i=r.indexOf(o),-1==i)return n("missingClosing");if(i<l)return n("closedBeforeOpened");if(i+=c,-1!=u&&u<i)return n("newBeforeClosed");f.push(r.slice(l,i));let e=t(r.slice(i));return f.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)&&(n[r]=t[a])}})),n.join("")}(n[t],e)}function c(n,c=!1,l={}){const{hasError:i,placeholders:u,chop:f,helpers:d,handshake:p}=function(e){const{template:t,helpers:n={},handshake:o}=e,{TG_PRX:s,TG_SFX:c}=a,l=[],i="string"==typeof t?t.replace(/<!--[\s\S]*?-->/g,"").replace(/\s{2,}/g," "):t;let u=null;const f=r(a)(i);return"string"==typeof f?u=f:f.forEach(((e,t)=>{const r=RegExp(s+"\\s*(.*?)\\s*(?::\\s*(.*?)\\s*)?"+c,"g");if(e.includes(s)){const a=r.exec(e);l.push({index:t,data:(n=a[1],n||null),action:a[2]?a[2].split(",").map((e=>e.trim())):null})}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]||(u=`Error: Missing helper: ${e}`,!1))))})),{hasError:u,placeholders:l,chop:f,helpers:n,handshake:o}}(n);if(i){function h(){return i}return c?[!1,h]:h}{let m=structuredClone(f);function b(r={},n={},...a){const c=[],i={};let f=o(r),h={...l,...n};if(r=e({data:r}),"null"===f)return m.join("");if("string"==typeof r)switch(r){case"raw":return m.join("");case"demo":if(!p)return"Error: No handshake data.";f=o(r=p);break;case"handshake":return p?structuredClone(p):"Error: No handshake data.";case"placeholders":return u.map((e=>m[e.index])).join(", ");default:return`Error: Wrong command "${r}". Available commands: raw, demo, handshake, placeholders.`}return"array"!==f&&(r=[r]),"null"===f?m.join(""):(r.forEach((r=>{u.forEach((n=>{const{index:a,data:c,action:l}=n,u=!l&&c,f=structuredClone(i),p={dependencies:h,memory:f};let b=r;if(c&&c.includes("/")?c.split("/").forEach((e=>{b=b.hasOwnProperty(e)?b[e]:[]})):"@all"===c||null===c||"@root"===c?b=r:c&&(b=b[c]),u){switch(o(b)){case"function":return void(m[a]=b());case"primitive":return void(m[a]=b);case"array":return void("primitive"===o(b[0])&&(m[a]=b[0]));case"object":return void(b.text&&(m[a]=b.text))}}else{let{dataDeepLevel:n,nestedData:c}=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})}(b,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;(c[l]||[]).forEach(((t,u)=>{let f=o(t);switch(n){case"route":switch(f){case"array":t.forEach(((e,r)=>{if(null==e)return;const n=o(e),c=d[a]({data:e,...p});null!=c&&("object"===n?t[r].text=s(e,c,d,h):t[r]=s(e,c,d,h))}));break;case"object":t.text=s(t,a,d,h)}break;case"save":i[a]=structuredClone(t);break;case"overwrite":r=structuredClone(t);break;case"data":switch(f){case"array":t.forEach(((e,r)=>t[r]=e instanceof Function?d[a]({data:e(),...p}):d[a]({data:e,...p})));break;case"object":c[l]=[d[a]({data:t,...p})];break;case"function":c[l]=[d[a]({data:t(),...p})];break;case"primitive":c[l]=d[a]({data:t,...p})}break;case"render":const m="function"==typeof d[a];switch(f){case"array":m?t.forEach(((e,r)=>{if(null==e)return;const n=o(e),s=d[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),c=s(e,a,d,h);null==c?t[r]=null:"object"===n?e.text=c:t[r]=c}));break;case"function":c[l]=d[a]({data:t(),...p});break;case"primitive":c[l]=s(t,a,d,h);break;case"object":m?c[l][u].text=d[a]({data:t,...p}):t.text=s(t,a,d,h)}break;case"extendedRender":"function"==typeof d[a]&&c[0].forEach(((e,t)=>c[0][t]=d[a]({data:e,...p})));break;case"mix":if(""===a)switch(f){case"object":Object.keys(t).find((e=>e.includes("/")))?Object.entries(t).forEach((([e,t])=>c[l][e]=t.text)):c[l]=t.text;for(let y=l-1;y>=0;y--)c[y]=e({data:c[y],objectCallback:b});function b({value:e,breadcrumbs:t}){return c[l][t]?c[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 v=d[a]({data:t,...p}),g=o(v);switch(t.forEach(((e,r)=>t.splice(r,1))),t.length=0,g){case"primitive":t[0]=v;break;case"array":t.push(...v)}}}}))}if(c instanceof Array&&1===c.length&&c[0]instanceof Array&&(c=c[0]),null==c[0])return;let f=o(c[0]),y=c[0];switch(f){case"primitive":if(null==y)return;m[a]=y;break;case"object":if(null==y.text)return;m[a]=y.text;break;case"array":const e=o(y[0]);m[a]="object"===e?y.map((e=>e.text)).join(""):y.join("")}}})),c.push(m.join(""))})),"array"===f?c:a?a.reduce(((e,t)=>"function"!=typeof t?e:t(e,h)),c.join("")):c.join(""))}return c?[!0,b]:b}}const l={default:{}};const i={build:c,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=c(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{i 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:l,TG_SIZE_S:s}=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+l),c=n.indexOf(o),-1==c)return r("missingClosing");if(c<i)return r("closedBeforeOpened");if(c+=s,-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(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);if(!r.includes("#"))return n.push([o]),{dataDeepLevel:0,nestedData:n};return 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}}function*a(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(),l=!1;function s(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:s,pullReverse:function(e=1,t=0){let r=s(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||!l){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=s(o-n))}return t=e instanceof Array?t.concat(e):t.concat([e]),l=!!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||!l){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=s(o-n))}return t=r?e.reduce(((e,t)=>[t,...e]),t):[e].reduce(((e,t)=>[t,...e]),t),l=!!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 o={TG_PRX:"{{",TG_SFX:"}}",TG_SIZE_P:2,TG_SIZE_S:2};function l(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,...a){e instanceof Object&&Object.entries(e).forEach((([t,r])=>{r instanceof Object&&(e[t]=r.text),r instanceof Array&&(e[t]=r[0])}));const l="function"==typeof n[r];return e=function(e={}){return"string"==typeof e?{text:e}:e}(e),l?n[r](e,...a):function(e,r){if(null==r)return null;const n=t(o)(e),a=o;return n.forEach(((e,t)=>{if(e.includes(a.TG_PRX)){const o=e.replace(a.TG_PRX,"").replace(a.TG_SFX,"").trim();r[o]&&(n[t]=r[o])}})),n.join("")}(n[r],e)}function i(r,i=!1,c={}){const{hasError:u,placeholders:f,chop:d,helpers:p,handshake:h}=function(e){const{template:r,helpers:n={},handshake:a}=e,{TG_PRX:l,TG_SFX:s}=o,i=[],c="string"==typeof r?r.replace(/<!--[\s\S]*?-->/g,"").replace(/\s{2,}/g," "):r;let u=null;const f=t(o)(c);return"string"==typeof f?u=f:f.forEach(((e,t)=>{const r=RegExp(l+"\\s*(.*?)\\s*(?::\\s*(.*?)\\s*)?"+s,"g");if(e.includes(l)){const a=r.exec(e);i.push({index:t,data:(n=a[1],n||null),action:a[2]?a[2].split(",").map((e=>e.trim())):null})}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]||(u=`Error: Missing helper: ${e}`,!1))))})),{hasError:u,placeholders:i,chop:f,helpers:n,handshake:a}}(r);if(u){function m(){return u}return i?[!1,m]:m}{let y=structuredClone(d);function g(t={},r={},...o){const i=[],u={};let d=l(t),m={...c,...r};if(t=e({data:t}),"null"===d)return y.join("");if("string"==typeof t)switch(t){case"raw":return y.join("");case"demo":if(!h)return"Error: No handshake data.";d=l(t=h);break;case"handshake":return h?structuredClone(h):"Error: No handshake data.";case"placeholders":return f.map((e=>y[e.index])).join(", ");default:return`Error: Wrong command "${t}". Available commands: raw, demo, handshake, placeholders.`}return"array"!==d&&(t=[t]),"null"===d?y.join(""):(t.forEach((t=>{f.forEach((r=>{const{index:o,data:i,action:c}=r,f=!c&&i,d=structuredClone(u),h={dependencies:m,memory:d};if(f){const e=t[i];switch(l(e)){case"function":return void(y[o]=e());case"primitive":return void(y[o]=e);case"array":return void("primitive"===l(e[0])&&(y[o]=e[0]));case"object":return void(e.text&&(y[o]=e.text))}}else{let{dataDeepLevel:r,nestedData:f}=n("@all"===i||null===i||"@root"===i?t:t[i],c),d=a(function(e,t=10){let r={},n=[...e],a=0,o=0,l=0;n.forEach((e=>{"#"===e&&l++})),l<t&&console.error(`Error: Not enough level markers (#) for data with depth level ${t}. Found ${l} 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}(c,r),r);for(let r of d){let{type:n,name:a,level:o}=r;(f[o]||[]).forEach(((r,i)=>{let c=l(r);switch(n){case"route":switch(c){case"array":r.forEach(((e,t)=>{if(null==e)return;const n=l(e),o=p[a]({data:e,...h});null!=o&&("object"===n?r[t].text=s(e,o,p,m):r[t]=s(e,o,p,m))}));break;case"object":r.text=s(r,a,p,m)}break;case"save":u[a]=structuredClone(r);break;case"overwrite":t=structuredClone(r);break;case"data":switch(c){case"array":r.forEach(((e,t)=>r[t]=e instanceof Function?p[a]({data:e(),...h}):p[a]({data:e,...h})));break;case"object":f[o]=[p[a]({data:r,...h})];break;case"function":f[o]=[p[a]({data:r(),...h})];break;case"primitive":f[o]=p[a]({data:r,...h})}break;case"render":const d="function"==typeof p[a];switch(c){case"array":d?r.forEach(((e,t)=>{if(null==e)return;const n=l(e),o=p[a]({data:e,...h});null==o&&(r[t]=null),"object"===n?e.text=o:r[t]=o})):r.forEach(((e,t)=>{if(null==e)return;const n=l(e),o=s(e,a,p,m);null==o?r[t]=null:"object"===n?e.text=o:r[t]=o}));break;case"function":f[o]=p[a]({data:r(),...h});break;case"primitive":f[o]=s(r,a,p,m);break;case"object":d?f[o][i].text=p[a]({data:r,...h}):r.text=s(r,a,p,m)}break;case"extendedRender":"function"==typeof p[a]&&f[0].forEach(((e,t)=>f[0][t]=p[a]({data:e,...h})));break;case"mix":if(""===a)switch(c){case"object":Object.keys(r).find((e=>e.includes("/")))?Object.entries(r).forEach((([e,t])=>f[o][e]=t.text)):f[o]=r.text;for(let g=o-1;g>=0;g--)f[g]=e({data:f[g],objectCallback:y});function y({value:e,breadcrumbs:t}){return f[o][t]?f[o][t]:e}break;case"array":r.forEach(((e,t)=>{if(t>0){let n=l(e);if(null==e)return;r[0]+="object"===n?`${e.text}`:`${e}`,r.toSpliced(t,1)}else{let t=l(e);if(r[0]="",null===t)return;r[0]="object"===t?`${e.text}`:`${e}`}})),r.length=1}else{let b=p[a]({data:r,...h}),v=l(b);switch(r.forEach(((e,t)=>r.splice(t,1))),r.length=0,v){case"primitive":r[0]=b;break;case"array":r.push(...b)}}}}))}if(f instanceof Array&&1===f.length&&f[0]instanceof Array&&(f=f[0]),null==f[0])return;let g=l(f[0]),b=f[0];switch(g){case"primitive":if(null==b)return;y[o]=b;break;case"object":if(null==b.text)return;y[o]=b.text;break;case"array":const e=l(b[0]);y[o]="object"===e?b.map((e=>e.text)).join(""):b.join("")}}})),i.push(y.join(""))})),"array"===d?i:o?o.reduce(((e,t)=>"function"!=typeof t?e:t(e,m)),i.join("")):i.join(""))}return i?[!0,g]:g}}const c={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 c[r]?c[r][t]?c[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,l=!0;if(c[a]||(c[a]={}),"function"!=typeof t){let e=i(t,!0,...r);l=e[0],o=e[1]}l?c[a][n]=o:console.error(`Error: Template "${n}" looks broken and is not added to storage.`)},list:function(e=["default"]){return e.map((e=>c[e]?Object.keys(c[e]):[])).flat()},clear:function(){Object.keys(c).forEach((e=>{"default"!=e?delete c[e]:c.default={}}))},remove:function(e){const[t,r="default"]=e;return c[r]?c[r][t]?void delete c[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:l,TG_SIZE_S:s}=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+l),c=n.indexOf(o),-1==c)return r("missingClosing");if(c<i)return r("closedBeforeOpened");if(c+=s,-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(),l=!1;function s(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:s,pullReverse:function(e=1,t=0){let r=s(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||!l){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=s(o-n))}return t=e instanceof Array?t.concat(e):t.concat([e]),l=!!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||!l){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=s(o-n))}return t=r?e.reduce(((e,t)=>[t,...e]),t):[e].reduce(((e,t)=>[t,...e]),t),l=!!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 l(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 l="function"==typeof n[r];return e=function(e={}){return"string"==typeof e?{text:e}:e}(e),l?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)&&(n[t]=r[a])}})),n.join("")}(n[r],e)}function s(r,s=!1,i={}){const{hasError:c,placeholders:u,chop:f,helpers:d,handshake:p}=function(e){const{template:r,helpers:n={},handshake:o}=e,{TG_PRX:l,TG_SFX:s}=a,i=[],c="string"==typeof r?r.replace(/<!--[\s\S]*?-->/g,"").replace(/\s{2,}/g," "):r;let u=null;const f=t(a)(c);return"string"==typeof f?u=f:f.forEach(((e,t)=>{const r=RegExp(l+"\\s*(.*?)\\s*(?::\\s*(.*?)\\s*)?"+s,"g");if(e.includes(l)){const a=r.exec(e);i.push({index:t,data:(n=a[1],n||null),action:a[2]?a[2].split(",").map((e=>e.trim())):null})}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]||(u=`Error: Missing helper: ${e}`,!1))))})),{hasError:u,placeholders:i,chop:f,helpers:n,handshake:o}}(r);if(c){function h(){return c}return s?[!1,h]:h}{let y=structuredClone(f);function m(t={},r={},...a){const s=[],c={};let f=o(t),h={...i,...r};if(t=e({data:t}),"null"===f)return y.join("");if("string"==typeof t)switch(t){case"raw":return y.join("");case"demo":if(!p)return"Error: No handshake data.";f=o(t=p);break;case"handshake":return p?structuredClone(p):"Error: No handshake data.";case"placeholders":return u.map((e=>y[e.index])).join(", ");default:return`Error: Wrong command "${t}". Available commands: raw, demo, handshake, placeholders.`}return"array"!==f&&(t=[t]),"null"===f?y.join(""):(t.forEach((t=>{u.forEach((r=>{const{index:a,data:s,action:i}=r,u=!i&&s,f=structuredClone(c),p={dependencies:h,memory:f};let m=t;if(s&&s.includes("/")?s.split("/").forEach((e=>{m=m.hasOwnProperty(e)?m[e]:[]})):"@all"===s||null===s||"@root"===s?m=t:s&&(m=m[s]),u){switch(o(m)){case"function":return void(y[a]=m());case"primitive":return void(y[a]=m);case"array":return void("primitive"===o(m[0])&&(y[a]=m[0]));case"object":return void(m.text&&(y[a]=m.text))}}else{let{dataDeepLevel:r,nestedData:s}=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})}(m,i),u=n(function(e,t=10){let r={},n=[...e],a=0,o=0,l=0;n.forEach((e=>{"#"===e&&l++})),l<t&&console.error(`Error: Not enough level markers (#) for data with depth level ${t}. Found ${l} 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;(s[i]||[]).forEach(((r,u)=>{let f=o(r);switch(n){case"route":switch(f){case"array":r.forEach(((e,t)=>{if(null==e)return;const n=o(e),s=d[a]({data:e,...p});null!=s&&("object"===n?r[t].text=l(e,s,d,h):r[t]=l(e,s,d,h))}));break;case"object":r.text=l(r,a,d,h)}break;case"save":c[a]=structuredClone(r);break;case"overwrite":t=structuredClone(r);break;case"data":switch(f){case"array":r.forEach(((e,t)=>r[t]=e instanceof Function?d[a]({data:e(),...p}):d[a]({data:e,...p})));break;case"object":s[i]=[d[a]({data:r,...p})];break;case"function":s[i]=[d[a]({data:r(),...p})];break;case"primitive":s[i]=d[a]({data:r,...p})}break;case"render":const y="function"==typeof d[a];switch(f){case"array":y?r.forEach(((e,t)=>{if(null==e)return;const n=o(e),l=d[a]({data:e,...p});null==l&&(r[t]=null),"object"===n?e.text=l:r[t]=l})):r.forEach(((e,t)=>{if(null==e)return;const n=o(e),s=l(e,a,d,h);null==s?r[t]=null:"object"===n?e.text=s:r[t]=s}));break;case"function":s[i]=d[a]({data:r(),...p});break;case"primitive":s[i]=l(r,a,d,h);break;case"object":y?s[i][u].text=d[a]({data:r,...p}):r.text=l(r,a,d,h)}break;case"extendedRender":"function"==typeof d[a]&&s[0].forEach(((e,t)=>s[0][t]=d[a]({data:e,...p})));break;case"mix":if(""===a)switch(f){case"object":Object.keys(r).find((e=>e.includes("/")))?Object.entries(r).forEach((([e,t])=>s[i][e]=t.text)):s[i]=r.text;for(let g=i-1;g>=0;g--)s[g]=e({data:s[g],objectCallback:m});function m({value:e,breadcrumbs:t}){return s[i][t]?s[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 b=d[a]({data:r,...p}),v=o(b);switch(r.forEach(((e,t)=>r.splice(t,1))),r.length=0,v){case"primitive":r[0]=b;break;case"array":r.push(...b)}}}}))}if(s instanceof Array&&1===s.length&&s[0]instanceof Array&&(s=s[0]),null==s[0])return;let f=o(s[0]),g=s[0];switch(f){case"primitive":if(null==g)return;y[a]=g;break;case"object":if(null==g.text)return;y[a]=g.text;break;case"array":const e=o(g[0]);y[a]="object"===e?g.map((e=>e.text)).join(""):g.join("")}}})),s.push(y.join(""))})),"array"===f?s:a?a.reduce(((e,t)=>"function"!=typeof t?e:t(e,h)),s.join("")):s.join(""))}return s?[!0,m]:m}}const i={default:{}};return{build:s,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,l=!0;if(i[a]||(i[a]={}),"function"!=typeof t){let e=s(t,!0,...r);l=e[0],o=e[1]}l?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": "2.
|
|
4
|
+
"version": "2.1.1",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Peter Naydenov",
|
|
7
7
|
"main": "./src/main.js",
|
|
@@ -33,11 +33,11 @@
|
|
|
33
33
|
"c8": "^10.1.3",
|
|
34
34
|
"chai": "5.2.0",
|
|
35
35
|
"mocha": "11.1.0",
|
|
36
|
-
"rollup": "^4.
|
|
36
|
+
"rollup": "^4.39.0"
|
|
37
37
|
},
|
|
38
38
|
"repository": {
|
|
39
39
|
"type": "git",
|
|
40
|
-
"url": "https://github.com/PeterNaydenov/morph.git"
|
|
40
|
+
"url": "git+https://github.com/PeterNaydenov/morph.git"
|
|
41
41
|
},
|
|
42
42
|
"c8": {
|
|
43
43
|
"include": [
|
|
@@ -6,7 +6,7 @@ import settings from './settings.js'
|
|
|
6
6
|
function _renderHolder ( template, data ) {
|
|
7
7
|
// Data should be an object. No array, no string.
|
|
8
8
|
if ( data == null ) return null
|
|
9
|
-
|
|
9
|
+
|
|
10
10
|
const
|
|
11
11
|
chop = _chopTemplate (settings)( template )
|
|
12
12
|
, set = settings
|
|
@@ -15,7 +15,7 @@ function _renderHolder ( template, data ) {
|
|
|
15
15
|
const isPlaceholder = item.includes ( set.TG_PRX )
|
|
16
16
|
if ( isPlaceholder ) {
|
|
17
17
|
const field = item.replace ( set.TG_PRX, '' ).replace ( set.TG_SFX, '' ).trim();
|
|
18
|
-
if ( data
|
|
18
|
+
if ( data.hasOwnProperty (field) ) chop[i] = data[field]
|
|
19
19
|
} // if isPlaceholder
|
|
20
20
|
}) // forEach chop
|
|
21
21
|
return chop.join ( '' )
|
package/src/methods/build.js
CHANGED
|
@@ -93,18 +93,30 @@ function build ( tpl, extra=false, buildDependencies={} ) {
|
|
|
93
93
|
|
|
94
94
|
d.forEach ( dElement => {
|
|
95
95
|
placeholders.forEach ( holder => { // Placeholders
|
|
96
|
+
|
|
97
|
+
|
|
96
98
|
const
|
|
97
99
|
{ index, data, action } = holder // index - placeholder index, data - key of data, action - list of operations
|
|
98
100
|
, dataOnly = !action && data
|
|
99
101
|
, mem = structuredClone ( memory )
|
|
100
102
|
, extendArguments = { dependencies: deps, memory:mem }
|
|
101
|
-
;
|
|
103
|
+
;
|
|
104
|
+
let info = dElement;
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
if ( data && data.includes('/') ) {
|
|
108
|
+
data.split('/').forEach ( d => {
|
|
109
|
+
if ( info.hasOwnProperty(d) ) info = info[d]
|
|
110
|
+
else info = []
|
|
111
|
+
})
|
|
112
|
+
} // If data contains '/'
|
|
113
|
+
else if ( data==='@all' || data===null || data==='@root' ) info = dElement
|
|
114
|
+
else if ( data ) info = info[data]
|
|
102
115
|
|
|
116
|
+
|
|
117
|
+
|
|
103
118
|
if ( dataOnly ) {
|
|
104
|
-
const
|
|
105
|
-
info = dElement[data]
|
|
106
|
-
, type = _defineDataType ( info )
|
|
107
|
-
;
|
|
119
|
+
const type = _defineDataType ( info );
|
|
108
120
|
switch ( type ) {
|
|
109
121
|
case 'function' :
|
|
110
122
|
cuts[index] = info ()
|
|
@@ -122,7 +134,7 @@ function build ( tpl, extra=false, buildDependencies={} ) {
|
|
|
122
134
|
} // dataOnly
|
|
123
135
|
else { // Data and Actions or only Actions
|
|
124
136
|
let
|
|
125
|
-
{ dataDeepLevel, nestedData } =
|
|
137
|
+
{ dataDeepLevel, nestedData } = _defineData ( info, action )
|
|
126
138
|
, actSetup = _actionSupply ( _setupActions ( action, dataDeepLevel ), dataDeepLevel )
|
|
127
139
|
;
|
|
128
140
|
|
|
@@ -133,6 +145,7 @@ function build ( tpl, extra=false, buildDependencies={} ) {
|
|
|
133
145
|
;
|
|
134
146
|
|
|
135
147
|
levelData.forEach ( (theData, iData ) => {
|
|
148
|
+
|
|
136
149
|
let dataType = _defineDataType ( theData )
|
|
137
150
|
|
|
138
151
|
switch ( type ) { // Action type 'route','data', 'render', or mix -> different operations
|
package/src/methods/render.js
CHANGED
|
@@ -15,7 +15,6 @@ import _renderHolder from "./_renderHolder.js"
|
|
|
15
15
|
*/
|
|
16
16
|
function render ( theData, name, helpers, ...args ) {
|
|
17
17
|
// *** Executes rendering and return the results
|
|
18
|
-
|
|
19
18
|
if ( theData instanceof Object ) { // Make sure all properties are not objects
|
|
20
19
|
Object.entries ( theData ).forEach ( ([key, value]) => {
|
|
21
20
|
if ( value instanceof Object ) theData[key] = value['text']
|