@amekusa/util.js 2.0.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -160,7 +160,43 @@ function merge(x, y, opts = {}) {
160
160
  return x.concat(y);
161
161
  }
162
162
  return y;
163
- }var gen=/*#__PURE__*/Object.freeze({__proto__:null,arr:arr,clean:clean,is:is,isEmpty:isEmpty,isEmptyOrFalsey:isEmptyOrFalsey,isEmptyOrFalsy:isEmptyOrFalsy,merge:merge});/*!
163
+ }
164
+
165
+ /**
166
+ * Gets a property from the given object by the given string path.
167
+ * @param {object} obj - Object to traverse
168
+ * @param {string} path - Property names separated with '.'
169
+ * @return {any} value of the found property, or undefined if it's not found
170
+ */
171
+ function dig(obj, path) {
172
+ path = path.split('.');
173
+ for (let i = 0; i < path.length; i++) {
174
+ let p = path[i];
175
+ if (typeof obj == 'object' && p in obj) obj = obj[p];
176
+ else return undefined;
177
+ }
178
+ return obj;
179
+ }
180
+
181
+ /**
182
+ * Substitutes the properties of the given data for the references in the given string.
183
+ * @param {string} str - String that contains references to the properties
184
+ * @param {object} data - Object that contains properties to replace the references
185
+ * @param {object} [opts] - Options
186
+ * @return {string} a modified `str`
187
+ */
188
+ function subst(str, data, opts = {}) {
189
+ let {
190
+ modifier = null,
191
+ start = '{{',
192
+ end = '}}',
193
+ } = opts;
194
+ let ref = new RegExp(start + '\\s*([-.\\w]+)\\s*' + end, 'g');
195
+ return str.replaceAll(ref, modifier
196
+ ? (_, m1) => (modifier(dig(data, m1), m1, data) || '')
197
+ : (_, m1) => (dig(data, m1) || '')
198
+ );
199
+ }var gen=/*#__PURE__*/Object.freeze({__proto__:null,arr:arr,clean:clean,dig:dig,is:is,isEmpty:isEmpty,isEmptyOrFalsey:isEmptyOrFalsey,isEmptyOrFalsy:isEmptyOrFalsy,merge:merge,subst:subst});/*!
164
200
  * === @amekusa/util.js/web === *
165
201
  * MIT License
166
202
  *
@@ -379,4 +415,4 @@ function hms(d, format = null) {
379
415
  */
380
416
  function iso9075(d) {
381
417
  return ymd(d, '-') + ' ' + hms(d, ':');
382
- }var time=/*#__PURE__*/Object.freeze({__proto__:null,addTime:addTime,ceil:ceil,date:date,floor:floor,hms:hms,iso9075:iso9075,localize:localize,ms:ms,quantize:quantize,round:round,ymd:ymd});export{arr,clean,gen,is,isEmpty,isEmptyOrFalsey,isEmptyOrFalsy,merge,time,web};
418
+ }var time=/*#__PURE__*/Object.freeze({__proto__:null,addTime:addTime,ceil:ceil,date:date,floor:floor,hms:hms,iso9075:iso9075,localize:localize,ms:ms,quantize:quantize,round:round,ymd:ymd});export{arr,clean,dig,gen,is,isEmpty,isEmptyOrFalsey,isEmptyOrFalsy,merge,subst,time,web};
@@ -22,7 +22,7 @@
22
22
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
23
  * SOFTWARE.
24
24
  */
25
- function e(e){return Array.isArray(e)?e:[e]}function t(e,...t){let r=typeof e;for(let n=0;n<t.length;n++){let i=t[n];if("string"==typeof i){if("array"==i){if(Array.isArray(e))return!0}else if(r==i)return!0}else if(e instanceof i)return!0}return!1}function r(e){if(Array.isArray(e))return 0==e.length;switch(typeof e){case"string":return!e;case"object":for(let t in e)return!1;return!0;case"undefined":return!0}return!1}function n(e){if(!e)return!0;if(Array.isArray(e))return 0==e.length;if("object"==typeof e)for(let t in e)return!1;return!1}const i=n;function u(e,t=8){if(t){if(Array.isArray(e)){let n=[];for(let i=0;i<e.length;i++){let o=u(e[i],t-1);r(o)||n.push(o)}return n}if("object"==typeof e){let n={};for(let i in e){let o=u(e[i],t-1);r(o)||(n[i]=o)}return n}}return e}function o(e,t,r={}){switch("recurse"in r||(r.recurse=8),Array.isArray(e)+Array.isArray(t)){case 0:if(r.recurse&&e&&t&&"object"==typeof e&&"object"==typeof t){r.recurse--;for(let n in t)e[n]=o(e[n],t[n],r);return r.recurse++,e}case 1:return t}switch(r.mergeArrays){case!0:for(let r=0;r<t.length;r++)e.includes(t[r])||e.push(t[r]);return e;case"push":return e.push(...t),e;case"concat":return e.concat(t)}return t}var a=Object.freeze({__proto__:null,arr:e,clean:u,is:t,isEmpty:r,isEmptyOrFalsey:i,isEmptyOrFalsy:n,merge:o});
25
+ function e(e){return Array.isArray(e)?e:[e]}function t(e,...t){let r=typeof e;for(let n=0;n<t.length;n++){let i=t[n];if("string"==typeof i){if("array"==i){if(Array.isArray(e))return!0}else if(r==i)return!0}else if(e instanceof i)return!0}return!1}function r(e){if(Array.isArray(e))return 0==e.length;switch(typeof e){case"string":return!e;case"object":for(let t in e)return!1;return!0;case"undefined":return!0}return!1}function n(e){if(!e)return!0;if(Array.isArray(e))return 0==e.length;if("object"==typeof e)for(let t in e)return!1;return!1}const i=n;function u(e,t=8){if(t){if(Array.isArray(e)){let n=[];for(let i=0;i<e.length;i++){let o=u(e[i],t-1);r(o)||n.push(o)}return n}if("object"==typeof e){let n={};for(let i in e){let o=u(e[i],t-1);r(o)||(n[i]=o)}return n}}return e}function o(e,t,r={}){switch("recurse"in r||(r.recurse=8),Array.isArray(e)+Array.isArray(t)){case 0:if(r.recurse&&e&&t&&"object"==typeof e&&"object"==typeof t){r.recurse--;for(let n in t)e[n]=o(e[n],t[n],r);return r.recurse++,e}case 1:return t}switch(r.mergeArrays){case!0:for(let r=0;r<t.length;r++)e.includes(t[r])||e.push(t[r]);return e;case"push":return e.push(...t),e;case"concat":return e.concat(t)}return t}function a(e,t){t=t.split(".");for(let r=0;r<t.length;r++){let n=t[r];if("object"!=typeof e||!(n in e))return;e=e[n]}return e}function c(e,t,r={}){let{modifier:n=null,start:i="{{",end:u="}}"}=r,o=new RegExp(i+"\\s*([-.\\w]+)\\s*"+u,"g");return e.replaceAll(o,n?(e,r)=>n(a(t,r),r,t)||"":(e,r)=>a(t,r)||"")}var s=Object.freeze({__proto__:null,arr:e,clean:u,dig:a,is:t,isEmpty:r,isEmptyOrFalsey:i,isEmptyOrFalsy:n,merge:o,subst:c});
26
26
  /*!
27
27
  * === @amekusa/util.js/web === *
28
28
  * MIT License
@@ -46,7 +46,7 @@ function e(e){return Array.isArray(e)?e:[e]}function t(e,...t){let r=typeof e;fo
46
46
  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
47
47
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
48
48
  * SOFTWARE.
49
- */function c(e){return`${e}`.replace(l,g)}const s=c,f={"&":"amp",'"':"quot","'":"apos","<":"lt",">":"gt"},l=new RegExp(`["'<>]|(&(?!${Object.values(f).join("|")};))`,"g"),g=e=>`&${f[e]};`;var y=Object.freeze({__proto__:null,escHTML:c,escHtml:s});
49
+ */function f(e){return`${e}`.replace(p,y)}const l=f,g={"&":"amp",'"':"quot","'":"apos","<":"lt",">":"gt"},p=new RegExp(`["'<>]|(&(?!${Object.values(g).join("|")};))`,"g"),y=e=>`&${g[e]};`;var d=Object.freeze({__proto__:null,escHTML:f,escHtml:l});
50
50
  /*!
51
51
  * === @amekusa/util.js/time === *
52
52
  * MIT License
@@ -70,4 +70,4 @@ function e(e){return Array.isArray(e)?e:[e]}function t(e,...t){let r=typeof e;fo
70
70
  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
71
71
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
72
72
  * SOFTWARE.
73
- */function p(e,t,r="round"){return e.setTime(Math[r](e.getTime()/t)*t),e}function h(e,t=null){let r=[e.getFullYear().toString(),(e.getMonth()+1).toString().padStart(2,"0"),e.getDate().toString().padStart(2,"0")];switch(typeof t){case"string":return r.join(t);case"object":return t?(t.Y=r[0],t.M=r[1],t.D=r[2],t):r;default:if(!t)return r;throw"invalid type"}}function m(e,t=null){let r=[e.getHours().toString().padStart(2,"0"),e.getMinutes().toString().padStart(2,"0"),e.getSeconds().toString().padStart(2,"0")];switch(typeof t){case"string":return r.join(t);case"object":return t?(t.h=r[0],t.m=r[1],t.s=r[2],t):r;default:if(!t)return r;throw"invalid type"}}var d=Object.freeze({__proto__:null,addTime:function(e,t){return e.setTime(e.getTime()+t),e},ceil:function(e,t){return p(e,t,"ceil")},date:function(...e){return e.length&&e[0]?e[0]instanceof Date?e[0]:new Date(...e):new Date},floor:function(e,t){return p(e,t,"floor")},hms:m,iso9075:function(e){return h(e,"-")+" "+m(e,":")},localize:function(e){return e.setTime(e.getTime()-6e4*e.getTimezoneOffset()),e},ms:function(...e){if(!e.length||!e[0])return Date.now();let t=e[0];return"number"==typeof t?t:t instanceof Date?t.getTime():new Date(...e).getTime()},quantize:p,round:function(e,t){return p(e,t,"round")},ymd:h});export{e as arr,u as clean,a as gen,t as is,r as isEmpty,i as isEmptyOrFalsey,n as isEmptyOrFalsy,o as merge,d as time,y as web};
73
+ */function h(e,t,r="round"){return e.setTime(Math[r](e.getTime()/t)*t),e}function m(e,t=null){let r=[e.getFullYear().toString(),(e.getMonth()+1).toString().padStart(2,"0"),e.getDate().toString().padStart(2,"0")];switch(typeof t){case"string":return r.join(t);case"object":return t?(t.Y=r[0],t.M=r[1],t.D=r[2],t):r;default:if(!t)return r;throw"invalid type"}}function A(e,t=null){let r=[e.getHours().toString().padStart(2,"0"),e.getMinutes().toString().padStart(2,"0"),e.getSeconds().toString().padStart(2,"0")];switch(typeof t){case"string":return r.join(t);case"object":return t?(t.h=r[0],t.m=r[1],t.s=r[2],t):r;default:if(!t)return r;throw"invalid type"}}var j=Object.freeze({__proto__:null,addTime:function(e,t){return e.setTime(e.getTime()+t),e},ceil:function(e,t){return h(e,t,"ceil")},date:function(...e){return e.length&&e[0]?e[0]instanceof Date?e[0]:new Date(...e):new Date},floor:function(e,t){return h(e,t,"floor")},hms:A,iso9075:function(e){return m(e,"-")+" "+A(e,":")},localize:function(e){return e.setTime(e.getTime()-6e4*e.getTimezoneOffset()),e},ms:function(...e){if(!e.length||!e[0])return Date.now();let t=e[0];return"number"==typeof t?t:t instanceof Date?t.getTime():new Date(...e).getTime()},quantize:h,round:function(e,t){return h(e,t,"round")},ymd:m});export{e as arr,u as clean,a as dig,s as gen,t as is,r as isEmpty,i as isEmptyOrFalsey,n as isEmptyOrFalsy,o as merge,c as subst,j as time,d as web};
@@ -160,7 +160,43 @@ function merge(x, y, opts = {}) {
160
160
  return x.concat(y);
161
161
  }
162
162
  return y;
163
- }var gen=/*#__PURE__*/Object.freeze({__proto__:null,arr:arr,clean:clean,is:is,isEmpty:isEmpty,isEmptyOrFalsey:isEmptyOrFalsey,isEmptyOrFalsy:isEmptyOrFalsy,merge:merge});/*!
163
+ }
164
+
165
+ /**
166
+ * Gets a property from the given object by the given string path.
167
+ * @param {object} obj - Object to traverse
168
+ * @param {string} path - Property names separated with '.'
169
+ * @return {any} value of the found property, or undefined if it's not found
170
+ */
171
+ function dig(obj, path) {
172
+ path = path.split('.');
173
+ for (let i = 0; i < path.length; i++) {
174
+ let p = path[i];
175
+ if (typeof obj == 'object' && p in obj) obj = obj[p];
176
+ else return undefined;
177
+ }
178
+ return obj;
179
+ }
180
+
181
+ /**
182
+ * Substitutes the properties of the given data for the references in the given string.
183
+ * @param {string} str - String that contains references to the properties
184
+ * @param {object} data - Object that contains properties to replace the references
185
+ * @param {object} [opts] - Options
186
+ * @return {string} a modified `str`
187
+ */
188
+ function subst(str, data, opts = {}) {
189
+ let {
190
+ modifier = null,
191
+ start = '{{',
192
+ end = '}}',
193
+ } = opts;
194
+ let ref = new RegExp(start + '\\s*([-.\\w]+)\\s*' + end, 'g');
195
+ return str.replaceAll(ref, modifier
196
+ ? (_, m1) => (modifier(dig(data, m1), m1, data) || '')
197
+ : (_, m1) => (dig(data, m1) || '')
198
+ );
199
+ }var gen=/*#__PURE__*/Object.freeze({__proto__:null,arr:arr,clean:clean,dig:dig,is:is,isEmpty:isEmpty,isEmptyOrFalsey:isEmptyOrFalsey,isEmptyOrFalsy:isEmptyOrFalsy,merge:merge,subst:subst});/*!
164
200
  * === @amekusa/util.js/web === *
165
201
  * MIT License
166
202
  *
@@ -379,4 +415,4 @@ function hms(d, format = null) {
379
415
  */
380
416
  function iso9075(d) {
381
417
  return ymd(d, '-') + ' ' + hms(d, ':');
382
- }var time=/*#__PURE__*/Object.freeze({__proto__:null,addTime:addTime,ceil:ceil,date:date,floor:floor,hms:hms,iso9075:iso9075,localize:localize,ms:ms,quantize:quantize,round:round,ymd:ymd});exports.arr=arr;exports.clean=clean;exports.gen=gen;exports.is=is;exports.isEmpty=isEmpty;exports.isEmptyOrFalsey=isEmptyOrFalsey;exports.isEmptyOrFalsy=isEmptyOrFalsy;exports.merge=merge;exports.time=time;exports.web=web;return exports;})({});
418
+ }var time=/*#__PURE__*/Object.freeze({__proto__:null,addTime:addTime,ceil:ceil,date:date,floor:floor,hms:hms,iso9075:iso9075,localize:localize,ms:ms,quantize:quantize,round:round,ymd:ymd});exports.arr=arr;exports.clean=clean;exports.dig=dig;exports.gen=gen;exports.is=is;exports.isEmpty=isEmpty;exports.isEmptyOrFalsey=isEmptyOrFalsey;exports.isEmptyOrFalsy=isEmptyOrFalsy;exports.merge=merge;exports.subst=subst;exports.time=time;exports.web=web;return exports;})({});
@@ -22,7 +22,7 @@ this.amekusa=this.amekusa||{},this.amekusa.util=function(e){"use strict";
22
22
  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
23
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
24
  * SOFTWARE.
25
- */function t(e){return Array.isArray(e)?e:[e]}function r(e,...t){let r=typeof e;for(let n=0;n<t.length;n++){let i=t[n];if("string"==typeof i){if("array"==i){if(Array.isArray(e))return!0}else if(r==i)return!0}else if(e instanceof i)return!0}return!1}function n(e){if(Array.isArray(e))return 0==e.length;switch(typeof e){case"string":return!e;case"object":for(let t in e)return!1;return!0;case"undefined":return!0}return!1}function i(e){if(!e)return!0;if(Array.isArray(e))return 0==e.length;if("object"==typeof e)for(let t in e)return!1;return!1}const u=i;function o(e,t=8){if(t){if(Array.isArray(e)){let r=[];for(let i=0;i<e.length;i++){let u=o(e[i],t-1);n(u)||r.push(u)}return r}if("object"==typeof e){let r={};for(let i in e){let u=o(e[i],t-1);n(u)||(r[i]=u)}return r}}return e}function a(e,t,r={}){switch("recurse"in r||(r.recurse=8),Array.isArray(e)+Array.isArray(t)){case 0:if(r.recurse&&e&&t&&"object"==typeof e&&"object"==typeof t){r.recurse--;for(let n in t)e[n]=a(e[n],t[n],r);return r.recurse++,e}case 1:return t}switch(r.mergeArrays){case!0:for(let r=0;r<t.length;r++)e.includes(t[r])||e.push(t[r]);return e;case"push":return e.push(...t),e;case"concat":return e.concat(t)}return t}var s=Object.freeze({__proto__:null,arr:t,clean:o,is:r,isEmpty:n,isEmptyOrFalsey:u,isEmptyOrFalsy:i,merge:a});
25
+ */function t(e){return Array.isArray(e)?e:[e]}function r(e,...t){let r=typeof e;for(let n=0;n<t.length;n++){let i=t[n];if("string"==typeof i){if("array"==i){if(Array.isArray(e))return!0}else if(r==i)return!0}else if(e instanceof i)return!0}return!1}function n(e){if(Array.isArray(e))return 0==e.length;switch(typeof e){case"string":return!e;case"object":for(let t in e)return!1;return!0;case"undefined":return!0}return!1}function i(e){if(!e)return!0;if(Array.isArray(e))return 0==e.length;if("object"==typeof e)for(let t in e)return!1;return!1}const u=i;function o(e,t=8){if(t){if(Array.isArray(e)){let r=[];for(let i=0;i<e.length;i++){let u=o(e[i],t-1);n(u)||r.push(u)}return r}if("object"==typeof e){let r={};for(let i in e){let u=o(e[i],t-1);n(u)||(r[i]=u)}return r}}return e}function s(e,t,r={}){switch("recurse"in r||(r.recurse=8),Array.isArray(e)+Array.isArray(t)){case 0:if(r.recurse&&e&&t&&"object"==typeof e&&"object"==typeof t){r.recurse--;for(let n in t)e[n]=s(e[n],t[n],r);return r.recurse++,e}case 1:return t}switch(r.mergeArrays){case!0:for(let r=0;r<t.length;r++)e.includes(t[r])||e.push(t[r]);return e;case"push":return e.push(...t),e;case"concat":return e.concat(t)}return t}function a(e,t){t=t.split(".");for(let r=0;r<t.length;r++){let n=t[r];if("object"!=typeof e||!(n in e))return;e=e[n]}return e}function c(e,t,r={}){let{modifier:n=null,start:i="{{",end:u="}}"}=r,o=new RegExp(i+"\\s*([-.\\w]+)\\s*"+u,"g");return e.replaceAll(o,n?(e,r)=>n(a(t,r),r,t)||"":(e,r)=>a(t,r)||"")}var f=Object.freeze({__proto__:null,arr:t,clean:o,dig:a,is:r,isEmpty:n,isEmptyOrFalsey:u,isEmptyOrFalsy:i,merge:s,subst:c});
26
26
  /*!
27
27
  * === @amekusa/util.js/web === *
28
28
  * MIT License
@@ -46,7 +46,7 @@ this.amekusa=this.amekusa||{},this.amekusa.util=function(e){"use strict";
46
46
  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
47
47
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
48
48
  * SOFTWARE.
49
- */function c(e){return`${e}`.replace(y,g)}const f=c,l={"&":"amp",'"':"quot","'":"apos","<":"lt",">":"gt"},y=new RegExp(`["'<>]|(&(?!${Object.values(l).join("|")};))`,"g"),g=e=>`&${l[e]};`;var p=Object.freeze({__proto__:null,escHTML:c,escHtml:f});
49
+ */function l(e){return`${e}`.replace(p,m)}const g=l,y={"&":"amp",'"':"quot","'":"apos","<":"lt",">":"gt"},p=new RegExp(`["'<>]|(&(?!${Object.values(y).join("|")};))`,"g"),m=e=>`&${y[e]};`;var h=Object.freeze({__proto__:null,escHTML:l,escHtml:g});
50
50
  /*!
51
51
  * === @amekusa/util.js/time === *
52
52
  * MIT License
@@ -70,4 +70,4 @@ this.amekusa=this.amekusa||{},this.amekusa.util=function(e){"use strict";
70
70
  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
71
71
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
72
72
  * SOFTWARE.
73
- */function m(e,t,r="round"){return e.setTime(Math[r](e.getTime()/t)*t),e}function h(e,t=null){let r=[e.getFullYear().toString(),(e.getMonth()+1).toString().padStart(2,"0"),e.getDate().toString().padStart(2,"0")];switch(typeof t){case"string":return r.join(t);case"object":return t?(t.Y=r[0],t.M=r[1],t.D=r[2],t):r;default:if(!t)return r;throw"invalid type"}}function d(e,t=null){let r=[e.getHours().toString().padStart(2,"0"),e.getMinutes().toString().padStart(2,"0"),e.getSeconds().toString().padStart(2,"0")];switch(typeof t){case"string":return r.join(t);case"object":return t?(t.h=r[0],t.m=r[1],t.s=r[2],t):r;default:if(!t)return r;throw"invalid type"}}var A=Object.freeze({__proto__:null,addTime:function(e,t){return e.setTime(e.getTime()+t),e},ceil:function(e,t){return m(e,t,"ceil")},date:function(...e){return e.length&&e[0]?e[0]instanceof Date?e[0]:new Date(...e):new Date},floor:function(e,t){return m(e,t,"floor")},hms:d,iso9075:function(e){return h(e,"-")+" "+d(e,":")},localize:function(e){return e.setTime(e.getTime()-6e4*e.getTimezoneOffset()),e},ms:function(...e){if(!e.length||!e[0])return Date.now();let t=e[0];return"number"==typeof t?t:t instanceof Date?t.getTime():new Date(...e).getTime()},quantize:m,round:function(e,t){return m(e,t,"round")},ymd:h});return e.arr=t,e.clean=o,e.gen=s,e.is=r,e.isEmpty=n,e.isEmptyOrFalsey=u,e.isEmptyOrFalsy=i,e.merge=a,e.time=A,e.web=p,e}({});
73
+ */function d(e,t,r="round"){return e.setTime(Math[r](e.getTime()/t)*t),e}function b(e,t=null){let r=[e.getFullYear().toString(),(e.getMonth()+1).toString().padStart(2,"0"),e.getDate().toString().padStart(2,"0")];switch(typeof t){case"string":return r.join(t);case"object":return t?(t.Y=r[0],t.M=r[1],t.D=r[2],t):r;default:if(!t)return r;throw"invalid type"}}function A(e,t=null){let r=[e.getHours().toString().padStart(2,"0"),e.getMinutes().toString().padStart(2,"0"),e.getSeconds().toString().padStart(2,"0")];switch(typeof t){case"string":return r.join(t);case"object":return t?(t.h=r[0],t.m=r[1],t.s=r[2],t):r;default:if(!t)return r;throw"invalid type"}}var j=Object.freeze({__proto__:null,addTime:function(e,t){return e.setTime(e.getTime()+t),e},ceil:function(e,t){return d(e,t,"ceil")},date:function(...e){return e.length&&e[0]?e[0]instanceof Date?e[0]:new Date(...e):new Date},floor:function(e,t){return d(e,t,"floor")},hms:A,iso9075:function(e){return b(e,"-")+" "+A(e,":")},localize:function(e){return e.setTime(e.getTime()-6e4*e.getTimezoneOffset()),e},ms:function(...e){if(!e.length||!e[0])return Date.now();let t=e[0];return"number"==typeof t?t:t instanceof Date?t.getTime():new Date(...e).getTime()},quantize:d,round:function(e,t){return d(e,t,"round")},ymd:b});return e.arr=t,e.clean=o,e.dig=a,e.gen=f,e.is=r,e.isEmpty=n,e.isEmptyOrFalsey=u,e.isEmptyOrFalsy=i,e.merge=s,e.subst=c,e.time=j,e.web=h,e}({});
@@ -160,7 +160,43 @@ function merge$1(x, y, opts = {}) {
160
160
  return x.concat(y);
161
161
  }
162
162
  return y;
163
- }var gen=/*#__PURE__*/Object.freeze({__proto__:null,arr:arr,clean:clean$1,is:is,isEmpty:isEmpty,isEmptyOrFalsey:isEmptyOrFalsey,isEmptyOrFalsy:isEmptyOrFalsy,merge:merge$1});/*!
163
+ }
164
+
165
+ /**
166
+ * Gets a property from the given object by the given string path.
167
+ * @param {object} obj - Object to traverse
168
+ * @param {string} path - Property names separated with '.'
169
+ * @return {any} value of the found property, or undefined if it's not found
170
+ */
171
+ function dig(obj, path) {
172
+ path = path.split('.');
173
+ for (let i = 0; i < path.length; i++) {
174
+ let p = path[i];
175
+ if (typeof obj == 'object' && p in obj) obj = obj[p];
176
+ else return undefined;
177
+ }
178
+ return obj;
179
+ }
180
+
181
+ /**
182
+ * Substitutes the properties of the given data for the references in the given string.
183
+ * @param {string} str - String that contains references to the properties
184
+ * @param {object} data - Object that contains properties to replace the references
185
+ * @param {object} [opts] - Options
186
+ * @return {string} a modified `str`
187
+ */
188
+ function subst(str, data, opts = {}) {
189
+ let {
190
+ modifier = null,
191
+ start = '{{',
192
+ end = '}}',
193
+ } = opts;
194
+ let ref = new RegExp(start + '\\s*([-.\\w]+)\\s*' + end, 'g');
195
+ return str.replaceAll(ref, modifier
196
+ ? (_, m1) => (modifier(dig(data, m1), m1, data) || '')
197
+ : (_, m1) => (dig(data, m1) || '')
198
+ );
199
+ }var gen=/*#__PURE__*/Object.freeze({__proto__:null,arr:arr,clean:clean$1,dig:dig,is:is,isEmpty:isEmpty,isEmptyOrFalsey:isEmptyOrFalsey,isEmptyOrFalsy:isEmptyOrFalsy,merge:merge$1,subst:subst});/*!
164
200
  * === @amekusa/util.js/web === *
165
201
  * MIT License
166
202
  *
@@ -478,7 +514,7 @@ function dev(set = undefined) {
478
514
  if (set != undefined) node_process.env.NODE_ENV = set ? value : '';
479
515
  return node_process.env.NODE_ENV == value;
480
516
  }var sh=/*#__PURE__*/Object.freeze({__proto__:null,args:args,dev:dev,exec:exec,prod:prod});/*!
481
- * === @amekusa/util.js/io === *
517
+ * === @amekusa/util.js/io/AssetImporter === *
482
518
  * MIT License
483
519
  *
484
520
  * Copyright (c) 2024 Satoshi Soma
@@ -503,6 +539,196 @@ function dev(set = undefined) {
503
539
  */
504
540
 
505
541
  /**
542
+ * This is for copying styles or scripts to a certain HTML directory.
543
+ * @author Satoshi Soma (github.com/amekusa)
544
+ */
545
+ class AssetImporter {
546
+ /**
547
+ * @param {object} config
548
+ * @param {boolean} [config.minify=false] - Prefer `*.min.*` version
549
+ * @param {string} config.src - Source dir to search
550
+ * @param {string} config.dst - Destination dir
551
+ */
552
+ constructor(config) {
553
+ this.config = Object.assign({
554
+ minify: false,
555
+ src: '', // source dir to search
556
+ dst: '', // destination dir
557
+ }, config);
558
+ this.queue = [];
559
+ this.results = {
560
+ script: [],
561
+ style: [],
562
+ asset: [],
563
+ };
564
+ }
565
+ /**
566
+ * Adds a new item to import.
567
+ * @param {string|string[]|object|object[]} newImport
568
+ */
569
+ add(newImport) {
570
+ if (!Array.isArray(newImport)) newImport = [newImport];
571
+ for (let i = 0; i < newImport.length; i++) {
572
+ let item = newImport[i];
573
+ switch (typeof item) {
574
+ case 'string':
575
+ item = {src: item};
576
+ break;
577
+ case 'object':
578
+ if (Array.isArray(item)) throw `invalid type: array`;
579
+ break;
580
+ default:
581
+ throw `invalid type: ${typeof item}`;
582
+ }
583
+ if (!('src' in item)) throw `'src' property is missing`;
584
+ this.queue.push(Object.assign({
585
+ order: 0,
586
+ resolve: 'local',
587
+ private: false,
588
+ }, item));
589
+ }
590
+ }
591
+ /**
592
+ * Resolves the location of the given file path
593
+ * @param {string} file - File path
594
+ * @param {string} method - Resolution method
595
+ * @return {string} Resolved file path
596
+ */
597
+ resolve(file, method) {
598
+ let find = [];
599
+ if (this.config.minify) {
600
+ let _ext = ext(file);
601
+ find.push(ext(file, '.min' + _ext));
602
+ }
603
+ find.push(file);
604
+ for (let i = 0; i < find.length; i++) {
605
+ let r;
606
+ switch (method) {
607
+ case 'require':
608
+ try {
609
+ r = require.resolve(find[i]);
610
+ } catch (e) {
611
+ if (e.code == 'MODULE_NOT_FOUND') continue;
612
+ throw e;
613
+ }
614
+ return r;
615
+ case 'local':
616
+ r = path.join(this.config.src, find[i]);
617
+ if (fs.existsSync(r)) return r;
618
+ break;
619
+ case 'local:absolute':
620
+ case 'local:abs':
621
+ r = find[i];
622
+ if (fs.existsSync(r)) return r;
623
+ break;
624
+ default:
625
+ throw `invalid resolution method: ${method}`;
626
+ }
627
+ }
628
+ throw `cannot resolve '${file}'`;
629
+ }
630
+ /**
631
+ * Imports all items in the queue at once.
632
+ * @return {Promise}
633
+ */
634
+ import() {
635
+ let tasks = [];
636
+ let typeMap = {
637
+ '.css': 'style',
638
+ '.js': 'script',
639
+ };
640
+ this.queue.sort((a, b) => (Number(a.order) - Number(b.order))); // sort by order
641
+ while (this.queue.length) {
642
+ let item = this.queue.shift();
643
+ let {type, src} = item;
644
+ let url;
645
+
646
+ if (!item.resolve) { // no resolution
647
+ url = src;
648
+ if (!type) type = typeMap[ext(src)] || 'asset';
649
+ console.log('---- File Link ----');
650
+ console.log(' type:', type);
651
+ console.log(' src:', src);
652
+
653
+ } else { // needs resolution
654
+ let {dst:dstDir, as:dstFile} = item;
655
+ let create = item.resolve == 'create'; // needs creation?
656
+ if (create) {
657
+ if (!dstFile) throw `'as' property is required with {resolve: 'create'}`;
658
+ } else {
659
+ src = this.resolve(src, item.resolve);
660
+ if (!dstFile) dstFile = path.basename(src);
661
+ }
662
+ if (!type) type = typeMap[ext(dstFile)] || 'asset';
663
+ if (!dstDir) dstDir = type + 's';
664
+
665
+ // absolute destination
666
+ url = path.join(dstDir, dstFile);
667
+ let dst = path.join(this.config.dst, url);
668
+ dstDir = path.dirname(dst);
669
+ if (!fs.existsSync(dstDir)) fs.mkdirSync(dstDir, {recursive:true});
670
+
671
+ // create/copy file
672
+ if (create) {
673
+ console.log('---- File Creation ----');
674
+ console.log(' type:', type);
675
+ console.log(' dst:', dst);
676
+ tasks.push(fsp.writeFile(dst, src));
677
+ } else {
678
+ console.log('---- File Import ----');
679
+ console.log(' type:', type);
680
+ console.log(' src:', src);
681
+ console.log(' dst:', dst);
682
+ tasks.push(fsp.copyFile(src, dst));
683
+ }
684
+ }
685
+
686
+ if (!item.private) {
687
+ if (!(type in this.results)) this.results[type] = [];
688
+ this.results[type].push({type, url});
689
+ }
690
+ }
691
+
692
+ return tasks.length ? Promise.all(tasks) : Promise.resolve();
693
+ }
694
+ /**
695
+ * Outputs HTML tags for imported items.
696
+ * @param {string} [type] - Type
697
+ * @return {string} HTML
698
+ */
699
+ toHTML(type = null) {
700
+ let r;
701
+ if (type) {
702
+ let tmpl = templates[type];
703
+ if (!tmpl) return '';
704
+ if (Array.isArray(tmpl)) tmpl = tmpl.join('\n');
705
+ let items = this.results[type];
706
+ r = new Array(items.length);
707
+ for (let i = 0; i < items.length; i++) {
708
+ r[i] = tmpl.replaceAll('%s', items[i].url || '');
709
+ }
710
+ } else {
711
+ let keys = Object.keys(this.results);
712
+ r = new Array(keys.length);
713
+ for (let i = 0; i < keys.length; i++) {
714
+ r[i] = this.toHTML(keys[i]);
715
+ }
716
+ }
717
+ return r.join('\n');
718
+ }
719
+ }
720
+
721
+ const templates = {
722
+ script: [
723
+ `<script src="%s"></script>`,
724
+ ],
725
+ module: [
726
+ `<script type="module" src="%s"></script>`,
727
+ ],
728
+ style: [
729
+ `<link rel="stylesheet" href="%s">`,
730
+ ],
731
+ };/**
506
732
  * Alias of `os.homedir()`.
507
733
  * @type {string}
508
734
  */
@@ -649,7 +875,7 @@ function modifyStream(fn) {
649
875
  }
650
876
  }
651
877
  });
652
- }var io=/*#__PURE__*/Object.freeze({__proto__:null,clean:clean,copy:copy,ext:ext,find:find,home:home,modifyStream:modifyStream,untilde:untilde});const merge = Object.assign;
878
+ }var io=/*#__PURE__*/Object.freeze({__proto__:null,AssetImporter:AssetImporter,clean:clean,copy:copy,ext:ext,find:find,home:home,modifyStream:modifyStream,untilde:untilde});const merge = Object.assign;
653
879
 
654
880
  /*!
655
881
  * === @amekusa/util.js/test === *
@@ -800,7 +1026,8 @@ function testMethod(construct, method, cases, opts = {}) {
800
1026
  // ---- instantiate ----
801
1027
  let obj;
802
1028
  if (opts.static) {
803
- if ('initArgs' in c) invalid(`'initArgs' is not for static method`);
1029
+ if ('initArgs' in c) invalid(`'initArgs' is not available for a static method`);
1030
+ if ('prepare' in c) invalid(`'prepare' is not available for a static method`);
804
1031
  obj = construct;
805
1032
  } else {
806
1033
  let initArgs = [];
@@ -814,6 +1041,11 @@ function testMethod(construct, method, cases, opts = {}) {
814
1041
  } catch (e) {
815
1042
  obj = construct(...initArgs);
816
1043
  }
1044
+ if ('prepare' in c) {
1045
+ if (typeof c.prepare != 'function') invalid(`'prepare' must be a function`);
1046
+ c.prepare(obj);
1047
+ delete c.prepare;
1048
+ }
817
1049
  }
818
1050
 
819
1051
  // ---- call method ----
@@ -923,4 +1155,4 @@ function testInstance(construct, cases, opts = {}) {
923
1155
  }
924
1156
  }
925
1157
  });
926
- }var test=/*#__PURE__*/Object.freeze({__proto__:null,InvalidTest:InvalidTest,assertEqual:assertEqual,assertProps:assertProps,assertType:assertType,testFn:testFn,testInstance:testInstance,testMethod:testMethod});exports.arr=arr;exports.clean=clean$1;exports.gen=gen;exports.io=io;exports.is=is;exports.isEmpty=isEmpty;exports.isEmptyOrFalsey=isEmptyOrFalsey;exports.isEmptyOrFalsy=isEmptyOrFalsy;exports.merge=merge$1;exports.sh=sh;exports.test=test;exports.time=time;exports.web=web;
1158
+ }var test=/*#__PURE__*/Object.freeze({__proto__:null,InvalidTest:InvalidTest,assertEqual:assertEqual,assertProps:assertProps,assertType:assertType,testFn:testFn,testInstance:testInstance,testMethod:testMethod});exports.arr=arr;exports.clean=clean$1;exports.dig=dig;exports.gen=gen;exports.io=io;exports.is=is;exports.isEmpty=isEmpty;exports.isEmptyOrFalsey=isEmptyOrFalsey;exports.isEmptyOrFalsy=isEmptyOrFalsy;exports.merge=merge$1;exports.sh=sh;exports.subst=subst;exports.test=test;exports.time=time;exports.web=web;
@@ -1,4 +1,4 @@
1
- import os from'node:os';import fs from'node:fs';import*as fsp from'node:fs/promises';import path from'node:path';import {Transform}from'node:stream';import {env}from'node:process';import {exec as exec$1}from'node:child_process';import assert from'node:assert';/*!
1
+ import os from'node:os';import fs,{existsSync,mkdirSync}from'node:fs';import*as fsp from'node:fs/promises';import {writeFile,copyFile}from'node:fs/promises';import path,{join,basename,dirname}from'node:path';import {Transform}from'node:stream';import {env}from'node:process';import {exec as exec$1}from'node:child_process';import assert from'node:assert';/*!
2
2
  * === @amekusa/util.js/gen === *
3
3
  * MIT License
4
4
  *
@@ -160,7 +160,43 @@ function merge$1(x, y, opts = {}) {
160
160
  return x.concat(y);
161
161
  }
162
162
  return y;
163
- }var gen=/*#__PURE__*/Object.freeze({__proto__:null,arr:arr,clean:clean$1,is:is,isEmpty:isEmpty,isEmptyOrFalsey:isEmptyOrFalsey,isEmptyOrFalsy:isEmptyOrFalsy,merge:merge$1});/*!
163
+ }
164
+
165
+ /**
166
+ * Gets a property from the given object by the given string path.
167
+ * @param {object} obj - Object to traverse
168
+ * @param {string} path - Property names separated with '.'
169
+ * @return {any} value of the found property, or undefined if it's not found
170
+ */
171
+ function dig(obj, path) {
172
+ path = path.split('.');
173
+ for (let i = 0; i < path.length; i++) {
174
+ let p = path[i];
175
+ if (typeof obj == 'object' && p in obj) obj = obj[p];
176
+ else return undefined;
177
+ }
178
+ return obj;
179
+ }
180
+
181
+ /**
182
+ * Substitutes the properties of the given data for the references in the given string.
183
+ * @param {string} str - String that contains references to the properties
184
+ * @param {object} data - Object that contains properties to replace the references
185
+ * @param {object} [opts] - Options
186
+ * @return {string} a modified `str`
187
+ */
188
+ function subst(str, data, opts = {}) {
189
+ let {
190
+ modifier = null,
191
+ start = '{{',
192
+ end = '}}',
193
+ } = opts;
194
+ let ref = new RegExp(start + '\\s*([-.\\w]+)\\s*' + end, 'g');
195
+ return str.replaceAll(ref, modifier
196
+ ? (_, m1) => (modifier(dig(data, m1), m1, data) || '')
197
+ : (_, m1) => (dig(data, m1) || '')
198
+ );
199
+ }var gen=/*#__PURE__*/Object.freeze({__proto__:null,arr:arr,clean:clean$1,dig:dig,is:is,isEmpty:isEmpty,isEmptyOrFalsey:isEmptyOrFalsey,isEmptyOrFalsy:isEmptyOrFalsy,merge:merge$1,subst:subst});/*!
164
200
  * === @amekusa/util.js/web === *
165
201
  * MIT License
166
202
  *
@@ -478,7 +514,7 @@ function dev(set = undefined) {
478
514
  if (set != undefined) env.NODE_ENV = set ? value : '';
479
515
  return env.NODE_ENV == value;
480
516
  }var sh=/*#__PURE__*/Object.freeze({__proto__:null,args:args,dev:dev,exec:exec,prod:prod});/*!
481
- * === @amekusa/util.js/io === *
517
+ * === @amekusa/util.js/io/AssetImporter === *
482
518
  * MIT License
483
519
  *
484
520
  * Copyright (c) 2024 Satoshi Soma
@@ -503,6 +539,196 @@ function dev(set = undefined) {
503
539
  */
504
540
 
505
541
  /**
542
+ * This is for copying styles or scripts to a certain HTML directory.
543
+ * @author Satoshi Soma (github.com/amekusa)
544
+ */
545
+ class AssetImporter {
546
+ /**
547
+ * @param {object} config
548
+ * @param {boolean} [config.minify=false] - Prefer `*.min.*` version
549
+ * @param {string} config.src - Source dir to search
550
+ * @param {string} config.dst - Destination dir
551
+ */
552
+ constructor(config) {
553
+ this.config = Object.assign({
554
+ minify: false,
555
+ src: '', // source dir to search
556
+ dst: '', // destination dir
557
+ }, config);
558
+ this.queue = [];
559
+ this.results = {
560
+ script: [],
561
+ style: [],
562
+ asset: [],
563
+ };
564
+ }
565
+ /**
566
+ * Adds a new item to import.
567
+ * @param {string|string[]|object|object[]} newImport
568
+ */
569
+ add(newImport) {
570
+ if (!Array.isArray(newImport)) newImport = [newImport];
571
+ for (let i = 0; i < newImport.length; i++) {
572
+ let item = newImport[i];
573
+ switch (typeof item) {
574
+ case 'string':
575
+ item = {src: item};
576
+ break;
577
+ case 'object':
578
+ if (Array.isArray(item)) throw `invalid type: array`;
579
+ break;
580
+ default:
581
+ throw `invalid type: ${typeof item}`;
582
+ }
583
+ if (!('src' in item)) throw `'src' property is missing`;
584
+ this.queue.push(Object.assign({
585
+ order: 0,
586
+ resolve: 'local',
587
+ private: false,
588
+ }, item));
589
+ }
590
+ }
591
+ /**
592
+ * Resolves the location of the given file path
593
+ * @param {string} file - File path
594
+ * @param {string} method - Resolution method
595
+ * @return {string} Resolved file path
596
+ */
597
+ resolve(file, method) {
598
+ let find = [];
599
+ if (this.config.minify) {
600
+ let _ext = ext(file);
601
+ find.push(ext(file, '.min' + _ext));
602
+ }
603
+ find.push(file);
604
+ for (let i = 0; i < find.length; i++) {
605
+ let r;
606
+ switch (method) {
607
+ case 'require':
608
+ try {
609
+ r = require.resolve(find[i]);
610
+ } catch (e) {
611
+ if (e.code == 'MODULE_NOT_FOUND') continue;
612
+ throw e;
613
+ }
614
+ return r;
615
+ case 'local':
616
+ r = join(this.config.src, find[i]);
617
+ if (existsSync(r)) return r;
618
+ break;
619
+ case 'local:absolute':
620
+ case 'local:abs':
621
+ r = find[i];
622
+ if (existsSync(r)) return r;
623
+ break;
624
+ default:
625
+ throw `invalid resolution method: ${method}`;
626
+ }
627
+ }
628
+ throw `cannot resolve '${file}'`;
629
+ }
630
+ /**
631
+ * Imports all items in the queue at once.
632
+ * @return {Promise}
633
+ */
634
+ import() {
635
+ let tasks = [];
636
+ let typeMap = {
637
+ '.css': 'style',
638
+ '.js': 'script',
639
+ };
640
+ this.queue.sort((a, b) => (Number(a.order) - Number(b.order))); // sort by order
641
+ while (this.queue.length) {
642
+ let item = this.queue.shift();
643
+ let {type, src} = item;
644
+ let url;
645
+
646
+ if (!item.resolve) { // no resolution
647
+ url = src;
648
+ if (!type) type = typeMap[ext(src)] || 'asset';
649
+ console.log('---- File Link ----');
650
+ console.log(' type:', type);
651
+ console.log(' src:', src);
652
+
653
+ } else { // needs resolution
654
+ let {dst:dstDir, as:dstFile} = item;
655
+ let create = item.resolve == 'create'; // needs creation?
656
+ if (create) {
657
+ if (!dstFile) throw `'as' property is required with {resolve: 'create'}`;
658
+ } else {
659
+ src = this.resolve(src, item.resolve);
660
+ if (!dstFile) dstFile = basename(src);
661
+ }
662
+ if (!type) type = typeMap[ext(dstFile)] || 'asset';
663
+ if (!dstDir) dstDir = type + 's';
664
+
665
+ // absolute destination
666
+ url = join(dstDir, dstFile);
667
+ let dst = join(this.config.dst, url);
668
+ dstDir = dirname(dst);
669
+ if (!existsSync(dstDir)) mkdirSync(dstDir, {recursive:true});
670
+
671
+ // create/copy file
672
+ if (create) {
673
+ console.log('---- File Creation ----');
674
+ console.log(' type:', type);
675
+ console.log(' dst:', dst);
676
+ tasks.push(writeFile(dst, src));
677
+ } else {
678
+ console.log('---- File Import ----');
679
+ console.log(' type:', type);
680
+ console.log(' src:', src);
681
+ console.log(' dst:', dst);
682
+ tasks.push(copyFile(src, dst));
683
+ }
684
+ }
685
+
686
+ if (!item.private) {
687
+ if (!(type in this.results)) this.results[type] = [];
688
+ this.results[type].push({type, url});
689
+ }
690
+ }
691
+
692
+ return tasks.length ? Promise.all(tasks) : Promise.resolve();
693
+ }
694
+ /**
695
+ * Outputs HTML tags for imported items.
696
+ * @param {string} [type] - Type
697
+ * @return {string} HTML
698
+ */
699
+ toHTML(type = null) {
700
+ let r;
701
+ if (type) {
702
+ let tmpl = templates[type];
703
+ if (!tmpl) return '';
704
+ if (Array.isArray(tmpl)) tmpl = tmpl.join('\n');
705
+ let items = this.results[type];
706
+ r = new Array(items.length);
707
+ for (let i = 0; i < items.length; i++) {
708
+ r[i] = tmpl.replaceAll('%s', items[i].url || '');
709
+ }
710
+ } else {
711
+ let keys = Object.keys(this.results);
712
+ r = new Array(keys.length);
713
+ for (let i = 0; i < keys.length; i++) {
714
+ r[i] = this.toHTML(keys[i]);
715
+ }
716
+ }
717
+ return r.join('\n');
718
+ }
719
+ }
720
+
721
+ const templates = {
722
+ script: [
723
+ `<script src="%s"></script>`,
724
+ ],
725
+ module: [
726
+ `<script type="module" src="%s"></script>`,
727
+ ],
728
+ style: [
729
+ `<link rel="stylesheet" href="%s">`,
730
+ ],
731
+ };/**
506
732
  * Alias of `os.homedir()`.
507
733
  * @type {string}
508
734
  */
@@ -649,7 +875,7 @@ function modifyStream(fn) {
649
875
  }
650
876
  }
651
877
  });
652
- }var io=/*#__PURE__*/Object.freeze({__proto__:null,clean:clean,copy:copy,ext:ext,find:find,home:home,modifyStream:modifyStream,untilde:untilde});const merge = Object.assign;
878
+ }var io=/*#__PURE__*/Object.freeze({__proto__:null,AssetImporter:AssetImporter,clean:clean,copy:copy,ext:ext,find:find,home:home,modifyStream:modifyStream,untilde:untilde});const merge = Object.assign;
653
879
 
654
880
  /*!
655
881
  * === @amekusa/util.js/test === *
@@ -800,7 +1026,8 @@ function testMethod(construct, method, cases, opts = {}) {
800
1026
  // ---- instantiate ----
801
1027
  let obj;
802
1028
  if (opts.static) {
803
- if ('initArgs' in c) invalid(`'initArgs' is not for static method`);
1029
+ if ('initArgs' in c) invalid(`'initArgs' is not available for a static method`);
1030
+ if ('prepare' in c) invalid(`'prepare' is not available for a static method`);
804
1031
  obj = construct;
805
1032
  } else {
806
1033
  let initArgs = [];
@@ -814,6 +1041,11 @@ function testMethod(construct, method, cases, opts = {}) {
814
1041
  } catch (e) {
815
1042
  obj = construct(...initArgs);
816
1043
  }
1044
+ if ('prepare' in c) {
1045
+ if (typeof c.prepare != 'function') invalid(`'prepare' must be a function`);
1046
+ c.prepare(obj);
1047
+ delete c.prepare;
1048
+ }
817
1049
  }
818
1050
 
819
1051
  // ---- call method ----
@@ -923,4 +1155,4 @@ function testInstance(construct, cases, opts = {}) {
923
1155
  }
924
1156
  }
925
1157
  });
926
- }var test=/*#__PURE__*/Object.freeze({__proto__:null,InvalidTest:InvalidTest,assertEqual:assertEqual,assertProps:assertProps,assertType:assertType,testFn:testFn,testInstance:testInstance,testMethod:testMethod});export{arr,clean$1 as clean,gen,io,is,isEmpty,isEmptyOrFalsey,isEmptyOrFalsy,merge$1 as merge,sh,test,time,web};
1158
+ }var test=/*#__PURE__*/Object.freeze({__proto__:null,InvalidTest:InvalidTest,assertEqual:assertEqual,assertProps:assertProps,assertType:assertType,testFn:testFn,testInstance:testInstance,testMethod:testMethod});export{arr,clean$1 as clean,dig,gen,io,is,isEmpty,isEmptyOrFalsey,isEmptyOrFalsy,merge$1 as merge,sh,subst,test,time,web};
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "access": "public",
6
6
  "registry": "https://registry.npmjs.org/"
7
7
  },
8
- "version": "2.0.0",
8
+ "version": "2.2.0",
9
9
  "description": "General purpose utility for JS",
10
10
  "type": "module",
11
11
  "files": [