From a40d45c2c14930a77053b63aba4b184fe0f5d543 Mon Sep 17 00:00:00 2001 From: Avram Walden Date: Fri, 14 Mar 2025 16:00:29 -0700 Subject: [PATCH 1/4] =?UTF-8?q?style:=20=F0=9F=92=84=20adds=20and=20applie?= =?UTF-8?q?s=20some=20eslint=20rules?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .yarn/releases/yarn-4.5.3.cjs | 2 +- README.md | 4 +- commitlint.config.js | 2 +- eslint.config.mjs | 28 ++ fixJestDomEnvironment.ts | 2 +- jest.config.js | 14 +- jest.setup.ts | 8 +- release.config.js | 14 +- rollup.config.js | 90 ++-- src/Form/FormMetaWrapper.tsx | 4 +- src/Form/FormProvider.ts | 12 +- src/Form/index.tsx | 24 +- src/Inputs/DynamicInputs.tsx | 10 +- src/Inputs/Input.tsx | 12 +- src/Inputs/NestedFields.tsx | 8 +- src/Inputs/Submit.tsx | 8 +- src/Inputs/index.ts | 18 +- src/Inputs/useDynamicInputs.ts | 14 +- src/index.ts | 8 +- src/useInertiaForm.ts | 46 +- src/useInertiaInput/index.ts | 14 +- src/useInertiaInput/inputStrategy.ts | 4 +- src/utils/createContext.ts | 4 +- src/utils/fillEmptyValues.ts | 4 +- src/utils/index.ts | 26 +- src/utils/isUnset.ts | 10 +- src/utils/renameObjectWithAttributes.ts | 8 +- src/utils/unsetCompact.ts | 14 +- src/utils/useMaybeRemember.ts | 14 +- tests/components/ContextTest.tsx | 8 +- tests/components/data.ts | 26 +- tests/formComponent.test.tsx | 184 ++++---- tests/nestedFields.test.tsx | 16 +- tests/server.mock.ts | 24 +- tests/useDynamicInputs.test.tsx | 86 ++-- tests/useInertiaForm.server.test.tsx | 68 +-- tests/useInertiaForm.test.tsx | 422 +++++++++--------- tests/useInertiaInput.test.tsx | 58 +-- tests/utils/coerceArray.test.ts | 10 +- tests/utils/fillEmptyValues.test.ts | 18 +- tests/utils/isUnset.test.ts | 38 +- .../utils/renameObjectWithAttributes.test.ts | 18 +- tests/utils/stripAttributes.test.ts | 16 +- tests/utils/unsetCompact.test.ts | 156 +++---- 44 files changed, 801 insertions(+), 773 deletions(-) diff --git a/.yarn/releases/yarn-4.5.3.cjs b/.yarn/releases/yarn-4.5.3.cjs index 7529af2..578a751 100755 --- a/.yarn/releases/yarn-4.5.3.cjs +++ b/.yarn/releases/yarn-4.5.3.cjs @@ -1,5 +1,5 @@ #!/usr/bin/env node -/* eslint-disable */ + //prettier-ignore (()=>{var j3e=Object.create;var gT=Object.defineProperty;var G3e=Object.getOwnPropertyDescriptor;var W3e=Object.getOwnPropertyNames;var Y3e=Object.getPrototypeOf,K3e=Object.prototype.hasOwnProperty;var ve=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,r)=>(typeof require<"u"?require:e)[r]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')});var It=(t,e)=>()=>(t&&(e=t(t=0)),e);var _=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),Kt=(t,e)=>{for(var r in e)gT(t,r,{get:e[r],enumerable:!0})},V3e=(t,e,r,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of W3e(e))!K3e.call(t,a)&&a!==r&&gT(t,a,{get:()=>e[a],enumerable:!(o=G3e(e,a))||o.enumerable});return t};var et=(t,e,r)=>(r=t!=null?j3e(Y3e(t)):{},V3e(e||!t||!t.__esModule?gT(r,"default",{value:t,enumerable:!0}):r,t));var Pi={};Kt(Pi,{SAFE_TIME:()=>cW,S_IFDIR:()=>VD,S_IFLNK:()=>zD,S_IFMT:()=>Hu,S_IFREG:()=>ow});var Hu,VD,ow,zD,cW,uW=It(()=>{Hu=61440,VD=16384,ow=32768,zD=40960,cW=456789e3});var sr={};Kt(sr,{EBADF:()=>ho,EBUSY:()=>z3e,EEXIST:()=>t_e,EINVAL:()=>X3e,EISDIR:()=>e_e,ENOENT:()=>Z3e,ENOSYS:()=>J3e,ENOTDIR:()=>$3e,ENOTEMPTY:()=>n_e,EOPNOTSUPP:()=>i_e,EROFS:()=>r_e,ERR_DIR_CLOSED:()=>dT});function Nl(t,e){return Object.assign(new Error(`${t}: ${e}`),{code:t})}function z3e(t){return Nl("EBUSY",t)}function J3e(t,e){return Nl("ENOSYS",`${t}, ${e}`)}function X3e(t){return Nl("EINVAL",`invalid argument, ${t}`)}function ho(t){return Nl("EBADF",`bad file descriptor, ${t}`)}function Z3e(t){return Nl("ENOENT",`no such file or directory, ${t}`)}function $3e(t){return Nl("ENOTDIR",`not a directory, ${t}`)}function e_e(t){return Nl("EISDIR",`illegal operation on a directory, ${t}`)}function t_e(t){return Nl("EEXIST",`file already exists, ${t}`)}function r_e(t){return Nl("EROFS",`read-only filesystem, ${t}`)}function n_e(t){return Nl("ENOTEMPTY",`directory not empty, ${t}`)}function i_e(t){return Nl("EOPNOTSUPP",`operation not supported, ${t}`)}function dT(){return Nl("ERR_DIR_CLOSED","Directory handle was closed")}var JD=It(()=>{});var wa={};Kt(wa,{BigIntStatsEntry:()=>cm,DEFAULT_MODE:()=>ET,DirEntry:()=>mT,StatEntry:()=>lm,areStatsEqual:()=>CT,clearStats:()=>XD,convertToBigIntStats:()=>o_e,makeDefaultStats:()=>AW,makeEmptyStats:()=>s_e});function AW(){return new lm}function s_e(){return XD(AW())}function XD(t){for(let e in t)if(Object.hasOwn(t,e)){let r=t[e];typeof r=="number"?t[e]=0:typeof r=="bigint"?t[e]=BigInt(0):yT.types.isDate(r)&&(t[e]=new Date(0))}return t}function o_e(t){let e=new cm;for(let r in t)if(Object.hasOwn(t,r)){let o=t[r];typeof o=="number"?e[r]=BigInt(o):yT.types.isDate(o)&&(e[r]=new Date(o))}return e.atimeNs=e.atimeMs*BigInt(1e6),e.mtimeNs=e.mtimeMs*BigInt(1e6),e.ctimeNs=e.ctimeMs*BigInt(1e6),e.birthtimeNs=e.birthtimeMs*BigInt(1e6),e}function CT(t,e){if(t.atimeMs!==e.atimeMs||t.birthtimeMs!==e.birthtimeMs||t.blksize!==e.blksize||t.blocks!==e.blocks||t.ctimeMs!==e.ctimeMs||t.dev!==e.dev||t.gid!==e.gid||t.ino!==e.ino||t.isBlockDevice()!==e.isBlockDevice()||t.isCharacterDevice()!==e.isCharacterDevice()||t.isDirectory()!==e.isDirectory()||t.isFIFO()!==e.isFIFO()||t.isFile()!==e.isFile()||t.isSocket()!==e.isSocket()||t.isSymbolicLink()!==e.isSymbolicLink()||t.mode!==e.mode||t.mtimeMs!==e.mtimeMs||t.nlink!==e.nlink||t.rdev!==e.rdev||t.size!==e.size||t.uid!==e.uid)return!1;let r=t,o=e;return!(r.atimeNs!==o.atimeNs||r.mtimeNs!==o.mtimeNs||r.ctimeNs!==o.ctimeNs||r.birthtimeNs!==o.birthtimeNs)}var yT,ET,mT,lm,cm,IT=It(()=>{yT=et(ve("util")),ET=33188,mT=class{constructor(){this.name="";this.path="";this.mode=0}isBlockDevice(){return!1}isCharacterDevice(){return!1}isDirectory(){return(this.mode&61440)===16384}isFIFO(){return!1}isFile(){return(this.mode&61440)===32768}isSocket(){return!1}isSymbolicLink(){return(this.mode&61440)===40960}},lm=class{constructor(){this.uid=0;this.gid=0;this.size=0;this.blksize=0;this.atimeMs=0;this.mtimeMs=0;this.ctimeMs=0;this.birthtimeMs=0;this.atime=new Date(0);this.mtime=new Date(0);this.ctime=new Date(0);this.birthtime=new Date(0);this.dev=0;this.ino=0;this.mode=ET;this.nlink=1;this.rdev=0;this.blocks=1}isBlockDevice(){return!1}isCharacterDevice(){return!1}isDirectory(){return(this.mode&61440)===16384}isFIFO(){return!1}isFile(){return(this.mode&61440)===32768}isSocket(){return!1}isSymbolicLink(){return(this.mode&61440)===40960}},cm=class{constructor(){this.uid=BigInt(0);this.gid=BigInt(0);this.size=BigInt(0);this.blksize=BigInt(0);this.atimeMs=BigInt(0);this.mtimeMs=BigInt(0);this.ctimeMs=BigInt(0);this.birthtimeMs=BigInt(0);this.atimeNs=BigInt(0);this.mtimeNs=BigInt(0);this.ctimeNs=BigInt(0);this.birthtimeNs=BigInt(0);this.atime=new Date(0);this.mtime=new Date(0);this.ctime=new Date(0);this.birthtime=new Date(0);this.dev=BigInt(0);this.ino=BigInt(0);this.mode=BigInt(ET);this.nlink=BigInt(1);this.rdev=BigInt(0);this.blocks=BigInt(1)}isBlockDevice(){return!1}isCharacterDevice(){return!1}isDirectory(){return(this.mode&BigInt(61440))===BigInt(16384)}isFIFO(){return!1}isFile(){return(this.mode&BigInt(61440))===BigInt(32768)}isSocket(){return!1}isSymbolicLink(){return(this.mode&BigInt(61440))===BigInt(40960)}}});function A_e(t){let e,r;if(e=t.match(c_e))t=e[1];else if(r=t.match(u_e))t=`\\\\${r[1]?".\\":""}${r[2]}`;else return t;return t.replace(/\//g,"\\")}function f_e(t){t=t.replace(/\\/g,"/");let e,r;return(e=t.match(a_e))?t=`/${e[1]}`:(r=t.match(l_e))&&(t=`/unc/${r[1]?".dot/":""}${r[2]}`),t}function ZD(t,e){return t===Ae?pW(e):wT(e)}var aw,Bt,mr,Ae,K,fW,a_e,l_e,c_e,u_e,wT,pW,Ba=It(()=>{aw=et(ve("path")),Bt={root:"/",dot:".",parent:".."},mr={home:"~",nodeModules:"node_modules",manifest:"package.json",lockfile:"yarn.lock",virtual:"__virtual__",pnpJs:".pnp.js",pnpCjs:".pnp.cjs",pnpData:".pnp.data.json",pnpEsmLoader:".pnp.loader.mjs",rc:".yarnrc.yml",env:".env"},Ae=Object.create(aw.default),K=Object.create(aw.default.posix);Ae.cwd=()=>process.cwd();K.cwd=process.platform==="win32"?()=>wT(process.cwd()):process.cwd;process.platform==="win32"&&(K.resolve=(...t)=>t.length>0&&K.isAbsolute(t[0])?aw.default.posix.resolve(...t):aw.default.posix.resolve(K.cwd(),...t));fW=function(t,e,r){return e=t.normalize(e),r=t.normalize(r),e===r?".":(e.endsWith(t.sep)||(e=e+t.sep),r.startsWith(e)?r.slice(e.length):null)};Ae.contains=(t,e)=>fW(Ae,t,e);K.contains=(t,e)=>fW(K,t,e);a_e=/^([a-zA-Z]:.*)$/,l_e=/^\/\/(\.\/)?(.*)$/,c_e=/^\/([a-zA-Z]:.*)$/,u_e=/^\/unc\/(\.dot\/)?(.*)$/;wT=process.platform==="win32"?f_e:t=>t,pW=process.platform==="win32"?A_e:t=>t;Ae.fromPortablePath=pW;Ae.toPortablePath=wT});async function $D(t,e){let r="0123456789abcdef";await t.mkdirPromise(e.indexPath,{recursive:!0});let o=[];for(let a of r)for(let n of r)o.push(t.mkdirPromise(t.pathUtils.join(e.indexPath,`${a}${n}`),{recursive:!0}));return await Promise.all(o),e.indexPath}async function hW(t,e,r,o,a){let n=t.pathUtils.normalize(e),u=r.pathUtils.normalize(o),A=[],p=[],{atime:h,mtime:E}=a.stableTime?{atime:H0,mtime:H0}:await r.lstatPromise(u);await t.mkdirpPromise(t.pathUtils.dirname(e),{utimes:[h,E]}),await BT(A,p,t,n,r,u,{...a,didParentExist:!0});for(let w of A)await w();await Promise.all(p.map(w=>w()))}async function BT(t,e,r,o,a,n,u){let A=u.didParentExist?await gW(r,o):null,p=await a.lstatPromise(n),{atime:h,mtime:E}=u.stableTime?{atime:H0,mtime:H0}:p,w;switch(!0){case p.isDirectory():w=await h_e(t,e,r,o,A,a,n,p,u);break;case p.isFile():w=await m_e(t,e,r,o,A,a,n,p,u);break;case p.isSymbolicLink():w=await y_e(t,e,r,o,A,a,n,p,u);break;default:throw new Error(`Unsupported file type (${p.mode})`)}return(u.linkStrategy?.type!=="HardlinkFromIndex"||!p.isFile())&&((w||A?.mtime?.getTime()!==E.getTime()||A?.atime?.getTime()!==h.getTime())&&(e.push(()=>r.lutimesPromise(o,h,E)),w=!0),(A===null||(A.mode&511)!==(p.mode&511))&&(e.push(()=>r.chmodPromise(o,p.mode&511)),w=!0)),w}async function gW(t,e){try{return await t.lstatPromise(e)}catch{return null}}async function h_e(t,e,r,o,a,n,u,A,p){if(a!==null&&!a.isDirectory())if(p.overwrite)t.push(async()=>r.removePromise(o)),a=null;else return!1;let h=!1;a===null&&(t.push(async()=>{try{await r.mkdirPromise(o,{mode:A.mode})}catch(D){if(D.code!=="EEXIST")throw D}}),h=!0);let E=await n.readdirPromise(u),w=p.didParentExist&&!a?{...p,didParentExist:!1}:p;if(p.stableSort)for(let D of E.sort())await BT(t,e,r,r.pathUtils.join(o,D),n,n.pathUtils.join(u,D),w)&&(h=!0);else(await Promise.all(E.map(async b=>{await BT(t,e,r,r.pathUtils.join(o,b),n,n.pathUtils.join(u,b),w)}))).some(b=>b)&&(h=!0);return h}async function g_e(t,e,r,o,a,n,u,A,p,h){let E=await n.checksumFilePromise(u,{algorithm:"sha1"}),w=420,D=A.mode&511,b=`${E}${D!==w?D.toString(8):""}`,C=r.pathUtils.join(h.indexPath,E.slice(0,2),`${b}.dat`),T;(ue=>(ue[ue.Lock=0]="Lock",ue[ue.Rename=1]="Rename"))(T||={});let N=1,U=await gW(r,C);if(a){let le=U&&a.dev===U.dev&&a.ino===U.ino,ce=U?.mtimeMs!==p_e;if(le&&ce&&h.autoRepair&&(N=0,U=null),!le)if(p.overwrite)t.push(async()=>r.removePromise(o)),a=null;else return!1}let z=!U&&N===1?`${C}.${Math.floor(Math.random()*4294967296).toString(16).padStart(8,"0")}`:null,te=!1;return t.push(async()=>{if(!U&&(N===0&&await r.lockPromise(C,async()=>{let le=await n.readFilePromise(u);await r.writeFilePromise(C,le)}),N===1&&z)){let le=await n.readFilePromise(u);await r.writeFilePromise(z,le);try{await r.linkPromise(z,C)}catch(ce){if(ce.code==="EEXIST")te=!0,await r.unlinkPromise(z);else throw ce}}a||await r.linkPromise(C,o)}),e.push(async()=>{U||(await r.lutimesPromise(C,H0,H0),D!==w&&await r.chmodPromise(C,D)),z&&!te&&await r.unlinkPromise(z)}),!1}async function d_e(t,e,r,o,a,n,u,A,p){if(a!==null)if(p.overwrite)t.push(async()=>r.removePromise(o)),a=null;else return!1;return t.push(async()=>{let h=await n.readFilePromise(u);await r.writeFilePromise(o,h)}),!0}async function m_e(t,e,r,o,a,n,u,A,p){return p.linkStrategy?.type==="HardlinkFromIndex"?g_e(t,e,r,o,a,n,u,A,p,p.linkStrategy):d_e(t,e,r,o,a,n,u,A,p)}async function y_e(t,e,r,o,a,n,u,A,p){if(a!==null)if(p.overwrite)t.push(async()=>r.removePromise(o)),a=null;else return!1;return t.push(async()=>{await r.symlinkPromise(ZD(r.pathUtils,await n.readlinkPromise(u)),o)}),!0}var H0,p_e,vT=It(()=>{Ba();H0=new Date(456789e3*1e3),p_e=H0.getTime()});function eP(t,e,r,o){let a=()=>{let n=r.shift();if(typeof n>"u")return null;let u=t.pathUtils.join(e,n);return Object.assign(t.statSync(u),{name:n,path:void 0})};return new lw(e,a,o)}var lw,dW=It(()=>{JD();lw=class{constructor(e,r,o={}){this.path=e;this.nextDirent=r;this.opts=o;this.closed=!1}throwIfClosed(){if(this.closed)throw dT()}async*[Symbol.asyncIterator](){try{let e;for(;(e=await this.read())!==null;)yield e}finally{await this.close()}}read(e){let r=this.readSync();return typeof e<"u"?e(null,r):Promise.resolve(r)}readSync(){return this.throwIfClosed(),this.nextDirent()}close(e){return this.closeSync(),typeof e<"u"?e(null):Promise.resolve()}closeSync(){this.throwIfClosed(),this.opts.onClose?.(),this.closed=!0}}});function mW(t,e){if(t!==e)throw new Error(`Invalid StatWatcher status: expected '${e}', got '${t}'`)}var yW,tP,EW=It(()=>{yW=ve("events");IT();tP=class t extends yW.EventEmitter{constructor(r,o,{bigint:a=!1}={}){super();this.status="ready";this.changeListeners=new Map;this.startTimeout=null;this.fakeFs=r,this.path=o,this.bigint=a,this.lastStats=this.stat()}static create(r,o,a){let n=new t(r,o,a);return n.start(),n}start(){mW(this.status,"ready"),this.status="running",this.startTimeout=setTimeout(()=>{this.startTimeout=null,this.fakeFs.existsSync(this.path)||this.emit("change",this.lastStats,this.lastStats)},3)}stop(){mW(this.status,"running"),this.status="stopped",this.startTimeout!==null&&(clearTimeout(this.startTimeout),this.startTimeout=null),this.emit("stop")}stat(){try{return this.fakeFs.statSync(this.path,{bigint:this.bigint})}catch{let o=this.bigint?new cm:new lm;return XD(o)}}makeInterval(r){let o=setInterval(()=>{let a=this.stat(),n=this.lastStats;CT(a,n)||(this.lastStats=a,this.emit("change",a,n))},r.interval);return r.persistent?o:o.unref()}registerChangeListener(r,o){this.addListener("change",r),this.changeListeners.set(r,this.makeInterval(o))}unregisterChangeListener(r){this.removeListener("change",r);let o=this.changeListeners.get(r);typeof o<"u"&&clearInterval(o),this.changeListeners.delete(r)}unregisterAllChangeListeners(){for(let r of this.changeListeners.keys())this.unregisterChangeListener(r)}hasChangeListeners(){return this.changeListeners.size>0}ref(){for(let r of this.changeListeners.values())r.ref();return this}unref(){for(let r of this.changeListeners.values())r.unref();return this}}});function um(t,e,r,o){let a,n,u,A;switch(typeof r){case"function":a=!1,n=!0,u=5007,A=r;break;default:({bigint:a=!1,persistent:n=!0,interval:u=5007}=r),A=o;break}let p=rP.get(t);typeof p>"u"&&rP.set(t,p=new Map);let h=p.get(e);return typeof h>"u"&&(h=tP.create(t,e,{bigint:a}),p.set(e,h)),h.registerChangeListener(A,{persistent:n,interval:u}),h}function q0(t,e,r){let o=rP.get(t);if(typeof o>"u")return;let a=o.get(e);typeof a>"u"||(typeof r>"u"?a.unregisterAllChangeListeners():a.unregisterChangeListener(r),a.hasChangeListeners()||(a.stop(),o.delete(e)))}function j0(t){let e=rP.get(t);if(!(typeof e>"u"))for(let r of e.keys())q0(t,r)}var rP,DT=It(()=>{EW();rP=new WeakMap});function E_e(t){let e=t.match(/\r?\n/g);if(e===null)return IW.EOL;let r=e.filter(a=>a===`\r `).length,o=e.length-r;return r>o?`\r diff --git a/README.md b/README.md index 99afc23..62af3a4 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ This was developed alongside a Rails project, so the form handling ethos follows ### Wiki -I've chosen to keep the main readme clean and only provide basic examples to help get started. +I've chosen to keep the main readme clean and only provide basic examples to help get started. [More in depth documentation is available on the Wiki section of this repo](https://github.com/aviemet/useInertiaForm/wiki) @@ -18,7 +18,7 @@ I've chosen to keep the main readme clean and only provide basic examples to hel [Here is a codesandbox with usage examples for all hooks and components](https://codesandbox.io/s/useinertiaform-examples-0so45f) -If you encounter a bug, please try to reacreate it with a fork of the codesandbox below and submit it with the issue. I don't have much time to address issues, so seeing an actual recreation can really help me identifiy if it's something I should look into. +If you encounter a bug, please try to recreate it with a fork of the codesandbox below and submit it with the issue. I don't have much time to address issues, so seeing an actual recreation can really help me identify if it's something I should look into. ## Quickstart diff --git a/commitlint.config.js b/commitlint.config.js index 4fedde6..858aaa8 100644 --- a/commitlint.config.js +++ b/commitlint.config.js @@ -1 +1 @@ -module.exports = { extends: ['@commitlint/config-conventional'] } +module.exports = { extends: ["@commitlint/config-conventional"] } diff --git a/eslint.config.mjs b/eslint.config.mjs index 383d62c..cf952f5 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -88,6 +88,8 @@ export default [ while: { after: false }, switch: { after: false }, catch: { after: false }, + import: { after: true }, + export: { after: true }, }, }], '@stylistic/comma-dangle': ['error', { @@ -107,6 +109,32 @@ export default [ '!!': false, }, }], + "@stylistic/semi": ["error", "never"], + "@stylistic/jsx-quotes": ["error", "prefer-double"], + "@stylistic/quotes": ["error", "double"], + "@stylistic/space-before-function-paren": ["error", "never"], + "@stylistic/arrow-spacing": "error", + "@stylistic/space-before-blocks": ["error", "always"], + "@stylistic/no-multiple-empty-lines": ["error", { + max: 2, + maxBOF: 0, + }], + "@stylistic/comma-spacing": ["error", { + before: false, + after: true, + }], + "@stylistic/no-multi-spaces": "error", + "@stylistic/spaced-comment": ["error", "always", { + "line": { + "markers": ["/"], + "exceptions": ["-", "+"], + }, + "block": { + "markers": ["!"], + "exceptions": ["*"], + "balanced": true, + }, + }], 'no-trailing-spaces': ['error', { skipBlankLines: false, ignoreComments: false diff --git a/fixJestDomEnvironment.ts b/fixJestDomEnvironment.ts index bb26ac4..5953d08 100644 --- a/fixJestDomEnvironment.ts +++ b/fixJestDomEnvironment.ts @@ -1,4 +1,4 @@ -import JSDOMEnvironment from 'jest-environment-jsdom' +import JSDOMEnvironment from "jest-environment-jsdom" // https://github.com/facebook/jest/blob/v29.4.3/website/versioned_docs/version-29.4/Configuration.md#testenvironment-string export default class FixJSDOMEnvironment extends JSDOMEnvironment { diff --git a/jest.config.js b/jest.config.js index b59c662..99ab043 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,18 +1,18 @@ module.exports = { - preset: 'ts-jest', + preset: "ts-jest", clearMocks: true, - testMatch: ['/tests/**/*.test.(ts|tsx)'], - testEnvironment: 'jest-fixed-jsdom', + testMatch: ["/tests/**/*.test.(ts|tsx)"], + testEnvironment: "jest-fixed-jsdom", testEnvironmentOptions: { - customExportConditions: ['node'], + customExportConditions: ["node"], }, transform: { - '^.+\\.tsx?$': ['ts-jest', { - tsconfig: 'tsconfig.test.json', + "^.+\\.tsx?$": ["ts-jest", { + tsconfig: "tsconfig.test.json", diagnostics: { warnOnly: true, }, }], }, - setupFilesAfterEnv: ['./jest.setup.ts'], + setupFilesAfterEnv: ["./jest.setup.ts"], } diff --git a/jest.setup.ts b/jest.setup.ts index 2587857..7a46a49 100644 --- a/jest.setup.ts +++ b/jest.setup.ts @@ -1,5 +1,5 @@ -import '@testing-library/jest-dom'; +import "@testing-library/jest-dom" -global.window = global.window || ({} as unknown as Window & typeof globalThis); -global.window.performance = global.window.performance || ({} as Performance); -global.window.performance.getEntriesByType = jest.fn().mockReturnValue([]); +global.window = global.window || ({} as unknown as Window & typeof globalThis) +global.window.performance = global.window.performance || ({} as Performance) +global.window.performance.getEntriesByType = jest.fn().mockReturnValue([]) diff --git a/release.config.js b/release.config.js index 02d9e12..e5eb043 100644 --- a/release.config.js +++ b/release.config.js @@ -1,11 +1,11 @@ module.exports = { - 'branches': ['main'], + "branches": ["main"], plugins: [ - '@semantic-release/commit-analyzer', - '@semantic-release/github', - '@semantic-release/release-notes-generator', - '@semantic-release/changelog', - '@semantic-release/npm', - '@semantic-release/git', + "@semantic-release/commit-analyzer", + "@semantic-release/github", + "@semantic-release/release-notes-generator", + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/git", ], } diff --git a/rollup.config.js b/rollup.config.js index 1d3e385..a9eaa0c 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,23 +1,23 @@ -import external from 'rollup-plugin-peer-deps-external' -import babel from '@rollup/plugin-babel' -import typescript from '@rollup/plugin-typescript'; -import commonjs from '@rollup/plugin-commonjs' -import { nodeResolve } from '@rollup/plugin-node-resolve'; -import sourcemaps from 'rollup-plugin-sourcemaps' -import terser from '@rollup/plugin-terser' -import filesize from 'rollup-plugin-filesize' -import { dts } from 'rollup-plugin-dts' -import pkg from './package.json' +import external from "rollup-plugin-peer-deps-external" +import babel from "@rollup/plugin-babel" +import typescript from "@rollup/plugin-typescript" +import commonjs from "@rollup/plugin-commonjs" +import { nodeResolve } from "@rollup/plugin-node-resolve" +import sourcemaps from "rollup-plugin-sourcemaps" +import terser from "@rollup/plugin-terser" +import filesize from "rollup-plugin-filesize" +import { dts } from "rollup-plugin-dts" +import pkg from "./package.json" const externalDeps = [ - 'react', - 'react-dom', - '@inertiajs/core', - '@inertiajs/react', - 'lodash', - 'axios', - 'react/jsx-runtime', -]; + "react", + "react-dom", + "@inertiajs/core", + "@inertiajs/react", + "lodash", + "axios", + "react/jsx-runtime", +] // Base plugins to avoid redundancy const basePlugins = [ @@ -25,11 +25,11 @@ const basePlugins = [ nodeResolve(), commonjs(), typescript({ - tsconfig: './tsconfig.build.json', - declarationDir: './dist', - jsx: 'react-jsx', - include: ['*.ts+(|x)', '**/*.ts+(|x)'], - exclude: ['node_modules', 'dist'], + tsconfig: "./tsconfig.build.json", + declarationDir: "./dist", + jsx: "react-jsx", + include: ["*.ts+(|x)", "**/*.ts+(|x)"], + exclude: ["node_modules", "dist"], }), sourcemaps(), filesize({ @@ -37,48 +37,48 @@ const basePlugins = [ showGzippedSize: true, }), babel({ - babelHelpers: 'bundled', + babelHelpers: "bundled", presets: [ - '@babel/preset-react', - '@babel/preset-typescript', + "@babel/preset-react", + "@babel/preset-typescript", ], - extensions: ['.ts', '.tsx'], - exclude: 'node_modules/**', + extensions: [".ts", ".tsx"], + exclude: "node_modules/**", }), -]; +] export default [ { - input: 'src/index.ts', + input: "src/index.ts", output: { - name: 'useInertiaForm', + name: "useInertiaForm", file: pkg.unpkg, - format: 'umd', + format: "umd", sourcemap: true, globals: { - 'react': 'React', - 'react-dom': 'ReactDOM', - '@inertiajs/core': '@inertiajs/core', - '@inertiajs/react': '@inertiajs/react', - 'lodash': '_', - 'axios': 'axios', - 'react/jsx-runtime': 'jsxRuntime', + "react": "React", + "react-dom": "ReactDOM", + "@inertiajs/core": "@inertiajs/core", + "@inertiajs/react": "@inertiajs/react", + "lodash": "_", + "axios": "axios", + "react/jsx-runtime": "jsxRuntime", }, }, plugins: [...basePlugins, terser()], external: externalDeps, }, { - input: 'src/index.ts', + input: "src/index.ts", output: [ { file: pkg.main, // CommonJS - format: 'es', + format: "es", sourcemap: true, }, { file: pkg.cjs, // ESM - format: 'cjs', + format: "cjs", sourcemap: true, }, ], @@ -86,17 +86,17 @@ export default [ external: externalDeps, }, { - input: 'src/index.ts', + input: "src/index.ts", output: [ { file: pkg.types, - format: 'es', + format: "es", }, ], plugins: [ dts({ compilerOptions: { - baseUrl: './dist', + baseUrl: "./dist", }, }), ], diff --git a/src/Form/FormMetaWrapper.tsx b/src/Form/FormMetaWrapper.tsx index 5c492c0..c76e1de 100644 --- a/src/Form/FormMetaWrapper.tsx +++ b/src/Form/FormMetaWrapper.tsx @@ -1,5 +1,5 @@ -import React, { useReducer } from 'react' -import { createContext } from '../utils' +import React, { useReducer } from "react" +import { createContext } from "../utils" /** * Form Meta Context diff --git a/src/Form/FormProvider.ts b/src/Form/FormProvider.ts index 371b054..588b856 100644 --- a/src/Form/FormProvider.ts +++ b/src/Form/FormProvider.ts @@ -1,9 +1,9 @@ -import React from 'react' -import { type UseInertiaFormProps } from '../useInertiaForm' -import { type AxiosResponse } from 'axios' -import { NestedObject } from '../useInertiaForm' +import React from "react" +import { type UseInertiaFormProps } from "../useInertiaForm" +import { type AxiosResponse } from "axios" +import { NestedObject } from "../useInertiaForm" -export type HTTPVerb = 'post' | 'put' | 'get' | 'patch' | 'delete' +export type HTTPVerb = "post" | "put" | "get" | "patch" | "delete" export interface UseFormProps extends UseInertiaFormProps { model?: string @@ -20,7 +20,7 @@ export const createContext = () => { (context as unknown) as React.Context>, ) if(c === null) { - throw new Error('useContext must be inside a Provider with a value') + throw new Error("useContext must be inside a Provider with a value") } return c } diff --git a/src/Form/index.tsx b/src/Form/index.tsx index 341fefd..79c010a 100644 --- a/src/Form/index.tsx +++ b/src/Form/index.tsx @@ -1,13 +1,13 @@ /* eslint-disable react-hooks/exhaustive-deps */ /* eslint-disable react-hooks/rules-of-hooks */ -import React, { useCallback, useEffect } from 'react' -import { type VisitOptions } from '@inertiajs/core' -import useInertiaForm, { NestedObject } from '../useInertiaForm' -import { useForm, type UseFormProps, type HTTPVerb, FormProvider } from './FormProvider' -import FormMetaWrapper, { useFormMeta, type FormMetaValue } from './FormMetaWrapper' -import { unsetCompact } from '../utils' +import React, { useCallback, useEffect } from "react" +import { type VisitOptions } from "@inertiajs/core" +import useInertiaForm, { NestedObject } from "../useInertiaForm" +import { useForm, type UseFormProps, type HTTPVerb, FormProvider } from "./FormProvider" +import FormMetaWrapper, { useFormMeta, type FormMetaValue } from "./FormMetaWrapper" +import { unsetCompact } from "../utils" -type PartialHTMLForm = Omit, 'onChange' | 'onSubmit' | 'onError'> +type PartialHTMLForm = Omit, "onChange" | "onSubmit" | "onError"> export interface FormProps extends PartialHTMLForm { data?: TForm @@ -21,8 +21,8 @@ export interface FormProps extends PartialHTMLForm { filter?: string[] onChange?: (form: UseFormProps) => void onSubmit?: (form: UseFormProps) => boolean | void - onBefore?: (form: UseFormProps) => void - onStart?: (form: UseFormProps) => void + onBefore?: (form: UseFormProps) => void + onStart?: (form: UseFormProps) => void onSuccess?: (form: UseFormProps) => void onError?: (form: UseFormProps) => void onFinish?: (form: UseFormProps) => void @@ -32,7 +32,7 @@ const Form = ({ children, model, data, - method = 'post', + method = "post", to, async = false, resetAfterSubmit, @@ -46,7 +46,7 @@ const Form = ({ onError, onFinish, ...props -}: Omit, 'railsAttributes'>) => { +}: Omit, "railsAttributes">) => { /** * Omit values by key from the data object */ @@ -72,7 +72,7 @@ const Form = ({ * Submits the form. If async prop is true, submits using axios, * otherwise submits using Inertia's `useForm.submit` method */ - const submit = async (options?: Partial) => { + const submit = async(options?: Partial) => { let shouldSubmit = to && onSubmit?.(contextValueObject()) === false ? false : true if(!shouldSubmit) return diff --git a/src/Inputs/DynamicInputs.tsx b/src/Inputs/DynamicInputs.tsx index ec0d2c2..1bdcd00 100644 --- a/src/Inputs/DynamicInputs.tsx +++ b/src/Inputs/DynamicInputs.tsx @@ -1,6 +1,6 @@ -import React from 'react' -import NestedFields from './NestedFields' -import useDynamicInputs from './useDynamicInputs' +import React from "react" +import NestedFields from "./NestedFields" +import useDynamicInputs from "./useDynamicInputs" export interface DynamicInputsProps { children: React.ReactNode @@ -21,11 +21,11 @@ const DynamicInputs = ({ return ( <> - { React.cloneElement(addInputButton, { onClick: ()=> addInput(), type: 'button' }) } + { React.cloneElement(addInputButton, { onClick: () => addInput(), type: "button" }) } { paths.map((path, i) => (
{ children }
- { React.cloneElement(removeInputButton, { onClick: () => removeInput(i), type: 'button' }) } + { React.cloneElement(removeInputButton, { onClick: () => removeInput(i), type: "button" }) }
)) } diff --git a/src/Inputs/Input.tsx b/src/Inputs/Input.tsx index d1b3904..dd0d837 100644 --- a/src/Inputs/Input.tsx +++ b/src/Inputs/Input.tsx @@ -1,7 +1,7 @@ -import React from 'react' -import useInertiaInput from '../useInertiaInput' -import { NestedObject } from '../useInertiaForm' -import { BaseFormInputProps, InputConflicts } from '.' +import React from "react" +import useInertiaInput from "../useInertiaInput" +import { NestedObject } from "../useInertiaForm" +import { BaseFormInputProps, InputConflicts } from "." interface InputProps extends @@ -12,8 +12,8 @@ interface InputProps const Input = ( { name, - component = 'input', - type = 'text', + component = "input", + type = "text", model, onChange, errorKey, diff --git a/src/Inputs/NestedFields.tsx b/src/Inputs/NestedFields.tsx index cbdc407..95f82e8 100644 --- a/src/Inputs/NestedFields.tsx +++ b/src/Inputs/NestedFields.tsx @@ -1,6 +1,6 @@ -import React, { useEffect } from 'react' -import { createContext } from '../utils' -import { useFormMeta } from '../Form' +import React, { useEffect } from "react" +import { createContext } from "../utils" +import { useFormMeta } from "../Form" export interface NestedFieldsProps { children: React.ReactNode | React.ReactElement[] @@ -16,7 +16,7 @@ const NestedFields = ({ children, model }: NestedFieldsProps) => { try { const nested = useNestedAttribute() - if(model.charAt(0) === '[') { + if(model.charAt(0) === "[") { inputModel = `${nested}${model}` } else { inputModel = `${nested}.${model}` diff --git a/src/Inputs/Submit.tsx b/src/Inputs/Submit.tsx index 609b6cb..897b9bf 100644 --- a/src/Inputs/Submit.tsx +++ b/src/Inputs/Submit.tsx @@ -1,6 +1,6 @@ -import React, { useCallback } from 'react' -import { useForm } from '../Form' -import { isUnset } from '../utils' +import React, { useCallback } from "react" +import { useForm } from "../Form" +import { isUnset } from "../utils" interface ButtonProps extends React.ButtonHTMLAttributes { component?: string | React.ComponentType @@ -8,7 +8,7 @@ interface ButtonProps extends React.ButtonHTMLAttributes { } const Submit = React.forwardRef(( - { children, type = 'submit', disabled = false, component:Component = 'button', requiredFields, ...props }, + { children, type = "submit", disabled = false, component:Component = "button", requiredFields, ...props }, ref, ) => { const { data, getData, processing } = useForm() diff --git a/src/Inputs/index.ts b/src/Inputs/index.ts index cfc9827..dfd1be4 100644 --- a/src/Inputs/index.ts +++ b/src/Inputs/index.ts @@ -1,14 +1,14 @@ -import { UseFormProps } from '../Form' -import { NestedObject } from '../useInertiaForm' -import { UseInertiaInputProps } from '../useInertiaInput' +import { UseFormProps } from "../Form" +import { NestedObject } from "../useInertiaForm" +import { UseInertiaInputProps } from "../useInertiaInput" -export { default as Input } from './Input' -export { default as Submit } from './Submit' -export { default as NestedFields, type NestedFieldsProps } from './NestedFields' -export { default as DynamicInputs } from './DynamicInputs' -export { default as useDynamicInputs, type DynamicInputsProps } from './useDynamicInputs' +export { default as Input } from "./Input" +export { default as Submit } from "./Submit" +export { default as NestedFields, type NestedFieldsProps } from "./NestedFields" +export { default as DynamicInputs } from "./DynamicInputs" +export { default as useDynamicInputs, type DynamicInputsProps } from "./useDynamicInputs" -export type InputConflicts = 'name' | 'onChange' | 'onBlur' | 'onFocus' | 'value' | 'defaultValue' +export type InputConflicts = "name" | "onChange" | "onBlur" | "onFocus" | "value" | "defaultValue" export interface BaseFormInputProps extends UseInertiaInputProps { model?: string diff --git a/src/Inputs/useDynamicInputs.ts b/src/Inputs/useDynamicInputs.ts index 8688669..173447e 100644 --- a/src/Inputs/useDynamicInputs.ts +++ b/src/Inputs/useDynamicInputs.ts @@ -1,7 +1,7 @@ -import { useCallback } from 'react' -import { useForm, useFormMeta } from '../Form' -import { get, set } from 'lodash' -import { useNestedAttribute } from './NestedFields' +import { useCallback } from "react" +import { useForm, useFormMeta } from "../Form" +import { get, set } from "lodash" +import { useNestedAttribute } from "./NestedFields" export interface DynamicInputsProps> { model?: string @@ -19,14 +19,14 @@ type DynamicInputsReturn> = { const useDynamicInputs = >({ model, emptyData }: DynamicInputsProps): DynamicInputsReturn => { const { setData, unsetData, getData } = useForm() const { model: formModel } = useFormMeta() - let inputModel = formModel ?? '' + let inputModel = formModel ?? "" try { const nestedModel = useNestedAttribute() inputModel = formModel ? `${inputModel}.${nestedModel}` : nestedModel } catch(e) {} - inputModel = `${inputModel}.${model || ''}` + inputModel = `${inputModel}.${model || ""}` const handleAddInputs: AddInputHandler = useCallback(override => { setData((formData: T) => { @@ -63,7 +63,7 @@ const useDynamicInputs = >({ model, emptyData const generatePaths = useCallback(() => { if(!Array.isArray(data)) return [] - return data.map((_,i) => `${model || ''}[${i}]`) + return data.map((_, i) => `${model || ""}[${i}]`) }, [data]) return { diff --git a/src/index.ts b/src/index.ts index fc90777..799f980 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,12 +2,12 @@ export { default as useInertiaForm, type UseInertiaFormProps, type NestedObject, -} from './useInertiaForm' +} from "./useInertiaForm" export { default as useInertiaInput, type UseInertiaInputProps, -} from './useInertiaInput' +} from "./useInertiaInput" export { Form, @@ -15,7 +15,7 @@ export { type HTTPVerb, type UseFormProps, type FormProps, -} from './Form' +} from "./Form" export { Input, @@ -25,4 +25,4 @@ export { useDynamicInputs, type NestedFieldsProps, type DynamicInputsProps, -} from './Inputs' +} from "./Inputs" diff --git a/src/useInertiaForm.ts b/src/useInertiaForm.ts index 2a4ba78..c38173b 100644 --- a/src/useInertiaForm.ts +++ b/src/useInertiaForm.ts @@ -4,7 +4,7 @@ import { useMemo, useRef, useState, -} from 'react' +} from "react" import { ActiveVisit, Method, @@ -14,8 +14,8 @@ import { type Progress, type VisitOptions as InertiaVisitOptions, type RequestPayload, -} from '@inertiajs/core' -import { router } from '@inertiajs/react' +} from "@inertiajs/core" +import { router } from "@inertiajs/react" import { coerceArray, fillEmptyValues, @@ -24,12 +24,12 @@ import { useMaybeRemember, type Path, type PathValue, -} from './utils' -import { get, isEqual, isPlainObject, set } from 'lodash' -import { useFormMeta } from './Form/FormMetaWrapper' -import axios, { AxiosResponse } from 'axios' +} from "./utils" +import { get, isEqual, isPlainObject, set } from "lodash" +import { useFormMeta } from "./Form/FormMetaWrapper" +import axios, { AxiosResponse } from "axios" -type VisitOptions = (Omit & { +type VisitOptions = (Omit & { errors?: Record async: TAsync onSuccess?: (page: TAsync extends true ? AxiosResponse : Page) => void @@ -41,10 +41,10 @@ export type Primitive = string | number | null | undefined export type NestedObject = { [key: string]: unknown | NestedObject | NestedObject[] -}; +} -type setDataByPath =

>(key: P, value: PathValue) => void; -type setDataByString = (key: string, value: unknown) => void; +type setDataByPath =

>(key: P, value: PathValue) => void +type setDataByString = (key: string, value: unknown) => void type setDataByObject = (data: TForm) => void type setDataByMethod = (data: (previousData: TForm) => TForm) => void @@ -111,7 +111,7 @@ export default function useInertiaForm( const getFormArguments = useCallback((): [string, TForm] => { let rememberKey: string = null let transformedData = rememberKeyOrInitialValues - if(typeof rememberKeyOrInitialValues === 'string') { + if(typeof rememberKeyOrInitialValues === "string") { rememberKey = rememberKeyOrInitialValues transformedData = maybeInitialValues } @@ -282,8 +282,8 @@ export default function useInertiaForm( _options.onBefore(undefined) _options.onStart(undefined) axios[method](url, transformedData as RequestPayload, { - onUploadProgress: progessEvent => { - _options.onProgress(progessEvent) + onUploadProgress: progressEvent => { + _options.onProgress(progressEvent) }, }) .then(response => { @@ -296,7 +296,7 @@ export default function useInertiaForm( _options.onFinish(undefined) }) } else { - if(method === 'delete') { + if(method === "delete") { router.delete(url, { ..._options, data: transformedData as RequestPayload }) } else { router[method](url, transformedData as RequestPayload, _options) @@ -344,7 +344,7 @@ export default function useInertiaForm( }, setData: (keyOrData: string | TForm | ((previousData: TForm) => TForm), maybeValue?: any) => { - if(typeof keyOrData === 'string') { + if(typeof keyOrData === "string") { return setData(data => { const clone = structuredClone(data) if(onChangeRef.current) { @@ -398,7 +398,7 @@ export default function useInertiaForm( setDefaults((defaults) => ({ ...defaults, - ...(typeof fieldOrFields === 'string' ? { [fieldOrFields]: maybeValue } : (fieldOrFields as TForm)), + ...(typeof fieldOrFields === "string" ? { [fieldOrFields]: maybeValue } : (fieldOrFields as TForm)), })) }, @@ -429,7 +429,7 @@ export default function useInertiaForm( setErrors((errors) => { const newErrors = { ...errors, - ...(typeof fieldOrFields === 'string' + ...(typeof fieldOrFields === "string" ? { [fieldOrFields]: maybeValue } : (fieldOrFields as Record)), } @@ -447,23 +447,23 @@ export default function useInertiaForm( submit, get: (url, options) => { - submit('get', url, options) + submit("get", url, options) }, post: (url, options) => { - submit('post', url, options) + submit("post", url, options) }, put: (url, options) => { - submit('put', url, options) + submit("put", url, options) }, patch: (url, options) => { - submit('patch', url, options) + submit("patch", url, options) }, delete: (url, options) => { - submit('delete', url, options) + submit("delete", url, options) }, cancel: () => { diff --git a/src/useInertiaInput/index.ts b/src/useInertiaInput/index.ts index 81791f9..a7cd682 100644 --- a/src/useInertiaInput/index.ts +++ b/src/useInertiaInput/index.ts @@ -1,8 +1,8 @@ -import { useEffect, useRef } from 'react' -import { useForm } from '../Form' -import { useNestedAttribute } from '../Inputs/NestedFields' -import inputStrategy, { type InputStrategy } from './inputStrategy' -import { type NestedObject } from '../useInertiaForm' +import { useEffect, useRef } from "react" +import { useForm } from "../Form" +import { useNestedAttribute } from "../Inputs/NestedFields" +import inputStrategy, { type InputStrategy } from "./inputStrategy" +import { type NestedObject } from "../useInertiaForm" export interface UseInertiaInputProps { name: string @@ -42,7 +42,7 @@ const useInertiaInput = ({ const inputValue = form.getData(inputName) if(inputValue === null || inputValue === undefined) { - form.setData(inputName, defaultValue || '') + form.setData(inputName, defaultValue || "") } initializingRef.current = false @@ -63,7 +63,7 @@ const useInertiaInput = ({ form, inputName: inputName, inputId, - value: value ?? '' as T, + value: value ?? "" as T, setValue: (value: T) => { return form.setData(inputName, value) }, diff --git a/src/useInertiaInput/inputStrategy.ts b/src/useInertiaInput/inputStrategy.ts index d5f4938..950056b 100644 --- a/src/useInertiaInput/inputStrategy.ts +++ b/src/useInertiaInput/inputStrategy.ts @@ -18,14 +18,14 @@ const inputStrategy: InputStrategy = (name, model) => { let inputName: string - if(name.charAt(0) === '[') { + if(name.charAt(0) === "[") { inputName = `${model}${name}` } else { inputName = `${model}.${name}` } return { - inputId: `${model}_${name}`.replace('.', '_').replace(/\[(\d)\]/, '_$1'), + inputId: `${model}_${name}`.replace(".", "_").replace(/\[(\d)\]/, "_$1"), inputName: inputName, } } diff --git a/src/utils/createContext.ts b/src/utils/createContext.ts index 33461b2..3464a38 100644 --- a/src/utils/createContext.ts +++ b/src/utils/createContext.ts @@ -1,4 +1,4 @@ -import React from 'react' +import React from "react" /** * Creates context with simplified type notations @@ -12,7 +12,7 @@ export const createContext = () => { (context as unknown) as React.Context, ) if(c === null) { - throw new Error('useContext must be inside a Provider with a value') + throw new Error("useContext must be inside a Provider with a value") } return c } diff --git a/src/utils/fillEmptyValues.ts b/src/utils/fillEmptyValues.ts index 8eb1d4e..45bdcdf 100644 --- a/src/utils/fillEmptyValues.ts +++ b/src/utils/fillEmptyValues.ts @@ -1,4 +1,4 @@ -import { isPlainObject } from 'lodash' +import { isPlainObject } from "lodash" /** * Replaces undefined or null values with empty values, @@ -18,7 +18,7 @@ export const fillEmptyValues = (data: TForm) => { clone[key] = clone[key].map(el => fillEmptyValues(el)) } else if(clone[key] === undefined || clone[key] === null) { // @ts-ignore - clone[key] = '' + clone[key] = "" } } diff --git a/src/utils/index.ts b/src/utils/index.ts index b5f40c2..a99f853 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -1,15 +1,15 @@ -export { createContext } from './createContext' -export { fillEmptyValues } from './fillEmptyValues' -export { isUnset } from './isUnset' -export { renameObjectWithAttributes } from './renameObjectWithAttributes' -export { unsetCompact } from './unsetCompact' -export { useMaybeRemember } from './useMaybeRemember' +export { createContext } from "./createContext" +export { fillEmptyValues } from "./fillEmptyValues" +export { isUnset } from "./isUnset" +export { renameObjectWithAttributes } from "./renameObjectWithAttributes" +export { unsetCompact } from "./unsetCompact" +export { useMaybeRemember } from "./useMaybeRemember" /** * Removes appended string (default of '_attributes') from dot notation */ -export const stripAttributes = (str: string, attribute = '_attributes') => - str.replace(new RegExp(`${attribute}\\.`), '.') +export const stripAttributes = (str: string, attribute = "_attributes") => + str.replace(new RegExp(`${attribute}\\.`), ".") /** * Ensures passed value is an array @@ -18,19 +18,19 @@ export const coerceArray = (arg: T | T[]) => Array.isArray(arg) ? a // Added recursion limit to path types to prevent the error: // "Type instantiation is excessively deep and possibly infinite" -type Increment = [0, ...A]; +type Increment = [0, ...A] type PathImpl = - A['length'] extends 5 ? never : + A["length"] extends 5 ? never : K extends string ? T[K] extends Record ? T[K] extends ArrayLike ? K | `${K}.${PathImpl, Increment>}` : K | `${K}.${PathImpl>}` : K - : never; + : never -export type Path = PathImpl | Extract; +export type Path = PathImpl | Extract export type PathValue>> = P extends `${infer K}.${infer Rest}` @@ -41,4 +41,4 @@ export type PathValue>> = : never : P extends keyof Required ? Required[P] - : never; + : never diff --git a/src/utils/isUnset.ts b/src/utils/isUnset.ts index 25cca93..9eb1ca2 100644 --- a/src/utils/isUnset.ts +++ b/src/utils/isUnset.ts @@ -1,4 +1,4 @@ -import { isEmpty } from 'lodash' +import { isEmpty } from "lodash" /** * Returns whether a value should be considered empty in the context of a form input @@ -8,11 +8,11 @@ export const isUnset = (v: any) => { return true } - if(typeof v === 'string') { - return v === '' + if(typeof v === "string") { + return v === "" } - if(typeof v === 'number') { + if(typeof v === "number") { return v === 0 ? false : !Boolean(v) } @@ -20,7 +20,7 @@ export const isUnset = (v: any) => { return isNaN(v.valueOf()) } - if(typeof v === 'boolean') { + if(typeof v === "boolean") { return false } diff --git a/src/utils/renameObjectWithAttributes.ts b/src/utils/renameObjectWithAttributes.ts index 3560a6a..c5fd393 100644 --- a/src/utils/renameObjectWithAttributes.ts +++ b/src/utils/renameObjectWithAttributes.ts @@ -1,15 +1,15 @@ -import { isPlainObject } from 'lodash' -import { NestedObject } from '../useInertiaForm' +import { isPlainObject } from "lodash" +import { NestedObject } from "../useInertiaForm" /** * Append string (default of '_attributes') to keys of nested records */ -export const renameObjectWithAttributes = (data: T, str = '_attributes') => { +export const renameObjectWithAttributes = (data: T, str = "_attributes") => { const clone = structuredClone(data) // Start at one level deep Object.values(clone).forEach(value => { - if(isPlainObject(value)){ + if(isPlainObject(value)) { recursiveAppendString(value, str) } }) diff --git a/src/utils/unsetCompact.ts b/src/utils/unsetCompact.ts index c5825e7..e4b1b32 100644 --- a/src/utils/unsetCompact.ts +++ b/src/utils/unsetCompact.ts @@ -1,5 +1,5 @@ -import { unset, get } from 'lodash' -import { type NestedObject } from '../useInertiaForm' +import { unset, get } from "lodash" +import { type NestedObject } from "../useInertiaForm" /** * Extends _.unset splice out array elements rather than leaving empty values in arrays @@ -10,11 +10,11 @@ import { type NestedObject } from '../useInertiaForm' type TArrType = string | number | NestedObject export const unsetCompact = (data: NestedObject, path: string) => { // Ignore tailing [] since it causes unnecessary recursion - const sanitizedPath = path.replace(/\[\]$/, '') + const sanitizedPath = path.replace(/\[\]$/, "") // Handle special empty array syntax - if(sanitizedPath.includes('[]')) { - const emptyArrayPosition = sanitizedPath.indexOf('[]') + if(sanitizedPath.includes("[]")) { + const emptyArrayPosition = sanitizedPath.indexOf("[]") const startPath = sanitizedPath.slice(0, emptyArrayPosition) const restPath = sanitizedPath.slice(emptyArrayPosition + 2) const arr = get(data, startPath) as TArrType[] @@ -29,9 +29,9 @@ export const unsetCompact = (data: NestedObject, path: string) => { // Directly removing an array element is the only way to have an empty array element // Handle it separately using slice rather than unset - if(sanitizedPath.charAt(sanitizedPath.length - 1) === ']') { + if(sanitizedPath.charAt(sanitizedPath.length - 1) === "]") { const match = sanitizedPath.match(/(?\d*)\]$/) - const arr = get(data, sanitizedPath.slice(0, sanitizedPath.lastIndexOf('['))) + const arr = get(data, sanitizedPath.slice(0, sanitizedPath.lastIndexOf("["))) if(Array.isArray(arr) && match?.groups?.index !== undefined) { arr.splice(Number(match.groups.index), 1) diff --git a/src/utils/useMaybeRemember.ts b/src/utils/useMaybeRemember.ts index 27af7d2..104f707 100644 --- a/src/utils/useMaybeRemember.ts +++ b/src/utils/useMaybeRemember.ts @@ -1,17 +1,17 @@ -import { useState } from "react"; -import { useRemember } from "@inertiajs/react"; +import { useState } from "react" +import { useRemember } from "@inertiajs/react" /** * Conditionally use useState or useRemember without violating the rule of hooks */ const useMaybeRemember = (initialValue: T, rememberKey?: string): [T, React.Dispatch>] => { - const [rememberedData, setRememberedData] = useRemember(initialValue, rememberKey); - const [localData, setLocalData] = useState(initialValue); + const [rememberedData, setRememberedData] = useRemember(initialValue, rememberKey) + const [localData, setLocalData] = useState(initialValue) if(rememberKey) { - return [rememberedData, setRememberedData]; + return [rememberedData, setRememberedData] } - return [localData, setLocalData]; -}; + return [localData, setLocalData] +} export { useMaybeRemember } diff --git a/tests/components/ContextTest.tsx b/tests/components/ContextTest.tsx index ac97dec..fe9ad45 100644 --- a/tests/components/ContextTest.tsx +++ b/tests/components/ContextTest.tsx @@ -1,12 +1,12 @@ -import { useEffect } from 'react' -import { NestedObject, useForm, UseFormProps } from '../../src' -import CircularJSON from 'circular-json' +import { useEffect } from "react" +import { NestedObject, useForm, UseFormProps } from "../../src" +import CircularJSON from "circular-json" const safeStringify = (obj) => { try { return CircularJSON.stringify(obj) } catch(err) { - console.error('Error stringifying object:', err) + console.error("Error stringifying object:", err) return null } } diff --git a/tests/components/data.ts b/tests/components/data.ts index 582cb16..3436db2 100644 --- a/tests/components/data.ts +++ b/tests/components/data.ts @@ -1,40 +1,40 @@ export const multiRootData = { user: { - username: 'some name', + username: "some name", }, person: { - first_name: 'first', - last_name: 'last', + first_name: "first", + last_name: "last", middle_name: undefined, nested: { - key: 'value', + key: "value", }, }, contact: { phones: [ - { number: '1234567890', type: 'home' }, - { number: '2234567890', type: 'home' }, - { number: '3234567890', type: 'home' }, + { number: "1234567890", type: "home" }, + { number: "2234567890", type: "home" }, + { number: "3234567890", type: "home" }, ], }, } export const singleRootData = { person: { - first_name: 'first', - last_name: 'last', + first_name: "first", + last_name: "last", middle_name: undefined, nested: { - key: 'value', + key: "value", }, }, } export const flatData = { - first_name: 'first', - last_name: 'last', + first_name: "first", + last_name: "last", middle_name: undefined, nested: { - key: 'value', + key: "value", }, } diff --git a/tests/formComponent.test.tsx b/tests/formComponent.test.tsx index 6b8e469..1899efc 100644 --- a/tests/formComponent.test.tsx +++ b/tests/formComponent.test.tsx @@ -1,20 +1,20 @@ -import { act, fireEvent, render, screen } from '@testing-library/react' -import '@testing-library/jest-dom' +import { act, fireEvent, render, screen } from "@testing-library/react" +import "@testing-library/jest-dom" import { Form, Input, Submit, -} from '../src' -import { router } from '@inertiajs/react' -import { Page, type PendingVisit } from '@inertiajs/core' -import { get } from 'lodash' -import ContextTest from './components/ContextTest' -import { multiRootData, singleRootData } from './components/data' -import axios from 'axios' - -describe('Form Component', () => { - describe('When not passed a data object', () => { - it('builds the data object from inputs', () => { +} from "../src" +import { router } from "@inertiajs/react" +import { Page, type PendingVisit } from "@inertiajs/core" +import { get } from "lodash" +import ContextTest from "./components/ContextTest" +import { multiRootData, singleRootData } from "./components/data" +import axios from "axios" + +describe("Form Component", () => { + describe("When not passed a data object", () => { + it("builds the data object from inputs", () => { render(

@@ -25,20 +25,20 @@ describe('Form Component', () => { , ) - expect(screen.getByTestId('data')).toHaveTextContent( - '{"user":{"username":"","firstName":"","lastName":""}}', + expect(screen.getByTestId("data")).toHaveTextContent( + "{\"user\":{\"username\":\"\",\"firstName\":\"\",\"lastName\":\"\"}}", ) }) }) - describe('When passed a data object', () => { - it('it uses the data values ignoring defaultValue', () => { + describe("When passed a data object", () => { + it("it uses the data values ignoring defaultValue", () => { render(
@@ -49,17 +49,17 @@ describe('Form Component', () => {
, ) - expect(screen.getByTestId('data')).toHaveTextContent( - '{"user":{"username":"username","firstName":"Firsty","lastName":"Lasty"}}', + expect(screen.getByTestId("data")).toHaveTextContent( + "{\"user\":{\"username\":\"username\",\"firstName\":\"Firsty\",\"lastName\":\"Lasty\"}}", ) }) - it('adds missing keys to the data object from inputs', () => { + it("adds missing keys to the data object from inputs", () => { render(
@@ -70,8 +70,8 @@ describe('Form Component', () => {
, ) - expect(screen.getByTestId('data')).toHaveTextContent( - '{"user":{"username":"username","firstName":"Firsty","lastName":"Lasty"}}', + expect(screen.getByTestId("data")).toHaveTextContent( + "{\"user\":{\"username\":\"username\",\"firstName\":\"Firsty\",\"lastName\":\"Lasty\"}}", ) }) }) @@ -79,37 +79,37 @@ describe('Form Component', () => { /** * Rails Attributes `false` tests */ - describe('With railsAttributes false', () => { - it('renders a form with values in inputs', () => { + describe("With railsAttributes false", () => { + it("renders a form with values in inputs", () => { render(
, ) - const input = screen.getByRole('textbox') + const input = screen.getByRole("textbox") expect(input).toHaveValue(multiRootData.user.username) }) - it('updates form data with user input', () => { + it("updates form data with user input", () => { render(
, ) - const input = screen.getByRole('textbox') + const input = screen.getByRole("textbox") - fireEvent.change(input, { target: { value: 'modified form data' } }) - expect(input).toHaveValue('modified form data') + fireEvent.change(input, { target: { value: "modified form data" } }) + expect(input).toHaveValue("modified form data") }) - describe('when async is false', () => { - it('sends the correct data to the server upon form submit', async () => { + describe("when async is false", () => { + it("sends the correct data to the server upon form submit", async() => { let capturedData: any - const mockRequest = jest.spyOn(router, 'visit').mockImplementation((route, request) => { + const mockRequest = jest.spyOn(router, "visit").mockImplementation((route, request) => { capturedData = request?.data return Promise.resolve({ data: request?.data }) @@ -123,19 +123,19 @@ describe('Form Component', () => { , ) - const button = screen.getByRole('button') + const button = screen.getByRole("button") await fireEvent.click(button) expect(mockRequest).toHaveBeenCalled() - expect(get(capturedData, 'person.nested.key')).toBe('value') + expect(get(capturedData, "person.nested.key")).toBe("value") }) }) - describe('when async is true', () => { - it('sends the correct data to the server upon form submit', async () => { + describe("when async is true", () => { + it("sends the correct data to the server upon form submit", async() => { let capturedData: any - const mockRequest = jest.spyOn(axios, 'post').mockImplementation((url, data, config) => { + const mockRequest = jest.spyOn(axios, "post").mockImplementation((url, data, config) => { capturedData = data return Promise.resolve({ data }) }) @@ -148,14 +148,14 @@ describe('Form Component', () => { , ) - await act(async () => { - const button = screen.getByRole('button') + await act(async() => { + const button = screen.getByRole("button") await fireEvent.click(button) }) expect(mockRequest).toHaveBeenCalled() - expect(get(capturedData, 'person.nested.key')).toBe('value') + expect(get(capturedData, "person.nested.key")).toBe("value") }) }) }) @@ -163,8 +163,8 @@ describe('Form Component', () => { /** * Rails Attributes `true` tests */ - describe('With railsAttributes true', () => { - it('renders a form with values in inputs', () => { + describe("With railsAttributes true", () => { + it("renders a form with values in inputs", () => { render(
{
, ) - const input = screen.getByRole('textbox') + const input = screen.getByRole("textbox") expect(input).toHaveValue(multiRootData.user.username) }) - it('updates values as normal', () => { + it("updates values as normal", () => { render(
{
, ) - const input = screen.getByRole('textbox') + const input = screen.getByRole("textbox") - fireEvent.change(input, { target: { value: 'rails attributes' } }) - expect(input).toHaveValue('rails attributes') + fireEvent.change(input, { target: { value: "rails attributes" } }) + expect(input).toHaveValue("rails attributes") }) - describe('with async false', () => { - it('sends the correct data to the server upon form submit', () => { + describe("with async false", () => { + it("sends the correct data to the server upon form submit", () => { let capturedData: any - const mockRequest = jest.spyOn(router, 'visit').mockImplementation((route, request) => { + const mockRequest = jest.spyOn(router, "visit").mockImplementation((route, request) => { capturedData = request?.data return Promise.resolve({ data: request?.data }) }) const handleSubmit = (form) => { - form.transform(data => ({ ...data, extra: { value: 'exists' } })) + form.transform(data => ({ ...data, extra: { value: "exists" } })) } render( @@ -229,29 +229,29 @@ describe('Form Component', () => { , ) - const button = screen.getByRole('button') + const button = screen.getByRole("button") fireEvent.click(button) expect(mockRequest).toHaveBeenCalled() - expect(get(capturedData, 'user.username')).toBe(multiRootData.user.username) - expect(get(capturedData, 'person.nested_attributes.key')).toBe(multiRootData.person.nested.key) - expect(get(capturedData, 'extra.value')).toBe('exists') + expect(get(capturedData, "user.username")).toBe(multiRootData.user.username) + expect(get(capturedData, "person.nested_attributes.key")).toBe(multiRootData.person.nested.key) + expect(get(capturedData, "extra.value")).toBe("exists") }) }) - describe('with async true', () => { - it('sends the correct data to the server upon form submit', async () => { + describe("with async true", () => { + it("sends the correct data to the server upon form submit", async() => { let capturedData: any - const mockRequest = jest.spyOn(axios, 'post').mockImplementation((url, data, config) => { + const mockRequest = jest.spyOn(axios, "post").mockImplementation((url, data, config) => { capturedData = data return Promise.resolve({ data }) }) const handleSubmit = (form) => { - form.transform(data => ({ ...data, extra: { value: 'exists' } })) + form.transform(data => ({ ...data, extra: { value: "exists" } })) } render( @@ -270,22 +270,22 @@ describe('Form Component', () => { , ) - await act(async () => { - const button = screen.getByRole('button') + await act(async() => { + const button = screen.getByRole("button") await fireEvent.click(button) }) expect(mockRequest).toHaveBeenCalled() - expect(get(capturedData, 'person.first_name')).toEqual(singleRootData.person.first_name) - expect(get(capturedData, 'person.nested_attributes.key')).toEqual(singleRootData.person.nested.key) - expect(get(capturedData, 'extra.value')).toEqual('exists') + expect(get(capturedData, "person.first_name")).toEqual(singleRootData.person.first_name) + expect(get(capturedData, "person.nested_attributes.key")).toEqual(singleRootData.person.nested.key) + expect(get(capturedData, "extra.value")).toEqual("exists") }) }) }) - describe('Filter', () => { - it('unsets data at the given paths', () => { + describe("Filter", () => { + it("unsets data at the given paths", () => { const handleChange = (form) => { expect(form.data.person.last_name).toBeUndefined() expect(form.data.user.username).toBeUndefined() @@ -299,7 +299,7 @@ describe('Form Component', () => { model="person" to="/form" data={ multiRootData } - filter={ ['person.last_name', 'user.username', 'contact.phones[].type'] } + filter={ ["person.last_name", "user.username", "contact.phones[].type"] } onChange={ handleChange } > @@ -309,32 +309,32 @@ describe('Form Component', () => { }) }) - describe('when async is false', () => { - it('should trigger all callbacks in correct order with progress', async () => { - const callOrder: string[] = []; + describe("when async is false", () => { + it("should trigger all callbacks in correct order with progress", async() => { + const callOrder: string[] = [] const callbacks = { onBefore: jest.fn(() => { - callOrder.push('onBefore') + callOrder.push("onBefore") }), onStart: jest.fn(() => { - callOrder.push('onStart') + callOrder.push("onStart") }), onProgress: jest.fn(() => { - callOrder.push('onProgress') + callOrder.push("onProgress") }), onSuccess: jest.fn(() => { - callOrder.push('onSuccess') + callOrder.push("onSuccess") }), onError: jest.fn(), onFinish: jest.fn(() => { - callOrder.push('onFinish') + callOrder.push("onFinish") }), } - const mockRequest = jest.spyOn(router, 'visit').mockImplementation((route, request) => { + const mockRequest = jest.spyOn(router, "visit").mockImplementation((route, request) => { const pendingVisit: PendingVisit = Object.assign({ url: new URL(`http://www.example.com${route}`), - method: 'post', + method: "post", data: {}, replace: false, preserveScroll: false, @@ -344,7 +344,7 @@ describe('Form Component', () => { headers: {}, errorBag: null, forceFormData: false, - queryStringArrayFormat: 'indices', + queryStringArrayFormat: "indices", async: false, showProgress: false, prefetch: false, @@ -359,10 +359,10 @@ describe('Form Component', () => { request.onBefore(pendingVisit) request.onStart(pendingVisit) request.onSuccess({ - component: 'Page', + component: "Page", props: {}, url: `http://www.example.com${route}`, - version: '', + version: "", clearHistory: true, encryptHistory: true, } as Page<{}>) @@ -387,17 +387,17 @@ describe('Form Component', () => { ) - const button = screen.getByRole('button') - await act(async () => { + const button = screen.getByRole("button") + await act(async() => { await fireEvent.click(button) - }); + }) expect(mockRequest).toHaveBeenCalled() - expect(callbacks.onBefore).toHaveBeenCalled(); - expect(callbacks.onStart).toHaveBeenCalled(); - expect(callbacks.onSuccess).toHaveBeenCalled(); - expect(callbacks.onFinish).toHaveBeenCalled(); + expect(callbacks.onBefore).toHaveBeenCalled() + expect(callbacks.onStart).toHaveBeenCalled() + expect(callbacks.onSuccess).toHaveBeenCalled() + expect(callbacks.onFinish).toHaveBeenCalled() }) }) diff --git a/tests/nestedFields.test.tsx b/tests/nestedFields.test.tsx index 7deb3d2..abebcfc 100644 --- a/tests/nestedFields.test.tsx +++ b/tests/nestedFields.test.tsx @@ -1,15 +1,15 @@ -import { render, screen } from '@testing-library/react' -import '@testing-library/jest-dom' +import { render, screen } from "@testing-library/react" +import "@testing-library/jest-dom" import { Form, Input, NestedFields, -} from '../src' -import ContextTest from './components/ContextTest' +} from "../src" +import ContextTest from "./components/ContextTest" -describe('NestedFields', () => { - it('adds values to the form data object', () => { +describe("NestedFields", () => { + it("adds values to the form data object", () => { render(
@@ -22,8 +22,8 @@ describe('NestedFields', () => {
, ) - expect(screen.getByTestId('data')).toHaveTextContent( - '{"user":{"username":"","nest":{"nested_value":""}}}', + expect(screen.getByTestId("data")).toHaveTextContent( + "{\"user\":{\"username\":\"\",\"nest\":{\"nested_value\":\"\"}}}", ) }) diff --git a/tests/server.mock.ts b/tests/server.mock.ts index 1ce0b0b..685ef98 100644 --- a/tests/server.mock.ts +++ b/tests/server.mock.ts @@ -1,27 +1,27 @@ -import { http, HttpResponse } from 'msw'; -import { setupServer } from 'msw/node'; +import { http, HttpResponse } from "msw" +import { setupServer } from "msw/node" // Mock data for testing const mockSuccessData = { - id: '1', - name: 'Test Item', - details: 'Some test details', -}; + id: "1", + name: "Test Item", + details: "Some test details", +} const mockErrorResponse = { errors: { - users: ['No data found'], + users: ["No data found"], }, -}; +} export const server = setupServer( // Success scenario - http.post('/api/data', () => { - return HttpResponse.json(mockSuccessData); + http.post("/api/data", () => { + return HttpResponse.json(mockSuccessData) }), // Error scenario - http.post('/api/data-error', () => { - return HttpResponse.json(mockErrorResponse, { status: 302 }); + http.post("/api/data-error", () => { + return HttpResponse.json(mockErrorResponse, { status: 302 }) }) ) diff --git a/tests/useDynamicInputs.test.tsx b/tests/useDynamicInputs.test.tsx index 16ecac0..df2d291 100644 --- a/tests/useDynamicInputs.test.tsx +++ b/tests/useDynamicInputs.test.tsx @@ -1,33 +1,33 @@ -import { render, screen, act } from '@testing-library/react' -import '@testing-library/jest-dom' +import { render, screen, act } from "@testing-library/react" +import "@testing-library/jest-dom" import { Form, useForm, DynamicInputs, useDynamicInputs, Input, -} from '../src' -import { multiRootData } from './components/data' -import ContextTest from './components/ContextTest' +} from "../src" +import { multiRootData } from "./components/data" +import ContextTest from "./components/ContextTest" -describe('DynamicInputs', () => { - describe('With data object passed in', () => { +describe("DynamicInputs", () => { + describe("With data object passed in", () => { - it('renders dynamic input fields', () => { + it("renders dynamic input fields", () => { render(
- + , ) - const buttons = screen.getAllByRole('button') + const buttons = screen.getAllByRole("button") expect(buttons.length).toBe(4) }) - it('adds inputs', () => { + it("adds inputs", () => { let form, inputs render( @@ -39,15 +39,15 @@ describe('DynamicInputs', () => { function TestComponent() { form = useForm() inputs = useDynamicInputs({ - model: 'phones', - emptyData: { number: '' }, + model: "phones", + emptyData: { number: "" }, }) return null } act(() => { inputs.addInput() - inputs.addInput({ number: '1' }) + inputs.addInput({ number: "1" }) inputs.addInput(records => { return ({ number: `${parseInt(records[1].number) + 1}`, @@ -55,14 +55,14 @@ describe('DynamicInputs', () => { }) }) - const phones = form.getData('contact.phones') + const phones = form.getData("contact.phones") - expect(phones).toContainEqual({ number: '' }) - expect(phones).toContainEqual({ number: '1' }) - expect(phones).toContainEqual({ number: '2234567891' }) + expect(phones).toContainEqual({ number: "" }) + expect(phones).toContainEqual({ number: "1" }) + expect(phones).toContainEqual({ number: "2234567891" }) }) - it('removes inputs', () => { + it("removes inputs", () => { let form, inputs render( @@ -74,35 +74,35 @@ describe('DynamicInputs', () => { function TestComponent() { form = useForm() inputs = useDynamicInputs({ - model: 'phones', - emptyData: { number: '' }, + model: "phones", + emptyData: { number: "" }, }) return null } - let phones = form.getData('contact.phones') + let phones = form.getData("contact.phones") expect(phones.length).toEqual(3) act(() => { inputs.removeInput(1) }) - phones = form.getData('contact.phones') + phones = form.getData("contact.phones") expect(phones.length).toEqual(2) - expect(phones).not.toContainEqual({ number: '2234567890' }) + expect(phones).not.toContainEqual({ number: "2234567890" }) }) }) /** * No data prop tests */ - describe('With no data object passed in', () => { + describe("With no data object passed in", () => { - it('renders dynamic input fields', () => { + it("renders dynamic input fields", () => { render(
- + @@ -111,25 +111,25 @@ describe('DynamicInputs', () => { , ) - const buttons = screen.getAllByRole('button') - const dataEl = screen.getByTestId('data') + const buttons = screen.getAllByRole("button") + const dataEl = screen.getByTestId("data") act(() => { buttons[0].click() }) expect(buttons.length).toBe(1) - expect(dataEl).toHaveTextContent('{"contact":{"phones":[{"title":"","number":"+1"}]}}') + expect(dataEl).toHaveTextContent("{\"contact\":{\"phones\":[{\"title\":\"\",\"number\":\"+1\"}]}}") }) - it('adds inputs', () => { + it("adds inputs", () => { let form, inputs function TestComponent() { form = useForm() inputs = useDynamicInputs({ - model: 'phones', - emptyData: { number: '' }, + model: "phones", + emptyData: { number: "" }, }) return null } @@ -142,7 +142,7 @@ describe('DynamicInputs', () => { act(() => { inputs.addInput() - inputs.addInput({ number: '1' }) + inputs.addInput({ number: "1" }) inputs.addInput(records => { return ({ number: `${parseInt(records[1].number) + 1}`, @@ -150,14 +150,14 @@ describe('DynamicInputs', () => { }) }) - const phones = form.getData('contact.phones') + const phones = form.getData("contact.phones") - expect(phones).toContainEqual({ number: '' }) - expect(phones).toContainEqual({ number: '1' }) - expect(phones).toContainEqual({ number: '2' }) + expect(phones).toContainEqual({ number: "" }) + expect(phones).toContainEqual({ number: "1" }) + expect(phones).toContainEqual({ number: "2" }) }) - it('removes inputs', () => { + it("removes inputs", () => { let form, inputs render( @@ -169,8 +169,8 @@ describe('DynamicInputs', () => { function TestComponent() { form = useForm() inputs = useDynamicInputs({ - model: 'phones', - emptyData: { number: '' }, + model: "phones", + emptyData: { number: "" }, }) return null } @@ -181,13 +181,13 @@ describe('DynamicInputs', () => { inputs.addInput() }) - expect(form.getData('contact.phones').length).toEqual(2) + expect(form.getData("contact.phones").length).toEqual(2) act(() => { inputs.removeInput(1) }) - expect(form.getData('contact.phones').length).toEqual(1) + expect(form.getData("contact.phones").length).toEqual(1) }) }) diff --git a/tests/useInertiaForm.server.test.tsx b/tests/useInertiaForm.server.test.tsx index 5bc3714..a5a79fa 100644 --- a/tests/useInertiaForm.server.test.tsx +++ b/tests/useInertiaForm.server.test.tsx @@ -1,92 +1,92 @@ -import { router } from '@inertiajs/react' -import { renderHook, act } from '@testing-library/react' -import { server } from './server.mock' -import { useInertiaForm } from '../src' +import { router } from "@inertiajs/react" +import { renderHook, act } from "@testing-library/react" +import { server } from "./server.mock" +import { useInertiaForm } from "../src" beforeAll(() => server.listen()) afterEach(() => server.resetHandlers()) afterAll(() => server.close()) -describe('submit', () => { - describe('flat data forms with errors', () => { - it('should handle flat data with one key', async () => { +describe("submit", () => { + describe("flat data forms with errors", () => { + it("should handle flat data with one key", async() => { const testData = { - email: 'some name', + email: "some name", } - jest.spyOn(router, 'post').mockImplementation((url, data, options) => { + jest.spyOn(router, "post").mockImplementation((url, data, options) => { options.onError({ // @ts-ignore - email: ['must exist'], + email: ["must exist"], }) }) const { result } = renderHook(() => useInertiaForm(testData)) - await act(async () => { - result.current.submit('post', '/api/data-error') + await act(async() => { + result.current.submit("post", "/api/data-error") }) expect(result.current.errors).toMatchObject({ - email: ['must exist'], + email: ["must exist"], }) }) - it('should flat data with more than one key', async () => { + it("should flat data with more than one key", async() => { const testData = { - email: 'some email', - user: 'some name', + email: "some email", + user: "some name", } - jest.spyOn(router, 'post').mockImplementation((url, data, options) => { + jest.spyOn(router, "post").mockImplementation((url, data, options) => { options.onError({ // @ts-ignore - email: ['must exist'], + email: ["must exist"], // @ts-ignore - username: ['must exist'], + username: ["must exist"], }) }) const { result } = renderHook(() => useInertiaForm(testData)) - await act(async () => { - result.current.submit('post', '/api/data-error') + await act(async() => { + result.current.submit("post", "/api/data-error") }) expect(result.current.errors).toMatchObject({ - email: ['must exist'], - username: ['must exist'], + email: ["must exist"], + username: ["must exist"], }) }) }) - describe('nested data', () => { - it('should nest errors', async () => { + describe("nested data", () => { + it("should nest errors", async() => { const testData = { user: { - email: 'some email', - username: 'some name', + email: "some email", + username: "some name", }, } - jest.spyOn(router, 'post').mockImplementation((url, data, options) => { + jest.spyOn(router, "post").mockImplementation((url, data, options) => { options.onError({ // @ts-ignore - email: ['must exist'], + email: ["must exist"], // @ts-ignore - username: ['must exist'], + username: ["must exist"], }) }) const { result } = renderHook(() => useInertiaForm(testData)) - await act(async () => { - result.current.submit('post', '/api/data-error') + await act(async() => { + result.current.submit("post", "/api/data-error") }) expect(result.current.errors).toMatchObject({ - 'user.email': ['must exist'], - 'user.username': ['must exist'], + "user.email": ["must exist"], + "user.username": ["must exist"], }) }) }) diff --git a/tests/useInertiaForm.test.tsx b/tests/useInertiaForm.test.tsx index 4ebb70b..62d4e82 100644 --- a/tests/useInertiaForm.test.tsx +++ b/tests/useInertiaForm.test.tsx @@ -1,10 +1,10 @@ -import { act, renderHook } from '@testing-library/react' -import { router } from '@inertiajs/core' -import { useInertiaForm } from '../src' -import { get } from 'lodash' -import axios from 'axios' -import { singleRootData } from './components/data' -import { fillEmptyValues } from '../src/utils' +import { act, renderHook } from "@testing-library/react" +import { router } from "@inertiajs/core" +import { useInertiaForm } from "../src" +import { get } from "lodash" +import axios from "axios" +import { singleRootData } from "./components/data" +import { fillEmptyValues } from "../src/utils" type InitialData = { user: { @@ -22,229 +22,229 @@ type InitialData = { const initialData: InitialData = { user: { - username: 'some name', + username: "some name", }, person: { - first_name: 'first', - last_name: 'last', + first_name: "first", + last_name: "last", middle_name: undefined, }, contact: { phones: [ - { number: '1234567890' }, - { number: '2234567890' }, - { number: '3234567890' }, + { number: "1234567890" }, + { number: "2234567890" }, + { number: "3234567890" }, ], }, } const flatData: Record = { - first_name: 'first', + first_name: "first", middle_name: undefined, - last_name: 'last', + last_name: "last", } const singleValue: Record = { first_name: undefined, } -describe('useInertiaForm', () => { - describe('with nested data', () => { +describe("useInertiaForm", () => { + describe("with nested data", () => { const { result } = renderHook(() => useInertiaForm(initialData)) - it('data value should be equal to initialData, with undefined values converted to empty strings', () => { + it("data value should be equal to initialData, with undefined values converted to empty strings", () => { const expectedValue = structuredClone(initialData) - expectedValue.person.middle_name = '' + expectedValue.person.middle_name = "" expect(result.current.data).toStrictEqual(expectedValue) }) }) - describe('with flat data', () => { + describe("with flat data", () => { const { result } = renderHook(() => useInertiaForm(flatData)) - it('data value should be equal to flatData, with undefined values converted to empty strings', () => { + it("data value should be equal to flatData, with undefined values converted to empty strings", () => { const expectedValue = structuredClone(flatData) - expectedValue.middle_name = '' + expectedValue.middle_name = "" expect(result.current.data).toStrictEqual(expectedValue) }) }) - describe('with only one key', () => { + describe("with only one key", () => { const { result } = renderHook(() => useInertiaForm(singleValue)) - it('data value should be equal to singleValue, with undefined values converted to empty strings', () => { + it("data value should be equal to singleValue, with undefined values converted to empty strings", () => { const expectedValue = structuredClone(singleValue) - expectedValue.first_name = '' + expectedValue.first_name = "" expect(result.current.data).toStrictEqual(expectedValue) }) }) }) -describe('setData', () => { - describe('with nested data', () => { - it('should update nested state', () => { +describe("setData", () => { + describe("with nested data", () => { + it("should update nested state", () => { const { result } = renderHook(() => useInertiaForm(initialData)) act(() => { - result.current.setData('user.username', 'changed') + result.current.setData("user.username", "changed") }) - expect(result.current.data?.user.username).toStrictEqual('changed') + expect(result.current.data?.user.username).toStrictEqual("changed") }) - it('should update nested array values', () => { + it("should update nested array values", () => { const { result } = renderHook(() => useInertiaForm(initialData)) act(() => { - result.current.setData('contact.phones[0].number', '234567') - result.current.setData('contact.phones[3].number', 'new number') + result.current.setData("contact.phones[0].number", "234567") + result.current.setData("contact.phones[3].number", "new number") }) - expect(result.current.data?.contact.phones[0].number).toStrictEqual('234567') - expect(result.current.data?.contact.phones[3].number).toStrictEqual('new number') + expect(result.current.data?.contact.phones[0].number).toStrictEqual("234567") + expect(result.current.data?.contact.phones[3].number).toStrictEqual("new number") }) }) - describe('with flat data', () => { - it('should update state', () => { + describe("with flat data", () => { + it("should update state", () => { const { result } = renderHook(() => useInertiaForm(flatData)) act(() => { - result.current.setData('first_name', 'changed') + result.current.setData("first_name", "changed") }) - expect(result.current.data?.first_name).toStrictEqual('changed') + expect(result.current.data?.first_name).toStrictEqual("changed") }) }) - describe('with only one key', () => { - it('should update state', () => { + describe("with only one key", () => { + it("should update state", () => { const { result } = renderHook(() => useInertiaForm(singleValue)) act(() => { - result.current.setData('first_name', 'changed') + result.current.setData("first_name", "changed") }) - expect(result.current.data?.first_name).toStrictEqual('changed') + expect(result.current.data?.first_name).toStrictEqual("changed") }) }) }) -describe('getData', () => { - describe('with nested data', () => { - it('should get initial nested state', () => { +describe("getData", () => { + describe("with nested data", () => { + it("should get initial nested state", () => { const { result } = renderHook(() => useInertiaForm(initialData)) act(() => { - expect(result.current.getData('user.username')).toStrictEqual(initialData.user.username) - expect(result.current.getData('contact.phones[0].number')).toStrictEqual(initialData.contact.phones[0].number) + expect(result.current.getData("user.username")).toStrictEqual(initialData.user.username) + expect(result.current.getData("contact.phones[0].number")).toStrictEqual(initialData.contact.phones[0].number) }) }) - it('should get updated nested state', () => { + it("should get updated nested state", () => { const { result } = renderHook(() => useInertiaForm(initialData)) act(() => { - result.current.setData('user.username', 'something') - result.current.setData('contact.phones[0].number', '123-456-7890') + result.current.setData("user.username", "something") + result.current.setData("contact.phones[0].number", "123-456-7890") }) act(() => { - expect(result.current.getData('user.username')).toStrictEqual('something') - expect(result.current.getData('contact.phones[0].number')).toStrictEqual('123-456-7890') + expect(result.current.getData("user.username")).toStrictEqual("something") + expect(result.current.getData("contact.phones[0].number")).toStrictEqual("123-456-7890") }) }) }) - describe('with flat data', () => { - it('should get initial state', () => { + describe("with flat data", () => { + it("should get initial state", () => { const { result } = renderHook(() => useInertiaForm(flatData)) act(() => { - expect(result.current.getData('first_name')).toStrictEqual(flatData.first_name) - expect(result.current.getData('middle_name')).toStrictEqual('') + expect(result.current.getData("first_name")).toStrictEqual(flatData.first_name) + expect(result.current.getData("middle_name")).toStrictEqual("") }) }) - it('should get updated state', () => { + it("should get updated state", () => { const { result } = renderHook(() => useInertiaForm(flatData)) - act(() => result.current.setData('middle_name', 'something')) + act(() => result.current.setData("middle_name", "something")) act(() => { - expect(result.current.getData('middle_name')).toStrictEqual('something') + expect(result.current.getData("middle_name")).toStrictEqual("something") }) }) }) - describe('with only one key', () => { - it('should get nested state', () => { + describe("with only one key", () => { + it("should get nested state", () => { const { result } = renderHook(() => useInertiaForm(singleValue)) act(() => { - expect(result.current.getData('first_name')).toStrictEqual('') + expect(result.current.getData("first_name")).toStrictEqual("") }) }) }) - describe('with only one key', () => { - it('should get updated state', () => { + describe("with only one key", () => { + it("should get updated state", () => { const { result } = renderHook(() => useInertiaForm(singleValue)) - act(() => result.current.setData('first_name', 'something')) + act(() => result.current.setData("first_name", "something")) act(() => { - expect(result.current.getData('first_name')).toStrictEqual('something') + expect(result.current.getData("first_name")).toStrictEqual("something") }) }) }) }) -describe('unsetData', () => { - describe('with nested data', () => { - it('should remove nested state', () => { +describe("unsetData", () => { + describe("with nested data", () => { + it("should remove nested state", () => { const { result } = renderHook(() => useInertiaForm(initialData)) - act(() => result.current.unsetData('user.username')) + act(() => result.current.unsetData("user.username")) act(() => expect(result.current.data?.user).toMatchObject({})) }) - it('should reorder arrays when removing an element', () => { + it("should reorder arrays when removing an element", () => { const { result } = renderHook(() => useInertiaForm(initialData)) - act(() => result.current.unsetData('contact.phones[1]')) + act(() => result.current.unsetData("contact.phones[1]")) act(() => { - expect(result.current.data?.contact.phones[0].number).toStrictEqual('1234567890') - expect(result.current.data?.contact.phones[1].number).toStrictEqual('3234567890') + expect(result.current.data?.contact.phones[0].number).toStrictEqual("1234567890") + expect(result.current.data?.contact.phones[1].number).toStrictEqual("3234567890") }) }) }) - describe('with flat data', () => { - it('should remove a value', () => { + describe("with flat data", () => { + it("should remove a value", () => { const { result } = renderHook(() => useInertiaForm(flatData)) - act(() => result.current.unsetData('first_name')) + act(() => result.current.unsetData("first_name")) act(() => { - expect(result.current.data).not.toHaveProperty('first_name') + expect(result.current.data).not.toHaveProperty("first_name") // Others are untouched expect(result.current.data?.last_name).toStrictEqual(flatData.last_name) }) }) }) - describe('with only one key', () => { - it('should remove a value', () => { + describe("with only one key", () => { + it("should remove a value", () => { const { result } = renderHook(() => useInertiaForm(singleValue)) - act(() => result.current.unsetData('first_name')) + act(() => result.current.unsetData("first_name")) act(() => { - expect(result.current.data).not.toHaveProperty('first_name') + expect(result.current.data).not.toHaveProperty("first_name") expect(result.current.data).toEqual({}) }) }) @@ -252,13 +252,13 @@ describe('unsetData', () => { }) // Tests not strictly necessary since we don't override setError -describe('setError', () => { - describe('with nested data', () => { - it('should set errors by key', () => { +describe("setError", () => { + describe("with nested data", () => { + it("should set errors by key", () => { const { result } = renderHook(() => useInertiaForm(initialData)) - const key = 'person.middle_name' - const error = 'Value must not be empty' + const key = "person.middle_name" + const error = "Value must not be empty" act(() => result.current.setError(key, error)) @@ -268,12 +268,12 @@ describe('setError', () => { }) }) - it('should set errors by object', () => { + it("should set errors by object", () => { const { result } = renderHook(() => useInertiaForm(initialData)) const errors = { - 'person.middle_name': 'Value must not be empty', - 'contact.phones[1].number': 'Value is no good!', + "person.middle_name": "Value must not be empty", + "contact.phones[1].number": "Value is no good!", } act(() => result.current.setError(errors)) @@ -285,12 +285,12 @@ describe('setError', () => { }) }) - describe('with flat data', () => { - it('should set errors by key', () => { + describe("with flat data", () => { + it("should set errors by key", () => { const { result } = renderHook(() => useInertiaForm(flatData)) - const key = 'middle_name' - const error = 'Value must not be empty' + const key = "middle_name" + const error = "Value must not be empty" act(() => result.current.setError(key, error)) @@ -300,12 +300,12 @@ describe('setError', () => { }) }) - it('should set errors by object', () => { + it("should set errors by object", () => { const { result } = renderHook(() => useInertiaForm(flatData)) const errors = { - 'first_name': 'Value must not be empty', - 'middle_name': 'Value is no good!', + "first_name": "Value must not be empty", + "middle_name": "Value is no good!", } act(() => result.current.setError(errors)) @@ -317,12 +317,12 @@ describe('setError', () => { }) }) - describe('with only one key', () => { - it('should set errors by key', () => { + describe("with only one key", () => { + it("should set errors by key", () => { const { result } = renderHook(() => useInertiaForm(singleValue)) - const key = 'first_name' - const error = 'Value must not be empty' + const key = "first_name" + const error = "Value must not be empty" act(() => result.current.setError(key, error)) @@ -332,11 +332,11 @@ describe('setError', () => { }) }) - it('should set errors by object', () => { + it("should set errors by object", () => { const { result } = renderHook(() => useInertiaForm(singleValue)) const errors = { - 'first_name': 'Value must not be empty', + "first_name": "Value must not be empty", } act(() => result.current.setError(errors)) @@ -349,13 +349,13 @@ describe('setError', () => { }) }) -describe('getError', () => { - describe('with nested data', () => { - it('should return a single error by key', () => { +describe("getError", () => { + describe("with nested data", () => { + it("should return a single error by key", () => { const { result } = renderHook(() => useInertiaForm(initialData)) - const key = 'person.middle_name' - const error = 'Value must not be empty' + const key = "person.middle_name" + const error = "Value must not be empty" act(() => result.current.setError(key, error)) @@ -363,12 +363,12 @@ describe('getError', () => { }) }) - describe('with flat data', () => { - it('should return a single error by key', () => { + describe("with flat data", () => { + it("should return a single error by key", () => { const { result } = renderHook(() => useInertiaForm(flatData)) - const key = 'middle_name' - const error = 'Value must not be empty' + const key = "middle_name" + const error = "Value must not be empty" act(() => result.current.setError(key, error)) @@ -376,12 +376,12 @@ describe('getError', () => { }) }) - describe('with single value', () => { - it('should return a single error by key', () => { + describe("with single value", () => { + it("should return a single error by key", () => { const { result } = renderHook(() => useInertiaForm(singleValue)) - const key = 'first_name' - const error = 'Value must not be empty' + const key = "first_name" + const error = "Value must not be empty" act(() => result.current.setError(key, error)) @@ -390,23 +390,23 @@ describe('getError', () => { }) }) -describe('clearErrors', () => { - it('should remove one error when supplied a string', () => { +describe("clearErrors", () => { + it("should remove one error when supplied a string", () => { const { result } = renderHook(() => useInertiaForm(initialData)) - const key = 'person.middle_name' + const key = "person.middle_name" - act(() => result.current.setError(key, 'Value must not be empty')) + act(() => result.current.setError(key, "Value must not be empty")) act(() => result.current.clearErrors(key)) act(() => expect(result.current.errors).toEqual({})) }) - it('should remove several errors when supplied an array of strings', () => { + it("should remove several errors when supplied an array of strings", () => { const { result } = renderHook(() => useInertiaForm(initialData)) - const keys = ['user.username', 'person.middle_name', 'person.last_name'] - const error = 'There is an error' + const keys = ["user.username", "person.middle_name", "person.last_name"] + const error = "There is an error" act(() => { keys.forEach(key => { result.current.setError(key, error) @@ -418,11 +418,11 @@ describe('clearErrors', () => { act(() => expect(result.current.errors).toEqual({ [keys[2]]: error })) }) - it('should remove all errors when called with no arguments', () => { + it("should remove all errors when called with no arguments", () => { const { result } = renderHook(() => useInertiaForm(initialData)) - const keys = ['user.username', 'person.middle_name', 'person.last_name'] - const error = 'There is an error' + const keys = ["user.username", "person.middle_name", "person.last_name"] + const error = "There is an error" act(() => { keys.forEach(key => { @@ -436,13 +436,13 @@ describe('clearErrors', () => { }) }) -describe('setDefaults and reset', () => { +describe("setDefaults and reset", () => { const newData = structuredClone(initialData) - newData.user.username = 'changed' - newData.person.middle_name = 'Another' + newData.user.username = "changed" + newData.person.middle_name = "Another" newData.contact.phones = [] - it('should set defaults to the current values of form data when given no arguments', () => { + it("should set defaults to the current values of form data when given no arguments", () => { const { result } = renderHook(() => useInertiaForm(initialData)) act(() => result.current.setData(newData)) @@ -452,7 +452,7 @@ describe('setDefaults and reset', () => { act(() => expect(result.current.data).toEqual(newData)) }) - it('should set the defaults to the values of a supplied object', () => { + it("should set the defaults to the values of a supplied object", () => { const { result } = renderHook(() => useInertiaForm(initialData)) act(() => result.current.setDefaults(newData)) @@ -461,51 +461,51 @@ describe('setDefaults and reset', () => { act(() => expect(result.current.data).toEqual(newData)) }) - it('should change one default value when passed a key value pair', () => { + it("should change one default value when passed a key value pair", () => { const { result } = renderHook(() => useInertiaForm(initialData)) - const key = 'user.username' - const newValue = 'different' + const key = "user.username" + const newValue = "different" act(() => result.current.setDefaults(key, newValue)) act(() => result.current.reset()) act(() => expect(result.current.getData(key)).not.toEqual(get(initialData, key))) - act(() => expect(result.current.getData('person.first_name')).toEqual(initialData.person.first_name)) + act(() => expect(result.current.getData("person.first_name")).toEqual(initialData.person.first_name)) act(() => expect(result.current.getData(key)).toEqual(newValue)) }) - it('should only reset a single value when reset is called with a string', () => { + it("should only reset a single value when reset is called with a string", () => { const { result } = renderHook(() => useInertiaForm(initialData)) - const key = 'user.username' + const key = "user.username" - act(() => result.current.setData('user.username', 'changed')) - act(() => result.current.reset('user.username')) + act(() => result.current.setData("user.username", "changed")) + act(() => result.current.reset("user.username")) act(() => expect(result.current.getData(key)).toEqual(initialData.user.username)) }) - it('should reset several, but not all values, when called with an array of string', () => { + it("should reset several, but not all values, when called with an array of string", () => { const { result } = renderHook(() => useInertiaForm(initialData)) - const keys = ['user.username', 'person.middle_name'] + const keys = ["user.username", "person.middle_name"] act(() => result.current.setData(newData)) act(() => result.current.reset(keys)) act(() => expect(result.current.getData(keys[0])).toEqual(initialData.user.username)) - act(() => expect(result.current.getData(keys[1])).toEqual('')) - act(() => expect(result.current.getData('contact.phones')).toEqual([])) + act(() => expect(result.current.getData(keys[1])).toEqual("")) + act(() => expect(result.current.getData("contact.phones")).toEqual([])) }) }) -describe('onChange', () => { - it('should be called whenever data is changed', () => { +describe("onChange", () => { + it("should be called whenever data is changed", () => { const { result } = renderHook(() => useInertiaForm(initialData)) - const changeKey = 'user.username' - const changeValue1 = 'something' + const changeKey = "user.username" + const changeValue1 = "something" act(() => { result.current.onChange((key, value, prev) => { @@ -519,76 +519,76 @@ describe('onChange', () => { }) }) -describe('submit', () => { - it('should submit transformed data to the server', () => { +describe("submit", () => { + it("should submit transformed data to the server", () => { const testData = { user: { - username: 'some name', + username: "some name", }, } - const mockRequest = jest.spyOn(router, 'visit').mockImplementation((route, request) => { - expect(request?.data).toMatchObject({ ...testData, transformed: 'value' }) + const mockRequest = jest.spyOn(router, "visit").mockImplementation((route, request) => { + expect(request?.data).toMatchObject({ ...testData, transformed: "value" }) return Promise.resolve({ data: request?.data }) }) const { result } = renderHook(() => useInertiaForm(testData)) act(() => { - result.current.transform(data => ({ ...data, transformed: 'value' })) - result.current.submit('post', '/form') + result.current.transform(data => ({ ...data, transformed: "value" })) + result.current.submit("post", "/form") expect(mockRequest).toHaveBeenCalled() }) }) - describe('when async is true', () => { - it('should submit transformed data using axios', async () => { + describe("when async is true", () => { + it("should submit transformed data using axios", async() => { const testData = { user: { - username: 'some name', + username: "some name", }, } let capturedData: any - const mockRequest = jest.spyOn(axios, 'post').mockImplementation((url, data) => { + const mockRequest = jest.spyOn(axios, "post").mockImplementation((url, data) => { capturedData = data return Promise.resolve({ data }) }) const { result } = renderHook(() => useInertiaForm(testData)) - await act(async () => { - result.current.transform(data => ({ ...data, transformed: 'value' })) - await result.current.submit('post', '/form', { async: true }) + await act(async() => { + result.current.transform(data => ({ ...data, transformed: "value" })) + await result.current.submit("post", "/form", { async: true }) expect(mockRequest).toHaveBeenCalled() - expect(capturedData).toMatchObject({ ...testData, transformed: 'value' }) + expect(capturedData).toMatchObject({ ...testData, transformed: "value" }) }) }) - it('should trigger all callbacks in correct order with progress', async () => { - const callOrder: string[] = []; + it("should trigger all callbacks in correct order with progress", async() => { + const callOrder: string[] = [] const callbacks = { onBefore: jest.fn(() => { - callOrder.push('onBefore') + callOrder.push("onBefore") }), onStart: jest.fn(() => { - callOrder.push('onStart') + callOrder.push("onStart") }), onProgress: jest.fn(() => { - callOrder.push('onProgress') + callOrder.push("onProgress") }), onSuccess: jest.fn(() => { - callOrder.push('onSuccess') + callOrder.push("onSuccess") }), onError: jest.fn(), onFinish: jest.fn(() => { - callOrder.push('onFinish') + callOrder.push("onFinish") }), - }; + } - const mockRequest = jest.spyOn(axios, 'post').mockImplementation((url, data, config) => { + const mockRequest = jest.spyOn(axios, "post").mockImplementation((url, data, config) => { if(config?.onUploadProgress) { config.onUploadProgress({ loaded: 50, @@ -597,24 +597,24 @@ describe('submit', () => { bytes: 50, lengthComputable: true, percentage: 50, - }); + }) } - return Promise.resolve(data); - }); + return Promise.resolve(data) + }) - const { result } = renderHook(() => useInertiaForm(singleRootData)); + const { result } = renderHook(() => useInertiaForm(singleRootData)) - await act(async () => { - await result.current.submit('post', '/form', { + await act(async() => { + await result.current.submit("post", "/form", { async: true, ...callbacks, - }); - }); + }) + }) expect(mockRequest).toHaveBeenCalled() - expect(callbacks.onBefore).toHaveBeenCalledWith(undefined); - expect(callbacks.onStart).toHaveBeenCalledWith(undefined); + expect(callbacks.onBefore).toHaveBeenCalledWith(undefined) + expect(callbacks.onStart).toHaveBeenCalledWith(undefined) expect(callbacks.onProgress).toHaveBeenCalledWith({ loaded: 50, total: 100, @@ -622,20 +622,20 @@ describe('submit', () => { bytes: 50, lengthComputable: true, percentage: 50, - }); - expect(callbacks.onSuccess).toHaveBeenCalledWith(fillEmptyValues(singleRootData)); - expect(callbacks.onFinish).toHaveBeenCalledWith(undefined); + }) + expect(callbacks.onSuccess).toHaveBeenCalledWith(fillEmptyValues(singleRootData)) + expect(callbacks.onFinish).toHaveBeenCalledWith(undefined) expect(callOrder).toEqual([ - 'onBefore', - 'onStart', - 'onProgress', - 'onSuccess', - 'onFinish', - ]); - }); - - it('should handle errors correctly', async () => { + "onBefore", + "onStart", + "onProgress", + "onSuccess", + "onFinish", + ]) + }) + + it("should handle errors correctly", async() => { const callbacks = { onBefore: jest.fn(), onStart: jest.fn(), @@ -643,10 +643,10 @@ describe('submit', () => { onSuccess: jest.fn(), onError: jest.fn(), onFinish: jest.fn(), - }; + } - const mockError = new Error('Test error'); - const mockRequest = jest.spyOn(axios, 'post').mockImplementation((url, data, config) => { + const mockError = new Error("Test error") + const mockRequest = jest.spyOn(axios, "post").mockImplementation((url, data, config) => { if(config?.onUploadProgress) { config.onUploadProgress({ loaded: 50, @@ -655,29 +655,29 @@ describe('submit', () => { bytes: 50, lengthComputable: true, percentage: 50, - }); + }) } - return Promise.reject(mockError); - }); + return Promise.reject(mockError) + }) - const { result } = renderHook(() => useInertiaForm(singleRootData)); + const { result } = renderHook(() => useInertiaForm(singleRootData)) - await act(async () => { - await result.current.submit('post', '/form', { + await act(async() => { + await result.current.submit("post", "/form", { async: true, ...callbacks, }) - }); + }) expect(mockRequest).toHaveBeenCalled() - expect(callbacks.onBefore).toHaveBeenCalled(); - expect(callbacks.onStart).toHaveBeenCalled(); - expect(callbacks.onProgress).toHaveBeenCalled(); - expect(callbacks.onError).toHaveBeenCalledWith(mockError); - expect(callbacks.onFinish).toHaveBeenCalled(); - expect(callbacks.onSuccess).not.toHaveBeenCalled(); - }); + expect(callbacks.onBefore).toHaveBeenCalled() + expect(callbacks.onStart).toHaveBeenCalled() + expect(callbacks.onProgress).toHaveBeenCalled() + expect(callbacks.onError).toHaveBeenCalledWith(mockError) + expect(callbacks.onFinish).toHaveBeenCalled() + expect(callbacks.onSuccess).not.toHaveBeenCalled() + }) }) }) diff --git a/tests/useInertiaInput.test.tsx b/tests/useInertiaInput.test.tsx index 841416a..6f475dd 100644 --- a/tests/useInertiaInput.test.tsx +++ b/tests/useInertiaInput.test.tsx @@ -1,11 +1,11 @@ -import { fireEvent, render, screen } from '@testing-library/react' -import '@testing-library/jest-dom' -import { Form, Input } from '../src' -import ContextTest from './components/ContextTest' - -describe ('useInertiaInput', () => { - describe('With defaultValue', () => { - it('builds the data object with default values from inputs', () => { +import { fireEvent, render, screen } from "@testing-library/react" +import "@testing-library/jest-dom" +import { Form, Input } from "../src" +import ContextTest from "./components/ContextTest" + +describe ("useInertiaInput", () => { + describe("With defaultValue", () => { + it("builds the data object with default values from inputs", () => { render(
@@ -14,55 +14,55 @@ describe ('useInertiaInput', () => {
, ) - const input = screen.getByRole('input') + const input = screen.getByRole("input") - expect(screen.getByTestId('data')).toHaveTextContent('{"values":{"name":"me"}}') + expect(screen.getByTestId("data")).toHaveTextContent("{\"values\":{\"name\":\"me\"}}") - fireEvent.change(input, { target: { value: 'value' } }) - expect(screen.getByTestId('data')).toHaveTextContent('{"values":{"name":"value"}}') + fireEvent.change(input, { target: { value: "value" } }) + expect(screen.getByTestId("data")).toHaveTextContent("{\"values\":{\"name\":\"value\"}}") }) }) - describe('With clearErrorsOnChange = true', () => { - it('clears errors on an input when the value changes ', () => { + describe("With clearErrorsOnChange = true", () => { + it("clears errors on an input when the value changes ", () => { render( -
- + + { - form.setError('errors.name', 'Error') + form.setError("errors.name", "Error") } } /> , ) - const input = screen.getByRole('input') + const input = screen.getByRole("input") - expect(screen.getByTestId('errors')).toHaveTextContent('{"errors.name":"Error"}') + expect(screen.getByTestId("errors")).toHaveTextContent("{\"errors.name\":\"Error\"}") - fireEvent.change(input, { target: { value: 'something' } }) - expect(screen.getByTestId('errors')).toHaveTextContent('{}') + fireEvent.change(input, { target: { value: "something" } }) + expect(screen.getByTestId("errors")).toHaveTextContent("{}") }) }) - describe('With clearErrorsOnChange = false', () => { - it('doesn\'t clear errors on an input when the value changes', () => { + describe("With clearErrorsOnChange = false", () => { + it("doesn't clear errors on an input when the value changes", () => { render( -
+ { - form.setError('errors.name', 'Error') + form.setError("errors.name", "Error") } } /> , ) - const input = screen.getByRole('input') + const input = screen.getByRole("input") - expect(screen.getByTestId('errors')).toHaveTextContent('{"errors.name":"Error"}') + expect(screen.getByTestId("errors")).toHaveTextContent("{\"errors.name\":\"Error\"}") - fireEvent.change(input, { target: { value: 'something' } }) - expect(screen.getByTestId('errors')).toHaveTextContent('{"errors.name":"Error"}') + fireEvent.change(input, { target: { value: "something" } }) + expect(screen.getByTestId("errors")).toHaveTextContent("{\"errors.name\":\"Error\"}") }) }) diff --git a/tests/utils/coerceArray.test.ts b/tests/utils/coerceArray.test.ts index 8db2659..2aa39f2 100644 --- a/tests/utils/coerceArray.test.ts +++ b/tests/utils/coerceArray.test.ts @@ -1,9 +1,9 @@ -import { coerceArray } from '../../src/utils' +import { coerceArray } from "../../src/utils" -describe('coerceArray', () => { - it('should return an array regardless of input', () => { - const nonArray = 'hello' - const array = ['one', 'two', 'three'] +describe("coerceArray", () => { + it("should return an array regardless of input", () => { + const nonArray = "hello" + const array = ["one", "two", "three"] const coerced1 = coerceArray(nonArray) const coerced2 = coerceArray(array) diff --git a/tests/utils/fillEmptyValues.test.ts b/tests/utils/fillEmptyValues.test.ts index 7448d8e..875697d 100644 --- a/tests/utils/fillEmptyValues.test.ts +++ b/tests/utils/fillEmptyValues.test.ts @@ -1,9 +1,9 @@ -import { fillEmptyValues } from '../../src/utils' +import { fillEmptyValues } from "../../src/utils" -describe('fillEmptyValues', () => { - it('should replace undefined or null values with empty strings', () => { +describe("fillEmptyValues", () => { + it("should replace undefined or null values with empty strings", () => { const sanitized = fillEmptyValues({ - one: 'one', + one: "one", two: undefined, three: null, nested: { @@ -13,12 +13,12 @@ describe('fillEmptyValues', () => { }) expect(sanitized).toMatchObject({ - one: 'one', - two: '', - three: '', + one: "one", + two: "", + three: "", nested: { - four: '', - five: '', + four: "", + five: "", }, }) }) diff --git a/tests/utils/isUnset.test.ts b/tests/utils/isUnset.test.ts index 7f95b9d..4f04445 100644 --- a/tests/utils/isUnset.test.ts +++ b/tests/utils/isUnset.test.ts @@ -1,8 +1,8 @@ import { isUnset } from "../../src/utils" -describe('isUnset', () => { - describe('numbers', () => { - it('should be false for any number', () => { +describe("isUnset", () => { + describe("numbers", () => { + it("should be false for any number", () => { expect(isUnset(0)).toBe(false) expect(isUnset(-0)).toBe(false) expect(isUnset(1)).toBe(false) @@ -11,53 +11,53 @@ describe('isUnset', () => { expect(isUnset(-985619874)).toBe(false) }) - it('should be true for NaN', () => { + it("should be true for NaN", () => { expect(isUnset(NaN)).toBe(true) }) }) - describe('strings', () => { - it('should be false for any non-empty string', () => { - expect(isUnset('string')).toBe(false) - expect(isUnset(' ')).toBe(false) + describe("strings", () => { + it("should be false for any non-empty string", () => { + expect(isUnset("string")).toBe(false) + expect(isUnset(" ")).toBe(false) expect(isUnset(`string literal ${1 + 1}`)).toBe(false) }) - it('should be true for empty strings', () => { - expect(isUnset('')).toBe(true) + it("should be true for empty strings", () => { + expect(isUnset("")).toBe(true) }) }) - describe('dates', () => { - it('should be false for any valid date object', () => { + describe("dates", () => { + it("should be false for any valid date object", () => { expect(isUnset(new Date())).toBe(false) }) - it('should be true for any invalid date object', () => { - expect(isUnset(new Date('not a date'))).toBe(true) + it("should be true for any invalid date object", () => { + expect(isUnset(new Date("not a date"))).toBe(true) }) }) - describe('booleans', () => { - it('should be false for true and false', () => { + describe("booleans", () => { + it("should be false for true and false", () => { expect(isUnset(true)).toBe(false) expect(isUnset(false)).toBe(false) }) - it('should be true if variable is uninitialized', () => { + it("should be true if variable is uninitialized", () => { let b: boolean expect(isUnset(b)).toBe(true) }) }) - it('should be true for any "empty" primitive or empty object', () => { + it("should be true for any \"empty\" primitive or empty object", () => { expect(isUnset(undefined)).toBe(true) expect(isUnset(null)).toBe(true) expect(isUnset([])).toBe(true) expect(isUnset({})).toBe(true) }) - it('should be false for any non-empty value', () => { + it("should be false for any non-empty value", () => { expect(isUnset({ key: "value" })).toBe(false) expect(isUnset(["one"])).toBe(false) expect(isUnset([1])).toBe(false) diff --git a/tests/utils/renameObjectWithAttributes.test.ts b/tests/utils/renameObjectWithAttributes.test.ts index b0de588..05ca2e5 100644 --- a/tests/utils/renameObjectWithAttributes.test.ts +++ b/tests/utils/renameObjectWithAttributes.test.ts @@ -1,32 +1,32 @@ -import { renameObjectWithAttributes } from '../../src/utils' +import { renameObjectWithAttributes } from "../../src/utils" const mockFormData = { person: { - first_name: 'Something', + first_name: "Something", user: { - username: 'something', + username: "something", }, contact: { emails: [ - { email: 'something@email.com' }, + { email: "something@email.com" }, ], }, }, } -describe('renameObjectWithAttributes', () => { - it('should append attributes to keys deeper than the first level which contain another object', () => { +describe("renameObjectWithAttributes", () => { + it("should append attributes to keys deeper than the first level which contain another object", () => { const data = renameObjectWithAttributes(mockFormData) expect(data).toMatchObject({ person: { - first_name: 'Something', + first_name: "Something", user_attributes: { - username: 'something', + username: "something", }, contact_attributes: { emails_attributes: [ - { email: 'something@email.com' }, + { email: "something@email.com" }, ], }, }, diff --git a/tests/utils/stripAttributes.test.ts b/tests/utils/stripAttributes.test.ts index 6a79ad3..eb3805a 100644 --- a/tests/utils/stripAttributes.test.ts +++ b/tests/utils/stripAttributes.test.ts @@ -1,14 +1,14 @@ -import { stripAttributes } from '../../src/utils' +import { stripAttributes } from "../../src/utils" -describe('stripAttributes', () => { - it('should remove _attributes from dot notation strings', () => { - const key = 'user.person_attributes.name' - expect(stripAttributes(key)).toEqual('user.person.name') +describe("stripAttributes", () => { + it("should remove _attributes from dot notation strings", () => { + const key = "user.person_attributes.name" + expect(stripAttributes(key)).toEqual("user.person.name") }) - it('should not remove the word attributes without the _ or not at the end of a segment', () => { - const key1 = 'user.attributes' - const key2 = 'user.manager_attributes_sorted' + it("should not remove the word attributes without the _ or not at the end of a segment", () => { + const key1 = "user.attributes" + const key2 = "user.manager_attributes_sorted" expect(stripAttributes(key1)).toEqual(key1) expect(stripAttributes(key2)).toEqual(key2) }) diff --git a/tests/utils/unsetCompact.test.ts b/tests/utils/unsetCompact.test.ts index dbc9a69..7dc81f0 100644 --- a/tests/utils/unsetCompact.test.ts +++ b/tests/utils/unsetCompact.test.ts @@ -1,179 +1,179 @@ -import { NestedObject } from '../../src/useInertiaForm' -import { unsetCompact } from '../../src/utils' +import { NestedObject } from "../../src/useInertiaForm" +import { unsetCompact } from "../../src/utils" const nestedData: NestedObject = { - one: 'one', + one: "one", two: { - three: 'three', + three: "three", four: [ - { five: 'five', six: 'six' }, - { seven: 'seven' }, - { five: 'eight', six: 'nine', ten: [ - { eleven: 'eleven', twelve: 'twelve' }, - { eleven: 'eleven', thirteen: 'thirteen' }, + { five: "five", six: "six" }, + { seven: "seven" }, + { five: "eight", six: "nine", ten: [ + { eleven: "eleven", twelve: "twelve" }, + { eleven: "eleven", thirteen: "thirteen" }, ] }, ], last: { - just: 'testing', + just: "testing", }, }, } -describe('unsetCompact', () => { - it('should delete the value of a nested object using dot notation', () => { +describe("unsetCompact", () => { + it("should delete the value of a nested object using dot notation", () => { const data = structuredClone(nestedData) - unsetCompact(data, 'one') - unsetCompact(data, 'two.three') + unsetCompact(data, "one") + unsetCompact(data, "two.three") expect(data).toEqual({ two: { four: [ - { five: 'five', six: 'six' }, - { seven: 'seven' }, - { five: 'eight', six: 'nine', ten: [ - { eleven: 'eleven', twelve: 'twelve' }, - { eleven: 'eleven', thirteen: 'thirteen' }, + { five: "five", six: "six" }, + { seven: "seven" }, + { five: "eight", six: "nine", ten: [ + { eleven: "eleven", twelve: "twelve" }, + { eleven: "eleven", thirteen: "thirteen" }, ] }, ], last: { - just: 'testing', + just: "testing", }, }, }) }) - it('should delete by array index, filtering out empty array elements', () => { + it("should delete by array index, filtering out empty array elements", () => { const data = structuredClone(nestedData) - unsetCompact(data, 'two.four[0]') - unsetCompact(data, 'two.four[1].ten[0]') + unsetCompact(data, "two.four[0]") + unsetCompact(data, "two.four[1].ten[0]") expect(data).toEqual({ - one: 'one', + one: "one", two: { - three: 'three', + three: "three", four: [ - { seven: 'seven' }, - { five: 'eight', six: 'nine', ten: [ - { eleven: 'eleven', thirteen: 'thirteen' }, + { seven: "seven" }, + { five: "eight", six: "nine", ten: [ + { eleven: "eleven", thirteen: "thirteen" }, ] }, ], last: { - just: 'testing', + just: "testing", }, }, }) }) - describe('recursively unsets array elements by key with empty array brackets', () => { - it('unsets all instances of a key', () => { + describe("recursively unsets array elements by key with empty array brackets", () => { + it("unsets all instances of a key", () => { const data = structuredClone(nestedData) - unsetCompact(data, 'two.four[].five') + unsetCompact(data, "two.four[].five") expect(data).toEqual({ - one: 'one', + one: "one", two: { - three: 'three', + three: "three", four: [ - { six: 'six' }, - { seven: 'seven' }, - { six: 'nine', ten: [ - { eleven: 'eleven', twelve: 'twelve' }, - { eleven: 'eleven', thirteen: 'thirteen' }, + { six: "six" }, + { seven: "seven" }, + { six: "nine", ten: [ + { eleven: "eleven", twelve: "twelve" }, + { eleven: "eleven", thirteen: "thirteen" }, ] }, ], last: { - just: 'testing', + just: "testing", }, }, }) }) - it('works with nested array objects', () => { + it("works with nested array objects", () => { const data = structuredClone(nestedData) - unsetCompact(data, 'two.four[].ten[].twelve') + unsetCompact(data, "two.four[].ten[].twelve") expect(data).toEqual({ - one: 'one', + one: "one", two: { - three: 'three', + three: "three", four: [ - { five: 'five', six: 'six' }, - { seven: 'seven' }, - { five: 'eight', six: 'nine', ten: [ - { eleven: 'eleven' }, - { eleven: 'eleven', thirteen: 'thirteen' }, + { five: "five", six: "six" }, + { seven: "seven" }, + { five: "eight", six: "nine", ten: [ + { eleven: "eleven" }, + { eleven: "eleven", thirteen: "thirteen" }, ] }, ], last: { - just: 'testing', + just: "testing", }, }, }) }) - it('works when an element is specified after an empty bracket', () => { + it("works when an element is specified after an empty bracket", () => { const data = structuredClone(nestedData) - unsetCompact(data, 'two.four[].ten[1].eleven') + unsetCompact(data, "two.four[].ten[1].eleven") expect(data).toEqual({ - one: 'one', + one: "one", two: { - three: 'three', + three: "three", four: [ - { five: 'five', six: 'six' }, - { seven: 'seven' }, - { five: 'eight', six: 'nine', ten: [ - { eleven: 'eleven', twelve: 'twelve' }, - { thirteen: 'thirteen' }, + { five: "five", six: "six" }, + { seven: "seven" }, + { five: "eight", six: "nine", ten: [ + { eleven: "eleven", twelve: "twelve" }, + { thirteen: "thirteen" }, ] }, ], last: { - just: 'testing', + just: "testing", }, }, }) }) - it('works when an empty bracket is specified after an element', () => { + it("works when an empty bracket is specified after an element", () => { const data = structuredClone(nestedData) - unsetCompact(data, 'two.four[2].ten[].eleven') + unsetCompact(data, "two.four[2].ten[].eleven") expect(data).toEqual({ - one: 'one', + one: "one", two: { - three: 'three', + three: "three", four: [ - { five: 'five', six: 'six' }, - { seven: 'seven' }, - { five: 'eight', six: 'nine', ten: [ - { twelve: 'twelve' }, - { thirteen: 'thirteen' }, + { five: "five", six: "six" }, + { seven: "seven" }, + { five: "eight", six: "nine", ten: [ + { twelve: "twelve" }, + { thirteen: "thirteen" }, ] }, ], last: { - just: 'testing', + just: "testing", }, }, }) }) - it('ignores trailing []', () => { + it("ignores trailing []", () => { const data = structuredClone(nestedData) - unsetCompact(data, 'two.four[2].ten[]') + unsetCompact(data, "two.four[2].ten[]") expect(data).toEqual({ - one: 'one', + one: "one", two: { - three: 'three', + three: "three", four: [ - { five: 'five', six: 'six' }, - { seven: 'seven' }, - { five: 'eight', six: 'nine' }, + { five: "five", six: "six" }, + { seven: "seven" }, + { five: "eight", six: "nine" }, ], last: { - just: 'testing', + just: "testing", }, }, }) From c9a8202175d6200e83b1e55704ae5df8737bef27 Mon Sep 17 00:00:00 2001 From: Avram Walden Date: Fri, 14 Mar 2025 16:54:44 -0700 Subject: [PATCH 2/4] =?UTF-8?q?chore:=20=F0=9F=A4=96=20changes=20project?= =?UTF-8?q?=20type=20to=20module?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- commitlint.config.js | 1 - commitlint.config.ts | 1 + eslint.config.ts | 148 +++++++++++++++++++++++++++++++ jest.config.js => jest.config.ts | 9 +- package.json | 9 +- tsconfig.build.json | 2 +- yarn.lock | 146 +++++++++++++++++++++++++++++- 7 files changed, 307 insertions(+), 9 deletions(-) delete mode 100644 commitlint.config.js create mode 100644 commitlint.config.ts create mode 100644 eslint.config.ts rename jest.config.js => jest.config.ts (71%) diff --git a/commitlint.config.js b/commitlint.config.js deleted file mode 100644 index 858aaa8..0000000 --- a/commitlint.config.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = { extends: ["@commitlint/config-conventional"] } diff --git a/commitlint.config.ts b/commitlint.config.ts new file mode 100644 index 0000000..d22dd07 --- /dev/null +++ b/commitlint.config.ts @@ -0,0 +1 @@ +export const extend = ["@commitlint/config-conventional"] diff --git a/eslint.config.ts b/eslint.config.ts new file mode 100644 index 0000000..ea89f8e --- /dev/null +++ b/eslint.config.ts @@ -0,0 +1,148 @@ +import type { Linter } from "eslint" +import { fixupPluginRules } from "@eslint/compat" +import stylistic from "@stylistic/eslint-plugin" +import reactHooksPlugin from "eslint-plugin-react-hooks" +import jsxA11yPlugin from "eslint-plugin-jsx-a11y" +import tsParser from "@typescript-eslint/parser" +import jsoncParser from "jsonc-eslint-parser" + +const ignores = [ + "dist/**/*", + ".vscode/**/*", + ".yarn/**/*", +] + +const config: Linter.FlatConfig[] = [ + // Typescript/Javascript files + { + ...stylistic.configs.customize({ + indent: "tab", + }), + + files: ["**/*.{js,jsx,ts,tsx}"], + ignores, + languageOptions: { + ecmaVersion: "latest", + sourceType: "module", + parser: tsParser, + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, + }, + settings: { + "react": { + version: "detect", + }, + "import/resolver": { + typescript: {}, + }, + "jsx-a11y": { + polymorphicPropName: "component", + }, + }, + plugins: { + "react-hooks": fixupPluginRules(reactHooksPlugin), + "jsx-a11y": jsxA11yPlugin, + "@stylistic": stylistic, + }, + rules: { + "react/jsx-uses-react": "off", + "react/react-in-jsx-scope": "off", + "@stylistic/indent": ["error", "tab", { + SwitchCase: 1, + VariableDeclarator: "first", + MemberExpression: 1, + ArrayExpression: 1, + ignoredNodes: [ + "TSTypeParameterInstantiation", + ], + }], + "@stylistic/brace-style": ["error", "1tbs", { + allowSingleLine: true, + }], + "@stylistic/object-curly-spacing": ["error", "always", { + objectsInObjects: true, + }], + "@stylistic/jsx-curly-spacing": ["error", { + when: "always", + children: true, + }], + "@stylistic/member-delimiter-style": ["error", { + multiline: { + delimiter: "none", + }, + singleline: { + delimiter: "comma", + }, + multilineDetection: "brackets", + }], + "@stylistic/jsx-one-expression-per-line": "off", + "@stylistic/keyword-spacing": ["error", { + after: true, + before: true, + overrides: { + if: { after: false }, + for: { after: false }, + while: { after: false }, + switch: { after: false }, + catch: { after: false }, + }, + }], + "@stylistic/comma-dangle": ["error", { + arrays: "always-multiline", + objects: "always-multiline", + imports: "always-multiline", + exports: "always-multiline", + functions: "only-multiline", + }], + "@stylistic/multiline-ternary": ["error", "always-multiline"], + "@stylistic/space-infix-ops": "error", + "@stylistic/space-unary-ops": ["error", { + words: true, + nonwords: false, + overrides: { + "!": false, + "!!": false, + }, + }], + "no-trailing-spaces": ["error", { + skipBlankLines: false, + ignoreComments: false, + }], + "no-unused-vars": ["warn", { + vars: "all", + args: "none", + }], + "eqeqeq": "error", + "no-console": "warn", + "eol-last": ["error", "always"], + ...reactHooksPlugin.configs.recommended.rules, + }, + }, + // Typescript declaration files + { + files: ["**/*.d.ts"], + ignores, + rules: { + "no-unused-vars": "off", + "@typescript-eslint/member-delimiter-style": "off", + "@stylistic/ts/indent": "off", + }, + }, + // Json files + { + files: ["**/*.json", "**/*.jsonc"], + ignores, + languageOptions: { + parser: jsoncParser, + }, + rules: { + "indent": ["error", 2, { ignoredNodes: ["Property"] }], + "@stylistic/no-multi-spaces": "off", + }, + }, +] + +export default config diff --git a/jest.config.js b/jest.config.ts similarity index 71% rename from jest.config.js rename to jest.config.ts index 99ab043..a3c37da 100644 --- a/jest.config.js +++ b/jest.config.ts @@ -1,4 +1,6 @@ -module.exports = { +import type { Config } from "jest" + +const config: Config = { preset: "ts-jest", clearMocks: true, testMatch: ["/tests/**/*.test.(ts|tsx)"], @@ -15,4 +17,9 @@ module.exports = { }], }, setupFilesAfterEnv: ["./jest.setup.ts"], + transformIgnorePatterns: [ + "/node_modules/(?!lodash-es)", + ], } + +export default config diff --git a/package.json b/package.json index 5c2c0c4..fa1317e 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "name": "use-inertia-form", "version": "4.5.0", "description": "Extra functionality for Inertia.js useForm hook", + "type": "module", "main": "dist/useInertiaForm.js", "cjs": "dist/useInertiaForm.cjs", "unpkg": "dist/useInertiaForm.umd.min.js", @@ -37,9 +38,9 @@ "lint:fix": "npm run lint -- --fix", "lint:types": "tsc --noEmit", "lint:all": "yarn lint && yarn lint:types", - "test": "NODE_NO_WARNINGS=1 jest --silent=false", - "test:watch": "NODE_NO_WARNINGS=1 jest --watch --silent=false", - "test:coverage": "NODE_NO_WARNINGS=1 jest --coverage", + "test": "NODE_NO_WARNINGS=1 jest --config jest.config.ts --silent=false", + "test:watch": "NODE_NO_WARNINGS=1 jest --config jest.config.ts --watch --silent=false", + "test:coverage": "NODE_NO_WARNINGS=1 jest --config jest.config.ts --coverage", "release": "semantic-release", "cz": "git-cz" }, @@ -68,6 +69,7 @@ "@testing-library/user-event": "^14.5.2", "@types/jest": "^29.5.14", "@types/lodash": "^4.17.14", + "@types/node": "^22.13.10", "@types/react": "^19.0.2", "@types/react-dom": "^19.0.2", "@typescript-eslint/eslint-plugin": "^8.19.0", @@ -109,6 +111,7 @@ "rollup-plugin-typescript2": "^0.36.0", "semantic-release": "^24.2.1", "ts-jest": "^29.2.5", + "ts-node": "^10.9.2", "typescript": "^5.7.2" }, "peerDependencies": { diff --git a/tsconfig.build.json b/tsconfig.build.json index 72dc2ea..9aeac65 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -3,6 +3,6 @@ "compilerOptions": { "removeComments": true, }, - "include": ["src"], + "include": ["src", "rollup.config.ts"], "exclude": ["node_modules", "dist", "tests", "**/__tests__/**"] } \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index d93e994..8f6fa2f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1638,6 +1638,15 @@ __metadata: languageName: node linkType: hard +"@cspotcode/source-map-support@npm:^0.8.0": + version: 0.8.1 + resolution: "@cspotcode/source-map-support@npm:0.8.1" + dependencies: + "@jridgewell/trace-mapping": "npm:0.3.9" + checksum: 10/b6e38a1712fab242c86a241c229cf562195aad985d0564bd352ac404be583029e89e93028ffd2c251d2c407ecac5fb0cbdca94a2d5c10f29ac806ede0508b3ff + languageName: node + linkType: hard + "@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0": version: 4.4.1 resolution: "@eslint-community/eslint-utils@npm:4.4.1" @@ -2132,7 +2141,7 @@ __metadata: languageName: node linkType: hard -"@jridgewell/resolve-uri@npm:^3.1.0": +"@jridgewell/resolve-uri@npm:^3.0.3, @jridgewell/resolve-uri@npm:^3.1.0": version: 3.1.2 resolution: "@jridgewell/resolve-uri@npm:3.1.2" checksum: 10/97106439d750a409c22c8bff822d648f6a71f3aa9bc8e5129efdc36343cd3096ddc4eeb1c62d2fe48e9bdd4db37b05d4646a17114ecebd3bbcacfa2de51c3c1d @@ -2163,6 +2172,16 @@ __metadata: languageName: node linkType: hard +"@jridgewell/trace-mapping@npm:0.3.9": + version: 0.3.9 + resolution: "@jridgewell/trace-mapping@npm:0.3.9" + dependencies: + "@jridgewell/resolve-uri": "npm:^3.0.3" + "@jridgewell/sourcemap-codec": "npm:^1.4.10" + checksum: 10/83deafb8e7a5ca98993c2c6eeaa93c270f6f647a4c0dc00deb38c9cf9b2d3b7bf15e8839540155247ef034a052c0ec4466f980bf0c9e2ab63b97d16c0cedd3ff + languageName: node + linkType: hard + "@jridgewell/trace-mapping@npm:^0.3.12, @jridgewell/trace-mapping@npm:^0.3.18, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25": version: 0.3.25 resolution: "@jridgewell/trace-mapping@npm:0.3.25" @@ -3342,6 +3361,34 @@ __metadata: languageName: node linkType: hard +"@tsconfig/node10@npm:^1.0.7": + version: 1.0.11 + resolution: "@tsconfig/node10@npm:1.0.11" + checksum: 10/51fe47d55fe1b80ec35e6e5ed30a13665fd3a531945350aa74a14a1e82875fb60b350c2f2a5e72a64831b1b6bc02acb6760c30b3738b54954ec2dea82db7a267 + languageName: node + linkType: hard + +"@tsconfig/node12@npm:^1.0.7": + version: 1.0.11 + resolution: "@tsconfig/node12@npm:1.0.11" + checksum: 10/5ce29a41b13e7897a58b8e2df11269c5395999e588b9a467386f99d1d26f6c77d1af2719e407621412520ea30517d718d5192a32403b8dfcc163bf33e40a338a + languageName: node + linkType: hard + +"@tsconfig/node14@npm:^1.0.0": + version: 1.0.3 + resolution: "@tsconfig/node14@npm:1.0.3" + checksum: 10/19275fe80c4c8d0ad0abed6a96dbf00642e88b220b090418609c4376e1cef81bf16237bf170ad1b341452feddb8115d8dd2e5acdfdea1b27422071163dc9ba9d + languageName: node + linkType: hard + +"@tsconfig/node16@npm:^1.0.2": + version: 1.0.4 + resolution: "@tsconfig/node16@npm:1.0.4" + checksum: 10/202319785901f942a6e1e476b872d421baec20cf09f4b266a1854060efbf78cde16a4d256e8bc949d31e6cd9a90f1e8ef8fb06af96a65e98338a2b6b0de0a0ff + languageName: node + linkType: hard + "@tufjs/canonical-json@npm:1.0.0": version: 1.0.0 resolution: "@tufjs/canonical-json@npm:1.0.0" @@ -3546,6 +3593,15 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:^22.13.10": + version: 22.13.10 + resolution: "@types/node@npm:22.13.10" + dependencies: + undici-types: "npm:~6.20.0" + checksum: 10/57dc6a5e0110ca9edea8d7047082e649fa7fa813f79e4a901653b9174141c622f4336435648baced5b38d9f39843f404fa2d8d7a10981610da26066bc8caab48 + languageName: node + linkType: hard + "@types/normalize-package-data@npm:^2.4.3": version: 2.4.4 resolution: "@types/normalize-package-data@npm:2.4.4" @@ -3814,7 +3870,7 @@ __metadata: languageName: node linkType: hard -"acorn-walk@npm:^8.0.2": +"acorn-walk@npm:^8.0.2, acorn-walk@npm:^8.1.1": version: 8.3.4 resolution: "acorn-walk@npm:8.3.4" dependencies: @@ -3832,6 +3888,15 @@ __metadata: languageName: node linkType: hard +"acorn@npm:^8.4.1": + version: 8.14.1 + resolution: "acorn@npm:8.14.1" + bin: + acorn: bin/acorn + checksum: 10/d1379bbee224e8d44c3c3946e6ba6973e999fbdd4e22e41c3455d7f9b6f72f7ce18d3dc218002e1e48eea789539cf1cb6d1430c81838c6744799c712fb557d92 + languageName: node + linkType: hard + "agent-base@npm:6, agent-base@npm:^6.0.2": version: 6.0.2 resolution: "agent-base@npm:6.0.2" @@ -4022,6 +4087,13 @@ __metadata: languageName: node linkType: hard +"arg@npm:^4.1.0": + version: 4.1.3 + resolution: "arg@npm:4.1.3" + checksum: 10/969b491082f20cad166649fa4d2073ea9e974a4e5ac36247ca23d2e5a8b3cb12d60e9ff70a8acfe26d76566c71fd351ee5e6a9a6595157eb36f92b1fd64e1599 + languageName: node + linkType: hard + "argparse@npm:^1.0.7": version: 1.0.10 resolution: "argparse@npm:1.0.10" @@ -5281,6 +5353,13 @@ __metadata: languageName: node linkType: hard +"create-require@npm:^1.1.0": + version: 1.1.1 + resolution: "create-require@npm:1.1.1" + checksum: 10/a9a1503d4390d8b59ad86f4607de7870b39cad43d929813599a23714831e81c520bddf61bcdd1f8e30f05fd3a2b71ae8538e946eb2786dc65c2bbc520f692eff + languageName: node + linkType: hard + "cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.6": version: 7.0.6 resolution: "cross-spawn@npm:7.0.6" @@ -5587,6 +5666,13 @@ __metadata: languageName: node linkType: hard +"diff@npm:^4.0.1": + version: 4.0.2 + resolution: "diff@npm:4.0.2" + checksum: 10/ec09ec2101934ca5966355a229d77afcad5911c92e2a77413efda5455636c4cf2ce84057e2d7715227a2eeeda04255b849bd3ae3a4dd22eb22e86e76456df069 + languageName: node + linkType: hard + "diff@npm:^5.1.0": version: 5.2.0 resolution: "diff@npm:5.2.0" @@ -9562,7 +9648,7 @@ __metadata: languageName: node linkType: hard -"make-error@npm:^1.3.6": +"make-error@npm:^1.1.1, make-error@npm:^1.3.6": version: 1.3.6 resolution: "make-error@npm:1.3.6" checksum: 10/b86e5e0e25f7f777b77fabd8e2cbf15737972869d852a22b7e73c17623928fccb826d8e46b9951501d3f20e51ad74ba8c59ed584f610526a48f8ccf88aaec402 @@ -13276,6 +13362,44 @@ __metadata: languageName: node linkType: hard +"ts-node@npm:^10.9.2": + version: 10.9.2 + resolution: "ts-node@npm:10.9.2" + dependencies: + "@cspotcode/source-map-support": "npm:^0.8.0" + "@tsconfig/node10": "npm:^1.0.7" + "@tsconfig/node12": "npm:^1.0.7" + "@tsconfig/node14": "npm:^1.0.0" + "@tsconfig/node16": "npm:^1.0.2" + acorn: "npm:^8.4.1" + acorn-walk: "npm:^8.1.1" + arg: "npm:^4.1.0" + create-require: "npm:^1.1.0" + diff: "npm:^4.0.1" + make-error: "npm:^1.1.1" + v8-compile-cache-lib: "npm:^3.0.1" + yn: "npm:3.1.1" + peerDependencies: + "@swc/core": ">=1.2.50" + "@swc/wasm": ">=1.2.50" + "@types/node": "*" + typescript: ">=2.7" + peerDependenciesMeta: + "@swc/core": + optional: true + "@swc/wasm": + optional: true + bin: + ts-node: dist/bin.js + ts-node-cwd: dist/bin-cwd.js + ts-node-esm: dist/bin-esm.js + ts-node-script: dist/bin-script.js + ts-node-transpile-only: dist/bin-transpile.js + ts-script: dist/bin-script-deprecated.js + checksum: 10/a91a15b3c9f76ac462f006fa88b6bfa528130dcfb849dd7ef7f9d640832ab681e235b8a2bc58ecde42f72851cc1d5d4e22c901b0c11aa51001ea1d395074b794 + languageName: node + linkType: hard + "tsconfig-paths@npm:^3.15.0": version: 3.15.0 resolution: "tsconfig-paths@npm:3.15.0" @@ -13682,6 +13806,7 @@ __metadata: "@testing-library/user-event": "npm:^14.5.2" "@types/jest": "npm:^29.5.14" "@types/lodash": "npm:^4.17.14" + "@types/node": "npm:^22.13.10" "@types/react": "npm:^19.0.2" "@types/react-dom": "npm:^19.0.2" "@typescript-eslint/eslint-plugin": "npm:^8.19.0" @@ -13723,6 +13848,7 @@ __metadata: rollup-plugin-typescript2: "npm:^0.36.0" semantic-release: "npm:^24.2.1" ts-jest: "npm:^29.2.5" + ts-node: "npm:^10.9.2" typescript: "npm:^5.7.2" peerDependencies: "@inertiajs/react": ^1.0.0 || ^2.0.0 @@ -13740,6 +13866,13 @@ __metadata: languageName: node linkType: hard +"v8-compile-cache-lib@npm:^3.0.1": + version: 3.0.1 + resolution: "v8-compile-cache-lib@npm:3.0.1" + checksum: 10/88d3423a52b6aaf1836be779cab12f7016d47ad8430dffba6edf766695e6d90ad4adaa3d8eeb512cc05924f3e246c4a4ca51e089dccf4402caa536b5e5be8961 + languageName: node + linkType: hard + "v8-to-istanbul@npm:^9.0.1": version: 9.3.0 resolution: "v8-to-istanbul@npm:9.3.0" @@ -14166,6 +14299,13 @@ __metadata: languageName: node linkType: hard +"yn@npm:3.1.1": + version: 3.1.1 + resolution: "yn@npm:3.1.1" + checksum: 10/2c487b0e149e746ef48cda9f8bad10fc83693cd69d7f9dcd8be4214e985de33a29c9e24f3c0d6bcf2288427040a8947406ab27f7af67ee9456e6b84854f02dd6 + languageName: node + linkType: hard + "yocto-queue@npm:^0.1.0": version: 0.1.0 resolution: "yocto-queue@npm:0.1.0" From ebf22bb19d1990e14addd501a2e72aa0feabb841 Mon Sep 17 00:00:00 2001 From: Avram Walden Date: Fri, 14 Mar 2025 17:04:01 -0700 Subject: [PATCH 3/4] =?UTF-8?q?chore:=20=F0=9F=A4=96=20cleans=20up=20file?= =?UTF-8?q?=20renames?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- eslint.config.mjs | 177 ------------------------- release.config.js => release.config.ts | 2 +- 2 files changed, 1 insertion(+), 178 deletions(-) delete mode 100644 eslint.config.mjs rename release.config.js => release.config.ts (92%) diff --git a/eslint.config.mjs b/eslint.config.mjs deleted file mode 100644 index cf952f5..0000000 --- a/eslint.config.mjs +++ /dev/null @@ -1,177 +0,0 @@ -import { fixupPluginRules } from '@eslint/compat' -import stylistic from '@stylistic/eslint-plugin' -import reactHooksPlugin from 'eslint-plugin-react-hooks' -import jsxA11yPlugin from 'eslint-plugin-jsx-a11y' -import jsoncPlugin from 'eslint-plugin-jsonc' -import tsParser from '@typescript-eslint/parser' -import jsoncParser from 'jsonc-eslint-parser' - -const ignores = [ - 'dist/**/*', - '.vscode/**/*', - '.yarn/**/*', -] - -export default [ - // Typescript/Javascript files - { - ...stylistic.configs.customize({ - indent: 'tab', - }), - - files: ['**/*.{js,jsx,ts,tsx}'], - ignores, - languageOptions: { - ecmaVersion: 'latest', - sourceType: 'module', - parser: tsParser, - parserOptions: { - ecmaFeatures: { - jsx: true, - }, - }, - }, - settings: { - 'react': { - version: 'detect', - }, - 'import/resolver': { - typescript: {}, - }, - 'jsx-a11y': { - polymorphicPropName: 'component', - }, - }, - plugins: { - 'react-hooks': fixupPluginRules(reactHooksPlugin), - 'jsx-a11y': jsxA11yPlugin, - '@stylistic': stylistic, - }, - rules: { - 'react/jsx-uses-react': 'off', - 'react/react-in-jsx-scope': 'off', - '@stylistic/indent': ['error', 'tab', { - SwitchCase: 1, - VariableDeclarator: 'first', - MemberExpression: 1, - ArrayExpression: 1, - ignoredNodes: [ - "TSTypeParameterInstantiation", - ], - }], - '@stylistic/brace-style': ['error', '1tbs', { - allowSingleLine: true, - }], - '@stylistic/object-curly-spacing': ['error', 'always', { - objectsInObjects: true, - }], - '@stylistic/jsx-curly-spacing': ['error', { - when: 'always', - children: true, - }], - '@stylistic/member-delimiter-style': ['error', { - multiline: { - delimiter: 'none', - }, - singleline: { - delimiter: 'comma', - }, - multilineDetection: 'brackets', - }], - '@stylistic/jsx-one-expression-per-line': 'off', - '@stylistic/keyword-spacing': ['error', { - after: true, - before: true, - overrides: { - if: { after: false }, - for: { after: false }, - while: { after: false }, - switch: { after: false }, - catch: { after: false }, - import: { after: true }, - export: { after: true }, - }, - }], - '@stylistic/comma-dangle': ['error', { - arrays: 'always-multiline', - objects: 'always-multiline', - imports: 'always-multiline', - exports: 'always-multiline', - functions: 'only-multiline', - }], - '@stylistic/multiline-ternary': ['error', 'always-multiline'], - '@stylistic/space-infix-ops': 'error', - '@stylistic/space-unary-ops': ['error', { - words: true, - nonwords: false, - overrides: { - '!': false, - '!!': false, - }, - }], - "@stylistic/semi": ["error", "never"], - "@stylistic/jsx-quotes": ["error", "prefer-double"], - "@stylistic/quotes": ["error", "double"], - "@stylistic/space-before-function-paren": ["error", "never"], - "@stylistic/arrow-spacing": "error", - "@stylistic/space-before-blocks": ["error", "always"], - "@stylistic/no-multiple-empty-lines": ["error", { - max: 2, - maxBOF: 0, - }], - "@stylistic/comma-spacing": ["error", { - before: false, - after: true, - }], - "@stylistic/no-multi-spaces": "error", - "@stylistic/spaced-comment": ["error", "always", { - "line": { - "markers": ["/"], - "exceptions": ["-", "+"], - }, - "block": { - "markers": ["!"], - "exceptions": ["*"], - "balanced": true, - }, - }], - 'no-trailing-spaces': ['error', { - skipBlankLines: false, - ignoreComments: false - }], - 'no-unused-vars': ['warn', { - vars: 'all', - args: 'none', - }], - 'eqeqeq': 'error', - 'no-console': 'warn', - 'eol-last': ['error', 'always'], - ...reactHooksPlugin.configs.recommended.rules, - }, - }, - // Typescript declaration files - { - files: ['**/*.d.ts'], - ignores, - rules: { - 'no-unused-vars': 'off', - '@typescript-eslint/member-delimiter-style': 'off', - '@stylistic/ts/indent': 'off', - }, - }, - // Json files - { - files: ['**/*.json', '**/*.jsonc'], - ignores, - plugins: { - jsonc: jsoncPlugin, - }, - languageOptions: { - parser: jsoncParser, - }, - rules: { - 'jsonc/indent': ['error', 2, { ignoredNodes: ['Property'] }], - '@stylistic/no-multi-spaces': 'off', - }, - }, -] diff --git a/release.config.js b/release.config.ts similarity index 92% rename from release.config.js rename to release.config.ts index e5eb043..601d7d8 100644 --- a/release.config.js +++ b/release.config.ts @@ -1,4 +1,4 @@ -module.exports = { +export default { "branches": ["main"], plugins: [ "@semantic-release/commit-analyzer", From 186a97952364646f2bfa8a6099b10e97658efc74 Mon Sep 17 00:00:00 2001 From: Avram Walden Date: Fri, 14 Mar 2025 17:09:29 -0700 Subject: [PATCH 4/4] =?UTF-8?q?chore:=20=F0=9F=A4=96=20eslint=20and=20roll?= =?UTF-8?q?up=20configs=20don't=20want=20to=20be=20ts=20files?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- eslint.config.ts => eslint.config.mjs | 3 +-- package.json | 2 +- yarn.lock | 10 +++++----- 3 files changed, 7 insertions(+), 8 deletions(-) rename eslint.config.ts => eslint.config.mjs (97%) diff --git a/eslint.config.ts b/eslint.config.mjs similarity index 97% rename from eslint.config.ts rename to eslint.config.mjs index ea89f8e..6300445 100644 --- a/eslint.config.ts +++ b/eslint.config.mjs @@ -1,4 +1,3 @@ -import type { Linter } from "eslint" import { fixupPluginRules } from "@eslint/compat" import stylistic from "@stylistic/eslint-plugin" import reactHooksPlugin from "eslint-plugin-react-hooks" @@ -12,7 +11,7 @@ const ignores = [ ".yarn/**/*", ] -const config: Linter.FlatConfig[] = [ +const config = [ // Typescript/Javascript files { ...stylistic.configs.customize({ diff --git a/package.json b/package.json index fa1317e..44e80d6 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "@babel/preset-typescript": "^7.26.0", "@commitlint/cli": "^19.6.1", "@commitlint/config-conventional": "^19.6.0", - "@eslint/compat": "^1.2.4", + "@eslint/compat": "^1.2.7", "@inertiajs/react": "^2.0.0", "@rollup/plugin-babel": "^6.0.4", "@rollup/plugin-commonjs": "^28.0.2", diff --git a/yarn.lock b/yarn.lock index 8f6fa2f..de59820 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1665,15 +1665,15 @@ __metadata: languageName: node linkType: hard -"@eslint/compat@npm:^1.2.4": - version: 1.2.4 - resolution: "@eslint/compat@npm:1.2.4" +"@eslint/compat@npm:^1.2.7": + version: 1.2.7 + resolution: "@eslint/compat@npm:1.2.7" peerDependencies: eslint: ^9.10.0 peerDependenciesMeta: eslint: optional: true - checksum: 10/872ac21e3f430575ba70916d83f5a4e7e9cc7fa953111c99ecef225d1ed05b66fbdb5034761dd9035f00c3f0d7ca7657f8cbfa4ff7ead3967f630c8c783d2beb + checksum: 10/fad83a195864d6718ce523acc30fd56c6cb0838394fc5ddb8f7a91031b1669bb5d8627d3e90bb2f86568b3c452ddcc22a90f0d15edd76dcccf4c49617cb567cb languageName: node linkType: hard @@ -13789,7 +13789,7 @@ __metadata: "@babel/preset-typescript": "npm:^7.26.0" "@commitlint/cli": "npm:^19.6.1" "@commitlint/config-conventional": "npm:^19.6.0" - "@eslint/compat": "npm:^1.2.4" + "@eslint/compat": "npm:^1.2.7" "@inertiajs/react": "npm:^2.0.0" "@rollup/plugin-babel": "npm:^6.0.4" "@rollup/plugin-commonjs": "npm:^28.0.2"