@stoker-platform/node-client 0.5.51 → 0.5.52

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 CHANGED
@@ -5,10 +5,10 @@
5
5
  `),e=e.replace(/\r\n/g,`
6
6
  `),e.length>5e6)throw new Error("Email body is too long");return e},Io=async(n,e)=>{const t={};for(const s of e){const r=`${n}/${s}.js`,i=ci.pathToFileURL(r).href;t[s]=await import(i)}return t};let hs,xo,On,No,Jt,Do,kn,bn,ms=0,oi=!1;const Rt={getTenant(){if(!On)throw new Error("Tenant not provided");return On},setTenant(n){On=n},getMode(){return xo},getTimezone(){return No},getGlobalConfigModule(){return he(Jt)},getCustomizationFile(n,e){if(!Object.keys(e.collections).includes(n))throw new Error("PERMISSION_DENIED");const t=ra([n],Do,"node",Rt);return he(t?.[n])},getVersionInfo(){return kn},getMaintenanceInfo(){return bn}},Wc=async(n,e,t,s,r)=>{const i=!!oi;if(oi=!0,e&&(On=e),xo=n,hs&&!r)return Rt;if(!process.env.STOKER_FB_WEB_APP_CONFIG)throw new Error("STOKER_FB_WEB_APP_CONFIG not set.");const o=process.env.STOKER_FB_WEB_APP_CONFIG,a=JSON.parse(o),d=(await import(ci.pathToFileURL(t).href)).default;Jt=d({sdk:"node",utils:Rt}),!r&&n==="development"&&(process.env.FIREBASE_AUTH_EMULATOR_HOST="127.0.0.1:9099",process.env.FIREBASE_DATABASE_EMULATOR_HOST="127.0.0.1:9000",process.env.FIRESTORE_EMULATOR_HOST="127.0.0.1:8080",process.env.FIREBASE_STORAGE_EMULATOR_HOST="127.0.0.1:9199");try{hs=It.getApp()}catch{hs=It.initializeApp({credential:It.applicationDefault(),databaseURL:a.databaseURL,storageBucket:a.storageBucket,projectId:a.projectId})}const h=await ze();return Do=await Io(s,Object.keys(h.collections)),No=await oe(Jt.timezone),i||B.getFirestore().collection("system_deployment").doc("maintenance_mode").onSnapshot(u=>{u.exists?(bn=u.data(),oe(Jt.onMaintenanceUpdate,["node",bn.active?"on":"off"])):console.error("Maintenance status not found")},u=>{console.error(u.message)}),i||B.getFirestore().collection("system_deployment").doc("latest_deploy").onSnapshot(u=>{u.exists?(kn=u.data(),ms++,ms>1&&oe(Jt.onVersionUpdate,["node",kn,ms])):console.error("Version info not found")},u=>{console.error(u.message)}),await new Promise(u=>{const f=()=>{bn&&kn?u(Rt):setTimeout(f,100)};f()}),Rt},{getTenant:Ze,setTenant:jc,getMode:Ks,getTimezone:Xs,getGlobalConfigModule:vt,getCustomizationFile:qe,getVersionInfo:zc,getMaintenanceInfo:Zc}=Rt,qc=async(n,e,t,s)=>new Promise((r,i)=>{const o=Bo(n,e,{cwd:t||process.cwd(),env:{...process.env,...s}});let a="";const l=()=>{o.kill("SIGINT")},c=()=>{o.kill("SIGTERM")},d=()=>{process.removeListener("SIGINT",l),process.removeListener("SIGTERM",c)};o.stdout?.on("data",h=>{a+=h.toString(),console.log(h.toString())}),o.stderr?.on("data",h=>{console.log(h.toString())}),o.on("exit",h=>{d(),h===0?r(a):i()}),process.on("SIGINT",l),process.on("SIGTERM",c)}),Bc=async()=>{const n=process.env.STOKER_FB_WEB_APP_CONFIG;if(!n)throw new Error("Firebase web app config not found");const e=JSON.parse(n);try{return It.getApp()}catch{return It.initializeApp({credential:It.applicationDefault(),databaseURL:e.databaseURL,storageBucket:e.storageBucket,projectId:e.projectId})}},ze=async(n=!1)=>{const s=await ui.getDatabase().ref("schema").orderByChild("published_time").limitToLast(1).get(),r=Object.values(s.val())[0];if(n){for(const i of Object.values(r.collections))for(const o of i.fields)if(o.type==="Computed"){const a=Ae(o,qe(i.labels.collection,r));a.formula&&(o.formula=a.formula)}}else for(const i of Object.values(r.collections))i.fields=i.fields.filter(o=>o.type!=="Computed");return r},Hc=async()=>{const t=await ui.getDatabase().ref("schema").orderByChild("published_time").limitToLast(2).get();if(!(t.numChildren()<2))return Object.values(t.val())[0]},Re=(n,e,t)=>{let s=n.collection("tenants").doc(t);for(let r=0;r<e.length;r++)r%2===0?s=s.collection(e[r]):s=s.doc(e[r]);return s},Ao=(n,e,t,s,r)=>{const i=B.getFirestore(),o=e.at(-1);if(!o)throw new Error("EMPTY_PATH");const a=t.collections[o],{labels:l,fields:c,preloadCache:d}=a,h=qe(o,t),u=Re(i,e,n);if(r)if(s){const f=r.collections?.[l.collection];if(!r.Role)throw new Error("PERMISSION_DENIED");const y=f&&Te("Read",f),v=mi(a,t,r),p=fi(a,r),g=Ps(a,r),I=hi(a,t,r),k=(w=[])=>{const R=[],S=_i(r.Role,a,t);if(!S)throw new Error("PERMISSION_DENIED");if(y){let T=i.collection("tenants").doc(n).collection("system_fields").doc(l.collection).collection(`${l.collection}-${S.key}`).where("Collection_Path_String","==",e.join("/"));w.forEach(C=>{T=T.where(...C)}),R.push(T)}else if(v)for(const T of v){let C=i.collection("tenants").doc(n).collection("system_fields").doc(l.collection).collection(`${l.collection}-${T.field}`).where("Collection_Path_String","==",e.join("/"));w.forEach(q=>{C=C.where(...q)}),R.push(C)}return R},x=p.filter(w=>"operations"in w&&w.operations?w.operations.includes("Read"):!0);if(x.length===0&&g.length===0&&I.length===0)return k();let E=0;const F=w=>{w&&(E===0?E=w:E*=w)};if(x.length>0){for(const w of x)if(w.operations&&w.type==="Record_Property"){const R=w.roles.find(S=>S.role===r.Role);if(!R)throw new Error("PERMISSION_DENIED");F(R.values?.length)}}d?.roles.includes(r.Role)&&d.range&&F(d.range.fields.length);const _=h.admin?.statusField;_&&!d?.roles.includes(r.Role)&&F(Math.max(_.active?.length||0,_.archived?.length||0));const Z=E===0?30:Math.max(1,Math.floor(30/E)),b=[];x.filter(w=>w.type==="Record_Owner").forEach(()=>b.push(["Created_By","==",s])),x.filter(w=>w.type==="Record_User").forEach(w=>{if("collectionField"in w){const R=W(c,w.collectionField);b.push([`${R.name}_Array`,"array-contains",r.Doc_ID])}}),x.filter(w=>w.type==="Record_Property").forEach(w=>{if("propertyField"in w){const R=w.roles.find(T=>T.role===r.Role);if(!R)throw new Error("PERMISSION_DENIED");const S=W(c,w.propertyField);S.type==="Array"?b.push([`${S.name}_Array`,"array-contains-any",R.values]):b.push([S.name,"in",R.values])}});const m=[];g.filter(w=>w.type==="Individual").forEach(w=>{const R=f?.individualEntities,S=[];if(R){const T=w.singleQuery?w.singleQuery:Z;for(let C=0;C<R.length;C+=T){const q=R.slice(C,C+T);S.push(q)}if(!w.singleQuery)S.forEach(C=>{m.push(...k(b.concat([["id","in",C]])))});else{if(R.length>T)throw new Error(`INPUT_ERROR: Individual entity restriction with singleQuery set to true must not have more than ${w.singleQuery} entities`);b.push(["id","in",R])}}}),I.filter(w=>w.parentFilter.type==="Individual").forEach(w=>{const{parentFilter:R,parentRestriction:S}=w;if("collectionField"in R){const T=W(c,R.collectionField);if("collection"in T){const C=r.collections?.[T.collection];if(!C)throw new Error("PERMISSION_DENIED");const q=C.individualEntities,M=[];if(q){const Q=S.singleQuery?S.singleQuery:Z;for(let O=0;O<q.length;O+=Q){const G=q.slice(O,O+Q);M.push(G)}if(!S.singleQuery)M.forEach(O=>{m.push(...k(b.concat([[`${T.name}_Array`,"array-contains-any",O]])))});else{if(q.length>Q)throw new Error(`INPUT_ERROR: Individual entity parentFilter with singleQuery set to true must not have more than ${S.singleQuery} entities`);b.push([`${T.name}_Array`,"array-contains-any",q])}}}}});const L=[];g.filter(w=>w.type==="Parent").forEach(w=>{if("collectionField"in w){const R=W(c,w.collectionField);if("collection"in R){const S=f?.parentEntities,T=[];if(S){const C=w.singleQuery?w.singleQuery:Z;for(let q=0;q<S.length;q+=C){const M=S.slice(q,q+C);T.push(M)}if(!w.singleQuery)T.forEach(q=>{L.push(...k(b.concat([[`${R.name}_Array`,"array-contains-any",q]])))});else{if(S&&S.length>C)throw new Error(`INPUT_ERROR: Parent entity restriction with singleQuery set to true must not have more than ${w.singleQuery} entities`);b.push([`${R.name}_Array`,"array-contains-any",S])}}}}}),I.filter(w=>w.parentFilter.type==="Parent").forEach(w=>{const{parentFilter:R,parentRestriction:S}=w;if("collectionField"in R&&"parentCollectionField"in R){const T=W(c,R.collectionField),C=W(c,R.parentCollectionField);if("collection"in T&&"collection"in C){const q=r.collections?.[T.collection];if(!q)throw new Error("PERMISSION_DENIED");const M=q.parentEntities,Q=[];if(M){const O=S.singleQuery?S.singleQuery:Z;for(let G=0;G<M.length;G+=O){const z=M.slice(G,G+O);Q.push(z)}if(!S.singleQuery)Q.forEach(G=>{L.push(...k(b.concat([[`${C.name}_Array`,"array-contains-any",G]])))});else{if(M&&M.length>O)throw new Error(`INPUT_ERROR: Profile_Parent entity parentFilter with singleQuery set to true must not have more than ${S.singleQuery} entities`);b.push([`${C.name}_Array`,"array-contains-any",M])}}}}});const N=[];L.length===0&&(g.filter(w=>w.type==="Parent_Property").forEach(w=>{if("collectionField"in w&&"propertyField"in w){const R=W(c,w.collectionField),S=W(c,w.propertyField);if("collection"in R){const T=f?.parentPropertyEntities||{};Object.entries(T).forEach(([C,q])=>{if(q.length>0){const M=[];for(let Q=0;Q<q.length;Q+=Z){const O=q.slice(Q,Q+Z);M.push(O)}M.forEach(Q=>{N.push(...k(b.concat([[`${R.name}_Array`,"array-contains-any",Q],[S.name,"==",C]])))})}})}}}),I.filter(w=>w.parentFilter.type==="Parent_Property").forEach(w=>{const{parentFilter:R}=w;if("collectionField"in R&&"parentCollectionField"in R&&"parentPropertyField"in R){const S=W(c,R.collectionField),T=W(c,R.parentCollectionField),C=W(c,R.parentPropertyField);if("collection"in S&&"collection"in T){const q=r.collections?.[S.collection];if(!q)throw new Error("PERMISSION_DENIED");const M=q.parentPropertyEntities||{};Object.entries(M).forEach(([Q,O])=>{if(O.length>0){const G=[];for(let z=0;z<O.length;z+=Z){const X=O.slice(z,z+Z);G.push(X)}G.forEach(z=>{N.push(...k(b.concat([[`${T.name}_Array`,"array-contains-any",z],[C.name,"==",Q]])))})}})}}}));const D=[...m,...L,...N];return!g.length&&!I.length?k(b):D}else throw new Error("PERMISSION_DENIED");else return[u]},er=(n,e,t,s,r)=>{const i=B.getFirestore(),o=e.at(-1);if(!o)throw new Error("EMPTY_PATH");const a=s.collections[o],{labels:l}=a,c=Re(i,e,n);if(r){const d=r.collections?.[l.collection];if(!r.Role)throw new Error("PERMISSION_DENIED");const h=d&&Te("Read",d),u=mi(a,s,r),f=[],y=_i(r.Role,a,s);if(!y)throw new Error("PERMISSION_DENIED");if(h)f.push(i.collection("tenants").doc(n).collection("system_fields").doc(l.collection).collection(`${l.collection}-${y.key}`).doc(t));else if(u)for(const v of u)f.push(i.collection("tenants").doc(n).collection("system_fields").doc(l.collection).collection(`${l.collection}-${v.field}`).doc(t));return f}else return[c.doc(t)]},Co=async(n,e,t,s,r,i,o,a,l,c)=>{const d=t.at(-2),h=pi(r.collections[d],r).map(y=>y.labels.collection);s.collections?s.collections.forEach(y=>{if(!h.includes(y))throw new Error(`SCHEMA_ERROR: Collection ${y} not found in subcollections of ${d}`)}):s.collections=h;const u=s.depth-1,f=s.collections.map(async y=>{const v=await nr([...t,y],{constraints:s.constraints,userId:a,pagination:s.limit,providedTransaction:l,noEmbeddingFields:c}).catch(p=>{throw p.code==="permission-denied"&&console.info(`PERMISSION_DENIED for subcollection ${y} for document at ${t.join("/")}`),p});e[y]=v.records,i&&await Promise.all(e[y].map(p=>tr(n,p,[...t,y,p.id],i,r,void 0,a,l,c))),u>0&&await Promise.all(e[y].map(p=>Co(n,p,[...t,y,p.id],{depth:u},r,i,o,a,l,c)))});await Promise.all(f)},tr=async(n,e,t,s,r,i,o,a,l)=>{const c=t.at(-2);s.fields||=r.collections[c].fields.filter(u=>ee(u));const d=s.depth-1,h=[];for(const u of s.fields)if("collection"in u){const f=e[u.name];if(!f)continue;const y=Object.keys(f);for(const v of y){const p=f[v],g=Qe(p.Collection_Path,v,{userId:o,providedTransaction:a,noEmbeddingFields:l}).then(I=>{if(f[v]=I,d>0)return tr(n,f[v],[...p.Collection_Path,v],{depth:d},r,i,o,a,l)}).catch(I=>{if(I.message.includes("NOT_FOUND")||I.code==="permission-denied")delete f[v];else throw I});h.push(g)}}await Promise.all(h)},nr=async(n,e)=>{if(e?.subcollections?.depth&&e.subcollections.depth>10)throw new Error("INPUT_ERROR: Subcollections depth cannot exceed 10");if(e?.relations?.depth&&e.relations.depth>10)throw new Error("INPUT_ERROR: Relations depth cannot exceed 10");if(e?.pagination?.number!==void 0){const c=e.pagination.number;if(typeof c!="number"||!Number.isFinite(c)||!Number.isInteger(c)||c<1)throw new Error("INPUT_ERROR: Pagination number must be a positive finite integer")}const t=e?.constraints,s=Ze(),r=B.getFirestore();let i,o,a;const l=async c=>{const[d,h,u]=await Promise.all([e?.userId?c.get(r.collection("tenants").doc(s).collection("system_user_permissions").doc(e.userId)):Promise.resolve({}),c.get(r.collection("system_deployment").doc("maintenance_mode")),ze(!0)]);if(!h.exists)throw new Error("MAINTENANCE_MODE");if(h.data().active)throw new Error("MAINTENANCE_MODE");const y=u;let v;const p=vt(),g=n.at(-1);if(!g)throw new Error("EMPTY_PATH");const I=Object.keys(y.collections).includes(g),k=p.disabledCollections?.includes(g);if(!I||k)throw new Error("COLLECTION_NOT_FOUND");const x=y.collections[g],{labels:E}=x,F=qe(E.collection,y);if(e?.userId){if(!d?.exists)throw new Error("PERMISSION_DENIED");if(v=d.data(),!v.Role)throw new Error("USER_ERROR");if(!v.Enabled)throw new Error("PERMISSION_DENIED")}let _=Ao(s,n,y,e?.userId,v);if(_.length===0)return{cursor:{},pages:0,records:[]};if(t&&(_=_.map(w=>(t.forEach(([R,S,T])=>{w=w.where(R,S,T)}),w))),o=e?.pagination?.startAfter||e?.pagination?.endBefore||{first:new Map,last:new Map},e?.pagination){if(e.pagination.startAfter&&e.pagination.endBefore)throw new Error("INPUT_ERROR: startAfter and endBefore cannot be provided together");const w=e.pagination.startAfter||e.pagination.endBefore;if(e?.userId){const R=sa(v.Role,x,y);if(w&&R!==!0)throw new Error("INPUT_ERROR: Pagination is not allowed when using "+R)}e.pagination.orderByField&&e.pagination.orderByDirection?!e.pagination.startAfter&&!e.pagination.endBefore?_=_.map(R=>R.orderBy(e.pagination.orderByField,e.pagination.orderByDirection).limit(e.pagination.number)):e.pagination.startAfter?_=_.map((R,S)=>R.orderBy(e.pagination.orderByField,e.pagination.orderByDirection).startAfter(o.last.get(S)).limit(e.pagination.number)):_=_.map((R,S)=>R.orderBy(e.pagination.orderByField,e.pagination.orderByDirection).endBefore(o.first.get(S)).limitToLast(e.pagination.number)):!e.pagination.startAfter&&!e.pagination.endBefore?_=_.map(R=>R.limit(e.pagination.number)):e.pagination.startAfter?_=_.map((R,S)=>R.startAfter(o.last.get(S)).limit(e.pagination.number)):_=_.map((R,S)=>R.endBefore(o.first.get(S)).limitToLast(e.pagination.number))}const Z={};await ae("preOperation",p,F,{operation:"read",context:Z}),await ae("preRead",p,F,{context:Z,refs:_,multiple:!0,listener:!1}),a=new Map;const L=_.map(async w=>await c.get(w)),N=await Promise.all(L);for(const w of N){for(const R of w.docs){a.has(R.id)||a.set(R.id,{});const S=R.data(),T=a.get(R.id);T.id||=R.id;const C={...T,...S};delete C.Collection_Path_String,a.set(R.id,C)}o.first.set(N.indexOf(w),w.docs[0]),o.last.set(N.indexOf(w),w.docs.at(-1)||w.docs[0])}if(e?.pagination){let w=_[0];t&&(w=t.reduce((C,[q,M,Q])=>C.where(q,M,Q),w)),e.pagination.orderByField&&e.pagination.orderByDirection&&(w=w.orderBy(e.pagination.orderByField,e.pagination.orderByDirection));const S=(await w.count().get()).data().count,T=e.pagination.number;i=T>0?Math.ceil(S/T):0}let D;e?.noComputedFields||(D=await oe(F.admin?.retriever));for(const w of a.values()){const R=[],S=[...w.Collection_Path,w.id];e?.subcollections&&R.push(Co(s,a.get(w.id),S,he(e.subcollections),y,he(e?.relations),void 0,e.userId,e.transactional?c:void 0,e?.noEmbeddingFields)),e?.relations&&(e.relations.fields&&(e.relations.fields=e.relations.fields.map(M=>{if(typeof M=="string"){const Q=x.fields.find(O=>O.name===M);if(Q)return Q;throw new Error(`SCHEMA_ERROR: Field ${M} not found in collection ${g}`)}return M})),R.push(tr(s,a.get(w.id),S,he(e.relations),y,void 0,e.userId,e.transactional?c:void 0,e?.noEmbeddingFields))),await Promise.all(R);const T=[];for(const M of x.fields){if(M.type==="Computed"&&!e?.noComputedFields){const Q=Ae(M,F);if(!Q.formula)continue;T.push(oe(Q.formula,[w,D]).then(O=>{w[M.name]=O}))}e?.noEmbeddingFields&&M.type==="Embedding"&&delete w[M.name]}if(await Promise.all(T),e?.userId&&v?.Role){const M=v.Role;if(!(F.custom?.serverAccess?.read!==void 0?await oe(F.custom.serverAccess.read,[M,w]):!0)){a.delete(w.id);continue}for(const O of x.fields){const G=!O.access||O.access.includes(M),z=Ae(O,F),X=z?.custom?.serverAccess?.read!==void 0?await oe(z.custom.serverAccess.read,[M,w]):!0;(!G||!X)&&(ee(O)?(delete a.get(w.id)[O.name],delete a.get(w.id)[`${O.name}_Array`],delete a.get(w.id)[`${O.name}_Single`]):delete a.get(w.id)[O.name])}}const C={operation:"read",data:w,recordId:w.id,context:Z};await ae("postOperation",p,F,C),await ae("postRead",p,F,{context:Z,refs:_,record:w,listener:!1})}e?.userId&&await ta(Array.from(a.values()),x,y,e.userId,v)};return e?.providedTransaction?await l(e.providedTransaction):await r.runTransaction(async c=>{await l(c)},{readOnly:!0}),{cursor:o,pages:i,records:Array.from(a.values())}},Fo=async(n,e,t,s,r,i,o,a)=>{const l=s.at(-2),c=pi(i.collections[l],i).map(u=>u.labels.collection);r.collections?r.collections.forEach(u=>{if(!c.includes(u))throw new Error(`SCHEMA_ERROR: Collection ${u} not found in subcollections of ${l}`)}):r.collections=c;const d=r.depth-1,h=r.collections.map(async u=>{const f=await nr([...s,u],{constraints:r.constraints||[],userId:a,relations:o,pagination:r.limit,providedTransaction:e}).catch(y=>{throw y.code==="permission-denied"&&console.info(`PERMISSION_DENIED for subcollection ${u} for document at ${s.join("/")}`),y});t[u]=f.records,d>0&&await Promise.all(t[u].map(async y=>{await Fo(n,e,y,[...s,u,y.id],{depth:d},i,o,a)}))});await Promise.all(h)},$o=async(n,e,t,s,r,i,o,a,l)=>{const c=s.at(-2);i.fields||=r.collections[c].fields.filter(u=>ee(u));const d=i.depth-1,h=[];for(const u of i.fields)if("collection"in u){const f=t[u.name];if(!f)continue;for(const[y,v]of Object.entries(f)){const p=Qe(v.Collection_Path,y,{userId:o,providedTransaction:e,noComputedFields:a,noEmbeddingFields:l}).then(g=>{if(f[y]=g,d>0)return $o(n,e,f[y],[...v.Collection_Path,y],r,{depth:d},o,a,l)}).catch(g=>{if(g.message.includes("NOT_FOUND")||g.code==="permission-denied")delete f[y];else throw g});h.push(p)}}await Promise.all(h)},Qe=async(n,e,t)=>{if(t?.subcollections?.depth&&t.subcollections.depth>10)throw new Error("INPUT_ERROR: Subcollections depth cannot exceed 10");if(t?.relations?.depth&&t.relations.depth>10)throw new Error("INPUT_ERROR: Relations depth cannot exceed 10");const s=Ze(),r=B.getFirestore();let i;const o=async a=>{const[l,c,d]=await Promise.all([t?.userId?a.get(r.collection("tenants").doc(s).collection("system_user_permissions").doc(t.userId)):Promise.resolve({}),a.get(r.collection("system_deployment").doc("maintenance_mode")),ze(!0)]);if(!c.exists)throw new Error("MAINTENANCE_MODE");if(c.data().active)throw new Error("MAINTENANCE_MODE");const u=d;let f;const y=vt(),v=n.at(-1);if(!v)throw new Error("EMPTY_PATH");const p=Object.keys(u.collections).includes(v),g=y.disabledCollections?.includes(v);if(!p||g)throw new Error("COLLECTION_NOT_FOUND");const I=u.collections[v],{labels:k}=I,x=qe(k.collection,u);let E;if(t?.userId){if(!l?.exists)throw new Error("PERMISSION_DENIED");if(f=l.data(),!f.Role)throw new Error("USER_ERROR");if(!f.Enabled)throw new Error("PERMISSION_DENIED");if(E=f.collections?.[k.collection],!E)throw new Error("PERMISSION_DENIED")}if(t?.userId&&(!E||!Te("Read",E)))throw new Error("PERMISSION_DENIED");const F=er(s,n,e,u,f);if(F.length===0)throw new Error("PERMISSION_DENIED");const _={};await ae("preOperation",y,x,{operation:"read",recordId:e,context:_}),await ae("preRead",y,x,{context:_,refs:F,multiple:!1,listener:!1}),i={};const m=F.map(S=>a.get(S)),L=await Promise.all(m);for(const S of L)if(S.exists){const T=S.data();i.id||=S.id,i={...i,...T},delete i.Collection_Path_String}else throw new Error(`NOT_FOUND: Document with ID ${e} does not exist at location ${n?.join("/")||k.collection}`);const N=[],D=n?[...n,e]:[k.collection,e];if(t?.subcollections&&N.push(Fo(s,a,i,D,t.subcollections,u,void 0,t.userId)),t?.relations&&(t.relations.fields&&(t.relations.fields=t.relations.fields.map(S=>{if(typeof S=="string"){const T=I.fields.find(C=>C.name===S);if(T)return T;throw new Error(`SCHEMA_ERROR: Field ${S} not found in collection ${v}`)}return S})),N.push($o(s,a,i,D,u,t.relations,t.userId,t.noComputedFields,t.noEmbeddingFields))),await Promise.all(N),!t?.noComputedFields){for(const S of I.fields)if(S.type==="Computed"){const T=Ae(S,x);if(!T.formula)continue;i[S.name]=await T.formula(i)}}if(t?.noEmbeddingFields)for(const S of I.fields)S.type==="Embedding"&&delete i[S.name];if(t?.userId&&f?.Role){const S=f.Role;if(!(x.custom?.serverAccess?.read!==void 0?await oe(x.custom?.serverAccess?.read,[S,i]):!0))throw new Error("PERMISSION_DENIED");for(const C of I.fields){const q=!C.access||C.access.includes(S),M=Ae(C,x),Q=M?.custom?.serverAccess?.read!==void 0?await oe(M.custom.serverAccess.read,[S,i]):!0;(!q||!Q)&&(ee(C)?(delete i[C.name],delete i[`${C.name}_Array`],delete i[`${C.name}_Single`]):delete i[C.name])}}await ae("postOperation",y,x,{operation:"read",data:i,recordId:e,context:_}),await ae("postRead",y,x,{context:_,refs:F,record:i,listener:!1}),t?.userId&&await ea(i,I,u,t.userId,f)};return t?.providedTransaction?await o(t.providedTransaction):await r.runTransaction(async a=>{await o(a)},{readOnly:!0}),i},Mo=async(n,e,t,s,r,i,o,a)=>{const l=B.getFirestore(),c=qe(r.labels.collection,i),d=r.labels.collection,h=r.fields.filter(f=>"unique"in f&&f.unique),u=[];if(await Promise.all(h.map(async f=>{{if(s[f.name]===void 0||ke(s[f.name]))return;Ae(f,c);const y=s[f.name].toString().toLowerCase().replace(/\s/g,"---").replaceAll("/","|||");if(!Qs(y))u.push(`${f.name} "${s[f.name]}" is invalid`);else{const v=await l.collection("tenants").doc(e).collection("system_unique").doc(d).collection(`Unique-${d}-${f.name}`).doc(y).get();v.exists&&!(n==="update"&&v.data().id===t)&&u.push(`${f.name} "${s[f.name]}" already exists`)}}})),u.length>0)throw new Error(u.join(", "))},yt=async(n,e,t,s,r,i,o,a,l)=>{const{labels:c}=o,d=B.getFirestore(),h=vt(),u=await oe(h.firebase?.writeLogTTL),f={operation:n,collection:c.collection,docId:i,user:"System",status:e,Collection_Path:r,Last_Write_At:t.Last_Write_At,Last_Write_By:t.Last_Write_By,Last_Write_Connection_Status:t.Last_Write_Connection_Status,Last_Write_App:t.Last_Write_App,Last_Write_Version:t.Last_Write_Version,data:{}};if(u){const g=new Date,I=new Date(new Date().setDate(g.getDate()+u));f.TTL=B.Timestamp.fromDate(I)}const y=he(t);nt(y),n!=="delete"&&(f.data.data=he(y)),n==="update"&&(f.data.originalRecord=he(l)),n!=="delete"&&["started","written"].includes(e)&&(delete f.data.data.Saved_At,delete f.data.data.Last_Save_At),e==="failed"&&(f.data.error=JSON.stringify(a));const v=Re(d,r,s),p=t.Last_Write_At;await v.doc(i).collection("system_write_log").doc(`${t.Last_Write_By}-${p.valueOf()}`).set(f)},Wt=async n=>{const e=Ze(),t=gt.getAuth(),s=B.getFirestore(),r=[];if(await Promise.all([(async()=>{try{await s.collection("tenants").doc(e).collection("system_user_permissions").doc(n.User_ID).delete()}catch(i){r.push(`Error deleting user permissions:
7
7
  ${i}`)}})(),(async()=>{try{await t.deleteUser(n.User_ID)}catch(i){if(i.code==="auth/user-not-found")return;r.push(`Error deleting user:
8
- ${i}`)}})()]),r.length>0)throw new Error(r.join(", "))},sr=async(n,e,t,s,r,i,o,a,l)=>{const c=B.getFirestore(),d=Ks(),h=process.env.ADMIN_EMAIL;if(d==="development"||process.env.FIRESTORE_EMULATOR_HOST)if(h)n=h;else throw new Error("Admin email not set");const u=fs(n),f=Uc(e),y=t?ii(t):void 0,v=s?ii(s):void 0,p=r?fs(r):void 0,g=i?fs(i):void 0,I=o?Un(o):void 0,k=l?Un(l):void 0,x=Array.isArray(u)?u:[u];if(x.length===0||x.length===1&&!x[0])throw new Error("No valid email addresses provided");const E={to:u,message:{subject:f}};if(y&&(E.message.text=y),v&&(E.message.html=v),p){const F=Array.isArray(p)?p:[p];F.length>0&&F[0]&&(E.cc=p)}if(g){const F=Array.isArray(g)?g:[g];F.length>0&&F[0]&&(E.bcc=g)}I&&(E.replyTo=I),a&&(E.message.attachments=a),k&&(E.from=k),await c.collection("system_mail").add(E)},Gc=["tenant","role","collection","doc"],Po=new Set(Gc);function rr(n){return Po.has(n)}function Yc(n){if(!n)return{};const e={};for(const t of Object.keys(n))Po.has(t)||(e[t]=n[t]);return e}const ir=async(n,e,t,s,r,i,o)=>{const a=gt.getAuth(),l=B.getFirestore(),{labels:c,fields:d}=s,h="USER_ERROR",u=async(p,g)=>{try{await Wt(p)}catch{throw new Error(`ROLLBACK_FAILED: ${g}`)}};let f;try{f=await a.createUser({email:r.Email,emailVerified:!1,password:o,displayName:r.Name,photoURL:r.Photo_URL,disabled:!r.Enabled})}catch{throw new Error(h)}const y={};for(const p of d)p.addToAuthToken&&!rr(p.name)&&r[p.name]!==void 0&&p.type!=="Timestamp"&&p.type!=="Computed"&&p.type!=="Embedding"&&(ke(r[p.name])?y[p.name]=null:y[p.name]=r[p.name]);try{await a.setCustomUserClaims(f.uid,{...y,tenant:n,role:r.Role,collection:c.collection,doc:e})}catch{throw await u(r,h),new Error(h)}try{await l.collection("tenants").doc(n).collection("system_user_permissions").doc(f.uid).set({...i,Role:r.Role,Enabled:r.Enabled??!1,Collection:c.collection,Doc_ID:e})}catch{throw await u(r,h),new Error(h)}const v=t.auth.enableMultiFactorAuth;if(v===!0||typeof v=="object"&&v.includes(r.Role)){let p;try{p=await a.generateEmailVerificationLink(r.Email)}catch{throw await u(r,h),new Error(h)}if(p.includes("apiKey=&")){const g=JSON.parse(process.env.STOKER_FB_WEB_APP_CONFIG);p=p.replace("apiKey=&",`apiKey=${g.apiKey}&`)}if(p){const g=`https://${a.app.options.projectId}.firebaseapp.com/__/auth/action${p}`,I=await oe(t.appName),k=t?.mail?.emailVerification&&t.mail.emailVerification(g,I);try{await sr(r.Email,k?.subject||"Please verify your email address",void 0,k?.html||`Please verify your email address by clicking the link:
8
+ ${i}`)}})()]),r.length>0)throw new Error(r.join(", "))},sr=async(n,e,t,s,r,i,o,a,l)=>{const c=B.getFirestore(),d=Ks(),h=process.env.ADMIN_EMAIL;if(d==="development"||process.env.FIRESTORE_EMULATOR_HOST)if(h)n=h;else throw new Error("Admin email not set");const u=fs(n),f=Uc(e),y=t?ii(t):void 0,v=s?ii(s):void 0,p=r?fs(r):void 0,g=i?fs(i):void 0,I=o?Un(o):void 0,k=l?Un(l):void 0,x=Array.isArray(u)?u:[u];if(x.length===0||x.length===1&&!x[0])throw new Error("No valid email addresses provided");const E={to:u,message:{subject:f}};if(y&&(E.message.text=y),v&&(E.message.html=v),p){const F=Array.isArray(p)?p:[p];F.length>0&&F[0]&&(E.cc=p)}if(g){const F=Array.isArray(g)?g:[g];F.length>0&&F[0]&&(E.bcc=g)}I&&(E.replyTo=I),a&&(E.message.attachments=a),k&&(E.from=k),await c.collection("system_mail").add(E)},Gc=["tenant","role","collection","doc"],Po=new Set(Gc);function rr(n){return Po.has(n)}function Yc(n){if(!n)return{};const e={};for(const t of Object.keys(n))Po.has(t)||(e[t]=n[t]);return e}const ir=async(n,e,t,s,r,i,o)=>{const a=gt.getAuth(),l=B.getFirestore(),{labels:c,fields:d}=s,h="USER_ERROR",u=async(p,g)=>{try{await Wt(p)}catch{throw new Error(`ROLLBACK_FAILED: ${g}`)}};let f;try{f=await a.createUser({email:r.Email,emailVerified:!1,password:o,displayName:r.Name,photoURL:r.Photo_URL,disabled:!r.Enabled})}catch{throw new Error(h)}const y={};for(const p of d)p.saveToAuthToken&&!rr(p.name)&&r[p.name]!==void 0&&p.type!=="Timestamp"&&p.type!=="Computed"&&p.type!=="Embedding"&&(ke(r[p.name])?y[p.name]=null:y[p.name]=r[p.name]);try{await a.setCustomUserClaims(f.uid,{...y,tenant:n,role:r.Role,collection:c.collection,doc:e})}catch{throw await u(r,h),new Error(h)}try{await l.collection("tenants").doc(n).collection("system_user_permissions").doc(f.uid).set({...i,Role:r.Role,Enabled:r.Enabled??!1,Collection:c.collection,Doc_ID:e})}catch{throw await u(r,h),new Error(h)}const v=t.auth.enableMultiFactorAuth;if(v===!0||typeof v=="object"&&v.includes(r.Role)){let p;try{p=await a.generateEmailVerificationLink(r.Email)}catch{throw await u(r,h),new Error(h)}if(p.includes("apiKey=&")){const g=JSON.parse(process.env.STOKER_FB_WEB_APP_CONFIG);p=p.replace("apiKey=&",`apiKey=${g.apiKey}&`)}if(p){const g=`https://${a.app.options.projectId}.firebaseapp.com/__/auth/action${p}`,I=await oe(t.appName),k=t?.mail?.emailVerification&&t.mail.emailVerification(g,I);try{await sr(r.Email,k?.subject||"Please verify your email address",void 0,k?.html||`Please verify your email address by clicking the link:
9
9
  </br>
10
10
  </br>
11
- <a href="${g}">${g}</a>`)}catch{throw await u(r,h),new Error(h)}}}return f.uid},or=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")},Wn=n=>n!==null&&typeof n=="object"&&!Array.isArray(n),Jc=n=>{const e=t=>{Object.entries(t).forEach(([s,r])=>{Wn(r)&&Object.keys(r).length===2&&typeof r.seconds=="number"&&typeof r.nanoseconds=="number"?t[s]=new B.Timestamp(r.seconds,r.nanoseconds):Wn(r)&&e(r)})};e(n)},ar=n=>{const e=t=>{Object.entries(t).forEach(([s,r])=>{Wn(r)&&Object.keys(r).length===2&&typeof r._seconds=="number"&&typeof r._nanoseconds=="number"?t[s]=new B.Timestamp(r._seconds,r._nanoseconds):Wn(r)&&e(r)})};e(n)},Jn=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():Jn(n[e]))},Qc=(n,e,t)=>{if(ee(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);wt(n,[i]).size===1&&(s[`${r}_Lowercase`]=e[`${r}_Lowercase`])}}),s}return{}},ai=async(n,e,t,s,r,i,o)=>{if(!ee(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[d,h]=c[0];if(!h)throw new Error(`VALIDATION_ERROR: Relation ${t.name} is required`);const u=Re(l,h.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(u.doc(d));if(!f.exists)throw new Error(`VALIDATION_ERROR: Record ${d} not found in collection ${t.collection}`);const y=f.data(),v=W(a,t.enforceHierarchy.field),p=t.enforceHierarchy;if(!y[p.recordLinkField]||!s[v.name]||!Object.keys(s[v.name]).every(g=>Object.keys(y[p.recordLinkField]).includes(g)))throw new Error("VALIDATION_ERROR: Invalid relation hierarchy")},gn=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`]},ps=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`]={id:s,...t})},Kc=(n,e,t,s,r,i)=>{const o=[],a=[];for(const l of s.fields)ee(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}},lr=async(n,e,t,s,r,i,o,a,l,c,d,h)=>{const{fields:u}=i,f=B.getFirestore(),y=new Map,v=new Map,p=new Map;for(const g of u)ee(g)&&["OneToOne","OneToMany"].includes(g.type)&&g.enforceHierarchy&&s[g.name]&&(n==="Create"||n==="Update"&&!He(h?.[g.name],s[g.name]))&&await ai(e,i,g,s,a,l);for(const g of u)if(ee(g)&&g.twoWay){const I=o.collections[g.collection],k=W(I.fields,g.twoWay),x=dt(I,[k]);if(s[g.name]){const E=Object.entries(s[g.name]);for(const F of E){const[_,Z]=F;if(n==="Create"||!h?.[g.name]?.[_]){let b;const m=p.get(g.collection)?.[_];if(m)b=m;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 N=Re(f,Z.Collection_Path,e),D=await a.get(N.doc(_));if(!D.exists){gn(g,r,_);continue}const w=D.data();v.set(g.collection,{...v.get(g.collection)||{},[_]:w}),b=he({...w,...Tn(s)})}const L={...b[k.name],[t]:{Collection_Path:s.Collection_Path,...Qc(i,s,k)}};b[k.name]=L,b[`${k.name}_Array`]||=[],b[`${k.name}_Array`].push(t),x.size===1&&(b[`${k.name}_Single`]={id:t,...L}),p.set(g.collection,{...p.get(g.collection)||{},[_]:b})}}}if(n==="Update"){const E=Object.entries(h?.[g.name]||{});for(const F of E){const[_,Z]=F;if(!s[g.name]?.[_]){let b;const m=p.get(g.collection)?.[_];if(m)b=m;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 L=Re(f,Z.Collection_Path,e),N=await a.get(L.doc(_));if(!N.exists){y.set(g.name,[...y.get(g.name)||[],_]);continue}const D=N.data();v.set(g.collection,{...v.get(g.collection)||{},[_]:D}),b=he({...D,...Tn(s)})}b[k.name][t]&&delete b[k.name][t],Array.isArray(b[`${k.name}_Array`])&&(b[`${k.name}_Array`]=b[`${k.name}_Array`].filter(L=>L!==t)),x.size===1&&delete b[`${k.name}_Single`],p.set(g.collection,{...p.get(g.collection)||{},[_]:b})}}}}for(const[g,I]of p.entries()){const k=o.collections[g],x=qe(g,o);for(const[E,F]of Object.entries(I)){const{addedFields:_,removedFields:Z}=Kc(n,E,g,i,s,h);if(c&&d){for(const b of _){const m=W(k.fields,b.twoWay);if(!dr(k,m,d)){gn(b,r,E);continue}}for(const b of Z){const m=W(k.fields,b.twoWay),L=dt(k,[m]);if(!dr(k,m,d)){ps(b,r,h?.[b.name]?.[E],E,L.size===1);continue}}if(!it("Update",k,o,c,d,v.get(g)?.[E])){for(const b of _)gn(b,r,E);for(const b of Z){const m=W(k.fields,b.twoWay),L=dt(k,[m]);ps(b,r,h?.[b.name]?.[E],E,L.size===1)}}if(!it("Update",k,o,c,d,F)){for(const b of _)gn(b,r,E);for(const b of Z){const m=W(k.fields,b.twoWay),L=dt(k,[m]);ps(b,r,h?.[b.name]?.[E],E,L.size===1)}}}try{await sn("update",F,k,x,{operation:"update",record:F,context:{},originalRecord:F},o)}catch(b){throw new Error(`VALIDATION_ERROR: Two way relation update would invalidate record ${E} in ${g}: ${b.message}`)}for(const b of _){const m=W(k.fields,b.twoWay);["OneToOne","OneToMany"].includes(m.type)&&ee(m)&&m.enforceHierarchy&&await ai(e,k,m,F,a,l,!0)}}}return y},Lo=(n,e,t)=>{n==="create"&&mt.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}`)}),mt.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}`)}))},cr=(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")}},ys=async(n,e,t,s,r)=>{if(!Te("Read",r.collections?.[e.labels.collection]))return!1;try{await Qe([e.labels.collection],t,{userId:s,providedTransaction:n})}catch{return!1}return!0},Xc=10,eu=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))},Vo=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,d=r.collections[a];if(s.collections?.[a]?.restrictEntities||s?.collections?.[a]?.recordOwner?.active||s?.collections?.[a]?.recordUser?.active||s?.collections?.[a]?.recordProperty?.active){const u=i?.collections?.[a],f=[];if(l.individualEntities){const y=l.individualEntities,v=u?.individualEntities||[],p=i?y.filter(g=>!v.includes(g)):y;for(const g 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 ys(n,d,g,t,s))throw new Error("PERMISSION_DENIED")})}}if(l.parentEntities){const y=c.entityRestrictions?.restrictions?.find(x=>x.type==="Parent"&&x.roles.some(E=>E.role===e.Role));if(!y)throw new Error("PERMISSION_DENIED");const v=W(d.fields,y.collectionField),p=r.collections[v.collection],g=l.parentEntities,I=u?.parentEntities||[],k=i?g.filter(x=>!I.includes(x)):g;for(const x of k){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 ys(n,p,x,t,s))throw new Error("PERMISSION_DENIED")})}}if(l.parentPropertyEntities){const y=c.entityRestrictions?.restrictions?.find(k=>k.type==="Parent_Property"&&k.roles.some(x=>x.role===e.Role));if(!y)throw new Error("PERMISSION_DENIED");const v=W(d.fields,y.collectionField),p=r.collections[v.collection],g=l.parentPropertyEntities,I=u?.parentPropertyEntities||{};for(const[k,x]of Object.entries(g)){const E=I[k]||[],F=i?x.filter(_=>!E.includes(_)):x;for(const _ of F){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 ys(n,p,_,t,s))throw new Error("PERMISSION_DENIED")})}}}await eu(f,Xc)}}},tu=async(n,e,t)=>{const s=t?.userId,r=t?.user;let i=t?.context;const o=Ze(),a=vt();if(t?.providedTransaction&&s)throw new Error("PERMISSION_DENIED");if(t?.providedSchema&&s)throw new Error("PERMISSION_DENIED");let l=t?.providedSchema||await ze();if(n.length===0)throw new Error("EMPTY_PATH");const c=n.at(-1),d=Object.keys(l.collections).includes(c),h=a.disabledCollections?.includes(c);if(!d||h)throw new Error("COLLECTION_NOT_FOUND");const u=l.collections[c],{labels:f,fields:y,enableWriteLog:v,softDelete:p}=u,g=qe(f.collection,l),I=await oe(a.appName),k=B.getFirestore(),x=gt.getAuth(),F=(s?await x.getUser(s):void 0)?.customClaims?.role;let _;s&&await or(n,u);const Z=Re(k,n,o),b=t?.id||Z.doc().id;i=i||{},i.collection=f.collection,e.id=b,ar(e),Jn(e);const m=Us("create",n,e,l,I,"Online",s||"System",B.Timestamp.now(),B.FieldValue.serverTimestamp());t?.createdAt&&(m.Created_At=t.createdAt),t?.createdBy&&(m.Created_By=t.createdBy);const L=he(m);p&&(m[p.archivedField]=!1),Ve(e),v&&!t?.providedTransaction&&await yt("create","started",m,o,n,b,u),await ae("preOperation",a,g,{operation:"create",data:m,recordId:b,context:i}),await ae("preWrite",a,g,{operation:"create",data:m,recordId:b,context:i}),Sn(u,m,l),Rn(u,m),await ca(m,u,g,F),Ve(m);try{if(u.auth&&r&&!r.password)throw new Error("Password is required");t?.providedTransaction||(await Mo("create",o,b,m,u,l),await sn("create",m,u,g,{operation:"create",record:m,context:i},l))}catch(T){throw new Error(`VALIDATION_ERROR: ${T.message}`)}Ve(m),e.id=b,p&&(m[p.archivedField]=!1),Sn(u,m,l),Rn(u,m);try{Lo("create",m,L),cr("create",u,m),await sn("create",m,u,g,{operation:"create",record:m,context:i},l)}catch(T){throw new Error(`VALIDATION_ERROR: ${T.message}`)}if(s){const T=F;if(!T)throw new Error("USER_ERROR");if(!(g.custom?.serverAccess?.create!==void 0?await oe(g.custom.serverAccess.create,[T,m]):!0))throw new Error("PERMISSION_DENIED");for(const q of u.fields){if(!(q.name in m))continue;const M=Ae(q,g);if(M?.custom?.serverAccess?.create!==void 0&&!await oe(M.custom.serverAccess.create,[T,m]))throw new Error("PERMISSION_DENIED")}}r&&(r.permissions||={},r.permissions.Role||=m.Role,r.permissions.Enabled||=m.Enabled);const w=async(T,C)=>{const[q,M,Q,O]=await Promise.all([t?.providedTransaction?Promise.resolve({}):T.get(k.collection("system_deployment").doc("latest_deploy")),t?.providedTransaction?Promise.resolve({}):T.get(k.collection("system_deployment").doc("maintenance_mode")),s?T.get(k.collection("tenants").doc(o).collection("system_user_permissions").doc(s)):Promise.resolve({}),t?.providedSchema?Promise.resolve(t.providedSchema):ze()]);if(C&&(C.size+=3),!t?.providedTransaction){if(!q.exists)throw new Error("VERSION_ERROR");const G=q.data();if(G.force&&m.Last_Write_At.valueOf()<G.time.valueOf())throw new Error("VERSION_ERROR");if(!M.exists)throw new Error("MAINTENANCE_MODE");if(M.data().active)throw new Error("MAINTENANCE_MODE")}if(l=O,s){if(!Q?.exists)throw new Error("PERMISSION_DENIED");if(_=Q.data(),!_.Role)throw new Error("USER_ERROR");if(!_.Enabled)throw new Error("PERMISSION_DENIED")}if(!t?.providedTransaction){const z=y.filter(X=>"unique"in X&&X.unique).map(async X=>{if(!s||!X.access||X.access.includes(_.Role)){if(!e[X.name])return;const Ie=Ae(X,g);if(!(s&&Ie?.custom?.serverAccess?.read!==void 0?await oe(Ie.custom.serverAccess.read,[_?.Role,m]):!0))throw new Error("PERMISSION_DENIED");const fe=e[X.name].toString().toLowerCase().replace(/\s/g,"---").replaceAll("/","|||");if(Qs(fe)){if(C&&C.size++,C&&C.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 T.get(k.collection("tenants").doc(o).collection("system_unique").doc(f.collection).collection(`Unique-${f.collection}-${X.name}`).doc(fe)))?.exists)throw new Error(`VALIDATION_ERROR: ${X.name} "${m[X.name]}" already exists`)}else throw new Error(`VALIDATION_ERROR: ${X.name} "${m[X.name]}" is invalid`)}});await Promise.all(z)}fr(m,b,u,l,s,_,r?.permissions),r?.permissions&&s&&_&&await Vo(T,r.permissions,s,_,l),fr(m,b,u,l,s,_,r?.permissions)};if(u.auth&&r){await k.runTransaction(async C=>{await w(C)},{maxAttempts:10});const T=await ir(o,b,a,u,m,r.permissions,r.password);m.User_ID=T}const R=async T=>{try{const C={size:1};await w(T,C),t?.noTwoWay||await lr("Create",o,b,m,m,u,l,T,C,s,_);const q=Vs(l);Js("create",T,n,b,m,l,u,t,q,B.FieldValue.arrayUnion,B.FieldValue.arrayRemove,B.FieldValue.delete,M=>k.collection("tenants").doc(o).collection("system_fields").doc(f.collection).collection(`${f.collection}-${M.name}`).doc(b),(M,Q)=>k.collection("tenants").doc(o).collection("system_unique").doc(f.collection).collection(`Unique-${f.collection}-${M.name}`).doc(Q),M=>k.collection("tenants").doc(o).collection("system_fields").doc(f.collection).collection(`${f.collection}-${M}`).doc(b),(M,Q)=>Re(k,M,o).doc(Q),(M,Q,O)=>k.collection("tenants").doc(o).collection("system_fields").doc(M.collection).collection(`${M.collection}-${Q}`).doc(O),(M,Q,O)=>k.collection("tenants").doc(o).collection("system_fields").doc(M.collection).collection(`${M.collection}-${Q.replaceAll(" ","-")}`).doc(O),void 0,void 0,C),T.set(Z.doc(b),m)}catch(C){if(t?.providedTransaction)throw C;{const M=await ae("postWriteError",a,g,{operation:"create",data:m,recordId:b,context:i,error:C});if(v&&(await new Promise(Q=>{setTimeout(Q,250)}),await yt("create",M?.resolved?"success":"failed",m,o,n,b,u,M?.resolved?void 0:C)),!M?.resolved)throw u.auth&&r&&await Wt(m),C}}};if(t?.providedTransaction?await R(t.providedTransaction):await k.runTransaction(async T=>{await R(T)},{maxAttempts:10}),!t?.providedTransaction){const T={operation:"create",data:m,recordId:b,context:i},C={...T};await ae("postWrite",a,g,T),await ae("postOperation",a,g,C)}return{id:b,...m}},Qt=async(n,e,t,s)=>{const r=Ze(),i=gt.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}`)},Uo=async(n,e,t,s,r,i,o,a,l,c,d)=>{const h=gt.getAuth(),u=B.getFirestore(),f={};for(const p of r.fields)p.addToAuthToken&&!rr(p.name)&&i[p.name]!==void 0&&p.type!=="Timestamp"&&p.type!=="Computed"&&p.type!=="Embedding"&&(ke(i[p.name])?f[p.name]=null:f[p.name]=i[p.name]);const y="USER_ERROR";let v="";if(n==="create"){if(!d)throw new Error("VALIDATION_ERROR: Password is required");if(!l)throw new Error("VALIDATION_ERROR: Permissions are required");try{v=await ir(e,t,s,r,i,l,d)}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),d&&(p.password=d),Object.keys(p).length)try{await h.updateUser(o.User_ID,p),p.disabled===!0&&await h.revokeRefreshTokens(o.User_ID)}catch{throw await Qt(o.User_ID,a,c,y),new Error(y)}if(i.Role&&i.Role!==o.Role||Object.keys(f).length)try{const g={...Yc(a.customClaims),...f};await h.setCustomUserClaims(o.User_ID,{...g,tenant:e,role:i.Role,collection:r.labels.collection,doc:t}),await h.revokeRefreshTokens(o.User_ID)}catch{throw await Qt(o.User_ID,a,c,y),new Error(y)}try{await u.collection("tenants").doc(e).collection("system_user_permissions").doc(o.User_ID).set({...l||c,Collection:r.labels.collection,Doc_ID:t,Role:i.Role,Enabled:i.Enabled??o.Enabled??!1})}catch{throw await Qt(o.User_ID,a,c,y),new Error(y)}if(o.Email!==i.Email){const g=s.auth.enableMultiFactorAuth;if(g===!0||typeof g=="object"&&g.includes(i.Role)){let I=await h.generateEmailVerificationLink(i.Email).catch(()=>{throw new Error("Error generating email verification link")});if(I.includes("apiKey=&")){const k=JSON.parse(process.env.STOKER_FB_WEB_APP_CONFIG);I=I.replace("apiKey=&",`apiKey=${k.apiKey}&`)}if(I){const k=`https://${h.app.options.projectId}.firebaseapp.com/__/auth/action${I}`,x=await oe(s.appName),E=s?.mail?.emailVerification&&s.mail.emailVerification(k,x);try{await sr(i.Email,E?.subject||"Please verify your email address",void 0,E?.html||`Please verify your email address by clicking the link:
11
+ <a href="${g}">${g}</a>`)}catch{throw await u(r,h),new Error(h)}}}return f.uid},or=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")},Wn=n=>n!==null&&typeof n=="object"&&!Array.isArray(n),Jc=n=>{const e=t=>{Object.entries(t).forEach(([s,r])=>{Wn(r)&&Object.keys(r).length===2&&typeof r.seconds=="number"&&typeof r.nanoseconds=="number"?t[s]=new B.Timestamp(r.seconds,r.nanoseconds):Wn(r)&&e(r)})};e(n)},ar=n=>{const e=t=>{Object.entries(t).forEach(([s,r])=>{Wn(r)&&Object.keys(r).length===2&&typeof r._seconds=="number"&&typeof r._nanoseconds=="number"?t[s]=new B.Timestamp(r._seconds,r._nanoseconds):Wn(r)&&e(r)})};e(n)},Jn=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():Jn(n[e]))},Qc=(n,e,t)=>{if(ee(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);wt(n,[i]).size===1&&(s[`${r}_Lowercase`]=e[`${r}_Lowercase`])}}),s}return{}},ai=async(n,e,t,s,r,i,o)=>{if(!ee(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[d,h]=c[0];if(!h)throw new Error(`VALIDATION_ERROR: Relation ${t.name} is required`);const u=Re(l,h.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(u.doc(d));if(!f.exists)throw new Error(`VALIDATION_ERROR: Record ${d} not found in collection ${t.collection}`);const y=f.data(),v=W(a,t.enforceHierarchy.field),p=t.enforceHierarchy;if(!y[p.recordLinkField]||!s[v.name]||!Object.keys(s[v.name]).every(g=>Object.keys(y[p.recordLinkField]).includes(g)))throw new Error("VALIDATION_ERROR: Invalid relation hierarchy")},gn=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`]},ps=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`]={id:s,...t})},Kc=(n,e,t,s,r,i)=>{const o=[],a=[];for(const l of s.fields)ee(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}},lr=async(n,e,t,s,r,i,o,a,l,c,d,h)=>{const{fields:u}=i,f=B.getFirestore(),y=new Map,v=new Map,p=new Map;for(const g of u)ee(g)&&["OneToOne","OneToMany"].includes(g.type)&&g.enforceHierarchy&&s[g.name]&&(n==="Create"||n==="Update"&&!He(h?.[g.name],s[g.name]))&&await ai(e,i,g,s,a,l);for(const g of u)if(ee(g)&&g.twoWay){const I=o.collections[g.collection],k=W(I.fields,g.twoWay),x=dt(I,[k]);if(s[g.name]){const E=Object.entries(s[g.name]);for(const F of E){const[_,Z]=F;if(n==="Create"||!h?.[g.name]?.[_]){let b;const m=p.get(g.collection)?.[_];if(m)b=m;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 N=Re(f,Z.Collection_Path,e),D=await a.get(N.doc(_));if(!D.exists){gn(g,r,_);continue}const w=D.data();v.set(g.collection,{...v.get(g.collection)||{},[_]:w}),b=he({...w,...Tn(s)})}const L={...b[k.name],[t]:{Collection_Path:s.Collection_Path,...Qc(i,s,k)}};b[k.name]=L,b[`${k.name}_Array`]||=[],b[`${k.name}_Array`].push(t),x.size===1&&(b[`${k.name}_Single`]={id:t,...L}),p.set(g.collection,{...p.get(g.collection)||{},[_]:b})}}}if(n==="Update"){const E=Object.entries(h?.[g.name]||{});for(const F of E){const[_,Z]=F;if(!s[g.name]?.[_]){let b;const m=p.get(g.collection)?.[_];if(m)b=m;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 L=Re(f,Z.Collection_Path,e),N=await a.get(L.doc(_));if(!N.exists){y.set(g.name,[...y.get(g.name)||[],_]);continue}const D=N.data();v.set(g.collection,{...v.get(g.collection)||{},[_]:D}),b=he({...D,...Tn(s)})}b[k.name][t]&&delete b[k.name][t],Array.isArray(b[`${k.name}_Array`])&&(b[`${k.name}_Array`]=b[`${k.name}_Array`].filter(L=>L!==t)),x.size===1&&delete b[`${k.name}_Single`],p.set(g.collection,{...p.get(g.collection)||{},[_]:b})}}}}for(const[g,I]of p.entries()){const k=o.collections[g],x=qe(g,o);for(const[E,F]of Object.entries(I)){const{addedFields:_,removedFields:Z}=Kc(n,E,g,i,s,h);if(c&&d){for(const b of _){const m=W(k.fields,b.twoWay);if(!dr(k,m,d)){gn(b,r,E);continue}}for(const b of Z){const m=W(k.fields,b.twoWay),L=dt(k,[m]);if(!dr(k,m,d)){ps(b,r,h?.[b.name]?.[E],E,L.size===1);continue}}if(!it("Update",k,o,c,d,v.get(g)?.[E])){for(const b of _)gn(b,r,E);for(const b of Z){const m=W(k.fields,b.twoWay),L=dt(k,[m]);ps(b,r,h?.[b.name]?.[E],E,L.size===1)}}if(!it("Update",k,o,c,d,F)){for(const b of _)gn(b,r,E);for(const b of Z){const m=W(k.fields,b.twoWay),L=dt(k,[m]);ps(b,r,h?.[b.name]?.[E],E,L.size===1)}}}try{await sn("update",F,k,x,{operation:"update",record:F,context:{},originalRecord:F},o)}catch(b){throw new Error(`VALIDATION_ERROR: Two way relation update would invalidate record ${E} in ${g}: ${b.message}`)}for(const b of _){const m=W(k.fields,b.twoWay);["OneToOne","OneToMany"].includes(m.type)&&ee(m)&&m.enforceHierarchy&&await ai(e,k,m,F,a,l,!0)}}}return y},Lo=(n,e,t)=>{n==="create"&&mt.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}`)}),mt.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}`)}))},cr=(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")}},ys=async(n,e,t,s,r)=>{if(!Te("Read",r.collections?.[e.labels.collection]))return!1;try{await Qe([e.labels.collection],t,{userId:s,providedTransaction:n})}catch{return!1}return!0},Xc=10,eu=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))},Vo=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,d=r.collections[a];if(s.collections?.[a]?.restrictEntities||s?.collections?.[a]?.recordOwner?.active||s?.collections?.[a]?.recordUser?.active||s?.collections?.[a]?.recordProperty?.active){const u=i?.collections?.[a],f=[];if(l.individualEntities){const y=l.individualEntities,v=u?.individualEntities||[],p=i?y.filter(g=>!v.includes(g)):y;for(const g 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 ys(n,d,g,t,s))throw new Error("PERMISSION_DENIED")})}}if(l.parentEntities){const y=c.entityRestrictions?.restrictions?.find(x=>x.type==="Parent"&&x.roles.some(E=>E.role===e.Role));if(!y)throw new Error("PERMISSION_DENIED");const v=W(d.fields,y.collectionField),p=r.collections[v.collection],g=l.parentEntities,I=u?.parentEntities||[],k=i?g.filter(x=>!I.includes(x)):g;for(const x of k){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 ys(n,p,x,t,s))throw new Error("PERMISSION_DENIED")})}}if(l.parentPropertyEntities){const y=c.entityRestrictions?.restrictions?.find(k=>k.type==="Parent_Property"&&k.roles.some(x=>x.role===e.Role));if(!y)throw new Error("PERMISSION_DENIED");const v=W(d.fields,y.collectionField),p=r.collections[v.collection],g=l.parentPropertyEntities,I=u?.parentPropertyEntities||{};for(const[k,x]of Object.entries(g)){const E=I[k]||[],F=i?x.filter(_=>!E.includes(_)):x;for(const _ of F){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 ys(n,p,_,t,s))throw new Error("PERMISSION_DENIED")})}}}await eu(f,Xc)}}},tu=async(n,e,t)=>{const s=t?.userId,r=t?.user;let i=t?.context;const o=Ze(),a=vt();if(t?.providedTransaction&&s)throw new Error("PERMISSION_DENIED");if(t?.providedSchema&&s)throw new Error("PERMISSION_DENIED");let l=t?.providedSchema||await ze();if(n.length===0)throw new Error("EMPTY_PATH");const c=n.at(-1),d=Object.keys(l.collections).includes(c),h=a.disabledCollections?.includes(c);if(!d||h)throw new Error("COLLECTION_NOT_FOUND");const u=l.collections[c],{labels:f,fields:y,enableWriteLog:v,softDelete:p}=u,g=qe(f.collection,l),I=await oe(a.appName),k=B.getFirestore(),x=gt.getAuth(),F=(s?await x.getUser(s):void 0)?.customClaims?.role;let _;s&&await or(n,u);const Z=Re(k,n,o),b=t?.id||Z.doc().id;i=i||{},i.collection=f.collection,e.id=b,ar(e),Jn(e);const m=Us("create",n,e,l,I,"Online",s||"System",B.Timestamp.now(),B.FieldValue.serverTimestamp());t?.createdAt&&(m.Created_At=t.createdAt),t?.createdBy&&(m.Created_By=t.createdBy);const L=he(m);p&&(m[p.archivedField]=!1),Ve(e),v&&!t?.providedTransaction&&await yt("create","started",m,o,n,b,u),await ae("preOperation",a,g,{operation:"create",data:m,recordId:b,context:i}),await ae("preWrite",a,g,{operation:"create",data:m,recordId:b,context:i}),Sn(u,m,l),Rn(u,m),await ca(m,u,g,F),Ve(m);try{if(u.auth&&r&&!r.password)throw new Error("Password is required");t?.providedTransaction||(await Mo("create",o,b,m,u,l),await sn("create",m,u,g,{operation:"create",record:m,context:i},l))}catch(T){throw new Error(`VALIDATION_ERROR: ${T.message}`)}Ve(m),e.id=b,p&&(m[p.archivedField]=!1),Sn(u,m,l),Rn(u,m);try{Lo("create",m,L),cr("create",u,m),await sn("create",m,u,g,{operation:"create",record:m,context:i},l)}catch(T){throw new Error(`VALIDATION_ERROR: ${T.message}`)}if(s){const T=F;if(!T)throw new Error("USER_ERROR");if(!(g.custom?.serverAccess?.create!==void 0?await oe(g.custom.serverAccess.create,[T,m]):!0))throw new Error("PERMISSION_DENIED");for(const q of u.fields){if(!(q.name in m))continue;const M=Ae(q,g);if(M?.custom?.serverAccess?.create!==void 0&&!await oe(M.custom.serverAccess.create,[T,m]))throw new Error("PERMISSION_DENIED")}}r&&(r.permissions||={},r.permissions.Role||=m.Role,r.permissions.Enabled||=m.Enabled);const w=async(T,C)=>{const[q,M,Q,O]=await Promise.all([t?.providedTransaction?Promise.resolve({}):T.get(k.collection("system_deployment").doc("latest_deploy")),t?.providedTransaction?Promise.resolve({}):T.get(k.collection("system_deployment").doc("maintenance_mode")),s?T.get(k.collection("tenants").doc(o).collection("system_user_permissions").doc(s)):Promise.resolve({}),t?.providedSchema?Promise.resolve(t.providedSchema):ze()]);if(C&&(C.size+=3),!t?.providedTransaction){if(!q.exists)throw new Error("VERSION_ERROR");const G=q.data();if(G.force&&m.Last_Write_At.valueOf()<G.time.valueOf())throw new Error("VERSION_ERROR");if(!M.exists)throw new Error("MAINTENANCE_MODE");if(M.data().active)throw new Error("MAINTENANCE_MODE")}if(l=O,s){if(!Q?.exists)throw new Error("PERMISSION_DENIED");if(_=Q.data(),!_.Role)throw new Error("USER_ERROR");if(!_.Enabled)throw new Error("PERMISSION_DENIED")}if(!t?.providedTransaction){const z=y.filter(X=>"unique"in X&&X.unique).map(async X=>{if(!s||!X.access||X.access.includes(_.Role)){if(!e[X.name])return;const Ie=Ae(X,g);if(!(s&&Ie?.custom?.serverAccess?.read!==void 0?await oe(Ie.custom.serverAccess.read,[_?.Role,m]):!0))throw new Error("PERMISSION_DENIED");const fe=e[X.name].toString().toLowerCase().replace(/\s/g,"---").replaceAll("/","|||");if(Qs(fe)){if(C&&C.size++,C&&C.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 T.get(k.collection("tenants").doc(o).collection("system_unique").doc(f.collection).collection(`Unique-${f.collection}-${X.name}`).doc(fe)))?.exists)throw new Error(`VALIDATION_ERROR: ${X.name} "${m[X.name]}" already exists`)}else throw new Error(`VALIDATION_ERROR: ${X.name} "${m[X.name]}" is invalid`)}});await Promise.all(z)}fr(m,b,u,l,s,_,r?.permissions),r?.permissions&&s&&_&&await Vo(T,r.permissions,s,_,l),fr(m,b,u,l,s,_,r?.permissions)};if(u.auth&&r){await k.runTransaction(async C=>{await w(C)},{maxAttempts:10});const T=await ir(o,b,a,u,m,r.permissions,r.password);m.User_ID=T}const R=async T=>{try{const C={size:1};await w(T,C),t?.noTwoWay||await lr("Create",o,b,m,m,u,l,T,C,s,_);const q=Vs(l);Js("create",T,n,b,m,l,u,t,q,B.FieldValue.arrayUnion,B.FieldValue.arrayRemove,B.FieldValue.delete,M=>k.collection("tenants").doc(o).collection("system_fields").doc(f.collection).collection(`${f.collection}-${M.name}`).doc(b),(M,Q)=>k.collection("tenants").doc(o).collection("system_unique").doc(f.collection).collection(`Unique-${f.collection}-${M.name}`).doc(Q),M=>k.collection("tenants").doc(o).collection("system_fields").doc(f.collection).collection(`${f.collection}-${M}`).doc(b),(M,Q)=>Re(k,M,o).doc(Q),(M,Q,O)=>k.collection("tenants").doc(o).collection("system_fields").doc(M.collection).collection(`${M.collection}-${Q}`).doc(O),(M,Q,O)=>k.collection("tenants").doc(o).collection("system_fields").doc(M.collection).collection(`${M.collection}-${Q.replaceAll(" ","-")}`).doc(O),void 0,void 0,C),T.set(Z.doc(b),m)}catch(C){if(t?.providedTransaction)throw C;{const M=await ae("postWriteError",a,g,{operation:"create",data:m,recordId:b,context:i,error:C});if(v&&(await new Promise(Q=>{setTimeout(Q,250)}),await yt("create",M?.resolved?"success":"failed",m,o,n,b,u,M?.resolved?void 0:C)),!M?.resolved)throw u.auth&&r&&await Wt(m),C}}};if(t?.providedTransaction?await R(t.providedTransaction):await k.runTransaction(async T=>{await R(T)},{maxAttempts:10}),!t?.providedTransaction){const T={operation:"create",data:m,recordId:b,context:i},C={...T};await ae("postWrite",a,g,T),await ae("postOperation",a,g,C)}return{id:b,...m}},Qt=async(n,e,t,s)=>{const r=Ze(),i=gt.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}`)},Uo=async(n,e,t,s,r,i,o,a,l,c,d)=>{const h=gt.getAuth(),u=B.getFirestore(),f={};for(const p of r.fields)p.saveToAuthToken&&!rr(p.name)&&i[p.name]!==void 0&&p.type!=="Timestamp"&&p.type!=="Computed"&&p.type!=="Embedding"&&(ke(i[p.name])?f[p.name]=null:f[p.name]=i[p.name]);const y="USER_ERROR";let v="";if(n==="create"){if(!d)throw new Error("VALIDATION_ERROR: Password is required");if(!l)throw new Error("VALIDATION_ERROR: Permissions are required");try{v=await ir(e,t,s,r,i,l,d)}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),d&&(p.password=d),Object.keys(p).length)try{await h.updateUser(o.User_ID,p),p.disabled===!0&&await h.revokeRefreshTokens(o.User_ID)}catch{throw await Qt(o.User_ID,a,c,y),new Error(y)}if(i.Role&&i.Role!==o.Role||Object.keys(f).length)try{const g={...Yc(a.customClaims),...f};await h.setCustomUserClaims(o.User_ID,{...g,tenant:e,role:i.Role,collection:r.labels.collection,doc:t}),await h.revokeRefreshTokens(o.User_ID)}catch{throw await Qt(o.User_ID,a,c,y),new Error(y)}try{await u.collection("tenants").doc(e).collection("system_user_permissions").doc(o.User_ID).set({...l||c,Collection:r.labels.collection,Doc_ID:t,Role:i.Role,Enabled:i.Enabled??o.Enabled??!1})}catch{throw await Qt(o.User_ID,a,c,y),new Error(y)}if(o.Email!==i.Email){const g=s.auth.enableMultiFactorAuth;if(g===!0||typeof g=="object"&&g.includes(i.Role)){let I=await h.generateEmailVerificationLink(i.Email).catch(()=>{throw new Error("Error generating email verification link")});if(I.includes("apiKey=&")){const k=JSON.parse(process.env.STOKER_FB_WEB_APP_CONFIG);I=I.replace("apiKey=&",`apiKey=${k.apiKey}&`)}if(I){const k=`https://${h.app.options.projectId}.firebaseapp.com/__/auth/action${I}`,x=await oe(s.appName),E=s?.mail?.emailVerification&&s.mail.emailVerification(k,x);try{await sr(i.Email,E?.subject||"Please verify your email address",void 0,E?.html||`Please verify your email address by clicking the link:
12
12
  </br>
13
13
  </br>
14
- <a href="${k}">${k}</a>`)}catch{throw await Qt(o.User_ID,a,c,y),new Error(y)}}}}}else if(n==="delete")try{await Wt(o)}catch(p){throw new Error(p.message)}if(v)return v},nu=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})},li=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()},Wo=async(n,e,t,s)=>{const r=s?.userId,i=s?.user;let o=s?.context;const a=Ze(),l=vt();if(s?.providedTransaction&&r)throw new Error("PERMISSION_DENIED");if(s?.providedSchema&&r)throw new Error("PERMISSION_DENIED");if(s?.providedTransaction&&!s?.originalRecord)throw new Error("PERMISSION_DENIED");let c=s?.providedSchema||await ze(!0);if(n.length===0)throw new Error("EMPTY_PATH");const d=n.at(-1),h=Object.keys(c.collections).includes(d),u=l.disabledCollections?.includes(d);if(!h||u)throw new Error("COLLECTION_NOT_FOUND");const f=c.collections[d],{labels:y,fields:v,enableWriteLog:p}=f,g=qe(y.collection,c),I=await oe(l.appName),k=gt.getAuth(),x=B.getFirestore();let E;r&&await or(n,f);const F=Re(x,n,a);o=o||{},o.collection=y.collection;let _=s?.originalRecord||await Qe(n,e,{userId:r,noComputedFields:!0,noEmbeddingFields:!0});for(const O of v)O.type==="Computed"&&delete t[O.name];if(c={...c,collections:Object.fromEntries(Object.entries(c.collections).map(([O,G])=>[O,{...G,fields:G.fields.filter(z=>z.type!=="Computed")}]))},i&&!i.operation)throw new Error("VALIDATION_ERROR: User operation is required");if(i&&!f.auth)throw new Error("VALIDATION_ERROR: User operations are only permitted for auth collections");if(i?.operation==="delete"&&i.permissions)throw new Error("VALIDATION_ERROR: Permissions are not allowed for delete operations");const Z=f.fields.filter(O=>O.addToAuthToken&&!rr(O.name)),b=f.auth&&i?.operation==="create",m=f.auth&&i?.operation==="delete",L=f.auth&&!b&&!m&&(i?.operation==="update"||t.Role||t.Enabled!==void 0||t.Name||t.Email||t.Photo_URL||Z.some(O=>t[O.name]!==void 0)),N=O=>O.User_ID&&(f.auth&&!b&&!m&&i?.operation==="update"||t.Role&&t.Role!==O.Role||t.Enabled!==void 0&&t.Enabled!==O.Enabled||t.Name&&t.Name!==O.Name||t.Email&&t.Email!==O.Email||t.Photo_URL&&t.Photo_URL!==O.Photo_URL||Z.some(G=>t[G.name]!==void 0&&t[G.name]!==O[G.name]));delete t.id,ar(t),Jn(t);const D=Us("update",n,t,c,I,"Online",r||"System",B.Timestamp.now(),B.FieldValue.serverTimestamp()),w=he(D);for(const O of v)!ee(O)&&ke(D[O.name])&&O.nullable&&(D[O.name]=null);Ve(D),Ve(_),p&&!s?.providedTransaction&&await yt("update","started",D,a,n,e,f,void 0,_);const R={operation:"update",data:D,recordId:e,context:o,originalRecord:he(_)};await ae("preOperation",l,g,R);const S={operation:"update",data:D,recordId:e,context:o,originalRecord:he(_)};await ae("preWrite",l,g,S),Sn(f,D,c),Rn(f,D),Ve(D);try{if(b&&!i.password)throw new Error("Password is required");if(!s?.providedTransaction){const O={..._,...D};await Mo("update",a,e,O,f,c),nt(O),await sn("update",O,f,g,{operation:"update",record:D,context:o,originalRecord:he(_)},c)}}catch(O){throw new Error(`VALIDATION_ERROR: ${O.message}`)}Ve(D),delete t.id,Sn(f,D,c),Rn(f,D);for(const O of v)!ee(O)&&ke(D[O.name])&&O.nullable&&(D[O.name]=null);try{const O={..._,...D};nt(O),cr("update",f,D,_),Lo("update",D,w),await sn("update",O,f,g,{operation:"update",record:D,context:o,originalRecord:_},c)}catch(O){throw new Error(`VALIDATION_ERROR: ${O.message}`)}let T;i&&(i.permissions||={});const C=async(O,G,z)=>{const[X,Ie,at,fe,Le]=await Promise.all([s?.providedTransaction?Promise.resolve({}):O.get(x.collection("system_deployment").doc("latest_deploy")),s?.providedTransaction?Promise.resolve({}):O.get(x.collection("system_deployment").doc("maintenance_mode")),s?.providedTransaction?Promise.resolve(_):Qe(n,e,{userId:r,providedTransaction:O,noComputedFields:!0}),r?O.get(x.collection("tenants").doc(a).collection("system_user_permissions").doc(r)):Promise.resolve({}),s?.providedSchema?Promise.resolve(s.providedSchema):ze()]);if(z&&(z.size+=3),!s?.providedTransaction){if(!X.exists)throw new Error("VERSION_ERROR");const Ee=X.data();if(Ee.force&&D.Last_Write_At.valueOf()<Ee.time.valueOf())throw new Error("VERSION_ERROR");if(!Ie.exists)throw new Error("MAINTENANCE_MODE");if(Ie.data().active)throw new Error("MAINTENANCE_MODE")}if(!at)throw new Error("NOT_FOUND");if(_=at,c=Le,r){if(!fe?.exists)throw new Error("PERMISSION_DENIED");if(E=fe.data(),!E.Role)throw new Error("USER_ERROR");if(!E.Enabled)throw new Error("PERMISSION_DENIED")}if(z&&(z.size+=er(a,n,e,c,E).length),b&&_.User_ID||m&&!_.User_ID)throw new Error("USER_ERROR");if(N(_)){const Ee=await O.get(x.collection("tenants").doc(a).collection("system_user_permissions").doc(_.User_ID));if(z&&z.size++,!Ee?.exists)throw new Error("PERMISSION_DENIED");if(T=Ee.data(),i?.permissions){if(i.permissions.Role||=D.Role||_.Role,i.permissions.Enabled??=D.Enabled??_.Enabled,ke(i.permissions.Role))throw new Error("VALIDATION_ERROR: Role field is required");if(ke(i.permissions.Enabled))throw new Error("VALIDATION_ERROR: Enabled field is required")}}if(!s?.providedTransaction){const jt=v.filter(ge=>"unique"in ge&&ge.unique).map(async ge=>{if(!r||!ge.access||ge.access.includes(E.Role)){if(D[ge.name]===void 0||ke(D[ge.name]))return;const zt=Ae(ge,g),un={..._,...D};if(!(r&&zt?.custom?.serverAccess?.read!==void 0?await oe(zt.custom.serverAccess.read,[E?.Role,un]):!0))throw new Error("PERMISSION_DENIED");const Qn=D[ge.name].toString().toLowerCase().replace(/\s/g,"---").replaceAll("/","|||");if(Qs(Qn)){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 ur=await O.get(x.collection("tenants").doc(a).collection("system_unique").doc(y.collection).collection(`Unique-${y.collection}-${ge.name}`).doc(Qn));if(ur.exists&&ur.data().id!==e)throw new Error(`VALIDATION_ERROR: ${ge.name} "${D[ge.name]}" already exists`)}else throw new Error(`VALIDATION_ERROR: ${ge.name} "${D[ge.name]}" is invalid`)}});await Promise.all(jt)}if(r&&E?.Role){const Ee=E.Role,jt={..._,...D};if(!(g.custom?.serverAccess?.update!==void 0?await oe(g.custom.serverAccess.update,[Ee,jt,_]):!0))throw new Error("PERMISSION_DENIED");for(const zt of f.fields){const un=Ae(zt,g);if(Object.prototype.hasOwnProperty.call(D,zt.name)&&un?.custom?.serverAccess?.update!==void 0&&!await oe(un.custom.serverAccess.update,[Ee,jt,_]))throw new Error("PERMISSION_DENIED")}}hr(D,_,e,f,c,r,E,i?.operation?i.operation:L?"update":void 0,i?.permissions,T),i?.permissions&&r&&E&&await Vo(O,i.permissions,r,E,c,T,z),hr(D,_,e,f,c,r,E,i?.operation?i.operation:L?"update":void 0,i?.permissions,T),G&&(b||N(_)||m)&&await nu(O,e,_.User_ID)};(b||L||m)&&await x.runTransaction(async O=>{await C(O,!0)},{maxAttempts:10});const q=async(O,G)=>{if(!_)throw new Error("NOT_FOUND");try{const z={size:1},X={..._,...D};await C(O,!1,z);let Ie;!s?.noTwoWay&&!s?.providedTransaction&&(Ie=await lr("Update",a,e,X,D,f,c,O,z,r,E,_));const at=Vs(c);Js("update",O,n,e,D,c,f,s,at,B.FieldValue.arrayUnion,B.FieldValue.arrayRemove,B.FieldValue.delete,fe=>x.collection("tenants").doc(a).collection("system_fields").doc(y.collection).collection(`${y.collection}-${fe.name}`).doc(e),(fe,Le)=>x.collection("tenants").doc(a).collection("system_unique").doc(y.collection).collection(`Unique-${y.collection}-${fe.name}`).doc(Le),fe=>x.collection("tenants").doc(a).collection("system_fields").doc(y.collection).collection(`${y.collection}-${fe}`).doc(e),(fe,Le)=>Re(x,fe,a).doc(Le),(fe,Le,Ee)=>x.collection("tenants").doc(a).collection("system_fields").doc(fe.collection).collection(`${fe.collection}-${Le}`).doc(Ee),(fe,Le,Ee)=>x.collection("tenants").doc(a).collection("system_fields").doc(fe.collection).collection(`${fe.collection}-${Le.replaceAll(" ","-")}`).doc(Ee),_,Ie,z),O.update(F.doc(e),D)}catch(z){if(s?.providedTransaction)throw z;{const X={operation:"update",data:D,recordId:e,context:o,error:z,originalRecord:he(_)},Ie=await ae("postWriteError",l,g,X);if(p&&(await new Promise(at=>{setTimeout(at,250)}),await yt("update",Ie?.resolved?"success":"failed",D,a,n,e,f,Ie?.resolved?void 0:z,_)),!Ie?.resolved)throw b&&await Wt(_),N(_)&&await Qt(_.User_ID,G,T,"USER_ERROR"),m&&await x.collection("tenants").doc(a).collection(y.collection).doc(e).update({User_ID:B.FieldValue.delete()}),z}}(b||N(_)||m)&&await ri(li,[e,_.User_ID]).catch(()=>{throw new Error("USER_ERROR")})};try{let O;if(b||N(_)||m){if(N(_)){O=await k.getUser(_.User_ID);const X=O.customClaims;if(!(X&&X.role&&X.collection&&X.doc))throw new Error("USER_ERROR")}const G={..._,...D};nt(G);const z=await Uo(i?.operation||"update",a,e,l,f,G,_,O,i?.permissions,T,i?.password);b&&(D.User_ID=z),m&&(D.User_ID=B.FieldValue.delete())}s?.providedTransaction?await q(s.providedTransaction,O):await x.runTransaction(async G=>{await q(G,O)},{maxAttempts:10})}catch(O){throw(b||N(_)||m)&&await ri(li,[e,_.User_ID]).catch(()=>{throw new Error("USER_ERROR")}),O}if(!s?.providedTransaction){const O={operation:"update",data:D,recordId:e,context:o,originalRecord:he(_)},G={...O};await ae("postWrite",l,g,O),await ae("postOperation",l,g,G)}const M={..._,...D};return nt(M),{id:e,...M}},su=async(n,e,t)=>{const s=t?.userId;let r=t?.context;const i=Ze(),o=vt();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),d=o.disabledCollections?.includes(l);if(!c||d)throw new Error("COLLECTION_NOT_FOUND");const h=a.collections[l],{labels:u,auth:f,enableWriteLog:y,softDelete:v}=h,p=qe(u.collection,a),g=await oe(o.appName);if(v&&!f&&!t?.force)return await Wo(n,e,{[v.archivedField]:!0,[v.timestampField]:B.FieldValue.serverTimestamp()},{userId:s});const I=B.getFirestore();let k;s&&await or(n,h);const x=Re(I,n,i);r=r||{},r.collection=u.collection;const E=await Qe(n,e,{userId:s});let F=Us("delete",n,E,a,g,"Online",s||"System",B.Timestamp.now(),B.FieldValue.serverTimestamp());const _=Tn(F);Ve(F),y&&await yt("delete","started",F,i,n,e,h),await ae("preOperation",o,p,{operation:"delete",data:F,recordId:e,context:r}),await ae("preWrite",o,p,{operation:"delete",data:F,recordId:e,context:r}),Ve(F);const m=async w=>{const[R,S,T,C]=await Promise.all([w.get(I.collection("system_deployment").doc("maintenance_mode")),Qe(n,e,{userId:s,providedTransaction:w}),s?w.get(I.collection("tenants").doc(i).collection("system_user_permissions").doc(s)):Promise.resolve({}),ze()]);if(!R.exists)throw new Error("MAINTENANCE_MODE");if(R.data().active)throw new Error("MAINTENANCE_MODE");if(!S)throw new Error("NOT_FOUND");if(F={...S,..._},a=C,s){if(!T?.exists)throw new Error("PERMISSION_DENIED");if(k=T.data(),!k.Role)throw new Error("USER_ERROR");if(!k.Enabled)throw new Error("PERMISSION_DENIED");Xo(F,e,h,a,s,k)}if(s&&k?.Role){const M=k.Role;if(!(p.custom?.serverAccess?.delete!==void 0?await oe(p.custom.serverAccess.delete,[M,F]):!0))throw new Error("PERMISSION_DENIED")}};h.auth&&(await I.runTransaction(async w=>{await m(w)},{maxAttempts:10}),F.User_ID&&await Wt(F));try{await I.runTransaction(async w=>{await m(w);const R=Vs(a);Js("delete",w,n,e,F,a,h,t,R,B.FieldValue.arrayUnion,B.FieldValue.arrayRemove,B.FieldValue.delete,S=>I.collection("tenants").doc(i).collection("system_fields").doc(u.collection).collection(`${u.collection}-${S.name}`).doc(e),(S,T)=>I.collection("tenants").doc(i).collection("system_unique").doc(u.collection).collection(`Unique-${u.collection}-${S.name}`).doc(T),S=>I.collection("tenants").doc(i).collection("system_fields").doc(u.collection).collection(`${u.collection}-${S}`).doc(e),(S,T)=>Re(I,S,i).doc(T),(S,T,C)=>I.collection("tenants").doc(i).collection("system_fields").doc(S.collection).collection(`${S.collection}-${T}`).doc(C),(S,T,C)=>I.collection("tenants").doc(i).collection("system_fields").doc(S.collection).collection(`${S.collection}-${T.replaceAll(" ","-")}`).doc(C)),w.delete(x.doc(e))},{maxAttempts:10})}catch(w){const S=await ae("postWriteError",o,p,{operation:"delete",data:F,recordId:e,context:r,error:w});if(y&&(await new Promise(T=>{setTimeout(T,250)}),await yt("delete",S?.resolved?"success":"failed",F,i,n,e,h,S?.resolved?void 0:w)),!S?.resolved)throw h.auth&&F.User_ID&&await I.collection("tenants").doc(i).collection(u.collection).doc(e).update({User_ID:B.FieldValue.delete()}),w}const L={operation:"delete",data:F,recordId:e,context:r},N={...L};return await ae("postWrite",o,p,L),await ae("postOperation",o,p,N),{id:e,...F}},ru=async(n,e)=>{const t=B.getFirestore(),s=Ks(),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)},iu=n=>n!==null&&typeof n=="object",ou=n=>{const e=t=>{Object.entries(t).forEach(([s,r])=>{r instanceof B.Timestamp?t[s]={_seconds:r.seconds,_nanoseconds:r.nanoseconds}:iu(r)&&e(r)})};e(n)},au=async n=>await gt.getAuth().getUser(n),lu=n=>{const e=Xs();return V.fromJSDate(n).setZone(e)},jo=n=>{const e=Xs();return V.fromJSDate(n.toDate()).setZone(e)},cu=(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()},uu=(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()},du=n=>"seconds"in n&&"nanoseconds"in n?jo(new B.Timestamp(n.seconds,n.nanoseconds)).toFormat("MMMM d, yyyy '@' h:mm a"):"";exports.addRecord=tu;exports.addUser=ir;exports.convertDateToTimezone=lu;exports.convertTimestampToTimezone=jo;exports.deleteRecord=su;exports.deleteUser=Wt;exports.deserializeDeleteSentinels=Jn;exports.deserializeTimestamps=ar;exports.deserializeTimestampsWithoutUnderscores=Jc;exports.displayDate=du;exports.fetchCurrentSchema=ze;exports.fetchLastSchema=Hc;exports.getCachedConfigValue=ia;exports.getCollectionRefs=Ao;exports.getCustomizationFile=qe;exports.getCustomizationFiles=Io;exports.getDocumentRefs=er;exports.getFirestorePathRef=Re;exports.getGlobalConfigModule=vt;exports.getInputSchema=Vc;exports.getMaintenanceInfo=Zc;exports.getMode=Ks;exports.getOne=Qe;exports.getSome=nr;exports.getTenant=Ze;exports.getTimezone=Xs;exports.getUser=au;exports.getVersionInfo=zc;exports.getZodSchema=bi;exports.initializeFirebase=Bc;exports.initializeStoker=Wc;exports.isDeleteSentinel=ke;exports.keepTimezone=cu;exports.removeTimezone=uu;exports.runChildProcess=qc;exports.sendMail=sr;exports.sendMessage=ru;exports.serializeTimestamps=ou;exports.setTenant=jc;exports.tryPromise=oe;exports.updateRecord=Wo;exports.updateUser=Uo;exports.validateRelations=lr;exports.validateSoftDelete=cr;exports.writeLog=yt;
14
+ <a href="${k}">${k}</a>`)}catch{throw await Qt(o.User_ID,a,c,y),new Error(y)}}}}}else if(n==="delete")try{await Wt(o)}catch(p){throw new Error(p.message)}if(v)return v},nu=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})},li=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()},Wo=async(n,e,t,s)=>{const r=s?.userId,i=s?.user;let o=s?.context;const a=Ze(),l=vt();if(s?.providedTransaction&&r)throw new Error("PERMISSION_DENIED");if(s?.providedSchema&&r)throw new Error("PERMISSION_DENIED");if(s?.providedTransaction&&!s?.originalRecord)throw new Error("PERMISSION_DENIED");let c=s?.providedSchema||await ze(!0);if(n.length===0)throw new Error("EMPTY_PATH");const d=n.at(-1),h=Object.keys(c.collections).includes(d),u=l.disabledCollections?.includes(d);if(!h||u)throw new Error("COLLECTION_NOT_FOUND");const f=c.collections[d],{labels:y,fields:v,enableWriteLog:p}=f,g=qe(y.collection,c),I=await oe(l.appName),k=gt.getAuth(),x=B.getFirestore();let E;r&&await or(n,f);const F=Re(x,n,a);o=o||{},o.collection=y.collection;let _=s?.originalRecord||await Qe(n,e,{userId:r,noComputedFields:!0,noEmbeddingFields:!0});for(const O of v)O.type==="Computed"&&delete t[O.name];if(c={...c,collections:Object.fromEntries(Object.entries(c.collections).map(([O,G])=>[O,{...G,fields:G.fields.filter(z=>z.type!=="Computed")}]))},i&&!i.operation)throw new Error("VALIDATION_ERROR: User operation is required");if(i&&!f.auth)throw new Error("VALIDATION_ERROR: User operations are only permitted for auth collections");if(i?.operation==="delete"&&i.permissions)throw new Error("VALIDATION_ERROR: Permissions are not allowed for delete operations");const Z=f.fields.filter(O=>O.saveToAuthToken&&!rr(O.name)),b=f.auth&&i?.operation==="create",m=f.auth&&i?.operation==="delete",L=f.auth&&!b&&!m&&(i?.operation==="update"||t.Role||t.Enabled!==void 0||t.Name||t.Email||t.Photo_URL||Z.some(O=>t[O.name]!==void 0)),N=O=>O.User_ID&&(f.auth&&!b&&!m&&i?.operation==="update"||t.Role&&t.Role!==O.Role||t.Enabled!==void 0&&t.Enabled!==O.Enabled||t.Name&&t.Name!==O.Name||t.Email&&t.Email!==O.Email||t.Photo_URL&&t.Photo_URL!==O.Photo_URL||Z.some(G=>t[G.name]!==void 0&&t[G.name]!==O[G.name]));delete t.id,ar(t),Jn(t);const D=Us("update",n,t,c,I,"Online",r||"System",B.Timestamp.now(),B.FieldValue.serverTimestamp()),w=he(D);for(const O of v)!ee(O)&&ke(D[O.name])&&O.nullable&&(D[O.name]=null);Ve(D),Ve(_),p&&!s?.providedTransaction&&await yt("update","started",D,a,n,e,f,void 0,_);const R={operation:"update",data:D,recordId:e,context:o,originalRecord:he(_)};await ae("preOperation",l,g,R);const S={operation:"update",data:D,recordId:e,context:o,originalRecord:he(_)};await ae("preWrite",l,g,S),Sn(f,D,c),Rn(f,D),Ve(D);try{if(b&&!i.password)throw new Error("Password is required");if(!s?.providedTransaction){const O={..._,...D};await Mo("update",a,e,O,f,c),nt(O),await sn("update",O,f,g,{operation:"update",record:D,context:o,originalRecord:he(_)},c)}}catch(O){throw new Error(`VALIDATION_ERROR: ${O.message}`)}Ve(D),delete t.id,Sn(f,D,c),Rn(f,D);for(const O of v)!ee(O)&&ke(D[O.name])&&O.nullable&&(D[O.name]=null);try{const O={..._,...D};nt(O),cr("update",f,D,_),Lo("update",D,w),await sn("update",O,f,g,{operation:"update",record:D,context:o,originalRecord:_},c)}catch(O){throw new Error(`VALIDATION_ERROR: ${O.message}`)}let T;i&&(i.permissions||={});const C=async(O,G,z)=>{const[X,Ie,at,fe,Le]=await Promise.all([s?.providedTransaction?Promise.resolve({}):O.get(x.collection("system_deployment").doc("latest_deploy")),s?.providedTransaction?Promise.resolve({}):O.get(x.collection("system_deployment").doc("maintenance_mode")),s?.providedTransaction?Promise.resolve(_):Qe(n,e,{userId:r,providedTransaction:O,noComputedFields:!0}),r?O.get(x.collection("tenants").doc(a).collection("system_user_permissions").doc(r)):Promise.resolve({}),s?.providedSchema?Promise.resolve(s.providedSchema):ze()]);if(z&&(z.size+=3),!s?.providedTransaction){if(!X.exists)throw new Error("VERSION_ERROR");const Ee=X.data();if(Ee.force&&D.Last_Write_At.valueOf()<Ee.time.valueOf())throw new Error("VERSION_ERROR");if(!Ie.exists)throw new Error("MAINTENANCE_MODE");if(Ie.data().active)throw new Error("MAINTENANCE_MODE")}if(!at)throw new Error("NOT_FOUND");if(_=at,c=Le,r){if(!fe?.exists)throw new Error("PERMISSION_DENIED");if(E=fe.data(),!E.Role)throw new Error("USER_ERROR");if(!E.Enabled)throw new Error("PERMISSION_DENIED")}if(z&&(z.size+=er(a,n,e,c,E).length),b&&_.User_ID||m&&!_.User_ID)throw new Error("USER_ERROR");if(N(_)){const Ee=await O.get(x.collection("tenants").doc(a).collection("system_user_permissions").doc(_.User_ID));if(z&&z.size++,!Ee?.exists)throw new Error("PERMISSION_DENIED");if(T=Ee.data(),i?.permissions){if(i.permissions.Role||=D.Role||_.Role,i.permissions.Enabled??=D.Enabled??_.Enabled,ke(i.permissions.Role))throw new Error("VALIDATION_ERROR: Role field is required");if(ke(i.permissions.Enabled))throw new Error("VALIDATION_ERROR: Enabled field is required")}}if(!s?.providedTransaction){const jt=v.filter(ge=>"unique"in ge&&ge.unique).map(async ge=>{if(!r||!ge.access||ge.access.includes(E.Role)){if(D[ge.name]===void 0||ke(D[ge.name]))return;const zt=Ae(ge,g),un={..._,...D};if(!(r&&zt?.custom?.serverAccess?.read!==void 0?await oe(zt.custom.serverAccess.read,[E?.Role,un]):!0))throw new Error("PERMISSION_DENIED");const Qn=D[ge.name].toString().toLowerCase().replace(/\s/g,"---").replaceAll("/","|||");if(Qs(Qn)){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 ur=await O.get(x.collection("tenants").doc(a).collection("system_unique").doc(y.collection).collection(`Unique-${y.collection}-${ge.name}`).doc(Qn));if(ur.exists&&ur.data().id!==e)throw new Error(`VALIDATION_ERROR: ${ge.name} "${D[ge.name]}" already exists`)}else throw new Error(`VALIDATION_ERROR: ${ge.name} "${D[ge.name]}" is invalid`)}});await Promise.all(jt)}if(r&&E?.Role){const Ee=E.Role,jt={..._,...D};if(!(g.custom?.serverAccess?.update!==void 0?await oe(g.custom.serverAccess.update,[Ee,jt,_]):!0))throw new Error("PERMISSION_DENIED");for(const zt of f.fields){const un=Ae(zt,g);if(Object.prototype.hasOwnProperty.call(D,zt.name)&&un?.custom?.serverAccess?.update!==void 0&&!await oe(un.custom.serverAccess.update,[Ee,jt,_]))throw new Error("PERMISSION_DENIED")}}hr(D,_,e,f,c,r,E,i?.operation?i.operation:L?"update":void 0,i?.permissions,T),i?.permissions&&r&&E&&await Vo(O,i.permissions,r,E,c,T,z),hr(D,_,e,f,c,r,E,i?.operation?i.operation:L?"update":void 0,i?.permissions,T),G&&(b||N(_)||m)&&await nu(O,e,_.User_ID)};(b||L||m)&&await x.runTransaction(async O=>{await C(O,!0)},{maxAttempts:10});const q=async(O,G)=>{if(!_)throw new Error("NOT_FOUND");try{const z={size:1},X={..._,...D};await C(O,!1,z);let Ie;!s?.noTwoWay&&!s?.providedTransaction&&(Ie=await lr("Update",a,e,X,D,f,c,O,z,r,E,_));const at=Vs(c);Js("update",O,n,e,D,c,f,s,at,B.FieldValue.arrayUnion,B.FieldValue.arrayRemove,B.FieldValue.delete,fe=>x.collection("tenants").doc(a).collection("system_fields").doc(y.collection).collection(`${y.collection}-${fe.name}`).doc(e),(fe,Le)=>x.collection("tenants").doc(a).collection("system_unique").doc(y.collection).collection(`Unique-${y.collection}-${fe.name}`).doc(Le),fe=>x.collection("tenants").doc(a).collection("system_fields").doc(y.collection).collection(`${y.collection}-${fe}`).doc(e),(fe,Le)=>Re(x,fe,a).doc(Le),(fe,Le,Ee)=>x.collection("tenants").doc(a).collection("system_fields").doc(fe.collection).collection(`${fe.collection}-${Le}`).doc(Ee),(fe,Le,Ee)=>x.collection("tenants").doc(a).collection("system_fields").doc(fe.collection).collection(`${fe.collection}-${Le.replaceAll(" ","-")}`).doc(Ee),_,Ie,z),O.update(F.doc(e),D)}catch(z){if(s?.providedTransaction)throw z;{const X={operation:"update",data:D,recordId:e,context:o,error:z,originalRecord:he(_)},Ie=await ae("postWriteError",l,g,X);if(p&&(await new Promise(at=>{setTimeout(at,250)}),await yt("update",Ie?.resolved?"success":"failed",D,a,n,e,f,Ie?.resolved?void 0:z,_)),!Ie?.resolved)throw b&&await Wt(_),N(_)&&await Qt(_.User_ID,G,T,"USER_ERROR"),m&&await x.collection("tenants").doc(a).collection(y.collection).doc(e).update({User_ID:B.FieldValue.delete()}),z}}(b||N(_)||m)&&await ri(li,[e,_.User_ID]).catch(()=>{throw new Error("USER_ERROR")})};try{let O;if(b||N(_)||m){if(N(_)){O=await k.getUser(_.User_ID);const X=O.customClaims;if(!(X&&X.role&&X.collection&&X.doc))throw new Error("USER_ERROR")}const G={..._,...D};nt(G);const z=await Uo(i?.operation||"update",a,e,l,f,G,_,O,i?.permissions,T,i?.password);b&&(D.User_ID=z),m&&(D.User_ID=B.FieldValue.delete())}s?.providedTransaction?await q(s.providedTransaction,O):await x.runTransaction(async G=>{await q(G,O)},{maxAttempts:10})}catch(O){throw(b||N(_)||m)&&await ri(li,[e,_.User_ID]).catch(()=>{throw new Error("USER_ERROR")}),O}if(!s?.providedTransaction){const O={operation:"update",data:D,recordId:e,context:o,originalRecord:he(_)},G={...O};await ae("postWrite",l,g,O),await ae("postOperation",l,g,G)}const M={..._,...D};return nt(M),{id:e,...M}},su=async(n,e,t)=>{const s=t?.userId;let r=t?.context;const i=Ze(),o=vt();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),d=o.disabledCollections?.includes(l);if(!c||d)throw new Error("COLLECTION_NOT_FOUND");const h=a.collections[l],{labels:u,auth:f,enableWriteLog:y,softDelete:v}=h,p=qe(u.collection,a),g=await oe(o.appName);if(v&&!f&&!t?.force)return await Wo(n,e,{[v.archivedField]:!0,[v.timestampField]:B.FieldValue.serverTimestamp()},{userId:s});const I=B.getFirestore();let k;s&&await or(n,h);const x=Re(I,n,i);r=r||{},r.collection=u.collection;const E=await Qe(n,e,{userId:s});let F=Us("delete",n,E,a,g,"Online",s||"System",B.Timestamp.now(),B.FieldValue.serverTimestamp());const _=Tn(F);Ve(F),y&&await yt("delete","started",F,i,n,e,h),await ae("preOperation",o,p,{operation:"delete",data:F,recordId:e,context:r}),await ae("preWrite",o,p,{operation:"delete",data:F,recordId:e,context:r}),Ve(F);const m=async w=>{const[R,S,T,C]=await Promise.all([w.get(I.collection("system_deployment").doc("maintenance_mode")),Qe(n,e,{userId:s,providedTransaction:w}),s?w.get(I.collection("tenants").doc(i).collection("system_user_permissions").doc(s)):Promise.resolve({}),ze()]);if(!R.exists)throw new Error("MAINTENANCE_MODE");if(R.data().active)throw new Error("MAINTENANCE_MODE");if(!S)throw new Error("NOT_FOUND");if(F={...S,..._},a=C,s){if(!T?.exists)throw new Error("PERMISSION_DENIED");if(k=T.data(),!k.Role)throw new Error("USER_ERROR");if(!k.Enabled)throw new Error("PERMISSION_DENIED");Xo(F,e,h,a,s,k)}if(s&&k?.Role){const M=k.Role;if(!(p.custom?.serverAccess?.delete!==void 0?await oe(p.custom.serverAccess.delete,[M,F]):!0))throw new Error("PERMISSION_DENIED")}};h.auth&&(await I.runTransaction(async w=>{await m(w)},{maxAttempts:10}),F.User_ID&&await Wt(F));try{await I.runTransaction(async w=>{await m(w);const R=Vs(a);Js("delete",w,n,e,F,a,h,t,R,B.FieldValue.arrayUnion,B.FieldValue.arrayRemove,B.FieldValue.delete,S=>I.collection("tenants").doc(i).collection("system_fields").doc(u.collection).collection(`${u.collection}-${S.name}`).doc(e),(S,T)=>I.collection("tenants").doc(i).collection("system_unique").doc(u.collection).collection(`Unique-${u.collection}-${S.name}`).doc(T),S=>I.collection("tenants").doc(i).collection("system_fields").doc(u.collection).collection(`${u.collection}-${S}`).doc(e),(S,T)=>Re(I,S,i).doc(T),(S,T,C)=>I.collection("tenants").doc(i).collection("system_fields").doc(S.collection).collection(`${S.collection}-${T}`).doc(C),(S,T,C)=>I.collection("tenants").doc(i).collection("system_fields").doc(S.collection).collection(`${S.collection}-${T.replaceAll(" ","-")}`).doc(C)),w.delete(x.doc(e))},{maxAttempts:10})}catch(w){const S=await ae("postWriteError",o,p,{operation:"delete",data:F,recordId:e,context:r,error:w});if(y&&(await new Promise(T=>{setTimeout(T,250)}),await yt("delete",S?.resolved?"success":"failed",F,i,n,e,h,S?.resolved?void 0:w)),!S?.resolved)throw h.auth&&F.User_ID&&await I.collection("tenants").doc(i).collection(u.collection).doc(e).update({User_ID:B.FieldValue.delete()}),w}const L={operation:"delete",data:F,recordId:e,context:r},N={...L};return await ae("postWrite",o,p,L),await ae("postOperation",o,p,N),{id:e,...F}},ru=async(n,e)=>{const t=B.getFirestore(),s=Ks(),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)},iu=n=>n!==null&&typeof n=="object",ou=n=>{const e=t=>{Object.entries(t).forEach(([s,r])=>{r instanceof B.Timestamp?t[s]={_seconds:r.seconds,_nanoseconds:r.nanoseconds}:iu(r)&&e(r)})};e(n)},au=async n=>await gt.getAuth().getUser(n),lu=n=>{const e=Xs();return V.fromJSDate(n).setZone(e)},jo=n=>{const e=Xs();return V.fromJSDate(n.toDate()).setZone(e)},cu=(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()},uu=(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()},du=n=>"seconds"in n&&"nanoseconds"in n?jo(new B.Timestamp(n.seconds,n.nanoseconds)).toFormat("MMMM d, yyyy '@' h:mm a"):"";exports.addRecord=tu;exports.addUser=ir;exports.convertDateToTimezone=lu;exports.convertTimestampToTimezone=jo;exports.deleteRecord=su;exports.deleteUser=Wt;exports.deserializeDeleteSentinels=Jn;exports.deserializeTimestamps=ar;exports.deserializeTimestampsWithoutUnderscores=Jc;exports.displayDate=du;exports.fetchCurrentSchema=ze;exports.fetchLastSchema=Hc;exports.getCachedConfigValue=ia;exports.getCollectionRefs=Ao;exports.getCustomizationFile=qe;exports.getCustomizationFiles=Io;exports.getDocumentRefs=er;exports.getFirestorePathRef=Re;exports.getGlobalConfigModule=vt;exports.getInputSchema=Vc;exports.getMaintenanceInfo=Zc;exports.getMode=Ks;exports.getOne=Qe;exports.getSome=nr;exports.getTenant=Ze;exports.getTimezone=Xs;exports.getUser=au;exports.getVersionInfo=zc;exports.getZodSchema=bi;exports.initializeFirebase=Bc;exports.initializeStoker=Wc;exports.isDeleteSentinel=ke;exports.keepTimezone=cu;exports.removeTimezone=uu;exports.runChildProcess=qc;exports.sendMail=sr;exports.sendMessage=ru;exports.serializeTimestamps=ou;exports.setTenant=jc;exports.tryPromise=oe;exports.updateRecord=Wo;exports.updateUser=Uo;exports.validateRelations=lr;exports.validateSoftDelete=cr;exports.writeLog=yt;
package/dist/bundle.js CHANGED
@@ -10294,7 +10294,7 @@ const Mo = async (n, e, t, s, r, i, o) => {
10294
10294
  }
10295
10295
  const y = {};
10296
10296
  for (const p of d)
10297
- p.addToAuthToken && !Xs(p.name) && r[p.name] !== void 0 && p.type !== "Timestamp" && p.type !== "Computed" && p.type !== "Embedding" && (Se(r[p.name]) ? y[p.name] = null : y[p.name] = r[p.name]);
10297
+ p.saveToAuthToken && !Xs(p.name) && r[p.name] !== void 0 && p.type !== "Timestamp" && p.type !== "Computed" && p.type !== "Embedding" && (Se(r[p.name]) ? y[p.name] = null : y[p.name] = r[p.name]);
10298
10298
  try {
10299
10299
  await a.setCustomUserClaims(f.uid, {
10300
10300
  ...y,
@@ -10848,7 +10848,7 @@ const Mo = async (n, e, t, s, r, i, o) => {
10848
10848
  }, Bc = async (n, e, t, s, r, i, o, a, l, c, d) => {
10849
10849
  const h = wt(), u = ce(), f = {};
10850
10850
  for (const p of r.fields)
10851
- p.addToAuthToken && !Xs(p.name) && i[p.name] !== void 0 && p.type !== "Timestamp" && p.type !== "Computed" && p.type !== "Embedding" && (Se(i[p.name]) ? f[p.name] = null : f[p.name] = i[p.name]);
10851
+ p.saveToAuthToken && !Xs(p.name) && i[p.name] !== void 0 && p.type !== "Timestamp" && p.type !== "Computed" && p.type !== "Embedding" && (Se(i[p.name]) ? f[p.name] = null : f[p.name] = i[p.name]);
10852
10852
  const y = "USER_ERROR";
10853
10853
  let v = "";
10854
10854
  if (n === "create") {
@@ -10993,7 +10993,7 @@ const Mo = async (n, e, t, s, r, i, o) => {
10993
10993
  throw new Error("VALIDATION_ERROR: User operations are only permitted for auth collections");
10994
10994
  if (i?.operation === "delete" && i.permissions)
10995
10995
  throw new Error("VALIDATION_ERROR: Permissions are not allowed for delete operations");
10996
- const z = f.fields.filter((O) => O.addToAuthToken && !Xs(O.name)), b = f.auth && i?.operation === "create", m = f.auth && i?.operation === "delete", L = f.auth && !b && !m && (i?.operation === "update" || t.Role || t.Enabled !== void 0 || t.Name || t.Email || t.Photo_URL || // eslint-disable-next-line security/detect-object-injection
10996
+ const z = f.fields.filter((O) => O.saveToAuthToken && !Xs(O.name)), b = f.auth && i?.operation === "create", m = f.auth && i?.operation === "delete", L = f.auth && !b && !m && (i?.operation === "update" || t.Role || t.Enabled !== void 0 || t.Name || t.Email || t.Photo_URL || // eslint-disable-next-line security/detect-object-injection
10997
10997
  z.some((O) => t[O.name] !== void 0)), N = (O) => O.User_ID && (f.auth && !b && !m && i?.operation === "update" || t.Role && t.Role !== O.Role || t.Enabled !== void 0 && t.Enabled !== O.Enabled || t.Name && t.Name !== O.Name || t.Email && t.Email !== O.Email || t.Photo_URL && t.Photo_URL !== O.Photo_URL || z.some(
10998
10998
  // eslint-disable-next-line security/detect-object-injection
10999
10999
  (H) => t[H.name] !== void 0 && t[H.name] !== O[H.name]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stoker-platform/node-client",
3
- "version": "0.5.51",
3
+ "version": "0.5.52",
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.32",
28
- "@stoker-platform/utils": "0.5.43",
27
+ "@stoker-platform/types": "0.5.33",
28
+ "@stoker-platform/utils": "0.5.44",
29
29
  "@types/luxon": "^3.7.1",
30
30
  "cross-spawn": "^7.0.6",
31
31
  "firebase-admin": "^13.8.0",