@zuzjs/flare 0.2.9 → 0.2.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -0
- package/dist/index.cjs +2 -2
- package/dist/index.d.cts +23 -2
- package/dist/index.d.ts +23 -2
- package/dist/index.js +2 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -462,6 +462,53 @@ Join alias note:
|
|
|
462
462
|
- `.join('users', ...)` and `.join('_users', ...)` both resolve to the app auth-users collection (`_flare_auth_users`) on server.
|
|
463
463
|
- Use `_users` when you want an explicit auth-collection relation in query code.
|
|
464
464
|
|
|
465
|
+
### Data Mapper (Collection + Join Alias)
|
|
466
|
+
|
|
467
|
+
You can provide `dataMapper` in `connectApp(...)` to shape inbound rows on the client side.
|
|
468
|
+
|
|
469
|
+
Mapping rules:
|
|
470
|
+
- Base collection rows use the mapper key matching the collection name.
|
|
471
|
+
- Joined rows use the mapper key matching join `as`.
|
|
472
|
+
|
|
473
|
+
```ts
|
|
474
|
+
import { connectApp } from '@zuzjs/flare';
|
|
475
|
+
|
|
476
|
+
const app = connectApp({
|
|
477
|
+
endpoint: 'https://flare.zuzcdn.net',
|
|
478
|
+
appId: 'my-app',
|
|
479
|
+
apiKey: 'FA_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
|
|
480
|
+
dataMapper: {
|
|
481
|
+
boards: (row) => ({
|
|
482
|
+
id: row.id,
|
|
483
|
+
name: row.name,
|
|
484
|
+
description: row.description,
|
|
485
|
+
createdAt: new Date(row.createdAt ?? row.created_at),
|
|
486
|
+
}),
|
|
487
|
+
team: (row) => ({
|
|
488
|
+
id: row.id,
|
|
489
|
+
name: row.authMeta?.additionalParams?.name || 'Unknown',
|
|
490
|
+
email: row.email,
|
|
491
|
+
createdAt: new Date(row.createdAt ?? row.created_at),
|
|
492
|
+
}),
|
|
493
|
+
},
|
|
494
|
+
});
|
|
495
|
+
|
|
496
|
+
const boards = await app
|
|
497
|
+
.collection('boards')
|
|
498
|
+
.where({ boardId: '123' })
|
|
499
|
+
.join('users', {
|
|
500
|
+
source: 'team.uid',
|
|
501
|
+
target: 'uid',
|
|
502
|
+
as: 'team',
|
|
503
|
+
})
|
|
504
|
+
.get();
|
|
505
|
+
|
|
506
|
+
// boards[*] is mapped by dataMapper.boards
|
|
507
|
+
// boards[*].team[*] is mapped by dataMapper.team (join alias)
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
Tip: If your join alias is `team`, define `dataMapper.team` (not `dataMapper.users`) for that join payload.
|
|
511
|
+
|
|
465
512
|
### Template-Based Email APIs
|
|
466
513
|
|
|
467
514
|
### Security Rules Example (Boards Owner Or Team Member)
|
package/dist/index.cjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
'use strict';var auth=require('@zuzjs/auth'),core=require('@zuzjs/core');/* ZuzFlare Client */
|
|
2
|
-
var h=class extends Error{constructor(t,i,r){super(t);this.code=i;this.cause=r;this.name="ZuzFlareError";}};var oe={AuthenticationFailed:"AUTHENTICATION_FAILED",PermissionDenied:"PERMISSION_DENIED",WriteFailed:"WRITE_FAILED",QueryFailed:"QUERY_FAILED",ParseError:"PARSE_ERROR"},u=oe;var ae=(c=>(c.SUBSCRIBE="subscribe",c.UNSUBSCRIBE="unsubscribe",c.WRITE="write",c.DELETE="delete",c.AUTH="auth",c.PING="ping",c.OFFLINE_SYNC="offline_sync",c.CALL="call",c.QUERY="query",c.PRESENCE_JOIN="presence_join",c.PRESENCE_LEAVE="presence_leave",c.PRESENCE_HEARTBEAT="presence_heartbeat",c))(ae||{}),ce=(c=>(c.SNAPSHOT="snapshot",c.CHANGE="change",c.ERROR="error",c.ACK="ack",c.PONG="pong",c.AUTH_OK="auth_ok",c.OFFLINE_ACK="offline_ack",c.CALL_RESPONSE="call_response",c.QUERY_RESULT="query_result",c.PRESENCE_STATE="presence_state",c.PRESENCE_JOIN="presence_join",c.PRESENCE_LEAVE="presence_leave",c))(ce||{});function j(a){let e=[];for(let[t,i]of Object.entries(a))if(typeof i=="string"){let r=i.match(/^(>=|<=|!=|>|<|==)\s*(.+)$/);if(r){let[,n,s]=r;e.push({field:t,op:n,value:ee(s.trim())});}else e.push({field:t,op:"==",value:i});}else Array.isArray(i)?e.push({field:t,op:"in",value:i}):e.push({field:t,op:"==",value:i});return e}function ee(a){if(!isNaN(Number(a)))return Number(a);if(a==="true")return true;if(a==="false")return false;if(a==="null")return null;if(a!=="undefined")return a}var A=class{constructor(e,t,i){this.client=e;this.collection=t;this.docIdFromRef=i;}whereCondition;updateData;setData;deleteOp=false;promise;where(e){return this.whereCondition=e,this}update(e){return this.updateData=e,this}set(e){return this.setData=e,this}delete(){return this.deleteOp=true,this}getDocId(){if(this.docIdFromRef)return this.docIdFromRef;if(this.whereCondition&&(this.whereCondition.id||this.whereCondition._id)){let e=this.whereCondition.id??this.whereCondition._id;if(typeof e=="string")return e}throw new h('Document ID not specified. Use .where({ id: "..." }) or doc(collection, id)',u.QueryFailed)}async execute(){return this._execute()}async _execute(){let e=this.getDocId();if(this.deleteOp){await this.client.send("delete",{collection:this.collection,docId:e});return}if(this.updateData){await this.client.send("write",{collection:this.collection,docId:e,data:this.updateData,merge:true});return}if(this.setData){await this.client.send("write",{collection:this.collection,docId:e,data:this.setData,merge:false});return}return this.get()}then(e,t){return this.promise||(this.promise=this._execute()),this.promise.then(e,t)}async get(){let e=this.getDocId(),t=core.uuid2(18);return new Promise((i,r)=>{let n=this.client.subscribe(t,this.collection,e,void 0,s=>{s.type==="snapshot"&&(n(),i(s.data));});setTimeout(()=>{n(),r(new Error("Document fetch timeout"));},1e4);})}onSnapshot(e){let t=this.getDocId(),i=core.uuid2(18);return this.client.subscribe(i,this.collection,t,void 0,e)}};var V=class{constructor(e,t,i){this.client=e;this.collection=t;this.id=i;}async get(){return new A(this.client,this.collection,this.id).get()}async set(e){await this.client.send("write",{collection:this.collection,docId:this.id,data:e,merge:false});}async update(e){await this.client.send("write",{collection:this.collection,docId:this.id,data:e,merge:true});}async delete(){await this.client.send("delete",{collection:this.collection,docId:this.id});}onSnapshot(e){let t=core.uuid2(18),i=()=>{};return i=this.client.subscribe(t,this.collection,this.id,void 0,r=>{r.type==="snapshot"&&(e(r),i());}),i}onDocUpdated(e){let t=core.uuid2(18);return this.client.subscribe(t,this.collection,this.id,void 0,i=>{i.type==="change"&&(i.operation==="update"||i.operation==="replace")&&i.data&&e(i.data,i.docId);},{skipSnapshot:true})}onDocDeleted(e){let t=core.uuid2(18);return this.client.subscribe(t,this.collection,this.id,void 0,i=>{i.type==="change"&&i.operation==="delete"&&e(i.docId);},{skipSnapshot:true})}onDocChanged(e){let t=core.uuid2(18);return this.client.subscribe(t,this.collection,this.id,void 0,i=>{i.type==="change"&&e(i.data??null,i.docId,i.operation);},{skipSnapshot:true})}},Q=V;var z=class a{constructor(e,t){this.client=e;this.collection=t;return new Proxy(this,{get:(i,r,n)=>{if(typeof r=="string"&&!(r in i)&&this.client.hasQueryPreset(r))return (o={})=>i.with(r,o);let s=Reflect.get(i,r,n);return typeof s=="function"?s.bind(i):s}})}sq={};promise;doc(e){return new Q(this.client,this.collection,e)}clone(e){let t=new a(this.client,this.collection);return t.sq={...this.sq,...e},t}normalizeFilterValue(e,t){return e==="in"||e==="not-in"||e==="array-contains-any"?Array.isArray(t)?t:[t]:t}normalizeFilter(e){return {...e,value:this.normalizeFilterValue(e.op,e.value)}}toQueryFilters(e){return j(e).map(t=>this.normalizeFilter(t))}appendOperatorFilter(e,t,i,r){return this.appendFilters([this.normalizeFilter({field:e,op:t,value:i})],r)}appendAndFilters(e){return this.clone({where:[...this.sq.where??[],...e]})}toOrNode(e){return {or:e}}toAndNode(e){return {and:e}}isLeafFilter(e){return !("or"in e)&&!("and"in e)}isIdentityGuard(e){return this.isLeafFilter(e)?(e.field==="id"||e.field==="_id")&&e.op==="==":false}splitIdentityGuards(e){let t=[],i=[];for(let r of e){if(this.isIdentityGuard(r)){t.push(r);continue}i.push(r);}return {guards:t,rest:i}}appendOrFilters(e){let t=[...this.sq.where??[]];if(t.length===0)return this.clone({where:[this.toOrNode(e)]});let i=t[0];if(t.length===1&&typeof i=="object"&&i!=null&&"or"in i){let d=i;return this.clone({where:[{or:[...d.or,...e]}]})}let{guards:n,rest:s}=this.splitIdentityGuards(t);if(n.length>0){let d=s.length===0?void 0:s.length===1?s[0]:{and:s},l=d?[{or:[d,...e]}]:[{or:[...e]}];return this.clone({where:[...n,...l]})}let o=t.length===1?t[0]:{and:t};return this.clone({where:[{or:[o,...e]}]})}appendFilters(e,t){return t==="or"?this.appendOrFilters(e):this.appendAndFilters(e)}with(e,t={}){return this.client.applyQueryPreset(this,e,t)}where(e){return this.appendFilters(this.toQueryFilters(e),"and")}and(e){return this.appendFilters(this.toQueryFilters(e),"and")}or(e){return this.appendFilters(this.toQueryFilters(e),"or")}in(e,t){return this.appendOperatorFilter(e,"in",t,"and")}andIn(e,t){return this.appendOperatorFilter(e,"in",t,"and")}orIn(e,t){return this.appendOperatorFilter(e,"in",t,"or")}notIn(e,t){return this.appendOperatorFilter(e,"not-in",t,"and")}andNotIn(e,t){return this.appendOperatorFilter(e,"not-in",t,"and")}orNotIn(e,t){return this.appendOperatorFilter(e,"not-in",t,"or")}arrayContains(e,t){return this.appendOperatorFilter(e,"array-contains",t,"and")}andArrayContains(e,t){return this.appendOperatorFilter(e,"array-contains",t,"and")}orArrayContains(e,t){return this.appendOperatorFilter(e,"array-contains",t,"or")}arrayContainsAny(e,t){return this.appendOperatorFilter(e,"array-contains-any",t,"and")}andArrayContainsAny(e,t){return this.appendOperatorFilter(e,"array-contains-any",t,"and")}orArrayContainsAny(e,t){return this.appendOperatorFilter(e,"array-contains-any",t,"or")}some(e,t){return this.appendOperatorFilter(e,"elem-match",t,"and")}andSome(e,t){return this.appendOperatorFilter(e,"elem-match",t,"and")}orSome(e,t){return this.appendOperatorFilter(e,"elem-match",t,"or")}like(e,t){return this.appendOperatorFilter(e,"like",t,"and")}andLike(e,t){return this.appendOperatorFilter(e,"like",t,"and")}orLike(e,t){return this.appendOperatorFilter(e,"like",t,"or")}notLike(e,t){return this.appendOperatorFilter(e,"not-like",t,"and")}andNotLike(e,t){return this.appendOperatorFilter(e,"not-like",t,"and")}orNotLike(e,t){return this.appendOperatorFilter(e,"not-like",t,"or")}exists(e){return this.appendOperatorFilter(e,"exists",true,"and")}andExists(e){return this.appendOperatorFilter(e,"exists",true,"and")}orExists(e){return this.appendOperatorFilter(e,"exists",true,"or")}notExists(e){return this.appendOperatorFilter(e,"not-exists",true,"and")}andNotExists(e){return this.appendOperatorFilter(e,"not-exists",true,"and")}orNotExists(e){return this.appendOperatorFilter(e,"not-exists",true,"or")}latest(){return this.clone({orderBy:[...this.sq.orderBy??[],{field:"_seq",dir:"desc"}]})}newest(){return this.clone({orderBy:[...this.sq.orderBy??[],{field:"_seq",dir:"desc"}]})}oldest(){return this.clone({orderBy:[...this.sq.orderBy??[],{field:"_seq",dir:"asc"}]})}orderBy(e,t="asc"){return this.clone({orderBy:[...this.sq.orderBy??[],{field:e,dir:t}]})}limit(e){return this.clone({limit:e})}offset(e){return this.clone({offset:e})}startAt(...e){return this.clone({startAt:{values:e}})}startAfter(...e){return this.clone({startAfter:{values:e}})}endAt(...e){return this.clone({endAt:{values:e}})}endBefore(...e){return this.clone({endBefore:{values:e}})}aggregate(...e){return this.clone({aggregate:[...this.sq.aggregate??[],...e]})}count(e="count"){return this.aggregate({fn:"count",alias:e})}sum(e,t){return this.aggregate({fn:"sum",field:e,alias:t??`sum_${e}`})}avg(e,t){return this.aggregate({fn:"avg",field:e,alias:t??`avg_${e}`})}min(e,t){return this.aggregate({fn:"min",field:e,alias:t??`min_${e}`})}max(e,t){return this.aggregate({fn:"max",field:e,alias:t??`max_${e}`})}distinct(e,t){return this.aggregate({fn:"distinct",field:e,alias:t??`distinct_${e}`})}groupBy(...e){return this.clone({groupBy:{fields:e}})}having(e,t,i){return this.clone({having:[...this.sq.having??[],{field:e,op:t,value:i}]})}buildStructuredJoin(e,t){let r={from:String(e??""),localField:String(t?.source??""),foreignField:String(t?.target??""),as:String(t?.as??""),single:t?.single};return Array.isArray(t?.where)&&(r.where=t.where),Array.isArray(t?.orderBy)&&(r.orderBy=t.orderBy),typeof t?.limit=="number"&&(r.limit=t.limit),typeof t?.offset=="number"&&(r.offset=t.offset),t?.startAt&&(r.startAt=t.startAt),t?.startAfter&&(r.startAfter=t.startAfter),t?.endAt&&(r.endAt=t.endAt),t?.endBefore&&(r.endBefore=t.endBefore),Array.isArray(t?.aggregate)&&(r.aggregate=t.aggregate),t?.groupBy&&(r.groupBy=t.groupBy),Array.isArray(t?.having)&&(r.having=t.having),t?.vectorSearch&&(r.vectorSearch=t.vectorSearch),Array.isArray(t?.select)&&(r.select=t.select),typeof t?.distinctField=="string"&&(r.distinctField=t.distinctField),Array.isArray(t?.joins)&&(r.joins=t.joins.map(n=>this.buildStructuredJoin(String(n?.collection??""),n))),r}cloneStructuredJoin(e){let t={...e};return Array.isArray(e.where)&&(t.where=e.where.map(i=>({...i}))),Array.isArray(e.orderBy)&&(t.orderBy=e.orderBy.map(i=>({...i}))),Array.isArray(e.aggregate)&&(t.aggregate=e.aggregate.map(i=>({...i}))),Array.isArray(e.having)&&(t.having=e.having.map(i=>({...i}))),Array.isArray(e.select)&&(t.select=[...e.select]),e.groupBy?.fields&&(t.groupBy={fields:[...e.groupBy.fields]}),e.startAt?.values&&(t.startAt={values:[...e.startAt.values]}),e.startAfter?.values&&(t.startAfter={values:[...e.startAfter.values]}),e.endAt?.values&&(t.endAt={values:[...e.endAt.values]}),e.endBefore?.values&&(t.endBefore={values:[...e.endBefore.values]}),Array.isArray(e.joins)&&(t.joins=e.joins.map(i=>this.cloneStructuredJoin(i))),t}appendNestedJoinByAlias(e,t,i){for(let r of e){if(r.as===t)return r.joins=[...r.joins??[],i],true;if(Array.isArray(r.joins)&&this.appendNestedJoinByAlias(r.joins,t,i))return true}return false}parseRelationRef(e){let i=String(e??"").trim().match(/^([A-Za-z0-9_.]+)\s*->\s*([A-Za-z0-9_]+)\.([A-Za-z0-9_.]+)(?:\s+as\s+([A-Za-z0-9_]+))?$/i);if(!i)throw new Error(`Invalid relation format: "${e}". Expected "source.path->collection.target"`);return {source:i[1],collection:i[2],target:i[3],alias:i[4]}}join(e,t){let i=this.buildStructuredJoin(e,t);return this.clone({joins:[...this.sq.joins??[],i]})}joinNested(e,t,i){let r=String(e??"").trim();if(!r)throw new Error("joinNested requires parentAlias");let n=(this.sq.joins??[]).map(o=>this.cloneStructuredJoin(o));if(n.length===0)throw new Error(`joinNested parent alias "${r}" not found`);let s=this.buildStructuredJoin(t,i);if(!this.appendNestedJoinByAlias(n,r,s))throw new Error(`joinNested parent alias "${r}" not found`);return this.clone({joins:n})}Join(e,t){return this.join(e,t)}JoinNested(e,t,i){return this.joinNested(e,t,i)}withRelation(e,t={}){let i=this.parseRelationRef(e);return this.join(i.collection,{...t,source:i.source,target:i.target,as:t.as??i.alias??i.collection})}select(...e){return this.clone({select:e})}distinctField(e){return this.clone({distinctField:e})}vectorSearch(e){return this.clone({vectorSearch:e})}getRawQuery(){let e={...this.sq};return Array.isArray(this.sq.where)&&(e.where=this.sq.where.map(t=>({...t}))),Array.isArray(this.sq.orderBy)&&(e.orderBy=this.sq.orderBy.map(t=>({...t}))),Array.isArray(this.sq.aggregate)&&(e.aggregate=this.sq.aggregate.map(t=>({...t}))),Array.isArray(this.sq.having)&&(e.having=this.sq.having.map(t=>({...t}))),Array.isArray(this.sq.select)&&(e.select=[...this.sq.select]),Array.isArray(this.sq.joins)&&(e.joins=this.sq.joins.map(t=>this.cloneStructuredJoin(t))),this.sq.groupBy?.fields&&(e.groupBy={fields:[...this.sq.groupBy.fields]}),this.sq.startAt?.values&&(e.startAt={values:[...this.sq.startAt.values]}),this.sq.startAfter?.values&&(e.startAfter={values:[...this.sq.startAfter.values]}),this.sq.endAt?.values&&(e.endAt={values:[...this.sq.endAt.values]}),this.sq.endBefore?.values&&(e.endBefore={values:[...this.sq.endBefore.values]}),{collection:this.collection,query:e}}async get(){return this._execute()}async first(){let e=await this._execute();return e.length>0?e[0]:null}async last(){let e=await this._execute();return e.length>0?e[e.length-1]:null}_isStructured(){return !!(this.sq.orderBy?.length||this.sq.aggregate?.length||this.sq.groupBy||this.sq.having?.length||this.sq.joins?.length||this.sq.vectorSearch||this.sq.distinctField||this.sq.offset||this.sq.startAt||this.sq.startAfter||this.sq.endAt||this.sq.endBefore||this.sq.select?.length)}async _execute(){return this._isStructured()?this._executeQuery():this._executeSubscribe()}async _executeQuery(){return (await this.client.send("query",{collection:this.collection,query:this.sq})).data??[]}async _executeSubscribe(){let e=core.uuid2(18);return new Promise((t,i)=>{let r=Object.keys(this.sq).length>0?this.sq:void 0,n=this.client.subscribe(e,this.collection,void 0,r,s=>{s.type==="snapshot"&&(n(),t(s.data));});setTimeout(()=>{n(),i(new Error("Collection fetch timeout"));},1e4);})}then(e,t){return this.promise||(this.promise=this._execute()),this.promise.then(e,t)}onSnapshot(e){let t=core.uuid2(18),i=Object.keys(this.sq).length>0?this.sq:void 0,r=(()=>{});return r=this.client.subscribe(t,this.collection,void 0,i,n=>{n.type==="snapshot"&&(e(n),r());}),r}stream(e={}){let t=core.uuid2(18),i=Object.keys(this.sq).length>0?this.sq:void 0,r=new Set,n=[],s=new Map,o=Math.max(0,Number(e.flushMs??24)),d=Math.max(1,Number(e.maxBatchSize??200)),l=e.insertAt??"end",f=typeof e.maxDocs=="number"&&e.maxDocs>0?Math.floor(e.maxDocs):void 0,y=String(e.idField??"id"),c=[],C=false,S=false,x=0,w,v=()=>{s.clear();for(let p=0;p<c.length;p+=1){let m=W(c[p]);m&&s.set(m,p);}},W=(p,m)=>{if(m)return m;if(p==null)return;if(typeof e.getId=="function"){let I=e.getId(p);if(typeof I=="string"&&I.length>0)return I}let P=p?.[y]??p?._id??p?.docId;if(typeof P=="string"&&P.length>0)return P},F=()=>{f==null||c.length<=f||(c=c.slice(0,f));},E=()=>{typeof e.sort=="function"&&(c=c.slice().sort(e.sort));},M=(p,m)=>{x+=1;let P=c.slice(),I={reason:p,batchSize:m,version:x,ready:S};for(let N of Array.from(r))try{N(P,I);}catch{}},T=()=>{w!=null&&(clearTimeout(w),w=void 0);},g=p=>{if(p.operation==="delete"){let N=s.get(p.docId);if(N==null)return;c.splice(N,1),v();return}let m=p.data;if(m==null)return;let P=W(m,p.docId);if(!P)return;let I=s.get(P);if(typeof I=="number"){c[I]=m;return}l==="start"?c.unshift(m):c.push(m),F(),v();},B=()=>{if(C||n.length===0)return;T();let p=n.splice(0,n.length);for(let m of p)g(m);E(),v(),M("change-batch",p.length);},$=()=>{C||w!=null||(w=setTimeout(B,o));},K=this.client.subscribe(t,this.collection,void 0,i,p=>{if(!C){if(p.type==="snapshot"){c=Array.isArray(p.data)?[...p.data]:[],S=true,T(),n.length=0,E(),F(),v(),M("snapshot",0);return}if(n.push(p),n.length>=d){B();return}$();}}),J={subscribe(p,m=true){if(r.add(p),m){let P={reason:S?"change-batch":"snapshot",batchSize:0,version:x,ready:S};try{p(c.slice(),P);}catch{}}return ()=>{r.delete(p);}},getSnapshot(){return c.slice()},isReady(){return S},getVersion(){return x},close:()=>{C||(C=true,T(),n.length=0,r.clear(),K());},onError(p){return K.onError(p),J},onPermissionDenied(p){return K.onPermissionDenied(p),J}};return J}asStore(e={}){let t=this.stream(e);return {subscribe:i=>t.subscribe(()=>{i();},false),getSnapshot:()=>t.getSnapshot(),getServerSnapshot:()=>[],stream:t,destroy:()=>{t.close();}}}onDocAdded(e){let t=core.uuid2(18),i=Object.keys(this.sq).length>0?this.sq:void 0;return this.client.subscribe(t,this.collection,void 0,i,r=>{r.type==="change"&&r.operation==="insert"&&r.data!=null&&e(r.data,r.docId);},{skipSnapshot:true})}onDocUpdated(e){let t=core.uuid2(18),i=Object.keys(this.sq).length>0?this.sq:void 0;return this.client.subscribe(t,this.collection,void 0,i,r=>{r.type==="change"&&(r.operation==="update"||r.operation==="replace")&&r.data!=null&&e(r.data,r.docId);},{skipSnapshot:true})}onDocDeleted(e){let t=core.uuid2(18),i=Object.keys(this.sq).length>0?this.sq:void 0;return this.client.subscribe(t,this.collection,void 0,i,r=>{r.type==="change"&&r.operation==="delete"&&e(r.docId);},{skipSnapshot:true})}onDocChanged(e){let t=core.uuid2(18),i=Object.keys(this.sq).length>0?this.sq:void 0;return this.client.subscribe(t,this.collection,void 0,i,r=>{r.type==="change"&&e(r.data??null,r.docId,r.operation);},{skipSnapshot:true})}async add(e){let t=core.uuid2(18),i=this.doc(t);return await i.set(e),i}update(e){return new A(this.client,this.collection).update(e)}delete(){return new A(this.client,this.collection).delete()}},G=z;async function ue(a){let e=a.replace(/-----BEGIN PUBLIC KEY-----/,"").replace(/-----END PUBLIC KEY-----/,"").replace(/\s+/g,""),t=typeof atob<"u"?atob(e):Buffer.from(e,"base64").toString("binary"),i=new Uint8Array(t.length);for(let n=0;n<t.length;n++)i[n]=t.charCodeAt(n);return (globalThis.crypto??(await import('crypto')).webcrypto).subtle.importKey("spki",i.buffer,{name:"RSA-OAEP",hash:"SHA-256"},false,["encrypt"])}async function de(a,e){let t=await ue(e),i=new TextEncoder().encode(JSON.stringify(a)),n=await(globalThis.crypto??(await import('crypto')).webcrypto).subtle.encrypt({name:"RSA-OAEP"},t,i),s=typeof btoa<"u"?btoa(String.fromCharCode(...new Uint8Array(n))):Buffer.from(n).toString("base64");return JSON.stringify({enc:"rsa",data:s})}var H=class{socket=null;reconnectInterval;maxReconnectDelay;isConnected=false;shouldReconnect=true;options;messageQueue=[];heartbeatInterval=null;connectionTimeout=null;constructor(e){this.options=e,this.reconnectInterval=e.reconnectDelay||2,this.maxReconnectDelay=e.maxReconnectDelay||60,this.log("Transport initialized",e.url);}connect(){if(this.socket){this.log("Socket already exists, skipping connection");return}this.log("Connecting to",this.options.url),this.socket=new WebSocket(this.options.url),this.connectionTimeout=setTimeout(()=>{this.isConnected||(this.log("Connection timeout"),this.socket?.close(),this.handleReconnect());},1e4),this.socket.onopen=()=>{this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.isConnected=true,this.reconnectInterval=this.options.reconnectDelay||2,this.log("Connected to server"),this.options.onOpen?.(),this.startHeartbeat(),this.flushQueue();},this.socket.onmessage=e=>{try{let t=JSON.parse(e.data);this.options.onMessage(t);}catch(t){this.log("Parse error",t),this.options.onError?.(t);}},this.socket.onerror=e=>{this.log("WebSocket error",e),this.options.onError?.(new Error("WebSocket error"));},this.socket.onclose=e=>{this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.isConnected=false,this.socket=null,this.stopHeartbeat(),this.log("Connection closed",e.code,e.reason),this.options.onClose?.(),e.code!==1e3&&this.shouldReconnect&&this.options.autoReconnect&&this.handleReconnect();};}handleReconnect(){let e=this.reconnectInterval*1e3;this.log(`Reconnecting in ${this.reconnectInterval}s...`),setTimeout(()=>{this.reconnectInterval=Math.min(this.reconnectInterval*2,this.maxReconnectDelay),this.connect();},e);}startHeartbeat(){this.heartbeatInterval=setInterval(()=>{this.isConnected&&this.send({type:"ping",id:Date.now().toString(),ts:Date.now()});},3e4);}stopHeartbeat(){this.heartbeatInterval&&(clearInterval(this.heartbeatInterval),this.heartbeatInterval=null);}flushQueue(){for(this.log("Flushing message queue",this.messageQueue.length);this.messageQueue.length>0;){let e=this.messageQueue.shift();e&&this.send(e);}}send(e){if(this.socket&&this.socket.readyState===WebSocket.OPEN){let t=i=>{try{this.socket.send(i),this.log("Sent message",e);}catch(r){this.log("Send error",r),this.messageQueue.push(e);}};this.options.publicKey?de(e,this.options.publicKey).then(t).catch(i=>{this.log("RSA encrypt error \u2014 sending plaintext",i),t(JSON.stringify(e));}):t(JSON.stringify(e));}else this.log("Socket not ready, queueing message"),this.messageQueue.push(e);}disconnect(){this.shouldReconnect=false,this.stopHeartbeat(),this.socket&&(this.socket.close(1e3,"Client disconnect"),this.socket=null),this.isConnected=false,this.log("Disconnected");}get connected(){return this.isConnected}log(...e){this.options.debug&&console.log("[FlareTransport]",...e);}};var ye={id:"_id",createdAt:"_createdAt",updatedAt:"_updatedAt"},te={_id:"id",_createdAt:"createdAt",_updatedAt:"updatedAt"},q=class{transport;config;pendingAcks=new Map;subscriptions=new Map;activeSubscriptions=new Map;queryPresets=new Map;subscriptionErrorHandlers=new Map;subscriptionPermissionHandlers=new Map;subscriptionLastErrors=new Map;offlineQueue=[];currentState="disconnected";connectionListeners=[];errorListeners=[];isDebug=false;socketAuthUid="anon";pendingSubscriptionReplay=false;subscriptionReplayPromise=Promise.resolve();requestTraceSeq=0;requestTimingEnabled=true;httpInFlight=new Map;httpResponseCache=new Map;maxHttpCacheEntries=200;presenceCallbacks=new Map;presenceJoinCbs=new Map;presenceLeaveCbs=new Map;presenceHeartbeatTimer;embedder;vectorSchema=new Map;throwFetchFlareError(e,t,i){let r=e,n=typeof r?.error=="string"&&r.error.length>0?r.error:i,s=typeof r?.message=="string"&&r.message.length>0?r.message:t;throw new h(s,n,e)}nowMs(){return typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now()}normalizeHeaders(e){if(!e)return {};let t={};if(e instanceof Headers)e.forEach((i,r)=>{t[r]=i;});else if(Array.isArray(e))for(let[i,r]of e)t[String(i)]=String(r);else for(let[i,r]of Object.entries(e))t[String(i)]=String(r);return t}redactHeaders(e){let t={...e};for(let i of Object.keys(t)){let r=i.toLowerCase();(r==="authorization"||r==="x-flare-csrf"||r==="x-csrf-token")&&(t[i]="[redacted]");}return t}stableStringify(e){if(e==null)return "";if(typeof e=="string")return e;if(typeof URLSearchParams<"u"&&e instanceof URLSearchParams)return e.toString();if(typeof e!="object")return String(e);if(Array.isArray(e))return `[${e.map(r=>this.stableStringify(r)).join(",")}]`;let t=e;return `{${Object.keys(t).sort().map(r=>`${r}:${this.stableStringify(t[r])}`).join(",")}}`}buildHttpCacheKey(e,t,i,r,n){let o=Object.entries(i).map(([l,f])=>[l.toLowerCase(),f]).sort(([l],[f])=>l.localeCompare(f)).map(([l,f])=>`${l}:${f}`).join("|"),d=this.stableStringify(r);return `${e}|${t}|${n??""}|${o}|${d}`}shouldCacheResponse(e,t){return !!(e==="GET"||e==="POST"&&/\/auth\/refresh(?:\?|$)/.test(t))}rememberHttpResponse(e,t){if(this.httpResponseCache.set(e,t),this.httpResponseCache.size<=this.maxHttpCacheEntries)return;let i=this.httpResponseCache.keys().next().value;i&&this.httpResponseCache.delete(i);}createTimedFetchTrace(e,t,i,r,n,s){return {response:{status:e.status,ok:e.status>=200&&e.status<300,headers:{get:o=>{let d=o.toLowerCase();for(let[l,f]of Object.entries(e.headers))if(l.toLowerCase()===d)return String(f);return null}},json:async()=>e.data??{}},requestId:t,startedAtMs:i,networkMs:s,method:r,url:n}}logHttpTiming(...e){this.requestTimingEnabled&&this.log("[FlareClient][http]",...e);}mergeHeaders(e,t){if(!e)return t;if(e instanceof Headers){let i=new Headers(e);for(let[r,n]of Object.entries(t))i.set(r,n);return i}return Array.isArray(e)?[...e,...Object.entries(t)]:{...e,...t}}toWireField(e){let t=String(e??"").trim();return t&&(ye[t]??t)}fromWireField(e){let t=String(e??"").trim();return t&&(te[t]?te[t]:t.startsWith("_")&&!t.startsWith("__")&&t.length>1?t.slice(1):t)}normalizeOutboundData(e){if(Array.isArray(e))return e.map(r=>this.normalizeOutboundData(r));if(!e||typeof e!="object")return e;let t=e,i={};for(let[r,n]of Object.entries(t))i[this.toWireField(r)]=this.normalizeOutboundData(n);return i}normalizeInboundData(e){if(Array.isArray(e))return e.map(r=>this.normalizeInboundData(r));if(!e||typeof e!="object")return e;let t=e,i={};for(let[r,n]of Object.entries(t))i[this.fromWireField(r)]=this.normalizeInboundData(n);return i}normalizeOutboundAnyFilter(e){return Array.isArray(e.or)?{...e,or:e.or.map(t=>this.normalizeOutboundAnyFilter(t))}:Array.isArray(e.and)?{...e,and:e.and.map(t=>this.normalizeOutboundAnyFilter(t))}:typeof e.field=="string"?{...e,field:this.toWireField(e.field)}:{...e}}normalizeOutboundQuery(e){if(!e||typeof e!="object")return e;let t=e,i={...t},r=n=>{let s={...n};return s.localField=this.toWireField(String(n?.localField??"")),s.foreignField=this.toWireField(String(n?.foreignField??"")),Array.isArray(n.where)&&(s.where=n.where.map(o=>this.normalizeOutboundAnyFilter(o))),Array.isArray(n.orderBy)&&(s.orderBy=n.orderBy.map(o=>({...o,field:this.toWireField(String(o?.field??""))}))),n.groupBy&&typeof n.groupBy=="object"&&Array.isArray(n.groupBy.fields)&&(s.groupBy={...n.groupBy,fields:n.groupBy.fields.map(o=>this.toWireField(String(o??"")))}),Array.isArray(n.having)&&(s.having=n.having.map(o=>({...o,field:this.toWireField(String(o?.field??""))}))),Array.isArray(n.select)&&(s.select=n.select.map(o=>this.toWireField(String(o??"")))),typeof n.distinctField=="string"&&(s.distinctField=this.toWireField(n.distinctField)),n.vectorSearch&&typeof n.vectorSearch=="object"&&(s.vectorSearch={...n.vectorSearch,field:this.toWireField(String(n.vectorSearch.field??""))}),Array.isArray(n.joins)&&(s.joins=n.joins.map(o=>r(o))),s};return Array.isArray(t.where)&&(i.where=t.where.map(n=>this.normalizeOutboundAnyFilter(n))),Array.isArray(t.orderBy)&&(i.orderBy=t.orderBy.map(n=>({...n,field:this.toWireField(String(n?.field??""))}))),t.groupBy&&typeof t.groupBy=="object"&&Array.isArray(t.groupBy.fields)&&(i.groupBy={...t.groupBy,fields:t.groupBy.fields.map(n=>this.toWireField(String(n??"")))}),Array.isArray(t.having)&&(i.having=t.having.map(n=>({...n,field:this.toWireField(String(n?.field??""))}))),Array.isArray(t.select)&&(i.select=t.select.map(n=>this.toWireField(String(n??"")))),typeof t.distinctField=="string"&&(i.distinctField=this.toWireField(t.distinctField)),t.vectorSearch&&typeof t.vectorSearch=="object"&&(i.vectorSearch={...t.vectorSearch,field:this.toWireField(String(t.vectorSearch.field??""))}),Array.isArray(t.joins)&&(i.joins=t.joins.map(n=>r(n))),i}async timedFetch(e,t,i){let r=++this.requestTraceSeq,n=this.nowMs(),s=String(i?.method??"GET").toUpperCase(),o=this.normalizeHeaders(i?.headers),d=this.redactHeaders(o),l=i?.body,f=this.buildHttpCacheKey(s,t,o,l,i?.credentials),y=this.shouldCacheResponse(s,t);this.logHttpTiming(`#${r} ${e} start`,{method:s,url:t,headers:d,hasBody:!!i?.body});try{if(y){let T=this.httpResponseCache.get(f);if(T)return this.logHttpTiming(`#${r} ${e} cache-hit`,{method:s,url:t}),this.createTimedFetchTrace(T,r,n,s,t,0)}let c=this.httpInFlight.get(f);if(c){let T=await c,g=this.nowMs()-n;return this.logHttpTiming(`#${r} ${e} deduped`,{method:s,url:t,networkMs:Number(g.toFixed(2))}),this.createTimedFetchTrace(T,r,n,s,t,g)}let C=this.mergeHeaders(i?.headers,{"x-flare-request-id":String(r)}),S=this.normalizeHeaders(C),x=this.redactHeaders(S),w={timeout:Math.ceil((this.config.connectionTimeout??1e4)/1e3),ignoreKind:!0,headers:S,withCredentials:i?.credentials==="include",returnRawResponse:!0,appendCookiesToBody:!1,appendTimestamp:!1};this.logHttpTiming(`#${r} ${e} request`,{method:s,url:t,headers:x,hasBody:!!i?.body});let v=s.toUpperCase(),F=(async()=>{let T=v==="GET"?await core.withGet(t,w):v==="PUT"?await core.withPut(t,l,w):v==="PATCH"?await core.withPatch(t,l,w):await core.withPost(t,l,w),g={status:Number(T?.status??0),headers:Object.fromEntries(Object.entries(T?.headers??{}).map(([B,$])=>[B,String($)])),data:T?.data??{}};return y&&this.rememberHttpResponse(f,g),g})();this.httpInFlight.set(f,F);let E=await F.finally(()=>{this.httpInFlight.delete(f);}),M=this.nowMs()-n;return this.logHttpTiming(`#${r} ${e} response`,{status:E.status,networkMs:Number(M.toFixed(2))}),this.createTimedFetchTrace(E,r,n,s,t,M)}catch(c){let C=this.nowMs()-n;throw this.logHttpTiming(`#${r} ${e} failed`,{networkMs:Number(C.toFixed(2)),message:c?.message??String(c)}),c}}async parseJsonWithTiming(e,t){let i=this.nowMs(),r=await t.response.json().catch(()=>({})),n=this.nowMs()-i,s=this.nowMs()-t.startedAtMs;return this.logHttpTiming(`#${t.requestId} ${e} complete`,{method:t.method,url:t.url,status:t.response.status,networkMs:Number(t.networkMs.toFixed(2)),parseMs:Number(n.toFixed(2)),totalMs:Number(s.toFixed(2))}),r}getHttpBase(){if(this.config.httpBase)return this.config.httpBase.replace(/\/$/,"");let e=new URL(this.config.endpoint);return `${e.protocol}//${e.host}`}log(...e){this.isDebug&&console.log("[FlareClient]",...e);}constructor(e){this.config={autoReconnect:true,reconnectDelay:2,maxReconnectDelay:60,debug:false,connectionTimeout:1e4,...e},this.isDebug=this.config.debug||false,this.requestTimingEnabled=this.config.requestTiming??true;let{hostname:t,port:i,protocol:r}=new URL(this.config.endpoint),n=r==="https:",d=`${n?"wss":"ws"}://${t}:${i||(n?"443":"80")}/?appId=${this.config.appId}${this.config.apiKey?`&apiKey=${this.config.apiKey}`:""}`;this.transport=new H({url:d,publicKey:this.config.publicKey,autoReconnect:this.config.autoReconnect,reconnectDelay:this.config.reconnectDelay,maxReconnectDelay:this.config.maxReconnectDelay,onMessage:l=>this.handleIncoming(l),onOpen:()=>this.onConnected(),onClose:()=>this.onDisconnected(),onError:l=>this.handleTransportError(l),debug:this.isDebug});}connect(){this.setState("connecting"),this.transport.connect();}disconnect(){this.transport.disconnect(),this.setState("disconnected");}get connectionState(){return this.currentState}get isConnected(){return this.currentState==="connected"}onConnectionStateChange(e){return this.connectionListeners.push(e),()=>{this.connectionListeners=this.connectionListeners.filter(t=>t!==e);}}onError(e){return this.errorListeners.push(e),()=>{this.errorListeners=this.errorListeners.filter(t=>t!==e);}}collection(e){return new G(this,e)}registerQueryPreset(e,t){let i=String(e??"").trim();if(!i)throw new h("Preset name is required",u.QueryFailed);if(typeof t!="function")throw new h(`Query preset "${i}" handler must be a function`,u.QueryFailed);return this.queryPresets.set(i,t),this}registerQueryPresets(e){for(let[t,i]of Object.entries(e??{}))this.registerQueryPreset(t,i);return this}hasQueryPreset(e){return this.queryPresets.has(String(e??"").trim())}applyQueryPreset(e,t,i={}){let r=String(t??"").trim(),n=this.queryPresets.get(r);if(!n)throw new h(`Unknown query preset "${r}"`,u.QueryFailed);let s=n(e,i??{});if(!s||typeof s.get!="function")throw new h(`Query preset "${r}" must return a CollectionReference`,u.QueryFailed);return s}doc(e,t){return t!==void 0?new Q(this,e,t):new A(this,e)}async ping(){let e=Date.now();return await this.send("ping",{}),Date.now()-e}async call(e,t={}){let i=await this.send("call",{topic:e,payload:t});if(!i.success)throw new h(i.error??`CALL "${e}" failed`,u.QueryFailed);return i.result}async query(e,t={}){return (await this.send("query",{collection:e,query:t})).data??[]}setEmbedder(e){this.embedder=e;}markVectorField(e,t,i={dimensions:1536}){this.vectorSchema.has(e)||this.vectorSchema.set(e,new Map),this.vectorSchema.get(e).set(t,i);}async embedVectorFields(e,t){let i=this.vectorSchema.get(e);if(!i)return t;let r={...t};for(let[n,s]of i){let o=r[n];if(typeof o=="string"){let d=s.embed??this.embedder;if(!d){this.log(`[vector] No embedder for field "${n}" \u2014 storing raw text`);continue}r[n]=await d(o);}}return r}async joinPresence(e,t){return await this.send("presence_join",{room:e,meta:t}),this._startPresenceHeartbeat(e,t),()=>this.leavePresence(e)}async leavePresence(e){await this.send("presence_leave",{room:e}),this._stopPresenceHeartbeat();}onPresenceState(e,t){return this.presenceCallbacks.has(e)||this.presenceCallbacks.set(e,[]),this.presenceCallbacks.get(e).push(t),()=>{let i=this.presenceCallbacks.get(e)??[];this.presenceCallbacks.set(e,i.filter(r=>r!==t));}}onPresenceJoin(e,t){return this.presenceJoinCbs.has(e)||this.presenceJoinCbs.set(e,[]),this.presenceJoinCbs.get(e).push(t),()=>{let i=this.presenceJoinCbs.get(e)??[];this.presenceJoinCbs.set(e,i.filter(r=>r!==t));}}onPresenceLeave(e,t){return this.presenceLeaveCbs.has(e)||this.presenceLeaveCbs.set(e,[]),this.presenceLeaveCbs.get(e).push(t),()=>{let i=this.presenceLeaveCbs.get(e)??[];this.presenceLeaveCbs.set(e,i.filter(r=>r!==t));}}_startPresenceHeartbeat(e,t){this.presenceHeartbeatTimer||(this.presenceHeartbeatTimer=setInterval(()=>{this.isConnected&&this.send("presence_heartbeat",{meta:t}).catch(()=>{});},2e4));}_stopPresenceHeartbeat(){this.presenceHeartbeatTimer&&(clearInterval(this.presenceHeartbeatTimer),this.presenceHeartbeatTimer=void 0);}async syncOffline(){if(this.offlineQueue.length===0)return;this.log("Syncing offline operations",this.offlineQueue.length);let e=[...this.offlineQueue];this.offlineQueue.length=0;let t=await this.send("offline_sync",{operations:e});t.conflicts&&t.conflicts.length>0&&(this.log("Offline sync conflicts",t.conflicts),t.conflicts.forEach(i=>{let r=e.find(n=>n.id===i.operationId);r&&this.offlineQueue.push(r);}));}async beforeActivateSubscription(e){}async activateSubscription(e){if(!this.isConnected){this.pendingSubscriptionReplay=true;return}await this.beforeActivateSubscription(e),this.subscriptions.set(e.liveId,e.callback);try{let t=await this.send("subscribe",{collection:e.collection,docId:e.docId,query:e.query,skipSnapshot:e.options.skipSnapshot});if(!this.activeSubscriptions.has(e.baseId)){this.subscriptions.delete(e.liveId);return}t.subscriptionId&&t.subscriptionId!==e.liveId&&(this.subscriptions.delete(e.liveId),e.liveId=t.subscriptionId,this.subscriptions.set(e.liveId,e.callback),this.log("Subscription remapped",e.baseId,"\u2192",e.liveId));}catch(t){this.subscriptions.delete(e.liveId),this.pendingSubscriptionReplay=true;let i=this.toSubscriptionError(t);this.emitSubscriptionError(e.baseId,i),this.log("Subscription failed",t);}}toSubscriptionError(e){let t=e instanceof Error?e.message:String(e??"Unknown subscription error"),i=t.match(/^\[([^\]]+)\]\s*(.*)$/),r=i?.[1],n=(i?.[2]??t).trim()||t,s=r===u.PermissionDenied||t.includes(u.PermissionDenied);return {code:r,message:n,permissionDenied:s,raw:e}}emitSubscriptionError(e,t){this.subscriptionLastErrors.set(e,t);let i=this.subscriptionErrorHandlers.get(e);if(i)for(let r of i)try{r(t);}catch(n){this.log("Subscription error callback failed",n);}if(t.permissionDenied){let r=this.subscriptionPermissionHandlers.get(e);if(r)for(let n of r)try{n(t);}catch(s){this.log("Subscription permission callback failed",s);}}}async replayActiveSubscriptions(){if(!this.isConnected){this.pendingSubscriptionReplay=true;return}let e=Array.from(this.activeSubscriptions.values());if(e.length===0){this.pendingSubscriptionReplay=false;return}this.pendingSubscriptionReplay=false,this.subscriptionReplayPromise=this.subscriptionReplayPromise.then(async()=>{for(let t of e){if(!this.activeSubscriptions.has(t.baseId))continue;let i=t.liveId;this.subscriptions.delete(i),t.liveId=t.baseId,i&&await this.send("unsubscribe",{subscriptionId:i}).catch(()=>{}),await this.activateSubscription(t);}}).catch(t=>{this.pendingSubscriptionReplay=true,this.log("Subscription replay failed",t);}),await this.subscriptionReplayPromise;}subscribe(e,t,i,r,n,s={}){this.log("Creating subscription",e,t,i);let o={baseId:e,liveId:e,collection:t,docId:i,query:r,callback:n,options:s};this.activeSubscriptions.set(e,o),this.subscriptionErrorHandlers.has(e)||this.subscriptionErrorHandlers.set(e,new Set),this.subscriptionPermissionHandlers.has(e)||this.subscriptionPermissionHandlers.set(e,new Set),this.activateSubscription(o).catch(f=>{this.log("Subscription activation failed",f);});let d=()=>{let y=this.activeSubscriptions.get(e)?.liveId??e;this.log("Unsubscribing",y),this.activeSubscriptions.delete(e),this.subscriptions.delete(y),this.subscriptionErrorHandlers.delete(e),this.subscriptionPermissionHandlers.delete(e),this.subscriptionLastErrors.delete(e),this.isConnected&&this.send("unsubscribe",{subscriptionId:y}).catch(c=>this.log("Unsubscribe failed",c));},l=d;return l.unsubscribe=d,l.onError=f=>{this.subscriptionErrorHandlers.get(e)?.add(f);let y=this.subscriptionLastErrors.get(e);if(y)try{f(y);}catch(c){this.log("Subscription error callback failed",c);}return l},l.onPermissionDenied=f=>{this.subscriptionPermissionHandlers.get(e)?.add(f);let y=this.subscriptionLastErrors.get(e);if(y?.permissionDenied)try{f(y);}catch(c){this.log("Subscription permission callback failed",c);}return l},l.catch=f=>l.onError(f),l}async send(e,t){if(e==="write"&&t.collection&&t.data){let i=await this.embedVectorFields(t.collection,t.data);t={...t,data:this.normalizeOutboundData(i)};}return (e==="subscribe"||e==="query")&&t?.query&&(t={...t,query:this.normalizeOutboundQuery(t.query)}),new Promise((i,r)=>{let n=core.uuid2(18),s={id:n,type:e,ts:Date.now(),...t};this.pendingAcks.set(n,o=>{o.type==="error"?r(new Error(`[${o.code}] ${o.message}`)):i(o);}),this.isConnected?this.transport.send(s):(this.log("Queueing message for offline",s),this.offlineQueue.push(s),r(new Error("Not connected - message queued"))),setTimeout(()=>{this.pendingAcks.has(n)&&(this.pendingAcks.delete(n),r(new Error("Request timeout")));},this.config.connectionTimeout);})}handleTransportError(e){this.log("Transport error",e),this.errorListeners.forEach(t=>{try{t(e);}catch(i){this.log("Error listener error",i);}});}onConnected(){this.setState("connected"),this.log("Connected to FlareServer"),this.activeSubscriptions.size>0&&(this.pendingSubscriptionReplay=true),this.offlineQueue.length>0&&this.syncOffline().catch(e=>{this.log("Offline sync failed",e);});}onDisconnected(){this.currentState!=="disconnected"&&this.setState("reconnecting"),this.activeSubscriptions.size>0&&(this.pendingSubscriptionReplay=true),this.log("Disconnected from FlareServer");}setState(e){this.currentState!==e&&(this.currentState=e,this.log("Connection state changed",e),this.connectionListeners.forEach(t=>{try{t(e);}catch(i){this.log("Connection listener error",i);}}));}handleIncoming(e){if(this.log("Received message",e.type,e),e.type==="query_result"&&Array.isArray(e.data)&&(e={...e,data:this.normalizeInboundData(e.data)}),e.type==="ack"||e.type==="pong"||e.type==="auth_ok"||e.type==="call_response"||e.type==="query_result"){let t=this.pendingAcks.get(e.correlationId||e.id);t&&(t(e),this.pendingAcks.delete(e.correlationId||e.id));return}if(e.type==="error"){this.log("Server error",e.code,e.message);let t=new Error(`[${e.code}] ${e.message}`);this.errorListeners.forEach(r=>{try{r(t);}catch(n){this.log("Error listener error",n);}});let i=Array.from(this.activeSubscriptions.values()).find(r=>r.liveId===e.correlationId||r.baseId===e.correlationId);if(i&&this.emitSubscriptionError(i.baseId,{code:typeof e.code=="string"?e.code:void 0,message:String(e.message??"Subscription error"),permissionDenied:e.code===u.PermissionDenied,raw:e}),e.correlationId){let r=this.pendingAcks.get(e.correlationId);r&&(r(e),this.pendingAcks.delete(e.correlationId));}return}if(e.type==="presence_state"){(this.presenceCallbacks.get(e.room)??[]).forEach(i=>{try{i(e.members);}catch{}});return}if(e.type==="presence_join"){(this.presenceJoinCbs.get(e.room)??[]).forEach(i=>{try{i(e);}catch{}});return}if(e.type==="presence_leave"){(this.presenceLeaveCbs.get(e.room)??[]).forEach(i=>{try{i(e.uid);}catch{}});return}if(e.type==="snapshot"){let t=this.subscriptions.get(e.subscriptionId);if(t){let i=this.normalizeInboundData(Array.isArray(e.data)?e.data:e.data!=null?[e.data]:[]),r={type:"snapshot",subscriptionId:e.subscriptionId,collection:e.collection,data:Array.isArray(i)?i:[]};try{t(r);}catch(n){this.log("Subscription callback error",n);}}return}if(e.type==="change"){let t=this.subscriptions.get(e.subscriptionId);if(t){let i={type:"change",subscriptionId:e.subscriptionId,collection:e.collection,docId:e.docId,operation:e.operation,data:e.operation==="delete"?null:this.normalizeInboundData(e.data)};try{t(i);}catch(r){this.log("Subscription callback error",r);}}}}};var D=class extends q{authToken;userId;authGuard;authConfig;csrfToken;csrfInitPromise;csrfBootstrapAttempted=false;socketAuthSyncPromise;pushServiceWorkerInitPromise;authSession=null;authStateListeners=[];authConfigListeners=[];currentProfile=void 0;getDefaultCsrfCookieName(){return `__flare_csrf_${this.config.appId.replace(/[^a-zA-Z0-9_-]/g,"_")}`}getCsrfCookieName(){return this.authConfig?.cookie?.csrfTokenName??this.getDefaultCsrfCookieName()}getCsrfToken(){return this.getCookieValue(this.getCsrfCookieName())??this.csrfToken??null}getCookieValue(e){if(typeof document>"u")return null;let t=document.cookie.split(";").map(r=>r.trim()).find(r=>r.startsWith(`${e}=`)||r.startsWith(`${encodeURIComponent(e)}=`));if(!t)return null;let i=t.indexOf("=");return i>=0?decodeURIComponent(t.slice(i+1)):null}extractCsrfToken(e,t){let i=e,r=typeof i?.csrfToken=="string"?String(i.csrfToken):typeof i?.csrf_token=="string"?String(i.csrf_token):void 0;if(r)return r;if(!t)return;let n=t.headers.get("x-flare-csrf")??t.headers.get("x-csrf-token")??t.headers.get("csrf-token");return typeof n=="string"&&n.length>0?n:void 0}getCsrfHeaders(){let e=this.getCsrfToken();return e?{"x-flare-csrf":e}:{}}setCsrfToken(e){this.csrfToken=e,this.csrfBootstrapAttempted=true,this.log("CSRF token injected",{length:e.length});}async ensureCsrfProtection(){if(this.getCsrfToken()){this.csrfBootstrapAttempted=true;return}if(this.config.httpBase){this.csrfBootstrapAttempted=true;return}this.csrfBootstrapAttempted||(this.csrfInitPromise||(this.csrfBootstrapAttempted=true,this.csrfInitPromise=this.loadAuthConfig().then(()=>{}).finally(()=>{this.csrfInitPromise=void 0;})),await this.csrfInitPromise,this.getCsrfToken()||this.log("CSRF token unavailable after auth config load",{hasAuthConfig:!!this.authConfig,csrfCookieName:this.getCsrfCookieName()}));}async loadAuthConfig(){let e=this.getHttpBase(),t=new URLSearchParams({appId:this.config.appId});this.config.apiKey&&t.set("apiKey",this.config.apiKey);let i=`${e}/auth/config?${t.toString()}`,r=await this.timedFetch("loadAuthConfig",i,{credentials:"include",headers:this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}}),n=await this.parseJsonWithTiming("loadAuthConfig",r);return r.response.ok||this.throwFetchFlareError(n,"Failed to load auth config",u.QueryFailed),this.authConfig=n,this.csrfToken=this.extractCsrfToken(n,r.response)??this.csrfToken,this.authConfigListeners.forEach(s=>{try{s(this.authConfig);}catch(o){this.log("Auth config listener error",o);}}),this.authConfig}async fetchAuthConfig(){return this.authConfig?this.authConfig:this.loadAuthConfig()}onAuthConfigLoaded(e){return this.authConfigListeners.push(e),this.authConfig&&e(this.authConfig),()=>{this.authConfigListeners=this.authConfigListeners.filter(t=>t!==e);}}setProfile(e){this.currentProfile=e;}setAuthSession(e){this.authSession=e,e?(this.authToken=e.accessToken,this.userId=e.uid):(this.authToken=void 0,this.userId=void 0,this.currentProfile=void 0,this.httpResponseCache.clear(),this.httpInFlight.clear());let t=this.authSession?{...this.authSession,...this.currentProfile??{}}:null;this.authStateListeners.forEach(i=>{try{i(t);}catch(r){this.log("Auth state listener error",r);}});}onAuthStateChanged(e){this.authStateListeners.push(e);let t=this.authSession?{...this.authSession,...this.currentProfile??{}}:null;try{e(t);}catch(i){this.log("Auth state listener error during initialization",i);}return ()=>{this.authStateListeners=this.authStateListeners.filter(i=>i!==e);}}onAuthStateChange(e){return this.onAuthStateChanged(e)}get currentUser(){return this.currentProfile}getCurrentUser(){return this.currentUser}async syncSocketAuth(e){if(!this.isConnected)return;let t=await this.send("auth",e?{token:e}:{});if(t.type!=="auth_ok")throw new h("Socket auth sync failed",u.AuthenticationFailed);if(!e||t.uid==="anon"){this.authToken=void 0,this.userId=void 0,await this.updateSocketIdentity("anon");return}this.authToken=typeof t.token=="string"?t.token:e,this.userId=typeof t.uid=="string"?t.uid:this.userId,await this.updateSocketIdentity(typeof t.uid=="string"?t.uid:this.userId);}async updateSocketIdentity(e,t=false){let i=typeof e=="string"&&e.length>0?e:"anon",r=i!==this.socketAuthUid;this.socketAuthUid=i,(r||t||this.pendingSubscriptionReplay)&&this.activeSubscriptions.size>0&&await this.replayActiveSubscriptions();}async beforeActivateSubscription(e){if(!this.isConnected)return;let t=this.authSession;!t?.accessToken||!t.uid||this.socketAuthUid!==t.uid&&(this.socketAuthSyncPromise||(this.socketAuthSyncPromise=this.syncSocketAuth(t.accessToken).catch(i=>{throw this.log("Socket auth sync failed before subscribe",i),i}).finally(()=>{this.socketAuthSyncPromise=void 0;})),await this.socketAuthSyncPromise);}onConnected(){super.onConnected(),this.authSession?.accessToken&&this.syncSocketAuth(this.authSession.accessToken).catch(e=>{this.log("Socket auth sync failed after connect",e);});}handleIncoming(e){if(e.type==="auth_ok"&&!e.correlationId){let t=typeof e.token=="string"?e.token:void 0,i=typeof e.uid=="string"?e.uid:void 0;this.updateSocketIdentity(i,this.pendingSubscriptionReplay).catch(r=>{this.log("Socket identity update failed",r);}),t&&i&&i!=="anon"&&i!=="__admin__"?this.fetchAuthMe(t).then(r=>{this.setAuthSession({uid:i,accessToken:t,refreshToken:this.authSession?.refreshToken??null,email:r?.email??null,emailVerified:r?.email_verified});}).catch(()=>{this.setAuthSession({uid:i,accessToken:t,refreshToken:this.authSession?.refreshToken??null});}):i==="anon"&&this.authSession&&this.setAuthSession(null);}super.handleIncoming(e);}async auth(e){let t=await this.send("auth",{token:e});if(t.type==="auth_ok"){let i=t.token??e;this.authToken=i,this.userId=t.uid;let r=await this.fetchAuthMe(i).catch(()=>null);return this.setAuthSession({uid:t.uid??t.id,accessToken:i,refreshToken:this.authSession?.refreshToken??null,email:r?.email??null,emailVerified:r?.email_verified}),await this.updateSocketIdentity(t.uid),this.log("Authentication successful",t.uid),{uid:t.uid,token:t.token??e}}throw new h("Authentication failed",u.AuthenticationFailed)}async signInWithEmailAndPassword(e,t,i){try{let r=await this.requestEmailPasswordToken(e,t,i?.scope),n=await this.auth(r.access_token),s=await this.fetchAuthMe(r.access_token).catch(()=>null);return this.setAuthSession({uid:n.uid,accessToken:r.access_token,refreshToken:r.refresh_token,provider:r.provider,email:s?.email??e,emailVerified:s?.email_verified}),this.log("Credentials sign-in successful",n.uid),{...n,kind:r.kind,accessToken:r.access_token,refreshToken:r.refresh_token,authToken:r}}catch(r){let n=/invalid_email|user.not.found|no user/i.test(r?.message??"");if(i?.createIfMissing&&n){let s=await this.createUserWithEmail(e,t,{scope:i.scope,signInIfAllowed:true});if("verificationRequired"in s&&s.verificationRequired)throw new h("Email verification required before sign-in",u.AuthenticationFailed);return {uid:s.uid,token:s.token,accessToken:s.accessToken,refreshToken:s.refreshToken,authToken:s.authToken,created:true}}throw r instanceof h?r:new h(r instanceof Error?r.message:"Sign-in with email/password failed",r.error??r.code??u.AuthenticationFailed,r)}}async signInWithEmail(e,t,i){return this.signInWithEmailAndPassword(e,t,i)}async createUserWithEmail(e,t,i){let r=await this.registerWithEmail(e,t,i);if(r.verification_required)return {kind:r.kind,verificationRequired:true,emailSent:!!r.email_sent,preview:r.preview};let n=String(r.access_token??"");if(!n)throw new h("User created but no access token returned",u.AuthenticationFailed);let s={access_token:n,refresh_token:r.refresh_token?String(r.refresh_token):null,expires_in:r.expires_in?Number(r.expires_in):null,token_type:String(r.token_type??"Bearer"),scope:r.scope?String(r.scope):null,profile:null,provider:"credentials"},o=await this.auth(n),d=await this.fetchAuthMe(n).catch(()=>null);return this.setAuthSession({uid:o.uid,accessToken:n,refreshToken:s.refresh_token,provider:"credentials",email:d?.email??e,emailVerified:d?.email_verified}),{...o,accessToken:n,refreshToken:s.refresh_token,authToken:s,verificationRequired:false,emailSent:!!r.email_sent,preview:r.preview}}async createUserWithEmailAndPassword(e,t,i){return this.createUserWithEmail(e,t,i)}async signInOrCreateWithEmail(e,t,i){try{return {...await this.signInWithEmailAndPassword(e,t,{scope:i?.scope}),created:!1}}catch(r){if(!/invalid_email|user.not.found|no user/i.test(r?.message??""))throw r;let s=await this.createUserWithEmail(e,t,{scope:i?.scope,additionalParams:i?.additionalParams,signInIfAllowed:true});return "verificationRequired"in s&&s.verificationRequired?{...s,created:true}:{...s,created:true}}}async signInOrCreateWithEmailAndPassword(e,t,i){return this.signInOrCreateWithEmail(e,t,i)}async sendEmailVerification(e){let t=this.getHttpBase();await this.ensureCsrfProtection();let i=await this.timedFetch("sendEmailVerification",`${t}/auth/verify/send?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:JSON.stringify({email:e,appId:this.config.appId,apiKey:this.config.apiKey})}),r=await this.parseJsonWithTiming("sendEmailVerification",i);return i.response.ok||this.throwFetchFlareError(r,"Failed to send verification email",u.AuthenticationFailed),r}async verifyEmailWithCode(e,t){let i=this.getHttpBase();await this.ensureCsrfProtection();let r=await this.timedFetch("verifyEmailWithCode",`${i}/auth/verify/confirm?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:JSON.stringify({email:e,code:t,appId:this.config.appId,apiKey:this.config.apiKey})}),n=await this.parseJsonWithTiming("verifyEmailWithCode",r);return r.response.ok||this.throwFetchFlareError(n,"Email verification failed",u.AuthenticationFailed),n}async confirmEmailLink(e,t){let i=this.getHttpBase();await this.ensureCsrfProtection();let r=await this.timedFetch("confirmEmailLink",`${i}/auth/verify/confirm?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:JSON.stringify({token:e,email:t,appId:this.config.appId,apiKey:this.config.apiKey})}),n=await this.parseJsonWithTiming("confirmEmailLink",r);return r.response.ok||this.throwFetchFlareError(n,"Email link verification failed",u.AuthenticationFailed),n}async sendAccountRecovery(e){let t=this.getHttpBase();await this.ensureCsrfProtection();let i=await this.timedFetch("sendAccountRecovery",`${t}/auth/recover/send?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:JSON.stringify({email:e,appId:this.config.appId,apiKey:this.config.apiKey})}),r=await this.parseJsonWithTiming("sendAccountRecovery",i);return i.response.ok||this.throwFetchFlareError(r,"Failed to send recovery email",u.AuthenticationFailed),r}async recoverAccountWithCode(e,t,i){let r=this.getHttpBase();await this.ensureCsrfProtection();let n=await this.timedFetch("recoverAccountWithCode",`${r}/auth/recover/confirm?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:JSON.stringify({email:e,code:t,newPassword:i,appId:this.config.appId,apiKey:this.config.apiKey})}),s=await this.parseJsonWithTiming("recoverAccountWithCode",n);return n.response.ok||this.throwFetchFlareError(s,"Account recovery failed",u.AuthenticationFailed),s}async recoverAccountWithToken(e,t){let i=this.getHttpBase();await this.ensureCsrfProtection();let r=await this.timedFetch("recoverAccountWithToken",`${i}/auth/recover/confirm?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:JSON.stringify({token:e,newPassword:t,appId:this.config.appId,apiKey:this.config.apiKey})}),n=await this.parseJsonWithTiming("recoverAccountWithToken",r);return r.response.ok||this.throwFetchFlareError(n,"Account recovery failed",u.AuthenticationFailed),n}toUint8ArrayFromBase64Url(e){let t=e.replace(/-/g,"+").replace(/_/g,"/"),i="=".repeat((4-t.length%4)%4),r=t+i,n=atob(r),s=new Uint8Array(n.length);for(let o=0;o<n.length;o+=1)s[o]=n.charCodeAt(o);return s}encodePushTokenFromSubscription(e){let t=e.toJSON(),i=String(t.endpoint??"").trim(),r=String(t.keys?.p256dh??"").trim(),n=String(t.keys?.auth??"").trim(),s=JSON.stringify({endpoint:i,p256dh:r,auth:n});return `webpush:${btoa(s)}`}async fetchPushSetupConfig(){let e=this.getHttpBase(),t=new URLSearchParams({appId:this.config.appId});this.config.apiKey&&t.set("apiKey",this.config.apiKey);let i=`${e}/push/config?${t.toString()}`,r=await this.timedFetch("fetchPushSetupConfig",i,{method:"GET",credentials:"include",headers:this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}}),n=await this.parseJsonWithTiming("fetchPushSetupConfig",r);r.response.ok||this.throwFetchFlareError(n,"Failed to fetch push setup config",u.QueryFailed);let s=String(n.vapidPublicKey??"").trim(),o=String(n.serviceWorkerPath??"").trim();if(o.startsWith("/"))try{let l=new URL(e,typeof window<"u"?window.location.origin:"http://localhost").pathname.replace(/\/+$/,"");l&&l!=="/"&&!o.startsWith(`${l}/`)&&(o=`${l}${o}`);}catch{}if(!s||!o)throw new h("Push setup response is missing vapidPublicKey or serviceWorkerPath",u.ParseError,n);return {vapidPublicKey:s,serviceWorkerPath:o}}async setupPushServiceWorker(){return typeof window>"u"||typeof navigator>"u"||!("serviceWorker"in navigator)?null:(this.pushServiceWorkerInitPromise||(this.pushServiceWorkerInitPromise=(async()=>{let e=await this.fetchPushSetupConfig(),t=new URL(e.serviceWorkerPath,window.location.origin);if(t.origin!==window.location.origin)throw new h("Service worker URL must be same-origin with the app",u.WriteFailed);return await navigator.serviceWorker.register(t.pathname+t.search,{scope:"/"})})().catch(e=>{throw this.log("Push service worker setup failed",e),e})),this.pushServiceWorkerInitPromise)}async requestPushPermission(){if(typeof window>"u"||typeof Notification>"u")throw new h("Push permission can only be requested in browser runtime",u.WriteFailed);let e=await Notification.requestPermission();if(e!=="granted")throw new h(`Push permission is ${e}`,u.PermissionDenied);return e}async acquireBrowserPushToken(e={}){if(typeof window>"u"||typeof navigator>"u")throw new h("Push token acquisition can only run in browser runtime",u.WriteFailed);if(!("serviceWorker"in navigator))throw new h("Service worker is not supported in this browser",u.WriteFailed);if(!("PushManager"in window))throw new h("Push manager is not supported in this browser",u.WriteFailed);await this.requestPushPermission();let t=e.applicationServerKey?null:await this.fetchPushSetupConfig(),i=e.serviceWorkerRegistration??await this.setupPushServiceWorker()??await navigator.serviceWorker.ready,r=e.subscription??await i.pushManager.getSubscription();if(e.forceResubscribe&&r&&(await r.unsubscribe().catch(()=>{}),r=null),!r){let s=e.applicationServerKey??t?.vapidPublicKey;if(!s)throw new h("No VAPID public key available for push subscription",u.WriteFailed);r=await i.pushManager.subscribe({userVisibleOnly:true,applicationServerKey:this.toUint8ArrayFromBase64Url(s)});}return {token:this.encodePushTokenFromSubscription(r),subscription:r}}async enableBrowserPush(e={}){let{token:t,subscription:i}=await this.acquireBrowserPushToken(e);return {...await this.registerPushToken({token:t,platform:e.platform??"web",deviceId:e.deviceId,topics:e.topics,authAppId:e.authAppId}),subscription:i}}async registerPushToken(e){let t=this.getHttpBase();await this.ensureCsrfProtection();let i=String(e.token??"").trim();if(!i)throw new h("Push token is required",u.WriteFailed);let r=await this.timedFetch("registerPushToken",`${t}/notify/token?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{},...this.authSession?.accessToken?{Authorization:`Bearer ${this.authSession.accessToken}`}:{}},body:JSON.stringify({appId:this.config.appId,token:i,platform:e.platform,deviceId:e.deviceId,topics:e.topics,...e.authAppId?{authAppId:e.authAppId}:{}})}),n=await this.parseJsonWithTiming("registerPushToken",r);return r.response.ok||this.throwFetchFlareError(n,"Failed to register push token",u.WriteFailed),{registered:!!n.registered,appId:String(n.appId??this.config.appId),uid:String(n.uid??this.authSession?.uid??""),token:String(n.token??i),...typeof n.platform=="string"?{platform:n.platform}:{}}}async unregisterPushToken(e,t){let i=this.getHttpBase();await this.ensureCsrfProtection();let r=String(e??"").trim();if(!r)throw new h("Push token is required",u.WriteFailed);let n=await this.timedFetch("unregisterPushToken",`${i}/notify/token?appId=${encodeURIComponent(this.config.appId)}`,{method:"DELETE",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{},...this.authSession?.accessToken?{Authorization:`Bearer ${this.authSession.accessToken}`}:{}},body:JSON.stringify({appId:this.config.appId,token:r,...t?{authAppId:t}:{}})}),s=await this.parseJsonWithTiming("unregisterPushToken",n);return n.response.ok||this.throwFetchFlareError(s,"Failed to unregister push token",u.WriteFailed),{unregistered:!!s.unregistered,appId:String(s.appId??this.config.appId),token:String(s.token??r),removed:!!s.removed}}async sendPushNotification(e){let t=this.getHttpBase();await this.ensureCsrfProtection();let i=await this.timedFetch("sendPushNotification",`${t}/system/apps/${encodeURIComponent(this.config.appId)}/notifications/send`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.authSession?.accessToken?{Authorization:`Bearer ${this.authSession.accessToken}`}:{},...e.authAppId?{"x-flare-auth-app-id":e.authAppId}:{}},body:JSON.stringify({...e,appId:this.config.appId})}),r=await this.parseJsonWithTiming("sendPushNotification",i);return i.response.ok||this.throwFetchFlareError(r,"Failed to send push notification",u.WriteFailed),{sent:!!r.sent,appId:String(r.appId??this.config.appId),targetCount:Number(r.targetCount??0),successCount:Number(r.successCount??0),failureCount:Number(r.failureCount??0),invalidatedTokenCount:Number(r.invalidatedTokenCount??0),dryRun:!!r.dryRun}}async sendEmail(e){let t=this.getHttpBase();await this.ensureCsrfProtection();let i=await this.timedFetch("sendEmail",`${t}/system/apps/${encodeURIComponent(this.config.appId)}/email/send`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.authSession?.accessToken?{Authorization:`Bearer ${this.authSession.accessToken}`}:{},...e.authAppId?{"x-flare-auth-app-id":e.authAppId}:{}},body:JSON.stringify({...e,appId:this.config.appId})}),r=await this.parseJsonWithTiming("sendEmail",i);return i.response.ok||this.throwFetchFlareError(r,"Failed to send template email",u.WriteFailed),{sent:!!r.sent,appId:String(r.appId??this.config.appId),tag:String(r.tag??e.tag??""),recipientCount:Number(r.recipientCount??0),acceptedCount:Number(r.acceptedCount??0),rejectedCount:Number(r.rejectedCount??0),...typeof r.includeVerificationLink=="boolean"?{includeVerificationLink:r.includeVerificationLink}:{},...typeof r.linkId=="string"?{linkId:r.linkId}:{},...typeof r.verifyUrl=="string"?{verifyUrl:r.verifyUrl}:{},...typeof r.messageId=="string"?{messageId:r.messageId}:{}}}async verifyEmailLink(e){let t=this.getHttpBase(),i=String(e.token??"").trim();if(!i)throw new h("Verification token is required",u.WriteFailed);let r=await this.timedFetch("verifyEmailLink",`${t}/email/link/verify?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{},...this.authSession?.accessToken?{Authorization:`Bearer ${this.authSession.accessToken}`}:{},...e.authAppId?{"x-flare-auth-app-id":e.authAppId}:{}},body:JSON.stringify({appId:this.config.appId,apiKey:this.config.apiKey,token:i,...e.tag?{tag:e.tag}:{},...e.email?{email:e.email}:{},...e.authAppId?{authAppId:e.authAppId}:{}})}),n=await this.parseJsonWithTiming("verifyEmailLink",r);return r.response.ok||this.throwFetchFlareError(n,"Failed to verify email link",u.WriteFailed),{verified:!!(n.verified??n.accepted),alreadyVerified:!!(n.alreadyVerified??n.alreadyAccepted),appId:String(n.appId??this.config.appId),linkId:String(n.linkId??""),email:String(n.email??""),tag:String(n.tag??e.tag??""),...typeof n.verifiedAt=="string"?{verifiedAt:n.verifiedAt}:{},...typeof n.acceptedByUid=="string"?{acceptedByUid:n.acceptedByUid}:{}}}async signIn(e,t,i){let r=typeof e?.signIn=="function",n=r?e:await this.getAuthGuard(),s=r?t:e,o=r?i:t;return n.signIn(s,o)}async signInWithGoogle(e){return this.signIn("google",e)}async signInWithGitHub(e){return this.signIn("github",e)}async signInWithFacebook(e){return this.signIn("facebook",e)}async signInWithDropbox(e){return this.signIn("dropbox",e)}async handleSignInRedirect(e,t=false){let i=typeof e?.handleRedirect=="function",r=i?e:await this.getAuthGuard(),n=i?t:typeof e=="boolean"?e:false,s=await r.handleRedirect(n);if(!s||!s.access_token||!s.provider)return null;let o=await this.exchangeProviderToken(s.provider,s.access_token),d=await this.auth(o.token),l=await this.fetchAuthMe(o.token).catch(()=>null);return this.setAuthSession({uid:d.uid,accessToken:o.token,refreshToken:s.refresh_token,provider:s.provider,email:l?.email??null,emailVerified:l?.email_verified}),{...d,authToken:s,provider:s.provider}}async exchangeProviderToken(e,t){let i=`${this.getHttpBase()}/auth/exchange`;await this.ensureCsrfProtection();let r=await this.timedFetch("exchangeProviderToken",i,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders()},body:JSON.stringify({appId:this.config.appId,client_id:this.config.apiKey,provider:e,access_token:t})}),n=await this.parseJsonWithTiming("exchangeProviderToken",r);if(r.response.ok||this.throwFetchFlareError(n,"OAuth token exchange failed",u.AuthenticationFailed),!n?.token)throw new h("OAuth token exchange failed",u.ParseError,n);return {token:String(n.token)}}async getAuthGuard(){if(this.authGuard)return this.authGuard;let e=await this.fetchAuthConfig();if(!e.enabled)throw new h("Authentication is disabled for this app",u.AuthenticationFailed);let t=this.getHttpBase(),i=`${t}/auth/oauth/token?appId=${encodeURIComponent(this.config.appId)}`,r=[],n=(s,o)=>({...o,token_url:i,tokenParams:{...o.tokenParams??{},provider:s}});if(e.providers.credentials?.enabled&&r.push({...auth.Credentials({clientId:this.config.apiKey}),token_url:`${t}/auth/token?appId=${encodeURIComponent(this.config.appId)}`,createUserUrl:`${t}/auth/register?appId=${encodeURIComponent(this.config.appId)}`,createUserGrantType:"create_user"}),e.providers.anonymous?.enabled&&r.push({...auth.Anonymous({clientId:this.config.apiKey}),token_url:`${t}/auth/token?appId=${encodeURIComponent(this.config.appId)}`}),e.providers.google?.enabled&&e.providers.google.clientId&&r.push(n("google",auth.Google({clientId:e.providers.google.clientId,scopes:e.providers.google.scopes}))),e.providers.github?.enabled&&e.providers.github.clientId&&r.push(n("github",auth.GitHub({clientId:e.providers.github.clientId,scopes:e.providers.github.scopes}))),e.providers.facebook?.enabled&&e.providers.facebook.clientId&&r.push(n("facebook",auth.Facebook({clientId:e.providers.facebook.clientId,scopes:e.providers.facebook.scopes}))),e.providers.dropbox?.enabled&&e.providers.dropbox.clientId&&r.push(n("dropbox",auth.Dropbox({clientId:e.providers.dropbox.clientId,scopes:e.providers.dropbox.scopes}))),e.providers.apple?.enabled&&e.providers.apple.clientId&&r.push(n("apple",auth.Apple({clientId:e.providers.apple.clientId,scopes:e.providers.apple.scopes}))),e.providers.twitter?.enabled&&e.providers.twitter.clientId&&r.push(n("twitter",auth.Twitter({clientId:e.providers.twitter.clientId,scopes:e.providers.twitter.scopes}))),r.length===0)throw new h("No authentication providers are enabled for this app",u.AuthenticationFailed);return this.authGuard=new auth.AuthGuard({providers:r,redirectUri:e.redirectUri}),this.authGuard}async refreshAuthSession(e){let t=this.getHttpBase();await this.ensureCsrfProtection();let i=await this.timedFetch("refreshAuthSession",`${t}/auth/refresh?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:JSON.stringify({appId:this.config.appId,apiKey:this.config.apiKey,...e?{refresh_token:e}:{}})}),r=await this.parseJsonWithTiming("refreshAuthSession",i);if(!i.response.ok){if(i.response.status===401)return this.setAuthSession(null),await this.syncSocketAuth(null).catch(()=>{}),null;this.throwFetchFlareError(r,"Failed to refresh auth session",u.AuthenticationFailed);}let n=String(r.access_token??"");if(!n)throw new h("Refresh succeeded but no access token was returned",u.ParseError);let s=await this.fetchAuthMe(n).catch(()=>null),o={uid:String(s?.id??this.authSession?.uid??this.userId??""),accessToken:n,refreshToken:r.refresh_token?String(r.refresh_token):this.authSession?.refreshToken??null,provider:this.authSession?.provider,email:s?.email??this.authSession?.email??null,emailVerified:s?.email_verified};if(s){try{delete s.kind,s.uid=s.id??s.uid,delete s.id;}catch{}this.setProfile(s);}return this.setAuthSession(o),await this.syncSocketAuth(n).catch(()=>{}),o}async issueSsrToken(e=120){let t=this.getHttpBase();await this.ensureCsrfProtection();let i=await this.timedFetch("issueSsrToken",`${t}/auth/ssr/token?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:JSON.stringify({appId:this.config.appId,apiKey:this.config.apiKey,ttlSeconds:e})}),r=await this.parseJsonWithTiming("issueSsrToken",i);i.response.ok||this.throwFetchFlareError(r,"Failed to mint SSR token",u.AuthenticationFailed);let n=String(r.token??"");if(!n)throw new h("SSR token response is missing token",u.ParseError,r);return {token:n,token_type:String(r.token_type??"Bearer"),expires_in:Number(r.expires_in??0),uid:String(r.uid??""),role:String(r.role??"user"),...typeof r.email=="string"?{email:r.email}:{}}}async signOut(){try{if(this.authSession?.accessToken||this.authSession?.refreshToken||this.config.httpBase){let t=this.getHttpBase();await this.ensureCsrfProtection(),await this.timedFetch("signOut",`${t}/auth/logout?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{},...this.authSession?.accessToken?{Authorization:`Bearer ${this.authSession.accessToken}`}:{}},body:JSON.stringify({appId:this.config.appId,apiKey:this.config.apiKey,refresh_token:this.authSession?.refreshToken})}).catch(()=>{});}}finally{this.setAuthSession(null),await this.syncSocketAuth(null).catch(()=>{});}this.log("Signed out");}async registerWithEmail(e,t,i){let r=this.getHttpBase();await this.ensureCsrfProtection();let n=new URLSearchParams;n.set("appId",this.config.appId),n.set("client_id",this.config.apiKey??""),n.set("grant_type","create_user"),n.set("email",e),n.set("password",t),i?.scope?.length&&n.set("scope",i.scope.join(" ")),i?.additionalParams&&n.set("additional_params",JSON.stringify(i.additionalParams));let s=await this.timedFetch("registerWithEmail",`${r}/auth/register?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/x-www-form-urlencoded",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:n.toString()}),o=await this.parseJsonWithTiming("registerWithEmail",s);return !s.response.ok&&s.response.status!==202&&this.throwFetchFlareError(o,"User creation failed",u.WriteFailed),o}async requestEmailPasswordToken(e,t,i){let r=this.getHttpBase();await this.ensureCsrfProtection();let n=new URLSearchParams;n.set("appId",this.config.appId),n.set("client_id",this.config.apiKey??""),n.set("grant_type","password"),n.set("email",e),n.set("password",t),i?.length&&n.set("scope",i.join(" "));let s=await this.timedFetch("requestEmailPasswordToken",`${r}/auth/token?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/x-www-form-urlencoded",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:n.toString()}),o=await this.parseJsonWithTiming("requestEmailPasswordToken",s);return s.response.ok||this.throwFetchFlareError(o,"Sign-in with email/password failed",u.AuthenticationFailed),{kind:String(o.kind),access_token:String(o.access_token??""),refresh_token:o.refresh_token?String(o.refresh_token):null,expires_in:o.expires_in?Number(o.expires_in):null,token_type:String(o.token_type??"Bearer"),scope:o.scope?String(o.scope):null,profile:null,provider:"credentials"}}async fetchAuthMe(e){let t=this.getHttpBase(),i=new URLSearchParams({appId:this.config.appId});this.config.apiKey&&i.set("apiKey",this.config.apiKey);let r=`${t}/auth/me?${i.toString()}`,n=await this.timedFetch("fetchAuthMe",r,{credentials:"include",headers:{Authorization:`Bearer ${e}`,...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}}}),s=await this.parseJsonWithTiming("fetchAuthMe",n);return n.response.ok||this.throwFetchFlareError(s,"Failed to fetch profile",u.QueryFailed),s}};var Y=class extends D{autoPushRegisteredIdentity;constructor(e){super(e),this.log("FlareClient initialized",e),e.pushNotifications===true&&this.enableAutoPushNotificationsAfterAuth();}enableAutoPushNotificationsAfterAuth(){let e=async()=>{let t=this.authSession,i=String(t?.uid??"").trim()||"anon",r=String(t?.accessToken??"").trim(),n=i!=="anon"&&r?i:"anon";if(this.autoPushRegisteredIdentity!==n)try{await this.autoEnablePushNotifications(),this.autoPushRegisteredIdentity=n;}catch(s){this.log("Auto push enable failed",s);}};this.onAuthStateChanged(()=>{e().catch(()=>{});}),e().catch(()=>{});}async autoEnablePushNotifications(){await this.setupPushServiceWorker().catch(()=>{}),await this.requestPushPermission();let{token:e}=await this.acquireBrowserPushToken();await this.registerPushToken({token:e,platform:"web",topics:[this.config.appId]});}},re=Y;function Z(a){return `__flare_csrf_${a.replace(/[^a-zA-Z0-9_-]/g,"_")}`}function Ie(a){return `__flare_csrf_${a.replace(/[^a-zA-Z0-9_-]/g,"_")}`}function L(a,e){let t=e.toLowerCase();for(let[i,r]of Object.entries(a??{}))if(i.toLowerCase()===t&&typeof r=="string")return r}function Re(a){let e=L(a,"set-cookie");if(typeof e=="string"&&e.length>0)return [e];for(let[t,i]of Object.entries(a??{}))if(t.toLowerCase()==="set-cookie"&&Array.isArray(i))return i.filter(r=>typeof r=="string");return []}function xe(a,e){for(let t of a){let i=t.split(";").map(d=>d.trim()),[r]=i;if(!r)continue;let n=r.indexOf("=");if(n<=0)continue;let s=decodeURIComponent(r.slice(0,n)),o=r.slice(n+1);if(s===e)return decodeURIComponent(o)}}async function Fe(a){let e=new URL("/auth/config",a.endpoint);return e.searchParams.set("appId",a.appId),a.apiKey&&e.searchParams.set("apiKey",a.apiKey),await core.withGet(e.toString(),{ignoreKind:true,withCredentials:true,returnRawResponse:true,headers:a.apiKey?{"x-flare-api-key":a.apiKey}:{},appendCookiesToBody:false,appendTimestamp:false}).catch(()=>null)}async function ie(a){let e=await Fe(a),t=e?.data,i=e?.headers??{},r=L(i,"x-flare-csrf")??L(i,"x-csrf-token")??L(i,"csrf-token");if(typeof r=="string"&&r.length>0)return {csrfToken:r,...t};let n=t?.cookie?.csrfTokenName,s=n&&n.length>0?n:Ie(a.appId),o=Re(i),d=xe(o,s);if(typeof d=="string"&&d.length>0)return {csrfToken:d,...t}}function ne(a,e,t){return `${encodeURIComponent(a)}=${encodeURIComponent(e)}; HttpOnly; SameSite=Strict; Path=/; Max-Age=${t}`}function Ee(a){let e=a.proxyCookieName??Z(a.appId),t=a.proxyCookieMaxAge??3600;return async function(r){let n=await ie(a),s=n?.csrfToken,o=new Headers({"Content-Type":"application/json"});return s&&o.set("Set-Cookie",ne(e,s,t)),new Response(JSON.stringify({csrfToken:s??null,...n}),{status:200,headers:o})}}function Me(a){let e=a.proxyCookieName??Z(a.appId),t=a.proxyCookieMaxAge??3600;return async function(r,n){if(r.method!=="GET"&&r.method!=="HEAD"){n.status(405).json({error:"Method not allowed"});return}let o=(await ie(a))?.csrfToken;o&&n.setHeader("Set-Cookie",ne(e,o,t)),n.status(200).json({csrfToken:o??null});}}function Qe(a,e,t){let i=t??Z(e);if(a instanceof Request){let s=(a.headers.get("cookie")??"").split(";").map(d=>d.trim()).find(d=>d.startsWith(`${encodeURIComponent(i)}=`)||d.startsWith(`${i}=`));if(!s)return null;let o=s.indexOf("=");return o>=0?decodeURIComponent(s.slice(o+1)):null}let{cookies:r}=a;return typeof r?.get=="function"?r.get(i)?.value??null:r&&typeof r=="object"?r[i]??null:null}function Oe(a,e){let t={};return a&&(t["x-flare-csrf"]=a),e?.accessToken&&(t.Authorization=`Bearer ${e.accessToken}`),e?.apiKey&&(t["x-flare-api-key"]=e.apiKey),t}var Be=a=>a==="guest"?"auth == null":a==="auth"?"auth != null":"true",Ne=(a,e)=>{let t=String(e??"").trim();return t?a==="true"?t:`(${a}) && (${t})`:a},_e=a=>{let e=String(a??"").trim();if(!e||e==="false")return {auth:"any"};if(e==="auth != null")return {auth:"auth"};if(e==="auth == null")return {auth:"guest"};if(e==="true")return {auth:"any"};let t=e.match(/^\((auth != null|auth == null|true)\)\s*&&\s*\((.+)\)$/);if(t)return {auth:se(t[1]),condition:t[2].trim()};let i=e.match(/^(auth != null|auth == null|true)\s*&&\s*(.+)$/);return i?{auth:se(i[1]),condition:i[2].trim()}:{auth:"any",condition:e}},se=a=>{let e=String(a??"").trim();return e==="auth == null"?"guest":e==="auth != null"?"auth":"any"},Bt=a=>{let e={};for(let t of a){let i=String(t.collection||"").trim();if(!i)continue;let r=i==="any"?"*":i,n=Ne(Be(t.auth),t.condition);e[r]={".read":t.permissions.includes("read")?n:"false",".create":t.permissions.includes("create")?n:"false",".update":t.permissions.includes("update")?n:"false",".delete":t.permissions.includes("delete")?n:"false"};}return e},Nt=a=>Object.entries(a).map(([e,t],i)=>{let r=t?.[".read"],n=t?.[".create"],s=t?.[".update"],o=t?.[".delete"],d=t?.[".write"],l=[];typeof r=="string"&&r.trim()!=="false"&&l.push("read");let f=typeof n=="string"&&n.trim()!=="false"||typeof d=="string"&&d.trim()!=="false",y=typeof s=="string"&&s.trim()!=="false"||typeof d=="string"&&d.trim()!=="false",c=typeof o=="string"&&o.trim()!=="false"||typeof d=="string"&&d.trim()!=="false";f&&l.push("create"),y&&l.push("update"),c&&l.push("delete");let S=_e(r||n||s||o||d);return {id:`${e}-${i}`,name:e==="*"?"All Collections":e,auth:S.auth,collection:e==="*"?"any":e,condition:S.condition,permissions:l}});var He=(y=>(y.authEmailNotVerified="auth/email-not-verified",y.authEmailAlreadyVerified="auth/email-already-verified",y.authInvalidToken="auth/invalid-token",y.authUserDisabled="auth/user-disabled",y.authUserNotFound="auth/user-not-found",y.authWrongPassword="auth/wrong-password",y.authEmailAlreadyInUse="auth/email-already-in-use",y.authInvalidEmail="auth/invalid-email",y.authWeakPassword="auth/weak-password",y.authTooManyRequests="auth/too-many-requests",y.authInternalError="auth/internal-error",y))(He||{});var qe=(g=>(g.health="health",g.authConfig="auth_config",g.authRegistration="auth/registration",g.authRegistrationVerificationRequired="auth/registration-verification-required",g.authSession="auth/session",g.authExchange="auth/exchange",g.authLogout="auth/logout",g.authSsrBridge="auth/ssr_bridge",g.authSsrVerify="auth/ssr_verify",g.accountRecovery="account/recovery",g.emailVerification="email/verification",g.verificationDispatch="verification/dispatch",g.authProfile="auth/profile",g.adminToken="admin/token",g.documentDelete="document/delete",g.documentsDelete="documents/delete",g.documents="documents",g.document="document",g.documentCreate="document/create",g.documentUpdate="document/update",g.oauthProviderResponse="oauth_provider_response",g.success="success",g.response="response",g))(qe||{});var k=null,O=null,U=null,De=a=>JSON.stringify({endpoint:a.endpoint,appId:a.appId,apiKey:a.apiKey,publicKey:a.publicKey,autoReconnect:a.autoReconnect,reconnectDelay:a.reconnectDelay,maxReconnectDelay:a.maxReconnectDelay}),$t=a=>{let e=De(a);if(k&&U!==e&&(k.disconnect(),k=null,O=null,U=null),!k){k=new re(a),U=e;let t=typeof window<"u"&&typeof document<"u",i=typeof process<"u"&&typeof process.env?.NEXT_RUNTIME=="string";(t||!i)&&k.connect(),t&&k.setupPushServiceWorker().catch(()=>{}),O=new Proxy(k,{get(r,n,s){if(n==="onAuthStateChange")return r.onAuthStateChanged.bind(r);if(n==="onAuthConfigLoaded")return r.onAuthConfigLoaded.bind(r);let o=Reflect.get(r,n,s);return typeof o=="function"?o.bind(r):o}});}return O??k},Kt=()=>O??k,Jt=()=>{k&&(k.disconnect(),k=null,O=null,U=null);};
|
|
3
|
-
Object.defineProperty(exports,"Anonymous",{enumerable:true,get:function(){return auth.Anonymous}});Object.defineProperty(exports,"Apple",{enumerable:true,get:function(){return auth.Apple}});Object.defineProperty(exports,"AuthGuard",{enumerable:true,get:function(){return auth.AuthGuard}});Object.defineProperty(exports,"Credentials",{enumerable:true,get:function(){return auth.Credentials}});Object.defineProperty(exports,"Dropbox",{enumerable:true,get:function(){return auth.Dropbox}});Object.defineProperty(exports,"Facebook",{enumerable:true,get:function(){return auth.Facebook}});Object.defineProperty(exports,"GitHub",{enumerable:true,get:function(){return auth.GitHub}});Object.defineProperty(exports,"Google",{enumerable:true,get:function(){return auth.Google}});Object.defineProperty(exports,"Providers",{enumerable:true,get:function(){return auth.Providers}});Object.defineProperty(exports,"Twitter",{enumerable:true,get:function(){return auth.Twitter}});Object.defineProperty(exports,"setupProvider",{enumerable:true,get:function(){return auth.setupProvider}});exports.CollectionReference=G;exports.DocumentQueryBuilder=A;exports.DocumentReference=
|
|
2
|
+
var h=class extends Error{constructor(t,i,r){super(t);this.code=i;this.cause=r;this.name="ZuzFlareError";}};var oe={AuthenticationFailed:"AUTHENTICATION_FAILED",PermissionDenied:"PERMISSION_DENIED",WriteFailed:"WRITE_FAILED",QueryFailed:"QUERY_FAILED",ParseError:"PARSE_ERROR"},d=oe;var ae=(u=>(u.SUBSCRIBE="subscribe",u.UNSUBSCRIBE="unsubscribe",u.WRITE="write",u.DELETE="delete",u.AUTH="auth",u.PING="ping",u.OFFLINE_SYNC="offline_sync",u.CALL="call",u.QUERY="query",u.PRESENCE_JOIN="presence_join",u.PRESENCE_LEAVE="presence_leave",u.PRESENCE_HEARTBEAT="presence_heartbeat",u))(ae||{}),ce=(u=>(u.SNAPSHOT="snapshot",u.CHANGE="change",u.ERROR="error",u.ACK="ack",u.PONG="pong",u.AUTH_OK="auth_ok",u.OFFLINE_ACK="offline_ack",u.CALL_RESPONSE="call_response",u.QUERY_RESULT="query_result",u.PRESENCE_STATE="presence_state",u.PRESENCE_JOIN="presence_join",u.PRESENCE_LEAVE="presence_leave",u))(ce||{});function j(a){let e=[];for(let[t,i]of Object.entries(a))if(typeof i=="string"){let r=i.match(/^(>=|<=|!=|>|<|==)\s*(.+)$/);if(r){let[,n,s]=r;e.push({field:t,op:n,value:ee(s.trim())});}else e.push({field:t,op:"==",value:i});}else Array.isArray(i)?e.push({field:t,op:"in",value:i}):e.push({field:t,op:"==",value:i});return e}function ee(a){if(!isNaN(Number(a)))return Number(a);if(a==="true")return true;if(a==="false")return false;if(a==="null")return null;if(a!=="undefined")return a}var A=class{constructor(e,t,i){this.client=e;this.collection=t;this.docIdFromRef=i;}whereCondition;updateData;setData;deleteOp=false;promise;where(e){return this.whereCondition=e,this}update(e){return this.updateData=e,this}set(e){return this.setData=e,this}delete(){return this.deleteOp=true,this}getDocId(){if(this.docIdFromRef)return this.docIdFromRef;if(this.whereCondition&&(this.whereCondition.id||this.whereCondition._id)){let e=this.whereCondition.id??this.whereCondition._id;if(typeof e=="string")return e}throw new h('Document ID not specified. Use .where({ id: "..." }) or doc(collection, id)',d.QueryFailed)}async execute(){return this._execute()}async _execute(){let e=this.getDocId();if(this.deleteOp){await this.client.send("delete",{collection:this.collection,docId:e});return}if(this.updateData){await this.client.send("write",{collection:this.collection,docId:e,data:this.updateData,merge:true});return}if(this.setData){await this.client.send("write",{collection:this.collection,docId:e,data:this.setData,merge:false});return}return this.get()}then(e,t){return this.promise||(this.promise=this._execute()),this.promise.then(e,t)}async get(){let e=this.getDocId(),t=core.uuid2(18);return new Promise((i,r)=>{let n=this.client.subscribe(t,this.collection,e,void 0,s=>{s.type==="snapshot"&&(n(),i(s.data));});setTimeout(()=>{n(),r(new Error("Document fetch timeout"));},1e4);})}onSnapshot(e){let t=this.getDocId(),i=core.uuid2(18);return this.client.subscribe(i,this.collection,t,void 0,e)}};var V=class{constructor(e,t,i){this.client=e;this.collection=t;this.id=i;}async get(){return new A(this.client,this.collection,this.id).get()}async set(e){await this.client.send("write",{collection:this.collection,docId:this.id,data:e,merge:false});}async update(e){await this.client.send("write",{collection:this.collection,docId:this.id,data:e,merge:true});}async delete(){await this.client.send("delete",{collection:this.collection,docId:this.id});}onSnapshot(e){let t=core.uuid2(18),i=()=>{};return i=this.client.subscribe(t,this.collection,this.id,void 0,r=>{r.type==="snapshot"&&(e(r),i());}),i}onDocUpdated(e){let t=core.uuid2(18);return this.client.subscribe(t,this.collection,this.id,void 0,i=>{i.type==="change"&&(i.operation==="update"||i.operation==="replace")&&i.data&&e(i.data,i.docId);},{skipSnapshot:true})}onDocDeleted(e){let t=core.uuid2(18);return this.client.subscribe(t,this.collection,this.id,void 0,i=>{i.type==="change"&&i.operation==="delete"&&e(i.docId);},{skipSnapshot:true})}onDocChanged(e){let t=core.uuid2(18);return this.client.subscribe(t,this.collection,this.id,void 0,i=>{i.type==="change"&&e(i.data??null,i.docId,i.operation);},{skipSnapshot:true})}},B=V;var z=class a{constructor(e,t){this.client=e;this.collection=t;return new Proxy(this,{get:(i,r,n)=>{if(typeof r=="string"&&!(r in i)&&this.client.hasQueryPreset(r))return (o={})=>i.with(r,o);let s=Reflect.get(i,r,n);return typeof s=="function"?s.bind(i):s}})}sq={};promise;doc(e){return new B(this.client,this.collection,e)}clone(e){let t=new a(this.client,this.collection);return t.sq={...this.sq,...e},t}normalizeFilterValue(e,t){return e==="in"||e==="not-in"||e==="array-contains-any"?Array.isArray(t)?t:[t]:t}normalizeFilter(e){return {...e,value:this.normalizeFilterValue(e.op,e.value)}}toQueryFilters(e){return j(e).map(t=>this.normalizeFilter(t))}appendOperatorFilter(e,t,i,r){return this.appendFilters([this.normalizeFilter({field:e,op:t,value:i})],r)}appendAndFilters(e){return this.clone({where:[...this.sq.where??[],...e]})}toOrNode(e){return {or:e}}toAndNode(e){return {and:e}}isLeafFilter(e){return !("or"in e)&&!("and"in e)}isIdentityGuard(e){return this.isLeafFilter(e)?(e.field==="id"||e.field==="_id")&&e.op==="==":false}splitIdentityGuards(e){let t=[],i=[];for(let r of e){if(this.isIdentityGuard(r)){t.push(r);continue}i.push(r);}return {guards:t,rest:i}}appendOrFilters(e){let t=[...this.sq.where??[]];if(t.length===0)return this.clone({where:[this.toOrNode(e)]});let i=t[0];if(t.length===1&&typeof i=="object"&&i!=null&&"or"in i){let c=i;return this.clone({where:[{or:[...c.or,...e]}]})}let{guards:n,rest:s}=this.splitIdentityGuards(t);if(n.length>0){let c=s.length===0?void 0:s.length===1?s[0]:{and:s},l=c?[{or:[c,...e]}]:[{or:[...e]}];return this.clone({where:[...n,...l]})}let o=t.length===1?t[0]:{and:t};return this.clone({where:[{or:[o,...e]}]})}appendFilters(e,t){return t==="or"?this.appendOrFilters(e):this.appendAndFilters(e)}with(e,t={}){return this.client.applyQueryPreset(this,e,t)}where(e){return this.appendFilters(this.toQueryFilters(e),"and")}and(e){return this.appendFilters(this.toQueryFilters(e),"and")}or(e){return this.appendFilters(this.toQueryFilters(e),"or")}in(e,t){return this.appendOperatorFilter(e,"in",t,"and")}andIn(e,t){return this.appendOperatorFilter(e,"in",t,"and")}orIn(e,t){return this.appendOperatorFilter(e,"in",t,"or")}notIn(e,t){return this.appendOperatorFilter(e,"not-in",t,"and")}andNotIn(e,t){return this.appendOperatorFilter(e,"not-in",t,"and")}orNotIn(e,t){return this.appendOperatorFilter(e,"not-in",t,"or")}arrayContains(e,t){return this.appendOperatorFilter(e,"array-contains",t,"and")}andArrayContains(e,t){return this.appendOperatorFilter(e,"array-contains",t,"and")}orArrayContains(e,t){return this.appendOperatorFilter(e,"array-contains",t,"or")}arrayContainsAny(e,t){return this.appendOperatorFilter(e,"array-contains-any",t,"and")}andArrayContainsAny(e,t){return this.appendOperatorFilter(e,"array-contains-any",t,"and")}orArrayContainsAny(e,t){return this.appendOperatorFilter(e,"array-contains-any",t,"or")}some(e,t){return this.appendOperatorFilter(e,"elem-match",t,"and")}andSome(e,t){return this.appendOperatorFilter(e,"elem-match",t,"and")}orSome(e,t){return this.appendOperatorFilter(e,"elem-match",t,"or")}like(e,t){return this.appendOperatorFilter(e,"like",t,"and")}andLike(e,t){return this.appendOperatorFilter(e,"like",t,"and")}orLike(e,t){return this.appendOperatorFilter(e,"like",t,"or")}notLike(e,t){return this.appendOperatorFilter(e,"not-like",t,"and")}andNotLike(e,t){return this.appendOperatorFilter(e,"not-like",t,"and")}orNotLike(e,t){return this.appendOperatorFilter(e,"not-like",t,"or")}exists(e){return this.appendOperatorFilter(e,"exists",true,"and")}andExists(e){return this.appendOperatorFilter(e,"exists",true,"and")}orExists(e){return this.appendOperatorFilter(e,"exists",true,"or")}notExists(e){return this.appendOperatorFilter(e,"not-exists",true,"and")}andNotExists(e){return this.appendOperatorFilter(e,"not-exists",true,"and")}orNotExists(e){return this.appendOperatorFilter(e,"not-exists",true,"or")}latest(){return this.clone({orderBy:[...this.sq.orderBy??[],{field:"_seq",dir:"desc"}]})}newest(){return this.clone({orderBy:[...this.sq.orderBy??[],{field:"_seq",dir:"desc"}]})}oldest(){return this.clone({orderBy:[...this.sq.orderBy??[],{field:"_seq",dir:"asc"}]})}orderBy(e,t="asc"){return this.clone({orderBy:[...this.sq.orderBy??[],{field:e,dir:t}]})}limit(e){return this.clone({limit:e})}offset(e){return this.clone({offset:e})}startAt(...e){return this.clone({startAt:{values:e}})}startAfter(...e){return this.clone({startAfter:{values:e}})}endAt(...e){return this.clone({endAt:{values:e}})}endBefore(...e){return this.clone({endBefore:{values:e}})}aggregate(...e){return this.clone({aggregate:[...this.sq.aggregate??[],...e]})}count(e="count"){return this.aggregate({fn:"count",alias:e})}sum(e,t){return this.aggregate({fn:"sum",field:e,alias:t??`sum_${e}`})}avg(e,t){return this.aggregate({fn:"avg",field:e,alias:t??`avg_${e}`})}min(e,t){return this.aggregate({fn:"min",field:e,alias:t??`min_${e}`})}max(e,t){return this.aggregate({fn:"max",field:e,alias:t??`max_${e}`})}distinct(e,t){return this.aggregate({fn:"distinct",field:e,alias:t??`distinct_${e}`})}groupBy(...e){return this.clone({groupBy:{fields:e}})}having(e,t,i){return this.clone({having:[...this.sq.having??[],{field:e,op:t,value:i}]})}buildStructuredJoin(e,t){let r={from:String(e??""),localField:String(t?.source??""),foreignField:String(t?.target??""),as:String(t?.as??""),single:t?.single};return Array.isArray(t?.where)&&(r.where=t.where),Array.isArray(t?.orderBy)&&(r.orderBy=t.orderBy),typeof t?.limit=="number"&&(r.limit=t.limit),typeof t?.offset=="number"&&(r.offset=t.offset),t?.startAt&&(r.startAt=t.startAt),t?.startAfter&&(r.startAfter=t.startAfter),t?.endAt&&(r.endAt=t.endAt),t?.endBefore&&(r.endBefore=t.endBefore),Array.isArray(t?.aggregate)&&(r.aggregate=t.aggregate),t?.groupBy&&(r.groupBy=t.groupBy),Array.isArray(t?.having)&&(r.having=t.having),t?.vectorSearch&&(r.vectorSearch=t.vectorSearch),Array.isArray(t?.select)&&(r.select=t.select),typeof t?.distinctField=="string"&&(r.distinctField=t.distinctField),Array.isArray(t?.joins)&&(r.joins=t.joins.map(n=>this.buildStructuredJoin(String(n?.collection??""),n))),r}cloneStructuredJoin(e){let t={...e};return Array.isArray(e.where)&&(t.where=e.where.map(i=>({...i}))),Array.isArray(e.orderBy)&&(t.orderBy=e.orderBy.map(i=>({...i}))),Array.isArray(e.aggregate)&&(t.aggregate=e.aggregate.map(i=>({...i}))),Array.isArray(e.having)&&(t.having=e.having.map(i=>({...i}))),Array.isArray(e.select)&&(t.select=[...e.select]),e.groupBy?.fields&&(t.groupBy={fields:[...e.groupBy.fields]}),e.startAt?.values&&(t.startAt={values:[...e.startAt.values]}),e.startAfter?.values&&(t.startAfter={values:[...e.startAfter.values]}),e.endAt?.values&&(t.endAt={values:[...e.endAt.values]}),e.endBefore?.values&&(t.endBefore={values:[...e.endBefore.values]}),Array.isArray(e.joins)&&(t.joins=e.joins.map(i=>this.cloneStructuredJoin(i))),t}appendNestedJoinByAlias(e,t,i){for(let r of e){if(r.as===t)return r.joins=[...r.joins??[],i],true;if(Array.isArray(r.joins)&&this.appendNestedJoinByAlias(r.joins,t,i))return true}return false}parseRelationRef(e){let i=String(e??"").trim().match(/^([A-Za-z0-9_.]+)\s*->\s*([A-Za-z0-9_]+)\.([A-Za-z0-9_.]+)(?:\s+as\s+([A-Za-z0-9_]+))?$/i);if(!i)throw new Error(`Invalid relation format: "${e}". Expected "source.path->collection.target"`);return {source:i[1],collection:i[2],target:i[3],alias:i[4]}}join(e,t){let i=this.buildStructuredJoin(e,t);return this.clone({joins:[...this.sq.joins??[],i]})}joinNested(e,t,i){let r=String(e??"").trim();if(!r)throw new Error("joinNested requires parentAlias");let n=(this.sq.joins??[]).map(o=>this.cloneStructuredJoin(o));if(n.length===0)throw new Error(`joinNested parent alias "${r}" not found`);let s=this.buildStructuredJoin(t,i);if(!this.appendNestedJoinByAlias(n,r,s))throw new Error(`joinNested parent alias "${r}" not found`);return this.clone({joins:n})}Join(e,t){return this.join(e,t)}JoinNested(e,t,i){return this.joinNested(e,t,i)}withRelation(e,t={}){let i=this.parseRelationRef(e);return this.join(i.collection,{...t,source:i.source,target:i.target,as:t.as??i.alias??i.collection})}select(...e){return this.clone({select:e})}distinctField(e){return this.clone({distinctField:e})}vectorSearch(e){return this.clone({vectorSearch:e})}getRawQuery(){let e={...this.sq};return Array.isArray(this.sq.where)&&(e.where=this.sq.where.map(t=>({...t}))),Array.isArray(this.sq.orderBy)&&(e.orderBy=this.sq.orderBy.map(t=>({...t}))),Array.isArray(this.sq.aggregate)&&(e.aggregate=this.sq.aggregate.map(t=>({...t}))),Array.isArray(this.sq.having)&&(e.having=this.sq.having.map(t=>({...t}))),Array.isArray(this.sq.select)&&(e.select=[...this.sq.select]),Array.isArray(this.sq.joins)&&(e.joins=this.sq.joins.map(t=>this.cloneStructuredJoin(t))),this.sq.groupBy?.fields&&(e.groupBy={fields:[...this.sq.groupBy.fields]}),this.sq.startAt?.values&&(e.startAt={values:[...this.sq.startAt.values]}),this.sq.startAfter?.values&&(e.startAfter={values:[...this.sq.startAfter.values]}),this.sq.endAt?.values&&(e.endAt={values:[...this.sq.endAt.values]}),this.sq.endBefore?.values&&(e.endBefore={values:[...this.sq.endBefore.values]}),{collection:this.collection,query:e}}async get(){return this._execute()}async first(){let e=await this._execute();return e.length>0?e[0]:null}async last(){let e=await this._execute();return e.length>0?e[e.length-1]:null}_isStructured(){return !!(this.sq.orderBy?.length||this.sq.aggregate?.length||this.sq.groupBy||this.sq.having?.length||this.sq.joins?.length||this.sq.vectorSearch||this.sq.distinctField||this.sq.offset||this.sq.startAt||this.sq.startAfter||this.sq.endAt||this.sq.endBefore||this.sq.select?.length)}async _execute(){return this._isStructured()?this._executeQuery():this._executeSubscribe()}async _executeQuery(){return this.client.query(this.collection,this.sq)}async _executeSubscribe(){let e=core.uuid2(18);return new Promise((t,i)=>{let r=Object.keys(this.sq).length>0?this.sq:void 0,n=this.client.subscribe(e,this.collection,void 0,r,s=>{s.type==="snapshot"&&(n(),t(s.data));});setTimeout(()=>{n(),i(new Error("Collection fetch timeout"));},1e4);})}then(e,t){return this.promise||(this.promise=this._execute()),this.promise.then(e,t)}onSnapshot(e){let t=core.uuid2(18),i=Object.keys(this.sq).length>0?this.sq:void 0,r=(()=>{});return r=this.client.subscribe(t,this.collection,void 0,i,n=>{n.type==="snapshot"&&(e(n),r());}),r}stream(e={}){let t=core.uuid2(18),i=Object.keys(this.sq).length>0?this.sq:void 0,r=new Set,n=[],s=new Map,o=Math.max(0,Number(e.flushMs??24)),c=Math.max(1,Number(e.maxBatchSize??200)),l=e.insertAt??"end",g=typeof e.maxDocs=="number"&&e.maxDocs>0?Math.floor(e.maxDocs):void 0,y=String(e.idField??"id"),u=[],C=false,S=false,E=0,w,v=()=>{s.clear();for(let p=0;p<u.length;p+=1){let m=W(u[p]);m&&s.set(m,p);}},W=(p,m)=>{if(m)return m;if(p==null)return;if(typeof e.getId=="function"){let I=e.getId(p);if(typeof I=="string"&&I.length>0)return I}let P=p?.[y]??p?._id??p?.docId;if(typeof P=="string"&&P.length>0)return P},F=()=>{g==null||u.length<=g||(u=u.slice(0,g));},x=()=>{typeof e.sort=="function"&&(u=u.slice().sort(e.sort));},M=(p,m)=>{E+=1;let P=u.slice(),I={reason:p,batchSize:m,version:E,ready:S};for(let _ of Array.from(r))try{_(P,I);}catch{}},T=()=>{w!=null&&(clearTimeout(w),w=void 0);},f=p=>{if(p.operation==="delete"){let _=s.get(p.docId);if(_==null)return;u.splice(_,1),v();return}let m=p.data;if(m==null)return;let P=W(m,p.docId);if(!P)return;let I=s.get(P);if(typeof I=="number"){u[I]=m;return}l==="start"?u.unshift(m):u.push(m),F(),v();},O=()=>{if(C||n.length===0)return;T();let p=n.splice(0,n.length);for(let m of p)f(m);x(),v(),M("change-batch",p.length);},$=()=>{C||w!=null||(w=setTimeout(O,o));},K=this.client.subscribe(t,this.collection,void 0,i,p=>{if(!C){if(p.type==="snapshot"){u=Array.isArray(p.data)?[...p.data]:[],S=true,T(),n.length=0,x(),F(),v(),M("snapshot",0);return}if(n.push(p),n.length>=c){O();return}$();}}),J={subscribe(p,m=true){if(r.add(p),m){let P={reason:S?"change-batch":"snapshot",batchSize:0,version:E,ready:S};try{p(u.slice(),P);}catch{}}return ()=>{r.delete(p);}},getSnapshot(){return u.slice()},isReady(){return S},getVersion(){return E},close:()=>{C||(C=true,T(),n.length=0,r.clear(),K());},onError(p){return K.onError(p),J},onPermissionDenied(p){return K.onPermissionDenied(p),J}};return J}asStore(e={}){let t=this.stream(e);return {subscribe:i=>t.subscribe(()=>{i();},false),getSnapshot:()=>t.getSnapshot(),getServerSnapshot:()=>[],stream:t,destroy:()=>{t.close();}}}onDocAdded(e){let t=core.uuid2(18),i=Object.keys(this.sq).length>0?this.sq:void 0;return this.client.subscribe(t,this.collection,void 0,i,r=>{r.type==="change"&&r.operation==="insert"&&r.data!=null&&e(r.data,r.docId);},{skipSnapshot:true})}onDocUpdated(e){let t=core.uuid2(18),i=Object.keys(this.sq).length>0?this.sq:void 0;return this.client.subscribe(t,this.collection,void 0,i,r=>{r.type==="change"&&(r.operation==="update"||r.operation==="replace")&&r.data!=null&&e(r.data,r.docId);},{skipSnapshot:true})}onDocDeleted(e){let t=core.uuid2(18),i=Object.keys(this.sq).length>0?this.sq:void 0;return this.client.subscribe(t,this.collection,void 0,i,r=>{r.type==="change"&&r.operation==="delete"&&e(r.docId);},{skipSnapshot:true})}onDocChanged(e){let t=core.uuid2(18),i=Object.keys(this.sq).length>0?this.sq:void 0;return this.client.subscribe(t,this.collection,void 0,i,r=>{r.type==="change"&&e(r.data??null,r.docId,r.operation);},{skipSnapshot:true})}async add(e){let t=core.uuid2(18),i=this.doc(t);return await i.set(e),i}update(e){return new A(this.client,this.collection).update(e)}delete(){return new A(this.client,this.collection).delete()}},G=z;async function ue(a){let e=a.replace(/-----BEGIN PUBLIC KEY-----/,"").replace(/-----END PUBLIC KEY-----/,"").replace(/\s+/g,""),t=typeof atob<"u"?atob(e):Buffer.from(e,"base64").toString("binary"),i=new Uint8Array(t.length);for(let n=0;n<t.length;n++)i[n]=t.charCodeAt(n);return (globalThis.crypto??(await import('crypto')).webcrypto).subtle.importKey("spki",i.buffer,{name:"RSA-OAEP",hash:"SHA-256"},false,["encrypt"])}async function de(a,e){let t=await ue(e),i=new TextEncoder().encode(JSON.stringify(a)),n=await(globalThis.crypto??(await import('crypto')).webcrypto).subtle.encrypt({name:"RSA-OAEP"},t,i),s=typeof btoa<"u"?btoa(String.fromCharCode(...new Uint8Array(n))):Buffer.from(n).toString("base64");return JSON.stringify({enc:"rsa",data:s})}var D=class{socket=null;reconnectInterval;maxReconnectDelay;isConnected=false;shouldReconnect=true;options;messageQueue=[];heartbeatInterval=null;connectionTimeout=null;constructor(e){this.options=e,this.reconnectInterval=e.reconnectDelay||2,this.maxReconnectDelay=e.maxReconnectDelay||60,this.log("Transport initialized",e.url);}connect(){if(this.socket){this.log("Socket already exists, skipping connection");return}this.log("Connecting to",this.options.url),this.socket=new WebSocket(this.options.url),this.connectionTimeout=setTimeout(()=>{this.isConnected||(this.log("Connection timeout"),this.socket?.close(),this.handleReconnect());},1e4),this.socket.onopen=()=>{this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.isConnected=true,this.reconnectInterval=this.options.reconnectDelay||2,this.log("Connected to server"),this.options.onOpen?.(),this.startHeartbeat(),this.flushQueue();},this.socket.onmessage=e=>{try{let t=JSON.parse(e.data);this.options.onMessage(t);}catch(t){this.log("Parse error",t),this.options.onError?.(t);}},this.socket.onerror=e=>{this.log("WebSocket error",e),this.options.onError?.(new Error("WebSocket error"));},this.socket.onclose=e=>{this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.isConnected=false,this.socket=null,this.stopHeartbeat(),this.log("Connection closed",e.code,e.reason),this.options.onClose?.(),e.code!==1e3&&this.shouldReconnect&&this.options.autoReconnect&&this.handleReconnect();};}handleReconnect(){let e=this.reconnectInterval*1e3;this.log(`Reconnecting in ${this.reconnectInterval}s...`),setTimeout(()=>{this.reconnectInterval=Math.min(this.reconnectInterval*2,this.maxReconnectDelay),this.connect();},e);}startHeartbeat(){this.heartbeatInterval=setInterval(()=>{this.isConnected&&this.send({type:"ping",id:Date.now().toString(),ts:Date.now()});},3e4);}stopHeartbeat(){this.heartbeatInterval&&(clearInterval(this.heartbeatInterval),this.heartbeatInterval=null);}flushQueue(){for(this.log("Flushing message queue",this.messageQueue.length);this.messageQueue.length>0;){let e=this.messageQueue.shift();e&&this.send(e);}}send(e){if(this.socket&&this.socket.readyState===WebSocket.OPEN){let t=i=>{try{this.socket.send(i),this.log("Sent message",e);}catch(r){this.log("Send error",r),this.messageQueue.push(e);}};this.options.publicKey?de(e,this.options.publicKey).then(t).catch(i=>{this.log("RSA encrypt error \u2014 sending plaintext",i),t(JSON.stringify(e));}):t(JSON.stringify(e));}else this.log("Socket not ready, queueing message"),this.messageQueue.push(e);}disconnect(){this.shouldReconnect=false,this.stopHeartbeat(),this.socket&&(this.socket.close(1e3,"Client disconnect"),this.socket=null),this.isConnected=false,this.log("Disconnected");}get connected(){return this.isConnected}log(...e){this.options.debug&&console.log("[FlareTransport]",...e);}};var ye={id:"_id",createdAt:"_createdAt",updatedAt:"_updatedAt"},te={_id:"id",_createdAt:"createdAt",_updatedAt:"updatedAt"},H=class{transport;config;pendingAcks=new Map;subscriptions=new Map;activeSubscriptions=new Map;queryPresets=new Map;subscriptionErrorHandlers=new Map;subscriptionPermissionHandlers=new Map;subscriptionLastErrors=new Map;offlineQueue=[];currentState="disconnected";connectionListeners=[];errorListeners=[];isDebug=false;socketAuthUid="anon";pendingSubscriptionReplay=false;subscriptionReplayPromise=Promise.resolve();requestTraceSeq=0;requestTimingEnabled=true;httpInFlight=new Map;httpResponseCache=new Map;maxHttpCacheEntries=200;presenceCallbacks=new Map;presenceJoinCbs=new Map;presenceLeaveCbs=new Map;presenceHeartbeatTimer;embedder;vectorSchema=new Map;throwFetchFlareError(e,t,i){let r=e,n=typeof r?.error=="string"&&r.error.length>0?r.error:i,s=typeof r?.message=="string"&&r.message.length>0?r.message:t;throw new h(s,n,e)}nowMs(){return typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now()}normalizeHeaders(e){if(!e)return {};let t={};if(e instanceof Headers)e.forEach((i,r)=>{t[r]=i;});else if(Array.isArray(e))for(let[i,r]of e)t[String(i)]=String(r);else for(let[i,r]of Object.entries(e))t[String(i)]=String(r);return t}redactHeaders(e){let t={...e};for(let i of Object.keys(t)){let r=i.toLowerCase();(r==="authorization"||r==="x-flare-csrf"||r==="x-csrf-token")&&(t[i]="[redacted]");}return t}stableStringify(e){if(e==null)return "";if(typeof e=="string")return e;if(typeof URLSearchParams<"u"&&e instanceof URLSearchParams)return e.toString();if(typeof e!="object")return String(e);if(Array.isArray(e))return `[${e.map(r=>this.stableStringify(r)).join(",")}]`;let t=e;return `{${Object.keys(t).sort().map(r=>`${r}:${this.stableStringify(t[r])}`).join(",")}}`}buildHttpCacheKey(e,t,i,r,n){let o=Object.entries(i).map(([l,g])=>[l.toLowerCase(),g]).sort(([l],[g])=>l.localeCompare(g)).map(([l,g])=>`${l}:${g}`).join("|"),c=this.stableStringify(r);return `${e}|${t}|${n??""}|${o}|${c}`}shouldCacheResponse(e,t){return !!(e==="GET"||e==="POST"&&/\/auth\/refresh(?:\?|$)/.test(t))}rememberHttpResponse(e,t){if(this.httpResponseCache.set(e,t),this.httpResponseCache.size<=this.maxHttpCacheEntries)return;let i=this.httpResponseCache.keys().next().value;i&&this.httpResponseCache.delete(i);}createTimedFetchTrace(e,t,i,r,n,s){return {response:{status:e.status,ok:e.status>=200&&e.status<300,headers:{get:o=>{let c=o.toLowerCase();for(let[l,g]of Object.entries(e.headers))if(l.toLowerCase()===c)return String(g);return null}},json:async()=>e.data??{}},requestId:t,startedAtMs:i,networkMs:s,method:r,url:n}}logHttpTiming(...e){this.requestTimingEnabled&&this.log("[FlareClient][http]",...e);}mergeHeaders(e,t){if(!e)return t;if(e instanceof Headers){let i=new Headers(e);for(let[r,n]of Object.entries(t))i.set(r,n);return i}return Array.isArray(e)?[...e,...Object.entries(t)]:{...e,...t}}toWireField(e){let t=String(e??"").trim();return t&&(ye[t]??t)}fromWireField(e){let t=String(e??"").trim();return t&&(te[t]?te[t]:t.startsWith("_")&&!t.startsWith("__")&&t.length>1?t.slice(1):t)}normalizeOutboundData(e){if(Array.isArray(e))return e.map(r=>this.normalizeOutboundData(r));if(!e||typeof e!="object")return e;let t=e,i={};for(let[r,n]of Object.entries(t))i[this.toWireField(r)]=this.normalizeOutboundData(n);return i}normalizeInboundData(e){if(Array.isArray(e))return e.map(r=>this.normalizeInboundData(r));if(!e||typeof e!="object")return e;let t=e,i={};for(let[r,n]of Object.entries(t))i[this.fromWireField(r)]=this.normalizeInboundData(n);return i}getDataMapper(e){let t=this.config.dataMapper;if(!t||typeof t!="object")return null;let i=t[e];return typeof i=="function"?i:null}runMapper(e,t){let i=this.getDataMapper(e);if(!i||t==null||typeof t!="object")return t;try{return i(t)}catch(r){return this.log(`dataMapper for "${e}" failed`,r),t}}applyJoinAliasMappers(e,t){if(!e||typeof e!="object"||!Array.isArray(t)||t.length===0)return e;let i=e;for(let r of t){let n=String(r?.as??"").trim();if(!n)continue;let s=Array.isArray(r?.joins)?r.joins:[],o=i[n],c=o;Array.isArray(o)?c=o.map(l=>this.applyJoinAliasMappers(l,s)):o&&typeof o=="object"&&(c=this.applyJoinAliasMappers(o,s)),c=Array.isArray(c)?c.map(l=>this.runMapper(n,l)):this.runMapper(n,c),c!==o&&(i===e&&(i={...i}),i[n]=c);}return i}mapInboundResult(e,t,i){let r=Array.isArray(i?.joins)?i.joins:[],n=s=>{let o=this.applyJoinAliasMappers(s,r);return this.runMapper(e,o)};return Array.isArray(t)?t.map(s=>n(s)):n(t)}normalizeOutboundAnyFilter(e){return Array.isArray(e.or)?{...e,or:e.or.map(t=>this.normalizeOutboundAnyFilter(t))}:Array.isArray(e.and)?{...e,and:e.and.map(t=>this.normalizeOutboundAnyFilter(t))}:typeof e.field=="string"?{...e,field:this.toWireField(e.field)}:{...e}}normalizeOutboundQuery(e){if(!e||typeof e!="object")return e;let t=e,i={...t},r=n=>{let s={...n};return s.localField=this.toWireField(String(n?.localField??"")),s.foreignField=this.toWireField(String(n?.foreignField??"")),Array.isArray(n.where)&&(s.where=n.where.map(o=>this.normalizeOutboundAnyFilter(o))),Array.isArray(n.orderBy)&&(s.orderBy=n.orderBy.map(o=>({...o,field:this.toWireField(String(o?.field??""))}))),n.groupBy&&typeof n.groupBy=="object"&&Array.isArray(n.groupBy.fields)&&(s.groupBy={...n.groupBy,fields:n.groupBy.fields.map(o=>this.toWireField(String(o??"")))}),Array.isArray(n.having)&&(s.having=n.having.map(o=>({...o,field:this.toWireField(String(o?.field??""))}))),Array.isArray(n.select)&&(s.select=n.select.map(o=>this.toWireField(String(o??"")))),typeof n.distinctField=="string"&&(s.distinctField=this.toWireField(n.distinctField)),n.vectorSearch&&typeof n.vectorSearch=="object"&&(s.vectorSearch={...n.vectorSearch,field:this.toWireField(String(n.vectorSearch.field??""))}),Array.isArray(n.joins)&&(s.joins=n.joins.map(o=>r(o))),s};return Array.isArray(t.where)&&(i.where=t.where.map(n=>this.normalizeOutboundAnyFilter(n))),Array.isArray(t.orderBy)&&(i.orderBy=t.orderBy.map(n=>({...n,field:this.toWireField(String(n?.field??""))}))),t.groupBy&&typeof t.groupBy=="object"&&Array.isArray(t.groupBy.fields)&&(i.groupBy={...t.groupBy,fields:t.groupBy.fields.map(n=>this.toWireField(String(n??"")))}),Array.isArray(t.having)&&(i.having=t.having.map(n=>({...n,field:this.toWireField(String(n?.field??""))}))),Array.isArray(t.select)&&(i.select=t.select.map(n=>this.toWireField(String(n??"")))),typeof t.distinctField=="string"&&(i.distinctField=this.toWireField(t.distinctField)),t.vectorSearch&&typeof t.vectorSearch=="object"&&(i.vectorSearch={...t.vectorSearch,field:this.toWireField(String(t.vectorSearch.field??""))}),Array.isArray(t.joins)&&(i.joins=t.joins.map(n=>r(n))),i}async timedFetch(e,t,i){let r=++this.requestTraceSeq,n=this.nowMs(),s=String(i?.method??"GET").toUpperCase(),o=this.normalizeHeaders(i?.headers),c=this.redactHeaders(o),l=i?.body,g=this.buildHttpCacheKey(s,t,o,l,i?.credentials),y=this.shouldCacheResponse(s,t);this.logHttpTiming(`#${r} ${e} start`,{method:s,url:t,headers:c,hasBody:!!i?.body});try{if(y){let T=this.httpResponseCache.get(g);if(T)return this.logHttpTiming(`#${r} ${e} cache-hit`,{method:s,url:t}),this.createTimedFetchTrace(T,r,n,s,t,0)}let u=this.httpInFlight.get(g);if(u){let T=await u,f=this.nowMs()-n;return this.logHttpTiming(`#${r} ${e} deduped`,{method:s,url:t,networkMs:Number(f.toFixed(2))}),this.createTimedFetchTrace(T,r,n,s,t,f)}let C=this.mergeHeaders(i?.headers,{"x-flare-request-id":String(r)}),S=this.normalizeHeaders(C),E=this.redactHeaders(S),w={timeout:Math.ceil((this.config.connectionTimeout??1e4)/1e3),ignoreKind:!0,headers:S,withCredentials:i?.credentials==="include",returnRawResponse:!0,appendCookiesToBody:!1,appendTimestamp:!1};this.logHttpTiming(`#${r} ${e} request`,{method:s,url:t,headers:E,hasBody:!!i?.body});let v=s.toUpperCase(),F=(async()=>{let T=v==="GET"?await core.withGet(t,w):v==="PUT"?await core.withPut(t,l,w):v==="PATCH"?await core.withPatch(t,l,w):await core.withPost(t,l,w),f={status:Number(T?.status??0),headers:Object.fromEntries(Object.entries(T?.headers??{}).map(([O,$])=>[O,String($)])),data:T?.data??{}};return y&&this.rememberHttpResponse(g,f),f})();this.httpInFlight.set(g,F);let x=await F.finally(()=>{this.httpInFlight.delete(g);}),M=this.nowMs()-n;return this.logHttpTiming(`#${r} ${e} response`,{status:x.status,networkMs:Number(M.toFixed(2))}),this.createTimedFetchTrace(x,r,n,s,t,M)}catch(u){let C=this.nowMs()-n;throw this.logHttpTiming(`#${r} ${e} failed`,{networkMs:Number(C.toFixed(2)),message:u?.message??String(u)}),u}}async parseJsonWithTiming(e,t){let i=this.nowMs(),r=await t.response.json().catch(()=>({})),n=this.nowMs()-i,s=this.nowMs()-t.startedAtMs;return this.logHttpTiming(`#${t.requestId} ${e} complete`,{method:t.method,url:t.url,status:t.response.status,networkMs:Number(t.networkMs.toFixed(2)),parseMs:Number(n.toFixed(2)),totalMs:Number(s.toFixed(2))}),r}getHttpBase(){if(this.config.httpBase)return this.config.httpBase.replace(/\/$/,"");let e=new URL(this.config.endpoint);return `${e.protocol}//${e.host}`}log(...e){this.isDebug&&console.log("[FlareClient]",...e);}constructor(e){this.config={autoReconnect:true,reconnectDelay:2,maxReconnectDelay:60,debug:false,connectionTimeout:1e4,...e},this.isDebug=this.config.debug||false,this.requestTimingEnabled=this.config.requestTiming??true;let{hostname:t,port:i,protocol:r}=new URL(this.config.endpoint),n=r==="https:",c=`${n?"wss":"ws"}://${t}:${i||(n?"443":"80")}/?appId=${this.config.appId}${this.config.apiKey?`&apiKey=${this.config.apiKey}`:""}`;this.transport=new D({url:c,publicKey:this.config.publicKey,autoReconnect:this.config.autoReconnect,reconnectDelay:this.config.reconnectDelay,maxReconnectDelay:this.config.maxReconnectDelay,onMessage:l=>this.handleIncoming(l),onOpen:()=>this.onConnected(),onClose:()=>this.onDisconnected(),onError:l=>this.handleTransportError(l),debug:this.isDebug});}connect(){this.setState("connecting"),this.transport.connect();}disconnect(){this.transport.disconnect(),this.setState("disconnected");}get connectionState(){return this.currentState}get isConnected(){return this.currentState==="connected"}onConnectionStateChange(e){return this.connectionListeners.push(e),()=>{this.connectionListeners=this.connectionListeners.filter(t=>t!==e);}}onError(e){return this.errorListeners.push(e),()=>{this.errorListeners=this.errorListeners.filter(t=>t!==e);}}collection(e){return new G(this,e)}registerQueryPreset(e,t){let i=String(e??"").trim();if(!i)throw new h("Preset name is required",d.QueryFailed);if(typeof t!="function")throw new h(`Query preset "${i}" handler must be a function`,d.QueryFailed);return this.queryPresets.set(i,t),this}registerQueryPresets(e){for(let[t,i]of Object.entries(e??{}))this.registerQueryPreset(t,i);return this}hasQueryPreset(e){return this.queryPresets.has(String(e??"").trim())}applyQueryPreset(e,t,i={}){let r=String(t??"").trim(),n=this.queryPresets.get(r);if(!n)throw new h(`Unknown query preset "${r}"`,d.QueryFailed);let s=n(e,i??{});if(!s||typeof s.get!="function")throw new h(`Query preset "${r}" must return a CollectionReference`,d.QueryFailed);return s}doc(e,t){return t!==void 0?new B(this,e,t):new A(this,e)}async ping(){let e=Date.now();return await this.send("ping",{}),Date.now()-e}async call(e,t={}){let i=await this.send("call",{topic:e,payload:t});if(!i.success)throw new h(i.error??`CALL "${e}" failed`,d.QueryFailed);return i.result}async query(e,t={}){let i=await this.send("query",{collection:e,query:t});return this.mapInboundResult(e,i.data,t)??[]}setEmbedder(e){this.embedder=e;}markVectorField(e,t,i={dimensions:1536}){this.vectorSchema.has(e)||this.vectorSchema.set(e,new Map),this.vectorSchema.get(e).set(t,i);}async embedVectorFields(e,t){let i=this.vectorSchema.get(e);if(!i)return t;let r={...t};for(let[n,s]of i){let o=r[n];if(typeof o=="string"){let c=s.embed??this.embedder;if(!c){this.log(`[vector] No embedder for field "${n}" \u2014 storing raw text`);continue}r[n]=await c(o);}}return r}async joinPresence(e,t){return await this.send("presence_join",{room:e,meta:t}),this._startPresenceHeartbeat(e,t),()=>this.leavePresence(e)}async leavePresence(e){await this.send("presence_leave",{room:e}),this._stopPresenceHeartbeat();}onPresenceState(e,t){return this.presenceCallbacks.has(e)||this.presenceCallbacks.set(e,[]),this.presenceCallbacks.get(e).push(t),()=>{let i=this.presenceCallbacks.get(e)??[];this.presenceCallbacks.set(e,i.filter(r=>r!==t));}}onPresenceJoin(e,t){return this.presenceJoinCbs.has(e)||this.presenceJoinCbs.set(e,[]),this.presenceJoinCbs.get(e).push(t),()=>{let i=this.presenceJoinCbs.get(e)??[];this.presenceJoinCbs.set(e,i.filter(r=>r!==t));}}onPresenceLeave(e,t){return this.presenceLeaveCbs.has(e)||this.presenceLeaveCbs.set(e,[]),this.presenceLeaveCbs.get(e).push(t),()=>{let i=this.presenceLeaveCbs.get(e)??[];this.presenceLeaveCbs.set(e,i.filter(r=>r!==t));}}_startPresenceHeartbeat(e,t){this.presenceHeartbeatTimer||(this.presenceHeartbeatTimer=setInterval(()=>{this.isConnected&&this.send("presence_heartbeat",{meta:t}).catch(()=>{});},2e4));}_stopPresenceHeartbeat(){this.presenceHeartbeatTimer&&(clearInterval(this.presenceHeartbeatTimer),this.presenceHeartbeatTimer=void 0);}async syncOffline(){if(this.offlineQueue.length===0)return;this.log("Syncing offline operations",this.offlineQueue.length);let e=[...this.offlineQueue];this.offlineQueue.length=0;let t=await this.send("offline_sync",{operations:e});t.conflicts&&t.conflicts.length>0&&(this.log("Offline sync conflicts",t.conflicts),t.conflicts.forEach(i=>{let r=e.find(n=>n.id===i.operationId);r&&this.offlineQueue.push(r);}));}async beforeActivateSubscription(e){}async activateSubscription(e){if(!this.isConnected){this.pendingSubscriptionReplay=true;return}await this.beforeActivateSubscription(e),this.subscriptions.set(e.liveId,e.callback);try{let t=await this.send("subscribe",{collection:e.collection,docId:e.docId,query:e.query,skipSnapshot:e.options.skipSnapshot});if(!this.activeSubscriptions.has(e.baseId)){this.subscriptions.delete(e.liveId);return}t.subscriptionId&&t.subscriptionId!==e.liveId&&(this.subscriptions.delete(e.liveId),e.liveId=t.subscriptionId,this.subscriptions.set(e.liveId,e.callback),this.log("Subscription remapped",e.baseId,"\u2192",e.liveId));}catch(t){this.subscriptions.delete(e.liveId),this.pendingSubscriptionReplay=true;let i=this.toSubscriptionError(t);this.emitSubscriptionError(e.baseId,i),this.log("Subscription failed",t);}}toSubscriptionError(e){let t=e instanceof Error?e.message:String(e??"Unknown subscription error"),i=t.match(/^\[([^\]]+)\]\s*(.*)$/),r=i?.[1],n=(i?.[2]??t).trim()||t,s=r===d.PermissionDenied||t.includes(d.PermissionDenied);return {code:r,message:n,permissionDenied:s,raw:e}}emitSubscriptionError(e,t){this.subscriptionLastErrors.set(e,t);let i=this.subscriptionErrorHandlers.get(e);if(i)for(let r of i)try{r(t);}catch(n){this.log("Subscription error callback failed",n);}if(t.permissionDenied){let r=this.subscriptionPermissionHandlers.get(e);if(r)for(let n of r)try{n(t);}catch(s){this.log("Subscription permission callback failed",s);}}}async replayActiveSubscriptions(){if(!this.isConnected){this.pendingSubscriptionReplay=true;return}let e=Array.from(this.activeSubscriptions.values());if(e.length===0){this.pendingSubscriptionReplay=false;return}this.pendingSubscriptionReplay=false,this.subscriptionReplayPromise=this.subscriptionReplayPromise.then(async()=>{for(let t of e){if(!this.activeSubscriptions.has(t.baseId))continue;let i=t.liveId;this.subscriptions.delete(i),t.liveId=t.baseId,i&&await this.send("unsubscribe",{subscriptionId:i}).catch(()=>{}),await this.activateSubscription(t);}}).catch(t=>{this.pendingSubscriptionReplay=true,this.log("Subscription replay failed",t);}),await this.subscriptionReplayPromise;}subscribe(e,t,i,r,n,s={}){this.log("Creating subscription",e,t,i);let o={baseId:e,liveId:e,collection:t,docId:i,query:r,callback:n,options:s};this.activeSubscriptions.set(e,o),this.subscriptionErrorHandlers.has(e)||this.subscriptionErrorHandlers.set(e,new Set),this.subscriptionPermissionHandlers.has(e)||this.subscriptionPermissionHandlers.set(e,new Set),this.activateSubscription(o).catch(g=>{this.log("Subscription activation failed",g);});let c=()=>{let y=this.activeSubscriptions.get(e)?.liveId??e;this.log("Unsubscribing",y),this.activeSubscriptions.delete(e),this.subscriptions.delete(y),this.subscriptionErrorHandlers.delete(e),this.subscriptionPermissionHandlers.delete(e),this.subscriptionLastErrors.delete(e),this.isConnected&&this.send("unsubscribe",{subscriptionId:y}).catch(u=>this.log("Unsubscribe failed",u));},l=c;return l.unsubscribe=c,l.onError=g=>{this.subscriptionErrorHandlers.get(e)?.add(g);let y=this.subscriptionLastErrors.get(e);if(y)try{g(y);}catch(u){this.log("Subscription error callback failed",u);}return l},l.onPermissionDenied=g=>{this.subscriptionPermissionHandlers.get(e)?.add(g);let y=this.subscriptionLastErrors.get(e);if(y?.permissionDenied)try{g(y);}catch(u){this.log("Subscription permission callback failed",u);}return l},l.catch=g=>l.onError(g),l}async send(e,t){if(e==="write"&&t.collection&&t.data){let i=await this.embedVectorFields(t.collection,t.data);t={...t,data:this.normalizeOutboundData(i)};}return (e==="subscribe"||e==="query")&&t?.query&&(t={...t,query:this.normalizeOutboundQuery(t.query)}),new Promise((i,r)=>{let n=core.uuid2(18),s={id:n,type:e,ts:Date.now(),...t};this.pendingAcks.set(n,o=>{o.type==="error"?r(new Error(`[${o.code}] ${o.message}`)):i(o);}),this.isConnected?this.transport.send(s):(this.log("Queueing message for offline",s),this.offlineQueue.push(s),r(new Error("Not connected - message queued"))),setTimeout(()=>{this.pendingAcks.has(n)&&(this.pendingAcks.delete(n),r(new Error("Request timeout")));},this.config.connectionTimeout);})}handleTransportError(e){this.log("Transport error",e),this.errorListeners.forEach(t=>{try{t(e);}catch(i){this.log("Error listener error",i);}});}onConnected(){this.setState("connected"),this.log("Connected to FlareServer"),this.activeSubscriptions.size>0&&(this.pendingSubscriptionReplay=true),this.offlineQueue.length>0&&this.syncOffline().catch(e=>{this.log("Offline sync failed",e);});}onDisconnected(){this.currentState!=="disconnected"&&this.setState("reconnecting"),this.activeSubscriptions.size>0&&(this.pendingSubscriptionReplay=true),this.log("Disconnected from FlareServer");}setState(e){this.currentState!==e&&(this.currentState=e,this.log("Connection state changed",e),this.connectionListeners.forEach(t=>{try{t(e);}catch(i){this.log("Connection listener error",i);}}));}handleIncoming(e){if(this.log("Received message",e.type,e),e.type==="query_result"&&Array.isArray(e.data)&&(e={...e,data:this.normalizeInboundData(e.data)}),e.type==="ack"||e.type==="pong"||e.type==="auth_ok"||e.type==="call_response"||e.type==="query_result"){let t=this.pendingAcks.get(e.correlationId||e.id);t&&(t(e),this.pendingAcks.delete(e.correlationId||e.id));return}if(e.type==="error"){this.log("Server error",e.code,e.message);let t=new Error(`[${e.code}] ${e.message}`);this.errorListeners.forEach(r=>{try{r(t);}catch(n){this.log("Error listener error",n);}});let i=Array.from(this.activeSubscriptions.values()).find(r=>r.liveId===e.correlationId||r.baseId===e.correlationId);if(i&&this.emitSubscriptionError(i.baseId,{code:typeof e.code=="string"?e.code:void 0,message:String(e.message??"Subscription error"),permissionDenied:e.code===d.PermissionDenied,raw:e}),e.correlationId){let r=this.pendingAcks.get(e.correlationId);r&&(r(e),this.pendingAcks.delete(e.correlationId));}return}if(e.type==="presence_state"){(this.presenceCallbacks.get(e.room)??[]).forEach(i=>{try{i(e.members);}catch{}});return}if(e.type==="presence_join"){(this.presenceJoinCbs.get(e.room)??[]).forEach(i=>{try{i(e);}catch{}});return}if(e.type==="presence_leave"){(this.presenceLeaveCbs.get(e.room)??[]).forEach(i=>{try{i(e.uid);}catch{}});return}if(e.type==="snapshot"){let t=this.subscriptions.get(e.subscriptionId);if(t){let i=Array.from(this.activeSubscriptions.values()).find(o=>o.liveId===e.subscriptionId),r=this.normalizeInboundData(Array.isArray(e.data)?e.data:e.data!=null?[e.data]:[]),n=this.mapInboundResult(String(e.collection??i?.collection??""),r,i?.query),s={type:"snapshot",subscriptionId:e.subscriptionId,collection:e.collection,data:Array.isArray(n)?n:[]};try{t(s);}catch(o){this.log("Subscription callback error",o);}}return}if(e.type==="change"){let t=this.subscriptions.get(e.subscriptionId);if(t){let i=Array.from(this.activeSubscriptions.values()).find(o=>o.liveId===e.subscriptionId),r=e.operation==="delete"?null:this.normalizeInboundData(e.data),n=e.operation==="delete"?null:this.mapInboundResult(String(e.collection??i?.collection??""),r,i?.query),s={type:"change",subscriptionId:e.subscriptionId,collection:e.collection,docId:e.docId,operation:e.operation,data:n};try{t(s);}catch(o){this.log("Subscription callback error",o);}}}}};var q=class a extends H{static AUTH_TRACE_STORAGE_KEY="zuzjs.flare.auth.trace";authToken;userId;authGuard;authConfig;csrfToken;csrfInitPromise;csrfBootstrapAttempted=false;socketAuthSyncPromise;pushServiceWorkerInitPromise;authSession=null;authBootstrapPromise;authBootstrapAttempted=false;authStateListeners=[];authConfigListeners=[];currentProfile=void 0;isAuthTraceEnabled(){let e=globalThis?.__FLARE_AUTH_TRACE__;if(e===true||e===false)return e;if(typeof window<"u")try{let i=window.localStorage.getItem(a.AUTH_TRACE_STORAGE_KEY);if(i==="1"||i==="true")return !0;if(i==="0"||i==="false")return !1}catch{}let t=globalThis?.process?.env?.FLARE_AUTH_TRACE;return t==="1"||t==="true"}setAuthTrace(e,t=true){if(globalThis.__FLARE_AUTH_TRACE__=e,t&&typeof window<"u")try{window.localStorage.setItem(a.AUTH_TRACE_STORAGE_KEY,e?"1":"0");}catch{}}traceAuth(e,t){if(!this.isAuthTraceEnabled()||typeof console>"u")return;let i={event:e,appId:this.config.appId,ts:Date.now(),uid:this.authSession?.uid??this.userId??null,hasAccessToken:!!this.authSession?.accessToken,hasRefreshToken:!!this.authSession?.refreshToken,...t??{}};console.info("[FLARE_AUTH_TRACE]",i);}getDefaultCsrfCookieName(){return `__flare_csrf_${this.config.appId.replace(/[^a-zA-Z0-9_-]/g,"_")}`}getCsrfCookieName(){return this.authConfig?.cookie?.csrfTokenName??this.getDefaultCsrfCookieName()}getCsrfToken(){return this.getCookieValue(this.getCsrfCookieName())??this.csrfToken??null}getCookieValue(e){if(typeof document>"u")return null;let t=document.cookie.split(";").map(r=>r.trim()).find(r=>r.startsWith(`${e}=`)||r.startsWith(`${encodeURIComponent(e)}=`));if(!t)return null;let i=t.indexOf("=");return i>=0?decodeURIComponent(t.slice(i+1)):null}extractCsrfToken(e,t){let i=e,r=typeof i?.csrfToken=="string"?String(i.csrfToken):typeof i?.csrf_token=="string"?String(i.csrf_token):void 0;if(r)return r;if(!t)return;let n=t.headers.get("x-flare-csrf")??t.headers.get("x-csrf-token")??t.headers.get("csrf-token");return typeof n=="string"&&n.length>0?n:void 0}getCsrfHeaders(){let e=this.getCsrfToken();return e?{"x-flare-csrf":e}:{}}setCsrfToken(e){this.csrfToken=e,this.csrfBootstrapAttempted=true,this.log("CSRF token injected",{length:e.length});}async ensureCsrfProtection(){if(this.getCsrfToken()){this.csrfBootstrapAttempted=true;return}if(this.config.httpBase){this.csrfBootstrapAttempted=true;return}this.csrfBootstrapAttempted||(this.csrfInitPromise||(this.csrfBootstrapAttempted=true,this.csrfInitPromise=this.loadAuthConfig().then(()=>{}).finally(()=>{this.csrfInitPromise=void 0;})),await this.csrfInitPromise,this.getCsrfToken()||this.log("CSRF token unavailable after auth config load",{hasAuthConfig:!!this.authConfig,csrfCookieName:this.getCsrfCookieName()}));}async loadAuthConfig(){let e=this.getHttpBase(),t=new URLSearchParams({appId:this.config.appId});this.config.apiKey&&t.set("apiKey",this.config.apiKey);let i=`${e}/auth/config?${t.toString()}`,r=await this.timedFetch("loadAuthConfig",i,{credentials:"include",headers:this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}}),n=await this.parseJsonWithTiming("loadAuthConfig",r);return r.response.ok||this.throwFetchFlareError(n,"Failed to load auth config",d.QueryFailed),this.authConfig=n,this.csrfToken=this.extractCsrfToken(n,r.response)??this.csrfToken,this.authConfigListeners.forEach(s=>{try{s(this.authConfig);}catch(o){this.log("Auth config listener error",o);}}),this.authConfig}async fetchAuthConfig(){return this.authConfig?this.authConfig:this.loadAuthConfig()}onAuthConfigLoaded(e){return this.authConfigListeners.push(e),this.authConfig&&e(this.authConfig),()=>{this.authConfigListeners=this.authConfigListeners.filter(t=>t!==e);}}setProfile(e){this.currentProfile=e;}setAuthSession(e,t="unknown"){let i=this.authSession?.uid??this.userId??null;this.authSession=e,e?(this.authToken=e.accessToken,this.userId=e.uid,this.traceAuth("setAuthSession",{source:t,nextUid:e.uid,previousUid:i,mode:"set"})):(this.traceAuth("setAuthSession",{source:t,nextUid:null,previousUid:i,mode:"clear"}),this.authToken=void 0,this.userId=void 0,this.currentProfile=void 0,this.httpResponseCache.clear(),this.httpInFlight.clear());let r=this.authSession?{...this.authSession,...this.currentProfile??{}}:null;this.authStateListeners.forEach(n=>{try{n(r);}catch(s){this.log("Auth state listener error",s);}});}onAuthStateChanged(e){this.authStateListeners.push(e);let t=()=>{let n=this.authSession?{...this.authSession,...this.currentProfile??{}}:null;try{e(n);}catch(s){this.log("Auth state listener error during initialization",s);}},i=!this.authSession&&!this.authBootstrapAttempted&&typeof window<"u"&&typeof document<"u"&&!!this.config.httpBase,r=!this.authSession&&!!this.authBootstrapPromise;return i?(this.traceAuth("onAuthStateChanged.bootstrap.start",{listenerCount:this.authStateListeners.length}),this.authBootstrapAttempted=true,this.authBootstrapPromise||(this.authBootstrapPromise=this.refreshAuthSession().catch(()=>null).then(()=>{}).finally(()=>{this.authBootstrapPromise=void 0;})),this.authBootstrapPromise.finally(()=>{this.authStateListeners.includes(e)&&(this.traceAuth("onAuthStateChanged.bootstrap.done",{hasSession:!!this.authSession}),this.authSession||t());})):r?(this.traceAuth("onAuthStateChanged.bootstrap.wait",{listenerCount:this.authStateListeners.length}),this.authBootstrapPromise?.finally(()=>{this.authStateListeners.includes(e)&&(this.authSession||t());})):t(),()=>{this.authStateListeners=this.authStateListeners.filter(n=>n!==e);}}onAuthStateChange(e){return this.onAuthStateChanged(e)}get currentUser(){return this.currentProfile}getCurrentUser(){return this.currentUser}async syncSocketAuth(e){if(!this.isConnected)return;let t=await this.send("auth",e?{token:e}:{});if(t.type!=="auth_ok")throw new h("Socket auth sync failed",d.AuthenticationFailed);if(!e||t.uid==="anon"){this.authToken=void 0,this.userId=void 0,await this.updateSocketIdentity("anon");return}this.authToken=typeof t.token=="string"?t.token:e,this.userId=typeof t.uid=="string"?t.uid:this.userId,await this.updateSocketIdentity(typeof t.uid=="string"?t.uid:this.userId);}async updateSocketIdentity(e,t=false){let i=typeof e=="string"&&e.length>0?e:"anon",r=i!==this.socketAuthUid;this.socketAuthUid=i,(r||t||this.pendingSubscriptionReplay)&&this.activeSubscriptions.size>0&&await this.replayActiveSubscriptions();}async beforeActivateSubscription(e){if(!this.isConnected)return;let t=this.authSession;!t?.accessToken||!t.uid||this.socketAuthUid!==t.uid&&(this.socketAuthSyncPromise||(this.socketAuthSyncPromise=this.syncSocketAuth(t.accessToken).catch(i=>{throw this.log("Socket auth sync failed before subscribe",i),i}).finally(()=>{this.socketAuthSyncPromise=void 0;})),await this.socketAuthSyncPromise);}onConnected(){super.onConnected(),this.authSession?.accessToken&&this.syncSocketAuth(this.authSession.accessToken).catch(e=>{this.log("Socket auth sync failed after connect",e);});}handleIncoming(e){if(e.type==="auth_ok"&&!e.correlationId){let t=typeof e.token=="string"?e.token:void 0,i=typeof e.uid=="string"?e.uid:void 0;this.updateSocketIdentity(i,this.pendingSubscriptionReplay).catch(r=>{this.log("Socket identity update failed",r);}),t&&i&&i!=="anon"&&i!=="__admin__"?this.fetchAuthMe(t).then(r=>{this.setAuthSession({uid:i,accessToken:t,refreshToken:this.authSession?.refreshToken??null,email:r?.email??null,emailVerified:r?.email_verified});}).catch(()=>{this.setAuthSession({uid:i,accessToken:t,refreshToken:this.authSession?.refreshToken??null});}):i==="anon"&&this.authSession&&!this.socketAuthSyncPromise&&!this.authBootstrapPromise&&this.setAuthSession(null,"socket.auth_ok.anon");}super.handleIncoming(e);}async auth(e){let t=await this.send("auth",{token:e});if(t.type==="auth_ok"){let i=t.token??e;this.authToken=i,this.userId=t.uid;let r=await this.fetchAuthMe(i).catch(()=>null);return this.setAuthSession({uid:t.uid??t.id,accessToken:i,refreshToken:this.authSession?.refreshToken??null,email:r?.email??null,emailVerified:r?.email_verified}),await this.updateSocketIdentity(t.uid),this.log("Authentication successful",t.uid),{uid:t.uid,token:t.token??e}}throw new h("Authentication failed",d.AuthenticationFailed)}async signInWithEmailAndPassword(e,t,i){try{let r=await this.requestEmailPasswordToken(e,t,i?.scope),n=await this.auth(r.access_token),s=await this.fetchAuthMe(r.access_token).catch(()=>null);return this.setAuthSession({uid:n.uid,accessToken:r.access_token,refreshToken:r.refresh_token,provider:r.provider,email:s?.email??e,emailVerified:s?.email_verified}),this.log("Credentials sign-in successful",n.uid),{...n,kind:r.kind,accessToken:r.access_token,refreshToken:r.refresh_token,authToken:r}}catch(r){let n=/invalid_email|user.not.found|no user/i.test(r?.message??"");if(i?.createIfMissing&&n){let s=await this.createUserWithEmail(e,t,{scope:i.scope,signInIfAllowed:true});if("verificationRequired"in s&&s.verificationRequired)throw new h("Email verification required before sign-in",d.AuthenticationFailed);return {uid:s.uid,token:s.token,accessToken:s.accessToken,refreshToken:s.refreshToken,authToken:s.authToken,created:true}}throw r instanceof h?r:new h(r instanceof Error?r.message:"Sign-in with email/password failed",r.error??r.code??d.AuthenticationFailed,r)}}async signInWithEmail(e,t,i){return this.signInWithEmailAndPassword(e,t,i)}async createUserWithEmail(e,t,i){let r=await this.registerWithEmail(e,t,i);if(r.verification_required)return {kind:r.kind,verificationRequired:true,emailSent:!!r.email_sent,preview:r.preview};let n=String(r.access_token??"");if(!n)throw new h("User created but no access token returned",d.AuthenticationFailed);let s={access_token:n,refresh_token:r.refresh_token?String(r.refresh_token):null,expires_in:r.expires_in?Number(r.expires_in):null,token_type:String(r.token_type??"Bearer"),scope:r.scope?String(r.scope):null,profile:null,provider:"credentials"},o=await this.auth(n),c=await this.fetchAuthMe(n).catch(()=>null);return this.setAuthSession({uid:o.uid,accessToken:n,refreshToken:s.refresh_token,provider:"credentials",email:c?.email??e,emailVerified:c?.email_verified}),{...o,accessToken:n,refreshToken:s.refresh_token,authToken:s,verificationRequired:false,emailSent:!!r.email_sent,preview:r.preview}}async createUserWithEmailAndPassword(e,t,i){return this.createUserWithEmail(e,t,i)}async signInOrCreateWithEmail(e,t,i){try{return {...await this.signInWithEmailAndPassword(e,t,{scope:i?.scope}),created:!1}}catch(r){if(!/invalid_email|user.not.found|no user/i.test(r?.message??""))throw r;let s=await this.createUserWithEmail(e,t,{scope:i?.scope,additionalParams:i?.additionalParams,signInIfAllowed:true});return "verificationRequired"in s&&s.verificationRequired?{...s,created:true}:{...s,created:true}}}async signInOrCreateWithEmailAndPassword(e,t,i){return this.signInOrCreateWithEmail(e,t,i)}async sendEmailVerification(e){let t=this.getHttpBase();await this.ensureCsrfProtection();let i=await this.timedFetch("sendEmailVerification",`${t}/auth/verify/send?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:JSON.stringify({email:e,appId:this.config.appId,apiKey:this.config.apiKey})}),r=await this.parseJsonWithTiming("sendEmailVerification",i);return i.response.ok||this.throwFetchFlareError(r,"Failed to send verification email",d.AuthenticationFailed),r}async verifyEmailWithCode(e,t){let i=this.getHttpBase();await this.ensureCsrfProtection();let r=await this.timedFetch("verifyEmailWithCode",`${i}/auth/verify/confirm?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:JSON.stringify({email:e,code:t,appId:this.config.appId,apiKey:this.config.apiKey})}),n=await this.parseJsonWithTiming("verifyEmailWithCode",r);return r.response.ok||this.throwFetchFlareError(n,"Email verification failed",d.AuthenticationFailed),n}async confirmEmailLink(e,t){let i=this.getHttpBase();await this.ensureCsrfProtection();let r=await this.timedFetch("confirmEmailLink",`${i}/auth/verify/confirm?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:JSON.stringify({token:e,email:t,appId:this.config.appId,apiKey:this.config.apiKey})}),n=await this.parseJsonWithTiming("confirmEmailLink",r);return r.response.ok||this.throwFetchFlareError(n,"Email link verification failed",d.AuthenticationFailed),n}async sendAccountRecovery(e){let t=this.getHttpBase();await this.ensureCsrfProtection();let i=await this.timedFetch("sendAccountRecovery",`${t}/auth/recover/send?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:JSON.stringify({email:e,appId:this.config.appId,apiKey:this.config.apiKey})}),r=await this.parseJsonWithTiming("sendAccountRecovery",i);return i.response.ok||this.throwFetchFlareError(r,"Failed to send recovery email",d.AuthenticationFailed),r}async recoverAccountWithCode(e,t,i){let r=this.getHttpBase();await this.ensureCsrfProtection();let n=await this.timedFetch("recoverAccountWithCode",`${r}/auth/recover/confirm?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:JSON.stringify({email:e,code:t,newPassword:i,appId:this.config.appId,apiKey:this.config.apiKey})}),s=await this.parseJsonWithTiming("recoverAccountWithCode",n);return n.response.ok||this.throwFetchFlareError(s,"Account recovery failed",d.AuthenticationFailed),s}async recoverAccountWithToken(e,t){let i=this.getHttpBase();await this.ensureCsrfProtection();let r=await this.timedFetch("recoverAccountWithToken",`${i}/auth/recover/confirm?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:JSON.stringify({token:e,newPassword:t,appId:this.config.appId,apiKey:this.config.apiKey})}),n=await this.parseJsonWithTiming("recoverAccountWithToken",r);return r.response.ok||this.throwFetchFlareError(n,"Account recovery failed",d.AuthenticationFailed),n}toUint8ArrayFromBase64Url(e){let t=e.replace(/-/g,"+").replace(/_/g,"/"),i="=".repeat((4-t.length%4)%4),r=t+i,n=atob(r),s=new Uint8Array(n.length);for(let o=0;o<n.length;o+=1)s[o]=n.charCodeAt(o);return s}encodePushTokenFromSubscription(e){let t=e.toJSON(),i=String(t.endpoint??"").trim(),r=String(t.keys?.p256dh??"").trim(),n=String(t.keys?.auth??"").trim(),s=JSON.stringify({endpoint:i,p256dh:r,auth:n});return `webpush:${btoa(s)}`}async fetchPushSetupConfig(){let e=this.getHttpBase(),t=new URLSearchParams({appId:this.config.appId});this.config.apiKey&&t.set("apiKey",this.config.apiKey);let i=`${e}/push/config?${t.toString()}`,r=await this.timedFetch("fetchPushSetupConfig",i,{method:"GET",credentials:"include",headers:this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}}),n=await this.parseJsonWithTiming("fetchPushSetupConfig",r);r.response.ok||this.throwFetchFlareError(n,"Failed to fetch push setup config",d.QueryFailed);let s=String(n.vapidPublicKey??"").trim(),o=String(n.serviceWorkerPath??"").trim();if(o.startsWith("/"))try{let l=new URL(e,typeof window<"u"?window.location.origin:"http://localhost").pathname.replace(/\/+$/,"");l&&l!=="/"&&!o.startsWith(`${l}/`)&&(o=`${l}${o}`);}catch{}if(!s||!o)throw new h("Push setup response is missing vapidPublicKey or serviceWorkerPath",d.ParseError,n);return {vapidPublicKey:s,serviceWorkerPath:o}}async setupPushServiceWorker(){return typeof window>"u"||typeof navigator>"u"||!("serviceWorker"in navigator)?null:(this.pushServiceWorkerInitPromise||(this.pushServiceWorkerInitPromise=(async()=>{let e=await this.fetchPushSetupConfig(),t=new URL(e.serviceWorkerPath,window.location.origin);if(t.origin!==window.location.origin)throw new h("Service worker URL must be same-origin with the app",d.WriteFailed);return await navigator.serviceWorker.register(t.pathname+t.search,{scope:"/"})})().catch(e=>{throw this.log("Push service worker setup failed",e),e})),this.pushServiceWorkerInitPromise)}async requestPushPermission(){if(typeof window>"u"||typeof Notification>"u")throw new h("Push permission can only be requested in browser runtime",d.WriteFailed);let e=await Notification.requestPermission();if(e!=="granted")throw new h(`Push permission is ${e}`,d.PermissionDenied);return e}async acquireBrowserPushToken(e={}){if(typeof window>"u"||typeof navigator>"u")throw new h("Push token acquisition can only run in browser runtime",d.WriteFailed);if(!("serviceWorker"in navigator))throw new h("Service worker is not supported in this browser",d.WriteFailed);if(!("PushManager"in window))throw new h("Push manager is not supported in this browser",d.WriteFailed);await this.requestPushPermission();let t=e.applicationServerKey?null:await this.fetchPushSetupConfig(),i=e.serviceWorkerRegistration??await this.setupPushServiceWorker()??await navigator.serviceWorker.ready,r=e.subscription??await i.pushManager.getSubscription();if(e.forceResubscribe&&r&&(await r.unsubscribe().catch(()=>{}),r=null),!r){let s=e.applicationServerKey??t?.vapidPublicKey;if(!s)throw new h("No VAPID public key available for push subscription",d.WriteFailed);r=await i.pushManager.subscribe({userVisibleOnly:true,applicationServerKey:this.toUint8ArrayFromBase64Url(s)});}return {token:this.encodePushTokenFromSubscription(r),subscription:r}}async enableBrowserPush(e={}){let{token:t,subscription:i}=await this.acquireBrowserPushToken(e);return {...await this.registerPushToken({token:t,platform:e.platform??"web",deviceId:e.deviceId,topics:e.topics,authAppId:e.authAppId}),subscription:i}}async registerPushToken(e){let t=this.getHttpBase();await this.ensureCsrfProtection();let i=String(e.token??"").trim();if(!i)throw new h("Push token is required",d.WriteFailed);let r=await this.timedFetch("registerPushToken",`${t}/notify/token?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{},...this.authSession?.accessToken?{Authorization:`Bearer ${this.authSession.accessToken}`}:{}},body:JSON.stringify({appId:this.config.appId,token:i,platform:e.platform,deviceId:e.deviceId,topics:e.topics,...e.authAppId?{authAppId:e.authAppId}:{}})}),n=await this.parseJsonWithTiming("registerPushToken",r);return r.response.ok||this.throwFetchFlareError(n,"Failed to register push token",d.WriteFailed),{registered:!!n.registered,appId:String(n.appId??this.config.appId),uid:String(n.uid??this.authSession?.uid??""),token:String(n.token??i),...typeof n.platform=="string"?{platform:n.platform}:{}}}async unregisterPushToken(e,t){let i=this.getHttpBase();await this.ensureCsrfProtection();let r=String(e??"").trim();if(!r)throw new h("Push token is required",d.WriteFailed);let n=await this.timedFetch("unregisterPushToken",`${i}/notify/token?appId=${encodeURIComponent(this.config.appId)}`,{method:"DELETE",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{},...this.authSession?.accessToken?{Authorization:`Bearer ${this.authSession.accessToken}`}:{}},body:JSON.stringify({appId:this.config.appId,token:r,...t?{authAppId:t}:{}})}),s=await this.parseJsonWithTiming("unregisterPushToken",n);return n.response.ok||this.throwFetchFlareError(s,"Failed to unregister push token",d.WriteFailed),{unregistered:!!s.unregistered,appId:String(s.appId??this.config.appId),token:String(s.token??r),removed:!!s.removed}}async sendPushNotification(e){let t=this.getHttpBase();await this.ensureCsrfProtection();let i=await this.timedFetch("sendPushNotification",`${t}/system/apps/${encodeURIComponent(this.config.appId)}/notifications/send`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.authSession?.accessToken?{Authorization:`Bearer ${this.authSession.accessToken}`}:{},...e.authAppId?{"x-flare-auth-app-id":e.authAppId}:{}},body:JSON.stringify({...e,appId:this.config.appId})}),r=await this.parseJsonWithTiming("sendPushNotification",i);return i.response.ok||this.throwFetchFlareError(r,"Failed to send push notification",d.WriteFailed),{sent:!!r.sent,appId:String(r.appId??this.config.appId),targetCount:Number(r.targetCount??0),successCount:Number(r.successCount??0),failureCount:Number(r.failureCount??0),invalidatedTokenCount:Number(r.invalidatedTokenCount??0),dryRun:!!r.dryRun}}async sendEmail(e){let t=this.getHttpBase();await this.ensureCsrfProtection();let i=await this.timedFetch("sendEmail",`${t}/system/apps/${encodeURIComponent(this.config.appId)}/email/send`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.authSession?.accessToken?{Authorization:`Bearer ${this.authSession.accessToken}`}:{},...e.authAppId?{"x-flare-auth-app-id":e.authAppId}:{}},body:JSON.stringify({...e,appId:this.config.appId})}),r=await this.parseJsonWithTiming("sendEmail",i);return i.response.ok||this.throwFetchFlareError(r,"Failed to send template email",d.WriteFailed),{sent:!!r.sent,appId:String(r.appId??this.config.appId),tag:String(r.tag??e.tag??""),recipientCount:Number(r.recipientCount??0),acceptedCount:Number(r.acceptedCount??0),rejectedCount:Number(r.rejectedCount??0),...typeof r.includeVerificationLink=="boolean"?{includeVerificationLink:r.includeVerificationLink}:{},...typeof r.linkId=="string"?{linkId:r.linkId}:{},...typeof r.verifyUrl=="string"?{verifyUrl:r.verifyUrl}:{},...typeof r.messageId=="string"?{messageId:r.messageId}:{}}}async verifyEmailLink(e){let t=this.getHttpBase(),i=String(e.token??"").trim();if(!i)throw new h("Verification token is required",d.WriteFailed);let r=await this.timedFetch("verifyEmailLink",`${t}/email/link/verify?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{},...this.authSession?.accessToken?{Authorization:`Bearer ${this.authSession.accessToken}`}:{},...e.authAppId?{"x-flare-auth-app-id":e.authAppId}:{}},body:JSON.stringify({appId:this.config.appId,apiKey:this.config.apiKey,token:i,...e.tag?{tag:e.tag}:{},...e.email?{email:e.email}:{},...e.authAppId?{authAppId:e.authAppId}:{}})}),n=await this.parseJsonWithTiming("verifyEmailLink",r);return r.response.ok||this.throwFetchFlareError(n,"Failed to verify email link",d.WriteFailed),{verified:!!(n.verified??n.accepted),alreadyVerified:!!(n.alreadyVerified??n.alreadyAccepted),appId:String(n.appId??this.config.appId),linkId:String(n.linkId??""),email:String(n.email??""),tag:String(n.tag??e.tag??""),...typeof n.verifiedAt=="string"?{verifiedAt:n.verifiedAt}:{},...typeof n.acceptedByUid=="string"?{acceptedByUid:n.acceptedByUid}:{}}}async signIn(e,t,i){let r=typeof e?.signIn=="function",n=r?e:await this.getAuthGuard(),s=r?t:e,o=r?i:t;return n.signIn(s,o)}async signInWithGoogle(e){return this.signIn("google",e)}async signInWithGitHub(e){return this.signIn("github",e)}async signInWithFacebook(e){return this.signIn("facebook",e)}async signInWithDropbox(e){return this.signIn("dropbox",e)}async handleSignInRedirect(e,t=false){let i=typeof e?.handleRedirect=="function",r=i?e:await this.getAuthGuard(),n=i?t:typeof e=="boolean"?e:false,s=await r.handleRedirect(n);if(!s||!s.access_token||!s.provider)return null;let o=await this.exchangeProviderToken(s.provider,s.access_token),c=await this.auth(o.token),l=await this.fetchAuthMe(o.token).catch(()=>null);return this.setAuthSession({uid:c.uid,accessToken:o.token,refreshToken:s.refresh_token,provider:s.provider,email:l?.email??null,emailVerified:l?.email_verified}),{...c,authToken:s,provider:s.provider}}async exchangeProviderToken(e,t){let i=`${this.getHttpBase()}/auth/exchange`;await this.ensureCsrfProtection();let r=await this.timedFetch("exchangeProviderToken",i,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders()},body:JSON.stringify({appId:this.config.appId,client_id:this.config.apiKey,provider:e,access_token:t})}),n=await this.parseJsonWithTiming("exchangeProviderToken",r);if(r.response.ok||this.throwFetchFlareError(n,"OAuth token exchange failed",d.AuthenticationFailed),!n?.token)throw new h("OAuth token exchange failed",d.ParseError,n);return {token:String(n.token)}}async getAuthGuard(){if(this.authGuard)return this.authGuard;let e=await this.fetchAuthConfig();if(!e.enabled)throw new h("Authentication is disabled for this app",d.AuthenticationFailed);let t=this.getHttpBase(),i=`${t}/auth/oauth/token?appId=${encodeURIComponent(this.config.appId)}`,r=[],n=(s,o)=>({...o,token_url:i,tokenParams:{...o.tokenParams??{},provider:s}});if(e.providers.credentials?.enabled&&r.push({...auth.Credentials({clientId:this.config.apiKey}),token_url:`${t}/auth/token?appId=${encodeURIComponent(this.config.appId)}`,createUserUrl:`${t}/auth/register?appId=${encodeURIComponent(this.config.appId)}`,createUserGrantType:"create_user"}),e.providers.anonymous?.enabled&&r.push({...auth.Anonymous({clientId:this.config.apiKey}),token_url:`${t}/auth/token?appId=${encodeURIComponent(this.config.appId)}`}),e.providers.google?.enabled&&e.providers.google.clientId&&r.push(n("google",auth.Google({clientId:e.providers.google.clientId,scopes:e.providers.google.scopes}))),e.providers.github?.enabled&&e.providers.github.clientId&&r.push(n("github",auth.GitHub({clientId:e.providers.github.clientId,scopes:e.providers.github.scopes}))),e.providers.facebook?.enabled&&e.providers.facebook.clientId&&r.push(n("facebook",auth.Facebook({clientId:e.providers.facebook.clientId,scopes:e.providers.facebook.scopes}))),e.providers.dropbox?.enabled&&e.providers.dropbox.clientId&&r.push(n("dropbox",auth.Dropbox({clientId:e.providers.dropbox.clientId,scopes:e.providers.dropbox.scopes}))),e.providers.apple?.enabled&&e.providers.apple.clientId&&r.push(n("apple",auth.Apple({clientId:e.providers.apple.clientId,scopes:e.providers.apple.scopes}))),e.providers.twitter?.enabled&&e.providers.twitter.clientId&&r.push(n("twitter",auth.Twitter({clientId:e.providers.twitter.clientId,scopes:e.providers.twitter.scopes}))),r.length===0)throw new h("No authentication providers are enabled for this app",d.AuthenticationFailed);return this.authGuard=new auth.AuthGuard({providers:r,redirectUri:e.redirectUri}),this.authGuard}async refreshAuthSession(e){let t=this.getHttpBase();await this.ensureCsrfProtection(),this.traceAuth("refreshAuthSession.start",{providedRefreshToken:!!e,hasSessionBefore:!!this.authSession});let i=await this.timedFetch("refreshAuthSession",`${t}/auth/refresh?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:JSON.stringify({appId:this.config.appId,apiKey:this.config.apiKey,...e?{refresh_token:e}:{}})}),r=await this.parseJsonWithTiming("refreshAuthSession",i);if(!i.response.ok){if(i.response.status===401)return this.traceAuth("refreshAuthSession.response",{status:i.response.status,ok:false,reason:"unauthorized"}),this.setAuthSession(null,"refreshAuthSession.401"),await this.syncSocketAuth(null).catch(()=>{}),null;this.throwFetchFlareError(r,"Failed to refresh auth session",d.AuthenticationFailed);}let n=String(r.access_token??"");if(!n)throw new h("Refresh succeeded but no access token was returned",d.ParseError);let s=await this.fetchAuthMe(n).catch(()=>null),o={uid:String(s?.id??this.authSession?.uid??this.userId??""),accessToken:n,refreshToken:r.refresh_token?String(r.refresh_token):this.authSession?.refreshToken??null,provider:this.authSession?.provider,email:s?.email??this.authSession?.email??null,emailVerified:s?.email_verified};if(s){try{delete s.kind,s.uid=s.id??s.uid,delete s.id;}catch{}this.setProfile(s);}return this.traceAuth("refreshAuthSession.response",{status:i.response.status,ok:true,nextUid:o.uid,hasProfile:!!s}),this.setAuthSession(o,"refreshAuthSession.success"),await this.syncSocketAuth(n).catch(()=>{}),o}async issueSsrToken(e=120){let t=this.getHttpBase();await this.ensureCsrfProtection();let i=await this.timedFetch("issueSsrToken",`${t}/auth/ssr/token?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:JSON.stringify({appId:this.config.appId,apiKey:this.config.apiKey,ttlSeconds:e})}),r=await this.parseJsonWithTiming("issueSsrToken",i);i.response.ok||this.throwFetchFlareError(r,"Failed to mint SSR token",d.AuthenticationFailed);let n=String(r.token??"");if(!n)throw new h("SSR token response is missing token",d.ParseError,r);return {token:n,token_type:String(r.token_type??"Bearer"),expires_in:Number(r.expires_in??0),uid:String(r.uid??""),role:String(r.role??"user"),...typeof r.email=="string"?{email:r.email}:{}}}async signOut(){try{if(this.authSession?.accessToken||this.authSession?.refreshToken||this.config.httpBase){let t=this.getHttpBase();await this.ensureCsrfProtection(),await this.timedFetch("signOut",`${t}/auth/logout?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{},...this.authSession?.accessToken?{Authorization:`Bearer ${this.authSession.accessToken}`}:{}},body:JSON.stringify({appId:this.config.appId,apiKey:this.config.apiKey,refresh_token:this.authSession?.refreshToken})}).catch(()=>{});}}finally{this.setAuthSession(null,"signOut.finally"),await this.syncSocketAuth(null).catch(()=>{});}this.log("Signed out");}async registerWithEmail(e,t,i){let r=this.getHttpBase();await this.ensureCsrfProtection();let n=new URLSearchParams;n.set("appId",this.config.appId),n.set("client_id",this.config.apiKey??""),n.set("grant_type","create_user"),n.set("email",e),n.set("password",t),i?.scope?.length&&n.set("scope",i.scope.join(" ")),i?.additionalParams&&n.set("additional_params",JSON.stringify(i.additionalParams));let s=await this.timedFetch("registerWithEmail",`${r}/auth/register?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/x-www-form-urlencoded",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:n.toString()}),o=await this.parseJsonWithTiming("registerWithEmail",s);return !s.response.ok&&s.response.status!==202&&this.throwFetchFlareError(o,"User creation failed",d.WriteFailed),o}async requestEmailPasswordToken(e,t,i){let r=this.getHttpBase();await this.ensureCsrfProtection();let n=new URLSearchParams;n.set("appId",this.config.appId),n.set("client_id",this.config.apiKey??""),n.set("grant_type","password"),n.set("email",e),n.set("password",t),i?.length&&n.set("scope",i.join(" "));let s=await this.timedFetch("requestEmailPasswordToken",`${r}/auth/token?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/x-www-form-urlencoded",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:n.toString()}),o=await this.parseJsonWithTiming("requestEmailPasswordToken",s);return s.response.ok||this.throwFetchFlareError(o,"Sign-in with email/password failed",d.AuthenticationFailed),{kind:String(o.kind),access_token:String(o.access_token??""),refresh_token:o.refresh_token?String(o.refresh_token):null,expires_in:o.expires_in?Number(o.expires_in):null,token_type:String(o.token_type??"Bearer"),scope:o.scope?String(o.scope):null,profile:null,provider:"credentials"}}async fetchAuthMe(e){let t=this.getHttpBase(),i=new URLSearchParams({appId:this.config.appId});this.config.apiKey&&i.set("apiKey",this.config.apiKey);let r=`${t}/auth/me?${i.toString()}`,n=await this.timedFetch("fetchAuthMe",r,{credentials:"include",headers:{Authorization:`Bearer ${e}`,...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}}}),s=await this.parseJsonWithTiming("fetchAuthMe",n);return n.response.ok||this.throwFetchFlareError(s,"Failed to fetch profile",d.QueryFailed),s}};var Y=class extends q{autoPushRegisteredIdentity;constructor(e){super(e),this.log("FlareClient initialized",e),e.pushNotifications===true&&this.enableAutoPushNotificationsAfterAuth();}enableAutoPushNotificationsAfterAuth(){let e=async()=>{let t=this.authSession,i=String(t?.uid??"").trim()||"anon",r=String(t?.accessToken??"").trim(),n=i!=="anon"&&r?i:"anon";if(this.autoPushRegisteredIdentity!==n)try{await this.autoEnablePushNotifications(),this.autoPushRegisteredIdentity=n;}catch(s){this.log("Auto push enable failed",s);}};this.onAuthStateChanged(()=>{e().catch(()=>{});}),e().catch(()=>{});}async autoEnablePushNotifications(){await this.setupPushServiceWorker().catch(()=>{}),await this.requestPushPermission();let{token:e}=await this.acquireBrowserPushToken();await this.registerPushToken({token:e,platform:"web",topics:[this.config.appId]});}},re=Y;function Z(a){return `__flare_csrf_${a.replace(/[^a-zA-Z0-9_-]/g,"_")}`}function Ie(a){return `__flare_csrf_${a.replace(/[^a-zA-Z0-9_-]/g,"_")}`}function L(a,e){let t=e.toLowerCase();for(let[i,r]of Object.entries(a??{}))if(i.toLowerCase()===t&&typeof r=="string")return r}function Re(a){let e=L(a,"set-cookie");if(typeof e=="string"&&e.length>0)return [e];for(let[t,i]of Object.entries(a??{}))if(t.toLowerCase()==="set-cookie"&&Array.isArray(i))return i.filter(r=>typeof r=="string");return []}function Ee(a,e){for(let t of a){let i=t.split(";").map(c=>c.trim()),[r]=i;if(!r)continue;let n=r.indexOf("=");if(n<=0)continue;let s=decodeURIComponent(r.slice(0,n)),o=r.slice(n+1);if(s===e)return decodeURIComponent(o)}}async function Fe(a){let e=new URL("/auth/config",a.endpoint);return e.searchParams.set("appId",a.appId),a.apiKey&&e.searchParams.set("apiKey",a.apiKey),await core.withGet(e.toString(),{ignoreKind:true,withCredentials:true,returnRawResponse:true,headers:a.apiKey?{"x-flare-api-key":a.apiKey}:{},appendCookiesToBody:false,appendTimestamp:false}).catch(()=>null)}async function ie(a){let e=await Fe(a),t=e?.data,i=e?.headers??{},r=L(i,"x-flare-csrf")??L(i,"x-csrf-token")??L(i,"csrf-token");if(typeof r=="string"&&r.length>0)return {csrfToken:r,...t};let n=t?.cookie?.csrfTokenName,s=n&&n.length>0?n:Ie(a.appId),o=Re(i),c=Ee(o,s);if(typeof c=="string"&&c.length>0)return {csrfToken:c,...t}}function ne(a,e,t){return `${encodeURIComponent(a)}=${encodeURIComponent(e)}; HttpOnly; SameSite=Strict; Path=/; Max-Age=${t}`}function xe(a){let e=a.proxyCookieName??Z(a.appId),t=a.proxyCookieMaxAge??3600;return async function(r){let n=await ie(a),s=n?.csrfToken,o=new Headers({"Content-Type":"application/json"});return s&&o.set("Set-Cookie",ne(e,s,t)),new Response(JSON.stringify({csrfToken:s??null,...n}),{status:200,headers:o})}}function Me(a){let e=a.proxyCookieName??Z(a.appId),t=a.proxyCookieMaxAge??3600;return async function(r,n){if(r.method!=="GET"&&r.method!=="HEAD"){n.status(405).json({error:"Method not allowed"});return}let o=(await ie(a))?.csrfToken;o&&n.setHeader("Set-Cookie",ne(e,o,t)),n.status(200).json({csrfToken:o??null});}}function Be(a,e,t){let i=t??Z(e);if(a instanceof Request){let s=(a.headers.get("cookie")??"").split(";").map(c=>c.trim()).find(c=>c.startsWith(`${encodeURIComponent(i)}=`)||c.startsWith(`${i}=`));if(!s)return null;let o=s.indexOf("=");return o>=0?decodeURIComponent(s.slice(o+1)):null}let{cookies:r}=a;return typeof r?.get=="function"?r.get(i)?.value??null:r&&typeof r=="object"?r[i]??null:null}function Qe(a,e){let t={};return a&&(t["x-flare-csrf"]=a),e?.accessToken&&(t.Authorization=`Bearer ${e.accessToken}`),e?.apiKey&&(t["x-flare-api-key"]=e.apiKey),t}var Oe=a=>a==="guest"?"auth == null":a==="auth"?"auth != null":"true",_e=(a,e)=>{let t=String(e??"").trim();return t?a==="true"?t:`(${a}) && (${t})`:a},Ne=a=>{let e=String(a??"").trim();if(!e||e==="false")return {auth:"any"};if(e==="auth != null")return {auth:"auth"};if(e==="auth == null")return {auth:"guest"};if(e==="true")return {auth:"any"};let t=e.match(/^\((auth != null|auth == null|true)\)\s*&&\s*\((.+)\)$/);if(t)return {auth:se(t[1]),condition:t[2].trim()};let i=e.match(/^(auth != null|auth == null|true)\s*&&\s*(.+)$/);return i?{auth:se(i[1]),condition:i[2].trim()}:{auth:"any",condition:e}},se=a=>{let e=String(a??"").trim();return e==="auth == null"?"guest":e==="auth != null"?"auth":"any"},Ot=a=>{let e={};for(let t of a){let i=String(t.collection||"").trim();if(!i)continue;let r=i==="any"?"*":i,n=_e(Oe(t.auth),t.condition);e[r]={".read":t.permissions.includes("read")?n:"false",".create":t.permissions.includes("create")?n:"false",".update":t.permissions.includes("update")?n:"false",".delete":t.permissions.includes("delete")?n:"false"};}return e},_t=a=>Object.entries(a).map(([e,t],i)=>{let r=t?.[".read"],n=t?.[".create"],s=t?.[".update"],o=t?.[".delete"],c=t?.[".write"],l=[];typeof r=="string"&&r.trim()!=="false"&&l.push("read");let g=typeof n=="string"&&n.trim()!=="false"||typeof c=="string"&&c.trim()!=="false",y=typeof s=="string"&&s.trim()!=="false"||typeof c=="string"&&c.trim()!=="false",u=typeof o=="string"&&o.trim()!=="false"||typeof c=="string"&&c.trim()!=="false";g&&l.push("create"),y&&l.push("update"),u&&l.push("delete");let S=Ne(r||n||s||o||c);return {id:`${e}-${i}`,name:e==="*"?"All Collections":e,auth:S.auth,collection:e==="*"?"any":e,condition:S.condition,permissions:l}});var De=(y=>(y.authEmailNotVerified="auth/email-not-verified",y.authEmailAlreadyVerified="auth/email-already-verified",y.authInvalidToken="auth/invalid-token",y.authUserDisabled="auth/user-disabled",y.authUserNotFound="auth/user-not-found",y.authWrongPassword="auth/wrong-password",y.authEmailAlreadyInUse="auth/email-already-in-use",y.authInvalidEmail="auth/invalid-email",y.authWeakPassword="auth/weak-password",y.authTooManyRequests="auth/too-many-requests",y.authInternalError="auth/internal-error",y))(De||{});var He=(f=>(f.health="health",f.authConfig="auth_config",f.authRegistration="auth/registration",f.authRegistrationVerificationRequired="auth/registration-verification-required",f.authSession="auth/session",f.authExchange="auth/exchange",f.authLogout="auth/logout",f.authSsrBridge="auth/ssr_bridge",f.authSsrVerify="auth/ssr_verify",f.accountRecovery="account/recovery",f.emailVerification="email/verification",f.verificationDispatch="verification/dispatch",f.authProfile="auth/profile",f.adminToken="admin/token",f.documentDelete="document/delete",f.documentsDelete="documents/delete",f.documents="documents",f.document="document",f.documentCreate="document/create",f.documentUpdate="document/update",f.oauthProviderResponse="oauth_provider_response",f.success="success",f.response="response",f))(He||{});var k=null,Q=null,U=null,qe=a=>JSON.stringify({endpoint:a.endpoint,appId:a.appId,apiKey:a.apiKey,publicKey:a.publicKey,autoReconnect:a.autoReconnect,reconnectDelay:a.reconnectDelay,maxReconnectDelay:a.maxReconnectDelay,dataMapperKeys:Object.keys(a.dataMapper??{}).sort()}),$t=a=>{let e=qe(a);if(k&&U!==e&&(k.disconnect(),k=null,Q=null,U=null),!k){k=new re(a),U=e;let t=typeof window<"u"&&typeof document<"u",i=typeof process<"u"&&typeof process.env?.NEXT_RUNTIME=="string";(t||!i)&&k.connect(),t&&k.setupPushServiceWorker().catch(()=>{}),Q=new Proxy(k,{get(r,n,s){if(n==="onAuthStateChange")return r.onAuthStateChanged.bind(r);if(n==="onAuthConfigLoaded")return r.onAuthConfigLoaded.bind(r);let o=Reflect.get(r,n,s);return typeof o=="function"?o.bind(r):o}});}return Q??k},Kt=()=>Q??k,Jt=()=>{k&&(k.disconnect(),k=null,Q=null,U=null);};
|
|
3
|
+
Object.defineProperty(exports,"Anonymous",{enumerable:true,get:function(){return auth.Anonymous}});Object.defineProperty(exports,"Apple",{enumerable:true,get:function(){return auth.Apple}});Object.defineProperty(exports,"AuthGuard",{enumerable:true,get:function(){return auth.AuthGuard}});Object.defineProperty(exports,"Credentials",{enumerable:true,get:function(){return auth.Credentials}});Object.defineProperty(exports,"Dropbox",{enumerable:true,get:function(){return auth.Dropbox}});Object.defineProperty(exports,"Facebook",{enumerable:true,get:function(){return auth.Facebook}});Object.defineProperty(exports,"GitHub",{enumerable:true,get:function(){return auth.GitHub}});Object.defineProperty(exports,"Google",{enumerable:true,get:function(){return auth.Google}});Object.defineProperty(exports,"Providers",{enumerable:true,get:function(){return auth.Providers}});Object.defineProperty(exports,"Twitter",{enumerable:true,get:function(){return auth.Twitter}});Object.defineProperty(exports,"setupProvider",{enumerable:true,get:function(){return auth.setupProvider}});exports.CollectionReference=G;exports.DocumentQueryBuilder=A;exports.DocumentReference=B;exports.FlareAction=ae;exports.FlareClient=re;exports.FlareError=h;exports.FlareErrors=De;exports.FlareEvent=ce;exports.FlareResponseCodes=He;exports.buildFlareHeaders=Qe;exports.connectApp=$t;exports.createCsrfProxy=xe;exports.createCsrfProxyHandler=Me;exports.disconnectFlare=Jt;exports.extractCsrfFromRequest=Be;exports.flareRulesToSecurityMap=Ot;exports.getFlare=Kt;exports.parseValue=ee;exports.parseWhereCondition=j;exports.securityMapToFlareRules=_t;
|
package/dist/index.d.cts
CHANGED
|
@@ -35,7 +35,17 @@ interface FlareConfig {
|
|
|
35
35
|
connectionTimeout?: number;
|
|
36
36
|
/** Enable automatic push notification registration on supported platforms. */
|
|
37
37
|
pushNotifications?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Optional per-collection mapper registry for shaping inbound data.
|
|
40
|
+
*
|
|
41
|
+
* Keys can be:
|
|
42
|
+
* - base collection names (e.g. "boards")
|
|
43
|
+
* - join aliases (`join(..., { as: "team" })` => "team")
|
|
44
|
+
*/
|
|
45
|
+
dataMapper?: DataMapperRegistry;
|
|
38
46
|
}
|
|
47
|
+
type DataMapperFn<TRow = any, TMapped = any> = (row: TRow) => TMapped;
|
|
48
|
+
type DataMapperRegistry = Record<string, DataMapperFn<any, any>>;
|
|
39
49
|
type FlareAuthProviderId = "credentials" | "anonymous" | "google" | "facebook" | "github" | "dropbox" | "apple" | "twitter";
|
|
40
50
|
interface FlareAuthProviderPublicConfig {
|
|
41
51
|
enabled: boolean;
|
|
@@ -876,6 +886,10 @@ declare class FlareBase<TPresetMap extends QueryPresetMap = {}> {
|
|
|
876
886
|
protected fromWireField(field: string): string;
|
|
877
887
|
protected normalizeOutboundData(value: unknown): unknown;
|
|
878
888
|
protected normalizeInboundData(value: unknown): unknown;
|
|
889
|
+
private getDataMapper;
|
|
890
|
+
private runMapper;
|
|
891
|
+
private applyJoinAliasMappers;
|
|
892
|
+
mapInboundResult(collection: string, payload: unknown, query?: StructuredQuery): unknown;
|
|
879
893
|
protected normalizeOutboundAnyFilter(filter: Record<string, unknown>): Record<string, unknown>;
|
|
880
894
|
protected normalizeOutboundQuery(query: unknown): unknown;
|
|
881
895
|
protected timedFetch(label: string, input: string, init?: RequestInit): Promise<{
|
|
@@ -976,6 +990,7 @@ declare class FlareBase<TPresetMap extends QueryPresetMap = {}> {
|
|
|
976
990
|
* domain and one from the Next.js domain.
|
|
977
991
|
*/
|
|
978
992
|
declare class FlareAuth<TPresetMap extends QueryPresetMap = {}> extends FlareBase<TPresetMap> {
|
|
993
|
+
static AUTH_TRACE_STORAGE_KEY: string;
|
|
979
994
|
protected authToken?: string;
|
|
980
995
|
protected userId?: string;
|
|
981
996
|
protected authGuard?: AuthGuard;
|
|
@@ -987,9 +1002,14 @@ declare class FlareAuth<TPresetMap extends QueryPresetMap = {}> extends FlareBas
|
|
|
987
1002
|
protected socketAuthSyncPromise?: Promise<void>;
|
|
988
1003
|
protected pushServiceWorkerInitPromise?: Promise<ServiceWorkerRegistration | null>;
|
|
989
1004
|
protected authSession: FlareAuthSession | null;
|
|
1005
|
+
protected authBootstrapPromise?: Promise<void>;
|
|
1006
|
+
protected authBootstrapAttempted: boolean;
|
|
990
1007
|
protected authStateListeners: AuthStateListener[];
|
|
991
1008
|
protected authConfigListeners: AuthConfigListener[];
|
|
992
1009
|
protected currentProfile: FlareAuthUser | undefined;
|
|
1010
|
+
protected isAuthTraceEnabled(): boolean;
|
|
1011
|
+
setAuthTrace(enabled: boolean, persist?: boolean): void;
|
|
1012
|
+
protected traceAuth(event: string, details?: Record<string, unknown>): void;
|
|
993
1013
|
private getDefaultCsrfCookieName;
|
|
994
1014
|
getCsrfCookieName(): string;
|
|
995
1015
|
/**
|
|
@@ -1033,7 +1053,7 @@ declare class FlareAuth<TPresetMap extends QueryPresetMap = {}> extends FlareBas
|
|
|
1033
1053
|
protected fetchAuthConfig(): Promise<FlareAuthConfig>;
|
|
1034
1054
|
onAuthConfigLoaded(listener: AuthConfigListener): () => void;
|
|
1035
1055
|
protected setProfile(profile: FlareAuthUser): void;
|
|
1036
|
-
protected setAuthSession(session: FlareAuthSession | null): void;
|
|
1056
|
+
protected setAuthSession(session: FlareAuthSession | null, source?: string): void;
|
|
1037
1057
|
onAuthStateChanged(listener: AuthStateListener): () => void;
|
|
1038
1058
|
onAuthStateChange(listener: AuthStateListener): () => void;
|
|
1039
1059
|
get currentUser(): FlareAuthUser | undefined;
|
|
@@ -1165,6 +1185,7 @@ declare class FlareAuth<TPresetMap extends QueryPresetMap = {}> extends FlareBas
|
|
|
1165
1185
|
email: string;
|
|
1166
1186
|
}>;
|
|
1167
1187
|
sendAccountRecovery(email: string): Promise<{
|
|
1188
|
+
kind?: string;
|
|
1168
1189
|
sent: boolean;
|
|
1169
1190
|
emailSent?: boolean;
|
|
1170
1191
|
preview?: {
|
|
@@ -1494,4 +1515,4 @@ declare const getFlare: () => FlareClient | null;
|
|
|
1494
1515
|
*/
|
|
1495
1516
|
declare const disconnectFlare: () => void;
|
|
1496
1517
|
|
|
1497
|
-
export { type AggregateFunction, type AggregateSpec, type AndFilter, type AnyFilter, type AuthConfigListener, type AuthConfigResponse, type AuthResult, type AuthStateListener, type AuthWithPendingVerificationResult, type AuthWithTokenResult, type BaseMessage, type BrowserPushRegistrationOptions, type BrowserPushTokenOptions, type ChangeEvent, type ChangeOperation, type CollectionExternalStore, type CollectionPresetMethods, type CollectionQuery, CollectionReference, type CollectionStream, type CollectionStreamListener, type CollectionStreamMeta, type CollectionStreamOptions, type ConnectionState, type CsrfProxyConfig, type CursorValue, type DocAddedCallback, type DocChangedCallback, type DocDeletedCallback, type DocUpdatedCallback, DocumentQueryBuilder, DocumentReference, type DocumentSnapshot, type EmailLinkVerifyResult, type EmailSendResult, FlareAction, type FlareAuthConfig, type FlareAuthProviderId, type FlareAuthProviderPublicConfig, type FlareAuthSession, type FlareAuthUser, FlareClient, type FlareConfig, FlareError, FlareErrors, FlareEvent, FlareResponseCodes, type FlareRule, type GroupByClause, type HavingClause, type JoinClause, type JoinQueryPattern, type NestedJoinClause, type OfflineOperation, type OrFilter, type OrderByClause, type PresenceCallback, type PresenceJoinCallback, type PresenceLeaveCallback, type PresenceMember, type PushSendResult, type QueryConfig, type QueryOperator, type QueryPresetMap, type QueryPresetParams, type QueryPresetRow, type QueryPresetSpec, type QuerySnapshot, type RegisterPushTokenInput, type RulePermission, type SecurityRuleEntry, type SecurityRulesMap, type SendEmailInput, type SendPushNotificationInput, type SnapshotEvent, type StreamFlushReason, type StructuredJoinClause, type StructuredQuery, type SubscribeMessage, type SubscribeOptions, type SubscriptionCallback, type SubscriptionData, type SubscriptionError, type SubscriptionErrorCallback, type SubscriptionHandle, type VectorFieldConfig, type VectorSearchClause, type VerifyEmailLinkInput, type WhereCondition, buildFlareHeaders, connectApp, createCsrfProxy, createCsrfProxyHandler, disconnectFlare, extractCsrfFromRequest, flareRulesToSecurityMap, getFlare, parseValue, parseWhereCondition, securityMapToFlareRules };
|
|
1518
|
+
export { type AggregateFunction, type AggregateSpec, type AndFilter, type AnyFilter, type AuthConfigListener, type AuthConfigResponse, type AuthResult, type AuthStateListener, type AuthWithPendingVerificationResult, type AuthWithTokenResult, type BaseMessage, type BrowserPushRegistrationOptions, type BrowserPushTokenOptions, type ChangeEvent, type ChangeOperation, type CollectionExternalStore, type CollectionPresetMethods, type CollectionQuery, CollectionReference, type CollectionStream, type CollectionStreamListener, type CollectionStreamMeta, type CollectionStreamOptions, type ConnectionState, type CsrfProxyConfig, type CursorValue, type DataMapperFn, type DataMapperRegistry, type DocAddedCallback, type DocChangedCallback, type DocDeletedCallback, type DocUpdatedCallback, DocumentQueryBuilder, DocumentReference, type DocumentSnapshot, type EmailLinkVerifyResult, type EmailSendResult, FlareAction, type FlareAuthConfig, type FlareAuthProviderId, type FlareAuthProviderPublicConfig, type FlareAuthSession, type FlareAuthUser, FlareClient, type FlareConfig, FlareError, FlareErrors, FlareEvent, FlareResponseCodes, type FlareRule, type GroupByClause, type HavingClause, type JoinClause, type JoinQueryPattern, type NestedJoinClause, type OfflineOperation, type OrFilter, type OrderByClause, type PresenceCallback, type PresenceJoinCallback, type PresenceLeaveCallback, type PresenceMember, type PushSendResult, type QueryConfig, type QueryOperator, type QueryPresetMap, type QueryPresetParams, type QueryPresetRow, type QueryPresetSpec, type QuerySnapshot, type RegisterPushTokenInput, type RulePermission, type SecurityRuleEntry, type SecurityRulesMap, type SendEmailInput, type SendPushNotificationInput, type SnapshotEvent, type StreamFlushReason, type StructuredJoinClause, type StructuredQuery, type SubscribeMessage, type SubscribeOptions, type SubscriptionCallback, type SubscriptionData, type SubscriptionError, type SubscriptionErrorCallback, type SubscriptionHandle, type VectorFieldConfig, type VectorSearchClause, type VerifyEmailLinkInput, type WhereCondition, buildFlareHeaders, connectApp, createCsrfProxy, createCsrfProxyHandler, disconnectFlare, extractCsrfFromRequest, flareRulesToSecurityMap, getFlare, parseValue, parseWhereCondition, securityMapToFlareRules };
|
package/dist/index.d.ts
CHANGED
|
@@ -35,7 +35,17 @@ interface FlareConfig {
|
|
|
35
35
|
connectionTimeout?: number;
|
|
36
36
|
/** Enable automatic push notification registration on supported platforms. */
|
|
37
37
|
pushNotifications?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Optional per-collection mapper registry for shaping inbound data.
|
|
40
|
+
*
|
|
41
|
+
* Keys can be:
|
|
42
|
+
* - base collection names (e.g. "boards")
|
|
43
|
+
* - join aliases (`join(..., { as: "team" })` => "team")
|
|
44
|
+
*/
|
|
45
|
+
dataMapper?: DataMapperRegistry;
|
|
38
46
|
}
|
|
47
|
+
type DataMapperFn<TRow = any, TMapped = any> = (row: TRow) => TMapped;
|
|
48
|
+
type DataMapperRegistry = Record<string, DataMapperFn<any, any>>;
|
|
39
49
|
type FlareAuthProviderId = "credentials" | "anonymous" | "google" | "facebook" | "github" | "dropbox" | "apple" | "twitter";
|
|
40
50
|
interface FlareAuthProviderPublicConfig {
|
|
41
51
|
enabled: boolean;
|
|
@@ -876,6 +886,10 @@ declare class FlareBase<TPresetMap extends QueryPresetMap = {}> {
|
|
|
876
886
|
protected fromWireField(field: string): string;
|
|
877
887
|
protected normalizeOutboundData(value: unknown): unknown;
|
|
878
888
|
protected normalizeInboundData(value: unknown): unknown;
|
|
889
|
+
private getDataMapper;
|
|
890
|
+
private runMapper;
|
|
891
|
+
private applyJoinAliasMappers;
|
|
892
|
+
mapInboundResult(collection: string, payload: unknown, query?: StructuredQuery): unknown;
|
|
879
893
|
protected normalizeOutboundAnyFilter(filter: Record<string, unknown>): Record<string, unknown>;
|
|
880
894
|
protected normalizeOutboundQuery(query: unknown): unknown;
|
|
881
895
|
protected timedFetch(label: string, input: string, init?: RequestInit): Promise<{
|
|
@@ -976,6 +990,7 @@ declare class FlareBase<TPresetMap extends QueryPresetMap = {}> {
|
|
|
976
990
|
* domain and one from the Next.js domain.
|
|
977
991
|
*/
|
|
978
992
|
declare class FlareAuth<TPresetMap extends QueryPresetMap = {}> extends FlareBase<TPresetMap> {
|
|
993
|
+
static AUTH_TRACE_STORAGE_KEY: string;
|
|
979
994
|
protected authToken?: string;
|
|
980
995
|
protected userId?: string;
|
|
981
996
|
protected authGuard?: AuthGuard;
|
|
@@ -987,9 +1002,14 @@ declare class FlareAuth<TPresetMap extends QueryPresetMap = {}> extends FlareBas
|
|
|
987
1002
|
protected socketAuthSyncPromise?: Promise<void>;
|
|
988
1003
|
protected pushServiceWorkerInitPromise?: Promise<ServiceWorkerRegistration | null>;
|
|
989
1004
|
protected authSession: FlareAuthSession | null;
|
|
1005
|
+
protected authBootstrapPromise?: Promise<void>;
|
|
1006
|
+
protected authBootstrapAttempted: boolean;
|
|
990
1007
|
protected authStateListeners: AuthStateListener[];
|
|
991
1008
|
protected authConfigListeners: AuthConfigListener[];
|
|
992
1009
|
protected currentProfile: FlareAuthUser | undefined;
|
|
1010
|
+
protected isAuthTraceEnabled(): boolean;
|
|
1011
|
+
setAuthTrace(enabled: boolean, persist?: boolean): void;
|
|
1012
|
+
protected traceAuth(event: string, details?: Record<string, unknown>): void;
|
|
993
1013
|
private getDefaultCsrfCookieName;
|
|
994
1014
|
getCsrfCookieName(): string;
|
|
995
1015
|
/**
|
|
@@ -1033,7 +1053,7 @@ declare class FlareAuth<TPresetMap extends QueryPresetMap = {}> extends FlareBas
|
|
|
1033
1053
|
protected fetchAuthConfig(): Promise<FlareAuthConfig>;
|
|
1034
1054
|
onAuthConfigLoaded(listener: AuthConfigListener): () => void;
|
|
1035
1055
|
protected setProfile(profile: FlareAuthUser): void;
|
|
1036
|
-
protected setAuthSession(session: FlareAuthSession | null): void;
|
|
1056
|
+
protected setAuthSession(session: FlareAuthSession | null, source?: string): void;
|
|
1037
1057
|
onAuthStateChanged(listener: AuthStateListener): () => void;
|
|
1038
1058
|
onAuthStateChange(listener: AuthStateListener): () => void;
|
|
1039
1059
|
get currentUser(): FlareAuthUser | undefined;
|
|
@@ -1165,6 +1185,7 @@ declare class FlareAuth<TPresetMap extends QueryPresetMap = {}> extends FlareBas
|
|
|
1165
1185
|
email: string;
|
|
1166
1186
|
}>;
|
|
1167
1187
|
sendAccountRecovery(email: string): Promise<{
|
|
1188
|
+
kind?: string;
|
|
1168
1189
|
sent: boolean;
|
|
1169
1190
|
emailSent?: boolean;
|
|
1170
1191
|
preview?: {
|
|
@@ -1494,4 +1515,4 @@ declare const getFlare: () => FlareClient | null;
|
|
|
1494
1515
|
*/
|
|
1495
1516
|
declare const disconnectFlare: () => void;
|
|
1496
1517
|
|
|
1497
|
-
export { type AggregateFunction, type AggregateSpec, type AndFilter, type AnyFilter, type AuthConfigListener, type AuthConfigResponse, type AuthResult, type AuthStateListener, type AuthWithPendingVerificationResult, type AuthWithTokenResult, type BaseMessage, type BrowserPushRegistrationOptions, type BrowserPushTokenOptions, type ChangeEvent, type ChangeOperation, type CollectionExternalStore, type CollectionPresetMethods, type CollectionQuery, CollectionReference, type CollectionStream, type CollectionStreamListener, type CollectionStreamMeta, type CollectionStreamOptions, type ConnectionState, type CsrfProxyConfig, type CursorValue, type DocAddedCallback, type DocChangedCallback, type DocDeletedCallback, type DocUpdatedCallback, DocumentQueryBuilder, DocumentReference, type DocumentSnapshot, type EmailLinkVerifyResult, type EmailSendResult, FlareAction, type FlareAuthConfig, type FlareAuthProviderId, type FlareAuthProviderPublicConfig, type FlareAuthSession, type FlareAuthUser, FlareClient, type FlareConfig, FlareError, FlareErrors, FlareEvent, FlareResponseCodes, type FlareRule, type GroupByClause, type HavingClause, type JoinClause, type JoinQueryPattern, type NestedJoinClause, type OfflineOperation, type OrFilter, type OrderByClause, type PresenceCallback, type PresenceJoinCallback, type PresenceLeaveCallback, type PresenceMember, type PushSendResult, type QueryConfig, type QueryOperator, type QueryPresetMap, type QueryPresetParams, type QueryPresetRow, type QueryPresetSpec, type QuerySnapshot, type RegisterPushTokenInput, type RulePermission, type SecurityRuleEntry, type SecurityRulesMap, type SendEmailInput, type SendPushNotificationInput, type SnapshotEvent, type StreamFlushReason, type StructuredJoinClause, type StructuredQuery, type SubscribeMessage, type SubscribeOptions, type SubscriptionCallback, type SubscriptionData, type SubscriptionError, type SubscriptionErrorCallback, type SubscriptionHandle, type VectorFieldConfig, type VectorSearchClause, type VerifyEmailLinkInput, type WhereCondition, buildFlareHeaders, connectApp, createCsrfProxy, createCsrfProxyHandler, disconnectFlare, extractCsrfFromRequest, flareRulesToSecurityMap, getFlare, parseValue, parseWhereCondition, securityMapToFlareRules };
|
|
1518
|
+
export { type AggregateFunction, type AggregateSpec, type AndFilter, type AnyFilter, type AuthConfigListener, type AuthConfigResponse, type AuthResult, type AuthStateListener, type AuthWithPendingVerificationResult, type AuthWithTokenResult, type BaseMessage, type BrowserPushRegistrationOptions, type BrowserPushTokenOptions, type ChangeEvent, type ChangeOperation, type CollectionExternalStore, type CollectionPresetMethods, type CollectionQuery, CollectionReference, type CollectionStream, type CollectionStreamListener, type CollectionStreamMeta, type CollectionStreamOptions, type ConnectionState, type CsrfProxyConfig, type CursorValue, type DataMapperFn, type DataMapperRegistry, type DocAddedCallback, type DocChangedCallback, type DocDeletedCallback, type DocUpdatedCallback, DocumentQueryBuilder, DocumentReference, type DocumentSnapshot, type EmailLinkVerifyResult, type EmailSendResult, FlareAction, type FlareAuthConfig, type FlareAuthProviderId, type FlareAuthProviderPublicConfig, type FlareAuthSession, type FlareAuthUser, FlareClient, type FlareConfig, FlareError, FlareErrors, FlareEvent, FlareResponseCodes, type FlareRule, type GroupByClause, type HavingClause, type JoinClause, type JoinQueryPattern, type NestedJoinClause, type OfflineOperation, type OrFilter, type OrderByClause, type PresenceCallback, type PresenceJoinCallback, type PresenceLeaveCallback, type PresenceMember, type PushSendResult, type QueryConfig, type QueryOperator, type QueryPresetMap, type QueryPresetParams, type QueryPresetRow, type QueryPresetSpec, type QuerySnapshot, type RegisterPushTokenInput, type RulePermission, type SecurityRuleEntry, type SecurityRulesMap, type SendEmailInput, type SendPushNotificationInput, type SnapshotEvent, type StreamFlushReason, type StructuredJoinClause, type StructuredQuery, type SubscribeMessage, type SubscribeOptions, type SubscriptionCallback, type SubscriptionData, type SubscriptionError, type SubscriptionErrorCallback, type SubscriptionHandle, type VectorFieldConfig, type VectorSearchClause, type VerifyEmailLinkInput, type WhereCondition, buildFlareHeaders, connectApp, createCsrfProxy, createCsrfProxyHandler, disconnectFlare, extractCsrfFromRequest, flareRulesToSecurityMap, getFlare, parseValue, parseWhereCondition, securityMapToFlareRules };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {Credentials,Anonymous,Google,GitHub,Facebook,Dropbox,Apple,Twitter,AuthGuard}from'@zuzjs/auth';export{Anonymous,Apple,AuthGuard,Credentials,Dropbox,Facebook,GitHub,Google,Providers,Twitter,setupProvider}from'@zuzjs/auth';import {uuid2,withGet,withPut,withPatch,withPost}from'@zuzjs/core';var h=class extends Error{constructor(t,i,r){super(t);this.code=i;this.cause=r;this.name="ZuzFlareError";}};var ae={AuthenticationFailed:"AUTHENTICATION_FAILED",PermissionDenied:"PERMISSION_DENIED",WriteFailed:"WRITE_FAILED",QueryFailed:"QUERY_FAILED",ParseError:"PARSE_ERROR"},u=ae;var ce=(c=>(c.SUBSCRIBE="subscribe",c.UNSUBSCRIBE="unsubscribe",c.WRITE="write",c.DELETE="delete",c.AUTH="auth",c.PING="ping",c.OFFLINE_SYNC="offline_sync",c.CALL="call",c.QUERY="query",c.PRESENCE_JOIN="presence_join",c.PRESENCE_LEAVE="presence_leave",c.PRESENCE_HEARTBEAT="presence_heartbeat",c))(ce||{}),ue=(c=>(c.SNAPSHOT="snapshot",c.CHANGE="change",c.ERROR="error",c.ACK="ack",c.PONG="pong",c.AUTH_OK="auth_ok",c.OFFLINE_ACK="offline_ack",c.CALL_RESPONSE="call_response",c.QUERY_RESULT="query_result",c.PRESENCE_STATE="presence_state",c.PRESENCE_JOIN="presence_join",c.PRESENCE_LEAVE="presence_leave",c))(ue||{});function V(a){let e=[];for(let[t,i]of Object.entries(a))if(typeof i=="string"){let r=i.match(/^(>=|<=|!=|>|<|==)\s*(.+)$/);if(r){let[,n,s]=r;e.push({field:t,op:n,value:te(s.trim())});}else e.push({field:t,op:"==",value:i});}else Array.isArray(i)?e.push({field:t,op:"in",value:i}):e.push({field:t,op:"==",value:i});return e}function te(a){if(!isNaN(Number(a)))return Number(a);if(a==="true")return true;if(a==="false")return false;if(a==="null")return null;if(a!=="undefined")return a}var v=class{constructor(e,t,i){this.client=e;this.collection=t;this.docIdFromRef=i;}whereCondition;updateData;setData;deleteOp=false;promise;where(e){return this.whereCondition=e,this}update(e){return this.updateData=e,this}set(e){return this.setData=e,this}delete(){return this.deleteOp=true,this}getDocId(){if(this.docIdFromRef)return this.docIdFromRef;if(this.whereCondition&&(this.whereCondition.id||this.whereCondition._id)){let e=this.whereCondition.id??this.whereCondition._id;if(typeof e=="string")return e}throw new h('Document ID not specified. Use .where({ id: "..." }) or doc(collection, id)',u.QueryFailed)}async execute(){return this._execute()}async _execute(){let e=this.getDocId();if(this.deleteOp){await this.client.send("delete",{collection:this.collection,docId:e});return}if(this.updateData){await this.client.send("write",{collection:this.collection,docId:e,data:this.updateData,merge:true});return}if(this.setData){await this.client.send("write",{collection:this.collection,docId:e,data:this.setData,merge:false});return}return this.get()}then(e,t){return this.promise||(this.promise=this._execute()),this.promise.then(e,t)}async get(){let e=this.getDocId(),t=uuid2(18);return new Promise((i,r)=>{let n=this.client.subscribe(t,this.collection,e,void 0,s=>{s.type==="snapshot"&&(n(),i(s.data));});setTimeout(()=>{n(),r(new Error("Document fetch timeout"));},1e4);})}onSnapshot(e){let t=this.getDocId(),i=uuid2(18);return this.client.subscribe(i,this.collection,t,void 0,e)}};var z=class{constructor(e,t,i){this.client=e;this.collection=t;this.id=i;}async get(){return new v(this.client,this.collection,this.id).get()}async set(e){await this.client.send("write",{collection:this.collection,docId:this.id,data:e,merge:false});}async update(e){await this.client.send("write",{collection:this.collection,docId:this.id,data:e,merge:true});}async delete(){await this.client.send("delete",{collection:this.collection,docId:this.id});}onSnapshot(e){let t=uuid2(18),i=()=>{};return i=this.client.subscribe(t,this.collection,this.id,void 0,r=>{r.type==="snapshot"&&(e(r),i());}),i}onDocUpdated(e){let t=uuid2(18);return this.client.subscribe(t,this.collection,this.id,void 0,i=>{i.type==="change"&&(i.operation==="update"||i.operation==="replace")&&i.data&&e(i.data,i.docId);},{skipSnapshot:true})}onDocDeleted(e){let t=uuid2(18);return this.client.subscribe(t,this.collection,this.id,void 0,i=>{i.type==="change"&&i.operation==="delete"&&e(i.docId);},{skipSnapshot:true})}onDocChanged(e){let t=uuid2(18);return this.client.subscribe(t,this.collection,this.id,void 0,i=>{i.type==="change"&&e(i.data??null,i.docId,i.operation);},{skipSnapshot:true})}},O=z;var G=class a{constructor(e,t){this.client=e;this.collection=t;return new Proxy(this,{get:(i,r,n)=>{if(typeof r=="string"&&!(r in i)&&this.client.hasQueryPreset(r))return (o={})=>i.with(r,o);let s=Reflect.get(i,r,n);return typeof s=="function"?s.bind(i):s}})}sq={};promise;doc(e){return new O(this.client,this.collection,e)}clone(e){let t=new a(this.client,this.collection);return t.sq={...this.sq,...e},t}normalizeFilterValue(e,t){return e==="in"||e==="not-in"||e==="array-contains-any"?Array.isArray(t)?t:[t]:t}normalizeFilter(e){return {...e,value:this.normalizeFilterValue(e.op,e.value)}}toQueryFilters(e){return V(e).map(t=>this.normalizeFilter(t))}appendOperatorFilter(e,t,i,r){return this.appendFilters([this.normalizeFilter({field:e,op:t,value:i})],r)}appendAndFilters(e){return this.clone({where:[...this.sq.where??[],...e]})}toOrNode(e){return {or:e}}toAndNode(e){return {and:e}}isLeafFilter(e){return !("or"in e)&&!("and"in e)}isIdentityGuard(e){return this.isLeafFilter(e)?(e.field==="id"||e.field==="_id")&&e.op==="==":false}splitIdentityGuards(e){let t=[],i=[];for(let r of e){if(this.isIdentityGuard(r)){t.push(r);continue}i.push(r);}return {guards:t,rest:i}}appendOrFilters(e){let t=[...this.sq.where??[]];if(t.length===0)return this.clone({where:[this.toOrNode(e)]});let i=t[0];if(t.length===1&&typeof i=="object"&&i!=null&&"or"in i){let d=i;return this.clone({where:[{or:[...d.or,...e]}]})}let{guards:n,rest:s}=this.splitIdentityGuards(t);if(n.length>0){let d=s.length===0?void 0:s.length===1?s[0]:{and:s},l=d?[{or:[d,...e]}]:[{or:[...e]}];return this.clone({where:[...n,...l]})}let o=t.length===1?t[0]:{and:t};return this.clone({where:[{or:[o,...e]}]})}appendFilters(e,t){return t==="or"?this.appendOrFilters(e):this.appendAndFilters(e)}with(e,t={}){return this.client.applyQueryPreset(this,e,t)}where(e){return this.appendFilters(this.toQueryFilters(e),"and")}and(e){return this.appendFilters(this.toQueryFilters(e),"and")}or(e){return this.appendFilters(this.toQueryFilters(e),"or")}in(e,t){return this.appendOperatorFilter(e,"in",t,"and")}andIn(e,t){return this.appendOperatorFilter(e,"in",t,"and")}orIn(e,t){return this.appendOperatorFilter(e,"in",t,"or")}notIn(e,t){return this.appendOperatorFilter(e,"not-in",t,"and")}andNotIn(e,t){return this.appendOperatorFilter(e,"not-in",t,"and")}orNotIn(e,t){return this.appendOperatorFilter(e,"not-in",t,"or")}arrayContains(e,t){return this.appendOperatorFilter(e,"array-contains",t,"and")}andArrayContains(e,t){return this.appendOperatorFilter(e,"array-contains",t,"and")}orArrayContains(e,t){return this.appendOperatorFilter(e,"array-contains",t,"or")}arrayContainsAny(e,t){return this.appendOperatorFilter(e,"array-contains-any",t,"and")}andArrayContainsAny(e,t){return this.appendOperatorFilter(e,"array-contains-any",t,"and")}orArrayContainsAny(e,t){return this.appendOperatorFilter(e,"array-contains-any",t,"or")}some(e,t){return this.appendOperatorFilter(e,"elem-match",t,"and")}andSome(e,t){return this.appendOperatorFilter(e,"elem-match",t,"and")}orSome(e,t){return this.appendOperatorFilter(e,"elem-match",t,"or")}like(e,t){return this.appendOperatorFilter(e,"like",t,"and")}andLike(e,t){return this.appendOperatorFilter(e,"like",t,"and")}orLike(e,t){return this.appendOperatorFilter(e,"like",t,"or")}notLike(e,t){return this.appendOperatorFilter(e,"not-like",t,"and")}andNotLike(e,t){return this.appendOperatorFilter(e,"not-like",t,"and")}orNotLike(e,t){return this.appendOperatorFilter(e,"not-like",t,"or")}exists(e){return this.appendOperatorFilter(e,"exists",true,"and")}andExists(e){return this.appendOperatorFilter(e,"exists",true,"and")}orExists(e){return this.appendOperatorFilter(e,"exists",true,"or")}notExists(e){return this.appendOperatorFilter(e,"not-exists",true,"and")}andNotExists(e){return this.appendOperatorFilter(e,"not-exists",true,"and")}orNotExists(e){return this.appendOperatorFilter(e,"not-exists",true,"or")}latest(){return this.clone({orderBy:[...this.sq.orderBy??[],{field:"_seq",dir:"desc"}]})}newest(){return this.clone({orderBy:[...this.sq.orderBy??[],{field:"_seq",dir:"desc"}]})}oldest(){return this.clone({orderBy:[...this.sq.orderBy??[],{field:"_seq",dir:"asc"}]})}orderBy(e,t="asc"){return this.clone({orderBy:[...this.sq.orderBy??[],{field:e,dir:t}]})}limit(e){return this.clone({limit:e})}offset(e){return this.clone({offset:e})}startAt(...e){return this.clone({startAt:{values:e}})}startAfter(...e){return this.clone({startAfter:{values:e}})}endAt(...e){return this.clone({endAt:{values:e}})}endBefore(...e){return this.clone({endBefore:{values:e}})}aggregate(...e){return this.clone({aggregate:[...this.sq.aggregate??[],...e]})}count(e="count"){return this.aggregate({fn:"count",alias:e})}sum(e,t){return this.aggregate({fn:"sum",field:e,alias:t??`sum_${e}`})}avg(e,t){return this.aggregate({fn:"avg",field:e,alias:t??`avg_${e}`})}min(e,t){return this.aggregate({fn:"min",field:e,alias:t??`min_${e}`})}max(e,t){return this.aggregate({fn:"max",field:e,alias:t??`max_${e}`})}distinct(e,t){return this.aggregate({fn:"distinct",field:e,alias:t??`distinct_${e}`})}groupBy(...e){return this.clone({groupBy:{fields:e}})}having(e,t,i){return this.clone({having:[...this.sq.having??[],{field:e,op:t,value:i}]})}buildStructuredJoin(e,t){let r={from:String(e??""),localField:String(t?.source??""),foreignField:String(t?.target??""),as:String(t?.as??""),single:t?.single};return Array.isArray(t?.where)&&(r.where=t.where),Array.isArray(t?.orderBy)&&(r.orderBy=t.orderBy),typeof t?.limit=="number"&&(r.limit=t.limit),typeof t?.offset=="number"&&(r.offset=t.offset),t?.startAt&&(r.startAt=t.startAt),t?.startAfter&&(r.startAfter=t.startAfter),t?.endAt&&(r.endAt=t.endAt),t?.endBefore&&(r.endBefore=t.endBefore),Array.isArray(t?.aggregate)&&(r.aggregate=t.aggregate),t?.groupBy&&(r.groupBy=t.groupBy),Array.isArray(t?.having)&&(r.having=t.having),t?.vectorSearch&&(r.vectorSearch=t.vectorSearch),Array.isArray(t?.select)&&(r.select=t.select),typeof t?.distinctField=="string"&&(r.distinctField=t.distinctField),Array.isArray(t?.joins)&&(r.joins=t.joins.map(n=>this.buildStructuredJoin(String(n?.collection??""),n))),r}cloneStructuredJoin(e){let t={...e};return Array.isArray(e.where)&&(t.where=e.where.map(i=>({...i}))),Array.isArray(e.orderBy)&&(t.orderBy=e.orderBy.map(i=>({...i}))),Array.isArray(e.aggregate)&&(t.aggregate=e.aggregate.map(i=>({...i}))),Array.isArray(e.having)&&(t.having=e.having.map(i=>({...i}))),Array.isArray(e.select)&&(t.select=[...e.select]),e.groupBy?.fields&&(t.groupBy={fields:[...e.groupBy.fields]}),e.startAt?.values&&(t.startAt={values:[...e.startAt.values]}),e.startAfter?.values&&(t.startAfter={values:[...e.startAfter.values]}),e.endAt?.values&&(t.endAt={values:[...e.endAt.values]}),e.endBefore?.values&&(t.endBefore={values:[...e.endBefore.values]}),Array.isArray(e.joins)&&(t.joins=e.joins.map(i=>this.cloneStructuredJoin(i))),t}appendNestedJoinByAlias(e,t,i){for(let r of e){if(r.as===t)return r.joins=[...r.joins??[],i],true;if(Array.isArray(r.joins)&&this.appendNestedJoinByAlias(r.joins,t,i))return true}return false}parseRelationRef(e){let i=String(e??"").trim().match(/^([A-Za-z0-9_.]+)\s*->\s*([A-Za-z0-9_]+)\.([A-Za-z0-9_.]+)(?:\s+as\s+([A-Za-z0-9_]+))?$/i);if(!i)throw new Error(`Invalid relation format: "${e}". Expected "source.path->collection.target"`);return {source:i[1],collection:i[2],target:i[3],alias:i[4]}}join(e,t){let i=this.buildStructuredJoin(e,t);return this.clone({joins:[...this.sq.joins??[],i]})}joinNested(e,t,i){let r=String(e??"").trim();if(!r)throw new Error("joinNested requires parentAlias");let n=(this.sq.joins??[]).map(o=>this.cloneStructuredJoin(o));if(n.length===0)throw new Error(`joinNested parent alias "${r}" not found`);let s=this.buildStructuredJoin(t,i);if(!this.appendNestedJoinByAlias(n,r,s))throw new Error(`joinNested parent alias "${r}" not found`);return this.clone({joins:n})}Join(e,t){return this.join(e,t)}JoinNested(e,t,i){return this.joinNested(e,t,i)}withRelation(e,t={}){let i=this.parseRelationRef(e);return this.join(i.collection,{...t,source:i.source,target:i.target,as:t.as??i.alias??i.collection})}select(...e){return this.clone({select:e})}distinctField(e){return this.clone({distinctField:e})}vectorSearch(e){return this.clone({vectorSearch:e})}getRawQuery(){let e={...this.sq};return Array.isArray(this.sq.where)&&(e.where=this.sq.where.map(t=>({...t}))),Array.isArray(this.sq.orderBy)&&(e.orderBy=this.sq.orderBy.map(t=>({...t}))),Array.isArray(this.sq.aggregate)&&(e.aggregate=this.sq.aggregate.map(t=>({...t}))),Array.isArray(this.sq.having)&&(e.having=this.sq.having.map(t=>({...t}))),Array.isArray(this.sq.select)&&(e.select=[...this.sq.select]),Array.isArray(this.sq.joins)&&(e.joins=this.sq.joins.map(t=>this.cloneStructuredJoin(t))),this.sq.groupBy?.fields&&(e.groupBy={fields:[...this.sq.groupBy.fields]}),this.sq.startAt?.values&&(e.startAt={values:[...this.sq.startAt.values]}),this.sq.startAfter?.values&&(e.startAfter={values:[...this.sq.startAfter.values]}),this.sq.endAt?.values&&(e.endAt={values:[...this.sq.endAt.values]}),this.sq.endBefore?.values&&(e.endBefore={values:[...this.sq.endBefore.values]}),{collection:this.collection,query:e}}async get(){return this._execute()}async first(){let e=await this._execute();return e.length>0?e[0]:null}async last(){let e=await this._execute();return e.length>0?e[e.length-1]:null}_isStructured(){return !!(this.sq.orderBy?.length||this.sq.aggregate?.length||this.sq.groupBy||this.sq.having?.length||this.sq.joins?.length||this.sq.vectorSearch||this.sq.distinctField||this.sq.offset||this.sq.startAt||this.sq.startAfter||this.sq.endAt||this.sq.endBefore||this.sq.select?.length)}async _execute(){return this._isStructured()?this._executeQuery():this._executeSubscribe()}async _executeQuery(){return (await this.client.send("query",{collection:this.collection,query:this.sq})).data??[]}async _executeSubscribe(){let e=uuid2(18);return new Promise((t,i)=>{let r=Object.keys(this.sq).length>0?this.sq:void 0,n=this.client.subscribe(e,this.collection,void 0,r,s=>{s.type==="snapshot"&&(n(),t(s.data));});setTimeout(()=>{n(),i(new Error("Collection fetch timeout"));},1e4);})}then(e,t){return this.promise||(this.promise=this._execute()),this.promise.then(e,t)}onSnapshot(e){let t=uuid2(18),i=Object.keys(this.sq).length>0?this.sq:void 0,r=(()=>{});return r=this.client.subscribe(t,this.collection,void 0,i,n=>{n.type==="snapshot"&&(e(n),r());}),r}stream(e={}){let t=uuid2(18),i=Object.keys(this.sq).length>0?this.sq:void 0,r=new Set,n=[],s=new Map,o=Math.max(0,Number(e.flushMs??24)),d=Math.max(1,Number(e.maxBatchSize??200)),l=e.insertAt??"end",f=typeof e.maxDocs=="number"&&e.maxDocs>0?Math.floor(e.maxDocs):void 0,y=String(e.idField??"id"),c=[],w=false,C=false,F=0,P,I=()=>{s.clear();for(let p=0;p<c.length;p+=1){let m=$(c[p]);m&&s.set(m,p);}},$=(p,m)=>{if(m)return m;if(p==null)return;if(typeof e.getId=="function"){let R=e.getId(p);if(typeof R=="string"&&R.length>0)return R}let A=p?.[y]??p?._id??p?.docId;if(typeof A=="string"&&A.length>0)return A},E=()=>{f==null||c.length<=f||(c=c.slice(0,f));},M=()=>{typeof e.sort=="function"&&(c=c.slice().sort(e.sort));},Q=(p,m)=>{F+=1;let A=c.slice(),R={reason:p,batchSize:m,version:F,ready:C};for(let _ of Array.from(r))try{_(A,R);}catch{}},S=()=>{P!=null&&(clearTimeout(P),P=void 0);},g=p=>{if(p.operation==="delete"){let _=s.get(p.docId);if(_==null)return;c.splice(_,1),I();return}let m=p.data;if(m==null)return;let A=$(m,p.docId);if(!A)return;let R=s.get(A);if(typeof R=="number"){c[R]=m;return}l==="start"?c.unshift(m):c.push(m),E(),I();},N=()=>{if(w||n.length===0)return;S();let p=n.splice(0,n.length);for(let m of p)g(m);M(),I(),Q("change-batch",p.length);},K=()=>{w||P!=null||(P=setTimeout(N,o));},J=this.client.subscribe(t,this.collection,void 0,i,p=>{if(!w){if(p.type==="snapshot"){c=Array.isArray(p.data)?[...p.data]:[],C=true,S(),n.length=0,M(),E(),I(),Q("snapshot",0);return}if(n.push(p),n.length>=d){N();return}K();}}),j={subscribe(p,m=true){if(r.add(p),m){let A={reason:C?"change-batch":"snapshot",batchSize:0,version:F,ready:C};try{p(c.slice(),A);}catch{}}return ()=>{r.delete(p);}},getSnapshot(){return c.slice()},isReady(){return C},getVersion(){return F},close:()=>{w||(w=true,S(),n.length=0,r.clear(),J());},onError(p){return J.onError(p),j},onPermissionDenied(p){return J.onPermissionDenied(p),j}};return j}asStore(e={}){let t=this.stream(e);return {subscribe:i=>t.subscribe(()=>{i();},false),getSnapshot:()=>t.getSnapshot(),getServerSnapshot:()=>[],stream:t,destroy:()=>{t.close();}}}onDocAdded(e){let t=uuid2(18),i=Object.keys(this.sq).length>0?this.sq:void 0;return this.client.subscribe(t,this.collection,void 0,i,r=>{r.type==="change"&&r.operation==="insert"&&r.data!=null&&e(r.data,r.docId);},{skipSnapshot:true})}onDocUpdated(e){let t=uuid2(18),i=Object.keys(this.sq).length>0?this.sq:void 0;return this.client.subscribe(t,this.collection,void 0,i,r=>{r.type==="change"&&(r.operation==="update"||r.operation==="replace")&&r.data!=null&&e(r.data,r.docId);},{skipSnapshot:true})}onDocDeleted(e){let t=uuid2(18),i=Object.keys(this.sq).length>0?this.sq:void 0;return this.client.subscribe(t,this.collection,void 0,i,r=>{r.type==="change"&&r.operation==="delete"&&e(r.docId);},{skipSnapshot:true})}onDocChanged(e){let t=uuid2(18),i=Object.keys(this.sq).length>0?this.sq:void 0;return this.client.subscribe(t,this.collection,void 0,i,r=>{r.type==="change"&&e(r.data??null,r.docId,r.operation);},{skipSnapshot:true})}async add(e){let t=uuid2(18),i=this.doc(t);return await i.set(e),i}update(e){return new v(this.client,this.collection).update(e)}delete(){return new v(this.client,this.collection).delete()}},Y=G;async function de(a){let e=a.replace(/-----BEGIN PUBLIC KEY-----/,"").replace(/-----END PUBLIC KEY-----/,"").replace(/\s+/g,""),t=typeof atob<"u"?atob(e):Buffer.from(e,"base64").toString("binary"),i=new Uint8Array(t.length);for(let n=0;n<t.length;n++)i[n]=t.charCodeAt(n);return (globalThis.crypto??(await import('crypto')).webcrypto).subtle.importKey("spki",i.buffer,{name:"RSA-OAEP",hash:"SHA-256"},false,["encrypt"])}async function le(a,e){let t=await de(e),i=new TextEncoder().encode(JSON.stringify(a)),n=await(globalThis.crypto??(await import('crypto')).webcrypto).subtle.encrypt({name:"RSA-OAEP"},t,i),s=typeof btoa<"u"?btoa(String.fromCharCode(...new Uint8Array(n))):Buffer.from(n).toString("base64");return JSON.stringify({enc:"rsa",data:s})}var q=class{socket=null;reconnectInterval;maxReconnectDelay;isConnected=false;shouldReconnect=true;options;messageQueue=[];heartbeatInterval=null;connectionTimeout=null;constructor(e){this.options=e,this.reconnectInterval=e.reconnectDelay||2,this.maxReconnectDelay=e.maxReconnectDelay||60,this.log("Transport initialized",e.url);}connect(){if(this.socket){this.log("Socket already exists, skipping connection");return}this.log("Connecting to",this.options.url),this.socket=new WebSocket(this.options.url),this.connectionTimeout=setTimeout(()=>{this.isConnected||(this.log("Connection timeout"),this.socket?.close(),this.handleReconnect());},1e4),this.socket.onopen=()=>{this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.isConnected=true,this.reconnectInterval=this.options.reconnectDelay||2,this.log("Connected to server"),this.options.onOpen?.(),this.startHeartbeat(),this.flushQueue();},this.socket.onmessage=e=>{try{let t=JSON.parse(e.data);this.options.onMessage(t);}catch(t){this.log("Parse error",t),this.options.onError?.(t);}},this.socket.onerror=e=>{this.log("WebSocket error",e),this.options.onError?.(new Error("WebSocket error"));},this.socket.onclose=e=>{this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.isConnected=false,this.socket=null,this.stopHeartbeat(),this.log("Connection closed",e.code,e.reason),this.options.onClose?.(),e.code!==1e3&&this.shouldReconnect&&this.options.autoReconnect&&this.handleReconnect();};}handleReconnect(){let e=this.reconnectInterval*1e3;this.log(`Reconnecting in ${this.reconnectInterval}s...`),setTimeout(()=>{this.reconnectInterval=Math.min(this.reconnectInterval*2,this.maxReconnectDelay),this.connect();},e);}startHeartbeat(){this.heartbeatInterval=setInterval(()=>{this.isConnected&&this.send({type:"ping",id:Date.now().toString(),ts:Date.now()});},3e4);}stopHeartbeat(){this.heartbeatInterval&&(clearInterval(this.heartbeatInterval),this.heartbeatInterval=null);}flushQueue(){for(this.log("Flushing message queue",this.messageQueue.length);this.messageQueue.length>0;){let e=this.messageQueue.shift();e&&this.send(e);}}send(e){if(this.socket&&this.socket.readyState===WebSocket.OPEN){let t=i=>{try{this.socket.send(i),this.log("Sent message",e);}catch(r){this.log("Send error",r),this.messageQueue.push(e);}};this.options.publicKey?le(e,this.options.publicKey).then(t).catch(i=>{this.log("RSA encrypt error \u2014 sending plaintext",i),t(JSON.stringify(e));}):t(JSON.stringify(e));}else this.log("Socket not ready, queueing message"),this.messageQueue.push(e);}disconnect(){this.shouldReconnect=false,this.stopHeartbeat(),this.socket&&(this.socket.close(1e3,"Client disconnect"),this.socket=null),this.isConnected=false,this.log("Disconnected");}get connected(){return this.isConnected}log(...e){this.options.debug&&console.log("[FlareTransport]",...e);}};var me={id:"_id",createdAt:"_createdAt",updatedAt:"_updatedAt"},re={_id:"id",_createdAt:"createdAt",_updatedAt:"updatedAt"},D=class{transport;config;pendingAcks=new Map;subscriptions=new Map;activeSubscriptions=new Map;queryPresets=new Map;subscriptionErrorHandlers=new Map;subscriptionPermissionHandlers=new Map;subscriptionLastErrors=new Map;offlineQueue=[];currentState="disconnected";connectionListeners=[];errorListeners=[];isDebug=false;socketAuthUid="anon";pendingSubscriptionReplay=false;subscriptionReplayPromise=Promise.resolve();requestTraceSeq=0;requestTimingEnabled=true;httpInFlight=new Map;httpResponseCache=new Map;maxHttpCacheEntries=200;presenceCallbacks=new Map;presenceJoinCbs=new Map;presenceLeaveCbs=new Map;presenceHeartbeatTimer;embedder;vectorSchema=new Map;throwFetchFlareError(e,t,i){let r=e,n=typeof r?.error=="string"&&r.error.length>0?r.error:i,s=typeof r?.message=="string"&&r.message.length>0?r.message:t;throw new h(s,n,e)}nowMs(){return typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now()}normalizeHeaders(e){if(!e)return {};let t={};if(e instanceof Headers)e.forEach((i,r)=>{t[r]=i;});else if(Array.isArray(e))for(let[i,r]of e)t[String(i)]=String(r);else for(let[i,r]of Object.entries(e))t[String(i)]=String(r);return t}redactHeaders(e){let t={...e};for(let i of Object.keys(t)){let r=i.toLowerCase();(r==="authorization"||r==="x-flare-csrf"||r==="x-csrf-token")&&(t[i]="[redacted]");}return t}stableStringify(e){if(e==null)return "";if(typeof e=="string")return e;if(typeof URLSearchParams<"u"&&e instanceof URLSearchParams)return e.toString();if(typeof e!="object")return String(e);if(Array.isArray(e))return `[${e.map(r=>this.stableStringify(r)).join(",")}]`;let t=e;return `{${Object.keys(t).sort().map(r=>`${r}:${this.stableStringify(t[r])}`).join(",")}}`}buildHttpCacheKey(e,t,i,r,n){let o=Object.entries(i).map(([l,f])=>[l.toLowerCase(),f]).sort(([l],[f])=>l.localeCompare(f)).map(([l,f])=>`${l}:${f}`).join("|"),d=this.stableStringify(r);return `${e}|${t}|${n??""}|${o}|${d}`}shouldCacheResponse(e,t){return !!(e==="GET"||e==="POST"&&/\/auth\/refresh(?:\?|$)/.test(t))}rememberHttpResponse(e,t){if(this.httpResponseCache.set(e,t),this.httpResponseCache.size<=this.maxHttpCacheEntries)return;let i=this.httpResponseCache.keys().next().value;i&&this.httpResponseCache.delete(i);}createTimedFetchTrace(e,t,i,r,n,s){return {response:{status:e.status,ok:e.status>=200&&e.status<300,headers:{get:o=>{let d=o.toLowerCase();for(let[l,f]of Object.entries(e.headers))if(l.toLowerCase()===d)return String(f);return null}},json:async()=>e.data??{}},requestId:t,startedAtMs:i,networkMs:s,method:r,url:n}}logHttpTiming(...e){this.requestTimingEnabled&&this.log("[FlareClient][http]",...e);}mergeHeaders(e,t){if(!e)return t;if(e instanceof Headers){let i=new Headers(e);for(let[r,n]of Object.entries(t))i.set(r,n);return i}return Array.isArray(e)?[...e,...Object.entries(t)]:{...e,...t}}toWireField(e){let t=String(e??"").trim();return t&&(me[t]??t)}fromWireField(e){let t=String(e??"").trim();return t&&(re[t]?re[t]:t.startsWith("_")&&!t.startsWith("__")&&t.length>1?t.slice(1):t)}normalizeOutboundData(e){if(Array.isArray(e))return e.map(r=>this.normalizeOutboundData(r));if(!e||typeof e!="object")return e;let t=e,i={};for(let[r,n]of Object.entries(t))i[this.toWireField(r)]=this.normalizeOutboundData(n);return i}normalizeInboundData(e){if(Array.isArray(e))return e.map(r=>this.normalizeInboundData(r));if(!e||typeof e!="object")return e;let t=e,i={};for(let[r,n]of Object.entries(t))i[this.fromWireField(r)]=this.normalizeInboundData(n);return i}normalizeOutboundAnyFilter(e){return Array.isArray(e.or)?{...e,or:e.or.map(t=>this.normalizeOutboundAnyFilter(t))}:Array.isArray(e.and)?{...e,and:e.and.map(t=>this.normalizeOutboundAnyFilter(t))}:typeof e.field=="string"?{...e,field:this.toWireField(e.field)}:{...e}}normalizeOutboundQuery(e){if(!e||typeof e!="object")return e;let t=e,i={...t},r=n=>{let s={...n};return s.localField=this.toWireField(String(n?.localField??"")),s.foreignField=this.toWireField(String(n?.foreignField??"")),Array.isArray(n.where)&&(s.where=n.where.map(o=>this.normalizeOutboundAnyFilter(o))),Array.isArray(n.orderBy)&&(s.orderBy=n.orderBy.map(o=>({...o,field:this.toWireField(String(o?.field??""))}))),n.groupBy&&typeof n.groupBy=="object"&&Array.isArray(n.groupBy.fields)&&(s.groupBy={...n.groupBy,fields:n.groupBy.fields.map(o=>this.toWireField(String(o??"")))}),Array.isArray(n.having)&&(s.having=n.having.map(o=>({...o,field:this.toWireField(String(o?.field??""))}))),Array.isArray(n.select)&&(s.select=n.select.map(o=>this.toWireField(String(o??"")))),typeof n.distinctField=="string"&&(s.distinctField=this.toWireField(n.distinctField)),n.vectorSearch&&typeof n.vectorSearch=="object"&&(s.vectorSearch={...n.vectorSearch,field:this.toWireField(String(n.vectorSearch.field??""))}),Array.isArray(n.joins)&&(s.joins=n.joins.map(o=>r(o))),s};return Array.isArray(t.where)&&(i.where=t.where.map(n=>this.normalizeOutboundAnyFilter(n))),Array.isArray(t.orderBy)&&(i.orderBy=t.orderBy.map(n=>({...n,field:this.toWireField(String(n?.field??""))}))),t.groupBy&&typeof t.groupBy=="object"&&Array.isArray(t.groupBy.fields)&&(i.groupBy={...t.groupBy,fields:t.groupBy.fields.map(n=>this.toWireField(String(n??"")))}),Array.isArray(t.having)&&(i.having=t.having.map(n=>({...n,field:this.toWireField(String(n?.field??""))}))),Array.isArray(t.select)&&(i.select=t.select.map(n=>this.toWireField(String(n??"")))),typeof t.distinctField=="string"&&(i.distinctField=this.toWireField(t.distinctField)),t.vectorSearch&&typeof t.vectorSearch=="object"&&(i.vectorSearch={...t.vectorSearch,field:this.toWireField(String(t.vectorSearch.field??""))}),Array.isArray(t.joins)&&(i.joins=t.joins.map(n=>r(n))),i}async timedFetch(e,t,i){let r=++this.requestTraceSeq,n=this.nowMs(),s=String(i?.method??"GET").toUpperCase(),o=this.normalizeHeaders(i?.headers),d=this.redactHeaders(o),l=i?.body,f=this.buildHttpCacheKey(s,t,o,l,i?.credentials),y=this.shouldCacheResponse(s,t);this.logHttpTiming(`#${r} ${e} start`,{method:s,url:t,headers:d,hasBody:!!i?.body});try{if(y){let S=this.httpResponseCache.get(f);if(S)return this.logHttpTiming(`#${r} ${e} cache-hit`,{method:s,url:t}),this.createTimedFetchTrace(S,r,n,s,t,0)}let c=this.httpInFlight.get(f);if(c){let S=await c,g=this.nowMs()-n;return this.logHttpTiming(`#${r} ${e} deduped`,{method:s,url:t,networkMs:Number(g.toFixed(2))}),this.createTimedFetchTrace(S,r,n,s,t,g)}let w=this.mergeHeaders(i?.headers,{"x-flare-request-id":String(r)}),C=this.normalizeHeaders(w),F=this.redactHeaders(C),P={timeout:Math.ceil((this.config.connectionTimeout??1e4)/1e3),ignoreKind:!0,headers:C,withCredentials:i?.credentials==="include",returnRawResponse:!0,appendCookiesToBody:!1,appendTimestamp:!1};this.logHttpTiming(`#${r} ${e} request`,{method:s,url:t,headers:F,hasBody:!!i?.body});let I=s.toUpperCase(),E=(async()=>{let S=I==="GET"?await withGet(t,P):I==="PUT"?await withPut(t,l,P):I==="PATCH"?await withPatch(t,l,P):await withPost(t,l,P),g={status:Number(S?.status??0),headers:Object.fromEntries(Object.entries(S?.headers??{}).map(([N,K])=>[N,String(K)])),data:S?.data??{}};return y&&this.rememberHttpResponse(f,g),g})();this.httpInFlight.set(f,E);let M=await E.finally(()=>{this.httpInFlight.delete(f);}),Q=this.nowMs()-n;return this.logHttpTiming(`#${r} ${e} response`,{status:M.status,networkMs:Number(Q.toFixed(2))}),this.createTimedFetchTrace(M,r,n,s,t,Q)}catch(c){let w=this.nowMs()-n;throw this.logHttpTiming(`#${r} ${e} failed`,{networkMs:Number(w.toFixed(2)),message:c?.message??String(c)}),c}}async parseJsonWithTiming(e,t){let i=this.nowMs(),r=await t.response.json().catch(()=>({})),n=this.nowMs()-i,s=this.nowMs()-t.startedAtMs;return this.logHttpTiming(`#${t.requestId} ${e} complete`,{method:t.method,url:t.url,status:t.response.status,networkMs:Number(t.networkMs.toFixed(2)),parseMs:Number(n.toFixed(2)),totalMs:Number(s.toFixed(2))}),r}getHttpBase(){if(this.config.httpBase)return this.config.httpBase.replace(/\/$/,"");let e=new URL(this.config.endpoint);return `${e.protocol}//${e.host}`}log(...e){this.isDebug&&console.log("[FlareClient]",...e);}constructor(e){this.config={autoReconnect:true,reconnectDelay:2,maxReconnectDelay:60,debug:false,connectionTimeout:1e4,...e},this.isDebug=this.config.debug||false,this.requestTimingEnabled=this.config.requestTiming??true;let{hostname:t,port:i,protocol:r}=new URL(this.config.endpoint),n=r==="https:",d=`${n?"wss":"ws"}://${t}:${i||(n?"443":"80")}/?appId=${this.config.appId}${this.config.apiKey?`&apiKey=${this.config.apiKey}`:""}`;this.transport=new q({url:d,publicKey:this.config.publicKey,autoReconnect:this.config.autoReconnect,reconnectDelay:this.config.reconnectDelay,maxReconnectDelay:this.config.maxReconnectDelay,onMessage:l=>this.handleIncoming(l),onOpen:()=>this.onConnected(),onClose:()=>this.onDisconnected(),onError:l=>this.handleTransportError(l),debug:this.isDebug});}connect(){this.setState("connecting"),this.transport.connect();}disconnect(){this.transport.disconnect(),this.setState("disconnected");}get connectionState(){return this.currentState}get isConnected(){return this.currentState==="connected"}onConnectionStateChange(e){return this.connectionListeners.push(e),()=>{this.connectionListeners=this.connectionListeners.filter(t=>t!==e);}}onError(e){return this.errorListeners.push(e),()=>{this.errorListeners=this.errorListeners.filter(t=>t!==e);}}collection(e){return new Y(this,e)}registerQueryPreset(e,t){let i=String(e??"").trim();if(!i)throw new h("Preset name is required",u.QueryFailed);if(typeof t!="function")throw new h(`Query preset "${i}" handler must be a function`,u.QueryFailed);return this.queryPresets.set(i,t),this}registerQueryPresets(e){for(let[t,i]of Object.entries(e??{}))this.registerQueryPreset(t,i);return this}hasQueryPreset(e){return this.queryPresets.has(String(e??"").trim())}applyQueryPreset(e,t,i={}){let r=String(t??"").trim(),n=this.queryPresets.get(r);if(!n)throw new h(`Unknown query preset "${r}"`,u.QueryFailed);let s=n(e,i??{});if(!s||typeof s.get!="function")throw new h(`Query preset "${r}" must return a CollectionReference`,u.QueryFailed);return s}doc(e,t){return t!==void 0?new O(this,e,t):new v(this,e)}async ping(){let e=Date.now();return await this.send("ping",{}),Date.now()-e}async call(e,t={}){let i=await this.send("call",{topic:e,payload:t});if(!i.success)throw new h(i.error??`CALL "${e}" failed`,u.QueryFailed);return i.result}async query(e,t={}){return (await this.send("query",{collection:e,query:t})).data??[]}setEmbedder(e){this.embedder=e;}markVectorField(e,t,i={dimensions:1536}){this.vectorSchema.has(e)||this.vectorSchema.set(e,new Map),this.vectorSchema.get(e).set(t,i);}async embedVectorFields(e,t){let i=this.vectorSchema.get(e);if(!i)return t;let r={...t};for(let[n,s]of i){let o=r[n];if(typeof o=="string"){let d=s.embed??this.embedder;if(!d){this.log(`[vector] No embedder for field "${n}" \u2014 storing raw text`);continue}r[n]=await d(o);}}return r}async joinPresence(e,t){return await this.send("presence_join",{room:e,meta:t}),this._startPresenceHeartbeat(e,t),()=>this.leavePresence(e)}async leavePresence(e){await this.send("presence_leave",{room:e}),this._stopPresenceHeartbeat();}onPresenceState(e,t){return this.presenceCallbacks.has(e)||this.presenceCallbacks.set(e,[]),this.presenceCallbacks.get(e).push(t),()=>{let i=this.presenceCallbacks.get(e)??[];this.presenceCallbacks.set(e,i.filter(r=>r!==t));}}onPresenceJoin(e,t){return this.presenceJoinCbs.has(e)||this.presenceJoinCbs.set(e,[]),this.presenceJoinCbs.get(e).push(t),()=>{let i=this.presenceJoinCbs.get(e)??[];this.presenceJoinCbs.set(e,i.filter(r=>r!==t));}}onPresenceLeave(e,t){return this.presenceLeaveCbs.has(e)||this.presenceLeaveCbs.set(e,[]),this.presenceLeaveCbs.get(e).push(t),()=>{let i=this.presenceLeaveCbs.get(e)??[];this.presenceLeaveCbs.set(e,i.filter(r=>r!==t));}}_startPresenceHeartbeat(e,t){this.presenceHeartbeatTimer||(this.presenceHeartbeatTimer=setInterval(()=>{this.isConnected&&this.send("presence_heartbeat",{meta:t}).catch(()=>{});},2e4));}_stopPresenceHeartbeat(){this.presenceHeartbeatTimer&&(clearInterval(this.presenceHeartbeatTimer),this.presenceHeartbeatTimer=void 0);}async syncOffline(){if(this.offlineQueue.length===0)return;this.log("Syncing offline operations",this.offlineQueue.length);let e=[...this.offlineQueue];this.offlineQueue.length=0;let t=await this.send("offline_sync",{operations:e});t.conflicts&&t.conflicts.length>0&&(this.log("Offline sync conflicts",t.conflicts),t.conflicts.forEach(i=>{let r=e.find(n=>n.id===i.operationId);r&&this.offlineQueue.push(r);}));}async beforeActivateSubscription(e){}async activateSubscription(e){if(!this.isConnected){this.pendingSubscriptionReplay=true;return}await this.beforeActivateSubscription(e),this.subscriptions.set(e.liveId,e.callback);try{let t=await this.send("subscribe",{collection:e.collection,docId:e.docId,query:e.query,skipSnapshot:e.options.skipSnapshot});if(!this.activeSubscriptions.has(e.baseId)){this.subscriptions.delete(e.liveId);return}t.subscriptionId&&t.subscriptionId!==e.liveId&&(this.subscriptions.delete(e.liveId),e.liveId=t.subscriptionId,this.subscriptions.set(e.liveId,e.callback),this.log("Subscription remapped",e.baseId,"\u2192",e.liveId));}catch(t){this.subscriptions.delete(e.liveId),this.pendingSubscriptionReplay=true;let i=this.toSubscriptionError(t);this.emitSubscriptionError(e.baseId,i),this.log("Subscription failed",t);}}toSubscriptionError(e){let t=e instanceof Error?e.message:String(e??"Unknown subscription error"),i=t.match(/^\[([^\]]+)\]\s*(.*)$/),r=i?.[1],n=(i?.[2]??t).trim()||t,s=r===u.PermissionDenied||t.includes(u.PermissionDenied);return {code:r,message:n,permissionDenied:s,raw:e}}emitSubscriptionError(e,t){this.subscriptionLastErrors.set(e,t);let i=this.subscriptionErrorHandlers.get(e);if(i)for(let r of i)try{r(t);}catch(n){this.log("Subscription error callback failed",n);}if(t.permissionDenied){let r=this.subscriptionPermissionHandlers.get(e);if(r)for(let n of r)try{n(t);}catch(s){this.log("Subscription permission callback failed",s);}}}async replayActiveSubscriptions(){if(!this.isConnected){this.pendingSubscriptionReplay=true;return}let e=Array.from(this.activeSubscriptions.values());if(e.length===0){this.pendingSubscriptionReplay=false;return}this.pendingSubscriptionReplay=false,this.subscriptionReplayPromise=this.subscriptionReplayPromise.then(async()=>{for(let t of e){if(!this.activeSubscriptions.has(t.baseId))continue;let i=t.liveId;this.subscriptions.delete(i),t.liveId=t.baseId,i&&await this.send("unsubscribe",{subscriptionId:i}).catch(()=>{}),await this.activateSubscription(t);}}).catch(t=>{this.pendingSubscriptionReplay=true,this.log("Subscription replay failed",t);}),await this.subscriptionReplayPromise;}subscribe(e,t,i,r,n,s={}){this.log("Creating subscription",e,t,i);let o={baseId:e,liveId:e,collection:t,docId:i,query:r,callback:n,options:s};this.activeSubscriptions.set(e,o),this.subscriptionErrorHandlers.has(e)||this.subscriptionErrorHandlers.set(e,new Set),this.subscriptionPermissionHandlers.has(e)||this.subscriptionPermissionHandlers.set(e,new Set),this.activateSubscription(o).catch(f=>{this.log("Subscription activation failed",f);});let d=()=>{let y=this.activeSubscriptions.get(e)?.liveId??e;this.log("Unsubscribing",y),this.activeSubscriptions.delete(e),this.subscriptions.delete(y),this.subscriptionErrorHandlers.delete(e),this.subscriptionPermissionHandlers.delete(e),this.subscriptionLastErrors.delete(e),this.isConnected&&this.send("unsubscribe",{subscriptionId:y}).catch(c=>this.log("Unsubscribe failed",c));},l=d;return l.unsubscribe=d,l.onError=f=>{this.subscriptionErrorHandlers.get(e)?.add(f);let y=this.subscriptionLastErrors.get(e);if(y)try{f(y);}catch(c){this.log("Subscription error callback failed",c);}return l},l.onPermissionDenied=f=>{this.subscriptionPermissionHandlers.get(e)?.add(f);let y=this.subscriptionLastErrors.get(e);if(y?.permissionDenied)try{f(y);}catch(c){this.log("Subscription permission callback failed",c);}return l},l.catch=f=>l.onError(f),l}async send(e,t){if(e==="write"&&t.collection&&t.data){let i=await this.embedVectorFields(t.collection,t.data);t={...t,data:this.normalizeOutboundData(i)};}return (e==="subscribe"||e==="query")&&t?.query&&(t={...t,query:this.normalizeOutboundQuery(t.query)}),new Promise((i,r)=>{let n=uuid2(18),s={id:n,type:e,ts:Date.now(),...t};this.pendingAcks.set(n,o=>{o.type==="error"?r(new Error(`[${o.code}] ${o.message}`)):i(o);}),this.isConnected?this.transport.send(s):(this.log("Queueing message for offline",s),this.offlineQueue.push(s),r(new Error("Not connected - message queued"))),setTimeout(()=>{this.pendingAcks.has(n)&&(this.pendingAcks.delete(n),r(new Error("Request timeout")));},this.config.connectionTimeout);})}handleTransportError(e){this.log("Transport error",e),this.errorListeners.forEach(t=>{try{t(e);}catch(i){this.log("Error listener error",i);}});}onConnected(){this.setState("connected"),this.log("Connected to FlareServer"),this.activeSubscriptions.size>0&&(this.pendingSubscriptionReplay=true),this.offlineQueue.length>0&&this.syncOffline().catch(e=>{this.log("Offline sync failed",e);});}onDisconnected(){this.currentState!=="disconnected"&&this.setState("reconnecting"),this.activeSubscriptions.size>0&&(this.pendingSubscriptionReplay=true),this.log("Disconnected from FlareServer");}setState(e){this.currentState!==e&&(this.currentState=e,this.log("Connection state changed",e),this.connectionListeners.forEach(t=>{try{t(e);}catch(i){this.log("Connection listener error",i);}}));}handleIncoming(e){if(this.log("Received message",e.type,e),e.type==="query_result"&&Array.isArray(e.data)&&(e={...e,data:this.normalizeInboundData(e.data)}),e.type==="ack"||e.type==="pong"||e.type==="auth_ok"||e.type==="call_response"||e.type==="query_result"){let t=this.pendingAcks.get(e.correlationId||e.id);t&&(t(e),this.pendingAcks.delete(e.correlationId||e.id));return}if(e.type==="error"){this.log("Server error",e.code,e.message);let t=new Error(`[${e.code}] ${e.message}`);this.errorListeners.forEach(r=>{try{r(t);}catch(n){this.log("Error listener error",n);}});let i=Array.from(this.activeSubscriptions.values()).find(r=>r.liveId===e.correlationId||r.baseId===e.correlationId);if(i&&this.emitSubscriptionError(i.baseId,{code:typeof e.code=="string"?e.code:void 0,message:String(e.message??"Subscription error"),permissionDenied:e.code===u.PermissionDenied,raw:e}),e.correlationId){let r=this.pendingAcks.get(e.correlationId);r&&(r(e),this.pendingAcks.delete(e.correlationId));}return}if(e.type==="presence_state"){(this.presenceCallbacks.get(e.room)??[]).forEach(i=>{try{i(e.members);}catch{}});return}if(e.type==="presence_join"){(this.presenceJoinCbs.get(e.room)??[]).forEach(i=>{try{i(e);}catch{}});return}if(e.type==="presence_leave"){(this.presenceLeaveCbs.get(e.room)??[]).forEach(i=>{try{i(e.uid);}catch{}});return}if(e.type==="snapshot"){let t=this.subscriptions.get(e.subscriptionId);if(t){let i=this.normalizeInboundData(Array.isArray(e.data)?e.data:e.data!=null?[e.data]:[]),r={type:"snapshot",subscriptionId:e.subscriptionId,collection:e.collection,data:Array.isArray(i)?i:[]};try{t(r);}catch(n){this.log("Subscription callback error",n);}}return}if(e.type==="change"){let t=this.subscriptions.get(e.subscriptionId);if(t){let i={type:"change",subscriptionId:e.subscriptionId,collection:e.collection,docId:e.docId,operation:e.operation,data:e.operation==="delete"?null:this.normalizeInboundData(e.data)};try{t(i);}catch(r){this.log("Subscription callback error",r);}}}}};var L=class extends D{authToken;userId;authGuard;authConfig;csrfToken;csrfInitPromise;csrfBootstrapAttempted=false;socketAuthSyncPromise;pushServiceWorkerInitPromise;authSession=null;authStateListeners=[];authConfigListeners=[];currentProfile=void 0;getDefaultCsrfCookieName(){return `__flare_csrf_${this.config.appId.replace(/[^a-zA-Z0-9_-]/g,"_")}`}getCsrfCookieName(){return this.authConfig?.cookie?.csrfTokenName??this.getDefaultCsrfCookieName()}getCsrfToken(){return this.getCookieValue(this.getCsrfCookieName())??this.csrfToken??null}getCookieValue(e){if(typeof document>"u")return null;let t=document.cookie.split(";").map(r=>r.trim()).find(r=>r.startsWith(`${e}=`)||r.startsWith(`${encodeURIComponent(e)}=`));if(!t)return null;let i=t.indexOf("=");return i>=0?decodeURIComponent(t.slice(i+1)):null}extractCsrfToken(e,t){let i=e,r=typeof i?.csrfToken=="string"?String(i.csrfToken):typeof i?.csrf_token=="string"?String(i.csrf_token):void 0;if(r)return r;if(!t)return;let n=t.headers.get("x-flare-csrf")??t.headers.get("x-csrf-token")??t.headers.get("csrf-token");return typeof n=="string"&&n.length>0?n:void 0}getCsrfHeaders(){let e=this.getCsrfToken();return e?{"x-flare-csrf":e}:{}}setCsrfToken(e){this.csrfToken=e,this.csrfBootstrapAttempted=true,this.log("CSRF token injected",{length:e.length});}async ensureCsrfProtection(){if(this.getCsrfToken()){this.csrfBootstrapAttempted=true;return}if(this.config.httpBase){this.csrfBootstrapAttempted=true;return}this.csrfBootstrapAttempted||(this.csrfInitPromise||(this.csrfBootstrapAttempted=true,this.csrfInitPromise=this.loadAuthConfig().then(()=>{}).finally(()=>{this.csrfInitPromise=void 0;})),await this.csrfInitPromise,this.getCsrfToken()||this.log("CSRF token unavailable after auth config load",{hasAuthConfig:!!this.authConfig,csrfCookieName:this.getCsrfCookieName()}));}async loadAuthConfig(){let e=this.getHttpBase(),t=new URLSearchParams({appId:this.config.appId});this.config.apiKey&&t.set("apiKey",this.config.apiKey);let i=`${e}/auth/config?${t.toString()}`,r=await this.timedFetch("loadAuthConfig",i,{credentials:"include",headers:this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}}),n=await this.parseJsonWithTiming("loadAuthConfig",r);return r.response.ok||this.throwFetchFlareError(n,"Failed to load auth config",u.QueryFailed),this.authConfig=n,this.csrfToken=this.extractCsrfToken(n,r.response)??this.csrfToken,this.authConfigListeners.forEach(s=>{try{s(this.authConfig);}catch(o){this.log("Auth config listener error",o);}}),this.authConfig}async fetchAuthConfig(){return this.authConfig?this.authConfig:this.loadAuthConfig()}onAuthConfigLoaded(e){return this.authConfigListeners.push(e),this.authConfig&&e(this.authConfig),()=>{this.authConfigListeners=this.authConfigListeners.filter(t=>t!==e);}}setProfile(e){this.currentProfile=e;}setAuthSession(e){this.authSession=e,e?(this.authToken=e.accessToken,this.userId=e.uid):(this.authToken=void 0,this.userId=void 0,this.currentProfile=void 0,this.httpResponseCache.clear(),this.httpInFlight.clear());let t=this.authSession?{...this.authSession,...this.currentProfile??{}}:null;this.authStateListeners.forEach(i=>{try{i(t);}catch(r){this.log("Auth state listener error",r);}});}onAuthStateChanged(e){this.authStateListeners.push(e);let t=this.authSession?{...this.authSession,...this.currentProfile??{}}:null;try{e(t);}catch(i){this.log("Auth state listener error during initialization",i);}return ()=>{this.authStateListeners=this.authStateListeners.filter(i=>i!==e);}}onAuthStateChange(e){return this.onAuthStateChanged(e)}get currentUser(){return this.currentProfile}getCurrentUser(){return this.currentUser}async syncSocketAuth(e){if(!this.isConnected)return;let t=await this.send("auth",e?{token:e}:{});if(t.type!=="auth_ok")throw new h("Socket auth sync failed",u.AuthenticationFailed);if(!e||t.uid==="anon"){this.authToken=void 0,this.userId=void 0,await this.updateSocketIdentity("anon");return}this.authToken=typeof t.token=="string"?t.token:e,this.userId=typeof t.uid=="string"?t.uid:this.userId,await this.updateSocketIdentity(typeof t.uid=="string"?t.uid:this.userId);}async updateSocketIdentity(e,t=false){let i=typeof e=="string"&&e.length>0?e:"anon",r=i!==this.socketAuthUid;this.socketAuthUid=i,(r||t||this.pendingSubscriptionReplay)&&this.activeSubscriptions.size>0&&await this.replayActiveSubscriptions();}async beforeActivateSubscription(e){if(!this.isConnected)return;let t=this.authSession;!t?.accessToken||!t.uid||this.socketAuthUid!==t.uid&&(this.socketAuthSyncPromise||(this.socketAuthSyncPromise=this.syncSocketAuth(t.accessToken).catch(i=>{throw this.log("Socket auth sync failed before subscribe",i),i}).finally(()=>{this.socketAuthSyncPromise=void 0;})),await this.socketAuthSyncPromise);}onConnected(){super.onConnected(),this.authSession?.accessToken&&this.syncSocketAuth(this.authSession.accessToken).catch(e=>{this.log("Socket auth sync failed after connect",e);});}handleIncoming(e){if(e.type==="auth_ok"&&!e.correlationId){let t=typeof e.token=="string"?e.token:void 0,i=typeof e.uid=="string"?e.uid:void 0;this.updateSocketIdentity(i,this.pendingSubscriptionReplay).catch(r=>{this.log("Socket identity update failed",r);}),t&&i&&i!=="anon"&&i!=="__admin__"?this.fetchAuthMe(t).then(r=>{this.setAuthSession({uid:i,accessToken:t,refreshToken:this.authSession?.refreshToken??null,email:r?.email??null,emailVerified:r?.email_verified});}).catch(()=>{this.setAuthSession({uid:i,accessToken:t,refreshToken:this.authSession?.refreshToken??null});}):i==="anon"&&this.authSession&&this.setAuthSession(null);}super.handleIncoming(e);}async auth(e){let t=await this.send("auth",{token:e});if(t.type==="auth_ok"){let i=t.token??e;this.authToken=i,this.userId=t.uid;let r=await this.fetchAuthMe(i).catch(()=>null);return this.setAuthSession({uid:t.uid??t.id,accessToken:i,refreshToken:this.authSession?.refreshToken??null,email:r?.email??null,emailVerified:r?.email_verified}),await this.updateSocketIdentity(t.uid),this.log("Authentication successful",t.uid),{uid:t.uid,token:t.token??e}}throw new h("Authentication failed",u.AuthenticationFailed)}async signInWithEmailAndPassword(e,t,i){try{let r=await this.requestEmailPasswordToken(e,t,i?.scope),n=await this.auth(r.access_token),s=await this.fetchAuthMe(r.access_token).catch(()=>null);return this.setAuthSession({uid:n.uid,accessToken:r.access_token,refreshToken:r.refresh_token,provider:r.provider,email:s?.email??e,emailVerified:s?.email_verified}),this.log("Credentials sign-in successful",n.uid),{...n,kind:r.kind,accessToken:r.access_token,refreshToken:r.refresh_token,authToken:r}}catch(r){let n=/invalid_email|user.not.found|no user/i.test(r?.message??"");if(i?.createIfMissing&&n){let s=await this.createUserWithEmail(e,t,{scope:i.scope,signInIfAllowed:true});if("verificationRequired"in s&&s.verificationRequired)throw new h("Email verification required before sign-in",u.AuthenticationFailed);return {uid:s.uid,token:s.token,accessToken:s.accessToken,refreshToken:s.refreshToken,authToken:s.authToken,created:true}}throw r instanceof h?r:new h(r instanceof Error?r.message:"Sign-in with email/password failed",r.error??r.code??u.AuthenticationFailed,r)}}async signInWithEmail(e,t,i){return this.signInWithEmailAndPassword(e,t,i)}async createUserWithEmail(e,t,i){let r=await this.registerWithEmail(e,t,i);if(r.verification_required)return {kind:r.kind,verificationRequired:true,emailSent:!!r.email_sent,preview:r.preview};let n=String(r.access_token??"");if(!n)throw new h("User created but no access token returned",u.AuthenticationFailed);let s={access_token:n,refresh_token:r.refresh_token?String(r.refresh_token):null,expires_in:r.expires_in?Number(r.expires_in):null,token_type:String(r.token_type??"Bearer"),scope:r.scope?String(r.scope):null,profile:null,provider:"credentials"},o=await this.auth(n),d=await this.fetchAuthMe(n).catch(()=>null);return this.setAuthSession({uid:o.uid,accessToken:n,refreshToken:s.refresh_token,provider:"credentials",email:d?.email??e,emailVerified:d?.email_verified}),{...o,accessToken:n,refreshToken:s.refresh_token,authToken:s,verificationRequired:false,emailSent:!!r.email_sent,preview:r.preview}}async createUserWithEmailAndPassword(e,t,i){return this.createUserWithEmail(e,t,i)}async signInOrCreateWithEmail(e,t,i){try{return {...await this.signInWithEmailAndPassword(e,t,{scope:i?.scope}),created:!1}}catch(r){if(!/invalid_email|user.not.found|no user/i.test(r?.message??""))throw r;let s=await this.createUserWithEmail(e,t,{scope:i?.scope,additionalParams:i?.additionalParams,signInIfAllowed:true});return "verificationRequired"in s&&s.verificationRequired?{...s,created:true}:{...s,created:true}}}async signInOrCreateWithEmailAndPassword(e,t,i){return this.signInOrCreateWithEmail(e,t,i)}async sendEmailVerification(e){let t=this.getHttpBase();await this.ensureCsrfProtection();let i=await this.timedFetch("sendEmailVerification",`${t}/auth/verify/send?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:JSON.stringify({email:e,appId:this.config.appId,apiKey:this.config.apiKey})}),r=await this.parseJsonWithTiming("sendEmailVerification",i);return i.response.ok||this.throwFetchFlareError(r,"Failed to send verification email",u.AuthenticationFailed),r}async verifyEmailWithCode(e,t){let i=this.getHttpBase();await this.ensureCsrfProtection();let r=await this.timedFetch("verifyEmailWithCode",`${i}/auth/verify/confirm?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:JSON.stringify({email:e,code:t,appId:this.config.appId,apiKey:this.config.apiKey})}),n=await this.parseJsonWithTiming("verifyEmailWithCode",r);return r.response.ok||this.throwFetchFlareError(n,"Email verification failed",u.AuthenticationFailed),n}async confirmEmailLink(e,t){let i=this.getHttpBase();await this.ensureCsrfProtection();let r=await this.timedFetch("confirmEmailLink",`${i}/auth/verify/confirm?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:JSON.stringify({token:e,email:t,appId:this.config.appId,apiKey:this.config.apiKey})}),n=await this.parseJsonWithTiming("confirmEmailLink",r);return r.response.ok||this.throwFetchFlareError(n,"Email link verification failed",u.AuthenticationFailed),n}async sendAccountRecovery(e){let t=this.getHttpBase();await this.ensureCsrfProtection();let i=await this.timedFetch("sendAccountRecovery",`${t}/auth/recover/send?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:JSON.stringify({email:e,appId:this.config.appId,apiKey:this.config.apiKey})}),r=await this.parseJsonWithTiming("sendAccountRecovery",i);return i.response.ok||this.throwFetchFlareError(r,"Failed to send recovery email",u.AuthenticationFailed),r}async recoverAccountWithCode(e,t,i){let r=this.getHttpBase();await this.ensureCsrfProtection();let n=await this.timedFetch("recoverAccountWithCode",`${r}/auth/recover/confirm?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:JSON.stringify({email:e,code:t,newPassword:i,appId:this.config.appId,apiKey:this.config.apiKey})}),s=await this.parseJsonWithTiming("recoverAccountWithCode",n);return n.response.ok||this.throwFetchFlareError(s,"Account recovery failed",u.AuthenticationFailed),s}async recoverAccountWithToken(e,t){let i=this.getHttpBase();await this.ensureCsrfProtection();let r=await this.timedFetch("recoverAccountWithToken",`${i}/auth/recover/confirm?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:JSON.stringify({token:e,newPassword:t,appId:this.config.appId,apiKey:this.config.apiKey})}),n=await this.parseJsonWithTiming("recoverAccountWithToken",r);return r.response.ok||this.throwFetchFlareError(n,"Account recovery failed",u.AuthenticationFailed),n}toUint8ArrayFromBase64Url(e){let t=e.replace(/-/g,"+").replace(/_/g,"/"),i="=".repeat((4-t.length%4)%4),r=t+i,n=atob(r),s=new Uint8Array(n.length);for(let o=0;o<n.length;o+=1)s[o]=n.charCodeAt(o);return s}encodePushTokenFromSubscription(e){let t=e.toJSON(),i=String(t.endpoint??"").trim(),r=String(t.keys?.p256dh??"").trim(),n=String(t.keys?.auth??"").trim(),s=JSON.stringify({endpoint:i,p256dh:r,auth:n});return `webpush:${btoa(s)}`}async fetchPushSetupConfig(){let e=this.getHttpBase(),t=new URLSearchParams({appId:this.config.appId});this.config.apiKey&&t.set("apiKey",this.config.apiKey);let i=`${e}/push/config?${t.toString()}`,r=await this.timedFetch("fetchPushSetupConfig",i,{method:"GET",credentials:"include",headers:this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}}),n=await this.parseJsonWithTiming("fetchPushSetupConfig",r);r.response.ok||this.throwFetchFlareError(n,"Failed to fetch push setup config",u.QueryFailed);let s=String(n.vapidPublicKey??"").trim(),o=String(n.serviceWorkerPath??"").trim();if(o.startsWith("/"))try{let l=new URL(e,typeof window<"u"?window.location.origin:"http://localhost").pathname.replace(/\/+$/,"");l&&l!=="/"&&!o.startsWith(`${l}/`)&&(o=`${l}${o}`);}catch{}if(!s||!o)throw new h("Push setup response is missing vapidPublicKey or serviceWorkerPath",u.ParseError,n);return {vapidPublicKey:s,serviceWorkerPath:o}}async setupPushServiceWorker(){return typeof window>"u"||typeof navigator>"u"||!("serviceWorker"in navigator)?null:(this.pushServiceWorkerInitPromise||(this.pushServiceWorkerInitPromise=(async()=>{let e=await this.fetchPushSetupConfig(),t=new URL(e.serviceWorkerPath,window.location.origin);if(t.origin!==window.location.origin)throw new h("Service worker URL must be same-origin with the app",u.WriteFailed);return await navigator.serviceWorker.register(t.pathname+t.search,{scope:"/"})})().catch(e=>{throw this.log("Push service worker setup failed",e),e})),this.pushServiceWorkerInitPromise)}async requestPushPermission(){if(typeof window>"u"||typeof Notification>"u")throw new h("Push permission can only be requested in browser runtime",u.WriteFailed);let e=await Notification.requestPermission();if(e!=="granted")throw new h(`Push permission is ${e}`,u.PermissionDenied);return e}async acquireBrowserPushToken(e={}){if(typeof window>"u"||typeof navigator>"u")throw new h("Push token acquisition can only run in browser runtime",u.WriteFailed);if(!("serviceWorker"in navigator))throw new h("Service worker is not supported in this browser",u.WriteFailed);if(!("PushManager"in window))throw new h("Push manager is not supported in this browser",u.WriteFailed);await this.requestPushPermission();let t=e.applicationServerKey?null:await this.fetchPushSetupConfig(),i=e.serviceWorkerRegistration??await this.setupPushServiceWorker()??await navigator.serviceWorker.ready,r=e.subscription??await i.pushManager.getSubscription();if(e.forceResubscribe&&r&&(await r.unsubscribe().catch(()=>{}),r=null),!r){let s=e.applicationServerKey??t?.vapidPublicKey;if(!s)throw new h("No VAPID public key available for push subscription",u.WriteFailed);r=await i.pushManager.subscribe({userVisibleOnly:true,applicationServerKey:this.toUint8ArrayFromBase64Url(s)});}return {token:this.encodePushTokenFromSubscription(r),subscription:r}}async enableBrowserPush(e={}){let{token:t,subscription:i}=await this.acquireBrowserPushToken(e);return {...await this.registerPushToken({token:t,platform:e.platform??"web",deviceId:e.deviceId,topics:e.topics,authAppId:e.authAppId}),subscription:i}}async registerPushToken(e){let t=this.getHttpBase();await this.ensureCsrfProtection();let i=String(e.token??"").trim();if(!i)throw new h("Push token is required",u.WriteFailed);let r=await this.timedFetch("registerPushToken",`${t}/notify/token?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{},...this.authSession?.accessToken?{Authorization:`Bearer ${this.authSession.accessToken}`}:{}},body:JSON.stringify({appId:this.config.appId,token:i,platform:e.platform,deviceId:e.deviceId,topics:e.topics,...e.authAppId?{authAppId:e.authAppId}:{}})}),n=await this.parseJsonWithTiming("registerPushToken",r);return r.response.ok||this.throwFetchFlareError(n,"Failed to register push token",u.WriteFailed),{registered:!!n.registered,appId:String(n.appId??this.config.appId),uid:String(n.uid??this.authSession?.uid??""),token:String(n.token??i),...typeof n.platform=="string"?{platform:n.platform}:{}}}async unregisterPushToken(e,t){let i=this.getHttpBase();await this.ensureCsrfProtection();let r=String(e??"").trim();if(!r)throw new h("Push token is required",u.WriteFailed);let n=await this.timedFetch("unregisterPushToken",`${i}/notify/token?appId=${encodeURIComponent(this.config.appId)}`,{method:"DELETE",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{},...this.authSession?.accessToken?{Authorization:`Bearer ${this.authSession.accessToken}`}:{}},body:JSON.stringify({appId:this.config.appId,token:r,...t?{authAppId:t}:{}})}),s=await this.parseJsonWithTiming("unregisterPushToken",n);return n.response.ok||this.throwFetchFlareError(s,"Failed to unregister push token",u.WriteFailed),{unregistered:!!s.unregistered,appId:String(s.appId??this.config.appId),token:String(s.token??r),removed:!!s.removed}}async sendPushNotification(e){let t=this.getHttpBase();await this.ensureCsrfProtection();let i=await this.timedFetch("sendPushNotification",`${t}/system/apps/${encodeURIComponent(this.config.appId)}/notifications/send`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.authSession?.accessToken?{Authorization:`Bearer ${this.authSession.accessToken}`}:{},...e.authAppId?{"x-flare-auth-app-id":e.authAppId}:{}},body:JSON.stringify({...e,appId:this.config.appId})}),r=await this.parseJsonWithTiming("sendPushNotification",i);return i.response.ok||this.throwFetchFlareError(r,"Failed to send push notification",u.WriteFailed),{sent:!!r.sent,appId:String(r.appId??this.config.appId),targetCount:Number(r.targetCount??0),successCount:Number(r.successCount??0),failureCount:Number(r.failureCount??0),invalidatedTokenCount:Number(r.invalidatedTokenCount??0),dryRun:!!r.dryRun}}async sendEmail(e){let t=this.getHttpBase();await this.ensureCsrfProtection();let i=await this.timedFetch("sendEmail",`${t}/system/apps/${encodeURIComponent(this.config.appId)}/email/send`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.authSession?.accessToken?{Authorization:`Bearer ${this.authSession.accessToken}`}:{},...e.authAppId?{"x-flare-auth-app-id":e.authAppId}:{}},body:JSON.stringify({...e,appId:this.config.appId})}),r=await this.parseJsonWithTiming("sendEmail",i);return i.response.ok||this.throwFetchFlareError(r,"Failed to send template email",u.WriteFailed),{sent:!!r.sent,appId:String(r.appId??this.config.appId),tag:String(r.tag??e.tag??""),recipientCount:Number(r.recipientCount??0),acceptedCount:Number(r.acceptedCount??0),rejectedCount:Number(r.rejectedCount??0),...typeof r.includeVerificationLink=="boolean"?{includeVerificationLink:r.includeVerificationLink}:{},...typeof r.linkId=="string"?{linkId:r.linkId}:{},...typeof r.verifyUrl=="string"?{verifyUrl:r.verifyUrl}:{},...typeof r.messageId=="string"?{messageId:r.messageId}:{}}}async verifyEmailLink(e){let t=this.getHttpBase(),i=String(e.token??"").trim();if(!i)throw new h("Verification token is required",u.WriteFailed);let r=await this.timedFetch("verifyEmailLink",`${t}/email/link/verify?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{},...this.authSession?.accessToken?{Authorization:`Bearer ${this.authSession.accessToken}`}:{},...e.authAppId?{"x-flare-auth-app-id":e.authAppId}:{}},body:JSON.stringify({appId:this.config.appId,apiKey:this.config.apiKey,token:i,...e.tag?{tag:e.tag}:{},...e.email?{email:e.email}:{},...e.authAppId?{authAppId:e.authAppId}:{}})}),n=await this.parseJsonWithTiming("verifyEmailLink",r);return r.response.ok||this.throwFetchFlareError(n,"Failed to verify email link",u.WriteFailed),{verified:!!(n.verified??n.accepted),alreadyVerified:!!(n.alreadyVerified??n.alreadyAccepted),appId:String(n.appId??this.config.appId),linkId:String(n.linkId??""),email:String(n.email??""),tag:String(n.tag??e.tag??""),...typeof n.verifiedAt=="string"?{verifiedAt:n.verifiedAt}:{},...typeof n.acceptedByUid=="string"?{acceptedByUid:n.acceptedByUid}:{}}}async signIn(e,t,i){let r=typeof e?.signIn=="function",n=r?e:await this.getAuthGuard(),s=r?t:e,o=r?i:t;return n.signIn(s,o)}async signInWithGoogle(e){return this.signIn("google",e)}async signInWithGitHub(e){return this.signIn("github",e)}async signInWithFacebook(e){return this.signIn("facebook",e)}async signInWithDropbox(e){return this.signIn("dropbox",e)}async handleSignInRedirect(e,t=false){let i=typeof e?.handleRedirect=="function",r=i?e:await this.getAuthGuard(),n=i?t:typeof e=="boolean"?e:false,s=await r.handleRedirect(n);if(!s||!s.access_token||!s.provider)return null;let o=await this.exchangeProviderToken(s.provider,s.access_token),d=await this.auth(o.token),l=await this.fetchAuthMe(o.token).catch(()=>null);return this.setAuthSession({uid:d.uid,accessToken:o.token,refreshToken:s.refresh_token,provider:s.provider,email:l?.email??null,emailVerified:l?.email_verified}),{...d,authToken:s,provider:s.provider}}async exchangeProviderToken(e,t){let i=`${this.getHttpBase()}/auth/exchange`;await this.ensureCsrfProtection();let r=await this.timedFetch("exchangeProviderToken",i,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders()},body:JSON.stringify({appId:this.config.appId,client_id:this.config.apiKey,provider:e,access_token:t})}),n=await this.parseJsonWithTiming("exchangeProviderToken",r);if(r.response.ok||this.throwFetchFlareError(n,"OAuth token exchange failed",u.AuthenticationFailed),!n?.token)throw new h("OAuth token exchange failed",u.ParseError,n);return {token:String(n.token)}}async getAuthGuard(){if(this.authGuard)return this.authGuard;let e=await this.fetchAuthConfig();if(!e.enabled)throw new h("Authentication is disabled for this app",u.AuthenticationFailed);let t=this.getHttpBase(),i=`${t}/auth/oauth/token?appId=${encodeURIComponent(this.config.appId)}`,r=[],n=(s,o)=>({...o,token_url:i,tokenParams:{...o.tokenParams??{},provider:s}});if(e.providers.credentials?.enabled&&r.push({...Credentials({clientId:this.config.apiKey}),token_url:`${t}/auth/token?appId=${encodeURIComponent(this.config.appId)}`,createUserUrl:`${t}/auth/register?appId=${encodeURIComponent(this.config.appId)}`,createUserGrantType:"create_user"}),e.providers.anonymous?.enabled&&r.push({...Anonymous({clientId:this.config.apiKey}),token_url:`${t}/auth/token?appId=${encodeURIComponent(this.config.appId)}`}),e.providers.google?.enabled&&e.providers.google.clientId&&r.push(n("google",Google({clientId:e.providers.google.clientId,scopes:e.providers.google.scopes}))),e.providers.github?.enabled&&e.providers.github.clientId&&r.push(n("github",GitHub({clientId:e.providers.github.clientId,scopes:e.providers.github.scopes}))),e.providers.facebook?.enabled&&e.providers.facebook.clientId&&r.push(n("facebook",Facebook({clientId:e.providers.facebook.clientId,scopes:e.providers.facebook.scopes}))),e.providers.dropbox?.enabled&&e.providers.dropbox.clientId&&r.push(n("dropbox",Dropbox({clientId:e.providers.dropbox.clientId,scopes:e.providers.dropbox.scopes}))),e.providers.apple?.enabled&&e.providers.apple.clientId&&r.push(n("apple",Apple({clientId:e.providers.apple.clientId,scopes:e.providers.apple.scopes}))),e.providers.twitter?.enabled&&e.providers.twitter.clientId&&r.push(n("twitter",Twitter({clientId:e.providers.twitter.clientId,scopes:e.providers.twitter.scopes}))),r.length===0)throw new h("No authentication providers are enabled for this app",u.AuthenticationFailed);return this.authGuard=new AuthGuard({providers:r,redirectUri:e.redirectUri}),this.authGuard}async refreshAuthSession(e){let t=this.getHttpBase();await this.ensureCsrfProtection();let i=await this.timedFetch("refreshAuthSession",`${t}/auth/refresh?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:JSON.stringify({appId:this.config.appId,apiKey:this.config.apiKey,...e?{refresh_token:e}:{}})}),r=await this.parseJsonWithTiming("refreshAuthSession",i);if(!i.response.ok){if(i.response.status===401)return this.setAuthSession(null),await this.syncSocketAuth(null).catch(()=>{}),null;this.throwFetchFlareError(r,"Failed to refresh auth session",u.AuthenticationFailed);}let n=String(r.access_token??"");if(!n)throw new h("Refresh succeeded but no access token was returned",u.ParseError);let s=await this.fetchAuthMe(n).catch(()=>null),o={uid:String(s?.id??this.authSession?.uid??this.userId??""),accessToken:n,refreshToken:r.refresh_token?String(r.refresh_token):this.authSession?.refreshToken??null,provider:this.authSession?.provider,email:s?.email??this.authSession?.email??null,emailVerified:s?.email_verified};if(s){try{delete s.kind,s.uid=s.id??s.uid,delete s.id;}catch{}this.setProfile(s);}return this.setAuthSession(o),await this.syncSocketAuth(n).catch(()=>{}),o}async issueSsrToken(e=120){let t=this.getHttpBase();await this.ensureCsrfProtection();let i=await this.timedFetch("issueSsrToken",`${t}/auth/ssr/token?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:JSON.stringify({appId:this.config.appId,apiKey:this.config.apiKey,ttlSeconds:e})}),r=await this.parseJsonWithTiming("issueSsrToken",i);i.response.ok||this.throwFetchFlareError(r,"Failed to mint SSR token",u.AuthenticationFailed);let n=String(r.token??"");if(!n)throw new h("SSR token response is missing token",u.ParseError,r);return {token:n,token_type:String(r.token_type??"Bearer"),expires_in:Number(r.expires_in??0),uid:String(r.uid??""),role:String(r.role??"user"),...typeof r.email=="string"?{email:r.email}:{}}}async signOut(){try{if(this.authSession?.accessToken||this.authSession?.refreshToken||this.config.httpBase){let t=this.getHttpBase();await this.ensureCsrfProtection(),await this.timedFetch("signOut",`${t}/auth/logout?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{},...this.authSession?.accessToken?{Authorization:`Bearer ${this.authSession.accessToken}`}:{}},body:JSON.stringify({appId:this.config.appId,apiKey:this.config.apiKey,refresh_token:this.authSession?.refreshToken})}).catch(()=>{});}}finally{this.setAuthSession(null),await this.syncSocketAuth(null).catch(()=>{});}this.log("Signed out");}async registerWithEmail(e,t,i){let r=this.getHttpBase();await this.ensureCsrfProtection();let n=new URLSearchParams;n.set("appId",this.config.appId),n.set("client_id",this.config.apiKey??""),n.set("grant_type","create_user"),n.set("email",e),n.set("password",t),i?.scope?.length&&n.set("scope",i.scope.join(" ")),i?.additionalParams&&n.set("additional_params",JSON.stringify(i.additionalParams));let s=await this.timedFetch("registerWithEmail",`${r}/auth/register?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/x-www-form-urlencoded",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:n.toString()}),o=await this.parseJsonWithTiming("registerWithEmail",s);return !s.response.ok&&s.response.status!==202&&this.throwFetchFlareError(o,"User creation failed",u.WriteFailed),o}async requestEmailPasswordToken(e,t,i){let r=this.getHttpBase();await this.ensureCsrfProtection();let n=new URLSearchParams;n.set("appId",this.config.appId),n.set("client_id",this.config.apiKey??""),n.set("grant_type","password"),n.set("email",e),n.set("password",t),i?.length&&n.set("scope",i.join(" "));let s=await this.timedFetch("requestEmailPasswordToken",`${r}/auth/token?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/x-www-form-urlencoded",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:n.toString()}),o=await this.parseJsonWithTiming("requestEmailPasswordToken",s);return s.response.ok||this.throwFetchFlareError(o,"Sign-in with email/password failed",u.AuthenticationFailed),{kind:String(o.kind),access_token:String(o.access_token??""),refresh_token:o.refresh_token?String(o.refresh_token):null,expires_in:o.expires_in?Number(o.expires_in):null,token_type:String(o.token_type??"Bearer"),scope:o.scope?String(o.scope):null,profile:null,provider:"credentials"}}async fetchAuthMe(e){let t=this.getHttpBase(),i=new URLSearchParams({appId:this.config.appId});this.config.apiKey&&i.set("apiKey",this.config.apiKey);let r=`${t}/auth/me?${i.toString()}`,n=await this.timedFetch("fetchAuthMe",r,{credentials:"include",headers:{Authorization:`Bearer ${e}`,...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}}}),s=await this.parseJsonWithTiming("fetchAuthMe",n);return n.response.ok||this.throwFetchFlareError(s,"Failed to fetch profile",u.QueryFailed),s}};var Z=class extends L{autoPushRegisteredIdentity;constructor(e){super(e),this.log("FlareClient initialized",e),e.pushNotifications===true&&this.enableAutoPushNotificationsAfterAuth();}enableAutoPushNotificationsAfterAuth(){let e=async()=>{let t=this.authSession,i=String(t?.uid??"").trim()||"anon",r=String(t?.accessToken??"").trim(),n=i!=="anon"&&r?i:"anon";if(this.autoPushRegisteredIdentity!==n)try{await this.autoEnablePushNotifications(),this.autoPushRegisteredIdentity=n;}catch(s){this.log("Auto push enable failed",s);}};this.onAuthStateChanged(()=>{e().catch(()=>{});}),e().catch(()=>{});}async autoEnablePushNotifications(){await this.setupPushServiceWorker().catch(()=>{}),await this.requestPushPermission();let{token:e}=await this.acquireBrowserPushToken();await this.registerPushToken({token:e,platform:"web",topics:[this.config.appId]});}},ie=Z;function X(a){return `__flare_csrf_${a.replace(/[^a-zA-Z0-9_-]/g,"_")}`}function Re(a){return `__flare_csrf_${a.replace(/[^a-zA-Z0-9_-]/g,"_")}`}function U(a,e){let t=e.toLowerCase();for(let[i,r]of Object.entries(a??{}))if(i.toLowerCase()===t&&typeof r=="string")return r}function xe(a){let e=U(a,"set-cookie");if(typeof e=="string"&&e.length>0)return [e];for(let[t,i]of Object.entries(a??{}))if(t.toLowerCase()==="set-cookie"&&Array.isArray(i))return i.filter(r=>typeof r=="string");return []}function Fe(a,e){for(let t of a){let i=t.split(";").map(d=>d.trim()),[r]=i;if(!r)continue;let n=r.indexOf("=");if(n<=0)continue;let s=decodeURIComponent(r.slice(0,n)),o=r.slice(n+1);if(s===e)return decodeURIComponent(o)}}async function Ee(a){let e=new URL("/auth/config",a.endpoint);return e.searchParams.set("appId",a.appId),a.apiKey&&e.searchParams.set("apiKey",a.apiKey),await withGet(e.toString(),{ignoreKind:true,withCredentials:true,returnRawResponse:true,headers:a.apiKey?{"x-flare-api-key":a.apiKey}:{},appendCookiesToBody:false,appendTimestamp:false}).catch(()=>null)}async function ne(a){let e=await Ee(a),t=e?.data,i=e?.headers??{},r=U(i,"x-flare-csrf")??U(i,"x-csrf-token")??U(i,"csrf-token");if(typeof r=="string"&&r.length>0)return {csrfToken:r,...t};let n=t?.cookie?.csrfTokenName,s=n&&n.length>0?n:Re(a.appId),o=xe(i),d=Fe(o,s);if(typeof d=="string"&&d.length>0)return {csrfToken:d,...t}}function se(a,e,t){return `${encodeURIComponent(a)}=${encodeURIComponent(e)}; HttpOnly; SameSite=Strict; Path=/; Max-Age=${t}`}function Me(a){let e=a.proxyCookieName??X(a.appId),t=a.proxyCookieMaxAge??3600;return async function(r){let n=await ne(a),s=n?.csrfToken,o=new Headers({"Content-Type":"application/json"});return s&&o.set("Set-Cookie",se(e,s,t)),new Response(JSON.stringify({csrfToken:s??null,...n}),{status:200,headers:o})}}function Qe(a){let e=a.proxyCookieName??X(a.appId),t=a.proxyCookieMaxAge??3600;return async function(r,n){if(r.method!=="GET"&&r.method!=="HEAD"){n.status(405).json({error:"Method not allowed"});return}let o=(await ne(a))?.csrfToken;o&&n.setHeader("Set-Cookie",se(e,o,t)),n.status(200).json({csrfToken:o??null});}}function Oe(a,e,t){let i=t??X(e);if(a instanceof Request){let s=(a.headers.get("cookie")??"").split(";").map(d=>d.trim()).find(d=>d.startsWith(`${encodeURIComponent(i)}=`)||d.startsWith(`${i}=`));if(!s)return null;let o=s.indexOf("=");return o>=0?decodeURIComponent(s.slice(o+1)):null}let{cookies:r}=a;return typeof r?.get=="function"?r.get(i)?.value??null:r&&typeof r=="object"?r[i]??null:null}function Be(a,e){let t={};return a&&(t["x-flare-csrf"]=a),e?.accessToken&&(t.Authorization=`Bearer ${e.accessToken}`),e?.apiKey&&(t["x-flare-api-key"]=e.apiKey),t}var Ne=a=>a==="guest"?"auth == null":a==="auth"?"auth != null":"true",_e=(a,e)=>{let t=String(e??"").trim();return t?a==="true"?t:`(${a}) && (${t})`:a},He=a=>{let e=String(a??"").trim();if(!e||e==="false")return {auth:"any"};if(e==="auth != null")return {auth:"auth"};if(e==="auth == null")return {auth:"guest"};if(e==="true")return {auth:"any"};let t=e.match(/^\((auth != null|auth == null|true)\)\s*&&\s*\((.+)\)$/);if(t)return {auth:oe(t[1]),condition:t[2].trim()};let i=e.match(/^(auth != null|auth == null|true)\s*&&\s*(.+)$/);return i?{auth:oe(i[1]),condition:i[2].trim()}:{auth:"any",condition:e}},oe=a=>{let e=String(a??"").trim();return e==="auth == null"?"guest":e==="auth != null"?"auth":"any"},Nt=a=>{let e={};for(let t of a){let i=String(t.collection||"").trim();if(!i)continue;let r=i==="any"?"*":i,n=_e(Ne(t.auth),t.condition);e[r]={".read":t.permissions.includes("read")?n:"false",".create":t.permissions.includes("create")?n:"false",".update":t.permissions.includes("update")?n:"false",".delete":t.permissions.includes("delete")?n:"false"};}return e},_t=a=>Object.entries(a).map(([e,t],i)=>{let r=t?.[".read"],n=t?.[".create"],s=t?.[".update"],o=t?.[".delete"],d=t?.[".write"],l=[];typeof r=="string"&&r.trim()!=="false"&&l.push("read");let f=typeof n=="string"&&n.trim()!=="false"||typeof d=="string"&&d.trim()!=="false",y=typeof s=="string"&&s.trim()!=="false"||typeof d=="string"&&d.trim()!=="false",c=typeof o=="string"&&o.trim()!=="false"||typeof d=="string"&&d.trim()!=="false";f&&l.push("create"),y&&l.push("update"),c&&l.push("delete");let C=He(r||n||s||o||d);return {id:`${e}-${i}`,name:e==="*"?"All Collections":e,auth:C.auth,collection:e==="*"?"any":e,condition:C.condition,permissions:l}});var qe=(y=>(y.authEmailNotVerified="auth/email-not-verified",y.authEmailAlreadyVerified="auth/email-already-verified",y.authInvalidToken="auth/invalid-token",y.authUserDisabled="auth/user-disabled",y.authUserNotFound="auth/user-not-found",y.authWrongPassword="auth/wrong-password",y.authEmailAlreadyInUse="auth/email-already-in-use",y.authInvalidEmail="auth/invalid-email",y.authWeakPassword="auth/weak-password",y.authTooManyRequests="auth/too-many-requests",y.authInternalError="auth/internal-error",y))(qe||{});var De=(g=>(g.health="health",g.authConfig="auth_config",g.authRegistration="auth/registration",g.authRegistrationVerificationRequired="auth/registration-verification-required",g.authSession="auth/session",g.authExchange="auth/exchange",g.authLogout="auth/logout",g.authSsrBridge="auth/ssr_bridge",g.authSsrVerify="auth/ssr_verify",g.accountRecovery="account/recovery",g.emailVerification="email/verification",g.verificationDispatch="verification/dispatch",g.authProfile="auth/profile",g.adminToken="admin/token",g.documentDelete="document/delete",g.documentsDelete="documents/delete",g.documents="documents",g.document="document",g.documentCreate="document/create",g.documentUpdate="document/update",g.oauthProviderResponse="oauth_provider_response",g.success="success",g.response="response",g))(De||{});var T=null,B=null,W=null,Le=a=>JSON.stringify({endpoint:a.endpoint,appId:a.appId,apiKey:a.apiKey,publicKey:a.publicKey,autoReconnect:a.autoReconnect,reconnectDelay:a.reconnectDelay,maxReconnectDelay:a.maxReconnectDelay}),Kt=a=>{let e=Le(a);if(T&&W!==e&&(T.disconnect(),T=null,B=null,W=null),!T){T=new ie(a),W=e;let t=typeof window<"u"&&typeof document<"u",i=typeof process<"u"&&typeof process.env?.NEXT_RUNTIME=="string";(t||!i)&&T.connect(),t&&T.setupPushServiceWorker().catch(()=>{}),B=new Proxy(T,{get(r,n,s){if(n==="onAuthStateChange")return r.onAuthStateChanged.bind(r);if(n==="onAuthConfigLoaded")return r.onAuthConfigLoaded.bind(r);let o=Reflect.get(r,n,s);return typeof o=="function"?o.bind(r):o}});}return B??T},Jt=()=>B??T,jt=()=>{T&&(T.disconnect(),T=null,B=null,W=null);};
|
|
2
|
-
export{Y as CollectionReference,v as DocumentQueryBuilder,
|
|
1
|
+
import {Credentials,Anonymous,Google,GitHub,Facebook,Dropbox,Apple,Twitter,AuthGuard}from'@zuzjs/auth';export{Anonymous,Apple,AuthGuard,Credentials,Dropbox,Facebook,GitHub,Google,Providers,Twitter,setupProvider}from'@zuzjs/auth';import {uuid2,withGet,withPut,withPatch,withPost}from'@zuzjs/core';var h=class extends Error{constructor(t,i,r){super(t);this.code=i;this.cause=r;this.name="ZuzFlareError";}};var ae={AuthenticationFailed:"AUTHENTICATION_FAILED",PermissionDenied:"PERMISSION_DENIED",WriteFailed:"WRITE_FAILED",QueryFailed:"QUERY_FAILED",ParseError:"PARSE_ERROR"},d=ae;var ce=(u=>(u.SUBSCRIBE="subscribe",u.UNSUBSCRIBE="unsubscribe",u.WRITE="write",u.DELETE="delete",u.AUTH="auth",u.PING="ping",u.OFFLINE_SYNC="offline_sync",u.CALL="call",u.QUERY="query",u.PRESENCE_JOIN="presence_join",u.PRESENCE_LEAVE="presence_leave",u.PRESENCE_HEARTBEAT="presence_heartbeat",u))(ce||{}),ue=(u=>(u.SNAPSHOT="snapshot",u.CHANGE="change",u.ERROR="error",u.ACK="ack",u.PONG="pong",u.AUTH_OK="auth_ok",u.OFFLINE_ACK="offline_ack",u.CALL_RESPONSE="call_response",u.QUERY_RESULT="query_result",u.PRESENCE_STATE="presence_state",u.PRESENCE_JOIN="presence_join",u.PRESENCE_LEAVE="presence_leave",u))(ue||{});function V(a){let e=[];for(let[t,i]of Object.entries(a))if(typeof i=="string"){let r=i.match(/^(>=|<=|!=|>|<|==)\s*(.+)$/);if(r){let[,n,s]=r;e.push({field:t,op:n,value:te(s.trim())});}else e.push({field:t,op:"==",value:i});}else Array.isArray(i)?e.push({field:t,op:"in",value:i}):e.push({field:t,op:"==",value:i});return e}function te(a){if(!isNaN(Number(a)))return Number(a);if(a==="true")return true;if(a==="false")return false;if(a==="null")return null;if(a!=="undefined")return a}var v=class{constructor(e,t,i){this.client=e;this.collection=t;this.docIdFromRef=i;}whereCondition;updateData;setData;deleteOp=false;promise;where(e){return this.whereCondition=e,this}update(e){return this.updateData=e,this}set(e){return this.setData=e,this}delete(){return this.deleteOp=true,this}getDocId(){if(this.docIdFromRef)return this.docIdFromRef;if(this.whereCondition&&(this.whereCondition.id||this.whereCondition._id)){let e=this.whereCondition.id??this.whereCondition._id;if(typeof e=="string")return e}throw new h('Document ID not specified. Use .where({ id: "..." }) or doc(collection, id)',d.QueryFailed)}async execute(){return this._execute()}async _execute(){let e=this.getDocId();if(this.deleteOp){await this.client.send("delete",{collection:this.collection,docId:e});return}if(this.updateData){await this.client.send("write",{collection:this.collection,docId:e,data:this.updateData,merge:true});return}if(this.setData){await this.client.send("write",{collection:this.collection,docId:e,data:this.setData,merge:false});return}return this.get()}then(e,t){return this.promise||(this.promise=this._execute()),this.promise.then(e,t)}async get(){let e=this.getDocId(),t=uuid2(18);return new Promise((i,r)=>{let n=this.client.subscribe(t,this.collection,e,void 0,s=>{s.type==="snapshot"&&(n(),i(s.data));});setTimeout(()=>{n(),r(new Error("Document fetch timeout"));},1e4);})}onSnapshot(e){let t=this.getDocId(),i=uuid2(18);return this.client.subscribe(i,this.collection,t,void 0,e)}};var z=class{constructor(e,t,i){this.client=e;this.collection=t;this.id=i;}async get(){return new v(this.client,this.collection,this.id).get()}async set(e){await this.client.send("write",{collection:this.collection,docId:this.id,data:e,merge:false});}async update(e){await this.client.send("write",{collection:this.collection,docId:this.id,data:e,merge:true});}async delete(){await this.client.send("delete",{collection:this.collection,docId:this.id});}onSnapshot(e){let t=uuid2(18),i=()=>{};return i=this.client.subscribe(t,this.collection,this.id,void 0,r=>{r.type==="snapshot"&&(e(r),i());}),i}onDocUpdated(e){let t=uuid2(18);return this.client.subscribe(t,this.collection,this.id,void 0,i=>{i.type==="change"&&(i.operation==="update"||i.operation==="replace")&&i.data&&e(i.data,i.docId);},{skipSnapshot:true})}onDocDeleted(e){let t=uuid2(18);return this.client.subscribe(t,this.collection,this.id,void 0,i=>{i.type==="change"&&i.operation==="delete"&&e(i.docId);},{skipSnapshot:true})}onDocChanged(e){let t=uuid2(18);return this.client.subscribe(t,this.collection,this.id,void 0,i=>{i.type==="change"&&e(i.data??null,i.docId,i.operation);},{skipSnapshot:true})}},Q=z;var G=class a{constructor(e,t){this.client=e;this.collection=t;return new Proxy(this,{get:(i,r,n)=>{if(typeof r=="string"&&!(r in i)&&this.client.hasQueryPreset(r))return (o={})=>i.with(r,o);let s=Reflect.get(i,r,n);return typeof s=="function"?s.bind(i):s}})}sq={};promise;doc(e){return new Q(this.client,this.collection,e)}clone(e){let t=new a(this.client,this.collection);return t.sq={...this.sq,...e},t}normalizeFilterValue(e,t){return e==="in"||e==="not-in"||e==="array-contains-any"?Array.isArray(t)?t:[t]:t}normalizeFilter(e){return {...e,value:this.normalizeFilterValue(e.op,e.value)}}toQueryFilters(e){return V(e).map(t=>this.normalizeFilter(t))}appendOperatorFilter(e,t,i,r){return this.appendFilters([this.normalizeFilter({field:e,op:t,value:i})],r)}appendAndFilters(e){return this.clone({where:[...this.sq.where??[],...e]})}toOrNode(e){return {or:e}}toAndNode(e){return {and:e}}isLeafFilter(e){return !("or"in e)&&!("and"in e)}isIdentityGuard(e){return this.isLeafFilter(e)?(e.field==="id"||e.field==="_id")&&e.op==="==":false}splitIdentityGuards(e){let t=[],i=[];for(let r of e){if(this.isIdentityGuard(r)){t.push(r);continue}i.push(r);}return {guards:t,rest:i}}appendOrFilters(e){let t=[...this.sq.where??[]];if(t.length===0)return this.clone({where:[this.toOrNode(e)]});let i=t[0];if(t.length===1&&typeof i=="object"&&i!=null&&"or"in i){let c=i;return this.clone({where:[{or:[...c.or,...e]}]})}let{guards:n,rest:s}=this.splitIdentityGuards(t);if(n.length>0){let c=s.length===0?void 0:s.length===1?s[0]:{and:s},l=c?[{or:[c,...e]}]:[{or:[...e]}];return this.clone({where:[...n,...l]})}let o=t.length===1?t[0]:{and:t};return this.clone({where:[{or:[o,...e]}]})}appendFilters(e,t){return t==="or"?this.appendOrFilters(e):this.appendAndFilters(e)}with(e,t={}){return this.client.applyQueryPreset(this,e,t)}where(e){return this.appendFilters(this.toQueryFilters(e),"and")}and(e){return this.appendFilters(this.toQueryFilters(e),"and")}or(e){return this.appendFilters(this.toQueryFilters(e),"or")}in(e,t){return this.appendOperatorFilter(e,"in",t,"and")}andIn(e,t){return this.appendOperatorFilter(e,"in",t,"and")}orIn(e,t){return this.appendOperatorFilter(e,"in",t,"or")}notIn(e,t){return this.appendOperatorFilter(e,"not-in",t,"and")}andNotIn(e,t){return this.appendOperatorFilter(e,"not-in",t,"and")}orNotIn(e,t){return this.appendOperatorFilter(e,"not-in",t,"or")}arrayContains(e,t){return this.appendOperatorFilter(e,"array-contains",t,"and")}andArrayContains(e,t){return this.appendOperatorFilter(e,"array-contains",t,"and")}orArrayContains(e,t){return this.appendOperatorFilter(e,"array-contains",t,"or")}arrayContainsAny(e,t){return this.appendOperatorFilter(e,"array-contains-any",t,"and")}andArrayContainsAny(e,t){return this.appendOperatorFilter(e,"array-contains-any",t,"and")}orArrayContainsAny(e,t){return this.appendOperatorFilter(e,"array-contains-any",t,"or")}some(e,t){return this.appendOperatorFilter(e,"elem-match",t,"and")}andSome(e,t){return this.appendOperatorFilter(e,"elem-match",t,"and")}orSome(e,t){return this.appendOperatorFilter(e,"elem-match",t,"or")}like(e,t){return this.appendOperatorFilter(e,"like",t,"and")}andLike(e,t){return this.appendOperatorFilter(e,"like",t,"and")}orLike(e,t){return this.appendOperatorFilter(e,"like",t,"or")}notLike(e,t){return this.appendOperatorFilter(e,"not-like",t,"and")}andNotLike(e,t){return this.appendOperatorFilter(e,"not-like",t,"and")}orNotLike(e,t){return this.appendOperatorFilter(e,"not-like",t,"or")}exists(e){return this.appendOperatorFilter(e,"exists",true,"and")}andExists(e){return this.appendOperatorFilter(e,"exists",true,"and")}orExists(e){return this.appendOperatorFilter(e,"exists",true,"or")}notExists(e){return this.appendOperatorFilter(e,"not-exists",true,"and")}andNotExists(e){return this.appendOperatorFilter(e,"not-exists",true,"and")}orNotExists(e){return this.appendOperatorFilter(e,"not-exists",true,"or")}latest(){return this.clone({orderBy:[...this.sq.orderBy??[],{field:"_seq",dir:"desc"}]})}newest(){return this.clone({orderBy:[...this.sq.orderBy??[],{field:"_seq",dir:"desc"}]})}oldest(){return this.clone({orderBy:[...this.sq.orderBy??[],{field:"_seq",dir:"asc"}]})}orderBy(e,t="asc"){return this.clone({orderBy:[...this.sq.orderBy??[],{field:e,dir:t}]})}limit(e){return this.clone({limit:e})}offset(e){return this.clone({offset:e})}startAt(...e){return this.clone({startAt:{values:e}})}startAfter(...e){return this.clone({startAfter:{values:e}})}endAt(...e){return this.clone({endAt:{values:e}})}endBefore(...e){return this.clone({endBefore:{values:e}})}aggregate(...e){return this.clone({aggregate:[...this.sq.aggregate??[],...e]})}count(e="count"){return this.aggregate({fn:"count",alias:e})}sum(e,t){return this.aggregate({fn:"sum",field:e,alias:t??`sum_${e}`})}avg(e,t){return this.aggregate({fn:"avg",field:e,alias:t??`avg_${e}`})}min(e,t){return this.aggregate({fn:"min",field:e,alias:t??`min_${e}`})}max(e,t){return this.aggregate({fn:"max",field:e,alias:t??`max_${e}`})}distinct(e,t){return this.aggregate({fn:"distinct",field:e,alias:t??`distinct_${e}`})}groupBy(...e){return this.clone({groupBy:{fields:e}})}having(e,t,i){return this.clone({having:[...this.sq.having??[],{field:e,op:t,value:i}]})}buildStructuredJoin(e,t){let r={from:String(e??""),localField:String(t?.source??""),foreignField:String(t?.target??""),as:String(t?.as??""),single:t?.single};return Array.isArray(t?.where)&&(r.where=t.where),Array.isArray(t?.orderBy)&&(r.orderBy=t.orderBy),typeof t?.limit=="number"&&(r.limit=t.limit),typeof t?.offset=="number"&&(r.offset=t.offset),t?.startAt&&(r.startAt=t.startAt),t?.startAfter&&(r.startAfter=t.startAfter),t?.endAt&&(r.endAt=t.endAt),t?.endBefore&&(r.endBefore=t.endBefore),Array.isArray(t?.aggregate)&&(r.aggregate=t.aggregate),t?.groupBy&&(r.groupBy=t.groupBy),Array.isArray(t?.having)&&(r.having=t.having),t?.vectorSearch&&(r.vectorSearch=t.vectorSearch),Array.isArray(t?.select)&&(r.select=t.select),typeof t?.distinctField=="string"&&(r.distinctField=t.distinctField),Array.isArray(t?.joins)&&(r.joins=t.joins.map(n=>this.buildStructuredJoin(String(n?.collection??""),n))),r}cloneStructuredJoin(e){let t={...e};return Array.isArray(e.where)&&(t.where=e.where.map(i=>({...i}))),Array.isArray(e.orderBy)&&(t.orderBy=e.orderBy.map(i=>({...i}))),Array.isArray(e.aggregate)&&(t.aggregate=e.aggregate.map(i=>({...i}))),Array.isArray(e.having)&&(t.having=e.having.map(i=>({...i}))),Array.isArray(e.select)&&(t.select=[...e.select]),e.groupBy?.fields&&(t.groupBy={fields:[...e.groupBy.fields]}),e.startAt?.values&&(t.startAt={values:[...e.startAt.values]}),e.startAfter?.values&&(t.startAfter={values:[...e.startAfter.values]}),e.endAt?.values&&(t.endAt={values:[...e.endAt.values]}),e.endBefore?.values&&(t.endBefore={values:[...e.endBefore.values]}),Array.isArray(e.joins)&&(t.joins=e.joins.map(i=>this.cloneStructuredJoin(i))),t}appendNestedJoinByAlias(e,t,i){for(let r of e){if(r.as===t)return r.joins=[...r.joins??[],i],true;if(Array.isArray(r.joins)&&this.appendNestedJoinByAlias(r.joins,t,i))return true}return false}parseRelationRef(e){let i=String(e??"").trim().match(/^([A-Za-z0-9_.]+)\s*->\s*([A-Za-z0-9_]+)\.([A-Za-z0-9_.]+)(?:\s+as\s+([A-Za-z0-9_]+))?$/i);if(!i)throw new Error(`Invalid relation format: "${e}". Expected "source.path->collection.target"`);return {source:i[1],collection:i[2],target:i[3],alias:i[4]}}join(e,t){let i=this.buildStructuredJoin(e,t);return this.clone({joins:[...this.sq.joins??[],i]})}joinNested(e,t,i){let r=String(e??"").trim();if(!r)throw new Error("joinNested requires parentAlias");let n=(this.sq.joins??[]).map(o=>this.cloneStructuredJoin(o));if(n.length===0)throw new Error(`joinNested parent alias "${r}" not found`);let s=this.buildStructuredJoin(t,i);if(!this.appendNestedJoinByAlias(n,r,s))throw new Error(`joinNested parent alias "${r}" not found`);return this.clone({joins:n})}Join(e,t){return this.join(e,t)}JoinNested(e,t,i){return this.joinNested(e,t,i)}withRelation(e,t={}){let i=this.parseRelationRef(e);return this.join(i.collection,{...t,source:i.source,target:i.target,as:t.as??i.alias??i.collection})}select(...e){return this.clone({select:e})}distinctField(e){return this.clone({distinctField:e})}vectorSearch(e){return this.clone({vectorSearch:e})}getRawQuery(){let e={...this.sq};return Array.isArray(this.sq.where)&&(e.where=this.sq.where.map(t=>({...t}))),Array.isArray(this.sq.orderBy)&&(e.orderBy=this.sq.orderBy.map(t=>({...t}))),Array.isArray(this.sq.aggregate)&&(e.aggregate=this.sq.aggregate.map(t=>({...t}))),Array.isArray(this.sq.having)&&(e.having=this.sq.having.map(t=>({...t}))),Array.isArray(this.sq.select)&&(e.select=[...this.sq.select]),Array.isArray(this.sq.joins)&&(e.joins=this.sq.joins.map(t=>this.cloneStructuredJoin(t))),this.sq.groupBy?.fields&&(e.groupBy={fields:[...this.sq.groupBy.fields]}),this.sq.startAt?.values&&(e.startAt={values:[...this.sq.startAt.values]}),this.sq.startAfter?.values&&(e.startAfter={values:[...this.sq.startAfter.values]}),this.sq.endAt?.values&&(e.endAt={values:[...this.sq.endAt.values]}),this.sq.endBefore?.values&&(e.endBefore={values:[...this.sq.endBefore.values]}),{collection:this.collection,query:e}}async get(){return this._execute()}async first(){let e=await this._execute();return e.length>0?e[0]:null}async last(){let e=await this._execute();return e.length>0?e[e.length-1]:null}_isStructured(){return !!(this.sq.orderBy?.length||this.sq.aggregate?.length||this.sq.groupBy||this.sq.having?.length||this.sq.joins?.length||this.sq.vectorSearch||this.sq.distinctField||this.sq.offset||this.sq.startAt||this.sq.startAfter||this.sq.endAt||this.sq.endBefore||this.sq.select?.length)}async _execute(){return this._isStructured()?this._executeQuery():this._executeSubscribe()}async _executeQuery(){return this.client.query(this.collection,this.sq)}async _executeSubscribe(){let e=uuid2(18);return new Promise((t,i)=>{let r=Object.keys(this.sq).length>0?this.sq:void 0,n=this.client.subscribe(e,this.collection,void 0,r,s=>{s.type==="snapshot"&&(n(),t(s.data));});setTimeout(()=>{n(),i(new Error("Collection fetch timeout"));},1e4);})}then(e,t){return this.promise||(this.promise=this._execute()),this.promise.then(e,t)}onSnapshot(e){let t=uuid2(18),i=Object.keys(this.sq).length>0?this.sq:void 0,r=(()=>{});return r=this.client.subscribe(t,this.collection,void 0,i,n=>{n.type==="snapshot"&&(e(n),r());}),r}stream(e={}){let t=uuid2(18),i=Object.keys(this.sq).length>0?this.sq:void 0,r=new Set,n=[],s=new Map,o=Math.max(0,Number(e.flushMs??24)),c=Math.max(1,Number(e.maxBatchSize??200)),l=e.insertAt??"end",g=typeof e.maxDocs=="number"&&e.maxDocs>0?Math.floor(e.maxDocs):void 0,y=String(e.idField??"id"),u=[],w=false,C=false,F=0,P,I=()=>{s.clear();for(let p=0;p<u.length;p+=1){let m=$(u[p]);m&&s.set(m,p);}},$=(p,m)=>{if(m)return m;if(p==null)return;if(typeof e.getId=="function"){let R=e.getId(p);if(typeof R=="string"&&R.length>0)return R}let A=p?.[y]??p?._id??p?.docId;if(typeof A=="string"&&A.length>0)return A},x=()=>{g==null||u.length<=g||(u=u.slice(0,g));},M=()=>{typeof e.sort=="function"&&(u=u.slice().sort(e.sort));},B=(p,m)=>{F+=1;let A=u.slice(),R={reason:p,batchSize:m,version:F,ready:C};for(let N of Array.from(r))try{N(A,R);}catch{}},S=()=>{P!=null&&(clearTimeout(P),P=void 0);},f=p=>{if(p.operation==="delete"){let N=s.get(p.docId);if(N==null)return;u.splice(N,1),I();return}let m=p.data;if(m==null)return;let A=$(m,p.docId);if(!A)return;let R=s.get(A);if(typeof R=="number"){u[R]=m;return}l==="start"?u.unshift(m):u.push(m),x(),I();},_=()=>{if(w||n.length===0)return;S();let p=n.splice(0,n.length);for(let m of p)f(m);M(),I(),B("change-batch",p.length);},K=()=>{w||P!=null||(P=setTimeout(_,o));},J=this.client.subscribe(t,this.collection,void 0,i,p=>{if(!w){if(p.type==="snapshot"){u=Array.isArray(p.data)?[...p.data]:[],C=true,S(),n.length=0,M(),x(),I(),B("snapshot",0);return}if(n.push(p),n.length>=c){_();return}K();}}),j={subscribe(p,m=true){if(r.add(p),m){let A={reason:C?"change-batch":"snapshot",batchSize:0,version:F,ready:C};try{p(u.slice(),A);}catch{}}return ()=>{r.delete(p);}},getSnapshot(){return u.slice()},isReady(){return C},getVersion(){return F},close:()=>{w||(w=true,S(),n.length=0,r.clear(),J());},onError(p){return J.onError(p),j},onPermissionDenied(p){return J.onPermissionDenied(p),j}};return j}asStore(e={}){let t=this.stream(e);return {subscribe:i=>t.subscribe(()=>{i();},false),getSnapshot:()=>t.getSnapshot(),getServerSnapshot:()=>[],stream:t,destroy:()=>{t.close();}}}onDocAdded(e){let t=uuid2(18),i=Object.keys(this.sq).length>0?this.sq:void 0;return this.client.subscribe(t,this.collection,void 0,i,r=>{r.type==="change"&&r.operation==="insert"&&r.data!=null&&e(r.data,r.docId);},{skipSnapshot:true})}onDocUpdated(e){let t=uuid2(18),i=Object.keys(this.sq).length>0?this.sq:void 0;return this.client.subscribe(t,this.collection,void 0,i,r=>{r.type==="change"&&(r.operation==="update"||r.operation==="replace")&&r.data!=null&&e(r.data,r.docId);},{skipSnapshot:true})}onDocDeleted(e){let t=uuid2(18),i=Object.keys(this.sq).length>0?this.sq:void 0;return this.client.subscribe(t,this.collection,void 0,i,r=>{r.type==="change"&&r.operation==="delete"&&e(r.docId);},{skipSnapshot:true})}onDocChanged(e){let t=uuid2(18),i=Object.keys(this.sq).length>0?this.sq:void 0;return this.client.subscribe(t,this.collection,void 0,i,r=>{r.type==="change"&&e(r.data??null,r.docId,r.operation);},{skipSnapshot:true})}async add(e){let t=uuid2(18),i=this.doc(t);return await i.set(e),i}update(e){return new v(this.client,this.collection).update(e)}delete(){return new v(this.client,this.collection).delete()}},Y=G;async function de(a){let e=a.replace(/-----BEGIN PUBLIC KEY-----/,"").replace(/-----END PUBLIC KEY-----/,"").replace(/\s+/g,""),t=typeof atob<"u"?atob(e):Buffer.from(e,"base64").toString("binary"),i=new Uint8Array(t.length);for(let n=0;n<t.length;n++)i[n]=t.charCodeAt(n);return (globalThis.crypto??(await import('crypto')).webcrypto).subtle.importKey("spki",i.buffer,{name:"RSA-OAEP",hash:"SHA-256"},false,["encrypt"])}async function le(a,e){let t=await de(e),i=new TextEncoder().encode(JSON.stringify(a)),n=await(globalThis.crypto??(await import('crypto')).webcrypto).subtle.encrypt({name:"RSA-OAEP"},t,i),s=typeof btoa<"u"?btoa(String.fromCharCode(...new Uint8Array(n))):Buffer.from(n).toString("base64");return JSON.stringify({enc:"rsa",data:s})}var H=class{socket=null;reconnectInterval;maxReconnectDelay;isConnected=false;shouldReconnect=true;options;messageQueue=[];heartbeatInterval=null;connectionTimeout=null;constructor(e){this.options=e,this.reconnectInterval=e.reconnectDelay||2,this.maxReconnectDelay=e.maxReconnectDelay||60,this.log("Transport initialized",e.url);}connect(){if(this.socket){this.log("Socket already exists, skipping connection");return}this.log("Connecting to",this.options.url),this.socket=new WebSocket(this.options.url),this.connectionTimeout=setTimeout(()=>{this.isConnected||(this.log("Connection timeout"),this.socket?.close(),this.handleReconnect());},1e4),this.socket.onopen=()=>{this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.isConnected=true,this.reconnectInterval=this.options.reconnectDelay||2,this.log("Connected to server"),this.options.onOpen?.(),this.startHeartbeat(),this.flushQueue();},this.socket.onmessage=e=>{try{let t=JSON.parse(e.data);this.options.onMessage(t);}catch(t){this.log("Parse error",t),this.options.onError?.(t);}},this.socket.onerror=e=>{this.log("WebSocket error",e),this.options.onError?.(new Error("WebSocket error"));},this.socket.onclose=e=>{this.connectionTimeout&&(clearTimeout(this.connectionTimeout),this.connectionTimeout=null),this.isConnected=false,this.socket=null,this.stopHeartbeat(),this.log("Connection closed",e.code,e.reason),this.options.onClose?.(),e.code!==1e3&&this.shouldReconnect&&this.options.autoReconnect&&this.handleReconnect();};}handleReconnect(){let e=this.reconnectInterval*1e3;this.log(`Reconnecting in ${this.reconnectInterval}s...`),setTimeout(()=>{this.reconnectInterval=Math.min(this.reconnectInterval*2,this.maxReconnectDelay),this.connect();},e);}startHeartbeat(){this.heartbeatInterval=setInterval(()=>{this.isConnected&&this.send({type:"ping",id:Date.now().toString(),ts:Date.now()});},3e4);}stopHeartbeat(){this.heartbeatInterval&&(clearInterval(this.heartbeatInterval),this.heartbeatInterval=null);}flushQueue(){for(this.log("Flushing message queue",this.messageQueue.length);this.messageQueue.length>0;){let e=this.messageQueue.shift();e&&this.send(e);}}send(e){if(this.socket&&this.socket.readyState===WebSocket.OPEN){let t=i=>{try{this.socket.send(i),this.log("Sent message",e);}catch(r){this.log("Send error",r),this.messageQueue.push(e);}};this.options.publicKey?le(e,this.options.publicKey).then(t).catch(i=>{this.log("RSA encrypt error \u2014 sending plaintext",i),t(JSON.stringify(e));}):t(JSON.stringify(e));}else this.log("Socket not ready, queueing message"),this.messageQueue.push(e);}disconnect(){this.shouldReconnect=false,this.stopHeartbeat(),this.socket&&(this.socket.close(1e3,"Client disconnect"),this.socket=null),this.isConnected=false,this.log("Disconnected");}get connected(){return this.isConnected}log(...e){this.options.debug&&console.log("[FlareTransport]",...e);}};var me={id:"_id",createdAt:"_createdAt",updatedAt:"_updatedAt"},re={_id:"id",_createdAt:"createdAt",_updatedAt:"updatedAt"},q=class{transport;config;pendingAcks=new Map;subscriptions=new Map;activeSubscriptions=new Map;queryPresets=new Map;subscriptionErrorHandlers=new Map;subscriptionPermissionHandlers=new Map;subscriptionLastErrors=new Map;offlineQueue=[];currentState="disconnected";connectionListeners=[];errorListeners=[];isDebug=false;socketAuthUid="anon";pendingSubscriptionReplay=false;subscriptionReplayPromise=Promise.resolve();requestTraceSeq=0;requestTimingEnabled=true;httpInFlight=new Map;httpResponseCache=new Map;maxHttpCacheEntries=200;presenceCallbacks=new Map;presenceJoinCbs=new Map;presenceLeaveCbs=new Map;presenceHeartbeatTimer;embedder;vectorSchema=new Map;throwFetchFlareError(e,t,i){let r=e,n=typeof r?.error=="string"&&r.error.length>0?r.error:i,s=typeof r?.message=="string"&&r.message.length>0?r.message:t;throw new h(s,n,e)}nowMs(){return typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now()}normalizeHeaders(e){if(!e)return {};let t={};if(e instanceof Headers)e.forEach((i,r)=>{t[r]=i;});else if(Array.isArray(e))for(let[i,r]of e)t[String(i)]=String(r);else for(let[i,r]of Object.entries(e))t[String(i)]=String(r);return t}redactHeaders(e){let t={...e};for(let i of Object.keys(t)){let r=i.toLowerCase();(r==="authorization"||r==="x-flare-csrf"||r==="x-csrf-token")&&(t[i]="[redacted]");}return t}stableStringify(e){if(e==null)return "";if(typeof e=="string")return e;if(typeof URLSearchParams<"u"&&e instanceof URLSearchParams)return e.toString();if(typeof e!="object")return String(e);if(Array.isArray(e))return `[${e.map(r=>this.stableStringify(r)).join(",")}]`;let t=e;return `{${Object.keys(t).sort().map(r=>`${r}:${this.stableStringify(t[r])}`).join(",")}}`}buildHttpCacheKey(e,t,i,r,n){let o=Object.entries(i).map(([l,g])=>[l.toLowerCase(),g]).sort(([l],[g])=>l.localeCompare(g)).map(([l,g])=>`${l}:${g}`).join("|"),c=this.stableStringify(r);return `${e}|${t}|${n??""}|${o}|${c}`}shouldCacheResponse(e,t){return !!(e==="GET"||e==="POST"&&/\/auth\/refresh(?:\?|$)/.test(t))}rememberHttpResponse(e,t){if(this.httpResponseCache.set(e,t),this.httpResponseCache.size<=this.maxHttpCacheEntries)return;let i=this.httpResponseCache.keys().next().value;i&&this.httpResponseCache.delete(i);}createTimedFetchTrace(e,t,i,r,n,s){return {response:{status:e.status,ok:e.status>=200&&e.status<300,headers:{get:o=>{let c=o.toLowerCase();for(let[l,g]of Object.entries(e.headers))if(l.toLowerCase()===c)return String(g);return null}},json:async()=>e.data??{}},requestId:t,startedAtMs:i,networkMs:s,method:r,url:n}}logHttpTiming(...e){this.requestTimingEnabled&&this.log("[FlareClient][http]",...e);}mergeHeaders(e,t){if(!e)return t;if(e instanceof Headers){let i=new Headers(e);for(let[r,n]of Object.entries(t))i.set(r,n);return i}return Array.isArray(e)?[...e,...Object.entries(t)]:{...e,...t}}toWireField(e){let t=String(e??"").trim();return t&&(me[t]??t)}fromWireField(e){let t=String(e??"").trim();return t&&(re[t]?re[t]:t.startsWith("_")&&!t.startsWith("__")&&t.length>1?t.slice(1):t)}normalizeOutboundData(e){if(Array.isArray(e))return e.map(r=>this.normalizeOutboundData(r));if(!e||typeof e!="object")return e;let t=e,i={};for(let[r,n]of Object.entries(t))i[this.toWireField(r)]=this.normalizeOutboundData(n);return i}normalizeInboundData(e){if(Array.isArray(e))return e.map(r=>this.normalizeInboundData(r));if(!e||typeof e!="object")return e;let t=e,i={};for(let[r,n]of Object.entries(t))i[this.fromWireField(r)]=this.normalizeInboundData(n);return i}getDataMapper(e){let t=this.config.dataMapper;if(!t||typeof t!="object")return null;let i=t[e];return typeof i=="function"?i:null}runMapper(e,t){let i=this.getDataMapper(e);if(!i||t==null||typeof t!="object")return t;try{return i(t)}catch(r){return this.log(`dataMapper for "${e}" failed`,r),t}}applyJoinAliasMappers(e,t){if(!e||typeof e!="object"||!Array.isArray(t)||t.length===0)return e;let i=e;for(let r of t){let n=String(r?.as??"").trim();if(!n)continue;let s=Array.isArray(r?.joins)?r.joins:[],o=i[n],c=o;Array.isArray(o)?c=o.map(l=>this.applyJoinAliasMappers(l,s)):o&&typeof o=="object"&&(c=this.applyJoinAliasMappers(o,s)),c=Array.isArray(c)?c.map(l=>this.runMapper(n,l)):this.runMapper(n,c),c!==o&&(i===e&&(i={...i}),i[n]=c);}return i}mapInboundResult(e,t,i){let r=Array.isArray(i?.joins)?i.joins:[],n=s=>{let o=this.applyJoinAliasMappers(s,r);return this.runMapper(e,o)};return Array.isArray(t)?t.map(s=>n(s)):n(t)}normalizeOutboundAnyFilter(e){return Array.isArray(e.or)?{...e,or:e.or.map(t=>this.normalizeOutboundAnyFilter(t))}:Array.isArray(e.and)?{...e,and:e.and.map(t=>this.normalizeOutboundAnyFilter(t))}:typeof e.field=="string"?{...e,field:this.toWireField(e.field)}:{...e}}normalizeOutboundQuery(e){if(!e||typeof e!="object")return e;let t=e,i={...t},r=n=>{let s={...n};return s.localField=this.toWireField(String(n?.localField??"")),s.foreignField=this.toWireField(String(n?.foreignField??"")),Array.isArray(n.where)&&(s.where=n.where.map(o=>this.normalizeOutboundAnyFilter(o))),Array.isArray(n.orderBy)&&(s.orderBy=n.orderBy.map(o=>({...o,field:this.toWireField(String(o?.field??""))}))),n.groupBy&&typeof n.groupBy=="object"&&Array.isArray(n.groupBy.fields)&&(s.groupBy={...n.groupBy,fields:n.groupBy.fields.map(o=>this.toWireField(String(o??"")))}),Array.isArray(n.having)&&(s.having=n.having.map(o=>({...o,field:this.toWireField(String(o?.field??""))}))),Array.isArray(n.select)&&(s.select=n.select.map(o=>this.toWireField(String(o??"")))),typeof n.distinctField=="string"&&(s.distinctField=this.toWireField(n.distinctField)),n.vectorSearch&&typeof n.vectorSearch=="object"&&(s.vectorSearch={...n.vectorSearch,field:this.toWireField(String(n.vectorSearch.field??""))}),Array.isArray(n.joins)&&(s.joins=n.joins.map(o=>r(o))),s};return Array.isArray(t.where)&&(i.where=t.where.map(n=>this.normalizeOutboundAnyFilter(n))),Array.isArray(t.orderBy)&&(i.orderBy=t.orderBy.map(n=>({...n,field:this.toWireField(String(n?.field??""))}))),t.groupBy&&typeof t.groupBy=="object"&&Array.isArray(t.groupBy.fields)&&(i.groupBy={...t.groupBy,fields:t.groupBy.fields.map(n=>this.toWireField(String(n??"")))}),Array.isArray(t.having)&&(i.having=t.having.map(n=>({...n,field:this.toWireField(String(n?.field??""))}))),Array.isArray(t.select)&&(i.select=t.select.map(n=>this.toWireField(String(n??"")))),typeof t.distinctField=="string"&&(i.distinctField=this.toWireField(t.distinctField)),t.vectorSearch&&typeof t.vectorSearch=="object"&&(i.vectorSearch={...t.vectorSearch,field:this.toWireField(String(t.vectorSearch.field??""))}),Array.isArray(t.joins)&&(i.joins=t.joins.map(n=>r(n))),i}async timedFetch(e,t,i){let r=++this.requestTraceSeq,n=this.nowMs(),s=String(i?.method??"GET").toUpperCase(),o=this.normalizeHeaders(i?.headers),c=this.redactHeaders(o),l=i?.body,g=this.buildHttpCacheKey(s,t,o,l,i?.credentials),y=this.shouldCacheResponse(s,t);this.logHttpTiming(`#${r} ${e} start`,{method:s,url:t,headers:c,hasBody:!!i?.body});try{if(y){let S=this.httpResponseCache.get(g);if(S)return this.logHttpTiming(`#${r} ${e} cache-hit`,{method:s,url:t}),this.createTimedFetchTrace(S,r,n,s,t,0)}let u=this.httpInFlight.get(g);if(u){let S=await u,f=this.nowMs()-n;return this.logHttpTiming(`#${r} ${e} deduped`,{method:s,url:t,networkMs:Number(f.toFixed(2))}),this.createTimedFetchTrace(S,r,n,s,t,f)}let w=this.mergeHeaders(i?.headers,{"x-flare-request-id":String(r)}),C=this.normalizeHeaders(w),F=this.redactHeaders(C),P={timeout:Math.ceil((this.config.connectionTimeout??1e4)/1e3),ignoreKind:!0,headers:C,withCredentials:i?.credentials==="include",returnRawResponse:!0,appendCookiesToBody:!1,appendTimestamp:!1};this.logHttpTiming(`#${r} ${e} request`,{method:s,url:t,headers:F,hasBody:!!i?.body});let I=s.toUpperCase(),x=(async()=>{let S=I==="GET"?await withGet(t,P):I==="PUT"?await withPut(t,l,P):I==="PATCH"?await withPatch(t,l,P):await withPost(t,l,P),f={status:Number(S?.status??0),headers:Object.fromEntries(Object.entries(S?.headers??{}).map(([_,K])=>[_,String(K)])),data:S?.data??{}};return y&&this.rememberHttpResponse(g,f),f})();this.httpInFlight.set(g,x);let M=await x.finally(()=>{this.httpInFlight.delete(g);}),B=this.nowMs()-n;return this.logHttpTiming(`#${r} ${e} response`,{status:M.status,networkMs:Number(B.toFixed(2))}),this.createTimedFetchTrace(M,r,n,s,t,B)}catch(u){let w=this.nowMs()-n;throw this.logHttpTiming(`#${r} ${e} failed`,{networkMs:Number(w.toFixed(2)),message:u?.message??String(u)}),u}}async parseJsonWithTiming(e,t){let i=this.nowMs(),r=await t.response.json().catch(()=>({})),n=this.nowMs()-i,s=this.nowMs()-t.startedAtMs;return this.logHttpTiming(`#${t.requestId} ${e} complete`,{method:t.method,url:t.url,status:t.response.status,networkMs:Number(t.networkMs.toFixed(2)),parseMs:Number(n.toFixed(2)),totalMs:Number(s.toFixed(2))}),r}getHttpBase(){if(this.config.httpBase)return this.config.httpBase.replace(/\/$/,"");let e=new URL(this.config.endpoint);return `${e.protocol}//${e.host}`}log(...e){this.isDebug&&console.log("[FlareClient]",...e);}constructor(e){this.config={autoReconnect:true,reconnectDelay:2,maxReconnectDelay:60,debug:false,connectionTimeout:1e4,...e},this.isDebug=this.config.debug||false,this.requestTimingEnabled=this.config.requestTiming??true;let{hostname:t,port:i,protocol:r}=new URL(this.config.endpoint),n=r==="https:",c=`${n?"wss":"ws"}://${t}:${i||(n?"443":"80")}/?appId=${this.config.appId}${this.config.apiKey?`&apiKey=${this.config.apiKey}`:""}`;this.transport=new H({url:c,publicKey:this.config.publicKey,autoReconnect:this.config.autoReconnect,reconnectDelay:this.config.reconnectDelay,maxReconnectDelay:this.config.maxReconnectDelay,onMessage:l=>this.handleIncoming(l),onOpen:()=>this.onConnected(),onClose:()=>this.onDisconnected(),onError:l=>this.handleTransportError(l),debug:this.isDebug});}connect(){this.setState("connecting"),this.transport.connect();}disconnect(){this.transport.disconnect(),this.setState("disconnected");}get connectionState(){return this.currentState}get isConnected(){return this.currentState==="connected"}onConnectionStateChange(e){return this.connectionListeners.push(e),()=>{this.connectionListeners=this.connectionListeners.filter(t=>t!==e);}}onError(e){return this.errorListeners.push(e),()=>{this.errorListeners=this.errorListeners.filter(t=>t!==e);}}collection(e){return new Y(this,e)}registerQueryPreset(e,t){let i=String(e??"").trim();if(!i)throw new h("Preset name is required",d.QueryFailed);if(typeof t!="function")throw new h(`Query preset "${i}" handler must be a function`,d.QueryFailed);return this.queryPresets.set(i,t),this}registerQueryPresets(e){for(let[t,i]of Object.entries(e??{}))this.registerQueryPreset(t,i);return this}hasQueryPreset(e){return this.queryPresets.has(String(e??"").trim())}applyQueryPreset(e,t,i={}){let r=String(t??"").trim(),n=this.queryPresets.get(r);if(!n)throw new h(`Unknown query preset "${r}"`,d.QueryFailed);let s=n(e,i??{});if(!s||typeof s.get!="function")throw new h(`Query preset "${r}" must return a CollectionReference`,d.QueryFailed);return s}doc(e,t){return t!==void 0?new Q(this,e,t):new v(this,e)}async ping(){let e=Date.now();return await this.send("ping",{}),Date.now()-e}async call(e,t={}){let i=await this.send("call",{topic:e,payload:t});if(!i.success)throw new h(i.error??`CALL "${e}" failed`,d.QueryFailed);return i.result}async query(e,t={}){let i=await this.send("query",{collection:e,query:t});return this.mapInboundResult(e,i.data,t)??[]}setEmbedder(e){this.embedder=e;}markVectorField(e,t,i={dimensions:1536}){this.vectorSchema.has(e)||this.vectorSchema.set(e,new Map),this.vectorSchema.get(e).set(t,i);}async embedVectorFields(e,t){let i=this.vectorSchema.get(e);if(!i)return t;let r={...t};for(let[n,s]of i){let o=r[n];if(typeof o=="string"){let c=s.embed??this.embedder;if(!c){this.log(`[vector] No embedder for field "${n}" \u2014 storing raw text`);continue}r[n]=await c(o);}}return r}async joinPresence(e,t){return await this.send("presence_join",{room:e,meta:t}),this._startPresenceHeartbeat(e,t),()=>this.leavePresence(e)}async leavePresence(e){await this.send("presence_leave",{room:e}),this._stopPresenceHeartbeat();}onPresenceState(e,t){return this.presenceCallbacks.has(e)||this.presenceCallbacks.set(e,[]),this.presenceCallbacks.get(e).push(t),()=>{let i=this.presenceCallbacks.get(e)??[];this.presenceCallbacks.set(e,i.filter(r=>r!==t));}}onPresenceJoin(e,t){return this.presenceJoinCbs.has(e)||this.presenceJoinCbs.set(e,[]),this.presenceJoinCbs.get(e).push(t),()=>{let i=this.presenceJoinCbs.get(e)??[];this.presenceJoinCbs.set(e,i.filter(r=>r!==t));}}onPresenceLeave(e,t){return this.presenceLeaveCbs.has(e)||this.presenceLeaveCbs.set(e,[]),this.presenceLeaveCbs.get(e).push(t),()=>{let i=this.presenceLeaveCbs.get(e)??[];this.presenceLeaveCbs.set(e,i.filter(r=>r!==t));}}_startPresenceHeartbeat(e,t){this.presenceHeartbeatTimer||(this.presenceHeartbeatTimer=setInterval(()=>{this.isConnected&&this.send("presence_heartbeat",{meta:t}).catch(()=>{});},2e4));}_stopPresenceHeartbeat(){this.presenceHeartbeatTimer&&(clearInterval(this.presenceHeartbeatTimer),this.presenceHeartbeatTimer=void 0);}async syncOffline(){if(this.offlineQueue.length===0)return;this.log("Syncing offline operations",this.offlineQueue.length);let e=[...this.offlineQueue];this.offlineQueue.length=0;let t=await this.send("offline_sync",{operations:e});t.conflicts&&t.conflicts.length>0&&(this.log("Offline sync conflicts",t.conflicts),t.conflicts.forEach(i=>{let r=e.find(n=>n.id===i.operationId);r&&this.offlineQueue.push(r);}));}async beforeActivateSubscription(e){}async activateSubscription(e){if(!this.isConnected){this.pendingSubscriptionReplay=true;return}await this.beforeActivateSubscription(e),this.subscriptions.set(e.liveId,e.callback);try{let t=await this.send("subscribe",{collection:e.collection,docId:e.docId,query:e.query,skipSnapshot:e.options.skipSnapshot});if(!this.activeSubscriptions.has(e.baseId)){this.subscriptions.delete(e.liveId);return}t.subscriptionId&&t.subscriptionId!==e.liveId&&(this.subscriptions.delete(e.liveId),e.liveId=t.subscriptionId,this.subscriptions.set(e.liveId,e.callback),this.log("Subscription remapped",e.baseId,"\u2192",e.liveId));}catch(t){this.subscriptions.delete(e.liveId),this.pendingSubscriptionReplay=true;let i=this.toSubscriptionError(t);this.emitSubscriptionError(e.baseId,i),this.log("Subscription failed",t);}}toSubscriptionError(e){let t=e instanceof Error?e.message:String(e??"Unknown subscription error"),i=t.match(/^\[([^\]]+)\]\s*(.*)$/),r=i?.[1],n=(i?.[2]??t).trim()||t,s=r===d.PermissionDenied||t.includes(d.PermissionDenied);return {code:r,message:n,permissionDenied:s,raw:e}}emitSubscriptionError(e,t){this.subscriptionLastErrors.set(e,t);let i=this.subscriptionErrorHandlers.get(e);if(i)for(let r of i)try{r(t);}catch(n){this.log("Subscription error callback failed",n);}if(t.permissionDenied){let r=this.subscriptionPermissionHandlers.get(e);if(r)for(let n of r)try{n(t);}catch(s){this.log("Subscription permission callback failed",s);}}}async replayActiveSubscriptions(){if(!this.isConnected){this.pendingSubscriptionReplay=true;return}let e=Array.from(this.activeSubscriptions.values());if(e.length===0){this.pendingSubscriptionReplay=false;return}this.pendingSubscriptionReplay=false,this.subscriptionReplayPromise=this.subscriptionReplayPromise.then(async()=>{for(let t of e){if(!this.activeSubscriptions.has(t.baseId))continue;let i=t.liveId;this.subscriptions.delete(i),t.liveId=t.baseId,i&&await this.send("unsubscribe",{subscriptionId:i}).catch(()=>{}),await this.activateSubscription(t);}}).catch(t=>{this.pendingSubscriptionReplay=true,this.log("Subscription replay failed",t);}),await this.subscriptionReplayPromise;}subscribe(e,t,i,r,n,s={}){this.log("Creating subscription",e,t,i);let o={baseId:e,liveId:e,collection:t,docId:i,query:r,callback:n,options:s};this.activeSubscriptions.set(e,o),this.subscriptionErrorHandlers.has(e)||this.subscriptionErrorHandlers.set(e,new Set),this.subscriptionPermissionHandlers.has(e)||this.subscriptionPermissionHandlers.set(e,new Set),this.activateSubscription(o).catch(g=>{this.log("Subscription activation failed",g);});let c=()=>{let y=this.activeSubscriptions.get(e)?.liveId??e;this.log("Unsubscribing",y),this.activeSubscriptions.delete(e),this.subscriptions.delete(y),this.subscriptionErrorHandlers.delete(e),this.subscriptionPermissionHandlers.delete(e),this.subscriptionLastErrors.delete(e),this.isConnected&&this.send("unsubscribe",{subscriptionId:y}).catch(u=>this.log("Unsubscribe failed",u));},l=c;return l.unsubscribe=c,l.onError=g=>{this.subscriptionErrorHandlers.get(e)?.add(g);let y=this.subscriptionLastErrors.get(e);if(y)try{g(y);}catch(u){this.log("Subscription error callback failed",u);}return l},l.onPermissionDenied=g=>{this.subscriptionPermissionHandlers.get(e)?.add(g);let y=this.subscriptionLastErrors.get(e);if(y?.permissionDenied)try{g(y);}catch(u){this.log("Subscription permission callback failed",u);}return l},l.catch=g=>l.onError(g),l}async send(e,t){if(e==="write"&&t.collection&&t.data){let i=await this.embedVectorFields(t.collection,t.data);t={...t,data:this.normalizeOutboundData(i)};}return (e==="subscribe"||e==="query")&&t?.query&&(t={...t,query:this.normalizeOutboundQuery(t.query)}),new Promise((i,r)=>{let n=uuid2(18),s={id:n,type:e,ts:Date.now(),...t};this.pendingAcks.set(n,o=>{o.type==="error"?r(new Error(`[${o.code}] ${o.message}`)):i(o);}),this.isConnected?this.transport.send(s):(this.log("Queueing message for offline",s),this.offlineQueue.push(s),r(new Error("Not connected - message queued"))),setTimeout(()=>{this.pendingAcks.has(n)&&(this.pendingAcks.delete(n),r(new Error("Request timeout")));},this.config.connectionTimeout);})}handleTransportError(e){this.log("Transport error",e),this.errorListeners.forEach(t=>{try{t(e);}catch(i){this.log("Error listener error",i);}});}onConnected(){this.setState("connected"),this.log("Connected to FlareServer"),this.activeSubscriptions.size>0&&(this.pendingSubscriptionReplay=true),this.offlineQueue.length>0&&this.syncOffline().catch(e=>{this.log("Offline sync failed",e);});}onDisconnected(){this.currentState!=="disconnected"&&this.setState("reconnecting"),this.activeSubscriptions.size>0&&(this.pendingSubscriptionReplay=true),this.log("Disconnected from FlareServer");}setState(e){this.currentState!==e&&(this.currentState=e,this.log("Connection state changed",e),this.connectionListeners.forEach(t=>{try{t(e);}catch(i){this.log("Connection listener error",i);}}));}handleIncoming(e){if(this.log("Received message",e.type,e),e.type==="query_result"&&Array.isArray(e.data)&&(e={...e,data:this.normalizeInboundData(e.data)}),e.type==="ack"||e.type==="pong"||e.type==="auth_ok"||e.type==="call_response"||e.type==="query_result"){let t=this.pendingAcks.get(e.correlationId||e.id);t&&(t(e),this.pendingAcks.delete(e.correlationId||e.id));return}if(e.type==="error"){this.log("Server error",e.code,e.message);let t=new Error(`[${e.code}] ${e.message}`);this.errorListeners.forEach(r=>{try{r(t);}catch(n){this.log("Error listener error",n);}});let i=Array.from(this.activeSubscriptions.values()).find(r=>r.liveId===e.correlationId||r.baseId===e.correlationId);if(i&&this.emitSubscriptionError(i.baseId,{code:typeof e.code=="string"?e.code:void 0,message:String(e.message??"Subscription error"),permissionDenied:e.code===d.PermissionDenied,raw:e}),e.correlationId){let r=this.pendingAcks.get(e.correlationId);r&&(r(e),this.pendingAcks.delete(e.correlationId));}return}if(e.type==="presence_state"){(this.presenceCallbacks.get(e.room)??[]).forEach(i=>{try{i(e.members);}catch{}});return}if(e.type==="presence_join"){(this.presenceJoinCbs.get(e.room)??[]).forEach(i=>{try{i(e);}catch{}});return}if(e.type==="presence_leave"){(this.presenceLeaveCbs.get(e.room)??[]).forEach(i=>{try{i(e.uid);}catch{}});return}if(e.type==="snapshot"){let t=this.subscriptions.get(e.subscriptionId);if(t){let i=Array.from(this.activeSubscriptions.values()).find(o=>o.liveId===e.subscriptionId),r=this.normalizeInboundData(Array.isArray(e.data)?e.data:e.data!=null?[e.data]:[]),n=this.mapInboundResult(String(e.collection??i?.collection??""),r,i?.query),s={type:"snapshot",subscriptionId:e.subscriptionId,collection:e.collection,data:Array.isArray(n)?n:[]};try{t(s);}catch(o){this.log("Subscription callback error",o);}}return}if(e.type==="change"){let t=this.subscriptions.get(e.subscriptionId);if(t){let i=Array.from(this.activeSubscriptions.values()).find(o=>o.liveId===e.subscriptionId),r=e.operation==="delete"?null:this.normalizeInboundData(e.data),n=e.operation==="delete"?null:this.mapInboundResult(String(e.collection??i?.collection??""),r,i?.query),s={type:"change",subscriptionId:e.subscriptionId,collection:e.collection,docId:e.docId,operation:e.operation,data:n};try{t(s);}catch(o){this.log("Subscription callback error",o);}}}}};var L=class a extends q{static AUTH_TRACE_STORAGE_KEY="zuzjs.flare.auth.trace";authToken;userId;authGuard;authConfig;csrfToken;csrfInitPromise;csrfBootstrapAttempted=false;socketAuthSyncPromise;pushServiceWorkerInitPromise;authSession=null;authBootstrapPromise;authBootstrapAttempted=false;authStateListeners=[];authConfigListeners=[];currentProfile=void 0;isAuthTraceEnabled(){let e=globalThis?.__FLARE_AUTH_TRACE__;if(e===true||e===false)return e;if(typeof window<"u")try{let i=window.localStorage.getItem(a.AUTH_TRACE_STORAGE_KEY);if(i==="1"||i==="true")return !0;if(i==="0"||i==="false")return !1}catch{}let t=globalThis?.process?.env?.FLARE_AUTH_TRACE;return t==="1"||t==="true"}setAuthTrace(e,t=true){if(globalThis.__FLARE_AUTH_TRACE__=e,t&&typeof window<"u")try{window.localStorage.setItem(a.AUTH_TRACE_STORAGE_KEY,e?"1":"0");}catch{}}traceAuth(e,t){if(!this.isAuthTraceEnabled()||typeof console>"u")return;let i={event:e,appId:this.config.appId,ts:Date.now(),uid:this.authSession?.uid??this.userId??null,hasAccessToken:!!this.authSession?.accessToken,hasRefreshToken:!!this.authSession?.refreshToken,...t??{}};console.info("[FLARE_AUTH_TRACE]",i);}getDefaultCsrfCookieName(){return `__flare_csrf_${this.config.appId.replace(/[^a-zA-Z0-9_-]/g,"_")}`}getCsrfCookieName(){return this.authConfig?.cookie?.csrfTokenName??this.getDefaultCsrfCookieName()}getCsrfToken(){return this.getCookieValue(this.getCsrfCookieName())??this.csrfToken??null}getCookieValue(e){if(typeof document>"u")return null;let t=document.cookie.split(";").map(r=>r.trim()).find(r=>r.startsWith(`${e}=`)||r.startsWith(`${encodeURIComponent(e)}=`));if(!t)return null;let i=t.indexOf("=");return i>=0?decodeURIComponent(t.slice(i+1)):null}extractCsrfToken(e,t){let i=e,r=typeof i?.csrfToken=="string"?String(i.csrfToken):typeof i?.csrf_token=="string"?String(i.csrf_token):void 0;if(r)return r;if(!t)return;let n=t.headers.get("x-flare-csrf")??t.headers.get("x-csrf-token")??t.headers.get("csrf-token");return typeof n=="string"&&n.length>0?n:void 0}getCsrfHeaders(){let e=this.getCsrfToken();return e?{"x-flare-csrf":e}:{}}setCsrfToken(e){this.csrfToken=e,this.csrfBootstrapAttempted=true,this.log("CSRF token injected",{length:e.length});}async ensureCsrfProtection(){if(this.getCsrfToken()){this.csrfBootstrapAttempted=true;return}if(this.config.httpBase){this.csrfBootstrapAttempted=true;return}this.csrfBootstrapAttempted||(this.csrfInitPromise||(this.csrfBootstrapAttempted=true,this.csrfInitPromise=this.loadAuthConfig().then(()=>{}).finally(()=>{this.csrfInitPromise=void 0;})),await this.csrfInitPromise,this.getCsrfToken()||this.log("CSRF token unavailable after auth config load",{hasAuthConfig:!!this.authConfig,csrfCookieName:this.getCsrfCookieName()}));}async loadAuthConfig(){let e=this.getHttpBase(),t=new URLSearchParams({appId:this.config.appId});this.config.apiKey&&t.set("apiKey",this.config.apiKey);let i=`${e}/auth/config?${t.toString()}`,r=await this.timedFetch("loadAuthConfig",i,{credentials:"include",headers:this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}}),n=await this.parseJsonWithTiming("loadAuthConfig",r);return r.response.ok||this.throwFetchFlareError(n,"Failed to load auth config",d.QueryFailed),this.authConfig=n,this.csrfToken=this.extractCsrfToken(n,r.response)??this.csrfToken,this.authConfigListeners.forEach(s=>{try{s(this.authConfig);}catch(o){this.log("Auth config listener error",o);}}),this.authConfig}async fetchAuthConfig(){return this.authConfig?this.authConfig:this.loadAuthConfig()}onAuthConfigLoaded(e){return this.authConfigListeners.push(e),this.authConfig&&e(this.authConfig),()=>{this.authConfigListeners=this.authConfigListeners.filter(t=>t!==e);}}setProfile(e){this.currentProfile=e;}setAuthSession(e,t="unknown"){let i=this.authSession?.uid??this.userId??null;this.authSession=e,e?(this.authToken=e.accessToken,this.userId=e.uid,this.traceAuth("setAuthSession",{source:t,nextUid:e.uid,previousUid:i,mode:"set"})):(this.traceAuth("setAuthSession",{source:t,nextUid:null,previousUid:i,mode:"clear"}),this.authToken=void 0,this.userId=void 0,this.currentProfile=void 0,this.httpResponseCache.clear(),this.httpInFlight.clear());let r=this.authSession?{...this.authSession,...this.currentProfile??{}}:null;this.authStateListeners.forEach(n=>{try{n(r);}catch(s){this.log("Auth state listener error",s);}});}onAuthStateChanged(e){this.authStateListeners.push(e);let t=()=>{let n=this.authSession?{...this.authSession,...this.currentProfile??{}}:null;try{e(n);}catch(s){this.log("Auth state listener error during initialization",s);}},i=!this.authSession&&!this.authBootstrapAttempted&&typeof window<"u"&&typeof document<"u"&&!!this.config.httpBase,r=!this.authSession&&!!this.authBootstrapPromise;return i?(this.traceAuth("onAuthStateChanged.bootstrap.start",{listenerCount:this.authStateListeners.length}),this.authBootstrapAttempted=true,this.authBootstrapPromise||(this.authBootstrapPromise=this.refreshAuthSession().catch(()=>null).then(()=>{}).finally(()=>{this.authBootstrapPromise=void 0;})),this.authBootstrapPromise.finally(()=>{this.authStateListeners.includes(e)&&(this.traceAuth("onAuthStateChanged.bootstrap.done",{hasSession:!!this.authSession}),this.authSession||t());})):r?(this.traceAuth("onAuthStateChanged.bootstrap.wait",{listenerCount:this.authStateListeners.length}),this.authBootstrapPromise?.finally(()=>{this.authStateListeners.includes(e)&&(this.authSession||t());})):t(),()=>{this.authStateListeners=this.authStateListeners.filter(n=>n!==e);}}onAuthStateChange(e){return this.onAuthStateChanged(e)}get currentUser(){return this.currentProfile}getCurrentUser(){return this.currentUser}async syncSocketAuth(e){if(!this.isConnected)return;let t=await this.send("auth",e?{token:e}:{});if(t.type!=="auth_ok")throw new h("Socket auth sync failed",d.AuthenticationFailed);if(!e||t.uid==="anon"){this.authToken=void 0,this.userId=void 0,await this.updateSocketIdentity("anon");return}this.authToken=typeof t.token=="string"?t.token:e,this.userId=typeof t.uid=="string"?t.uid:this.userId,await this.updateSocketIdentity(typeof t.uid=="string"?t.uid:this.userId);}async updateSocketIdentity(e,t=false){let i=typeof e=="string"&&e.length>0?e:"anon",r=i!==this.socketAuthUid;this.socketAuthUid=i,(r||t||this.pendingSubscriptionReplay)&&this.activeSubscriptions.size>0&&await this.replayActiveSubscriptions();}async beforeActivateSubscription(e){if(!this.isConnected)return;let t=this.authSession;!t?.accessToken||!t.uid||this.socketAuthUid!==t.uid&&(this.socketAuthSyncPromise||(this.socketAuthSyncPromise=this.syncSocketAuth(t.accessToken).catch(i=>{throw this.log("Socket auth sync failed before subscribe",i),i}).finally(()=>{this.socketAuthSyncPromise=void 0;})),await this.socketAuthSyncPromise);}onConnected(){super.onConnected(),this.authSession?.accessToken&&this.syncSocketAuth(this.authSession.accessToken).catch(e=>{this.log("Socket auth sync failed after connect",e);});}handleIncoming(e){if(e.type==="auth_ok"&&!e.correlationId){let t=typeof e.token=="string"?e.token:void 0,i=typeof e.uid=="string"?e.uid:void 0;this.updateSocketIdentity(i,this.pendingSubscriptionReplay).catch(r=>{this.log("Socket identity update failed",r);}),t&&i&&i!=="anon"&&i!=="__admin__"?this.fetchAuthMe(t).then(r=>{this.setAuthSession({uid:i,accessToken:t,refreshToken:this.authSession?.refreshToken??null,email:r?.email??null,emailVerified:r?.email_verified});}).catch(()=>{this.setAuthSession({uid:i,accessToken:t,refreshToken:this.authSession?.refreshToken??null});}):i==="anon"&&this.authSession&&!this.socketAuthSyncPromise&&!this.authBootstrapPromise&&this.setAuthSession(null,"socket.auth_ok.anon");}super.handleIncoming(e);}async auth(e){let t=await this.send("auth",{token:e});if(t.type==="auth_ok"){let i=t.token??e;this.authToken=i,this.userId=t.uid;let r=await this.fetchAuthMe(i).catch(()=>null);return this.setAuthSession({uid:t.uid??t.id,accessToken:i,refreshToken:this.authSession?.refreshToken??null,email:r?.email??null,emailVerified:r?.email_verified}),await this.updateSocketIdentity(t.uid),this.log("Authentication successful",t.uid),{uid:t.uid,token:t.token??e}}throw new h("Authentication failed",d.AuthenticationFailed)}async signInWithEmailAndPassword(e,t,i){try{let r=await this.requestEmailPasswordToken(e,t,i?.scope),n=await this.auth(r.access_token),s=await this.fetchAuthMe(r.access_token).catch(()=>null);return this.setAuthSession({uid:n.uid,accessToken:r.access_token,refreshToken:r.refresh_token,provider:r.provider,email:s?.email??e,emailVerified:s?.email_verified}),this.log("Credentials sign-in successful",n.uid),{...n,kind:r.kind,accessToken:r.access_token,refreshToken:r.refresh_token,authToken:r}}catch(r){let n=/invalid_email|user.not.found|no user/i.test(r?.message??"");if(i?.createIfMissing&&n){let s=await this.createUserWithEmail(e,t,{scope:i.scope,signInIfAllowed:true});if("verificationRequired"in s&&s.verificationRequired)throw new h("Email verification required before sign-in",d.AuthenticationFailed);return {uid:s.uid,token:s.token,accessToken:s.accessToken,refreshToken:s.refreshToken,authToken:s.authToken,created:true}}throw r instanceof h?r:new h(r instanceof Error?r.message:"Sign-in with email/password failed",r.error??r.code??d.AuthenticationFailed,r)}}async signInWithEmail(e,t,i){return this.signInWithEmailAndPassword(e,t,i)}async createUserWithEmail(e,t,i){let r=await this.registerWithEmail(e,t,i);if(r.verification_required)return {kind:r.kind,verificationRequired:true,emailSent:!!r.email_sent,preview:r.preview};let n=String(r.access_token??"");if(!n)throw new h("User created but no access token returned",d.AuthenticationFailed);let s={access_token:n,refresh_token:r.refresh_token?String(r.refresh_token):null,expires_in:r.expires_in?Number(r.expires_in):null,token_type:String(r.token_type??"Bearer"),scope:r.scope?String(r.scope):null,profile:null,provider:"credentials"},o=await this.auth(n),c=await this.fetchAuthMe(n).catch(()=>null);return this.setAuthSession({uid:o.uid,accessToken:n,refreshToken:s.refresh_token,provider:"credentials",email:c?.email??e,emailVerified:c?.email_verified}),{...o,accessToken:n,refreshToken:s.refresh_token,authToken:s,verificationRequired:false,emailSent:!!r.email_sent,preview:r.preview}}async createUserWithEmailAndPassword(e,t,i){return this.createUserWithEmail(e,t,i)}async signInOrCreateWithEmail(e,t,i){try{return {...await this.signInWithEmailAndPassword(e,t,{scope:i?.scope}),created:!1}}catch(r){if(!/invalid_email|user.not.found|no user/i.test(r?.message??""))throw r;let s=await this.createUserWithEmail(e,t,{scope:i?.scope,additionalParams:i?.additionalParams,signInIfAllowed:true});return "verificationRequired"in s&&s.verificationRequired?{...s,created:true}:{...s,created:true}}}async signInOrCreateWithEmailAndPassword(e,t,i){return this.signInOrCreateWithEmail(e,t,i)}async sendEmailVerification(e){let t=this.getHttpBase();await this.ensureCsrfProtection();let i=await this.timedFetch("sendEmailVerification",`${t}/auth/verify/send?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:JSON.stringify({email:e,appId:this.config.appId,apiKey:this.config.apiKey})}),r=await this.parseJsonWithTiming("sendEmailVerification",i);return i.response.ok||this.throwFetchFlareError(r,"Failed to send verification email",d.AuthenticationFailed),r}async verifyEmailWithCode(e,t){let i=this.getHttpBase();await this.ensureCsrfProtection();let r=await this.timedFetch("verifyEmailWithCode",`${i}/auth/verify/confirm?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:JSON.stringify({email:e,code:t,appId:this.config.appId,apiKey:this.config.apiKey})}),n=await this.parseJsonWithTiming("verifyEmailWithCode",r);return r.response.ok||this.throwFetchFlareError(n,"Email verification failed",d.AuthenticationFailed),n}async confirmEmailLink(e,t){let i=this.getHttpBase();await this.ensureCsrfProtection();let r=await this.timedFetch("confirmEmailLink",`${i}/auth/verify/confirm?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:JSON.stringify({token:e,email:t,appId:this.config.appId,apiKey:this.config.apiKey})}),n=await this.parseJsonWithTiming("confirmEmailLink",r);return r.response.ok||this.throwFetchFlareError(n,"Email link verification failed",d.AuthenticationFailed),n}async sendAccountRecovery(e){let t=this.getHttpBase();await this.ensureCsrfProtection();let i=await this.timedFetch("sendAccountRecovery",`${t}/auth/recover/send?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:JSON.stringify({email:e,appId:this.config.appId,apiKey:this.config.apiKey})}),r=await this.parseJsonWithTiming("sendAccountRecovery",i);return i.response.ok||this.throwFetchFlareError(r,"Failed to send recovery email",d.AuthenticationFailed),r}async recoverAccountWithCode(e,t,i){let r=this.getHttpBase();await this.ensureCsrfProtection();let n=await this.timedFetch("recoverAccountWithCode",`${r}/auth/recover/confirm?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:JSON.stringify({email:e,code:t,newPassword:i,appId:this.config.appId,apiKey:this.config.apiKey})}),s=await this.parseJsonWithTiming("recoverAccountWithCode",n);return n.response.ok||this.throwFetchFlareError(s,"Account recovery failed",d.AuthenticationFailed),s}async recoverAccountWithToken(e,t){let i=this.getHttpBase();await this.ensureCsrfProtection();let r=await this.timedFetch("recoverAccountWithToken",`${i}/auth/recover/confirm?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:JSON.stringify({token:e,newPassword:t,appId:this.config.appId,apiKey:this.config.apiKey})}),n=await this.parseJsonWithTiming("recoverAccountWithToken",r);return r.response.ok||this.throwFetchFlareError(n,"Account recovery failed",d.AuthenticationFailed),n}toUint8ArrayFromBase64Url(e){let t=e.replace(/-/g,"+").replace(/_/g,"/"),i="=".repeat((4-t.length%4)%4),r=t+i,n=atob(r),s=new Uint8Array(n.length);for(let o=0;o<n.length;o+=1)s[o]=n.charCodeAt(o);return s}encodePushTokenFromSubscription(e){let t=e.toJSON(),i=String(t.endpoint??"").trim(),r=String(t.keys?.p256dh??"").trim(),n=String(t.keys?.auth??"").trim(),s=JSON.stringify({endpoint:i,p256dh:r,auth:n});return `webpush:${btoa(s)}`}async fetchPushSetupConfig(){let e=this.getHttpBase(),t=new URLSearchParams({appId:this.config.appId});this.config.apiKey&&t.set("apiKey",this.config.apiKey);let i=`${e}/push/config?${t.toString()}`,r=await this.timedFetch("fetchPushSetupConfig",i,{method:"GET",credentials:"include",headers:this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}}),n=await this.parseJsonWithTiming("fetchPushSetupConfig",r);r.response.ok||this.throwFetchFlareError(n,"Failed to fetch push setup config",d.QueryFailed);let s=String(n.vapidPublicKey??"").trim(),o=String(n.serviceWorkerPath??"").trim();if(o.startsWith("/"))try{let l=new URL(e,typeof window<"u"?window.location.origin:"http://localhost").pathname.replace(/\/+$/,"");l&&l!=="/"&&!o.startsWith(`${l}/`)&&(o=`${l}${o}`);}catch{}if(!s||!o)throw new h("Push setup response is missing vapidPublicKey or serviceWorkerPath",d.ParseError,n);return {vapidPublicKey:s,serviceWorkerPath:o}}async setupPushServiceWorker(){return typeof window>"u"||typeof navigator>"u"||!("serviceWorker"in navigator)?null:(this.pushServiceWorkerInitPromise||(this.pushServiceWorkerInitPromise=(async()=>{let e=await this.fetchPushSetupConfig(),t=new URL(e.serviceWorkerPath,window.location.origin);if(t.origin!==window.location.origin)throw new h("Service worker URL must be same-origin with the app",d.WriteFailed);return await navigator.serviceWorker.register(t.pathname+t.search,{scope:"/"})})().catch(e=>{throw this.log("Push service worker setup failed",e),e})),this.pushServiceWorkerInitPromise)}async requestPushPermission(){if(typeof window>"u"||typeof Notification>"u")throw new h("Push permission can only be requested in browser runtime",d.WriteFailed);let e=await Notification.requestPermission();if(e!=="granted")throw new h(`Push permission is ${e}`,d.PermissionDenied);return e}async acquireBrowserPushToken(e={}){if(typeof window>"u"||typeof navigator>"u")throw new h("Push token acquisition can only run in browser runtime",d.WriteFailed);if(!("serviceWorker"in navigator))throw new h("Service worker is not supported in this browser",d.WriteFailed);if(!("PushManager"in window))throw new h("Push manager is not supported in this browser",d.WriteFailed);await this.requestPushPermission();let t=e.applicationServerKey?null:await this.fetchPushSetupConfig(),i=e.serviceWorkerRegistration??await this.setupPushServiceWorker()??await navigator.serviceWorker.ready,r=e.subscription??await i.pushManager.getSubscription();if(e.forceResubscribe&&r&&(await r.unsubscribe().catch(()=>{}),r=null),!r){let s=e.applicationServerKey??t?.vapidPublicKey;if(!s)throw new h("No VAPID public key available for push subscription",d.WriteFailed);r=await i.pushManager.subscribe({userVisibleOnly:true,applicationServerKey:this.toUint8ArrayFromBase64Url(s)});}return {token:this.encodePushTokenFromSubscription(r),subscription:r}}async enableBrowserPush(e={}){let{token:t,subscription:i}=await this.acquireBrowserPushToken(e);return {...await this.registerPushToken({token:t,platform:e.platform??"web",deviceId:e.deviceId,topics:e.topics,authAppId:e.authAppId}),subscription:i}}async registerPushToken(e){let t=this.getHttpBase();await this.ensureCsrfProtection();let i=String(e.token??"").trim();if(!i)throw new h("Push token is required",d.WriteFailed);let r=await this.timedFetch("registerPushToken",`${t}/notify/token?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{},...this.authSession?.accessToken?{Authorization:`Bearer ${this.authSession.accessToken}`}:{}},body:JSON.stringify({appId:this.config.appId,token:i,platform:e.platform,deviceId:e.deviceId,topics:e.topics,...e.authAppId?{authAppId:e.authAppId}:{}})}),n=await this.parseJsonWithTiming("registerPushToken",r);return r.response.ok||this.throwFetchFlareError(n,"Failed to register push token",d.WriteFailed),{registered:!!n.registered,appId:String(n.appId??this.config.appId),uid:String(n.uid??this.authSession?.uid??""),token:String(n.token??i),...typeof n.platform=="string"?{platform:n.platform}:{}}}async unregisterPushToken(e,t){let i=this.getHttpBase();await this.ensureCsrfProtection();let r=String(e??"").trim();if(!r)throw new h("Push token is required",d.WriteFailed);let n=await this.timedFetch("unregisterPushToken",`${i}/notify/token?appId=${encodeURIComponent(this.config.appId)}`,{method:"DELETE",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{},...this.authSession?.accessToken?{Authorization:`Bearer ${this.authSession.accessToken}`}:{}},body:JSON.stringify({appId:this.config.appId,token:r,...t?{authAppId:t}:{}})}),s=await this.parseJsonWithTiming("unregisterPushToken",n);return n.response.ok||this.throwFetchFlareError(s,"Failed to unregister push token",d.WriteFailed),{unregistered:!!s.unregistered,appId:String(s.appId??this.config.appId),token:String(s.token??r),removed:!!s.removed}}async sendPushNotification(e){let t=this.getHttpBase();await this.ensureCsrfProtection();let i=await this.timedFetch("sendPushNotification",`${t}/system/apps/${encodeURIComponent(this.config.appId)}/notifications/send`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.authSession?.accessToken?{Authorization:`Bearer ${this.authSession.accessToken}`}:{},...e.authAppId?{"x-flare-auth-app-id":e.authAppId}:{}},body:JSON.stringify({...e,appId:this.config.appId})}),r=await this.parseJsonWithTiming("sendPushNotification",i);return i.response.ok||this.throwFetchFlareError(r,"Failed to send push notification",d.WriteFailed),{sent:!!r.sent,appId:String(r.appId??this.config.appId),targetCount:Number(r.targetCount??0),successCount:Number(r.successCount??0),failureCount:Number(r.failureCount??0),invalidatedTokenCount:Number(r.invalidatedTokenCount??0),dryRun:!!r.dryRun}}async sendEmail(e){let t=this.getHttpBase();await this.ensureCsrfProtection();let i=await this.timedFetch("sendEmail",`${t}/system/apps/${encodeURIComponent(this.config.appId)}/email/send`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.authSession?.accessToken?{Authorization:`Bearer ${this.authSession.accessToken}`}:{},...e.authAppId?{"x-flare-auth-app-id":e.authAppId}:{}},body:JSON.stringify({...e,appId:this.config.appId})}),r=await this.parseJsonWithTiming("sendEmail",i);return i.response.ok||this.throwFetchFlareError(r,"Failed to send template email",d.WriteFailed),{sent:!!r.sent,appId:String(r.appId??this.config.appId),tag:String(r.tag??e.tag??""),recipientCount:Number(r.recipientCount??0),acceptedCount:Number(r.acceptedCount??0),rejectedCount:Number(r.rejectedCount??0),...typeof r.includeVerificationLink=="boolean"?{includeVerificationLink:r.includeVerificationLink}:{},...typeof r.linkId=="string"?{linkId:r.linkId}:{},...typeof r.verifyUrl=="string"?{verifyUrl:r.verifyUrl}:{},...typeof r.messageId=="string"?{messageId:r.messageId}:{}}}async verifyEmailLink(e){let t=this.getHttpBase(),i=String(e.token??"").trim();if(!i)throw new h("Verification token is required",d.WriteFailed);let r=await this.timedFetch("verifyEmailLink",`${t}/email/link/verify?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{},...this.authSession?.accessToken?{Authorization:`Bearer ${this.authSession.accessToken}`}:{},...e.authAppId?{"x-flare-auth-app-id":e.authAppId}:{}},body:JSON.stringify({appId:this.config.appId,apiKey:this.config.apiKey,token:i,...e.tag?{tag:e.tag}:{},...e.email?{email:e.email}:{},...e.authAppId?{authAppId:e.authAppId}:{}})}),n=await this.parseJsonWithTiming("verifyEmailLink",r);return r.response.ok||this.throwFetchFlareError(n,"Failed to verify email link",d.WriteFailed),{verified:!!(n.verified??n.accepted),alreadyVerified:!!(n.alreadyVerified??n.alreadyAccepted),appId:String(n.appId??this.config.appId),linkId:String(n.linkId??""),email:String(n.email??""),tag:String(n.tag??e.tag??""),...typeof n.verifiedAt=="string"?{verifiedAt:n.verifiedAt}:{},...typeof n.acceptedByUid=="string"?{acceptedByUid:n.acceptedByUid}:{}}}async signIn(e,t,i){let r=typeof e?.signIn=="function",n=r?e:await this.getAuthGuard(),s=r?t:e,o=r?i:t;return n.signIn(s,o)}async signInWithGoogle(e){return this.signIn("google",e)}async signInWithGitHub(e){return this.signIn("github",e)}async signInWithFacebook(e){return this.signIn("facebook",e)}async signInWithDropbox(e){return this.signIn("dropbox",e)}async handleSignInRedirect(e,t=false){let i=typeof e?.handleRedirect=="function",r=i?e:await this.getAuthGuard(),n=i?t:typeof e=="boolean"?e:false,s=await r.handleRedirect(n);if(!s||!s.access_token||!s.provider)return null;let o=await this.exchangeProviderToken(s.provider,s.access_token),c=await this.auth(o.token),l=await this.fetchAuthMe(o.token).catch(()=>null);return this.setAuthSession({uid:c.uid,accessToken:o.token,refreshToken:s.refresh_token,provider:s.provider,email:l?.email??null,emailVerified:l?.email_verified}),{...c,authToken:s,provider:s.provider}}async exchangeProviderToken(e,t){let i=`${this.getHttpBase()}/auth/exchange`;await this.ensureCsrfProtection();let r=await this.timedFetch("exchangeProviderToken",i,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders()},body:JSON.stringify({appId:this.config.appId,client_id:this.config.apiKey,provider:e,access_token:t})}),n=await this.parseJsonWithTiming("exchangeProviderToken",r);if(r.response.ok||this.throwFetchFlareError(n,"OAuth token exchange failed",d.AuthenticationFailed),!n?.token)throw new h("OAuth token exchange failed",d.ParseError,n);return {token:String(n.token)}}async getAuthGuard(){if(this.authGuard)return this.authGuard;let e=await this.fetchAuthConfig();if(!e.enabled)throw new h("Authentication is disabled for this app",d.AuthenticationFailed);let t=this.getHttpBase(),i=`${t}/auth/oauth/token?appId=${encodeURIComponent(this.config.appId)}`,r=[],n=(s,o)=>({...o,token_url:i,tokenParams:{...o.tokenParams??{},provider:s}});if(e.providers.credentials?.enabled&&r.push({...Credentials({clientId:this.config.apiKey}),token_url:`${t}/auth/token?appId=${encodeURIComponent(this.config.appId)}`,createUserUrl:`${t}/auth/register?appId=${encodeURIComponent(this.config.appId)}`,createUserGrantType:"create_user"}),e.providers.anonymous?.enabled&&r.push({...Anonymous({clientId:this.config.apiKey}),token_url:`${t}/auth/token?appId=${encodeURIComponent(this.config.appId)}`}),e.providers.google?.enabled&&e.providers.google.clientId&&r.push(n("google",Google({clientId:e.providers.google.clientId,scopes:e.providers.google.scopes}))),e.providers.github?.enabled&&e.providers.github.clientId&&r.push(n("github",GitHub({clientId:e.providers.github.clientId,scopes:e.providers.github.scopes}))),e.providers.facebook?.enabled&&e.providers.facebook.clientId&&r.push(n("facebook",Facebook({clientId:e.providers.facebook.clientId,scopes:e.providers.facebook.scopes}))),e.providers.dropbox?.enabled&&e.providers.dropbox.clientId&&r.push(n("dropbox",Dropbox({clientId:e.providers.dropbox.clientId,scopes:e.providers.dropbox.scopes}))),e.providers.apple?.enabled&&e.providers.apple.clientId&&r.push(n("apple",Apple({clientId:e.providers.apple.clientId,scopes:e.providers.apple.scopes}))),e.providers.twitter?.enabled&&e.providers.twitter.clientId&&r.push(n("twitter",Twitter({clientId:e.providers.twitter.clientId,scopes:e.providers.twitter.scopes}))),r.length===0)throw new h("No authentication providers are enabled for this app",d.AuthenticationFailed);return this.authGuard=new AuthGuard({providers:r,redirectUri:e.redirectUri}),this.authGuard}async refreshAuthSession(e){let t=this.getHttpBase();await this.ensureCsrfProtection(),this.traceAuth("refreshAuthSession.start",{providedRefreshToken:!!e,hasSessionBefore:!!this.authSession});let i=await this.timedFetch("refreshAuthSession",`${t}/auth/refresh?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:JSON.stringify({appId:this.config.appId,apiKey:this.config.apiKey,...e?{refresh_token:e}:{}})}),r=await this.parseJsonWithTiming("refreshAuthSession",i);if(!i.response.ok){if(i.response.status===401)return this.traceAuth("refreshAuthSession.response",{status:i.response.status,ok:false,reason:"unauthorized"}),this.setAuthSession(null,"refreshAuthSession.401"),await this.syncSocketAuth(null).catch(()=>{}),null;this.throwFetchFlareError(r,"Failed to refresh auth session",d.AuthenticationFailed);}let n=String(r.access_token??"");if(!n)throw new h("Refresh succeeded but no access token was returned",d.ParseError);let s=await this.fetchAuthMe(n).catch(()=>null),o={uid:String(s?.id??this.authSession?.uid??this.userId??""),accessToken:n,refreshToken:r.refresh_token?String(r.refresh_token):this.authSession?.refreshToken??null,provider:this.authSession?.provider,email:s?.email??this.authSession?.email??null,emailVerified:s?.email_verified};if(s){try{delete s.kind,s.uid=s.id??s.uid,delete s.id;}catch{}this.setProfile(s);}return this.traceAuth("refreshAuthSession.response",{status:i.response.status,ok:true,nextUid:o.uid,hasProfile:!!s}),this.setAuthSession(o,"refreshAuthSession.success"),await this.syncSocketAuth(n).catch(()=>{}),o}async issueSsrToken(e=120){let t=this.getHttpBase();await this.ensureCsrfProtection();let i=await this.timedFetch("issueSsrToken",`${t}/auth/ssr/token?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:JSON.stringify({appId:this.config.appId,apiKey:this.config.apiKey,ttlSeconds:e})}),r=await this.parseJsonWithTiming("issueSsrToken",i);i.response.ok||this.throwFetchFlareError(r,"Failed to mint SSR token",d.AuthenticationFailed);let n=String(r.token??"");if(!n)throw new h("SSR token response is missing token",d.ParseError,r);return {token:n,token_type:String(r.token_type??"Bearer"),expires_in:Number(r.expires_in??0),uid:String(r.uid??""),role:String(r.role??"user"),...typeof r.email=="string"?{email:r.email}:{}}}async signOut(){try{if(this.authSession?.accessToken||this.authSession?.refreshToken||this.config.httpBase){let t=this.getHttpBase();await this.ensureCsrfProtection(),await this.timedFetch("signOut",`${t}/auth/logout?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{},...this.authSession?.accessToken?{Authorization:`Bearer ${this.authSession.accessToken}`}:{}},body:JSON.stringify({appId:this.config.appId,apiKey:this.config.apiKey,refresh_token:this.authSession?.refreshToken})}).catch(()=>{});}}finally{this.setAuthSession(null,"signOut.finally"),await this.syncSocketAuth(null).catch(()=>{});}this.log("Signed out");}async registerWithEmail(e,t,i){let r=this.getHttpBase();await this.ensureCsrfProtection();let n=new URLSearchParams;n.set("appId",this.config.appId),n.set("client_id",this.config.apiKey??""),n.set("grant_type","create_user"),n.set("email",e),n.set("password",t),i?.scope?.length&&n.set("scope",i.scope.join(" ")),i?.additionalParams&&n.set("additional_params",JSON.stringify(i.additionalParams));let s=await this.timedFetch("registerWithEmail",`${r}/auth/register?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/x-www-form-urlencoded",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:n.toString()}),o=await this.parseJsonWithTiming("registerWithEmail",s);return !s.response.ok&&s.response.status!==202&&this.throwFetchFlareError(o,"User creation failed",d.WriteFailed),o}async requestEmailPasswordToken(e,t,i){let r=this.getHttpBase();await this.ensureCsrfProtection();let n=new URLSearchParams;n.set("appId",this.config.appId),n.set("client_id",this.config.apiKey??""),n.set("grant_type","password"),n.set("email",e),n.set("password",t),i?.length&&n.set("scope",i.join(" "));let s=await this.timedFetch("requestEmailPasswordToken",`${r}/auth/token?appId=${encodeURIComponent(this.config.appId)}`,{method:"POST",credentials:"include",headers:{"Content-Type":"application/x-www-form-urlencoded",...this.getCsrfHeaders(),...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}},body:n.toString()}),o=await this.parseJsonWithTiming("requestEmailPasswordToken",s);return s.response.ok||this.throwFetchFlareError(o,"Sign-in with email/password failed",d.AuthenticationFailed),{kind:String(o.kind),access_token:String(o.access_token??""),refresh_token:o.refresh_token?String(o.refresh_token):null,expires_in:o.expires_in?Number(o.expires_in):null,token_type:String(o.token_type??"Bearer"),scope:o.scope?String(o.scope):null,profile:null,provider:"credentials"}}async fetchAuthMe(e){let t=this.getHttpBase(),i=new URLSearchParams({appId:this.config.appId});this.config.apiKey&&i.set("apiKey",this.config.apiKey);let r=`${t}/auth/me?${i.toString()}`,n=await this.timedFetch("fetchAuthMe",r,{credentials:"include",headers:{Authorization:`Bearer ${e}`,...this.config.apiKey?{"x-flare-api-key":this.config.apiKey}:{}}}),s=await this.parseJsonWithTiming("fetchAuthMe",n);return n.response.ok||this.throwFetchFlareError(s,"Failed to fetch profile",d.QueryFailed),s}};var Z=class extends L{autoPushRegisteredIdentity;constructor(e){super(e),this.log("FlareClient initialized",e),e.pushNotifications===true&&this.enableAutoPushNotificationsAfterAuth();}enableAutoPushNotificationsAfterAuth(){let e=async()=>{let t=this.authSession,i=String(t?.uid??"").trim()||"anon",r=String(t?.accessToken??"").trim(),n=i!=="anon"&&r?i:"anon";if(this.autoPushRegisteredIdentity!==n)try{await this.autoEnablePushNotifications(),this.autoPushRegisteredIdentity=n;}catch(s){this.log("Auto push enable failed",s);}};this.onAuthStateChanged(()=>{e().catch(()=>{});}),e().catch(()=>{});}async autoEnablePushNotifications(){await this.setupPushServiceWorker().catch(()=>{}),await this.requestPushPermission();let{token:e}=await this.acquireBrowserPushToken();await this.registerPushToken({token:e,platform:"web",topics:[this.config.appId]});}},ie=Z;function X(a){return `__flare_csrf_${a.replace(/[^a-zA-Z0-9_-]/g,"_")}`}function Re(a){return `__flare_csrf_${a.replace(/[^a-zA-Z0-9_-]/g,"_")}`}function U(a,e){let t=e.toLowerCase();for(let[i,r]of Object.entries(a??{}))if(i.toLowerCase()===t&&typeof r=="string")return r}function Ee(a){let e=U(a,"set-cookie");if(typeof e=="string"&&e.length>0)return [e];for(let[t,i]of Object.entries(a??{}))if(t.toLowerCase()==="set-cookie"&&Array.isArray(i))return i.filter(r=>typeof r=="string");return []}function Fe(a,e){for(let t of a){let i=t.split(";").map(c=>c.trim()),[r]=i;if(!r)continue;let n=r.indexOf("=");if(n<=0)continue;let s=decodeURIComponent(r.slice(0,n)),o=r.slice(n+1);if(s===e)return decodeURIComponent(o)}}async function xe(a){let e=new URL("/auth/config",a.endpoint);return e.searchParams.set("appId",a.appId),a.apiKey&&e.searchParams.set("apiKey",a.apiKey),await withGet(e.toString(),{ignoreKind:true,withCredentials:true,returnRawResponse:true,headers:a.apiKey?{"x-flare-api-key":a.apiKey}:{},appendCookiesToBody:false,appendTimestamp:false}).catch(()=>null)}async function ne(a){let e=await xe(a),t=e?.data,i=e?.headers??{},r=U(i,"x-flare-csrf")??U(i,"x-csrf-token")??U(i,"csrf-token");if(typeof r=="string"&&r.length>0)return {csrfToken:r,...t};let n=t?.cookie?.csrfTokenName,s=n&&n.length>0?n:Re(a.appId),o=Ee(i),c=Fe(o,s);if(typeof c=="string"&&c.length>0)return {csrfToken:c,...t}}function se(a,e,t){return `${encodeURIComponent(a)}=${encodeURIComponent(e)}; HttpOnly; SameSite=Strict; Path=/; Max-Age=${t}`}function Me(a){let e=a.proxyCookieName??X(a.appId),t=a.proxyCookieMaxAge??3600;return async function(r){let n=await ne(a),s=n?.csrfToken,o=new Headers({"Content-Type":"application/json"});return s&&o.set("Set-Cookie",se(e,s,t)),new Response(JSON.stringify({csrfToken:s??null,...n}),{status:200,headers:o})}}function Be(a){let e=a.proxyCookieName??X(a.appId),t=a.proxyCookieMaxAge??3600;return async function(r,n){if(r.method!=="GET"&&r.method!=="HEAD"){n.status(405).json({error:"Method not allowed"});return}let o=(await ne(a))?.csrfToken;o&&n.setHeader("Set-Cookie",se(e,o,t)),n.status(200).json({csrfToken:o??null});}}function Qe(a,e,t){let i=t??X(e);if(a instanceof Request){let s=(a.headers.get("cookie")??"").split(";").map(c=>c.trim()).find(c=>c.startsWith(`${encodeURIComponent(i)}=`)||c.startsWith(`${i}=`));if(!s)return null;let o=s.indexOf("=");return o>=0?decodeURIComponent(s.slice(o+1)):null}let{cookies:r}=a;return typeof r?.get=="function"?r.get(i)?.value??null:r&&typeof r=="object"?r[i]??null:null}function Oe(a,e){let t={};return a&&(t["x-flare-csrf"]=a),e?.accessToken&&(t.Authorization=`Bearer ${e.accessToken}`),e?.apiKey&&(t["x-flare-api-key"]=e.apiKey),t}var _e=a=>a==="guest"?"auth == null":a==="auth"?"auth != null":"true",Ne=(a,e)=>{let t=String(e??"").trim();return t?a==="true"?t:`(${a}) && (${t})`:a},De=a=>{let e=String(a??"").trim();if(!e||e==="false")return {auth:"any"};if(e==="auth != null")return {auth:"auth"};if(e==="auth == null")return {auth:"guest"};if(e==="true")return {auth:"any"};let t=e.match(/^\((auth != null|auth == null|true)\)\s*&&\s*\((.+)\)$/);if(t)return {auth:oe(t[1]),condition:t[2].trim()};let i=e.match(/^(auth != null|auth == null|true)\s*&&\s*(.+)$/);return i?{auth:oe(i[1]),condition:i[2].trim()}:{auth:"any",condition:e}},oe=a=>{let e=String(a??"").trim();return e==="auth == null"?"guest":e==="auth != null"?"auth":"any"},_t=a=>{let e={};for(let t of a){let i=String(t.collection||"").trim();if(!i)continue;let r=i==="any"?"*":i,n=Ne(_e(t.auth),t.condition);e[r]={".read":t.permissions.includes("read")?n:"false",".create":t.permissions.includes("create")?n:"false",".update":t.permissions.includes("update")?n:"false",".delete":t.permissions.includes("delete")?n:"false"};}return e},Nt=a=>Object.entries(a).map(([e,t],i)=>{let r=t?.[".read"],n=t?.[".create"],s=t?.[".update"],o=t?.[".delete"],c=t?.[".write"],l=[];typeof r=="string"&&r.trim()!=="false"&&l.push("read");let g=typeof n=="string"&&n.trim()!=="false"||typeof c=="string"&&c.trim()!=="false",y=typeof s=="string"&&s.trim()!=="false"||typeof c=="string"&&c.trim()!=="false",u=typeof o=="string"&&o.trim()!=="false"||typeof c=="string"&&c.trim()!=="false";g&&l.push("create"),y&&l.push("update"),u&&l.push("delete");let C=De(r||n||s||o||c);return {id:`${e}-${i}`,name:e==="*"?"All Collections":e,auth:C.auth,collection:e==="*"?"any":e,condition:C.condition,permissions:l}});var He=(y=>(y.authEmailNotVerified="auth/email-not-verified",y.authEmailAlreadyVerified="auth/email-already-verified",y.authInvalidToken="auth/invalid-token",y.authUserDisabled="auth/user-disabled",y.authUserNotFound="auth/user-not-found",y.authWrongPassword="auth/wrong-password",y.authEmailAlreadyInUse="auth/email-already-in-use",y.authInvalidEmail="auth/invalid-email",y.authWeakPassword="auth/weak-password",y.authTooManyRequests="auth/too-many-requests",y.authInternalError="auth/internal-error",y))(He||{});var qe=(f=>(f.health="health",f.authConfig="auth_config",f.authRegistration="auth/registration",f.authRegistrationVerificationRequired="auth/registration-verification-required",f.authSession="auth/session",f.authExchange="auth/exchange",f.authLogout="auth/logout",f.authSsrBridge="auth/ssr_bridge",f.authSsrVerify="auth/ssr_verify",f.accountRecovery="account/recovery",f.emailVerification="email/verification",f.verificationDispatch="verification/dispatch",f.authProfile="auth/profile",f.adminToken="admin/token",f.documentDelete="document/delete",f.documentsDelete="documents/delete",f.documents="documents",f.document="document",f.documentCreate="document/create",f.documentUpdate="document/update",f.oauthProviderResponse="oauth_provider_response",f.success="success",f.response="response",f))(qe||{});var T=null,O=null,W=null,Le=a=>JSON.stringify({endpoint:a.endpoint,appId:a.appId,apiKey:a.apiKey,publicKey:a.publicKey,autoReconnect:a.autoReconnect,reconnectDelay:a.reconnectDelay,maxReconnectDelay:a.maxReconnectDelay,dataMapperKeys:Object.keys(a.dataMapper??{}).sort()}),Kt=a=>{let e=Le(a);if(T&&W!==e&&(T.disconnect(),T=null,O=null,W=null),!T){T=new ie(a),W=e;let t=typeof window<"u"&&typeof document<"u",i=typeof process<"u"&&typeof process.env?.NEXT_RUNTIME=="string";(t||!i)&&T.connect(),t&&T.setupPushServiceWorker().catch(()=>{}),O=new Proxy(T,{get(r,n,s){if(n==="onAuthStateChange")return r.onAuthStateChanged.bind(r);if(n==="onAuthConfigLoaded")return r.onAuthConfigLoaded.bind(r);let o=Reflect.get(r,n,s);return typeof o=="function"?o.bind(r):o}});}return O??T},Jt=()=>O??T,jt=()=>{T&&(T.disconnect(),T=null,O=null,W=null);};
|
|
2
|
+
export{Y as CollectionReference,v as DocumentQueryBuilder,Q as DocumentReference,ce as FlareAction,ie as FlareClient,h as FlareError,He as FlareErrors,ue as FlareEvent,qe as FlareResponseCodes,Oe as buildFlareHeaders,Kt as connectApp,Me as createCsrfProxy,Be as createCsrfProxyHandler,jt as disconnectFlare,Qe as extractCsrfFromRequest,_t as flareRulesToSecurityMap,Jt as getFlare,te as parseValue,V as parseWhereCondition,Nt as securityMapToFlareRules};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zuzjs/flare",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.10",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"core",
|
|
6
6
|
"zuz",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"bugs": {
|
|
21
21
|
"url": "https://github.com/zuzjs/flare-client/issues"
|
|
22
22
|
},
|
|
23
|
-
"homepage": "https://flare.
|
|
23
|
+
"homepage": "https://flare.zuz.com.pk",
|
|
24
24
|
"main": "./dist/index.cjs",
|
|
25
25
|
"module": "./dist/index.js",
|
|
26
26
|
"types": "./dist/index.d.ts",
|