@rent-scraper/utils 1.0.31 → 1.0.33

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/README.md CHANGED
@@ -1,3 +1,20 @@
1
1
  # @rent-scraper/utils
2
2
 
3
- Utility functions for rent-scraper
3
+ Internal package. Shared utilities and config file management used across all `@rent-scraper/*` packages.
4
+
5
+ ## Config (`config.ts`)
6
+
7
+ Handles reading and writing the YAML config files (`config.zillow.yaml`, `config.redfin.yaml`).
8
+
9
+ - **`readConfigFile(source)`** — parse the config file for a source
10
+ - **`writeConfigFile(source, config)`** — write config back to disk
11
+ - **`getValueFromConfigFile(source, key)`** — read a single config key
12
+ - **`updateConfigFile(source, payload)`** — merge and save partial updates
13
+ - **`getConfigFilePath(source)`** — resolve the config file path (workspace root in dev, pointer file in prod)
14
+ - **`checkForConfigFile(source)`** — return whether the config file exists
15
+ - **`checkBrowserServer()`** — ping `localhost:8082` and return whether the browser server is running
16
+ - **`checkRequiredConfigValues(source, config)`** — return a list of missing required fields
17
+
18
+ ## Utilities (`index.ts`)
19
+
20
+ General-purpose helpers used across the monorepo: array comparison, error parsing, YAML read/write, path resolution, and random value selection.
package/dist/config.d.mts CHANGED
@@ -8,6 +8,7 @@ interface ScrapeConfig {
8
8
  regionIds?: Record<number, number | null>;
9
9
  browser?: string;
10
10
  autoCaptcha?: boolean;
11
+ forceCaptcha?: boolean;
11
12
  limit?: number;
12
13
  offset?: number;
13
14
  zillowCookie?: string;
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{readdir as ue,stat as oe,readFile as V,writeFile as Q}from"fs/promises";import G,{readdirSync as ce}from"fs";import A from"path";import*as fe from"csv";import X from"yaml";function le(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var L={exports:{}},he=L.exports,ee;function de(){return ee||(ee=1,(function(e,n){(function(i,h){e.exports=h()})(he,(function(){var i=1e3,h=6e4,D=36e5,m="millisecond",M="second",$="minute",d="hour",O="day",C="week",b="month",Z="quarter",_="year",k="date",B="Invalid Date",ne=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,se=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,ae={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(u){var s=["th","st","nd","rd"],t=u%100;return"["+u+(s[(t-20)%10]||s[t]||s[0])+"]"}},P=function(u,s,t){var a=String(u);return!a||a.length>=s?u:""+Array(s+1-a.length).join(t)+u},ie={s:P,z:function(u){var s=-u.utcOffset(),t=Math.abs(s),a=Math.floor(t/60),r=t%60;return(s<=0?"+":"-")+P(a,2,"0")+":"+P(r,2,"0")},m:function u(s,t){if(s.date()<t.date())return-u(t,s);var a=12*(t.year()-s.year())+(t.month()-s.month()),r=s.clone().add(a,b),o=t-r<0,c=s.clone().add(a+(o?-1:1),b);return+(-(a+(t-r)/(o?r-c:c-r))||0)},a:function(u){return u<0?Math.ceil(u)||0:Math.floor(u)},p:function(u){return{M:b,y:_,w:C,d:O,D:k,h:d,m:$,s:M,ms:m,Q:Z}[u]||String(u||"").toLowerCase().replace(/s$/,"")},u:function(u){return u===void 0}},E="en",N={};N[E]=ae;var R="$isDayjsObject",U=function(u){return u instanceof W||!(!u||!u[R])},H=function u(s,t,a){var r;if(!s)return E;if(typeof s=="string"){var o=s.toLowerCase();N[o]&&(r=o),t&&(N[o]=t,r=o);var c=s.split("-");if(!r&&c.length>1)return u(c[0])}else{var l=s.name;N[l]=s,r=l}return!a&&r&&(E=r),r||!a&&E},y=function(u,s){if(U(u))return u.clone();var t=typeof s=="object"?s:{};return t.date=u,t.args=arguments,new W(t)},f=ie;f.l=H,f.i=U,f.w=function(u,s){return y(u,{locale:s.$L,utc:s.$u,x:s.$x,$offset:s.$offset})};var W=(function(){function u(t){this.$L=H(t.locale,null,!0),this.parse(t),this.$x=this.$x||t.x||{},this[R]=!0}var s=u.prototype;return s.parse=function(t){this.$d=(function(a){var r=a.date,o=a.utc;if(r===null)return new Date(NaN);if(f.u(r))return new Date;if(r instanceof Date)return new Date(r);if(typeof r=="string"&&!/Z$/i.test(r)){var c=r.match(ne);if(c){var l=c[2]-1||0,p=(c[7]||"0").substring(0,3);return o?new Date(Date.UTC(c[1],l,c[3]||1,c[4]||0,c[5]||0,c[6]||0,p)):new Date(c[1],l,c[3]||1,c[4]||0,c[5]||0,c[6]||0,p)}}return new Date(r)})(t),this.init()},s.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds()},s.$utils=function(){return f},s.isValid=function(){return this.$d.toString()!==B},s.isSame=function(t,a){var r=y(t);return this.startOf(a)<=r&&r<=this.endOf(a)},s.isAfter=function(t,a){return y(t)<this.startOf(a)},s.isBefore=function(t,a){return this.endOf(a)<y(t)},s.$g=function(t,a,r){return f.u(t)?this[a]:this.set(r,t)},s.unix=function(){return Math.floor(this.valueOf()/1e3)},s.valueOf=function(){return this.$d.getTime()},s.startOf=function(t,a){var r=this,o=!!f.u(a)||a,c=f.p(t),l=function(j,S){var x=f.w(r.$u?Date.UTC(r.$y,S,j):new Date(r.$y,S,j),r);return o?x:x.endOf(O)},p=function(j,S){return f.w(r.toDate()[j].apply(r.toDate("s"),(o?[0,0,0,0]:[23,59,59,999]).slice(S)),r)},g=this.$W,v=this.$M,w=this.$D,F="set"+(this.$u?"UTC":"");switch(c){case _:return o?l(1,0):l(31,11);case b:return o?l(1,v):l(0,v+1);case C:var T=this.$locale().weekStart||0,Y=(g<T?g+7:g)-T;return l(o?w-Y:w+(6-Y),v);case O:case k:return p(F+"Hours",0);case d:return p(F+"Minutes",1);case $:return p(F+"Seconds",2);case M:return p(F+"Milliseconds",3);default:return this.clone()}},s.endOf=function(t){return this.startOf(t,!1)},s.$set=function(t,a){var r,o=f.p(t),c="set"+(this.$u?"UTC":""),l=(r={},r[O]=c+"Date",r[k]=c+"Date",r[b]=c+"Month",r[_]=c+"FullYear",r[d]=c+"Hours",r[$]=c+"Minutes",r[M]=c+"Seconds",r[m]=c+"Milliseconds",r)[o],p=o===O?this.$D+(a-this.$W):a;if(o===b||o===_){var g=this.clone().set(k,1);g.$d[l](p),g.init(),this.$d=g.set(k,Math.min(this.$D,g.daysInMonth())).$d}else l&&this.$d[l](p);return this.init(),this},s.set=function(t,a){return this.clone().$set(t,a)},s.get=function(t){return this[f.p(t)]()},s.add=function(t,a){var r,o=this;t=Number(t);var c=f.p(a),l=function(v){var w=y(o);return f.w(w.date(w.date()+Math.round(v*t)),o)};if(c===b)return this.set(b,this.$M+t);if(c===_)return this.set(_,this.$y+t);if(c===O)return l(1);if(c===C)return l(7);var p=(r={},r[$]=h,r[d]=D,r[M]=i,r)[c]||1,g=this.$d.getTime()+t*p;return f.w(g,this)},s.subtract=function(t,a){return this.add(-1*t,a)},s.format=function(t){var a=this,r=this.$locale();if(!this.isValid())return r.invalidDate||B;var o=t||"YYYY-MM-DDTHH:mm:ssZ",c=f.z(this),l=this.$H,p=this.$m,g=this.$M,v=r.weekdays,w=r.months,F=r.meridiem,T=function(S,x,I,J){return S&&(S[x]||S(a,o))||I[x].slice(0,J)},Y=function(S){return f.s(l%12||12,S,"0")},j=F||function(S,x,I){var J=S<12?"AM":"PM";return I?J.toLowerCase():J};return o.replace(se,(function(S,x){return x||(function(I){switch(I){case"YY":return String(a.$y).slice(-2);case"YYYY":return f.s(a.$y,4,"0");case"M":return g+1;case"MM":return f.s(g+1,2,"0");case"MMM":return T(r.monthsShort,g,w,3);case"MMMM":return T(w,g);case"D":return a.$D;case"DD":return f.s(a.$D,2,"0");case"d":return String(a.$W);case"dd":return T(r.weekdaysMin,a.$W,v,2);case"ddd":return T(r.weekdaysShort,a.$W,v,3);case"dddd":return v[a.$W];case"H":return String(l);case"HH":return f.s(l,2,"0");case"h":return Y(1);case"hh":return Y(2);case"a":return j(l,p,!0);case"A":return j(l,p,!1);case"m":return String(p);case"mm":return f.s(p,2,"0");case"s":return String(a.$s);case"ss":return f.s(a.$s,2,"0");case"SSS":return f.s(a.$ms,3,"0");case"Z":return c}return null})(S)||c.replace(":","")}))},s.utcOffset=function(){return 15*-Math.round(this.$d.getTimezoneOffset()/15)},s.diff=function(t,a,r){var o,c=this,l=f.p(a),p=y(t),g=(p.utcOffset()-this.utcOffset())*h,v=this-p,w=function(){return f.m(c,p)};switch(l){case _:o=w()/12;break;case b:o=w();break;case Z:o=w()/3;break;case C:o=(v-g)/6048e5;break;case O:o=(v-g)/864e5;break;case d:o=v/D;break;case $:o=v/h;break;case M:o=v/i;break;default:o=v}return r?o:f.a(o)},s.daysInMonth=function(){return this.endOf(b).$D},s.$locale=function(){return N[this.$L]},s.locale=function(t,a){if(!t)return this.$L;var r=this.clone(),o=H(t,a,!0);return o&&(r.$L=o),r},s.clone=function(){return f.w(this.$d,this)},s.toDate=function(){return new Date(this.valueOf())},s.toJSON=function(){return this.isValid()?this.toISOString():null},s.toISOString=function(){return this.$d.toISOString()},s.toString=function(){return this.$d.toUTCString()},u})(),K=W.prototype;return y.prototype=K,[["$ms",m],["$s",M],["$m",$],["$H",d],["$W",O],["$M",b],["$y",_],["$D",k]].forEach((function(u){K[u[1]]=function(s){return this.$g(s,u[0],u[1])}})),y.extend=function(u,s){return u.$i||(u(s,W,y),u.$i=!0),y},y.locale=H,y.isDayjs=U,y.unix=function(u){return y(1e3*u)},y.en=N[E],y.Ls=N,y.p={},y}))})(L)),L.exports}var me=de();const $e=le(me),pe=(e,n)=>e.reduce((i,h)=>({...i,[h[n]]:(i[h[n]]||[]).concat(h)}),{}),te=e=>typeof e=="object"&&!!e,ye=e=>te(e)&&Object.keys(e).length===0;function ge(e,n){throw new Error(JSON.stringify({status:n??400,message:e}))}const ve=e=>JSON.parse(e?.message),re=(e,n)=>e.length<=n?[e]:[e.slice(0,n),...re(e.slice(n),n)],z=(e,n)=>{const{round:i,zeros:h,type:D}=n??{};let m=e;return m=Number(i?q(e,i):m),m=h?Number(m).toFixed(h):m,m=D==="%"?`${m}%`:m,m=D==="$"?`$${m}`:m,n?m:Number(m)},Se=e=>z(e,{round:100,zeros:2,type:"$"}),De=(e,n)=>{const{round:i=100}=n??{};return z(e,{round:i,type:"%"})},Me=e=>Number(z(e,{round:100,zeros:2})),q=(e,n=100)=>Math.round(Number(e)*n)/n,we=e=>{const n=e?.replace("$","")?.replace(",","");return Number(n)},be=e=>{const n=e?.replace("+","")?.replace("%","");return q(Number(n)/100,1e3)},Oe=e=>e==="true"||Number(e)===1,_e=e=>{if(e?.response){const{status:n,data:i}=e?.response??{};return{status:n,message:i}}else{if(e?.errors)return{status:400,message:e?.errors?.map(n=>n).map(n=>n?.message).join("")};if(e?.message==="canceled")return{status:400,message:"request timed out at "+$e().format()};try{if(e?.body){const{status:n,message:i}=JSON.parse(e?.body)??{};return{status:n,message:i}}else{const{status:n,message:i}=JSON.parse(e?.message)??{};return{status:n,message:i}}}catch{const{status:n,message:i}=e??{};return console.log({status:n,message:i}),{status:n||400,message:i||"Internal Server Error"}}}},xe=(e,n,i)=>{const h=e.toString(),D=n.toString().padStart(2,"0"),m=i.toString().padStart(2,"0");return new Date(`${h}-${D}-${m}T00:00:00-08:00`)},Ne=async(e,n)=>{const{extension:i,prefix:h,prependDirectory:D,recursive:m=!1}=n??{},M=await ue(e,{recursive:m});let $=i?M.filter(d=>Array.isArray(i)?i.includes(A.extname(d)):A.extname(d)===i):M;return $=h?$.filter(d=>d.startsWith(h)):$,$=$.filter(d=>d!==".DS_Store"),D?$.map(d=>`${e}/${d}`):$},Te=(e,n)=>{const{extension:i,prefix:h,prependDirectory:D,recursive:m=!1}=n??{},M=ce(e,{recursive:m});let $=i?M.filter(d=>Array.isArray(i)?i.includes(A.extname(d)):A.extname(d)===i):M;return $=h?$.filter(d=>d.startsWith(h)):$,$=$.filter(d=>d!==".DS_Store"),D?$.map(d=>`${e}/${d}`):$},je=async e=>{try{const n=await oe(e);return n.isDirectory()||n.size>0}catch(n){if(n?.code==="ENOENT")return!1;throw n}},ke=e=>A.resolve(A.join(process.env.INIT_CWD,e)),Fe=e=>e[Math.floor(Math.random()*e.length)],Ae=async(e,n)=>{const i=[],h=G.createReadStream(e).pipe(fe.parse(n));for await(const D of h)i.push(D);return i},Ee=async e=>{const n=[],i=(await V(e,"utf8")).replace(/\n/g,",").replace(/ /g,"").split(",");for(const h of i)n.push(h);return n},Ye=async e=>JSON.parse(await V(e,"utf8")),Ie=async e=>{try{return X.parse(await V(e,"utf8"))}catch(n){n?.code==="ENOENT"&&await G.promises.writeFile(e,"")}},Ce=async(e,n)=>{await Q(e,X.stringify(n))},He=(e,n)=>e?.filter(i=>!n?.includes(i));class We{errors;constructor(n=[]){this.errors=n}add(n,i){i instanceof Error&&(n+=`: ${i.message}`),this.errors.push(n)}get(){return this.errors}async write(n,i){await Q(n,i)}}export{We as ErrorLog,je as checkForFile,re as chunkArray,He as compareArrays,xe as createDayStartInPST,Fe as getRandomArrayValue,pe as groupByKey,ye as isEmptyObject,te as isObject,ke as parseAbsolutePath,Ae as parseCsvFile,Se as parseCurrency,_e as parseError,Ye as parseJsonFile,z as parseNumber,De as parsePercentage,Me as parsePrice,ve as parseThrownError,Ee as parseTxtFile,Ie as parseYamlFile,be as percentageToDecimal,we as priceToInteger,Ne as readFilesInDirectory,Te as readFilesInDirectorySync,q as roundValue,ge as throwError,Oe as validateBooleanString,Ce as writeYamlFile};
1
+ import{readdir as ue,stat as oe,readFile as V,writeFile as Q}from"fs/promises";import G,{readdirSync as ce}from"fs";import A from"path";import*as fe from"csv";import X from"yaml";function le(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var L={exports:{}},he=L.exports,ee;function de(){return ee||(ee=1,(function(e,n){(function(u,h){e.exports=h()})(he,(function(){var u=1e3,h=6e4,D=36e5,m="millisecond",M="second",$="minute",d="hour",O="day",C="week",b="month",Z="quarter",_="year",k="date",B="Invalid Date",ne=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,se=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,ae={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(i){var s=["th","st","nd","rd"],t=i%100;return"["+i+(s[(t-20)%10]||s[t]||s[0])+"]"}},P=function(i,s,t){var a=String(i);return!a||a.length>=s?i:""+Array(s+1-a.length).join(t)+i},ie={s:P,z:function(i){var s=-i.utcOffset(),t=Math.abs(s),a=Math.floor(t/60),r=t%60;return(s<=0?"+":"-")+P(a,2,"0")+":"+P(r,2,"0")},m:function i(s,t){if(s.date()<t.date())return-i(t,s);var a=12*(t.year()-s.year())+(t.month()-s.month()),r=s.clone().add(a,b),o=t-r<0,c=s.clone().add(a+(o?-1:1),b);return+(-(a+(t-r)/(o?r-c:c-r))||0)},a:function(i){return i<0?Math.ceil(i)||0:Math.floor(i)},p:function(i){return{M:b,y:_,w:C,d:O,D:k,h:d,m:$,s:M,ms:m,Q:Z}[i]||String(i||"").toLowerCase().replace(/s$/,"")},u:function(i){return i===void 0}},E="en",N={};N[E]=ae;var R="$isDayjsObject",U=function(i){return i instanceof W||!(!i||!i[R])},H=function i(s,t,a){var r;if(!s)return E;if(typeof s=="string"){var o=s.toLowerCase();N[o]&&(r=o),t&&(N[o]=t,r=o);var c=s.split("-");if(!r&&c.length>1)return i(c[0])}else{var l=s.name;N[l]=s,r=l}return!a&&r&&(E=r),r||!a&&E},y=function(i,s){if(U(i))return i.clone();var t=typeof s=="object"?s:{};return t.date=i,t.args=arguments,new W(t)},f=ie;f.l=H,f.i=U,f.w=function(i,s){return y(i,{locale:s.$L,utc:s.$u,x:s.$x,$offset:s.$offset})};var W=(function(){function i(t){this.$L=H(t.locale,null,!0),this.parse(t),this.$x=this.$x||t.x||{},this[R]=!0}var s=i.prototype;return s.parse=function(t){this.$d=(function(a){var r=a.date,o=a.utc;if(r===null)return new Date(NaN);if(f.u(r))return new Date;if(r instanceof Date)return new Date(r);if(typeof r=="string"&&!/Z$/i.test(r)){var c=r.match(ne);if(c){var l=c[2]-1||0,p=(c[7]||"0").substring(0,3);return o?new Date(Date.UTC(c[1],l,c[3]||1,c[4]||0,c[5]||0,c[6]||0,p)):new Date(c[1],l,c[3]||1,c[4]||0,c[5]||0,c[6]||0,p)}}return new Date(r)})(t),this.init()},s.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds()},s.$utils=function(){return f},s.isValid=function(){return this.$d.toString()!==B},s.isSame=function(t,a){var r=y(t);return this.startOf(a)<=r&&r<=this.endOf(a)},s.isAfter=function(t,a){return y(t)<this.startOf(a)},s.isBefore=function(t,a){return this.endOf(a)<y(t)},s.$g=function(t,a,r){return f.u(t)?this[a]:this.set(r,t)},s.unix=function(){return Math.floor(this.valueOf()/1e3)},s.valueOf=function(){return this.$d.getTime()},s.startOf=function(t,a){var r=this,o=!!f.u(a)||a,c=f.p(t),l=function(j,S){var x=f.w(r.$u?Date.UTC(r.$y,S,j):new Date(r.$y,S,j),r);return o?x:x.endOf(O)},p=function(j,S){return f.w(r.toDate()[j].apply(r.toDate("s"),(o?[0,0,0,0]:[23,59,59,999]).slice(S)),r)},g=this.$W,v=this.$M,w=this.$D,F="set"+(this.$u?"UTC":"");switch(c){case _:return o?l(1,0):l(31,11);case b:return o?l(1,v):l(0,v+1);case C:var T=this.$locale().weekStart||0,Y=(g<T?g+7:g)-T;return l(o?w-Y:w+(6-Y),v);case O:case k:return p(F+"Hours",0);case d:return p(F+"Minutes",1);case $:return p(F+"Seconds",2);case M:return p(F+"Milliseconds",3);default:return this.clone()}},s.endOf=function(t){return this.startOf(t,!1)},s.$set=function(t,a){var r,o=f.p(t),c="set"+(this.$u?"UTC":""),l=(r={},r[O]=c+"Date",r[k]=c+"Date",r[b]=c+"Month",r[_]=c+"FullYear",r[d]=c+"Hours",r[$]=c+"Minutes",r[M]=c+"Seconds",r[m]=c+"Milliseconds",r)[o],p=o===O?this.$D+(a-this.$W):a;if(o===b||o===_){var g=this.clone().set(k,1);g.$d[l](p),g.init(),this.$d=g.set(k,Math.min(this.$D,g.daysInMonth())).$d}else l&&this.$d[l](p);return this.init(),this},s.set=function(t,a){return this.clone().$set(t,a)},s.get=function(t){return this[f.p(t)]()},s.add=function(t,a){var r,o=this;t=Number(t);var c=f.p(a),l=function(v){var w=y(o);return f.w(w.date(w.date()+Math.round(v*t)),o)};if(c===b)return this.set(b,this.$M+t);if(c===_)return this.set(_,this.$y+t);if(c===O)return l(1);if(c===C)return l(7);var p=(r={},r[$]=h,r[d]=D,r[M]=u,r)[c]||1,g=this.$d.getTime()+t*p;return f.w(g,this)},s.subtract=function(t,a){return this.add(-1*t,a)},s.format=function(t){var a=this,r=this.$locale();if(!this.isValid())return r.invalidDate||B;var o=t||"YYYY-MM-DDTHH:mm:ssZ",c=f.z(this),l=this.$H,p=this.$m,g=this.$M,v=r.weekdays,w=r.months,F=r.meridiem,T=function(S,x,I,J){return S&&(S[x]||S(a,o))||I[x].slice(0,J)},Y=function(S){return f.s(l%12||12,S,"0")},j=F||function(S,x,I){var J=S<12?"AM":"PM";return I?J.toLowerCase():J};return o.replace(se,(function(S,x){return x||(function(I){switch(I){case"YY":return String(a.$y).slice(-2);case"YYYY":return f.s(a.$y,4,"0");case"M":return g+1;case"MM":return f.s(g+1,2,"0");case"MMM":return T(r.monthsShort,g,w,3);case"MMMM":return T(w,g);case"D":return a.$D;case"DD":return f.s(a.$D,2,"0");case"d":return String(a.$W);case"dd":return T(r.weekdaysMin,a.$W,v,2);case"ddd":return T(r.weekdaysShort,a.$W,v,3);case"dddd":return v[a.$W];case"H":return String(l);case"HH":return f.s(l,2,"0");case"h":return Y(1);case"hh":return Y(2);case"a":return j(l,p,!0);case"A":return j(l,p,!1);case"m":return String(p);case"mm":return f.s(p,2,"0");case"s":return String(a.$s);case"ss":return f.s(a.$s,2,"0");case"SSS":return f.s(a.$ms,3,"0");case"Z":return c}return null})(S)||c.replace(":","")}))},s.utcOffset=function(){return 15*-Math.round(this.$d.getTimezoneOffset()/15)},s.diff=function(t,a,r){var o,c=this,l=f.p(a),p=y(t),g=(p.utcOffset()-this.utcOffset())*h,v=this-p,w=function(){return f.m(c,p)};switch(l){case _:o=w()/12;break;case b:o=w();break;case Z:o=w()/3;break;case C:o=(v-g)/6048e5;break;case O:o=(v-g)/864e5;break;case d:o=v/D;break;case $:o=v/h;break;case M:o=v/u;break;default:o=v}return r?o:f.a(o)},s.daysInMonth=function(){return this.endOf(b).$D},s.$locale=function(){return N[this.$L]},s.locale=function(t,a){if(!t)return this.$L;var r=this.clone(),o=H(t,a,!0);return o&&(r.$L=o),r},s.clone=function(){return f.w(this.$d,this)},s.toDate=function(){return new Date(this.valueOf())},s.toJSON=function(){return this.isValid()?this.toISOString():null},s.toISOString=function(){return this.$d.toISOString()},s.toString=function(){return this.$d.toUTCString()},i})(),K=W.prototype;return y.prototype=K,[["$ms",m],["$s",M],["$m",$],["$H",d],["$W",O],["$M",b],["$y",_],["$D",k]].forEach((function(i){K[i[1]]=function(s){return this.$g(s,i[0],i[1])}})),y.extend=function(i,s){return i.$i||(i(s,W,y),i.$i=!0),y},y.locale=H,y.isDayjs=U,y.unix=function(i){return y(1e3*i)},y.en=N[E],y.Ls=N,y.p={},y}))})(L)),L.exports}var me=de();const $e=le(me),pe=(e,n)=>e.reduce((u,h)=>({...u,[h[n]]:(u[h[n]]||[]).concat(h)}),{}),te=e=>typeof e=="object"&&!!e,ye=e=>te(e)&&Object.keys(e).length===0;function ge(e,n){throw new Error(JSON.stringify({status:n??400,message:e}))}const ve=e=>JSON.parse(e?.message),re=(e,n)=>e.length<=n?[e]:[e.slice(0,n),...re(e.slice(n),n)],z=(e,n)=>{const{round:u,zeros:h,type:D}=n??{};let m=e;return m=Number(u?q(e,u):m),m=h?Number(m).toFixed(h):m,m=D==="%"?`${m}%`:m,m=D==="$"?`$${m}`:m,n?m:Number(m)},Se=e=>z(e,{round:100,zeros:2,type:"$"}),De=(e,n)=>{const{round:u=100}=n??{};return z(e,{round:u,type:"%"})},Me=e=>Number(z(e,{round:100,zeros:2})),q=(e,n=100)=>Math.round(Number(e)*n)/n,we=e=>{const n=e?.replace("$","")?.replace(",","");return Number(n)},be=e=>{const n=e?.replace("+","")?.replace("%","");return q(Number(n)/100,1e3)},Oe=e=>e==="true"||Number(e)===1,_e=e=>{if(e?.response){const{status:n,data:u}=e?.response??{};return{status:n,message:u}}else{if(e?.errors)return{status:400,message:e?.errors?.map(n=>n).map(n=>n?.message).join("")};if(e?.message==="canceled")return{status:400,message:"request timed out at "+$e().format()};try{if(e?.body){const{status:n,message:u}=JSON.parse(e?.body)??{};return{status:n,message:u}}else{const{status:n,message:u}=JSON.parse(e?.message)??{};return{status:n,message:u}}}catch{const{status:n,message:u}=e??{};return{status:n||400,message:u||"Internal Server Error"}}}},xe=(e,n,u)=>{const h=e.toString(),D=n.toString().padStart(2,"0"),m=u.toString().padStart(2,"0");return new Date(`${h}-${D}-${m}T00:00:00-08:00`)},Ne=async(e,n)=>{const{extension:u,prefix:h,prependDirectory:D,recursive:m=!1}=n??{},M=await ue(e,{recursive:m});let $=u?M.filter(d=>Array.isArray(u)?u.includes(A.extname(d)):A.extname(d)===u):M;return $=h?$.filter(d=>d.startsWith(h)):$,$=$.filter(d=>d!==".DS_Store"),D?$.map(d=>`${e}/${d}`):$},Te=(e,n)=>{const{extension:u,prefix:h,prependDirectory:D,recursive:m=!1}=n??{},M=ce(e,{recursive:m});let $=u?M.filter(d=>Array.isArray(u)?u.includes(A.extname(d)):A.extname(d)===u):M;return $=h?$.filter(d=>d.startsWith(h)):$,$=$.filter(d=>d!==".DS_Store"),D?$.map(d=>`${e}/${d}`):$},je=async e=>{try{const n=await oe(e);return n.isDirectory()||n.size>0}catch(n){if(n?.code==="ENOENT")return!1;throw n}},ke=e=>A.resolve(A.join(process.env.INIT_CWD,e)),Fe=e=>e[Math.floor(Math.random()*e.length)],Ae=async(e,n)=>{const u=[],h=G.createReadStream(e).pipe(fe.parse(n));for await(const D of h)u.push(D);return u},Ee=async e=>{const n=[],u=(await V(e,"utf8")).replace(/\n/g,",").replace(/ /g,"").split(",");for(const h of u)n.push(h);return n},Ye=async e=>JSON.parse(await V(e,"utf8")),Ie=async e=>{try{return X.parse(await V(e,"utf8"))}catch(n){n?.code==="ENOENT"&&await G.promises.writeFile(e,"")}},Ce=async(e,n)=>{await Q(e,X.stringify(n))},He=(e,n)=>e?.filter(u=>!n?.includes(u));class We{errors;constructor(n=[]){this.errors=n}add(n,u){u instanceof Error&&(n+=`: ${u.message}`),this.errors.push(n)}get(){return this.errors}async write(n,u){await Q(n,u)}}export{We as ErrorLog,je as checkForFile,re as chunkArray,He as compareArrays,xe as createDayStartInPST,Fe as getRandomArrayValue,pe as groupByKey,ye as isEmptyObject,te as isObject,ke as parseAbsolutePath,Ae as parseCsvFile,Se as parseCurrency,_e as parseError,Ye as parseJsonFile,z as parseNumber,De as parsePercentage,Me as parsePrice,ve as parseThrownError,Ee as parseTxtFile,Ie as parseYamlFile,be as percentageToDecimal,we as priceToInteger,Ne as readFilesInDirectory,Te as readFilesInDirectorySync,q as roundValue,ge as throwError,Oe as validateBooleanString,Ce as writeYamlFile};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rent-scraper/utils",
3
- "version": "1.0.31",
3
+ "version": "1.0.33",
4
4
  "type": "module",
5
5
  "main": "./dist/index.mjs",
6
6
  "module": "./dist/index.mjs",
@@ -32,10 +32,11 @@
32
32
  "csv": "^6.3.11",
33
33
  "env-paths": "^3.0.0",
34
34
  "yaml": "^2.8.0",
35
- "@rent-scraper/api": "1.0.31"
35
+ "@rent-scraper/api": "1.0.33"
36
36
  },
37
37
  "devDependencies": {
38
- "unbuild": "^3.5.0"
38
+ "unbuild": "^3.5.0",
39
+ "vitest": "^4.1.7"
39
40
  },
40
41
  "engines": {
41
42
  "node": ">=22.x"
@@ -44,6 +45,7 @@
44
45
  "build": "unbuild",
45
46
  "typecheck": "tsc --noEmit",
46
47
  "lint": "eslint .",
47
- "lint:fix": "eslint --fix ."
48
+ "lint:fix": "eslint --fix .",
49
+ "test": "vitest run"
48
50
  }
49
51
  }