@stoker-platform/node-client 0.5.37 → 0.5.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundle.cjs +1 -1
- package/dist/bundle.js +1 -0
- package/package.json +3 -3
package/dist/bundle.cjs
CHANGED
|
@@ -11,4 +11,4 @@ ${i}`)}})()]),r.length>0)throw new Error(r.join(", "))},nr=async(n,e,t,s,r,i,o,a
|
|
|
11
11
|
<a href="${h}">${h}</a>`)}catch{throw await u(r,c),new Error(c)}}}return m.uid},rr=async(n,e)=>{const{labels:t,parentCollection:s}=e;if(s){const r=n.at(-2);if(!r)throw new Error("PERMISSION_DENIED");const i=[...n].slice(0,-2),o=await Qe(i,r).catch(()=>{throw new Error("PERMISSION_DENIED")}),a=o.Collection_Path;if(a.push(o.id),a.push(t.collection),!He(n,a))throw new Error("PERMISSION_DENIED")}else if(n.length>1)throw new Error("PERMISSION_DENIED")},Un=n=>n!==null&&typeof n=="object"&&!Array.isArray(n),qc=n=>{const e=t=>{Object.entries(t).forEach(([s,r])=>{Un(r)&&Object.keys(r).length===2&&typeof r.seconds=="number"&&typeof r.nanoseconds=="number"?t[s]=new B.Timestamp(r.seconds,r.nanoseconds):Un(r)&&e(r)})};e(n)},ir=n=>{const e=t=>{Object.entries(t).forEach(([s,r])=>{Un(r)&&Object.keys(r).length===2&&typeof r._seconds=="number"&&typeof r._nanoseconds=="number"?t[s]=new B.Timestamp(r._seconds,r._nanoseconds):Un(r)&&e(r)})};e(n)},Yn=n=>{if(typeof n=="object")for(const e in n)Object.prototype.hasOwnProperty.call(n,e)&&(n[e]==="_DELETE_FIELD"?n[e]=B.FieldValue.delete():Yn(n[e]))},Bc=(n,e,t)=>{if(X(t)&&t.includeFields){const s={};return t.includeFields.forEach(r=>{if(e[r]!==void 0){s[r]=e[r];const i=W(n.fields,r);gt(n,[i]).size===1&&(s[`${r}_Lowercase`]=e[`${r}_Lowercase`])}}),s}return{}},ii=async(n,e,t,s,r,i,o)=>{if(!X(t)||!t.enforceHierarchy)return;const{fields:a}=e,l=B.getFirestore(),c=Object.entries(s[t.name]);if(!c.length)throw new Error(`VALIDATION_ERROR: relation ${t.name} is required`);const[u,m]=c[0];if(!m)throw new Error(`VALIDATION_ERROR: Relation ${t.name} is required`);const d=Re(l,m.Collection_Path,n);if(i.size++,!o&&i.size>500)throw new Error("VALIDATION ERROR: The number of operations in the Firestore transaction has exceeded the limit of 500. This is likely due to a large number of unique field checks, entity restrictions (in permissions when dealing with user collections) or relation hierarchy checks.");const f=await r.get(d.doc(u));if(!f.exists)throw new Error(`VALIDATION_ERROR: Record ${u} not found in collection ${t.collection}`);const h=f.data(),v=W(a,t.enforceHierarchy.field),p=t.enforceHierarchy;if(!h[p.recordLinkField]||!s[v.name]||!Object.keys(s[v.name]).every(E=>Object.keys(h[p.recordLinkField]).includes(E)))throw new Error("VALIDATION_ERROR: Invalid relation hierarchy")},yn=async(n,e,t)=>{delete e[n.name][t],e[`${n.name}_Array`]=e[`${n.name}_Array`]?.filter(s=>s!==t),delete e[`${n.name}_Single`]},ms=async(n,e,t,s,r)=>{e[n.name]||={},e[n.name][s]=t,e[`${n.name}_Array`]||=[],e[`${n.name}_Array`].push(s),r&&(e[`${n.name}_Single`]=t)},Hc=(n,e,t,s,r,i)=>{const o=[],a=[];for(const l of s.fields)X(l)&&l.twoWay&&l.collection===t&&((n==="Create"||!i?.[l.name]?.[e])&&r[l.name]?.[e]&&o.push(l),n==="Update"&&i?.[l.name]?.[e]&&!r[l.name]?.[e]&&a.push(l));return{addedFields:o,removedFields:a}},ar=async(n,e,t,s,r,i,o,a,l,c,u,m)=>{const{fields:d}=i,f=B.getFirestore(),h=new Map,v=new Map,p=new Map;for(const E of d)X(E)&&["OneToOne","OneToMany"].includes(E.type)&&E.enforceHierarchy&&s[E.name]&&(n==="Create"||n==="Update"&&!He(m?.[E.name],s[E.name]))&&await ii(e,i,E,s,a,l);for(const E of d)if(X(E)&&E.twoWay){const O=o.collections[E.collection],R=W(O.fields,E.twoWay),x=ut(O,[R]);if(s[E.name]){const _=Object.entries(s[E.name]);for(const N of _){const[C,L]=N;if(n==="Create"||!m?.[E.name]?.[C]){let D;const y=p.get(E.collection)?.[C];if(y)D=y;else{l.size++,l&&l.size>500&&console.error(new Error(`VALIDATION_ERROR: ${l.size} operations in the Firestore transaction has exceeded the limit of 500. This is likely due to a large number of two way updates, unique field checks, entity restrictions (in permissions when dealing with user collections) or relation hierarchy checks.`));const w=Re(f,L.Collection_Path,e),H=await a.get(w.doc(C));if(!H.exists){yn(E,r,C);continue}const g=H.data();v.set(E.collection,{...v.get(E.collection)||{},[C]:g}),D=pe({...g,...bn(s)})}const k={...D[R.name],[t]:{Collection_Path:s.Collection_Path,...Bc(i,s,R)}};D[R.name]=k,D[`${R.name}_Array`]||=[],D[`${R.name}_Array`].push(t),x.size===1&&(D[`${R.name}_Single`]=k),p.set(E.collection,{...p.get(E.collection)||{},[C]:D})}}}if(n==="Update"){const _=Object.entries(m?.[E.name]||{});for(const N of _){const[C,L]=N;if(!s[E.name]?.[C]){let D;const y=p.get(E.collection)?.[C];if(y)D=y;else{l.size++,l&&l.size>500&&console.error(new Error(`VALIDATION_ERROR: ${l.size} operations in the Firestore transaction has exceeded the limit of 500. This is likely due to a large number of two way updates, unique field checks, entity restrictions (in permissions when dealing with user collections) or relation hierarchy checks.`));const k=Re(f,L.Collection_Path,e),w=await a.get(k.doc(C));if(!w.exists){h.set(E.name,[...h.get(E.name)||[],C]);continue}const H=w.data();v.set(E.collection,{...v.get(E.collection)||{},[C]:H}),D=pe({...H,...bn(s)})}D[R.name][t]&&delete D[R.name][t],Array.isArray(D[`${R.name}_Array`])&&(D[`${R.name}_Array`]=D[`${R.name}_Array`].filter(k=>k!==t)),x.size===1&&delete D[`${R.name}_Single`],p.set(E.collection,{...p.get(E.collection)||{},[C]:D})}}}}for(const[E,O]of p.entries()){const R=o.collections[E],x=qe(E,o);for(const[_,N]of Object.entries(O)){const{addedFields:C,removedFields:L}=Hc(n,_,E,i,s,m);if(c&&u){for(const D of C){const y=W(R.fields,D.twoWay);if(!cr(R,y,u)){yn(D,r,_);continue}}for(const D of L){const y=W(R.fields,D.twoWay),k=ut(R,[y]);if(!cr(R,y,u)){ms(D,r,m?.[D.name]?.[_],_,k.size===1);continue}}if(!it("Update",R,o,c,u,v.get(E)?.[_])){for(const D of C)yn(D,r,_);for(const D of L){const y=W(R.fields,D.twoWay),k=ut(R,[y]);ms(D,r,m?.[D.name]?.[_],_,k.size===1)}}if(!it("Update",R,o,c,u,N)){for(const D of C)yn(D,r,_);for(const D of L){const y=W(R.fields,D.twoWay),k=ut(R,[y]);ms(D,r,m?.[D.name]?.[_],_,k.size===1)}}}try{await nn("update",N,R,x,["update",N,{},void 0,N],o)}catch(D){throw new Error(`VALIDATION_ERROR: Two way relation update would invalidate record ${_} in ${E}: ${D.message}`)}for(const D of C){const y=W(R.fields,D.twoWay);["OneToOne","OneToMany"].includes(y.type)&&X(y)&&y.enforceHierarchy&&await ii(e,R,y,N,a,l,!0)}}}return h},Fa=(n,e,t)=>{n==="create"&&ht.forEach(s=>{if(!He(e[s],t[s]))throw new Error(`Updating system fields in hooks is not allowed: ${s}`)}),n==="update"&&(["id","Collection_Path","Created_At","Saved_At","Created_By"].forEach(s=>{if(s in e)throw new Error(`Cannot update system field: ${s}`)}),ht.forEach(s=>{if(!["id","Collection_Path","Created_At","Saved_At","Created_By"].includes(s)&&!He(e[s],t[s]))throw new Error(`Updating system fields in hooks is not allowed: ${s}`)}))},or=(n,e,t,s)=>{const{softDelete:r}=e;if(!r)return;const i=r?.archivedField,o=r?.timestampField;if(t[i]===!0)if(n==="create")t[o]=B.FieldValue.serverTimestamp();else{if(!s)throw new Error("Original record is required for update");if(!s[i])t[o]=B.FieldValue.serverTimestamp();else if(t[o]&&t[o]?.valueOf()!==s[o]?.valueOf())throw new Error("Soft delete timestamp cannot be changed")}},ps=async(n,e,t,s,r)=>{if(!Se("Read",r.collections?.[e.labels.collection]))return!1;try{await Qe([e.labels.collection],t,{user:s,providedTransaction:n})}catch{return!1}return!0},Gc=10,Yc=async(n,e)=>{if(n.length===0)return;const t=Math.min(e,n.length);let s=0;const r=async()=>{for(;s<n.length;){const i=s;s+=1,await n[i]()}};await Promise.all(Array.from({length:t},r))},$a=async(n,e,t,s,r,i,o)=>{for(const[a,l]of Object.entries(e?.collections||{})){if(!r.collections[a])throw new Error("PERMISSION_DENIED");const c=r.collections[a].access,u=r.collections[a];if(s.collections?.[a]?.restrictEntities||s?.collections?.[a]?.recordOwner?.active||s?.collections?.[a]?.recordUser?.active||s?.collections?.[a]?.recordProperty?.active){const d=i?.collections?.[a],f=[];if(l.individualEntities){const h=l.individualEntities,v=d?.individualEntities||[],p=i?h.filter(E=>!v.includes(E)):h;for(const E of p){if(o&&o.size++,o&&o.size>500)throw new Error("VALIDATION_ERROR: The number of operations in the Firestore transaction has exceeded the limit of 500. This is likely due to a large number of unique field checks or entity restrictions (in permissions when dealing with user collections).");f.push(async()=>{if(!await ps(n,u,E,t,s))throw new Error("PERMISSION_DENIED")})}}if(l.parentEntities){const h=c.entityRestrictions?.restrictions?.find(x=>x.type==="Parent"&&x.roles.some(_=>_.role===e.Role));if(!h)throw new Error("PERMISSION_DENIED");const v=W(u.fields,h.collectionField),p=r.collections[v.collection],E=l.parentEntities,O=d?.parentEntities||[],R=i?E.filter(x=>!O.includes(x)):E;for(const x of R){if(o&&o.size++,o&&o.size>500)throw new Error("VALIDATION_ERROR: The number of operations in the Firestore transaction has exceeded the limit of 500. This is likely due to a large number of unique field checks or entity restrictions (in permissions when dealing with user collections).");f.push(async()=>{if(!await ps(n,p,x,t,s))throw new Error("PERMISSION_DENIED")})}}if(l.parentPropertyEntities){const h=c.entityRestrictions?.restrictions?.find(R=>R.type==="Parent_Property"&&R.roles.some(x=>x.role===e.Role));if(!h)throw new Error("PERMISSION_DENIED");const v=W(u.fields,h.collectionField),p=r.collections[v.collection],E=l.parentPropertyEntities,O=d?.parentPropertyEntities||{};for(const[R,x]of Object.entries(E)){const _=O[R]||[],N=i?x.filter(C=>!_.includes(C)):x;for(const C of N){if(o&&o.size++,o&&o.size>500)throw new Error("VALIDATION_ERROR: The number of operations in the Firestore transaction has exceeded the limit of 500. This is likely due to a large number of unique field checks or entity restrictions (in permissions when dealing with user collections).");f.push(async()=>{if(!await ps(n,p,C,t,s))throw new Error("PERMISSION_DENIED")})}}}await Yc(f,Gc)}}},Jc=async(n,e,t,s,r,i,o)=>{const a=Ze(),l=Et();if(r?.providedTransaction&&s)throw new Error("PERMISSION_DENIED");if(r?.providedSchema&&s)throw new Error("PERMISSION_DENIED");let c=r?.providedSchema||await ze();if(n.length===0)throw new Error("EMPTY_PATH");const u=n.at(-1),m=Object.keys(c.collections).includes(u),d=l.disabledCollections?.includes(u);if(!m||d)throw new Error("COLLECTION_NOT_FOUND");const f=c.collections[u],{labels:h,fields:v,enableWriteLog:p,softDelete:E}=f,O=qe(h.collection,c),R=await ie(l.appName),x=B.getFirestore(),_=yt.getAuth(),C=(s?await _.getUser(s):void 0)?.customClaims?.role;let L;s&&await rr(n,f);const D=Re(x,n,a),y=o||D.doc().id;i=i||{},i.collection=h.collection,e.id=y,ir(e),Yn(e);const k=Vs("create",n,e,c,R,"Online",s||"System",B.Timestamp.now(),B.FieldValue.serverTimestamp());r?.createdAt&&(k.Created_At=r.createdAt),r?.createdBy&&(k.Created_By=r.createdBy);const w=pe(k);E&&(k[E.archivedField]=!1),Ve(e),p&&!r?.providedTransaction&&await pt("create","started",k,a,n,y,f),await ae("preOperation",l,O,["create",k,y,i]),await ae("preWrite",l,O,["create",k,y,i]),Tn(f,k,c),Sn(f,k),await io(k,f,O,C),Ve(k);try{if(f.auth&&t&&!t.password)throw new Error("Password is required");r?.providedTransaction||(await Ca("create",a,y,k,f,c),await nn("create",k,f,O,["create",k,i],c))}catch(I){throw new Error(`VALIDATION_ERROR: ${I.message}`)}Ve(k),e.id=y,E&&(k[E.archivedField]=!1),Tn(f,k,c),Sn(f,k);try{Fa("create",k,w),or("create",f,k),await nn("create",k,f,O,["create",k,i],c)}catch(I){throw new Error(`VALIDATION_ERROR: ${I.message}`)}if(s){const I=C;if(!I)throw new Error("USER_ERROR");if(!(O.custom?.serverAccess?.create!==void 0?await ie(O.custom.serverAccess.create,[I,k]):!0))throw new Error("PERMISSION_DENIED");for(const q of f.fields){if(!(q.name in k))continue;const b=Ae(q,O);if(b?.custom?.serverAccess?.create!==void 0&&!await ie(b.custom.serverAccess.create,[I,k]))throw new Error("PERMISSION_DENIED")}}t&&(t.permissions||={},t.permissions.Role||=k.Role,t.permissions.Enabled||=k.Enabled);const S=async(I,j)=>{const[q,b,M,Z]=await Promise.all([r?.providedTransaction?Promise.resolve({}):I.get(x.collection("system_deployment").doc("latest_deploy")),r?.providedTransaction?Promise.resolve({}):I.get(x.collection("system_deployment").doc("maintenance_mode")),s?I.get(x.collection("tenants").doc(a).collection("system_user_permissions").doc(s)):Promise.resolve({}),r?.providedSchema?Promise.resolve(r.providedSchema):ze()]);if(j&&(j.size+=3),!r?.providedTransaction){if(!q.exists)throw new Error("VERSION_ERROR");const K=q.data();if(K.force&&k.Last_Write_At.valueOf()<K.time.valueOf())throw new Error("VERSION_ERROR");if(!b.exists)throw new Error("MAINTENANCE_MODE");if(b.data().active)throw new Error("MAINTENANCE_MODE")}if(c=Z,s){if(!M?.exists)throw new Error("PERMISSION_DENIED");if(L=M.data(),!L.Role)throw new Error("USER_ERROR");if(!L.Enabled)throw new Error("PERMISSION_DENIED")}if(!r?.providedTransaction){const oe=v.filter(ue=>"unique"in ue&&ue.unique).map(async ue=>{if(!s||!ue.access||ue.access.includes(L.Role)){if(!e[ue.name])return;const he=Ae(ue,O);if(!(s&&he?.custom?.serverAccess?.read!==void 0?await ie(he.custom.serverAccess.read,[L?.Role,k]):!0))throw new Error("PERMISSION_DENIED");const me=e[ue.name].toString().toLowerCase().replace(/\s/g,"---").replaceAll("/","|||");if(Js(me)){if(j&&j.size++,j&&j.size>500)throw new Error("VALIDATION_ERROR: The number of operations in the Firestore transaction has exceeded the limit of 500. This is likely due to a large number of unique field checks.");if((await I.get(x.collection("tenants").doc(a).collection("system_unique").doc(h.collection).collection(`Unique-${h.collection}-${ue.name}`).doc(me)))?.exists)throw new Error(`VALIDATION_ERROR: ${ue.name} "${k[ue.name]}" already exists`)}else throw new Error(`VALIDATION_ERROR: ${ue.name} "${k[ue.name]}" is invalid`)}});await Promise.all(oe)}ur(k,y,f,c,s,L,t?.permissions),t?.permissions&&s&&L&&await $a(I,t.permissions,s,L,c),ur(k,y,f,c,s,L,t?.permissions)};if(f.auth&&t){await x.runTransaction(async j=>{await S(j)},{maxAttempts:10});const I=await sr(a,y,l,h.collection,k,t.permissions,t.password);k.User_ID=I}const T=async I=>{try{const j={size:1};await S(I,j),r?.noTwoWay||await ar("Create",a,y,k,k,f,c,I,j,s,L);const q=Ls(c);Ys("create",I,n,y,k,c,f,r,q,B.FieldValue.arrayUnion,B.FieldValue.arrayRemove,B.FieldValue.delete,b=>x.collection("tenants").doc(a).collection("system_fields").doc(h.collection).collection(`${h.collection}-${b.name}`).doc(y),(b,M)=>x.collection("tenants").doc(a).collection("system_unique").doc(h.collection).collection(`Unique-${h.collection}-${b.name}`).doc(M),b=>x.collection("tenants").doc(a).collection("system_fields").doc(h.collection).collection(`${h.collection}-${b}`).doc(y),(b,M)=>Re(x,b,a).doc(M),(b,M,Z)=>x.collection("tenants").doc(a).collection("system_fields").doc(b.collection).collection(`${b.collection}-${M}`).doc(Z),(b,M,Z)=>x.collection("tenants").doc(a).collection("system_fields").doc(b.collection).collection(`${b.collection}-${M.replaceAll(" ","-")}`).doc(Z),void 0,void 0,j),I.set(D.doc(y),k)}catch(j){if(r?.providedTransaction)throw j;{const b=await ae("postWriteError",l,O,["create",k,y,i,j]);if(p&&(await new Promise(M=>{setTimeout(M,250)}),await pt("create",b?.resolved?"success":"failed",k,a,n,y,f,b?.resolved?void 0:j)),!b?.resolved)throw f.auth&&t&&await Wt(k),j}}};if(r?.providedTransaction?await T(r.providedTransaction):await x.runTransaction(async I=>{await T(I)},{maxAttempts:10}),!r?.providedTransaction){const I=["create",k,y,i],j=[...I];await ae("postWrite",l,O,I),await ae("postOperation",l,O,j)}return{id:y,...k}},Jt=async(n,e,t,s)=>{const r=Ze(),i=yt.getAuth(),o=B.getFirestore(),a=e.customClaims||{};let l=!1;try{await i.updateUser(n,{email:e.email,disabled:e.disabled,displayName:e.displayName,photoURL:e.photoURL,emailVerified:!!e.emailVerified})}catch{l=!0}try{await i.setCustomUserClaims(n,{...a})}catch{l=!0}try{await o.collection("tenants").doc(r).collection("system_user_permissions").doc(n).update({...t,Collection:a.collection,Doc_ID:a.doc,Role:a.role,Enabled:!e.disabled})}catch{l=!0}if(l)throw new Error(`ROLLBACK_FAILED: ${s}`)},Ma=async(n,e,t,s,r,i,o,a,l,c,u)=>{const m=yt.getAuth(),d=B.getFirestore(),f=a?.customClaims||{},h="USER_ERROR";let v="";if(n==="create"){if(!u)throw new Error("VALIDATION_ERROR: Password is required");if(!l)throw new Error("VALIDATION_ERROR: Permissions are required");try{v=await sr(e,t,s,r,i,l,u)}catch(p){throw new Error(p.message)}}else if(n==="update"){if(!c||!a)throw new Error("USER_ERROR");const p={};if(o.Name!==i.Name&&(p.displayName=i.Name),o.Email!==i.Email&&(p.email=i.Email,p.emailVerified=!1),o.Photo_URL!==i.Photo_URL&&(p.photoURL=i.Photo_URL?i.Photo_URL:void 0),o.Enabled!==i.Enabled&&(p.disabled=!i.Enabled),u&&(p.password=u),Object.keys(p).length)try{await m.updateUser(o.User_ID,p),p.disabled===!0&&await m.revokeRefreshTokens(o.User_ID)}catch{throw await Jt(o.User_ID,a,c,h),new Error(h)}if(i.Role&&i.Role!==o.Role)try{await m.setCustomUserClaims(o.User_ID,{...f,role:i.Role}),await m.revokeRefreshTokens(o.User_ID)}catch{throw await Jt(o.User_ID,a,c,h),new Error(h)}try{await d.collection("tenants").doc(e).collection("system_user_permissions").doc(o.User_ID).set({...l||c,Collection:f.collection,Doc_ID:f.doc,Role:i.Role,Enabled:i.Enabled??o.Enabled??!1})}catch{throw await Jt(o.User_ID,a,c,h),new Error(h)}if(o.Email!==i.Email){const E=s.auth.enableMultiFactorAuth;if(E===!0||typeof E=="object"&&E.includes(i.Role)){let O=await m.generateEmailVerificationLink(i.Email).catch(()=>{throw new Error("Error generating email verification link")});if(O.includes("apiKey=&")){const R=JSON.parse(process.env.STOKER_FB_WEB_APP_CONFIG);O=O.replace("apiKey=&",`apiKey=${R.apiKey}&`)}if(O){const R=`https://${m.app.options.projectId}.firebaseapp.com/__/auth/action${O}`,x=await ie(s.appName),_=s?.mail?.emailVerification&&s.mail.emailVerification(R,x);try{await nr(i.Email,_?.subject||"Please verify your email address",void 0,_?.html||`Please verify your email address by clicking the link:
|
|
12
12
|
</br>
|
|
13
13
|
</br>
|
|
14
|
-
<a href="${R}">${R}</a>`)}catch{throw await Jt(o.User_ID,a,c,h),new Error(h)}}}}}else if(n==="delete")try{await Wt(o)}catch(p){throw new Error(p.message)}if(v)return v},Qc=async(n,e,t)=>{const s=Ze(),r=B.getFirestore(),i=[e];t&&t.trim()!==""&&i.push(t),i.sort();const o=[];for(const a of i){const l=r.collection("tenants").doc(s).collection("system_locks").doc(a);if((await n.get(l)).exists)throw new Error("DOCUMENT_LOCKED");o.push(l)}for(const a of o)n.set(a,{locked:!0})},ai=async(n,e)=>{const t=Ze(),s=B.getFirestore(),r=[n];e&&e.trim()!==""&&r.push(e),r.sort();const i=s.batch();for(const o of r){const a=s.collection("tenants").doc(t).collection("system_locks").doc(o);i.delete(a)}await i.commit()},Pa=async(n,e,t,s,r,i,o,a)=>{const l=Ze(),c=Et();if(i?.providedTransaction&&r)throw new Error("PERMISSION_DENIED");if(i?.providedSchema&&r)throw new Error("PERMISSION_DENIED");if(i?.providedTransaction&&!a)throw new Error("PERMISSION_DENIED");let u=i?.providedSchema||await ze(!0);if(n.length===0)throw new Error("EMPTY_PATH");const m=n.at(-1),d=Object.keys(u.collections).includes(m),f=c.disabledCollections?.includes(m);if(!d||f)throw new Error("COLLECTION_NOT_FOUND");const h=u.collections[m],{labels:v,fields:p,enableWriteLog:E}=h,O=qe(v.collection,u),R=await ie(c.appName),x=yt.getAuth(),_=B.getFirestore();let N;r&&await rr(n,h);const C=Re(_,n,l);o=o||{},o.collection=v.collection,a=a||await Qe(n,e,{user:r,noComputedFields:!0,noEmbeddingFields:!0});for(const b of p)b.type==="Computed"&&delete t[b.name];if(u={...u,collections:Object.fromEntries(Object.entries(u.collections).map(([b,M])=>[b,{...M,fields:M.fields.filter(Z=>Z.type!=="Computed")}]))},s&&!s.operation)throw new Error("VALIDATION_ERROR: User operation is required");if(s&&!h.auth)throw new Error("VALIDATION_ERROR: User operations are only permitted for auth collections");if(s?.operation==="delete"&&s.permissions)throw new Error("VALIDATION_ERROR: Permissions are not allowed for delete operations");const L=h.auth&&s?.operation==="create",D=h.auth&&s?.operation==="delete",y=h.auth&&!L&&!D&&(s?.operation==="update"||t.Role||t.Enabled!==void 0||t.Name||t.Email||t.Photo_URL),k=b=>b.User_ID&&(h.auth&&!L&&!D&&s?.operation==="update"||t.Role&&t.Role!==b.Role||t.Enabled!==void 0&&t.Enabled!==b.Enabled||t.Name&&t.Name!==b.Name||t.Email&&t.Email!==b.Email||t.Photo_URL&&t.Photo_URL!==b.Photo_URL);delete t.id,ir(t),Yn(t);const w=Vs("update",n,t,u,R,"Online",r||"System",B.Timestamp.now(),B.FieldValue.serverTimestamp()),H=pe(w);for(const b of p)!X(b)&&xe(w[b.name])&&b.nullable&&(w[b.name]=null);Ve(w),Ve(a),E&&!i?.providedTransaction&&await pt("update","started",w,l,n,e,h,void 0,a);const g=["update",w,e,o,void 0,pe(a)];await ae("preOperation",c,O,g);const S=["update",w,e,o,void 0,pe(a)];await ae("preWrite",c,O,S),Tn(h,w,u),Sn(h,w),Ve(w);try{if(L&&!s.password)throw new Error("Password is required");if(!i?.providedTransaction){const b={...a,...w};await Ca("update",l,e,b,h,u),nt(b),await nn("update",b,h,O,["update",w,o,void 0,pe(a)],u)}}catch(b){throw new Error(`VALIDATION_ERROR: ${b.message}`)}Ve(w),delete t.id,Tn(h,w,u),Sn(h,w);for(const b of p)!X(b)&&xe(w[b.name])&&b.nullable&&(w[b.name]=null);try{const b={...a,...w};nt(b),or("update",h,w,a),Fa("update",w,H),await nn("update",b,h,O,["update",w,o,void 0,a],u)}catch(b){throw new Error(`VALIDATION_ERROR: ${b.message}`)}let T;s&&(s.permissions||={});const F=async(b,M,Z)=>{const[K,oe,ue,he,Le]=await Promise.all([i?.providedTransaction?Promise.resolve({}):b.get(_.collection("system_deployment").doc("latest_deploy")),i?.providedTransaction?Promise.resolve({}):b.get(_.collection("system_deployment").doc("maintenance_mode")),i?.providedTransaction?Promise.resolve(a):Qe(n,e,{user:r,providedTransaction:b,noComputedFields:!0}),r?b.get(_.collection("tenants").doc(l).collection("system_user_permissions").doc(r)):Promise.resolve({}),i?.providedSchema?Promise.resolve(i.providedSchema):ze()]);if(Z&&(Z.size+=3),!i?.providedTransaction){if(!K.exists)throw new Error("VERSION_ERROR");const me=K.data();if(me.force&&w.Last_Write_At.valueOf()<me.time.valueOf())throw new Error("VERSION_ERROR");if(!oe.exists)throw new Error("MAINTENANCE_MODE");if(oe.data().active)throw new Error("MAINTENANCE_MODE")}if(!ue)throw new Error("NOT_FOUND");if(a=ue,u=Le,r){if(!he?.exists)throw new Error("PERMISSION_DENIED");if(N=he.data(),!N.Role)throw new Error("USER_ERROR");if(!N.Enabled)throw new Error("PERMISSION_DENIED")}if(Z&&(Z.size+=Xs(l,n,e,u,N).length),L&&a.User_ID||D&&!a.User_ID)throw new Error("USER_ERROR");if(k(a)){const me=await b.get(_.collection("tenants").doc(l).collection("system_user_permissions").doc(a.User_ID));if(Z&&Z.size++,!me?.exists)throw new Error("PERMISSION_DENIED");if(T=me.data(),s?.permissions){if(s.permissions.Role||=w.Role||a.Role,s.permissions.Enabled??=w.Enabled??a.Enabled,xe(s.permissions.Role))throw new Error("VALIDATION_ERROR: Role field is required");if(xe(s.permissions.Enabled))throw new Error("VALIDATION_ERROR: Enabled field is required")}}if(!i?.providedTransaction){const vt=p.filter(_e=>"unique"in _e&&_e.unique).map(async _e=>{if(!r||!_e.access||_e.access.includes(N.Role)){if(w[_e.name]===void 0||xe(w[_e.name]))return;const jt=Ae(_e,O),cn={...a,...w};if(!(r&&jt?.custom?.serverAccess?.read!==void 0?await ie(jt.custom.serverAccess.read,[N?.Role,cn]):!0))throw new Error("PERMISSION_DENIED");const Jn=w[_e.name].toString().toLowerCase().replace(/\s/g,"---").replaceAll("/","|||");if(Js(Jn)){if(Z&&Z.size++,Z&&Z.size>500)throw new Error("VALIDATION_ERROR: The number of operations in the Firestore transaction has exceeded the limit of 500. This is likely due to a large number of unique field checks.");const lr=await b.get(_.collection("tenants").doc(l).collection("system_unique").doc(v.collection).collection(`Unique-${v.collection}-${_e.name}`).doc(Jn));if(lr.exists&&lr.data().id!==e)throw new Error(`VALIDATION_ERROR: ${_e.name} "${w[_e.name]}" already exists`)}else throw new Error(`VALIDATION_ERROR: ${_e.name} "${w[_e.name]}" is invalid`)}});await Promise.all(vt)}if(r&&N?.Role){const me=N.Role,vt={...a,...w};if(!(O.custom?.serverAccess?.update!==void 0?await ie(O.custom.serverAccess.update,[me,vt,a]):!0))throw new Error("PERMISSION_DENIED");for(const jt of h.fields){const cn=Ae(jt,O);if(Object.prototype.hasOwnProperty.call(w,jt.name)&&cn?.custom?.serverAccess?.update!==void 0&&!await ie(cn.custom.serverAccess.update,[me,vt,a]))throw new Error("PERMISSION_DENIED")}}dr(w,a,e,h,u,r,N,s?.operation?s.operation:y?"update":void 0,s?.permissions,T),s?.permissions&&r&&N&&await $a(b,s.permissions,r,N,u,T,Z),dr(w,a,e,h,u,r,N,s?.operation?s.operation:y?"update":void 0,s?.permissions,T),M&&(L||k(a)||D)&&await Qc(b,e,a.User_ID)};(L||y||D)&&await _.runTransaction(async b=>{await F(b,!0)},{maxAttempts:10});const I=async(b,M)=>{if(!a)throw new Error("NOT_FOUND");try{const Z={size:1},K={...a,...w};await F(b,!1,Z);let oe;!i?.noTwoWay&&!i?.providedTransaction&&(oe=await ar("Update",l,e,K,w,h,u,b,Z,r,N,a));const ue=Ls(u);Ys("update",b,n,e,w,u,h,i,ue,B.FieldValue.arrayUnion,B.FieldValue.arrayRemove,B.FieldValue.delete,he=>_.collection("tenants").doc(l).collection("system_fields").doc(v.collection).collection(`${v.collection}-${he.name}`).doc(e),(he,Le)=>_.collection("tenants").doc(l).collection("system_unique").doc(v.collection).collection(`Unique-${v.collection}-${he.name}`).doc(Le),he=>_.collection("tenants").doc(l).collection("system_fields").doc(v.collection).collection(`${v.collection}-${he}`).doc(e),(he,Le)=>Re(_,he,l).doc(Le),(he,Le,me)=>_.collection("tenants").doc(l).collection("system_fields").doc(he.collection).collection(`${he.collection}-${Le}`).doc(me),(he,Le,me)=>_.collection("tenants").doc(l).collection("system_fields").doc(he.collection).collection(`${he.collection}-${Le.replaceAll(" ","-")}`).doc(me),a,oe,Z),b.update(C.doc(e),w)}catch(Z){if(i?.providedTransaction)throw Z;{const K=["update",w,e,o,Z,void 0,void 0,pe(a)],oe=await ae("postWriteError",c,O,K);if(E&&(await new Promise(ue=>{setTimeout(ue,250)}),await pt("update",oe?.resolved?"success":"failed",w,l,n,e,h,oe?.resolved?void 0:Z,a)),!oe?.resolved)throw L&&await Wt(a),k(a)&&await Jt(a.User_ID,M,T,"USER_ERROR"),D&&await _.collection("tenants").doc(l).collection(v.collection).doc(e).update({User_ID:B.FieldValue.delete()}),Z}}(L||k(a)||D)&&await ni(ai,[e,a.User_ID]).catch(()=>{throw new Error("USER_ERROR")})};try{let b;if(L||k(a)||D){if(k(a)){b=await x.getUser(a.User_ID);const K=b.customClaims;if(!(K&&K.role&&K.collection&&K.doc))throw new Error("USER_ERROR")}const M={...a,...w};nt(M);const Z=await Ma(s?.operation||"update",l,e,c,v.collection,M,a,b,s?.permissions,T,s?.password);L&&(w.User_ID=Z),D&&(w.User_ID=B.FieldValue.delete())}i?.providedTransaction?await I(i.providedTransaction,b):await _.runTransaction(async M=>{await I(M,b)},{maxAttempts:10})}catch(b){throw(L||k(a)||D)&&await ni(ai,[e,a.User_ID]).catch(()=>{throw new Error("USER_ERROR")}),b}if(!i?.providedTransaction){const b=["update",w,e,o,void 0,pe(a)],M=[...b];await ae("postWrite",c,O,b),await ae("postOperation",c,O,M)}const j={...a,...w};return nt(j),{id:e,...j}},Kc=async(n,e,t,s,r)=>{const i=Ze(),o=Et();let a=await ze();if(n.length===0)throw new Error("EMPTY_PATH");const l=n.at(-1),c=Object.keys(a.collections).includes(l),u=o.disabledCollections?.includes(l);if(!c||u)throw new Error("COLLECTION_NOT_FOUND");const m=a.collections[l],{labels:d,auth:f,enableWriteLog:h,softDelete:v}=m,p=qe(d.collection,a),E=await ie(o.appName);if(v&&!f&&!s?.force)return await Pa(n,e,{[v.archivedField]:!0,[v.timestampField]:B.FieldValue.serverTimestamp()},void 0,t);const O=B.getFirestore();let R;t&&await rr(n,m);const x=Re(O,n,i);r=r||{},r.collection=d.collection;const _=await Qe(n,e,{user:t});let N=Vs("delete",n,_,a,E,"Online",t||"System",B.Timestamp.now(),B.FieldValue.serverTimestamp());const C=bn(N);Ve(N),h&&await pt("delete","started",N,i,n,e,m),await ae("preOperation",o,p,["delete",N,e,r]),await ae("preWrite",o,p,["delete",N,e,r]),Ve(N);const y=async g=>{const[S,T,F,I]=await Promise.all([g.get(O.collection("system_deployment").doc("maintenance_mode")),Qe([d.collection],e,{user:t,providedTransaction:g}),t?g.get(O.collection("tenants").doc(i).collection("system_user_permissions").doc(t)):Promise.resolve({}),ze()]);if(!S.exists)throw new Error("MAINTENANCE_MODE");if(S.data().active)throw new Error("MAINTENANCE_MODE");if(!T)throw new Error("NOT_FOUND");if(N={...T,...C},a=I,t){if(!F?.exists)throw new Error("PERMISSION_DENIED");if(R=F.data(),!R.Role)throw new Error("USER_ERROR");if(!R.Enabled)throw new Error("PERMISSION_DENIED");Ya(N,e,m,a,t,R)}if(t&&R?.Role){const q=R.Role;if(!(p.custom?.serverAccess?.delete!==void 0?await ie(p.custom.serverAccess.delete,[q,N]):!0))throw new Error("PERMISSION_DENIED")}};m.auth&&(await O.runTransaction(async g=>{await y(g)},{maxAttempts:10}),N.User_ID&&await Wt(N));try{await O.runTransaction(async g=>{await y(g);const S=Ls(a);Ys("delete",g,n,e,N,a,m,s,S,B.FieldValue.arrayUnion,B.FieldValue.arrayRemove,B.FieldValue.delete,T=>O.collection("tenants").doc(i).collection("system_fields").doc(d.collection).collection(`${d.collection}-${T.name}`).doc(e),(T,F)=>O.collection("tenants").doc(i).collection("system_unique").doc(d.collection).collection(`Unique-${d.collection}-${T.name}`).doc(F),T=>O.collection("tenants").doc(i).collection("system_fields").doc(d.collection).collection(`${d.collection}-${T}`).doc(e),(T,F)=>Re(O,T,i).doc(F),(T,F,I)=>O.collection("tenants").doc(i).collection("system_fields").doc(T.collection).collection(`${T.collection}-${F}`).doc(I),(T,F,I)=>O.collection("tenants").doc(i).collection("system_fields").doc(T.collection).collection(`${T.collection}-${F.replaceAll(" ","-")}`).doc(I)),g.delete(x.doc(e))},{maxAttempts:10})}catch(g){const T=await ae("postWriteError",o,p,["delete",N,e,r,g]);if(h&&(await new Promise(F=>{setTimeout(F,250)}),await pt("delete",T?.resolved?"success":"failed",N,i,n,e,m,T?.resolved?void 0:g)),!T?.resolved)throw m.auth&&N.User_ID&&await O.collection("tenants").doc(i).collection(d.collection).doc(e).update({User_ID:B.FieldValue.delete()}),g}const k=["delete",N,e,r],w=[...k];return await ae("postWrite",o,p,k),await ae("postOperation",o,p,w),{id:e,...N}},Xc=async(n,e)=>{const t=B.getFirestore(),s=Qs(),r=process.env.ADMIN_SMS;if(s==="development")if(r)n=r;else throw new Error("Admin phone not set");const i={to:n,body:e};await t.collection("system_messages").add(i)},eu=n=>n!==null&&typeof n=="object",tu=n=>{const e=t=>{Object.entries(t).forEach(([s,r])=>{r instanceof B.Timestamp?t[s]={_seconds:r.seconds,_nanoseconds:r.nanoseconds}:eu(r)&&e(r)})};e(n)},nu=async n=>await yt.getAuth().getUser(n),su=n=>{const e=Ks();return V.fromJSDate(n).setZone(e)},La=n=>{const e=Ks();return V.fromJSDate(n.toDate()).setZone(e)},ru=(n,e)=>{const s=V.fromJSDate(n,{zone:e}).offset,i=V.fromJSDate(n).offset,o=s-i;return V.fromJSDate(n).plus({minutes:o}).toJSDate()},iu=(n,e)=>{const s=V.fromJSDate(n,{zone:e}).offset,i=V.fromJSDate(n).offset,o=s-i;return V.fromJSDate(n).minus({minutes:o}).toJSDate()},au=n=>"seconds"in n&&"nanoseconds"in n?La(new B.Timestamp(n.seconds,n.nanoseconds)).toFormat("MMMM d, yyyy '@' h:mm a"):"";exports.addRecord=Jc;exports.addUser=sr;exports.convertDateToTimezone=su;exports.convertTimestampToTimezone=La;exports.deleteRecord=Kc;exports.deleteUser=Wt;exports.deserializeDeleteSentinels=Yn;exports.deserializeTimestamps=ir;exports.deserializeTimestampsWithoutUnderscores=qc;exports.displayDate=au;exports.fetchCurrentSchema=ze;exports.fetchLastSchema=Zc;exports.getCachedConfigValue=to;exports.getCollectionRefs=xa;exports.getCustomizationFile=qe;exports.getCustomizationFiles=Ta;exports.getDocumentRefs=Xs;exports.getFirestorePathRef=Re;exports.getGlobalConfigModule=Et;exports.getInputSchema=Mc;exports.getMaintenanceInfo=Wc;exports.getMode=Qs;exports.getOne=Qe;exports.getSome=tr;exports.getTenant=Ze;exports.getTimezone=Ks;exports.getUser=nu;exports.getVersionInfo=Uc;exports.getZodSchema=Oi;exports.initializeFirebase=zc;exports.initializeStoker=Lc;exports.isDeleteSentinel=xe;exports.keepTimezone=ru;exports.removeTimezone=iu;exports.runChildProcess=jc;exports.sendMail=nr;exports.sendMessage=Xc;exports.serializeTimestamps=tu;exports.setTenant=Vc;exports.tryPromise=ie;exports.updateRecord=Pa;exports.updateUser=Ma;exports.validateRelations=ar;exports.validateSoftDelete=or;exports.writeLog=pt;
|
|
14
|
+
<a href="${R}">${R}</a>`)}catch{throw await Jt(o.User_ID,a,c,h),new Error(h)}}}}}else if(n==="delete")try{await Wt(o)}catch(p){throw new Error(p.message)}if(v)return v},Qc=async(n,e,t)=>{const s=Ze(),r=B.getFirestore(),i=[e];t&&t.trim()!==""&&i.push(t),i.sort();const o=[];for(const a of i){const l=r.collection("tenants").doc(s).collection("system_locks").doc(a);if((await n.get(l)).exists)throw new Error("DOCUMENT_LOCKED");o.push(l)}for(const a of o)n.set(a,{locked:!0})},ai=async(n,e)=>{const t=Ze(),s=B.getFirestore(),r=[n];e&&e.trim()!==""&&r.push(e),r.sort();const i=s.batch();for(const o of r){const a=s.collection("tenants").doc(t).collection("system_locks").doc(o);i.delete(a)}await i.commit()},Pa=async(n,e,t,s,r,i,o,a)=>{const l=Ze(),c=Et();if(i?.providedTransaction&&r)throw new Error("PERMISSION_DENIED");if(i?.providedSchema&&r)throw new Error("PERMISSION_DENIED");if(i?.providedTransaction&&!a)throw new Error("PERMISSION_DENIED");let u=i?.providedSchema||await ze(!0);if(n.length===0)throw new Error("EMPTY_PATH");const m=n.at(-1),d=Object.keys(u.collections).includes(m),f=c.disabledCollections?.includes(m);if(!d||f)throw new Error("COLLECTION_NOT_FOUND");const h=u.collections[m],{labels:v,fields:p,enableWriteLog:E}=h,O=qe(v.collection,u),R=await ie(c.appName),x=yt.getAuth(),_=B.getFirestore();let N;r&&await rr(n,h);const C=Re(_,n,l);o=o||{},o.collection=v.collection,a=a||await Qe(n,e,{user:r,noComputedFields:!0,noEmbeddingFields:!0});for(const b of p)b.type==="Computed"&&delete t[b.name];if(u={...u,collections:Object.fromEntries(Object.entries(u.collections).map(([b,M])=>[b,{...M,fields:M.fields.filter(Z=>Z.type!=="Computed")}]))},s&&!s.operation)throw new Error("VALIDATION_ERROR: User operation is required");if(s&&!h.auth)throw new Error("VALIDATION_ERROR: User operations are only permitted for auth collections");if(s?.operation==="delete"&&s.permissions)throw new Error("VALIDATION_ERROR: Permissions are not allowed for delete operations");const L=h.auth&&s?.operation==="create",D=h.auth&&s?.operation==="delete",y=h.auth&&!L&&!D&&(s?.operation==="update"||t.Role||t.Enabled!==void 0||t.Name||t.Email||t.Photo_URL),k=b=>b.User_ID&&(h.auth&&!L&&!D&&s?.operation==="update"||t.Role&&t.Role!==b.Role||t.Enabled!==void 0&&t.Enabled!==b.Enabled||t.Name&&t.Name!==b.Name||t.Email&&t.Email!==b.Email||t.Photo_URL&&t.Photo_URL!==b.Photo_URL);delete t.id,ir(t),Yn(t);const w=Vs("update",n,t,u,R,"Online",r||"System",B.Timestamp.now(),B.FieldValue.serverTimestamp()),H=pe(w);for(const b of p)!X(b)&&xe(w[b.name])&&b.nullable&&(w[b.name]=null);Ve(w),Ve(a),E&&!i?.providedTransaction&&await pt("update","started",w,l,n,e,h,void 0,a);const g=["update",w,e,o,void 0,pe(a)];await ae("preOperation",c,O,g);const S=["update",w,e,o,void 0,pe(a)];await ae("preWrite",c,O,S),Tn(h,w,u),Sn(h,w),Ve(w);try{if(L&&!s.password)throw new Error("Password is required");if(!i?.providedTransaction){const b={...a,...w};await Ca("update",l,e,b,h,u),nt(b),await nn("update",b,h,O,["update",w,o,void 0,pe(a)],u)}}catch(b){throw new Error(`VALIDATION_ERROR: ${b.message}`)}Ve(w),delete t.id,Tn(h,w,u),Sn(h,w);for(const b of p)!X(b)&&xe(w[b.name])&&b.nullable&&(w[b.name]=null);try{const b={...a,...w};nt(b),or("update",h,w,a),Fa("update",w,H),await nn("update",b,h,O,["update",w,o,void 0,a],u)}catch(b){throw new Error(`VALIDATION_ERROR: ${b.message}`)}let T;s&&(s.permissions||={});const F=async(b,M,Z)=>{const[K,oe,ue,he,Le]=await Promise.all([i?.providedTransaction?Promise.resolve({}):b.get(_.collection("system_deployment").doc("latest_deploy")),i?.providedTransaction?Promise.resolve({}):b.get(_.collection("system_deployment").doc("maintenance_mode")),i?.providedTransaction?Promise.resolve(a):Qe(n,e,{user:r,providedTransaction:b,noComputedFields:!0}),r?b.get(_.collection("tenants").doc(l).collection("system_user_permissions").doc(r)):Promise.resolve({}),i?.providedSchema?Promise.resolve(i.providedSchema):ze()]);if(Z&&(Z.size+=3),!i?.providedTransaction){if(!K.exists)throw new Error("VERSION_ERROR");const me=K.data();if(me.force&&w.Last_Write_At.valueOf()<me.time.valueOf())throw new Error("VERSION_ERROR");if(!oe.exists)throw new Error("MAINTENANCE_MODE");if(oe.data().active)throw new Error("MAINTENANCE_MODE")}if(!ue)throw new Error("NOT_FOUND");if(a=ue,u=Le,r){if(!he?.exists)throw new Error("PERMISSION_DENIED");if(N=he.data(),!N.Role)throw new Error("USER_ERROR");if(!N.Enabled)throw new Error("PERMISSION_DENIED")}if(Z&&(Z.size+=Xs(l,n,e,u,N).length),L&&a.User_ID||D&&!a.User_ID)throw new Error("USER_ERROR");if(k(a)){const me=await b.get(_.collection("tenants").doc(l).collection("system_user_permissions").doc(a.User_ID));if(Z&&Z.size++,!me?.exists)throw new Error("PERMISSION_DENIED");if(T=me.data(),s?.permissions){if(s.permissions.Role||=w.Role||a.Role,s.permissions.Enabled??=w.Enabled??a.Enabled,xe(s.permissions.Role))throw new Error("VALIDATION_ERROR: Role field is required");if(xe(s.permissions.Enabled))throw new Error("VALIDATION_ERROR: Enabled field is required")}}if(!i?.providedTransaction){const vt=p.filter(_e=>"unique"in _e&&_e.unique).map(async _e=>{if(!r||!_e.access||_e.access.includes(N.Role)){if(w[_e.name]===void 0||xe(w[_e.name]))return;const jt=Ae(_e,O),cn={...a,...w};if(!(r&&jt?.custom?.serverAccess?.read!==void 0?await ie(jt.custom.serverAccess.read,[N?.Role,cn]):!0))throw new Error("PERMISSION_DENIED");const Jn=w[_e.name].toString().toLowerCase().replace(/\s/g,"---").replaceAll("/","|||");if(Js(Jn)){if(Z&&Z.size++,Z&&Z.size>500)throw new Error("VALIDATION_ERROR: The number of operations in the Firestore transaction has exceeded the limit of 500. This is likely due to a large number of unique field checks.");const lr=await b.get(_.collection("tenants").doc(l).collection("system_unique").doc(v.collection).collection(`Unique-${v.collection}-${_e.name}`).doc(Jn));if(lr.exists&&lr.data().id!==e)throw new Error(`VALIDATION_ERROR: ${_e.name} "${w[_e.name]}" already exists`)}else throw new Error(`VALIDATION_ERROR: ${_e.name} "${w[_e.name]}" is invalid`)}});await Promise.all(vt)}if(r&&N?.Role){const me=N.Role,vt={...a,...w};if(!(O.custom?.serverAccess?.update!==void 0?await ie(O.custom.serverAccess.update,[me,vt,a]):!0))throw new Error("PERMISSION_DENIED");for(const jt of h.fields){const cn=Ae(jt,O);if(Object.prototype.hasOwnProperty.call(w,jt.name)&&cn?.custom?.serverAccess?.update!==void 0&&!await ie(cn.custom.serverAccess.update,[me,vt,a]))throw new Error("PERMISSION_DENIED")}}dr(w,a,e,h,u,r,N,s?.operation?s.operation:y?"update":void 0,s?.permissions,T),s?.permissions&&r&&N&&await $a(b,s.permissions,r,N,u,T,Z),dr(w,a,e,h,u,r,N,s?.operation?s.operation:y?"update":void 0,s?.permissions,T),M&&(L||k(a)||D)&&await Qc(b,e,a.User_ID)};(L||y||D)&&await _.runTransaction(async b=>{await F(b,!0)},{maxAttempts:10});const I=async(b,M)=>{if(!a)throw new Error("NOT_FOUND");try{const Z={size:1},K={...a,...w};await F(b,!1,Z);let oe;!i?.noTwoWay&&!i?.providedTransaction&&(oe=await ar("Update",l,e,K,w,h,u,b,Z,r,N,a));const ue=Ls(u);Ys("update",b,n,e,w,u,h,i,ue,B.FieldValue.arrayUnion,B.FieldValue.arrayRemove,B.FieldValue.delete,he=>_.collection("tenants").doc(l).collection("system_fields").doc(v.collection).collection(`${v.collection}-${he.name}`).doc(e),(he,Le)=>_.collection("tenants").doc(l).collection("system_unique").doc(v.collection).collection(`Unique-${v.collection}-${he.name}`).doc(Le),he=>_.collection("tenants").doc(l).collection("system_fields").doc(v.collection).collection(`${v.collection}-${he}`).doc(e),(he,Le)=>Re(_,he,l).doc(Le),(he,Le,me)=>_.collection("tenants").doc(l).collection("system_fields").doc(he.collection).collection(`${he.collection}-${Le}`).doc(me),(he,Le,me)=>_.collection("tenants").doc(l).collection("system_fields").doc(he.collection).collection(`${he.collection}-${Le.replaceAll(" ","-")}`).doc(me),a,oe,Z),b.update(C.doc(e),w)}catch(Z){if(i?.providedTransaction)throw Z;{const K=["update",w,e,o,Z,void 0,void 0,void 0,pe(a)],oe=await ae("postWriteError",c,O,K);if(E&&(await new Promise(ue=>{setTimeout(ue,250)}),await pt("update",oe?.resolved?"success":"failed",w,l,n,e,h,oe?.resolved?void 0:Z,a)),!oe?.resolved)throw L&&await Wt(a),k(a)&&await Jt(a.User_ID,M,T,"USER_ERROR"),D&&await _.collection("tenants").doc(l).collection(v.collection).doc(e).update({User_ID:B.FieldValue.delete()}),Z}}(L||k(a)||D)&&await ni(ai,[e,a.User_ID]).catch(()=>{throw new Error("USER_ERROR")})};try{let b;if(L||k(a)||D){if(k(a)){b=await x.getUser(a.User_ID);const K=b.customClaims;if(!(K&&K.role&&K.collection&&K.doc))throw new Error("USER_ERROR")}const M={...a,...w};nt(M);const Z=await Ma(s?.operation||"update",l,e,c,v.collection,M,a,b,s?.permissions,T,s?.password);L&&(w.User_ID=Z),D&&(w.User_ID=B.FieldValue.delete())}i?.providedTransaction?await I(i.providedTransaction,b):await _.runTransaction(async M=>{await I(M,b)},{maxAttempts:10})}catch(b){throw(L||k(a)||D)&&await ni(ai,[e,a.User_ID]).catch(()=>{throw new Error("USER_ERROR")}),b}if(!i?.providedTransaction){const b=["update",w,e,o,void 0,pe(a)],M=[...b];await ae("postWrite",c,O,b),await ae("postOperation",c,O,M)}const j={...a,...w};return nt(j),{id:e,...j}},Kc=async(n,e,t,s,r)=>{const i=Ze(),o=Et();let a=await ze();if(n.length===0)throw new Error("EMPTY_PATH");const l=n.at(-1),c=Object.keys(a.collections).includes(l),u=o.disabledCollections?.includes(l);if(!c||u)throw new Error("COLLECTION_NOT_FOUND");const m=a.collections[l],{labels:d,auth:f,enableWriteLog:h,softDelete:v}=m,p=qe(d.collection,a),E=await ie(o.appName);if(v&&!f&&!s?.force)return await Pa(n,e,{[v.archivedField]:!0,[v.timestampField]:B.FieldValue.serverTimestamp()},void 0,t);const O=B.getFirestore();let R;t&&await rr(n,m);const x=Re(O,n,i);r=r||{},r.collection=d.collection;const _=await Qe(n,e,{user:t});let N=Vs("delete",n,_,a,E,"Online",t||"System",B.Timestamp.now(),B.FieldValue.serverTimestamp());const C=bn(N);Ve(N),h&&await pt("delete","started",N,i,n,e,m),await ae("preOperation",o,p,["delete",N,e,r]),await ae("preWrite",o,p,["delete",N,e,r]),Ve(N);const y=async g=>{const[S,T,F,I]=await Promise.all([g.get(O.collection("system_deployment").doc("maintenance_mode")),Qe([d.collection],e,{user:t,providedTransaction:g}),t?g.get(O.collection("tenants").doc(i).collection("system_user_permissions").doc(t)):Promise.resolve({}),ze()]);if(!S.exists)throw new Error("MAINTENANCE_MODE");if(S.data().active)throw new Error("MAINTENANCE_MODE");if(!T)throw new Error("NOT_FOUND");if(N={...T,...C},a=I,t){if(!F?.exists)throw new Error("PERMISSION_DENIED");if(R=F.data(),!R.Role)throw new Error("USER_ERROR");if(!R.Enabled)throw new Error("PERMISSION_DENIED");Ya(N,e,m,a,t,R)}if(t&&R?.Role){const q=R.Role;if(!(p.custom?.serverAccess?.delete!==void 0?await ie(p.custom.serverAccess.delete,[q,N]):!0))throw new Error("PERMISSION_DENIED")}};m.auth&&(await O.runTransaction(async g=>{await y(g)},{maxAttempts:10}),N.User_ID&&await Wt(N));try{await O.runTransaction(async g=>{await y(g);const S=Ls(a);Ys("delete",g,n,e,N,a,m,s,S,B.FieldValue.arrayUnion,B.FieldValue.arrayRemove,B.FieldValue.delete,T=>O.collection("tenants").doc(i).collection("system_fields").doc(d.collection).collection(`${d.collection}-${T.name}`).doc(e),(T,F)=>O.collection("tenants").doc(i).collection("system_unique").doc(d.collection).collection(`Unique-${d.collection}-${T.name}`).doc(F),T=>O.collection("tenants").doc(i).collection("system_fields").doc(d.collection).collection(`${d.collection}-${T}`).doc(e),(T,F)=>Re(O,T,i).doc(F),(T,F,I)=>O.collection("tenants").doc(i).collection("system_fields").doc(T.collection).collection(`${T.collection}-${F}`).doc(I),(T,F,I)=>O.collection("tenants").doc(i).collection("system_fields").doc(T.collection).collection(`${T.collection}-${F.replaceAll(" ","-")}`).doc(I)),g.delete(x.doc(e))},{maxAttempts:10})}catch(g){const T=await ae("postWriteError",o,p,["delete",N,e,r,g]);if(h&&(await new Promise(F=>{setTimeout(F,250)}),await pt("delete",T?.resolved?"success":"failed",N,i,n,e,m,T?.resolved?void 0:g)),!T?.resolved)throw m.auth&&N.User_ID&&await O.collection("tenants").doc(i).collection(d.collection).doc(e).update({User_ID:B.FieldValue.delete()}),g}const k=["delete",N,e,r],w=[...k];return await ae("postWrite",o,p,k),await ae("postOperation",o,p,w),{id:e,...N}},Xc=async(n,e)=>{const t=B.getFirestore(),s=Qs(),r=process.env.ADMIN_SMS;if(s==="development")if(r)n=r;else throw new Error("Admin phone not set");const i={to:n,body:e};await t.collection("system_messages").add(i)},eu=n=>n!==null&&typeof n=="object",tu=n=>{const e=t=>{Object.entries(t).forEach(([s,r])=>{r instanceof B.Timestamp?t[s]={_seconds:r.seconds,_nanoseconds:r.nanoseconds}:eu(r)&&e(r)})};e(n)},nu=async n=>await yt.getAuth().getUser(n),su=n=>{const e=Ks();return V.fromJSDate(n).setZone(e)},La=n=>{const e=Ks();return V.fromJSDate(n.toDate()).setZone(e)},ru=(n,e)=>{const s=V.fromJSDate(n,{zone:e}).offset,i=V.fromJSDate(n).offset,o=s-i;return V.fromJSDate(n).plus({minutes:o}).toJSDate()},iu=(n,e)=>{const s=V.fromJSDate(n,{zone:e}).offset,i=V.fromJSDate(n).offset,o=s-i;return V.fromJSDate(n).minus({minutes:o}).toJSDate()},au=n=>"seconds"in n&&"nanoseconds"in n?La(new B.Timestamp(n.seconds,n.nanoseconds)).toFormat("MMMM d, yyyy '@' h:mm a"):"";exports.addRecord=Jc;exports.addUser=sr;exports.convertDateToTimezone=su;exports.convertTimestampToTimezone=La;exports.deleteRecord=Kc;exports.deleteUser=Wt;exports.deserializeDeleteSentinels=Yn;exports.deserializeTimestamps=ir;exports.deserializeTimestampsWithoutUnderscores=qc;exports.displayDate=au;exports.fetchCurrentSchema=ze;exports.fetchLastSchema=Zc;exports.getCachedConfigValue=to;exports.getCollectionRefs=xa;exports.getCustomizationFile=qe;exports.getCustomizationFiles=Ta;exports.getDocumentRefs=Xs;exports.getFirestorePathRef=Re;exports.getGlobalConfigModule=Et;exports.getInputSchema=Mc;exports.getMaintenanceInfo=Wc;exports.getMode=Qs;exports.getOne=Qe;exports.getSome=tr;exports.getTenant=Ze;exports.getTimezone=Ks;exports.getUser=nu;exports.getVersionInfo=Uc;exports.getZodSchema=Oi;exports.initializeFirebase=zc;exports.initializeStoker=Lc;exports.isDeleteSentinel=xe;exports.keepTimezone=ru;exports.removeTimezone=iu;exports.runChildProcess=jc;exports.sendMail=nr;exports.sendMessage=Xc;exports.serializeTimestamps=tu;exports.setTenant=Vc;exports.tryPromise=ie;exports.updateRecord=Pa;exports.updateUser=Ma;exports.validateRelations=ar;exports.validateSoftDelete=or;exports.writeLog=pt;
|
package/dist/bundle.js
CHANGED
|
@@ -11089,6 +11089,7 @@ ${i}`);
|
|
|
11089
11089
|
z,
|
|
11090
11090
|
void 0,
|
|
11091
11091
|
void 0,
|
|
11092
|
+
void 0,
|
|
11092
11093
|
ye(o)
|
|
11093
11094
|
], oe = await ie("postWriteError", c, O, Q);
|
|
11094
11095
|
if (E && (await new Promise((ue) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stoker-platform/node-client",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.39",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
6
6
|
"files": [
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@google-cloud/storage": "^7.19.0",
|
|
27
|
-
"@stoker-platform/types": "0.5.
|
|
28
|
-
"@stoker-platform/utils": "0.5.
|
|
27
|
+
"@stoker-platform/types": "0.5.27",
|
|
28
|
+
"@stoker-platform/utils": "0.5.33",
|
|
29
29
|
"@types/luxon": "^3.7.1",
|
|
30
30
|
"cross-spawn": "^7.0.6",
|
|
31
31
|
"firebase-admin": "^13.7.0",
|