@zuzjs/flare-admin 0.1.3 → 0.1.5
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 +210 -0
- package/dist/index.cjs +4 -4
- package/dist/index.d.cts +484 -1
- package/dist/index.d.ts +57 -2
- package/dist/index.js +3 -3
- package/dist/lib/grpc.d.ts +11 -0
- package/dist/lib/storage.d.ts +98 -0
- package/dist/serverTimestamp.d.ts +13 -0
- package/dist/types/index.d.ts +320 -0
- package/package.json +4 -1
- package/proto/admin.proto +129 -0
- package/proto/app.proto +69 -0
- package/proto/auth.proto +70 -0
- package/proto/flare.proto +11 -0
- package/proto/query.proto +109 -0
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import L from'ws';function k(o){let e=[];for(let[n,r]of Object.entries(o))if(typeof r=="string"){let t=r.match(/^(>=|<=|!=|>|<|==)\s*(.+)$/);if(t){let[,i,s]=t;e.push({field:n,op:i,value:I(s.trim())});}else e.push({field:n,op:"==",value:r});}else Array.isArray(r)?e.push({field:n,op:"in",value:r}):e.push({field:n,op:"==",value:r});return e}function I(o){return isNaN(Number(o))?o==="true"?true:o==="false"?false:o==="null"?null:o:Number(o)}function F(){return Math.random().toString(36).slice(2,12)+Date.now().toString(36)}function $(o,e){let n=o.dataMapper;if(!n||typeof n!="object")return null;let r=n[e];return typeof r=="function"?r:null}function q(o,e,n){let r=$(o,e);if(!r||n==null||typeof n!="object")return n;try{return r(n)}catch{return n}}function E(o,e,n){if(!e||typeof e!="object"||!Array.isArray(n)||n.length===0)return e;let r=e;for(let t of n){let i=String(t?.as??"").trim();if(!i)continue;let s=Array.isArray(t?.joins)?t.joins:[],a=r[i],c=a;Array.isArray(a)?c=a.map(l=>E(o,l,s)):a&&typeof a=="object"&&(c=E(o,a,s)),c=Array.isArray(c)?c.map(l=>q(o,i,l)):q(o,i,c),c!==a&&(r===e&&(r={...r}),r[i]=c);}return r}function f(o,e,n,r){let t=Array.isArray(r?.joins)?r.joins:[],i=s=>{let a=E(o,s,t);return q(o,e,a)};return Array.isArray(n)?n.map(s=>i(s)):i(n)}var g=class{constructor(e,n,r){this.cfg=e;this.collection=n;this.id=r;}get baseUrl(){return `${this.cfg.serverUrl}/admin/db/${this.cfg.appId}/${this.collection}/${this.id}`}get headers(){return {"Content-Type":"application/json",Authorization:`Bearer ${this.cfg.adminKey}`}}async request(e,n){let r;try{r=await fetch(this.baseUrl,{method:e,headers:this.headers,...n!==void 0?{body:JSON.stringify(n)}:{}});}catch(i){let s=i instanceof Error?i.message:String(i);throw new Error(`[flare-admin] Network error (${e} ${this.baseUrl}): ${s}`)}let t=await r.json().catch(()=>({}));if(!r.ok)throw new Error(`[flare-admin] ${e} ${this.baseUrl} failed (HTTP ${r.status}): `+(t.error??"Unknown error"));return t}async get(){let e;try{e=await fetch(this.baseUrl,{headers:this.headers});}catch(t){let i=t instanceof Error?t.message:String(t);throw new Error(`[flare-admin] Network error (GET ${this.baseUrl}): ${i}`)}if(e.status===404)return null;let n=await e.json().catch(()=>({}));if(!e.ok)throw new Error(`[flare-admin] GET ${this.baseUrl} failed (HTTP ${e.status}): `+(n.error??"Unknown error"));return f(this.cfg,this.collection,n.data)??null}async set(e){await this.request("PUT",e);}async update(e){await this.request("PATCH",e);}async delete(){await this.request("DELETE");}parent(){return new m(this.cfg,this.collection)}};var m=class o{constructor(e,n){this.cfg=e;this.name=n;this.sq={};this.opts={allowSensitiveAuthUserFields:true};}get baseUrl(){return `${this.cfg.serverUrl}/admin/db/${this.cfg.appId}/${this.name}`}get headers(){return {"Content-Type":"application/json",Authorization:`Bearer ${this.cfg.adminKey}`}}clone(e){let n=new o(this.cfg,this.name);return n.sq={...this.sq,...e},n.opts={...this.opts},n}allowSensitiveAuthUserFields(e=true){let n=this.clone({});return n.opts.allowSensitiveAuthUserFields=!!e,n}normalizeFilterValue(e,n){return e==="in"||e==="not-in"||e==="array-contains-any"?Array.isArray(n)?n:[n]:n}toQueryFilters(e){return k(e).map(r=>typeof r=="object"&&r!=null&&"field"in r&&"op"in r?{...r,value:this.normalizeFilterValue(r.op,r.value)}:r)}appendAndFilters(e){return this.clone({where:[...this.sq.where??[],...e]})}appendOrFilters(e){let n=[...this.sq.where??[]];if(n.length===0)return this.clone({where:[{or:e}]});let r=n[0];if(n.length===1&&typeof r=="object"&&r!=null&&"or"in r)return this.clone({where:[{or:[...r.or,...e]}]});let i=n.length===1?n[0]:{and:n};return this.clone({where:[{or:[i,...e]}]})}appendFilters(e,n){return n==="or"?this.appendOrFilters(e):this.appendAndFilters(e)}appendOperatorFilter(e,n,r,t){return this.appendFilters([{field:e,op:n,value:this.normalizeFilterValue(n,r)}],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,n){return this.appendOperatorFilter(e,"in",n,"and")}andIn(e,n){return this.appendOperatorFilter(e,"in",n,"and")}orIn(e,n){return this.appendOperatorFilter(e,"in",n,"or")}notIn(e,n){return this.appendOperatorFilter(e,"not-in",n,"and")}andNotIn(e,n){return this.appendOperatorFilter(e,"not-in",n,"and")}orNotIn(e,n){return this.appendOperatorFilter(e,"not-in",n,"or")}arrayContains(e,n){return this.appendOperatorFilter(e,"array-contains",n,"and")}andArrayContains(e,n){return this.appendOperatorFilter(e,"array-contains",n,"and")}orArrayContains(e,n){return this.appendOperatorFilter(e,"array-contains",n,"or")}arrayContainsAny(e,n){return this.appendOperatorFilter(e,"array-contains-any",n,"and")}andArrayContainsAny(e,n){return this.appendOperatorFilter(e,"array-contains-any",n,"and")}orArrayContainsAny(e,n){return this.appendOperatorFilter(e,"array-contains-any",n,"or")}some(e,n){return this.appendOperatorFilter(e,"elem-match",n,"and")}andSome(e,n){return this.appendOperatorFilter(e,"elem-match",n,"and")}orSome(e,n){return this.appendOperatorFilter(e,"elem-match",n,"or")}like(e,n){return this.appendOperatorFilter(e,"like",n,"and")}andLike(e,n){return this.appendOperatorFilter(e,"like",n,"and")}orLike(e,n){return this.appendOperatorFilter(e,"like",n,"or")}notLike(e,n){return this.appendOperatorFilter(e,"not-like",n,"and")}andNotLike(e,n){return this.appendOperatorFilter(e,"not-like",n,"and")}orNotLike(e,n){return this.appendOperatorFilter(e,"not-like",n,"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.latest()}oldest(){return this.clone({orderBy:[...this.sq.orderBy??[],{field:"_seq",dir:"asc"}]})}orderBy(e,n="asc"){return this.clone({orderBy:[...this.sq.orderBy??[],{field:e,dir:n}]})}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,n){return this.aggregate({fn:"sum",field:e,alias:n??`sum_${e}`})}avg(e,n){return this.aggregate({fn:"avg",field:e,alias:n??`avg_${e}`})}min(e,n){return this.aggregate({fn:"min",field:e,alias:n??`min_${e}`})}max(e,n){return this.aggregate({fn:"max",field:e,alias:n??`max_${e}`})}distinct(e,n){return this.aggregate({fn:"distinct",field:e,alias:n??`distinct_${e}`})}groupBy(...e){return this.clone({groupBy:{fields:e}})}having(e,n,r){return this.clone({having:[...this.sq.having??[],{field:e,op:n,value:r}]})}buildStructuredJoin(e,n){let r={from:String(e??""),localField:String(n?.source??""),foreignField:String(n?.target??""),as:String(n?.as??""),single:n?.single};return Array.isArray(n?.where)&&(r.where=n.where),Array.isArray(n?.orderBy)&&(r.orderBy=n.orderBy),typeof n?.limit=="number"&&(r.limit=n.limit),typeof n?.offset=="number"&&(r.offset=n.offset),Array.isArray(n?.select)&&(r.select=n.select),Array.isArray(n?.joins)&&(r.joins=n.joins.map(t=>this.buildStructuredJoin(String(t?.collection??""),t))),r}cloneStructuredJoin(e){let n={...e};return Array.isArray(e.where)&&(n.where=e.where.map(r=>({...r}))),Array.isArray(e.orderBy)&&(n.orderBy=e.orderBy.map(r=>({...r}))),Array.isArray(e.select)&&(n.select=[...e.select]),Array.isArray(e.joins)&&(n.joins=e.joins.map(r=>this.cloneStructuredJoin(r))),n}appendNestedJoinByAlias(e,n,r){for(let t of e){if(t.as===n)return t.joins=[...t.joins??[],r],true;if(Array.isArray(t.joins)&&this.appendNestedJoinByAlias(t.joins,n,r))return true}return false}parseRelationRef(e){let r=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(!r)throw new Error(`Invalid relation format: "${e}". Expected "source.path->collection.target"`);return {source:r[1],collection:r[2],target:r[3],alias:r[4]}}join(e,n){let r=this.buildStructuredJoin(e,n);return this.clone({joins:[...this.sq.joins??[],r]})}joinNested(e,n,r){let t=String(e??"").trim();if(!t)throw new Error("joinNested requires parentAlias");let i=(this.sq.joins??[]).map(a=>this.cloneStructuredJoin(a));if(i.length===0)throw new Error(`joinNested parent alias "${t}" not found`);let s=this.buildStructuredJoin(n,r);if(!this.appendNestedJoinByAlias(i,t,s))throw new Error(`joinNested parent alias "${t}" not found`);return this.clone({joins:i})}Join(e,n){return this.join(e,n)}JoinNested(e,n,r){return this.joinNested(e,n,r)}withRelation(e,n={}){let r=this.parseRelationRef(e);return this.join(r.collection,{...n,source:r.source,target:r.target,as:n.as??r.alias??r.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(n=>({...n}))),Array.isArray(this.sq.orderBy)&&(e.orderBy=this.sq.orderBy.map(n=>({...n}))),Array.isArray(this.sq.aggregate)&&(e.aggregate=this.sq.aggregate.map(n=>({...n}))),Array.isArray(this.sq.having)&&(e.having=this.sq.having.map(n=>({...n}))),Array.isArray(this.sq.select)&&(e.select=[...this.sq.select]),Array.isArray(this.sq.joins)&&(e.joins=this.sq.joins.map(n=>this.cloneStructuredJoin(n))),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.name,query:e}}async get(){let e=new URL(this.baseUrl);e.searchParams.set("query",JSON.stringify(this.sq)),e.searchParams.set("allowSensitiveAuthUserFields",this.opts.allowSensitiveAuthUserFields?"1":"0");let n;try{n=await fetch(e.toString(),{headers:this.headers});}catch(i){let s=i instanceof Error?i.message:String(i);throw new Error(`[flare-admin] Network error (GET ${this.baseUrl}): ${s}`)}let r=await n.json().catch(()=>({}));if(!n.ok)throw new Error(`[flare-admin] GET ${this.baseUrl} failed (HTTP ${n.status}): ${r.error??"Unknown error"}`);return f(this.cfg,this.name,r.data,this.sq)??[]}async first(){let e=await this.get();return e.length>0?e[0]:null}async last(){let e=await this.get();return e.length>0?e[e.length-1]:null}async add(e){let n;try{n=await fetch(this.baseUrl,{method:"POST",headers:this.headers,body:JSON.stringify(e)});}catch(t){let i=t instanceof Error?t.message:String(t);throw new Error(`[flare-admin] Network error (POST ${this.baseUrl}): ${i}`)}let r=await n.json().catch(()=>({}));if(!n.ok)throw new Error(`[flare-admin] POST ${this.baseUrl} failed (HTTP ${n.status}): ${r.error??"Unknown error"}`);return new g(this.cfg,this.name,r.id)}async deleteMany(){let e;try{e=await fetch(this.baseUrl,{method:"DELETE",headers:this.headers,body:JSON.stringify({where:this.sq.where??[]})});}catch(r){let t=r instanceof Error?r.message:String(r);throw new Error(`[flare-admin] Network error (DELETE ${this.baseUrl}): ${t}`)}let n=await e.json().catch(()=>({}));if(!e.ok)throw new Error(`[flare-admin] DELETE ${this.baseUrl} failed (HTTP ${e.status}): ${n.error??"Unknown error"}`);return n.deleted??0}doc(e){return new g(this.cfg,this.name,e)}};var A=class{constructor(e){this.cfg=e;}collection(e){return new m(this.cfg,e)}};var y=class{constructor(e){this.cfg=e;}async createCustomToken(e,n={}){let r=`${this.cfg.serverUrl.replace(/\/$/,"")}/admin/token`,t=JSON.stringify({appId:this.cfg.appId,uid:String(e),role:n.role??"user",claims:n.claims??{},ttl:n.ttl??this.cfg.defaultTtl}),i;try{i=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.cfg.adminKey}`},body:t});}catch(a){let c=a instanceof Error?a.message:String(a);throw new Error(`[flare-admin] Could not reach FlareServer at "${r}": ${c}
|
|
2
|
-
Make sure FLARE_URL is set correctly and the server is running.`)}let
|
|
3
|
-
Make sure FLARE_URL is set correctly and the server is running.`)}let s;try{s=await i.json();}catch{throw new Error(`[flare-admin] Server returned non-JSON response (status ${i.status})`)}if(!i.ok)throw new Error(`[flare-admin] getTicket failed (HTTP ${i.status}): `+(s.error??"Unknown error"));let a=s.ticket;if(!a||typeof a.ticket!="string")throw new Error('[flare-admin] Server response missing "ticket" object');return {ticket:String(a.ticket),tag:String(a.tag??""),uuid:String(a.uuid??""),expires_at:String(a.expires_at??""),one_time:!!(a.one_time??true),uid:String(a.uid??String(e)),role:String(a.role??n.role??"user"),ip:String(a.ip??"unknown")}}};var w=class{constructor(e){this.cfg=e;}get baseUrl(){return `${this.cfg.serverUrl.replace(/\/$/,"")}/admin/notify/${this.cfg.appId}`}get headers(){return {"Content-Type":"application/json",Authorization:`Bearer ${this.cfg.adminKey}`}}async send(e){let n;try{n=await fetch(`${this.baseUrl}/send`,{method:"POST",headers:this.headers,body:JSON.stringify(e??{})});}catch(t){let i=t instanceof Error?t.message:String(t);throw new Error(`[flare-admin] Network error (POST ${this.baseUrl}/send): ${i}`)}let r=await n.json().catch(()=>({}));if(!n.ok)throw new Error(`[flare-admin] Notification send failed (HTTP ${n.status}): `+(r.error??"Unknown error"));return {sent:!!r.sent,appId:String(r.appId??this.cfg.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 tokens(){let e;try{e=await fetch(`${this.baseUrl}/tokens`,{method:"GET",headers:this.headers});}catch(r){let t=r instanceof Error?r.message:String(r);throw new Error(`[flare-admin] Network error (GET ${this.baseUrl}/tokens): ${t}`)}let n=await e.json().catch(()=>({}));if(!e.ok)throw new Error(`[flare-admin] Tokens fetch failed (HTTP ${e.status}): `+(n.error??"Unknown error"));return {appId:String(n.appId??this.cfg.appId),hasPushGateway:!!n.hasPushGateway,total:Number(n.total??0),tokens:Array.isArray(n.tokens)?n.tokens:[]}}};var C=class{constructor(e){this.cfg=e;this.ws=null;this.pendingAcks=new Map;this.subscriptions=new Map;this.activeSubscriptions=new Map;this.subscriptionErrorHandlers=new Map;this.subscriptionPermissionHandlers=new Map;this.subscriptionLastErrors=new Map;this.connected=false;this.shouldReconnect=true;this.reconnectDelay=2e3;let n=e.serverUrl.replace(/^http/,"ws");this.wsUrl=`${n}/?appId=${encodeURIComponent(e.appId)}&adminKey=${encodeURIComponent(e.adminKey)}`,this._readyPromise=new Promise(r=>{this._readyResolve=r;}),this._connect();}ready(){return this._readyPromise}disconnect(){this.shouldReconnect=false,this.ws?.close(1e3,"Admin disconnect"),this.ws=null,this.connected=false;}send(e,n){return new Promise((r,t)=>{let i=F(),s={id:i,type:e,ts:Date.now(),...n},a=setTimeout(()=>{this.pendingAcks.delete(i),t(new Error(`[flare-admin] WS request timeout (${e})`));},1e4);this.pendingAcks.set(i,l=>{clearTimeout(a),l.type==="error"?t(new Error(`[flare-admin] Server error: ${l.message}`)):r(l);});let c=()=>this.ws?.send(JSON.stringify(s));this.connected&&this.ws?.readyState===L.OPEN?c():this.ready().then(c).catch(t);})}subscribe(e,n,r,t,i={}){let s=F(),a={baseId:s,liveId:s,collection:e,docId:n,structuredQuery:r,callback:t,options:i};this.activeSubscriptions.set(s,a),this.subscriptionErrorHandlers.set(s,new Set),this.subscriptionPermissionHandlers.set(s,new Set),this.activateSubscription(a);let c=()=>{let p=this.activeSubscriptions.get(s)?.liveId??s;this.activeSubscriptions.delete(s),this.subscriptions.delete(s),this.subscriptions.delete(p),this.subscriptionErrorHandlers.delete(s),this.subscriptionPermissionHandlers.delete(s),this.subscriptionLastErrors.delete(s),this.connected&&this.send("unsubscribe",{subscriptionId:p}).catch(()=>{});},l=c;return l.unsubscribe=c,l.onError=h=>{this.subscriptionErrorHandlers.get(s)?.add(h);let p=this.subscriptionLastErrors.get(s);if(p)try{h(p);}catch{}return l},l.onPermissionDenied=h=>{this.subscriptionPermissionHandlers.get(s)?.add(h);let p=this.subscriptionLastErrors.get(s);if(p?.permissionDenied)try{h(p);}catch{}return l},l.catch=h=>l.onError(h),l}activateSubscription(e){let n=()=>{this.subscriptions.set(e.liveId,e.callback);let r={collection:e.collection};e.docId&&(r.docId=e.docId),e.structuredQuery&&(r.query=e.structuredQuery),e.options.skipSnapshot&&(r.skipSnapshot=true),this.send("subscribe",r).then(t=>{let i=t.subscriptionId;if(i&&i!==e.liveId){let s=this.subscriptions.get(e.liveId);s&&(this.subscriptions.delete(e.liveId),this.subscriptions.set(i,s),e.liveId=i);}}).catch(()=>{this.subscriptions.delete(e.liveId),this.emitSubscriptionError(e.baseId,this.toSubscriptionError(new Error("Subscribe failed")));});};this.connected?n():this.ready().then(n).catch(r=>{this.emitSubscriptionError(e.baseId,this.toSubscriptionError(r));});}async replayActiveSubscriptions(){if(!this.connected)return;let e=Array.from(this.activeSubscriptions.values());for(let n of e){if(!this.activeSubscriptions.has(n.baseId))continue;let r=n.liveId;this.subscriptions.delete(r),n.liveId=n.baseId,r&&r!==n.baseId&&await this.send("unsubscribe",{subscriptionId:r}).catch(()=>{}),this.activateSubscription(n);}}toSubscriptionError(e){let n=e instanceof Error?e.message:String(e??"Unknown subscription error"),r=n.match(/^\[([^\]]+)\]\s*(.*)$/),t=r?.[1],i=(r?.[2]??n).trim()||n,s=t==="PERMISSION_DENIED"||n.includes("PERMISSION_DENIED");return {code:t,message:i,permissionDenied:s,raw:e}}emitSubscriptionError(e,n){this.subscriptionLastErrors.set(e,n);let r=this.subscriptionErrorHandlers.get(e);if(r)for(let t of r)try{t(n);}catch{}if(n.permissionDenied){let t=this.subscriptionPermissionHandlers.get(e);if(t)for(let i of t)try{i(n);}catch{}}}_connect(){this._readyPromise=new Promise(e=>{this._readyResolve=e;}),this.ws=new L(this.wsUrl),this.ws.on("message",e=>{let n;try{n=JSON.parse(e.toString());}catch{return}this._handle(n);}),this.ws.on("close",e=>{this.connected=false,this.shouldReconnect&&e!==1e3&&setTimeout(()=>{this.reconnectDelay=Math.min(this.reconnectDelay*2,3e4),this._connect();},this.reconnectDelay);}),this.ws.on("error",()=>{});}_handle(e){let n=e.type;if(n==="auth_ok"){this.connected||(this.connected=true,this.reconnectDelay=2e3,this._readyResolve(),this.replayActiveSubscriptions().catch(()=>{}));return}if(n==="ack"||n==="pong"||n==="call_response"){let r=e.correlationId??e.id,t=this.pendingAcks.get(r);t&&(t(e),this.pendingAcks.delete(r));return}if(n==="error"){let r=e.correlationId;if(r){let t=this.pendingAcks.get(r);t&&(t(e),this.pendingAcks.delete(r));let i=Array.from(this.activeSubscriptions.values()).find(s=>s.liveId===r||s.baseId===r);if(i){let s=this.toSubscriptionError(new Error(`[${String(e.code??"ERROR")}] ${String(e.message??"Unknown error")}`));this.emitSubscriptionError(i.baseId,s);}}return}if(n==="snapshot"||n==="change"){let r=e.subscriptionId,t=this.subscriptions.get(r);if(t){let i=Array.from(this.activeSubscriptions.values()).find(c=>c.liveId===r),s=String(e.collection??i?.collection??""),a=n==="change"&&e.operation==="delete"?null:f(this.cfg,s,e.data,i?.structuredQuery);t({subscriptionId:r,collection:s,docId:e.docId,data:a,type:n==="snapshot"?"snapshot":"change",operation:e.operation});}}}};var b=class{constructor(e,n,r){this.conn=e;this.collection=n;this.id=r;}onSnapshot(e){let n=()=>{};return n=this.conn.subscribe(this.collection,this.id,void 0,r=>{r.type==="snapshot"&&(e(r),n());}),n}};var S=class o{constructor(e,n){this.conn=e;this.name=n;this.sq={};}clone(e){let n=new o(this.conn,this.name);return n.sq={...this.sq,...e},n}normalizeFilterValue(e,n){return e==="in"||e==="not-in"||e==="array-contains-any"?Array.isArray(n)?n:[n]:n}toQueryFilters(e){return k(e).map(r=>typeof r=="object"&&r!=null&&"field"in r&&"op"in r?{...r,value:this.normalizeFilterValue(r.op,r.value)}:r)}appendAndFilters(e){return this.clone({where:[...this.sq.where??[],...e]})}appendOrFilters(e){let n=[...this.sq.where??[]];if(n.length===0)return this.clone({where:[{or:e}]});let r=n[0];if(n.length===1&&typeof r=="object"&&r!=null&&"or"in r)return this.clone({where:[{or:[...r.or,...e]}]});let i=n.length===1?n[0]:{and:n};return this.clone({where:[{or:[i,...e]}]})}appendFilters(e,n){return n==="or"?this.appendOrFilters(e):this.appendAndFilters(e)}appendOperatorFilter(e,n,r,t){return this.appendFilters([{field:e,op:n,value:this.normalizeFilterValue(n,r)}],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,n){return this.appendOperatorFilter(e,"in",n,"and")}andIn(e,n){return this.appendOperatorFilter(e,"in",n,"and")}orIn(e,n){return this.appendOperatorFilter(e,"in",n,"or")}notIn(e,n){return this.appendOperatorFilter(e,"not-in",n,"and")}andNotIn(e,n){return this.appendOperatorFilter(e,"not-in",n,"and")}orNotIn(e,n){return this.appendOperatorFilter(e,"not-in",n,"or")}arrayContains(e,n){return this.appendOperatorFilter(e,"array-contains",n,"and")}andArrayContains(e,n){return this.appendOperatorFilter(e,"array-contains",n,"and")}orArrayContains(e,n){return this.appendOperatorFilter(e,"array-contains",n,"or")}arrayContainsAny(e,n){return this.appendOperatorFilter(e,"array-contains-any",n,"and")}andArrayContainsAny(e,n){return this.appendOperatorFilter(e,"array-contains-any",n,"and")}orArrayContainsAny(e,n){return this.appendOperatorFilter(e,"array-contains-any",n,"or")}some(e,n){return this.appendOperatorFilter(e,"elem-match",n,"and")}andSome(e,n){return this.appendOperatorFilter(e,"elem-match",n,"and")}orSome(e,n){return this.appendOperatorFilter(e,"elem-match",n,"or")}like(e,n){return this.appendOperatorFilter(e,"like",n,"and")}andLike(e,n){return this.appendOperatorFilter(e,"like",n,"and")}orLike(e,n){return this.appendOperatorFilter(e,"like",n,"or")}notLike(e,n){return this.appendOperatorFilter(e,"not-like",n,"and")}andNotLike(e,n){return this.appendOperatorFilter(e,"not-like",n,"and")}orNotLike(e,n){return this.appendOperatorFilter(e,"not-like",n,"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.latest()}oldest(){return this.clone({orderBy:[...this.sq.orderBy??[],{field:"_seq",dir:"asc"}]})}orderBy(e,n="asc"){return this.clone({orderBy:[...this.sq.orderBy??[],{field:e,dir:n}]})}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,n){return this.aggregate({fn:"sum",field:e,alias:n??`sum_${e}`})}avg(e,n){return this.aggregate({fn:"avg",field:e,alias:n??`avg_${e}`})}min(e,n){return this.aggregate({fn:"min",field:e,alias:n??`min_${e}`})}max(e,n){return this.aggregate({fn:"max",field:e,alias:n??`max_${e}`})}distinct(e,n){return this.aggregate({fn:"distinct",field:e,alias:n??`distinct_${e}`})}groupBy(...e){return this.clone({groupBy:{fields:e}})}having(e,n,r){return this.clone({having:[...this.sq.having??[],{field:e,op:n,value:r}]})}buildStructuredJoin(e,n){let r={from:String(e??""),localField:String(n?.source??""),foreignField:String(n?.target??""),as:String(n?.as??""),single:n?.single};return Array.isArray(n?.where)&&(r.where=n.where),Array.isArray(n?.orderBy)&&(r.orderBy=n.orderBy),typeof n?.limit=="number"&&(r.limit=n.limit),typeof n?.offset=="number"&&(r.offset=n.offset),Array.isArray(n?.select)&&(r.select=n.select),Array.isArray(n?.joins)&&(r.joins=n.joins.map(t=>this.buildStructuredJoin(String(t?.collection??""),t))),r}cloneStructuredJoin(e){let n={...e};return Array.isArray(e.where)&&(n.where=e.where.map(r=>({...r}))),Array.isArray(e.orderBy)&&(n.orderBy=e.orderBy.map(r=>({...r}))),Array.isArray(e.select)&&(n.select=[...e.select]),Array.isArray(e.joins)&&(n.joins=e.joins.map(r=>this.cloneStructuredJoin(r))),n}appendNestedJoinByAlias(e,n,r){for(let t of e){if(t.as===n)return t.joins=[...t.joins??[],r],true;if(Array.isArray(t.joins)&&this.appendNestedJoinByAlias(t.joins,n,r))return true}return false}parseRelationRef(e){let r=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(!r)throw new Error(`Invalid relation format: "${e}". Expected "source.path->collection.target"`);return {source:r[1],collection:r[2],target:r[3],alias:r[4]}}join(e,n){let r=this.buildStructuredJoin(e,n);return this.clone({joins:[...this.sq.joins??[],r]})}joinNested(e,n,r){let t=String(e??"").trim();if(!t)throw new Error("joinNested requires parentAlias");let i=(this.sq.joins??[]).map(a=>this.cloneStructuredJoin(a));if(i.length===0)throw new Error(`joinNested parent alias "${t}" not found`);let s=this.buildStructuredJoin(n,r);if(!this.appendNestedJoinByAlias(i,t,s))throw new Error(`joinNested parent alias "${t}" not found`);return this.clone({joins:i})}Join(e,n){return this.join(e,n)}JoinNested(e,n,r){return this.joinNested(e,n,r)}withRelation(e,n={}){let r=this.parseRelationRef(e);return this.join(r.collection,{...n,source:r.source,target:r.target,as:n.as??r.alias??r.collection})}select(...e){return this.clone({select:e})}distinctField(e){return this.clone({distinctField:e})}vectorSearch(e){return this.clone({vectorSearch:e})}doc(e){return new b(this.conn,this.name,e)}getRawQuery(){let e={...this.sq};return Array.isArray(this.sq.where)&&(e.where=this.sq.where.map(n=>({...n}))),Array.isArray(this.sq.orderBy)&&(e.orderBy=this.sq.orderBy.map(n=>({...n}))),Array.isArray(this.sq.aggregate)&&(e.aggregate=this.sq.aggregate.map(n=>({...n}))),Array.isArray(this.sq.having)&&(e.having=this.sq.having.map(n=>({...n}))),Array.isArray(this.sq.select)&&(e.select=[...this.sq.select]),Array.isArray(this.sq.joins)&&(e.joins=this.sq.joins.map(n=>this.cloneStructuredJoin(n))),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.name,query:e}}onSnapshot(e){let n=this._buildSq(),r=()=>{};return r=this.conn.subscribe(this.name,void 0,n,t=>{t.type==="snapshot"&&(e(t),r());}),r}onDocAdded(e){let n=this._buildSq();return this.conn.subscribe(this.name,void 0,n,r=>{r.type==="change"&&r.operation==="insert"&&r.data!=null&&e(r.data,r.docId);},{skipSnapshot:true})}onDocUpdated(e){let n=this._buildSq();return this.conn.subscribe(this.name,void 0,n,r=>{r.type==="change"&&(r.operation==="update"||r.operation==="replace")&&r.data!=null&&e(r.data,r.docId);},{skipSnapshot:true})}onDocDeleted(e){let n=this._buildSq();return this.conn.subscribe(this.name,void 0,n,r=>{r.type==="change"&&r.operation==="delete"&&e(r.docId);},{skipSnapshot:true})}onDocChanged(e){let n=this._buildSq();return this.conn.subscribe(this.name,void 0,n,r=>{r.type==="change"&&e(r.data??null,r.docId,r.operation);},{skipSnapshot:true})}_buildSq(){let e={};return this.sq.where&&this.sq.where.length>0&&(e.where=this.sq.where),this.sq.orderBy&&this.sq.orderBy.length>0&&(e.orderBy=this.sq.orderBy),this.sq.limit!==void 0&&(e.limit=this.sq.limit),this.sq.offset!==void 0&&(e.offset=this.sq.offset),this.sq.startAt&&(e.startAt=this.sq.startAt),this.sq.startAfter&&(e.startAfter=this.sq.startAfter),this.sq.endAt&&(e.endAt=this.sq.endAt),this.sq.endBefore&&(e.endBefore=this.sq.endBefore),this.sq.aggregate&&this.sq.aggregate.length>0&&(e.aggregate=this.sq.aggregate),this.sq.groupBy&&(e.groupBy=this.sq.groupBy),this.sq.having&&this.sq.having.length>0&&(e.having=this.sq.having),this.sq.joins&&this.sq.joins.length>0&&(e.joins=this.sq.joins),this.sq.vectorSearch&&(e.vectorSearch=this.sq.vectorSearch),this.sq.select&&this.sq.select.length>0&&(e.select=this.sq.select),this.sq.distinctField&&(e.distinctField=this.sq.distinctField),e}};var v=class{constructor(e){this._ws=new C(e);}collection(e){return new S(this._ws,e)}ready(){return this._ws.ready()}disconnect(){this._ws.disconnect();}};var O=class{constructor(e){this.cfg={defaultTtl:"24h",...e,serverUrl:e.serverUrl.replace(/\/$/,""),dataMapper:e.dataMapper??{}};}auth(){return this._auth??(this._auth=new y(this.cfg))}db(){return this._db??(this._db=new A(this.cfg))}connection(){return this._conn??(this._conn=new v(this.cfg))}notifications(){return this._notifications??(this._notifications=new w(this.cfg))}},R=new Map;function we(o,e="[DEFAULT]"){if(R.has(e))return R.get(e);let n=new O(o);return R.set(e,n),n}function T(o="[DEFAULT]"){let e=R.get(o);if(!e)throw new Error(`[flare-admin] No app named "${o}" found. Call connectApp() before getApp().`);return e}function Ce(o="[DEFAULT]"){return T(o).auth()}function be(o="[DEFAULT]"){return T(o).db()}function Se(o="[DEFAULT]"){return T(o).connection()}function ve(o="[DEFAULT]"){return T(o).notifications()}export{m as AdminCollectionReference,g as AdminDocumentReference,S as AdminLiveCollectionReference,b as AdminLiveDocumentReference,O as FlareAdminApp,y as FlareAdminAuthService,v as FlareAdminConnection,A as FlareAdminDbService,w as FlareAdminNotificationsService,C as FlareAdminWsConnection,Ce as auth,we as connectApp,Se as connection,be as db,T as getApp,ve as notifications};
|
|
1
|
+
import re from'fs';import S from'path';import {fileURLToPath}from'url';import ee from'ws';var U=(i=>(i.Upload="upload",i.Download="download",i.Delete="delete",i.Edit="edit",i))(U||{});function x(r){let e=[];for(let[t,n]of Object.entries(r))if(typeof n=="string"){let i=n.match(/^(>=|<=|!=|>|<|==)\s*(.+)$/);if(i){let[,s,o]=i;e.push({field:t,op:s,value:te(o.trim())});}else e.push({field:t,op:"==",value:n});}else Array.isArray(n)?e.push({field:t,op:"in",value:n}):e.push({field:t,op:"==",value:n});return e}function te(r){return isNaN(Number(r))?r==="true"?true:r==="false"?false:r==="null"?null:r:Number(r)}function L(){return Math.random().toString(36).slice(2,12)+Date.now().toString(36)}function ne(r,e){let t=r.dataMapper;if(!t||typeof t!="object")return null;let n=t[e];return typeof n=="function"?n:null}function $(r,e,t){let n=ne(r,e);if(!n||t==null||typeof t!="object")return t;try{return n(t)}catch{return t}}function J(r,e,t){if(!e||typeof e!="object"||!Array.isArray(t)||t.length===0)return e;let n=e;for(let i of t){let s=String(i?.as??"").trim();if(!s)continue;let o=Array.isArray(i?.joins)?i.joins:[],a=n[s],d=a;Array.isArray(a)?d=a.map(c=>J(r,c,o)):a&&typeof a=="object"&&(d=J(r,a,o)),d=Array.isArray(d)?d.map(c=>$(r,s,c)):$(r,s,d),d!==a&&(n===e&&(n={...n}),n[s]=d);}return n}function y(r,e,t,n){let i=Array.isArray(n?.joins)?n.joins:[],s=o=>{let a=J(r,o,i);return $(r,e,a)};return Array.isArray(t)?t.map(o=>s(o)):s(t)}var se=()=>typeof process<"u"&&!!process.versions?.node,m=r=>{if(r.transport==="http")return false;let e=!!(r.grpcUrl&&r.grpcUrl.trim().length>0),t=se();if(r.transport==="grpc"){if(!e)throw new Error("[flare-admin][grpc] transport=grpc requires grpcUrl");if(!t)throw new Error("[flare-admin][grpc] transport=grpc requires Node.js runtime");return true}return e&&t},w=r=>{try{return JSON.stringify(r??{})}catch{return "{}"}},C=r=>r?.field&&r?.op?{queryFilter:{field:String(r.field),op:String(r.op),valueJson:w(r.value)}}:Array.isArray(r?.or)?{orFilter:{or:r.or.map(e=>C(e))}}:Array.isArray(r?.and)?{andFilter:{and:r.and.map(e=>C(e))}}:{queryFilter:{field:"",op:"==",valueJson:"null"}},E=r=>{if(!(!r||!Array.isArray(r.values)))return {valuesJson:r.values.map(e=>w(e))}},G=r=>({from:r.from,localField:r.localField,foreignField:r.foreignField,as:r.as,single:!!r.single,where:Array.isArray(r.where)?r.where.map(C):[],orderBy:Array.isArray(r.orderBy)?r.orderBy.map(e=>({field:e.field,dir:e.dir??"asc"})):[],limit:r.limit??0,offset:r.offset??0,select:Array.isArray(r.select)?r.select:[],joins:Array.isArray(r.joins)?r.joins.map(G):[]}),oe=r=>({where:Array.isArray(r.where)?r.where.map(C):[],orderBy:Array.isArray(r.orderBy)?r.orderBy.map(e=>({field:e.field,dir:e.dir??"asc"})):[],limit:r.limit??0,offset:r.offset??0,startAt:E(r.startAt),startAfter:E(r.startAfter),endAt:E(r.endAt),endBefore:E(r.endBefore),aggregate:Array.isArray(r.aggregate)?r.aggregate.map(e=>({fn:e.fn,field:e.field??"",alias:e.alias??""})):[],groupBy:r.groupBy?{fields:r.groupBy.fields??[]}:void 0,having:Array.isArray(r.having)?r.having.map(e=>({field:e.field,op:e.op,value:e.value})):[],joins:Array.isArray(r.joins)?r.joins.map(G):[],select:Array.isArray(r.select)?r.select:[],distinctField:r.distinctField??""});async function h(r){let e=await import('@grpc/grpc-js'),t=await import('@grpc/proto-loader'),n=S.dirname(fileURLToPath(import.meta.url)),i=[S.resolve(n,"../../proto"),S.resolve(n,"../proto"),S.resolve(process.cwd(),"proto")],s=i.find(l=>re.existsSync(S.join(l,"flare.proto")))??i[0],o=S.join(s,"flare.proto"),a=await t.load(o,{keepCase:false,longs:String,enums:String,defaults:true,oneofs:true,includeDirs:[s]}),c=e.loadPackageDefinition(a).flare;return new c.AdminService(r,e.credentials.createInsecure())}function f(r,e,t){return new Promise((n,i)=>{r[e](t,(s,o)=>{if(s)return i(s);n(o??{});});})}function A(r,e){if(r.error)throw new Error(`[flare-admin][grpc] ${e} failed: ${r.errorDescription||r.error}`)}async function M(r,e,t){if(!m(r))return null;let n=await h(r.grpcUrl),i=await f(n,"AdminQuery",{app_id:r.appId,admin_key:r.adminKey,collection:e,query:oe(t)});A(i,"admin_query");try{let s=JSON.parse(i.dataJson||"[]");return Array.isArray(s)?s:[]}catch{return []}}async function Q(r,e,t){if(!m(r))return null;let n=await h(r.grpcUrl),i=await f(n,"CreateCustomToken",{app_id:r.appId,admin_key:r.adminKey,uid:e,role:t.role??"user",claims_json:w(t.claims??{}),ttl:t.ttl??r.defaultTtl});if(A(i,"create_custom_token"),!i.token)throw new Error("[flare-admin][grpc] create_custom_token returned empty token");return String(i.token)}async function z(r,e,t){if(!m(r))return null;let n=await h(r.grpcUrl),i=await f(n,"CreateAuthTicket",{app_id:r.appId,admin_key:r.adminKey,uid:e,role:t.role??"user",email:t.email??"",sid:t.sid??"",tag:t.tag??"",ttl_seconds:t.ttlSeconds??0,ip:t.ip??""});return A(i,"create_auth_ticket"),{ticket:String(i.ticket??""),tag:String(i.tag??""),uuid:String(i.uuid??""),expires_at:String(i.expiresAt??""),one_time:!!(i.oneTime??true),uid:String(i.uid??e),role:String(i.role??t.role??"user"),ip:String(i.ip??"unknown")}}async function K(r,e,t){if(!m(r))return;let n=await h(r.grpcUrl),i=await f(n,"GetDocument",{app_id:r.appId,admin_key:r.adminKey,collection:e,doc_id:t});if(A(i,"get_document"),!i.found)return null;try{return JSON.parse(i.dataJson||"{}")}catch{return {}}}async function W(r,e,t){if(!m(r))return null;let n=await h(r.grpcUrl),i=await f(n,"CreateDocument",{app_id:r.appId,admin_key:r.adminKey,collection:e,data_json:w(t)});return A(i,"create_document"),String(i.id??"")}async function V(r,e,t,n){if(!m(r))return null;let i=await h(r.grpcUrl),s=await f(i,"ReplaceDocument",{app_id:r.appId,admin_key:r.adminKey,collection:e,doc_id:t,data_json:w(n)});return A(s,"replace_document"),true}async function Z(r,e,t,n){if(!m(r))return null;let i=await h(r.grpcUrl),s=await f(i,"UpdateDocument",{app_id:r.appId,admin_key:r.adminKey,collection:e,doc_id:t,data_json:w(n)});return A(s,"update_document"),true}async function X(r,e,t){if(!m(r))return null;let n=await h(r.grpcUrl),i=await f(n,"DeleteDocument",{app_id:r.appId,admin_key:r.adminKey,collection:e,doc_id:t});return A(i,"delete_document"),!!i.deleted}async function Y(r,e,t){if(!m(r))return null;let n=await h(r.grpcUrl),i=await f(n,"DeleteMany",{app_id:r.appId,admin_key:r.adminKey,collection:e,where:(t??[]).map(C)});return A(i,"delete_many"),Number(i.deleted??0)}var b=class{constructor(e,t,n){this.cfg=e;this.collection=t;this.id=n;}get baseUrl(){return `${this.cfg.serverUrl}/admin/db/${this.cfg.appId}/${this.collection}/${this.id}`}get headers(){return {"Content-Type":"application/json",Authorization:`Bearer ${this.cfg.adminKey}`}}async request(e,t){let n;try{n=await fetch(this.baseUrl,{method:e,headers:this.headers,...t!==void 0?{body:JSON.stringify(t)}:{}});}catch(s){let o=s instanceof Error?s.message:String(s);throw new Error(`[flare-admin] Network error (${e} ${this.baseUrl}): ${o}`)}let i=await n.json().catch(()=>({}));if(!n.ok)throw new Error(`[flare-admin] ${e} ${this.baseUrl} failed (HTTP ${n.status}): `+(i.error??"Unknown error"));return i}async get(){let e=await K(this.cfg,this.collection,this.id);if(e!==void 0)return e===null?null:y(this.cfg,this.collection,e)??null;let t;try{t=await fetch(this.baseUrl,{headers:this.headers});}catch(s){let o=s instanceof Error?s.message:String(s);throw new Error(`[flare-admin] Network error (GET ${this.baseUrl}): ${o}`)}if(t.status===404)return null;let n=await t.json().catch(()=>({}));if(!t.ok)throw new Error(`[flare-admin] GET ${this.baseUrl} failed (HTTP ${t.status}): `+(n.error??"Unknown error"));return y(this.cfg,this.collection,n.data)??null}async set(e){await V(this.cfg,this.collection,this.id,e)===null&&await this.request("PUT",e);}async update(e){await Z(this.cfg,this.collection,this.id,e)===null&&await this.request("PATCH",e);}async delete(){await X(this.cfg,this.collection,this.id)===null&&await this.request("DELETE");}parent(){return new k(this.cfg,this.collection)}};var k=class r{constructor(e,t){this.cfg=e;this.name=t;this.sq={};this.opts={allowSensitiveAuthUserFields:true};}get baseUrl(){return `${this.cfg.serverUrl}/admin/db/${this.cfg.appId}/${this.name}`}get headers(){return {"Content-Type":"application/json",Authorization:`Bearer ${this.cfg.adminKey}`}}clone(e){let t=new r(this.cfg,this.name);return t.sq={...this.sq,...e},t.opts={...this.opts},t}allowSensitiveAuthUserFields(e=true){let t=this.clone({});return t.opts.allowSensitiveAuthUserFields=!!e,t}normalizeFilterValue(e,t){return e==="in"||e==="not-in"||e==="array-contains-any"?Array.isArray(t)?t:[t]:t}toQueryFilters(e){return x(e).map(n=>typeof n=="object"&&n!=null&&"field"in n&&"op"in n?{...n,value:this.normalizeFilterValue(n.op,n.value)}:n)}appendAndFilters(e){return this.clone({where:[...this.sq.where??[],...e]})}appendOrFilters(e){let t=[...this.sq.where??[]];if(t.length===0)return this.clone({where:[{or:e}]});let n=t[0];if(t.length===1&&typeof n=="object"&&n!=null&&"or"in n)return this.clone({where:[{or:[...n.or,...e]}]});let s=t.length===1?t[0]:{and:t};return this.clone({where:[{or:[s,...e]}]})}appendFilters(e,t){return t==="or"?this.appendOrFilters(e):this.appendAndFilters(e)}appendOperatorFilter(e,t,n,i){return this.appendFilters([{field:e,op:t,value:this.normalizeFilterValue(t,n)}],i)}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.latest()}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,n){return this.clone({having:[...this.sq.having??[],{field:e,op:t,value:n}]})}buildStructuredJoin(e,t){let n={from:String(e??""),localField:String(t?.source??""),foreignField:String(t?.target??""),as:String(t?.as??""),single:t?.single};return Array.isArray(t?.where)&&(n.where=t.where),Array.isArray(t?.orderBy)&&(n.orderBy=t.orderBy),typeof t?.limit=="number"&&(n.limit=t.limit),typeof t?.offset=="number"&&(n.offset=t.offset),Array.isArray(t?.select)&&(n.select=t.select),Array.isArray(t?.joins)&&(n.joins=t.joins.map(i=>this.buildStructuredJoin(String(i?.collection??""),i))),n}cloneStructuredJoin(e){let t={...e};return Array.isArray(e.where)&&(t.where=e.where.map(n=>({...n}))),Array.isArray(e.orderBy)&&(t.orderBy=e.orderBy.map(n=>({...n}))),Array.isArray(e.select)&&(t.select=[...e.select]),Array.isArray(e.joins)&&(t.joins=e.joins.map(n=>this.cloneStructuredJoin(n))),t}appendNestedJoinByAlias(e,t,n){for(let i of e){if(i.as===t)return i.joins=[...i.joins??[],n],true;if(Array.isArray(i.joins)&&this.appendNestedJoinByAlias(i.joins,t,n))return true}return false}parseRelationRef(e){let n=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(!n)throw new Error(`Invalid relation format: "${e}". Expected "source.path->collection.target"`);return {source:n[1],collection:n[2],target:n[3],alias:n[4]}}join(e,t){let n=this.buildStructuredJoin(e,t);return this.clone({joins:[...this.sq.joins??[],n]})}joinNested(e,t,n){let i=String(e??"").trim();if(!i)throw new Error("joinNested requires parentAlias");let s=(this.sq.joins??[]).map(a=>this.cloneStructuredJoin(a));if(s.length===0)throw new Error(`joinNested parent alias "${i}" not found`);let o=this.buildStructuredJoin(t,n);if(!this.appendNestedJoinByAlias(s,i,o))throw new Error(`joinNested parent alias "${i}" not found`);return this.clone({joins:s})}Join(e,t){return this.join(e,t)}JoinNested(e,t,n){return this.joinNested(e,t,n)}withRelation(e,t={}){let n=this.parseRelationRef(e);return this.join(n.collection,{...t,source:n.source,target:n.target,as:t.as??n.alias??n.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.name,query:e}}async get(){let e=await M(this.cfg,this.name,this.sq);if(e)return y(this.cfg,this.name,e,this.sq)??[];let t=new URL(this.baseUrl);t.searchParams.set("query",JSON.stringify(this.sq)),t.searchParams.set("allowSensitiveAuthUserFields",this.opts.allowSensitiveAuthUserFields?"1":"0");let n;try{n=await fetch(t.toString(),{headers:this.headers});}catch(o){let a=o instanceof Error?o.message:String(o);throw new Error(`[flare-admin] Network error (GET ${this.baseUrl}): ${a}`)}let i=await n.json().catch(()=>({}));if(!n.ok)throw new Error(`[flare-admin] GET ${this.baseUrl} failed (HTTP ${n.status}): ${i.error??"Unknown error"}`);return y(this.cfg,this.name,i.data,this.sq)??[]}async first(){let e=await this.get();return e.length>0?e[0]:null}async last(){let e=await this.get();return e.length>0?e[e.length-1]:null}async add(e){let t=await W(this.cfg,this.name,e);if(t!==null)return new b(this.cfg,this.name,t);let n;try{n=await fetch(this.baseUrl,{method:"POST",headers:this.headers,body:JSON.stringify(e)});}catch(s){let o=s instanceof Error?s.message:String(s);throw new Error(`[flare-admin] Network error (POST ${this.baseUrl}): ${o}`)}let i=await n.json().catch(()=>({}));if(!n.ok)throw new Error(`[flare-admin] POST ${this.baseUrl} failed (HTTP ${n.status}): ${i.error??"Unknown error"}`);return new b(this.cfg,this.name,i.id)}async deleteMany(){let e=await Y(this.cfg,this.name,this.sq.where??[]);if(e!==null)return e;let t;try{t=await fetch(this.baseUrl,{method:"DELETE",headers:this.headers,body:JSON.stringify({where:this.sq.where??[]})});}catch(i){let s=i instanceof Error?i.message:String(i);throw new Error(`[flare-admin] Network error (DELETE ${this.baseUrl}): ${s}`)}let n=await t.json().catch(()=>({}));if(!t.ok)throw new Error(`[flare-admin] DELETE ${this.baseUrl} failed (HTTP ${t.status}): ${n.error??"Unknown error"}`);return n.deleted??0}doc(e){return new b(this.cfg,this.name,e)}};var v=class{constructor(e){this.cfg=e;}collection(e){return new k(this.cfg,e)}};var T=class{constructor(e){this.cfg=e;}async createCustomToken(e,t={}){if(m(this.cfg)){let a=await Q(this.cfg,String(e),t);if(!a)throw new Error("[flare-admin][grpc] create_custom_token returned empty token");return a}let n=`${this.cfg.serverUrl.replace(/\/$/,"")}/admin/token`,i=JSON.stringify({appId:this.cfg.appId,uid:String(e),role:t.role??"user",claims:t.claims??{},ttl:t.ttl??this.cfg.defaultTtl}),s;try{s=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.cfg.adminKey}`},body:i});}catch(a){let d=a instanceof Error?a.message:String(a);throw new Error(`[flare-admin] Could not reach FlareServer at "${n}": ${d}
|
|
2
|
+
Make sure FLARE_URL is set correctly and the server is running.`)}let o;try{o=await s.json();}catch{throw new Error(`[flare-admin] Server returned non-JSON response (status ${s.status})`)}if(!s.ok)throw new Error(`[flare-admin] createCustomToken failed (HTTP ${s.status}): `+(o.error??"Unknown error"));if(typeof o.token!="string")throw new Error('[flare-admin] Server response missing "token" field');return o.token}async getTicket(e,t={}){if(m(this.cfg)){let d=await z(this.cfg,String(e),t);if(!d)throw new Error("[flare-admin][grpc] create_auth_ticket returned empty payload");return d}let n=`${this.cfg.serverUrl.replace(/\/$/,"")}/admin/ticket`,i=JSON.stringify({appId:this.cfg.appId,uid:String(e),role:t.role??"user",email:t.email,sid:t.sid,tag:t.tag,ttlSeconds:t.ttlSeconds,ip:t.ip}),s;try{s=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.cfg.adminKey}`},body:i});}catch(d){let c=d instanceof Error?d.message:String(d);throw new Error(`[flare-admin] Could not reach FlareServer at "${n}": ${c}
|
|
3
|
+
Make sure FLARE_URL is set correctly and the server is running.`)}let o;try{o=await s.json();}catch{throw new Error(`[flare-admin] Server returned non-JSON response (status ${s.status})`)}if(!s.ok)throw new Error(`[flare-admin] getTicket failed (HTTP ${s.status}): `+(o.error??"Unknown error"));let a=o.ticket;if(!a||typeof a.ticket!="string")throw new Error('[flare-admin] Server response missing "ticket" object');return {ticket:String(a.ticket),tag:String(a.tag??""),uuid:String(a.uuid??""),expires_at:String(a.expires_at??""),one_time:!!(a.one_time??true),uid:String(a.uid??String(e)),role:String(a.role??t.role??"user"),ip:String(a.ip??"unknown")}}};var R=class{constructor(e){this.cfg=e;}get baseUrl(){return `${this.cfg.serverUrl.replace(/\/$/,"")}/admin/notify/${this.cfg.appId}`}get headers(){return {"Content-Type":"application/json",Authorization:`Bearer ${this.cfg.adminKey}`}}async send(e){let t;try{t=await fetch(`${this.baseUrl}/send`,{method:"POST",headers:this.headers,body:JSON.stringify(e??{})});}catch(i){let s=i instanceof Error?i.message:String(i);throw new Error(`[flare-admin] Network error (POST ${this.baseUrl}/send): ${s}`)}let n=await t.json().catch(()=>({}));if(!t.ok)throw new Error(`[flare-admin] Notification send failed (HTTP ${t.status}): `+(n.error??"Unknown error"));return {sent:!!n.sent,appId:String(n.appId??this.cfg.appId),targetCount:Number(n.targetCount??0),successCount:Number(n.successCount??0),failureCount:Number(n.failureCount??0),invalidatedTokenCount:Number(n.invalidatedTokenCount??0),dryRun:!!n.dryRun}}async tokens(){let e;try{e=await fetch(`${this.baseUrl}/tokens`,{method:"GET",headers:this.headers});}catch(n){let i=n instanceof Error?n.message:String(n);throw new Error(`[flare-admin] Network error (GET ${this.baseUrl}/tokens): ${i}`)}let t=await e.json().catch(()=>({}));if(!e.ok)throw new Error(`[flare-admin] Tokens fetch failed (HTTP ${e.status}): `+(t.error??"Unknown error"));return {appId:String(t.appId??this.cfg.appId),hasPushGateway:!!t.hasPushGateway,total:Number(t.total??0),tokens:Array.isArray(t.tokens)?t.tokens:[]}}};var _=class{constructor(e){this.cfg=e;}base(e){return `${this.cfg.serverUrl.replace(/\/$/,"")}/admin/storage/${encodeURIComponent(this.cfg.appId)}${e}`}get headers(){return {"Content-Type":"application/json",Authorization:`Bearer ${this.cfg.adminKey}`}}async jsonRequest(e,t,n){let i,s=this.base(t);try{i=await fetch(s,{method:e,headers:this.headers,...n!==void 0?{body:JSON.stringify(n)}:{}});}catch(a){let d=a instanceof Error?a.message:String(a);throw new Error(`[flare-admin] Network error (${e} ${s}): ${d}`)}let o=await i.json().catch(()=>({}));if(!i.ok)throw new Error(`[flare-admin] ${e} ${s} failed (HTTP ${i.status}): `+(o.error??"Unknown error"));return o}async request(e,t,n){return this.jsonRequest(e,t,n)}async servers(){let e=await this.jsonRequest("GET","/servers");return Array.isArray(e.servers)?e.servers:[]}async createServer(e){let t=await this.jsonRequest("POST","/servers",e??{});return {ok:!!(t.ok??true),serverId:String(t.serverId??"")}}async patchServer(e,t){let n=String(e??"").trim();if(!n)throw new Error("storage server id is required");let i=await this.jsonRequest("POST",`/servers/${encodeURIComponent(n)}`,t??{});return {ok:!!(i.ok??true),serverId:String(i.serverId??n)}}async deleteServer(e){let t=String(e??"").trim();if(!t)throw new Error("storage server id is required");let n=await this.jsonRequest("DELETE",`/servers/${encodeURIComponent(t)}`);return {ok:!!(n.ok??true),serverId:String(n.serverId??t),removedObjects:Number(n.removedObjects??0)}}async awsConfig(e){let t=String(e??"").trim();if(!t)throw new Error("storage server id is required");return (await this.jsonRequest("GET",`/servers/${encodeURIComponent(t)}/aws`)).aws??{}}async uploadObject(e){return await this.jsonRequest("POST","/object/upload",e??{})}async downloadObject(e){return await this.jsonRequest("POST","/object/download",e??{})}async deleteObject(e){return await this.jsonRequest("POST","/object/delete",e??{})}async createSignedUrl(e){return await this.jsonRequest("POST","/signed-url",e??{})}async setRules(e){let t=await this.jsonRequest("POST","/rules",{...e?.rules?{rules:e.rules}:{},...typeof e?.rulesDsl=="string"?{rulesDsl:e.rulesDsl}:{},...e?.rulesHistoryPolicy?{rulesHistoryPolicy:e.rulesHistoryPolicy}:{}});return {id:String(t.id??this.cfg.appId)}}async validateRules(e){let t=await this.jsonRequest("POST","/rules/validate",{rulesDsl:e});return {valid:!!t.valid,diagnostics:Array.isArray(t.diagnostics)?t.diagnostics:[],rulesCount:Number(t.rulesCount??0)}}async rulesHistory(){let e=await this.jsonRequest("GET","/rules/history");return {history:Array.isArray(e.history)?e.history:[],policy:e.policy??{maxEntries:30,maxAgeDays:365},restoreEvents:Array.isArray(e.restoreEvents)?e.restoreEvents:[]}}async restoreRules(e){let t=String(e??"").trim();if(!t)throw new Error("historyId is required");let n=await this.jsonRequest("POST","/rules/restore",{historyId:t});return {id:String(n.id??this.cfg.appId),rulesText:String(n.rulesText??"")}}};function N(r){if(typeof Buffer<"u")return Buffer.from(r).toString("base64");let e="";for(let t=0;t<r.length;t++)e+=String.fromCharCode(r[t]);return btoa(e)}async function ae(r){return r===void 0?"":typeof r=="string"?N(new TextEncoder().encode(r)):Buffer&&Buffer.isBuffer(r)?r.toString("base64"):r instanceof Uint8Array?N(r):r instanceof ArrayBuffer?N(new Uint8Array(r)):""}function ce(r){return Buffer?Buffer.from(String(r)).toString("base64"):btoa(String(r))}function de(r){try{let e=Buffer?Buffer.from(r,"base64").toString():atob(r),t=parseInt(e,10);return isNaN(t)?0:t}catch{return 0}}function le(r){return (String(r??"").split("/").pop()??"download").replace(/["\\\r\n]/g,"")||"download"}var O=class{constructor(e){this._bucketCache=new Map;this._bucketListLoaded=false;this._bucketListPromise=null;this._svc=e;}async _ensureBuckets(){if(!this._bucketListLoaded)return this._bucketListPromise||(this._bucketListPromise=this._loadBuckets().then(()=>{this._bucketListLoaded=true;}).catch(e=>{throw this._bucketListPromise=null,e}).finally(()=>{this._bucketListPromise=null;})),this._bucketListPromise}async _loadBuckets(){let e=await this.listBuckets();for(let t of e)this._bucketCache.set(t.bucket,t.id);}_invalidateCache(){this._bucketCache.clear(),this._bucketListLoaded=false,this._bucketListPromise=null;}async _resolveBucketId(e,t){let n=this._bucketCache.get(e);if(n)return n;await this._ensureBuckets();let i=this._bucketCache.get(e);if(i)return i;if(t)return (await this.createBucket(e)).id;throw new Error(`Bucket "${e}" not found. Create it first with createBucket("${e}").`)}async createBucket(e,t={}){let n=e.trim();if(!n)throw new Error("bucket name is required");await this._ensureBuckets();let i=this._bucketCache.get(n);if(i){let d=(await this.listBuckets()).find(c=>c.id===i);if(d)return d}let s;try{s=await this._svc.createServer({name:n,kind:t.kind??"managed",bucket:n,prefix:t.prefix,region:t.region,endpoint:t.endpoint,accessKey:t.accessKey,secretKey:t.secretKey,dataDir:t.dataDir,forcePathStyle:t.forcePathStyle});}catch(a){if((a instanceof Error?a.message:String(a)).includes("bucket_conflict")){this._invalidateCache(),await this._ensureBuckets();let c=this._bucketCache.get(n);if(c){let u=(await this.listBuckets()).find(D=>D.id===c);if(u)return u}}throw a}let o={id:s.serverId,name:n,bucket:n,kind:t.kind??"managed",prefix:t.prefix};return this._bucketCache.set(n,o.id),o}async listBuckets(){let t=(await this._svc.servers()).map(n=>({id:n.id,name:n.name,bucket:n.bucket,kind:n.kind,region:n.region,endpoint:n.endpoint,prefix:n.prefix,frozen:n.frozen,readOnly:n.readOnly,createdAt:n.createdAt,updatedAt:n.updatedAt}));this._bucketCache.clear();for(let n of t)this._bucketCache.set(n.bucket,n.id);return this._bucketListLoaded=true,t}async deleteBucket(e){let t=await this._resolveBucketId(e,false),n=await this._svc.deleteServer(t);return this._bucketCache.delete(e),{ok:n.ok,removedObjects:n.removedObjects}}async deleteBuckets(e){let t=[],n={};return await Promise.all(e.map(async i=>{try{await this.deleteBucket(i),t.push(i);}catch(s){n[i]=s instanceof Error?s.message:String(s);}})),{ok:Object.keys(n).length===0,deleted:t,errors:n}}async getBucketLocation(e){let n=(await this.listBuckets()).find(i=>i.bucket===e||i.name===e);if(!n)throw new Error(`Bucket "${e}" not found`);return {bucket:n.bucket,kind:n.kind,region:n.region,endpoint:n.endpoint}}async putObject(e){let t=await this._resolveBucketId(e.bucket,true);if(e.contentBase64!==void 0){let c=await this._svc.uploadObject({serverId:t,path:e.key,contentBase64:e.contentBase64,contentType:e.contentType,encrypt:e.encrypt});return {ok:c.ok,bucket:e.bucket,key:String(c.path??e.key),size:Number(c.size??0),encrypted:!!c.encrypted}}let n=4*1024*1024,i=e.base64MaxBytes??n,s;if(typeof e.body=="string"?s=new TextEncoder().encode(e.body).length:(e.body instanceof Uint8Array||e.body instanceof ArrayBuffer||Buffer&&Buffer.isBuffer(e.body))&&(s=e.body.byteLength),s!==void 0&&s>i){let c=await this.createSignedUrl({bucket:e.bucket,key:e.key,action:"upload",expiresInSeconds:300,sizeBytes:s,contentType:e.contentType,encrypt:e.encrypt}),l;typeof e.body=="string"?l=new TextEncoder().encode(e.body):l=e.body;let u=await fetch(c.url,{method:c.method??"PUT",headers:{...e.contentType?{"Content-Type":e.contentType}:{}},body:l});if(!u.ok){let D=await u.text().catch(()=>"");throw new Error(`[flare-admin] Signed-URL upload failed (HTTP ${u.status}): ${D}`)}return {ok:true,bucket:e.bucket,key:e.key,size:s??0,encrypted:!!(e.encrypt??true)}}let a=await ae(e.body),d=await this._svc.uploadObject({serverId:t,path:e.key,contentBase64:a,contentType:e.contentType,encrypt:e.encrypt});return {ok:d.ok,bucket:e.bucket,key:String(d.path??e.key),size:Number(d.size??0),encrypted:!!d.encrypted}}async getObject(e){let t=await this._resolveBucketId(e.bucket,false),n=await this._svc.downloadObject({serverId:t,path:e.key,decrypt:e.decrypt});return {ok:n.ok,bucket:e.bucket,key:String(n.path??e.key),contentBase64:String(n.contentBase64??""),contentType:String(n.contentType??"application/octet-stream"),size:Number(n.size??0),encrypted:!!n.encrypted}}async getObjectUrl(e){return (await this.createSignedUrl({bucket:e.bucket,key:e.key,action:"download",decrypt:e.decrypt,expiresInSeconds:e.expiresInSeconds,forceDownload:e.forceDownload,allowedOrigins:e.allowedOrigins,embedOnly:e.embedOnly})).url}async downloadObject(e){let t=e.forceDownload??true,n=await this.getObjectUrl({...e,forceDownload:t}),i=e.filename??le(e.key),s=globalThis.document;if(!s)return {ok:true,url:n,filename:i,triggered:false};let o=s.createElement("a");return o.href=n,e.openInNewTab?o.target="_blank":o.download=i,o.rel="noopener noreferrer",s.body?.appendChild(o),o.click(),o.remove(),{ok:true,url:n,filename:i,triggered:true}}async headObject(e){let t=await this._resolveBucketId(e.bucket,false),n=await this._svc.request("POST","/object/head",{serverId:t,path:e.key});return {bucket:e.bucket,key:String(n.path??e.key),size:Number(n.size??0),contentType:String(n.contentType??"application/octet-stream"),encrypted:!!n.encrypted,createdAt:n.createdAt,updatedAt:n.updatedAt}}async headObjects(e){return Promise.all(e.keys.map(t=>this.headObject({bucket:e.bucket,key:t})))}async listObjects(e){let t=await this._resolveBucketId(e.bucket,false),n=e.cursor?de(e.cursor):0,i=Math.max(1,Math.min(e.limit??100,1e3)),s=await this._svc.request("POST","/object/list",{serverId:t,prefix:e.prefix,limit:i,skip:n}),o=Array.isArray(s.objects)?s.objects:[],a=!!s.hasMore,d=Number(s.count??o.length);return {bucket:e.bucket,objects:o.map(c=>({bucket:e.bucket,key:String(c.path??c.key??""),size:Number(c.size??0),contentType:String(c.contentType??"application/octet-stream"),encrypted:!!c.encrypted,createdAt:c.createdAt,updatedAt:c.updatedAt})),count:d,hasMore:a,cursor:a?ce(n+o.length):void 0}}async copyObject(e){let[t,n]=await Promise.all([this._resolveBucketId(e.sourceBucket,false),this._resolveBucketId(e.destBucket,true)]);return {ok:!!((await this._svc.request("POST","/object/copy",{serverId:t,path:e.sourceKey,destServerId:n,destPath:e.destKey})).ok??true)}}async copyObjects(e){let t={};return await Promise.all(e.map(async n=>{try{await this.copyObject(n);}catch(i){t[`${n.sourceBucket}/${n.sourceKey}`]=i instanceof Error?i.message:String(i);}})),{ok:Object.keys(t).length===0,errors:t}}async deleteObject(e){return this._svc.deleteObject(e)}async deleteObjects(e){let t=await this._resolveBucketId(e.bucket,false),n=await this._svc.request("POST","/object/delete-many",{serverId:t,paths:e.keys});return {ok:!!(n.ok??true),deleted:Array.isArray(n.deleted)?n.deleted:e.keys,errors:n.errors??{}}}async createSignedUrl(e){let t=await this._resolveBucketId(e.bucket,false);return await this._svc.request("POST","/signed-url",{serverId:t,path:e.key,action:e.action,expiresInSeconds:e.expiresInSeconds,sizeBytes:e.sizeBytes,contentType:e.contentType,encrypt:e.encrypt,decrypt:e.decrypt,forceDownload:e.forceDownload,allowedOrigins:e.allowedOrigins,embedOnly:e.embedOnly})}};var j=class{constructor(e){this.cfg=e;this.ws=null;this.pendingAcks=new Map;this.subscriptions=new Map;this.activeSubscriptions=new Map;this.subscriptionErrorHandlers=new Map;this.subscriptionPermissionHandlers=new Map;this.subscriptionLastErrors=new Map;this.connected=false;this.shouldReconnect=true;this.reconnectDelay=2e3;let t=e.serverUrl.replace(/^http/,"ws");this.wsUrl=`${t}/?appId=${encodeURIComponent(e.appId)}&adminKey=${encodeURIComponent(e.adminKey)}`,this._readyPromise=new Promise(n=>{this._readyResolve=n;}),this._connect();}ready(){return this._readyPromise}disconnect(){this.shouldReconnect=false,this.ws?.close(1e3,"Admin disconnect"),this.ws=null,this.connected=false;}send(e,t){return new Promise((n,i)=>{let s=L(),o={id:s,type:e,ts:Date.now(),...t},a=setTimeout(()=>{this.pendingAcks.delete(s),i(new Error(`[flare-admin] WS request timeout (${e})`));},1e4);this.pendingAcks.set(s,c=>{clearTimeout(a),c.type==="error"?i(new Error(`[flare-admin] Server error: ${c.message}`)):n(c);});let d=()=>this.ws?.send(JSON.stringify(o));this.connected&&this.ws?.readyState===ee.OPEN?d():this.ready().then(d).catch(i);})}subscribe(e,t,n,i,s={}){let o=L(),a={baseId:o,liveId:o,collection:e,docId:t,structuredQuery:n,callback:i,options:s};this.activeSubscriptions.set(o,a),this.subscriptionErrorHandlers.set(o,new Set),this.subscriptionPermissionHandlers.set(o,new Set),this.activateSubscription(a);let d=()=>{let u=this.activeSubscriptions.get(o)?.liveId??o;this.activeSubscriptions.delete(o),this.subscriptions.delete(o),this.subscriptions.delete(u),this.subscriptionErrorHandlers.delete(o),this.subscriptionPermissionHandlers.delete(o),this.subscriptionLastErrors.delete(o),this.connected&&this.send("unsubscribe",{subscriptionId:u}).catch(()=>{});},c=d;return c.unsubscribe=d,c.onError=l=>{this.subscriptionErrorHandlers.get(o)?.add(l);let u=this.subscriptionLastErrors.get(o);if(u)try{l(u);}catch{}return c},c.onPermissionDenied=l=>{this.subscriptionPermissionHandlers.get(o)?.add(l);let u=this.subscriptionLastErrors.get(o);if(u?.permissionDenied)try{l(u);}catch{}return c},c.catch=l=>c.onError(l),c}activateSubscription(e){let t=()=>{this.subscriptions.set(e.liveId,e.callback);let n={collection:e.collection};e.docId&&(n.docId=e.docId),e.structuredQuery&&(n.query=e.structuredQuery),e.options.skipSnapshot&&(n.skipSnapshot=true),this.send("subscribe",n).then(i=>{let s=i.subscriptionId;if(s&&s!==e.liveId){let o=this.subscriptions.get(e.liveId);o&&(this.subscriptions.delete(e.liveId),this.subscriptions.set(s,o),e.liveId=s);}}).catch(()=>{this.subscriptions.delete(e.liveId),this.emitSubscriptionError(e.baseId,this.toSubscriptionError(new Error("Subscribe failed")));});};this.connected?t():this.ready().then(t).catch(n=>{this.emitSubscriptionError(e.baseId,this.toSubscriptionError(n));});}async replayActiveSubscriptions(){if(!this.connected)return;let e=Array.from(this.activeSubscriptions.values());for(let t of e){if(!this.activeSubscriptions.has(t.baseId))continue;let n=t.liveId;this.subscriptions.delete(n),t.liveId=t.baseId,n&&n!==t.baseId&&await this.send("unsubscribe",{subscriptionId:n}).catch(()=>{}),this.activateSubscription(t);}}toSubscriptionError(e){let t=e instanceof Error?e.message:String(e??"Unknown subscription error"),n=t.match(/^\[([^\]]+)\]\s*(.*)$/),i=n?.[1],s=(n?.[2]??t).trim()||t,o=i==="PERMISSION_DENIED"||t.includes("PERMISSION_DENIED");return {code:i,message:s,permissionDenied:o,raw:e}}emitSubscriptionError(e,t){this.subscriptionLastErrors.set(e,t);let n=this.subscriptionErrorHandlers.get(e);if(n)for(let i of n)try{i(t);}catch{}if(t.permissionDenied){let i=this.subscriptionPermissionHandlers.get(e);if(i)for(let s of i)try{s(t);}catch{}}}_connect(){this._readyPromise=new Promise(e=>{this._readyResolve=e;}),this.ws=new ee(this.wsUrl),this.ws.on("message",e=>{let t;try{t=JSON.parse(e.toString());}catch{return}this._handle(t);}),this.ws.on("close",e=>{this.connected=false,this.shouldReconnect&&e!==1e3&&setTimeout(()=>{this.reconnectDelay=Math.min(this.reconnectDelay*2,3e4),this._connect();},this.reconnectDelay);}),this.ws.on("error",()=>{});}_handle(e){let t=e.type;if(t==="auth_ok"){this.connected||(this.connected=true,this.reconnectDelay=2e3,this._readyResolve(),this.replayActiveSubscriptions().catch(()=>{}));return}if(t==="ack"||t==="pong"||t==="call_response"){let n=e.correlationId??e.id,i=this.pendingAcks.get(n);i&&(i(e),this.pendingAcks.delete(n));return}if(t==="error"){let n=e.correlationId;if(n){let i=this.pendingAcks.get(n);i&&(i(e),this.pendingAcks.delete(n));let s=Array.from(this.activeSubscriptions.values()).find(o=>o.liveId===n||o.baseId===n);if(s){let o=this.toSubscriptionError(new Error(`[${String(e.code??"ERROR")}] ${String(e.message??"Unknown error")}`));this.emitSubscriptionError(s.baseId,o);}}return}if(t==="snapshot"||t==="change"){let n=e.subscriptionId,i=this.subscriptions.get(n);if(i){let s=Array.from(this.activeSubscriptions.values()).find(d=>d.liveId===n),o=String(e.collection??s?.collection??""),a=t==="change"&&e.operation==="delete"?null:y(this.cfg,o,e.data,s?.structuredQuery);i({subscriptionId:n,collection:o,docId:e.docId,data:a,type:t==="snapshot"?"snapshot":"change",operation:e.operation});}}}};var I=class{constructor(e,t,n){this.conn=e;this.collection=t;this.id=n;}onSnapshot(e){let t=()=>{};return t=this.conn.subscribe(this.collection,this.id,void 0,n=>{n.type==="snapshot"&&(e(n),t());}),t}};var F=class r{constructor(e,t){this.conn=e;this.name=t;this.sq={};}clone(e){let t=new r(this.conn,this.name);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}toQueryFilters(e){return x(e).map(n=>typeof n=="object"&&n!=null&&"field"in n&&"op"in n?{...n,value:this.normalizeFilterValue(n.op,n.value)}:n)}appendAndFilters(e){return this.clone({where:[...this.sq.where??[],...e]})}appendOrFilters(e){let t=[...this.sq.where??[]];if(t.length===0)return this.clone({where:[{or:e}]});let n=t[0];if(t.length===1&&typeof n=="object"&&n!=null&&"or"in n)return this.clone({where:[{or:[...n.or,...e]}]});let s=t.length===1?t[0]:{and:t};return this.clone({where:[{or:[s,...e]}]})}appendFilters(e,t){return t==="or"?this.appendOrFilters(e):this.appendAndFilters(e)}appendOperatorFilter(e,t,n,i){return this.appendFilters([{field:e,op:t,value:this.normalizeFilterValue(t,n)}],i)}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.latest()}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,n){return this.clone({having:[...this.sq.having??[],{field:e,op:t,value:n}]})}buildStructuredJoin(e,t){let n={from:String(e??""),localField:String(t?.source??""),foreignField:String(t?.target??""),as:String(t?.as??""),single:t?.single};return Array.isArray(t?.where)&&(n.where=t.where),Array.isArray(t?.orderBy)&&(n.orderBy=t.orderBy),typeof t?.limit=="number"&&(n.limit=t.limit),typeof t?.offset=="number"&&(n.offset=t.offset),Array.isArray(t?.select)&&(n.select=t.select),Array.isArray(t?.joins)&&(n.joins=t.joins.map(i=>this.buildStructuredJoin(String(i?.collection??""),i))),n}cloneStructuredJoin(e){let t={...e};return Array.isArray(e.where)&&(t.where=e.where.map(n=>({...n}))),Array.isArray(e.orderBy)&&(t.orderBy=e.orderBy.map(n=>({...n}))),Array.isArray(e.select)&&(t.select=[...e.select]),Array.isArray(e.joins)&&(t.joins=e.joins.map(n=>this.cloneStructuredJoin(n))),t}appendNestedJoinByAlias(e,t,n){for(let i of e){if(i.as===t)return i.joins=[...i.joins??[],n],true;if(Array.isArray(i.joins)&&this.appendNestedJoinByAlias(i.joins,t,n))return true}return false}parseRelationRef(e){let n=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(!n)throw new Error(`Invalid relation format: "${e}". Expected "source.path->collection.target"`);return {source:n[1],collection:n[2],target:n[3],alias:n[4]}}join(e,t){let n=this.buildStructuredJoin(e,t);return this.clone({joins:[...this.sq.joins??[],n]})}joinNested(e,t,n){let i=String(e??"").trim();if(!i)throw new Error("joinNested requires parentAlias");let s=(this.sq.joins??[]).map(a=>this.cloneStructuredJoin(a));if(s.length===0)throw new Error(`joinNested parent alias "${i}" not found`);let o=this.buildStructuredJoin(t,n);if(!this.appendNestedJoinByAlias(s,i,o))throw new Error(`joinNested parent alias "${i}" not found`);return this.clone({joins:s})}Join(e,t){return this.join(e,t)}JoinNested(e,t,n){return this.joinNested(e,t,n)}withRelation(e,t={}){let n=this.parseRelationRef(e);return this.join(n.collection,{...t,source:n.source,target:n.target,as:t.as??n.alias??n.collection})}select(...e){return this.clone({select:e})}distinctField(e){return this.clone({distinctField:e})}vectorSearch(e){return this.clone({vectorSearch:e})}doc(e){return new I(this.conn,this.name,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.name,query:e}}onSnapshot(e){let t=this._buildSq(),n=()=>{};return n=this.conn.subscribe(this.name,void 0,t,i=>{i.type==="snapshot"&&(e(i),n());}),n}onDocAdded(e){let t=this._buildSq();return this.conn.subscribe(this.name,void 0,t,n=>{n.type==="change"&&n.operation==="insert"&&n.data!=null&&e(n.data,n.docId);},{skipSnapshot:true})}onDocUpdated(e){let t=this._buildSq();return this.conn.subscribe(this.name,void 0,t,n=>{n.type==="change"&&(n.operation==="update"||n.operation==="replace")&&n.data!=null&&e(n.data,n.docId);},{skipSnapshot:true})}onDocDeleted(e){let t=this._buildSq();return this.conn.subscribe(this.name,void 0,t,n=>{n.type==="change"&&n.operation==="delete"&&e(n.docId);},{skipSnapshot:true})}onDocChanged(e){let t=this._buildSq();return this.conn.subscribe(this.name,void 0,t,n=>{n.type==="change"&&e(n.data??null,n.docId,n.operation);},{skipSnapshot:true})}_buildSq(){let e={};return this.sq.where&&this.sq.where.length>0&&(e.where=this.sq.where),this.sq.orderBy&&this.sq.orderBy.length>0&&(e.orderBy=this.sq.orderBy),this.sq.limit!==void 0&&(e.limit=this.sq.limit),this.sq.offset!==void 0&&(e.offset=this.sq.offset),this.sq.startAt&&(e.startAt=this.sq.startAt),this.sq.startAfter&&(e.startAfter=this.sq.startAfter),this.sq.endAt&&(e.endAt=this.sq.endAt),this.sq.endBefore&&(e.endBefore=this.sq.endBefore),this.sq.aggregate&&this.sq.aggregate.length>0&&(e.aggregate=this.sq.aggregate),this.sq.groupBy&&(e.groupBy=this.sq.groupBy),this.sq.having&&this.sq.having.length>0&&(e.having=this.sq.having),this.sq.joins&&this.sq.joins.length>0&&(e.joins=this.sq.joins),this.sq.vectorSearch&&(e.vectorSearch=this.sq.vectorSearch),this.sq.select&&this.sq.select.length>0&&(e.select=this.sq.select),this.sq.distinctField&&(e.distinctField=this.sq.distinctField),e}};var P=class{constructor(e){this._ws=new j(e);}collection(e){return new F(this._ws,e)}ready(){return this._ws.ready()}disconnect(){this._ws.disconnect();}};var Et="ServerTimeStamp",_t={$serverTimestamp:true};var H=class{constructor(e){this.cfg={defaultTtl:"24h",transport:"auto",...e,serverUrl:e.serverUrl.replace(/\/$/,""),grpcUrl:e.grpcUrl??"",dataMapper:e.dataMapper??{}};}auth(){return this._auth??(this._auth=new T(this.cfg))}db(){return this._db??(this._db=new v(this.cfg))}connection(){return this._conn??(this._conn=new P(this.cfg))}notifications(){return this._notifications??(this._notifications=new R(this.cfg))}storageService(){return this._storage??(this._storage=new _(this.cfg))}storage(){return this._storageS3||(this._storageS3=new O(this.storageService())),this._storageS3}s3(){return this.storage()}async createSignedUrl(e){return await this.s3().createSignedUrl(e)}createBucket(e,t){return this.s3().createBucket(e,t)}listBuckets(){return this.s3().listBuckets()}deleteBucket(e){return this.s3().deleteBucket(e)}deleteBuckets(e){return this.s3().deleteBuckets(e)}getBucketLocation(e){return this.s3().getBucketLocation(e)}putObject(e){return this.s3().putObject(e)}getObject(e){return this.s3().getObject(e)}getObjectUrl(e){return this.s3().getObjectUrl(e)}downloadObject(e){return this.s3().downloadObject(e)}headObject(e){return this.s3().headObject(e)}headObjects(e){return this.s3().headObjects(e)}listObjects(e){return this.s3().listObjects(e)}copyObject(e){return this.s3().copyObject(e)}copyObjects(e){return this.s3().copyObjects(e)}deleteObjects(e){return this.s3().deleteObjects(e)}},q=new Map;function Ht(r,e="[DEFAULT]"){if(q.has(e))return q.get(e);let t=new H(r);return q.set(e,t),t}function B(r="[DEFAULT]"){let e=q.get(r);if(!e)throw new Error(`[flare-admin] No app named "${r}" found. Call connectApp() before getApp().`);return e}function Gt(r="[DEFAULT]"){return B(r).auth()}function Mt(r="[DEFAULT]"){return B(r).db()}function Qt(r="[DEFAULT]"){return B(r).connection()}function zt(r="[DEFAULT]"){return B(r).notifications()}function Kt(r="[DEFAULT]"){return B(r).storage()}export{k as AdminCollectionReference,b as AdminDocumentReference,F as AdminLiveCollectionReference,I as AdminLiveDocumentReference,U as AdminStorageSignedAction,H as FlareAdminApp,T as FlareAdminAuthService,P as FlareAdminConnection,v as FlareAdminDbService,R as FlareAdminNotificationsService,O as FlareAdminStorageS3,j as FlareAdminWsConnection,Et as ServerTimeStamp,_t as ServerTimeStampField,Gt as auth,Ht as connectApp,Qt as connection,Mt as db,B as getApp,zt as notifications,Kt as storage};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { AdminAuthTicket, CreateAuthTicketOptions, CreateCustomTokenOptions, FlareAdminConfig, StructuredQuery, AnyFilter } from "../types";
|
|
2
|
+
export declare const shouldUseGrpcTransport: (cfg: Required<FlareAdminConfig>) => boolean;
|
|
3
|
+
export declare function runGrpcAdminQuery<T = Record<string, unknown>>(cfg: Required<FlareAdminConfig>, collection: string, query: StructuredQuery): Promise<T[] | null>;
|
|
4
|
+
export declare function runGrpcCreateCustomToken(cfg: Required<FlareAdminConfig>, uid: string, opts: CreateCustomTokenOptions): Promise<string | null>;
|
|
5
|
+
export declare function runGrpcCreateAuthTicket(cfg: Required<FlareAdminConfig>, uid: string, opts: CreateAuthTicketOptions): Promise<AdminAuthTicket | null>;
|
|
6
|
+
export declare function runGrpcGetDocument<T = Record<string, unknown>>(cfg: Required<FlareAdminConfig>, collection: string, id: string): Promise<T | null | undefined>;
|
|
7
|
+
export declare function runGrpcCreateDocument(cfg: Required<FlareAdminConfig>, collection: string, data: unknown): Promise<string | null>;
|
|
8
|
+
export declare function runGrpcReplaceDocument(cfg: Required<FlareAdminConfig>, collection: string, id: string, data: unknown): Promise<boolean | null>;
|
|
9
|
+
export declare function runGrpcUpdateDocument(cfg: Required<FlareAdminConfig>, collection: string, id: string, data: unknown): Promise<boolean | null>;
|
|
10
|
+
export declare function runGrpcDeleteDocument(cfg: Required<FlareAdminConfig>, collection: string, id: string): Promise<boolean | null>;
|
|
11
|
+
export declare function runGrpcDeleteMany(cfg: Required<FlareAdminConfig>, collection: string, where: AnyFilter[]): Promise<number | null>;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { AdminCopyObjectInput, AdminDeleteObjectsInput, AdminDownloadObjectInput, AdminDownloadObjectResult, AdminGetObjectInput, AdminGetObjectResult, AdminGetObjectUrlInput, AdminHeadObjectInput, AdminHeadObjectsInput, AdminListObjectsInput, AdminListObjectsResult, AdminPutObjectInput, AdminPutObjectResult, AdminStorageAwsConfig, AdminStorageBucket, AdminStorageBucketInput, AdminStorageDeleteInput, AdminStorageDownloadInput, AdminStorageObjectMeta, AdminStorageObjectResult, AdminStorageRulesHistoryResult, AdminStorageRulesPolicy, AdminStorageServer, AdminStorageServerInput, AdminStorageServerPatchInput, AdminStorageSignedUrlInput, AdminStorageSignedUrlResult, AdminStorageUploadInput, FlareAdminConfig } from "../types";
|
|
2
|
+
export declare class FlareAdminStorageService {
|
|
3
|
+
private readonly cfg;
|
|
4
|
+
constructor(cfg: Required<FlareAdminConfig>);
|
|
5
|
+
private base;
|
|
6
|
+
private get headers();
|
|
7
|
+
protected jsonRequest<T>(method: string, path: string, body?: unknown): Promise<T>;
|
|
8
|
+
request<T>(method: string, path: string, body?: unknown): Promise<T>;
|
|
9
|
+
servers(): Promise<AdminStorageServer[]>;
|
|
10
|
+
createServer(input: AdminStorageServerInput): Promise<{
|
|
11
|
+
ok: boolean;
|
|
12
|
+
serverId: string;
|
|
13
|
+
}>;
|
|
14
|
+
patchServer(serverId: string, input: AdminStorageServerPatchInput): Promise<{
|
|
15
|
+
ok: boolean;
|
|
16
|
+
serverId: string;
|
|
17
|
+
}>;
|
|
18
|
+
deleteServer(serverId: string): Promise<{
|
|
19
|
+
ok: boolean;
|
|
20
|
+
serverId: string;
|
|
21
|
+
removedObjects: number;
|
|
22
|
+
}>;
|
|
23
|
+
awsConfig(serverId: string): Promise<AdminStorageAwsConfig>;
|
|
24
|
+
uploadObject(input: AdminStorageUploadInput): Promise<AdminStorageObjectResult>;
|
|
25
|
+
downloadObject(input: AdminStorageDownloadInput): Promise<AdminStorageObjectResult>;
|
|
26
|
+
deleteObject(input: AdminStorageDeleteInput): Promise<AdminStorageObjectResult>;
|
|
27
|
+
createSignedUrl(input: AdminStorageSignedUrlInput): Promise<AdminStorageSignedUrlResult>;
|
|
28
|
+
setRules(input: {
|
|
29
|
+
rules?: Record<string, unknown>;
|
|
30
|
+
rulesDsl?: string;
|
|
31
|
+
rulesHistoryPolicy?: AdminStorageRulesPolicy;
|
|
32
|
+
}): Promise<{
|
|
33
|
+
id: string;
|
|
34
|
+
}>;
|
|
35
|
+
validateRules(rulesDsl: string): Promise<{
|
|
36
|
+
valid: boolean;
|
|
37
|
+
diagnostics: unknown[];
|
|
38
|
+
rulesCount: number;
|
|
39
|
+
}>;
|
|
40
|
+
rulesHistory(): Promise<AdminStorageRulesHistoryResult>;
|
|
41
|
+
restoreRules(historyId: string): Promise<{
|
|
42
|
+
id: string;
|
|
43
|
+
rulesText: string;
|
|
44
|
+
}>;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* S3-compatible admin storage service.
|
|
48
|
+
* Works with bucket names; resolves server IDs internally.
|
|
49
|
+
*/
|
|
50
|
+
export declare class FlareAdminStorageS3 {
|
|
51
|
+
private readonly _svc;
|
|
52
|
+
private readonly _bucketCache;
|
|
53
|
+
private _bucketListLoaded;
|
|
54
|
+
private _bucketListPromise;
|
|
55
|
+
constructor(svc: FlareAdminStorageService);
|
|
56
|
+
private _ensureBuckets;
|
|
57
|
+
private _loadBuckets;
|
|
58
|
+
private _invalidateCache;
|
|
59
|
+
private _resolveBucketId;
|
|
60
|
+
createBucket(name: string, options?: AdminStorageBucketInput): Promise<AdminStorageBucket>;
|
|
61
|
+
listBuckets(): Promise<AdminStorageBucket[]>;
|
|
62
|
+
deleteBucket(name: string): Promise<{
|
|
63
|
+
ok: boolean;
|
|
64
|
+
removedObjects: number;
|
|
65
|
+
}>;
|
|
66
|
+
deleteBuckets(names: string[]): Promise<{
|
|
67
|
+
ok: boolean;
|
|
68
|
+
deleted: string[];
|
|
69
|
+
errors: Record<string, string>;
|
|
70
|
+
}>;
|
|
71
|
+
getBucketLocation(name: string): Promise<{
|
|
72
|
+
bucket: string;
|
|
73
|
+
kind: string;
|
|
74
|
+
region?: string;
|
|
75
|
+
endpoint?: string;
|
|
76
|
+
}>;
|
|
77
|
+
putObject(input: AdminPutObjectInput): Promise<AdminPutObjectResult>;
|
|
78
|
+
getObject(input: AdminGetObjectInput): Promise<AdminGetObjectResult>;
|
|
79
|
+
getObjectUrl(input: AdminGetObjectUrlInput): Promise<string>;
|
|
80
|
+
downloadObject(input: AdminDownloadObjectInput): Promise<AdminDownloadObjectResult>;
|
|
81
|
+
headObject(input: AdminHeadObjectInput): Promise<AdminStorageObjectMeta>;
|
|
82
|
+
headObjects(input: AdminHeadObjectsInput): Promise<AdminStorageObjectMeta[]>;
|
|
83
|
+
listObjects(input: AdminListObjectsInput): Promise<AdminListObjectsResult>;
|
|
84
|
+
copyObject(input: AdminCopyObjectInput): Promise<{
|
|
85
|
+
ok: boolean;
|
|
86
|
+
}>;
|
|
87
|
+
copyObjects(inputs: AdminCopyObjectInput[]): Promise<{
|
|
88
|
+
ok: boolean;
|
|
89
|
+
errors: Record<string, string>;
|
|
90
|
+
}>;
|
|
91
|
+
deleteObject(input: AdminStorageDeleteInput): Promise<AdminStorageObjectResult>;
|
|
92
|
+
deleteObjects(input: AdminDeleteObjectsInput): Promise<{
|
|
93
|
+
ok: boolean;
|
|
94
|
+
deleted: string[];
|
|
95
|
+
errors: Record<string, string>;
|
|
96
|
+
}>;
|
|
97
|
+
createSignedUrl(input: AdminStorageSignedUrlInput): Promise<AdminStorageSignedUrlResult>;
|
|
98
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sentinel value that asks flare-node to write the current server timestamp.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* await admin.db().collection("posts").doc(id).update({ updatedAt: ServerTimeStamp })
|
|
6
|
+
*/
|
|
7
|
+
export declare const ServerTimeStamp: "ServerTimeStamp";
|
|
8
|
+
/**
|
|
9
|
+
* Object form of the same sentinel for payloads that prefer structured values.
|
|
10
|
+
*/
|
|
11
|
+
export declare const ServerTimeStampField: {
|
|
12
|
+
readonly $serverTimestamp: true;
|
|
13
|
+
};
|