@homedev/objector 0.1.26 → 0.1.28

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.
Files changed (2) hide show
  1. package/dist/index.js +3 -3
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- import I from"fs/promises";import Z from"path";import u from"yaml";var a=async(w)=>{try{return await I.access(w,I.constants.R_OK),!0}catch{return!1}},J=async(w,r)=>{let O=await(async()=>{let j=[""];if(!Z.isAbsolute(w)&&r?.dirs)j.push(...r.dirs);for(let C of j){let $=Z.join(C,w);if(await a($))return Z.resolve($)}throw new Error(`File not found: "${w}"`)})(),E=await I.readFile(O),f=Z.dirname(O),T={"[.](yml|yaml)$":u.parse,"[.]json$":JSON.parse,...r?.parsers},g=Object.entries(T).find((j)=>O.match(j[0]));if(!g)throw new Error(`Unhandled file type: ${w}`);return{content:g[1](E.toString()),fullPath:O,folderPath:f}};var K=async(w,r)=>{for(let F of w){let O=[];if(r?.root)O.push(r.root);if(r?.loadOptions?.dirs)O.push(...r.loadOptions.dirs);let E=r?.load?await r.load(F):(await J(F,{...r?.loadOptions,dirs:O})).content;if(r?.loaded&&E)await r.loaded(E)}};var D=(w,r,F)=>{for(let O of Object.keys(r)){if(w[O]===void 0)continue;let E=r[O],f=w[O];if(typeof f!==typeof E||Array.isArray(f)!==Array.isArray(E)){let g=F?.mismatch?.(O,f,E,w,r);if(g!==void 0){r[O]=g;continue}throw new Error(`Type mismatch: ${O}`)}let T=F?.mode?.(O,f,E,w,r)??"merge";switch(T){case"source":r[O]=f;continue;case"target":continue;case"skip":delete r[O],delete w[O];continue;case"merge":break;default:throw new Error(`Unknown merge mode: ${T}`)}if(typeof f==="object")if(Array.isArray(f))E.push(...f);else{if(F?.navigate?.(O,f,E,w,r)===!1)continue;D(f,E,F)}else{if(f===E)continue;let g=F?.conflict?.(O,f,E,w,r);r[O]=g===void 0?E:g}}for(let O of Object.keys(w))if(r[O]===void 0)r[O]=w[O]};var d;((T)=>{T[T.Explore=0]="Explore";T[T.SkipSiblings=1]="SkipSiblings";T[T.NoExplore=2]="NoExplore";T[T.ReplaceItem=3]="ReplaceItem";T[T.ReplaceParent=4]="ReplaceParent";T[T.DeleteParent=5]="DeleteParent"})(d||={});class b{action;by;constructor(w,r){this.action=w;this.by=r}static ReplaceParent(w){return new b(4,w)}static ReplaceItem(w){return new b(3,w)}static SkipSiblings(){return new b(1)}static Explore(){return new b(0)}static NoExplore(){return new b(2)}static DeleteParent(){return new b(5)}}var H=async(w,r)=>{let F=async(E)=>{let f=E.key===null,T=f?{action:0}:await r(E);if(E.value&&typeof E.value==="object"&&T.action==0){if(!f)E.path.push(E.key),E.parents.push(E.parent);if(await O(E),!f)E.parents.pop(),E.path.pop()}return T},O=async(E)=>{for(let[f,T]of Object.entries(E.value)){let g=await F({key:f,value:T,path:E.path,parent:E.value,parents:E.parents});switch(g.action){case 4:if(!E.key)throw new Error("Cannot replace root");E.parent[E.key]=g.by;return;case 3:E.value[f]=g.by;break;case 5:delete E.parent[E.key];return;case 1:return}}};await F({key:null,value:w,path:[],parent:null,parents:[]})};var y=(w,r,F="(",O=")")=>{let E=0,f="",T=[];for(let g of w){if(f+=g,g===F)E++;if(g===O)E--;if(E===0&&g===r)T.push(f.slice(0,-1)),f=""}if(f)T.push(f);return T},z=(w)=>{let r=/(?:\s*(?:"([^"]*)"|'([^']*)')\s*|([^"',]+))(?:,)?|(,)/g,F=[],O;while((O=r.exec(w))!==null){let E=O[1]??O[2];F.push({value:E??O[3]?.trim()??"",quoted:E!==void 0})}return F};var Y=(w,r,F,O)=>{if(w.startsWith("{")){let E=w.substring(1,w.length-1);return L(r,E,F).toString()}return O?w:void 0},s=(w,r,F,O)=>{let E=Y(r,F,O);if(E)return L(w,E,O);let f=/^\[([^=\]]*)([=]*)([^\]]*)\]$/.exec(r);if(f){let[g,M,j,C]=f,$=Y(M.trim(),F,O,!0),B=Y(C.trim(),F,O,!0);if(Array.isArray(w))switch(j){case"==":case"=":return w.find((W)=>W[$]==B)}}let T=/^([^[\]]*)\[([^\]]*)]/.exec(r);if(T)return w[T[1]][T[2]];return w[r]},L=(w,r,F)=>{let O=void 0,E=void 0;r??="";let f=(C)=>C?.endsWith("?")?[C.substring(0,C.length-1),!0]:[C,!1],T=(C,$)=>{let[B,W]=f($.pop());if(B){let A=s(C,B,w,F);if(A===void 0){if(W||F?.defaultValue!==void 0)return;throw new Error(`Unknown path element: "${B}" in "${r}"`)}return O=C,E=B,T(A,$)}if(F?.set&&E)O[E]=F?.set;return C},g=y(r,F?.separator??".","{","}"),M=g.length>0&&g[g.length-1].startsWith("?=")?g.pop()?.substring(2):void 0;g.reverse();let j=T(w,g);if(j===void 0)return M??F?.defaultValue;return j};var U=(w,r)=>{let F=/^(?<path>[^@>]*)?(?:@(?<from>[^>]*))?$/.exec(w)?.groups;if(!F)throw new Error(`Invalid reference: "${w}"`);let{from:O,path:E}=F;if(!O)return L(r.root,E,{defaultValue:r?.defaultValue});if(r.async===!1){if(!r.load)throw new Error("No load function defined");return L(r.load(O),E,{defaultValue:r?.defaultValue})}else return(r.load??J)(O).then((f)=>L(f,E))};var G=async(w,r,F,O)=>{let E,f=[],T=r;if(!O.sources)return b.Explore();if(T=T.replaceAll(O.sourcesMatcher??/\$\((?<key>[^:()]+)(?::(?<arg>(?:(?:"[^"]*"|[^",()]*),?)*))?\)/g,(g,...M)=>{if(E)return g;let j=(_)=>{if(_ instanceof Promise)return`ð[${f.push(_)}]ñ`;if(typeof _==="object")return E=_,g;return _??""},C=M[M.length-1],$=O.sources[C.key];if(C.arg===void 0)return j(U(C.key,{root:F,load:O?.load}));if($===void 0)throw new Error(`Unhandled source type: ${C.key}`);let[B,W]="fn"in $?[$.fn,$]:[$,{}],A=z(C.arg),l=W.processArgs===!1?[]:A.map((_)=>{if(_.quoted)return _.value;return _.value.startsWith("@")?_.value.substring(1):U(_.value,{root:F})});return j(B({groups:C,args:l,rawArgs:A,path:w,value:T,root:F,key:C.key,options:O,file:O.file}))}),E)T=await E;else if(f.length){let g=await Promise.all(f);T=g.find((M)=>typeof M==="object")??T.replaceAll(/\xf0\[(\d+)]\xf1/g,(M,j)=>g[+j-1])}if(T===null)return b.DeleteParent();if(T===r)return b.Explore();if(T instanceof b)return T;if(typeof T==="string"){let g=await G(w,T,F,O);if(g.action!==0)return g}return b.ReplaceItem(T)};var m=async(w,r,F,O)=>{if(w.key.startsWith("$"))return b.NoExplore();if(!O.keys)return;let E=(O?.keysMatcher??/^\.(?<key>.*)/).exec(w.key)?.groups;if(E){let f=O.keys[E.key];if(f!==void 0){let T=typeof f==="object"?f:{},g=typeof f==="function"?f:f.fn,M={...F,self:w.value,this:w.parent,parent:w.parents[w.parents.length-1],parents:[w.parent,...w.parents.toReversed()]};if(typeof w.value==="string"){let $=await G(r,w.value,M,O);if($.by)w.value=$.by}else await q(w.value,{...O,root:M,filters:[...O.filters??[],...T.filters??[]]});let j={args:[w.value],rawArgs:[],groups:E,path:r,value:w.value,root:F,parent:w.parent,key:w.key,file:O?.file,options:O},C=await g(j);if(C instanceof b)return C;if(C===null)return b.DeleteParent();if(C===void 0)return b.Explore();return b.ReplaceParent(C)}}};var q=async(w,r)=>H(w,async(F)=>{let O=[...F.path,F.key].join(".");if(r.filters?.length&&r.filters.some((f)=>f.test(O)))return b.NoExplore();let E={...w,this:F.parent,parent:F.parents.length>0?F.parents[F.parents.length-1]:{},parents:F.parents.toReversed(),...r.root};try{return await m(F,O,E,r)??(typeof F.value==="string"?await G(O,F.value,E,r):b.Explore())}catch(f){throw new Error(`${f.message}
2
- in ${r.file??""}(${O}) `)}});var Ir=async(w,r)=>{let F=[];return await H(w,(O)=>{if(r([...O.path,O.key].join("."),O.value))F.push(O.value);return b.Explore()}),F};var P=(w,r="name")=>Object.entries(w).map(([F,O])=>({[r]:F,...O})),Pr=(w,r="name")=>Object.fromEntries(w.map((F)=>[F[r],F])),V=(w,r="name")=>Object.fromEntries(w.map((F)=>{let{[r]:O,...E}=F;return[O,E]}));import Q from"fs/promises";import p from"path";import e from"yaml";import S from"path";var R=(w)=>{return{load:async(r)=>{for(let{file:F,alias:O}of Array.isArray(r.value)?r.value:[r.value]){if(!F)throw new Error("File reference required");await w.load(F,O??F,r.file&&S.dirname(r.file))}delete r.parent[r.key]},include:(r)=>w.load(r.value,void 0,r.file&&S.dirname(r.file)),from:async(r)=>{let F=await U(r.value,{root:r.root,load:(O)=>w.load(O,void 0,r.file&&S.dirname(r.file))});if(r.parent.content){if(Array.isArray(r.parent.content)&&Array.isArray(F))return[...F,...r.parent.content];return w.merge(F,r.parent.content),r.parent.content}return F},concat:async(r)=>{let F=[];for(let O of Array.isArray(r.value)?r.value:[r.value])F.push(...await U(O,{root:r.root,load:(E)=>w.load(E,void 0,r.file&&S.dirname(r.file))}));return F.filter((O)=>O!==void 0)},extends:async(r)=>{for(let F of Array.isArray(r.value)?r.value:[r.value])w.merge(await U(F,{root:r.root,load:(O)=>w.load(O,void 0,r.file&&S.dirname(r.file))}),r.parent);delete r.parent[r.key]},alias:(r)=>{w.alias(r.value,r.parent),delete r.parent[r.key]},if:(r)=>{if(delete r.parent[r.key],r.value===null||r.value===void 0||["0",0,"false",""].includes(r.value)||Array.isArray(r.value)&&r.value.length===0)return null},skip:(r)=>{return delete r.parent[r.key],b.SkipSiblings()},output:(r)=>{delete r.parent[r.key];for(let F of Array.isArray(r.value)?r.value:[r.value])if(typeof F==="string")w.output({name:F,value:r.parent});else w.output({...F,value:F.value??r.parent})},each:{filters:[/select|model/],fn:async(r)=>{delete r.parent[r.key];let F=(j)=>U(j,{root:r.root,load:(C)=>w.load(C,void 0,r.file&&S.dirname(r.file))}),O=()=>{if(typeof r.value==="string"||!r.value.model)return r.parent;if(typeof r.value.model==="string")return F(r.value.model);return r.value.model},E=()=>{if(typeof r.value==="string")return F(r.value);if(Array.isArray(r.value))return r.value;if(typeof r.value.from==="string")return F(r.value.from);return r.value.from},f=async(j)=>{let C=r.value.select;if(C===void 0)return j;if(typeof C!=="string"){let $=JSON.parse(JSON.stringify(C));return await q($,{...r.options,root:{...r.root,result:j}}),$}return await U(C,{root:{...r.root,result:j}})},T=await E(),g=await O();if(!Array.isArray(T))throw new Error('Key "each" requires a source list');if(g===void 0)throw new Error('Key "each" must define a model');if(r.value.extend?.model)g=w.mergeAll([g,...Array.isArray(r.value.extend.model)?r.value.extend.model:[r.value.extend.model]]);let M=[];for(let j=0;j<T.length;j++){let C=JSON.parse(JSON.stringify(g));if(await q(C,{...r.options,root:{...r.root,item:T[j],this:C,index:j}}),r.value.extend?.result)C=w.mergeAll([C,...Array.isArray(r.value.extend?.result)?r.value.extend.result:[Array.isArray(r.value.extend?.result)]]);M.push(await f(C))}return M}}}};import n from"fs/promises";import X from"path";var N=(w)=>w.replace(/((?:[_ ]+)\w|^\w)/g,(r,F)=>F.toUpperCase()).replace(/_/g,""),i=(w)=>N(w).replace(/((?:[ ]+\w)|^\w)/g,(r,F)=>F.toLowerCase()),h=(w,r)=>w.replace(/([a-z])([A-Z])/g,`$1${r}$2`).replace(/\s+/g,r),k=(w,r)=>{switch(r){case"upper":return w.toUpperCase();case"lower":return w.toLowerCase();default:return w}},v=(w)=>{return{include:async(r)=>await w.load(r.args[0],r.args[1],r.file&&X.dirname(r.file),{parent:r.root}),file:async(r)=>await n.readFile(r.args[0]).then((F)=>F.toString()),scan:async(r)=>{let F=[],E=(()=>{let f=r.args[2]??["**/node_modules/**"],T=typeof f==="string"?f.split(",").map((g)=>g.trim()):f;if(!Array.isArray(T))throw new Error("Scan exclusion must be a list");return T})();for await(let f of n.glob(r.args[0],{cwd:r.args[1]??X.dirname(r.file??"."),exclude:(T)=>E.some((g)=>X.matchesGlob(T,g))}))F.push(f);return F},env:(r)=>process.env[r.args[0]],len:(r)=>r.args[0].length,reverse:(r)=>r.args[0].split("").reverse().join(""),substring:(r)=>r.args[0].substring(+r.args[1],+r.args[2]),concat:(r)=>r.args.join(""),lower:(r)=>r.args[0].toLowerCase(),upper:(r)=>r.args[0].toUpperCase(),pascal:(r)=>N(r.args[0]),camel:(r)=>i(r.args[0]),snake:(r)=>k(h(r.args[0],"_"),r.args[1]),kebab:(r)=>k(h(r.args[0],"-"),r.args[1]),encode:(r)=>Buffer.from(r.args[0]).toString(r.args[1]??"base64"),decode:(r)=>Buffer.from(r.args[0],r.args[1]??"base64").toString(),uuid:(r)=>crypto.randomUUID(),merge:(r)=>r.args.flatMap((F)=>F),join:(r)=>{let[F,O,E]=r.args,f=F;if(!Array.isArray(f))throw new Error("Object is not a list");if(O?.length)f=f.map((T)=>U(O,{root:{...r.root,...T},load:(g)=>w.load(g)}));return f.join(E?.replace("\\n",`
3
- `))},list:(r)=>P(r.args[0],r.args[1]),object:(r)=>V(r.args[0],r.args[1]),each:{processArgs:!1,fn:async(r)=>{let F=(M)=>U(M,{root:r.root,load:(j)=>w.load(j,void 0,r.file&&X.dirname(r.file))}),O=await F(r.rawArgs[0].value),E=await F(r.rawArgs[1].value),f=r.rawArgs[2]?.value,T=Array.isArray(O)?O:P(O),g=[];for(let M=0;M<T.length;M++){let j=JSON.parse(JSON.stringify(E)),C={instance:j};if(await q(C,{...r.options,root:{...r.root,item:T[M],this:j,index:M,params:r.rawArgs.slice(3).map(($)=>$.value)}}),f!==void 0&&f!=="@")g.push(C.instance[f]);else g.push(C.instance)}return g}},log:(r)=>{console.log(...r.args)},default:{processArgs:!1,fn:async(r)=>{let F=r.rawArgs[1]?.value?r.rawArgs[1].quoted?r.rawArgs[1].value:await U(r.rawArgs[1].value,{root:r.root,load:(O)=>w.load(O)}):"";return await U(r.rawArgs[0].value,{root:r.root,load:(O)=>w.load(O),defaultValue:F})}}}};class o{options={load:{dirs:[]},merge:{},include:{},fields:{},includeKey:"includes",mergeKey:".merge",includes:[],outputs:[]};cache={};includeDirectory(...w){return this.options.load.dirs??=[],this.options.load.dirs.push(...w),this}include(...w){return this.options.includes??=[],this.options.includes.push(...w),this}keys(w){return this.options.fields.keys={...this.options.fields.keys,...w},this}sources(w){return this.options.fields.sources={...this.options.fields.sources,...w},this}variables(w){return this.options.variables={...this.options.variables,...w},this}output(w){return this.options.outputs??=[],this.options.outputs.push(w),this}defaultProcessors(){return this.sources(v(this)).keys(R(this))}alias(w,r){return this.cache[w]=r,this}getAlias(w){return this.cache[w]}getOutputs(){return this.options.outputs??[]}use(w){return w(this),this}filter(w){return this.options.fields.filters??=[],this.options.fields.filters?.push(w),this}async load(w,r,F,O,E){if(r&&this.cache[r])return this.cache[r];if(this.cache[w])return this.cache[w];let f=F?[F]:[];this.options.load.dirs&&f.push(...this.options.load.dirs);let T=await J(w,{...this.options.load,dirs:f});if(!T.content)return null;if(r)this.cache[r]=T.content;let g=[];if(this.options.includeKey&&T.content[this.options.includeKey])g.push(...T.content[this.options.includeKey]),delete T.content[this.options.includeKey];if(this.options.includes)g.push(...this.options.includes),this.options.includes.length=0;if(await K(g,{root:T.folderPath,loaded:(M)=>{if(this.options.mergeKey)D(M,T.content,{mode:(j,C,$)=>$[this.options.mergeKey],...this.options.merge})},load:(M)=>this.load(M,void 0,T.folderPath,{parent:T.content,...O},!0),...this.options.include}),E!==!0)await q(T.content,{...this.options.fields,file:T.fullPath,root:{...this.options.fields.root,...this.options.variables,$document:{root:T,fileName:w,folder:T.folderPath,fullPath:T.fullPath,...O}},load:(M)=>this.load(M,void 0,T.folderPath,{parent:T.content,...O})});return T.content}merge(w,r){D(w,r,{mode:(F,O,E)=>E[this.options.mergeKey],...this.options.merge})}mergeAll(w){let r={};for(let F of w.toReversed())this.merge(F,r);return r}async writeOutputs(w){if(w?.targetDirectory&&w?.removeFirst)try{await Q.rm(w?.targetDirectory,{recursive:!0,force:!0})}catch(r){throw new Error(`Failed to clean the output directory: ${r.message}`)}for(let r of this.getOutputs()){let F=p.join(w?.targetDirectory??".",r.name),O=p.dirname(F);if(w?.writing?.(r)===!1)continue;try{await Q.mkdir(O,{recursive:!0})}catch(E){throw new Error(`Failed to create target directory "${O}" for output "${F}": ${E.message}`)}try{switch(r.type){case"yaml":await Q.writeFile(F,e.stringify(r.value));break;case"json":await Q.writeFile(F,JSON.stringify(r.value));break;default:await Q.writeFile(F,r.value.toString())}}catch(E){throw new Error(`Failed to write output "${F}": ${E.message}`)}}}}export{Pr as toObjectWithKey,V as toObject,P as toList,U as select,K as processIncludes,q as processFields,H as navigate,D as merge,J as load,Ir as find,o as Objector,b as NavigateResult,d as NavigateAction};
1
+ import I from"fs/promises";import n from"path";import u from"yaml";var a=async(w)=>{try{return await I.access(w,I.constants.R_OK),!0}catch{return!1}},J=async(w,r)=>{let f=await(async()=>{let j=[""];if(!n.isAbsolute(w)&&r?.dirs)j.push(...r.dirs);for(let T of j){let $=n.join(T,w);if(await a($))return n.resolve($)}throw new Error(`File not found: "${w}"`)})(),O=await I.readFile(f),E=n.dirname(f),g={"[.](yml|yaml)$":u.parse,"[.]json$":JSON.parse,...r?.parsers},C=Object.entries(g).find((j)=>f.match(j[0]));if(!C)throw new Error(`Unhandled file type: ${w}`);return{content:C[1](O.toString()),fullPath:f,folderPath:E}};var P=async(w,r)=>{for(let F of w){let f=[];if(r?.root)f.push(r.root);if(r?.loadOptions?.dirs)f.push(...r.loadOptions.dirs);let O=r?.load?await r.load(F):(await J(F,{...r?.loadOptions,dirs:f})).content;if(r?.loaded&&O)await r.loaded(O)}};var D=(w,r,F)=>{for(let f of Object.keys(r)){if(w[f]===void 0)continue;let O=r[f],E=w[f];if(typeof E!==typeof O||Array.isArray(E)!==Array.isArray(O)){let C=F?.mismatch?.(f,E,O,w,r);if(C!==void 0){r[f]=C;continue}throw new Error(`Type mismatch: ${f}`)}let g=F?.mode?.(f,E,O,w,r)??"merge";switch(g){case"source":r[f]=E;continue;case"target":continue;case"skip":delete r[f],delete w[f];continue;case"merge":break;default:throw new Error(`Unknown merge mode: ${g}`)}if(typeof E==="object")if(Array.isArray(E))O.push(...E);else{if(F?.navigate?.(f,E,O,w,r)===!1)continue;D(E,O,F)}else{if(E===O)continue;let C=F?.conflict?.(f,E,O,w,r);r[f]=C===void 0?O:C}}for(let f of Object.keys(w))if(r[f]===void 0)r[f]=w[f]};var d;((g)=>{g[g.Explore=0]="Explore";g[g.SkipSiblings=1]="SkipSiblings";g[g.NoExplore=2]="NoExplore";g[g.ReplaceItem=3]="ReplaceItem";g[g.ReplaceParent=4]="ReplaceParent";g[g.DeleteParent=5]="DeleteParent"})(d||={});class M{action;by;constructor(w,r){this.action=w;this.by=r}static ReplaceParent(w){return new M(4,w)}static ReplaceItem(w){return new M(3,w)}static SkipSiblings(){return new M(1)}static Explore(){return new M(0)}static NoExplore(){return new M(2)}static DeleteParent(){return new M(5)}}var H=async(w,r)=>{let F=async(O)=>{let E=O.key===null,g=E?{action:0}:await r(O);if(O.value&&typeof O.value==="object"&&g.action==0){if(!E)O.path.push(O.key),O.parents.push(O.parent);if(await f(O),!E)O.parents.pop(),O.path.pop()}return g},f=async(O)=>{for(let[E,g]of Object.entries(O.value)){let C=await F({key:E,value:g,path:O.path,parent:O.value,parents:O.parents});switch(C.action){case 4:if(!O.key)throw new Error("Cannot replace root");O.parent[O.key]=C.by;return;case 3:O.value[E]=C.by;break;case 5:delete O.parent[O.key];return;case 1:return}}};await F({key:null,value:w,path:[],parent:null,parents:[]})};var K=(w,r,F="(",f=")")=>{let O=0,E="",g=[];for(let C of w){if(E+=C,C===F)O++;if(C===f)O--;if(O===0&&C===r)g.push(E.slice(0,-1)),E=""}if(E)g.push(E);return g},z=(w)=>{let r=/(?:\s*(?:"([^"]*)"|'([^']*)')\s*|([^"',]+))(?:,)?|(,)/g,F=[],f;while((f=r.exec(w))!==null){let O=f[1]??f[2];F.push({value:O??f[3]?.trim()??"",quoted:O!==void 0})}return F};var Y=(w,r,F,f)=>{if(w.startsWith("{")){let O=w.substring(1,w.length-1);return L(r,O,F).toString()}return f?w:void 0},i=(w,r,F,f)=>{let O=Y(r,F,f);if(O)return L(w,O,f);let E=/^\[([^=\]]*)([=]*)([^\]]*)\]$/.exec(r);if(E){let[C,b,j,T]=E,$=Y(b.trim(),F,f,!0),A=Y(T.trim(),F,f,!0);if(Array.isArray(w))switch(j){case"==":case"=":return w.find((W)=>W[$]==A)}}let g=/^([^[\]]*)\[([^\]]*)]/.exec(r);if(g)return w[g[1]][g[2]];return w[r]},L=(w,r,F)=>{let f=void 0,O=void 0;r??="";let E=(T)=>T?.endsWith("?")?[T.substring(0,T.length-1),!0]:[T,!1],g=(T,$)=>{let[A,W]=E($.pop());if(A){let G=i(T,A,w,F);if(G===void 0){if(W||F?.defaultValue!==void 0)return;throw new Error(`Unknown path element: "${A}" in "${r}"`)}return f=T,O=A,g(G,$)}if(F?.set&&O)f[O]=F?.set;return T},C=K(r,F?.separator??".","{","}"),b=C.length>0&&C[C.length-1].startsWith("?=")?C.pop()?.substring(2):void 0;C.reverse();let j=g(w,C);if(j===void 0)return b??F?.defaultValue;return j};var U=(w,r)=>{let F=/^(?<path>[^@>]*)?(?:@(?<from>[^>]*))?$/.exec(w)?.groups;if(!F)throw new Error(`Invalid reference: "${w}"`);let{from:f,path:O}=F;if(!f)return L(r.root,O,{defaultValue:r?.defaultValue});if(r.async===!1){if(!r.load)throw new Error("No load function defined");return L(r.load(f),O,{defaultValue:r?.defaultValue})}else return(r.load??J)(f).then((E)=>L(E,O))};var Q=async(w,r,F,f)=>{let O,E=[],g=r;if(!f.sources)return M.Explore();if(g=g.replaceAll(f.sourcesMatcher??/\$\((?<key>[^:()]+)(?::(?<arg>(?:(?:"[^"]*"|[^",()]*),?)*))?\)/g,(C,...b)=>{if(O)return C;let j=(_)=>{if(_ instanceof Promise)return`ð[${E.push(_)}]ñ`;if(typeof _==="object")return O=_,C;return _??""},T=b[b.length-1],$=f.sources[T.key];if(T.arg===void 0)return j(U(T.key,{root:F,load:f?.load}));if($===void 0)throw new Error(`Unhandled source type: ${T.key}`);let[A,W]="fn"in $?[$.fn,$]:[$,{}],G=z(T.arg),p=W.processArgs===!1?[]:G.map((_)=>{if(_.quoted)return _.value;return _.value.startsWith("@")?_.value.substring(1):U(_.value,{root:F})});return j(A({groups:T,args:p,rawArgs:G,path:w,value:g,root:F,key:T.key,options:f,file:f.file}))}),O)g=await O;else if(E.length){let C=await Promise.all(E);g=C.find((b)=>typeof b==="object")??g.replaceAll(/\xf0\[(\d+)]\xf1/g,(b,j)=>C[+j-1])}if(g===null)return M.DeleteParent();if(g===r)return M.Explore();if(g instanceof M)return g;if(typeof g==="string"){let C=await Q(w,g,F,f);if(C.action!==0)return C}return M.ReplaceItem(g)};var m=async(w,r,F,f)=>{if(w.key.startsWith("$"))return M.NoExplore();if(!f.keys)return;let O=(f?.keysMatcher??/^\.(?<key>.*)/).exec(w.key)?.groups;if(O){let E=f.keys[O.key];if(E!==void 0){let g=typeof E==="object"?E:{},C=typeof E==="function"?E:E.fn,b={...F,self:w.value,this:w.parent,parent:w.parents[w.parents.length-1],parents:[w.parent,...w.parents.toReversed()]};if(typeof w.value==="string"){let $=await Q(r,w.value,b,f);if($.by)w.value=$.by}else await q(w.value,{...f,root:b,filters:[...f.filters??[],...g.filters??[]]});let j={args:[w.value],rawArgs:[],groups:O,path:r,value:w.value,root:F,parent:w.parent,key:w.key,file:f?.file,options:f},T=await C(j);if(T instanceof M)return T;if(T===null)return M.DeleteParent();if(T===void 0)return M.Explore();return M.ReplaceParent(T)}}};var q=async(w,r)=>H(w,async(F)=>{let f=[...F.path,F.key].join(".");if(r.filters?.length&&r.filters.some((E)=>E.test(f)))return M.NoExplore();let O={...w,this:F.parent,parent:F.parents.length>0?F.parents[F.parents.length-1]:{},parents:F.parents.toReversed(),...r.root};try{return await m(F,f,O,r)??(typeof F.value==="string"?await Q(f,F.value,O,r):M.Explore())}catch(E){throw new Error(`${E.message}
2
+ in ${r.file??""}(${f}) `)}});var Ir=async(w,r)=>{let F=[];return await H(w,(f)=>{if(r([...f.path,f.key].join("."),f.value))F.push(f.value);return M.Explore()}),F};var y=(w,r="name")=>Object.entries(w).map(([F,f])=>({[r]:F,...f})),yr=(w,r="name")=>Object.fromEntries(w.map((F)=>[F[r],F])),V=(w,r="name")=>Object.fromEntries(w.map((F)=>{let{[r]:f,...O}=F;return[f,O]}));import Z from"fs/promises";import s from"path";import o from"yaml";import S from"path";var R=(w)=>{return{load:async(r)=>{for(let{file:F,alias:f}of Array.isArray(r.value)?r.value:[r.value]){if(!F)throw new Error("File reference required");await w.load(F,f??F,r.file&&S.dirname(r.file))}delete r.parent[r.key]},include:(r)=>w.load(r.value,void 0,r.file&&S.dirname(r.file)),from:async(r)=>{let F=await U(r.value,{root:r.root,load:(f)=>w.load(f,void 0,r.file&&S.dirname(r.file))});if(r.parent.content){if(Array.isArray(r.parent.content)&&Array.isArray(F))return[...F,...r.parent.content];return w.merge(F,r.parent.content),r.parent.content}return F},concat:async(r)=>{let F=[];for(let f of Array.isArray(r.value)?r.value:[r.value])F.push(...await U(f,{root:r.root,load:(O)=>w.load(O,void 0,r.file&&S.dirname(r.file))}));return F.filter((f)=>f!==void 0)},extends:async(r)=>{for(let F of Array.isArray(r.value)?r.value:[r.value])w.merge(await U(F,{root:r.root,load:(f)=>w.load(f,void 0,r.file&&S.dirname(r.file))}),r.parent);delete r.parent[r.key]},alias:(r)=>{w.alias(r.value,r.parent),delete r.parent[r.key]},if:(r)=>{if(delete r.parent[r.key],r.value===null||r.value===void 0||["0",0,"false",""].includes(r.value)||Array.isArray(r.value)&&r.value.length===0)return null},skip:(r)=>{return delete r.parent[r.key],M.SkipSiblings()},output:(r)=>{delete r.parent[r.key];for(let F of Array.isArray(r.value)?r.value:[r.value])if(typeof F==="string")w.output({name:F,value:r.parent});else w.output({...F,value:F.value??r.parent})},each:{filters:[/select|model/],fn:async(r)=>{delete r.parent[r.key];let F=(j)=>U(j,{root:r.root,load:(T)=>w.load(T,void 0,r.file&&S.dirname(r.file))}),f=()=>{if(typeof r.value==="string"||!r.value.model)return r.parent;if(typeof r.value.model==="string")return F(r.value.model);return r.value.model},O=()=>{if(typeof r.value==="string")return F(r.value);if(Array.isArray(r.value))return r.value;if(typeof r.value.from==="string")return F(r.value.from);return r.value.from},E=async(j)=>{let T=r.value.select;if(T===void 0)return j;if(typeof T!=="string"){let $=JSON.parse(JSON.stringify(T));return await q($,{...r.options,root:{...r.root,result:j}}),$}return await U(T,{root:{...r.root,result:j}})},g=await O(),C=await f();if(!Array.isArray(g))throw new Error('Key "each" requires a source list');if(C===void 0)throw new Error('Key "each" must define a model');if(r.value.extend?.model)C=w.mergeAll([C,...Array.isArray(r.value.extend.model)?r.value.extend.model:[r.value.extend.model]]);let b=[];for(let j=0;j<g.length;j++){let T=JSON.parse(JSON.stringify(C));if(await q(T,{...r.options,root:{...r.root,item:g[j],this:T,index:j}}),r.value.extend?.result)T=w.mergeAll([T,...Array.isArray(r.value.extend?.result)?r.value.extend.result:[Array.isArray(r.value.extend?.result)]]);b.push(await E(T))}return b}}}};import h from"fs/promises";import X from"path";var v=(w)=>w.replace(/((?:[_ ]+)\w|^\w)/g,(r,F)=>F.toUpperCase()).replace(/_/g,""),e=(w)=>v(w).replace(/((?:[ ]+\w)|^\w)/g,(r,F)=>F.toLowerCase()),k=(w,r)=>w.replace(/([a-z])([A-Z])/g,`$1${r}$2`).replace(/\s+/g,r),N=(w,r)=>{switch(r){case"upper":return w.toUpperCase();case"lower":return w.toLowerCase();default:return w}},B=async(w,r,F,f)=>r.rawArgs[F].quoted?r.rawArgs[F].value:await U(r.rawArgs[F].value,{root:r.root,load:(O)=>w.load(O),defaultValue:f}),l=(w)=>{return{include:async(r)=>await w.load(r.args[0],r.args[1],r.file&&X.dirname(r.file),{parent:r.root}),file:async(r)=>await h.readFile(r.args[0]).then((F)=>F.toString()),scan:async(r)=>{let F=[],O=(()=>{let E=r.args[2]??["**/node_modules/**"],g=typeof E==="string"?E.split(",").map((C)=>C.trim()):E;if(!Array.isArray(g))throw new Error("Scan exclusion must be a list");return g})();for await(let E of h.glob(r.args[0],{cwd:r.args[1]??X.dirname(r.file??"."),exclude:(g)=>O.some((C)=>X.matchesGlob(g,C))}))F.push(E);return F},env:(r)=>process.env[r.args[0]],len:(r)=>r.args[0].length,reverse:(r)=>r.args[0].split("").reverse().join(""),substring:(r)=>r.args[0].substring(+r.args[1],+r.args[2]),concat:(r)=>r.args.join(""),lower:(r)=>r.args[0].toLowerCase(),upper:(r)=>r.args[0].toUpperCase(),pascal:(r)=>v(r.args[0]),camel:(r)=>e(r.args[0]),snake:(r)=>N(k(r.args[0],"_"),r.args[1]),kebab:(r)=>N(k(r.args[0],"-"),r.args[1]),encode:(r)=>Buffer.from(r.args[0]).toString(r.args[1]??"base64"),decode:(r)=>Buffer.from(r.args[0],r.args[1]??"base64").toString(),uuid:(r)=>crypto.randomUUID(),merge:(r)=>r.args.flatMap((F)=>F),join:(r)=>{let[F,f,O]=r.args,E=F;if(!Array.isArray(E))throw new Error("Object is not a list");if(f?.length)E=E.map((g)=>U(f,{root:{...r.root,...g},load:(C)=>w.load(C)}));return E.join(O?.replace("\\n",`
3
+ `))},list:(r)=>y(r.args[0],r.args[1]),object:(r)=>V(r.args[0],r.args[1]),each:{processArgs:!1,fn:async(r)=>{let F=(b)=>U(b,{root:r.root,load:(j)=>w.load(j,void 0,r.file&&X.dirname(r.file))}),f=await F(r.rawArgs[0].value),O=await F(r.rawArgs[1].value),E=r.rawArgs[2]?.value,g=Array.isArray(f)?f:y(f),C=[];for(let b=0;b<g.length;b++){let j=JSON.parse(JSON.stringify(O)),T={instance:j};if(await q(T,{...r.options,root:{...r.root,item:g[b],this:j,parent:r.root.this,index:b,params:r.rawArgs.slice(3).map(($)=>$.value)}}),E!==void 0&&E!=="@")C.push(T.instance[E]);else C.push(T.instance)}return C}},log:(r)=>{console.log(...r.args)},default:{processArgs:!1,fn:async(r)=>{let F=r.rawArgs[1]?.value?await B(w,r,1):"";return B(w,r,0,F)}},if:{processArgs:!1,fn:async(r)=>{if(!await B(w,r,0,!1))return r.rawArgs.length>2?B(w,r,2):"";return B(w,r,1)}},switch:{processArgs:!1,fn:async(r)=>{let F=await B(w,r,0,!1),f=await B(w,r,1);if(f[F]===void 0){if(r.rawArgs.length>2)return B(w,r,2);throw new Error(`Unhandled switch case: ${F}`)}return f[F]}}}};class x{options={load:{dirs:[]},merge:{},include:{},fields:{},includeKey:"includes",mergeKey:".merge",includes:[],outputs:[]};cache={};includeDirectory(...w){return this.options.load.dirs??=[],this.options.load.dirs.push(...w),this}include(...w){return this.options.includes??=[],this.options.includes.push(...w),this}keys(w){return this.options.fields.keys={...this.options.fields.keys,...w},this}sources(w){return this.options.fields.sources={...this.options.fields.sources,...w},this}variables(w){return this.options.variables={...this.options.variables,...w},this}output(w){return this.options.outputs??=[],this.options.outputs.push(w),this}defaultProcessors(){return this.sources(l(this)).keys(R(this))}alias(w,r){return this.cache[w]=r,this}getAlias(w){return this.cache[w]}getOutputs(){return this.options.outputs??[]}use(w){return w(this),this}filter(w){return this.options.fields.filters??=[],this.options.fields.filters?.push(w),this}async load(w,r,F,f,O){if(r&&this.cache[r])return this.cache[r];if(this.cache[w])return this.cache[w];let E=F?[F]:[];this.options.load.dirs&&E.push(...this.options.load.dirs);let g=await J(w,{...this.options.load,dirs:E});if(!g.content)return null;if(r)this.cache[r]=g.content;let C=[];if(this.options.includeKey&&g.content[this.options.includeKey])C.push(...g.content[this.options.includeKey]),delete g.content[this.options.includeKey];if(this.options.includes)C.push(...this.options.includes),this.options.includes.length=0;if(await P(C,{root:g.folderPath,loaded:(b)=>{if(this.options.mergeKey)D(b,g.content,{mode:(j,T,$)=>$[this.options.mergeKey],...this.options.merge})},load:(b)=>this.load(b,void 0,g.folderPath,{parent:g.content,...f},!0),...this.options.include}),O!==!0)await q(g.content,{...this.options.fields,file:g.fullPath,root:{...this.options.fields.root,...this.options.variables,$document:{root:g,fileName:w,folder:g.folderPath,fullPath:g.fullPath,...f}},load:(b)=>this.load(b,void 0,g.folderPath,{parent:g.content,...f})});return g.content}merge(w,r){D(w,r,{mode:(F,f,O)=>O[this.options.mergeKey],...this.options.merge})}mergeAll(w){let r={};for(let F of w.toReversed())this.merge(F,r);return r}async writeOutputs(w){if(w?.targetDirectory&&w?.removeFirst)try{await Z.rm(w?.targetDirectory,{recursive:!0,force:!0})}catch(r){throw new Error(`Failed to clean the output directory: ${r.message}`)}for(let r of this.getOutputs()){let F=s.join(w?.targetDirectory??".",r.name),f=s.dirname(F);if(w?.writing?.(r)===!1)continue;try{await Z.mkdir(f,{recursive:!0})}catch(O){throw new Error(`Failed to create target directory "${f}" for output "${F}": ${O.message}`)}try{switch(r.type){case"yaml":await Z.writeFile(F,o.stringify(r.value));break;case"json":await Z.writeFile(F,JSON.stringify(r.value));break;default:await Z.writeFile(F,r.value.toString())}}catch(O){throw new Error(`Failed to write output "${F}": ${O.message}`)}}}}export{yr as toObjectWithKey,V as toObject,y as toList,U as select,P as processIncludes,q as processFields,H as navigate,D as merge,J as load,Ir as find,x as Objector,M as NavigateResult,d as NavigateAction};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@homedev/objector",
3
- "version": "0.1.26",
3
+ "version": "0.1.28",
4
4
  "description": "object extensions for YAML/JSON",
5
5
  "author": "julzor",
6
6
  "license": "ISC",