@zuzjs/flare-admin 0.1.7 → 0.1.8
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 +1 -0
- package/dist/db/Collection.d.ts +4 -0
- package/dist/index.cjs +3 -3
- package/dist/index.d.cts +5 -0
- package/dist/index.js +2 -2
- package/dist/types/index.d.ts +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -208,6 +208,7 @@ const ticket = await admin.auth().getTicket(uid, {
|
|
|
208
208
|
const users = await admin.db().collection("users").get();
|
|
209
209
|
|
|
210
210
|
await admin.db().collection("users").doc("alice").set({ name: "Alice" });
|
|
211
|
+
await admin.db().collection("users").update("alice", { plan: "pro" });
|
|
211
212
|
await admin.db().collection("users").doc("alice").update({ plan: "pro" });
|
|
212
213
|
await admin.db().collection("users").doc("alice").delete();
|
|
213
214
|
|
package/dist/db/Collection.d.ts
CHANGED
|
@@ -90,6 +90,10 @@ export declare class AdminCollectionReference<T = Record<string, unknown>> {
|
|
|
90
90
|
* Create a single document and return its reference.
|
|
91
91
|
*/
|
|
92
92
|
add(data: Partial<T>): Promise<AdminDocumentReference<T>>;
|
|
93
|
+
/**
|
|
94
|
+
* Update a single document by id and return its reference.
|
|
95
|
+
*/
|
|
96
|
+
update(id: string, data: Partial<T>): Promise<AdminDocumentReference<T>>;
|
|
93
97
|
private ensureBulkOptions;
|
|
94
98
|
private toPercent;
|
|
95
99
|
private emitBulkProgress;
|
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
'use strict';var ve=require('fs'),
|
|
2
|
-
var Se=()=>typeof document>"u"?new URL(`file:${__filename}`).href:document.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"?document.currentScript.src:new URL("main.js",document.baseURI).href,p=Se();var V=(i=>(i.Upload="upload",i.Download="download",i.Delete="delete",i.Edit="edit",i))(V||{});function W(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:we(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 we(r){return isNaN(Number(r))?r==="true"?true:r==="false"?false:r==="null"?null:r:Number(r)}function Z(){return Math.random().toString(36).slice(2,12)+Date.now().toString(36)}function Ce(r,e){let t=r.dataMapper;if(!t||typeof t!="object")return null;let n=t[e];return typeof n=="function"?n:null}function X(r,e,t){let n=Ce(r,e);if(!n||t==null||typeof t!="object")return t;try{return n(t)}catch{return t}}function Y(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=>Y(r,c,o)):a&&typeof a=="object"&&(d=Y(r,a,o)),d=Array.isArray(d)?d.map(c=>X(r,s,c)):X(r,s,d),d!==a&&(n===e&&(n={...n}),n[s]=d);}return n}function v(r,e,t,n){let i=Array.isArray(n?.joins)?n.joins:[],s=o=>{let a=Y(r,o,i);return X(r,e,a)};return Array.isArray(t)?t.map(o=>s(o)):s(t)}var Re=()=>typeof process<"u"&&!!process.versions?.node,h=r=>{if(r.transport==="http")return false;let e=!!(r.grpcUrl&&r.grpcUrl.trim().length>0),t=Re();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},P=r=>{try{return JSON.stringify(r??{})}catch{return "{}"}},F=r=>r?.field&&r?.op?{queryFilter:{field:String(r.field),op:String(r.op),valueJson:P(r.value)}}:Array.isArray(r?.or)?{orFilter:{or:r.or.map(e=>F(e))}}:Array.isArray(r?.and)?{andFilter:{and:r.and.map(e=>F(e))}}:{queryFilter:{field:"",op:"==",valueJson:"null"}},H=r=>{if(!(!r||!Array.isArray(r.values)))return {valuesJson:r.values.map(e=>P(e))}},ae=r=>({from:r.from,localField:r.localField,foreignField:r.foreignField,as:r.as,single:!!r.single,where:Array.isArray(r.where)?r.where.map(F):[],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(ae):[]}),Oe=r=>({where:Array.isArray(r.where)?r.where.map(F):[],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:H(r.startAt),startAfter:H(r.startAfter),endAt:H(r.endAt),endBefore:H(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(ae):[],select:Array.isArray(r.select)?r.select:[],distinctField:r.distinctField??""});async function k(r){let e=await import('@grpc/grpc-js'),t=await import('@grpc/proto-loader'),n=B__default.default.dirname(url.fileURLToPath(p)),i=[B__default.default.resolve(n,"../../proto"),B__default.default.resolve(n,"../proto"),B__default.default.resolve(process.cwd(),"proto")],s=i.find(m=>ve__default.default.existsSync(B__default.default.join(m,"flare.proto")))??i[0],o=B__default.default.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 S(r,e,t){return new Promise((n,i)=>{r[e](t,(s,o)=>{if(s)return i(s);n(o??{});});})}function w(r,e){if(r.error)throw new Error(`[flare-admin][grpc] ${e} failed: ${r.errorDescription||r.error}`)}async function ce(r,e,t){if(!h(r))return null;let n=await k(r.grpcUrl),i=await S(n,"AdminQuery",{app_id:r.appId,admin_key:r.adminKey,collection:e,query:Oe(t)});w(i,"admin_query");try{let s=JSON.parse(i.dataJson||"[]");return Array.isArray(s)?s:[]}catch{return []}}async function de(r,e,t){if(!h(r))return null;let n=await k(r.grpcUrl),i=await S(n,"CreateCustomToken",{app_id:r.appId,admin_key:r.adminKey,uid:e,role:t.role??"user",claims_json:P(t.claims??{}),ttl:t.ttl??r.defaultTtl});if(w(i,"create_custom_token"),!i.token)throw new Error("[flare-admin][grpc] create_custom_token returned empty token");return String(i.token)}async function le(r,e,t){if(!h(r))return null;let n=await k(r.grpcUrl),i=await S(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 w(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 ue(r,e,t){if(!h(r))return;let n=await k(r.grpcUrl),i=await S(n,"GetDocument",{app_id:r.appId,admin_key:r.adminKey,collection:e,doc_id:t});if(w(i,"get_document"),!i.found)return null;try{return JSON.parse(i.dataJson||"{}")}catch{return {}}}async function me(r,e,t){if(!h(r))return null;let n=await k(r.grpcUrl),i=await S(n,"CreateDocument",{app_id:r.appId,admin_key:r.adminKey,collection:e,data_json:P(t)});return w(i,"create_document"),String(i.id??"")}async function pe(r,e,t,n){if(!h(r))return null;let i=await k(r.grpcUrl),s=await S(i,"ReplaceDocument",{app_id:r.appId,admin_key:r.adminKey,collection:e,doc_id:t,data_json:P(n)});return w(s,"replace_document"),true}async function ge(r,e,t,n){if(!h(r))return null;let i=await k(r.grpcUrl),s=await S(i,"UpdateDocument",{app_id:r.appId,admin_key:r.adminKey,collection:e,doc_id:t,data_json:P(n)});return w(s,"update_document"),true}async function he(r,e,t){if(!h(r))return null;let n=await k(r.grpcUrl),i=await S(n,"DeleteDocument",{app_id:r.appId,admin_key:r.adminKey,collection:e,doc_id:t});return w(i,"delete_document"),!!i.deleted}async function fe(r,e,t){if(!h(r))return null;let n=await k(r.grpcUrl),i=await S(n,"DeleteMany",{app_id:r.appId,admin_key:r.adminKey,collection:e,where:(t??[]).map(F)});return w(i,"delete_many"),Number(i.deleted??0)}var Ae=r=>r.replace(/\/$/,""),Ie=r=>{let e=String(r.httpBase??"").trim();return Ae(e||r.serverUrl)},A=(r,e)=>{let t=Ie(r),n=e.startsWith("/")?e:`/${e}`;return `${t}${n}`};var O=class{constructor(e,t,n){this.cfg=e;this.collection=t;this.id=n;}get baseUrl(){return A(this.cfg,`/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 ue(this.cfg,this.collection,this.id);if(e!==void 0)return e===null?null:v(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 v(this.cfg,this.collection,n.data)??null}async set(e){await pe(this.cfg,this.collection,this.id,e)===null&&await this.request("PUT",e);}async update(e){await ge(this.cfg,this.collection,this.id,e)===null&&await this.request("PATCH",e);}async delete(){await he(this.cfg,this.collection,this.id)===null&&await this.request("DELETE");}parent(){return new I(this.cfg,this.collection)}};var I=class r{constructor(e,t){this.cfg=e;this.name=t;this.sq={};this.opts={allowSensitiveAuthUserFields:true};}get baseUrl(){return A(this.cfg,`/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 W(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 ce(this.cfg,this.name,this.sq);if(e)return v(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 v(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 me(this.cfg,this.name,e);if(t!==null)return new O(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 O(this.cfg,this.name,i.id)}ensureBulkOptions(e){let t=Number(e?.batchSize??250),n=Number(e?.concurrency??1);return {...e,batchSize:Number.isFinite(t)&&t>0?Math.floor(t):250,concurrency:Number.isFinite(n)&&n>0?Math.floor(n):1,continueOnError:e?.continueOnError===true}}toPercent(e,t){if(!(typeof t!="number"||t<=0))return Math.round(e/t*100)}emitBulkProgress(e,t,n){n&&n({operation:e,...t,percent:this.toPercent(t.processed,t.total)});}async*chunkIterable(e,t){let n=[];for await(let i of e)n.push(i),n.length>=t&&(yield n,n=[]);n.length>0&&(yield n);}assertBulkSignal(e){if(e?.aborted)throw new Error("Bulk write aborted")}async runChunkWorkers(e,t,n,i,s,o,a=false,d){let c=0,m=async()=>{for(;c<t.length;){this.assertBulkSignal(d);let f=c;c+=1;let R=t[f];try{let b=await i(R);s.succeeded+=1,s.processed+=1,this.emitBulkProgress(e,{processed:s.processed,succeeded:s.succeeded,failed:s.failed,total:s.total,lastDocId:b.docId},o);}catch(b){if(s.failed+=1,s.processed+=1,this.emitBulkProgress(e,{processed:s.processed,succeeded:s.succeeded,failed:s.failed,total:s.total,lastError:b},o),!a)throw b}}},u=Math.max(1,Math.min(n,t.length));await Promise.all(Array.from({length:u},()=>m()));}async runBulkWrite(e,t,n,i){let s=this.ensureBulkOptions(i);this.assertBulkSignal(s.signal);let o={processed:0,succeeded:0,failed:0,total:Array.isArray(t)?t.length:void 0};this.emitBulkProgress(e,{processed:0,succeeded:0,failed:0,total:o.total},s.onProgress);for await(let a of this.chunkIterable(t,s.batchSize))this.assertBulkSignal(s.signal),await this.runChunkWorkers(e,a,s.concurrency,n,o,s.onProgress,s.continueOnError,s.signal);return {operation:e,processed:o.processed,succeeded:o.succeeded,failed:o.failed,total:o.total}}async addMany(e,t){return this.runBulkWrite("addMany",e,async n=>({docId:(await this.add(n)).id}),t)}async updateMany(e,t){return this.runBulkWrite("updateMany",e,async n=>(await this.doc(n.id).update(n.data),{docId:n.id}),t)}async deleteMany(e,t){return e==null?this.deleteManyByQuery():this.runBulkWrite("deleteMany",e,async n=>(await this.doc(n).delete(),{docId:n}),t)}async deleteManyByQuery(){let e=await fe(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 O(this.cfg,this.name,e)}};var x=class{constructor(e){this.cfg=e;}collection(e){return new I(this.cfg,e)}};var _=class{constructor(e){this.cfg=e;}async createCustomToken(e,t={}){if(h(this.cfg)){let a=await de(this.cfg,String(e),t);if(!a)throw new Error("[flare-admin][grpc] create_custom_token returned empty token");return a}let n=A(this.cfg,"/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}
|
|
1
|
+
'use strict';var ve=require('fs'),P=require('path'),url=require('url'),ye=require('ws');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var ve__default=/*#__PURE__*/_interopDefault(ve);var P__default=/*#__PURE__*/_interopDefault(P);var ye__default=/*#__PURE__*/_interopDefault(ye);/* @zuzjs/flare-admin */
|
|
2
|
+
var ke=()=>typeof document>"u"?new URL(`file:${__filename}`).href:document.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"?document.currentScript.src:new URL("main.js",document.baseURI).href,p=ke();var V=(i=>(i.Upload="upload",i.Download="download",i.Delete="delete",i.Edit="edit",i))(V||{});function W(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:we(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 we(r){return isNaN(Number(r))?r==="true"?true:r==="false"?false:r==="null"?null:r:Number(r)}function Z(){return Math.random().toString(36).slice(2,12)+Date.now().toString(36)}function Ce(r,e){let t=r.dataMapper;if(!t||typeof t!="object")return null;let n=t[e];return typeof n=="function"?n:null}function X(r,e,t){let n=Ce(r,e);if(!n||t==null||typeof t!="object")return t;try{return n(t)}catch{return t}}function Y(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=>Y(r,c,o)):a&&typeof a=="object"&&(d=Y(r,a,o)),d=Array.isArray(d)?d.map(c=>X(r,s,c)):X(r,s,d),d!==a&&(n===e&&(n={...n}),n[s]=d);}return n}function v(r,e,t,n){let i=Array.isArray(n?.joins)?n.joins:[],s=o=>{let a=Y(r,o,i);return X(r,e,a)};return Array.isArray(t)?t.map(o=>s(o)):s(t)}var Re=()=>typeof process<"u"&&!!process.versions?.node,h=r=>{if(r.transport==="http")return false;let e=!!(r.grpcUrl&&r.grpcUrl.trim().length>0),t=Re();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},B=r=>{try{return JSON.stringify(r??{})}catch{return "{}"}},F=r=>r?.field&&r?.op?{queryFilter:{field:String(r.field),op:String(r.op),valueJson:B(r.value)}}:Array.isArray(r?.or)?{orFilter:{or:r.or.map(e=>F(e))}}:Array.isArray(r?.and)?{andFilter:{and:r.and.map(e=>F(e))}}:{queryFilter:{field:"",op:"==",valueJson:"null"}},H=r=>{if(!(!r||!Array.isArray(r.values)))return {valuesJson:r.values.map(e=>B(e))}},ae=r=>({from:r.from,localField:r.localField,foreignField:r.foreignField,as:r.as,single:!!r.single,where:Array.isArray(r.where)?r.where.map(F):[],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(ae):[]}),Oe=r=>({where:Array.isArray(r.where)?r.where.map(F):[],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:H(r.startAt),startAfter:H(r.startAfter),endAt:H(r.endAt),endBefore:H(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(ae):[],select:Array.isArray(r.select)?r.select:[],distinctField:r.distinctField??""});async function S(r){let e=await import('@grpc/grpc-js'),t=await import('@grpc/proto-loader'),n=P__default.default.dirname(url.fileURLToPath(p)),i=[P__default.default.resolve(n,"../../proto"),P__default.default.resolve(n,"../proto"),P__default.default.resolve(process.cwd(),"proto")],s=i.find(m=>ve__default.default.existsSync(P__default.default.join(m,"flare.proto")))??i[0],o=P__default.default.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 k(r,e,t){return new Promise((n,i)=>{r[e](t,(s,o)=>{if(s)return i(s);n(o??{});});})}function w(r,e){if(r.error)throw new Error(`[flare-admin][grpc] ${e} failed: ${r.errorDescription||r.error}`)}async function ce(r,e,t){if(!h(r))return null;let n=await S(r.grpcUrl),i=await k(n,"AdminQuery",{app_id:r.appId,admin_key:r.adminKey,collection:e,query:Oe(t)});w(i,"admin_query");try{let s=JSON.parse(i.dataJson||"[]");return Array.isArray(s)?s:[]}catch{return []}}async function de(r,e,t){if(!h(r))return null;let n=await S(r.grpcUrl),i=await k(n,"CreateCustomToken",{app_id:r.appId,admin_key:r.adminKey,uid:e,role:t.role??"user",claims_json:B(t.claims??{}),ttl:t.ttl??r.defaultTtl});if(w(i,"create_custom_token"),!i.token)throw new Error("[flare-admin][grpc] create_custom_token returned empty token");return String(i.token)}async function le(r,e,t){if(!h(r))return null;let n=await S(r.grpcUrl),i=await k(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 w(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 ue(r,e,t){if(!h(r))return;let n=await S(r.grpcUrl),i=await k(n,"GetDocument",{app_id:r.appId,admin_key:r.adminKey,collection:e,doc_id:t});if(w(i,"get_document"),!i.found)return null;try{return JSON.parse(i.dataJson||"{}")}catch{return {}}}async function me(r,e,t){if(!h(r))return null;let n=await S(r.grpcUrl),i=await k(n,"CreateDocument",{app_id:r.appId,admin_key:r.adminKey,collection:e,data_json:B(t)});return w(i,"create_document"),String(i.id??"")}async function pe(r,e,t,n){if(!h(r))return null;let i=await S(r.grpcUrl),s=await k(i,"ReplaceDocument",{app_id:r.appId,admin_key:r.adminKey,collection:e,doc_id:t,data_json:B(n)});return w(s,"replace_document"),true}async function ge(r,e,t,n){if(!h(r))return null;let i=await S(r.grpcUrl),s=await k(i,"UpdateDocument",{app_id:r.appId,admin_key:r.adminKey,collection:e,doc_id:t,data_json:B(n)});return w(s,"update_document"),true}async function he(r,e,t){if(!h(r))return null;let n=await S(r.grpcUrl),i=await k(n,"DeleteDocument",{app_id:r.appId,admin_key:r.adminKey,collection:e,doc_id:t});return w(i,"delete_document"),!!i.deleted}async function fe(r,e,t){if(!h(r))return null;let n=await S(r.grpcUrl),i=await k(n,"DeleteMany",{app_id:r.appId,admin_key:r.adminKey,collection:e,where:(t??[]).map(F)});return w(i,"delete_many"),Number(i.deleted??0)}var Ae=r=>r.replace(/\/$/,""),Ie=r=>{let e=String(r.httpBase??"").trim();return Ae(e||r.serverUrl)},A=(r,e)=>{let t=Ie(r),n=e.startsWith("/")?e:`/${e}`;return `${t}${n}`};var O=class{constructor(e,t,n){this.cfg=e;this.collection=t;this.id=n;}get baseUrl(){return A(this.cfg,`/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 ue(this.cfg,this.collection,this.id);if(e!==void 0)return e===null?null:v(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 v(this.cfg,this.collection,n.data)??null}async set(e){await pe(this.cfg,this.collection,this.id,e)===null&&await this.request("PUT",e);}async update(e){await ge(this.cfg,this.collection,this.id,e)===null&&await this.request("PATCH",e);}async delete(){await he(this.cfg,this.collection,this.id)===null&&await this.request("DELETE");}parent(){return new I(this.cfg,this.collection)}};var I=class r{constructor(e,t){this.cfg=e;this.name=t;this.sq={};this.opts={allowSensitiveAuthUserFields:true};}get baseUrl(){return A(this.cfg,`/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 W(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 ce(this.cfg,this.name,this.sq);if(e)return v(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 v(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 me(this.cfg,this.name,e);if(t!==null)return new O(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 O(this.cfg,this.name,i.id)}async update(e,t){let n=this.doc(e);return await n.update(t),n}ensureBulkOptions(e){let t=Number(e?.batchSize??250),n=Number(e?.concurrency??1);return {...e,batchSize:Number.isFinite(t)&&t>0?Math.floor(t):250,concurrency:Number.isFinite(n)&&n>0?Math.floor(n):1,continueOnError:e?.continueOnError===true}}toPercent(e,t){if(!(typeof t!="number"||t<=0))return Math.round(e/t*100)}emitBulkProgress(e,t,n){n&&n({operation:e,...t,percent:this.toPercent(t.processed,t.total)});}async*chunkIterable(e,t){let n=[];for await(let i of e)n.push(i),n.length>=t&&(yield n,n=[]);n.length>0&&(yield n);}assertBulkSignal(e){if(e?.aborted)throw new Error("Bulk write aborted")}async runChunkWorkers(e,t,n,i,s,o,a=false,d){let c=0,m=async()=>{for(;c<t.length;){this.assertBulkSignal(d);let f=c;c+=1;let R=t[f];try{let b=await i(R);s.succeeded+=1,s.processed+=1,this.emitBulkProgress(e,{processed:s.processed,succeeded:s.succeeded,failed:s.failed,total:s.total,lastDocId:b.docId},o);}catch(b){if(s.failed+=1,s.processed+=1,this.emitBulkProgress(e,{processed:s.processed,succeeded:s.succeeded,failed:s.failed,total:s.total,lastError:b},o),!a)throw b}}},u=Math.max(1,Math.min(n,t.length));await Promise.all(Array.from({length:u},()=>m()));}async runBulkWrite(e,t,n,i){let s=this.ensureBulkOptions(i);this.assertBulkSignal(s.signal);let o={processed:0,succeeded:0,failed:0,total:Array.isArray(t)?t.length:void 0};this.emitBulkProgress(e,{processed:0,succeeded:0,failed:0,total:o.total},s.onProgress);for await(let a of this.chunkIterable(t,s.batchSize))this.assertBulkSignal(s.signal),await this.runChunkWorkers(e,a,s.concurrency,n,o,s.onProgress,s.continueOnError,s.signal);return {operation:e,processed:o.processed,succeeded:o.succeeded,failed:o.failed,total:o.total}}async addMany(e,t){return this.runBulkWrite("addMany",e,async n=>({docId:(await this.add(n)).id}),t)}async updateMany(e,t){return this.runBulkWrite("updateMany",e,async n=>(await this.doc(n.id).update(n.data),{docId:n.id}),t)}async deleteMany(e,t){return e==null?this.deleteManyByQuery():this.runBulkWrite("deleteMany",e,async n=>(await this.doc(n).delete(),{docId:n}),t)}async deleteManyByQuery(){let e=await fe(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 O(this.cfg,this.name,e)}};var x=class{constructor(e){this.cfg=e;}collection(e){return new I(this.cfg,e)}};var _=class{constructor(e){this.cfg=e;}async createCustomToken(e,t={}){if(h(this.cfg)){let a=await de(this.cfg,String(e),t);if(!a)throw new Error("[flare-admin][grpc] create_custom_token returned empty token");return a}let n=A(this.cfg,"/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}
|
|
3
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] 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(h(this.cfg)){let d=await le(this.cfg,String(e),t);if(!d)throw new Error("[flare-admin][grpc] create_auth_ticket returned empty payload");return d}let n=A(this.cfg,"/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}
|
|
4
|
-
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 E=class{constructor(e){this.cfg=e;}get baseUrl(){return A(this.cfg,`/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 G=class{constructor(e){this.cfg=e;}base(e){return A(this.cfg,`/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 ee(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 Be(r){return r===void 0?"":typeof r=="string"?ee(new TextEncoder().encode(r)):Buffer&&Buffer.isBuffer(r)?r.toString("base64"):r instanceof Uint8Array?ee(r):r instanceof ArrayBuffer?ee(new Uint8Array(r)):""}function Pe(r){return Buffer?Buffer.from(String(r)).toString("base64"):btoa(String(r))}function je(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 Fe(r){return (String(r??"").split("/").pop()??"download").replace(/["\\\r\n]/g,"")||"download"}var D=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(f=>f.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}),m;typeof e.body=="string"?m=new TextEncoder().encode(e.body):m=e.body;let u=await fetch(c.url,{method:c.method??"PUT",headers:{...e.contentType?{"Content-Type":e.contentType}:{}},body:m});if(!u.ok){let f=await u.text().catch(()=>"");throw new Error(`[flare-admin] Signed-URL upload failed (HTTP ${u.status}): ${f}`)}return {ok:true,bucket:e.bucket,key:e.key,size:s??0,encrypted:!!(e.encrypt??true)}}let a=await Be(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??Fe(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?je(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?Pe(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 q=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 L=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 W(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 q(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}stream(e={}){let t=this._buildSq(),n=new Set,i=[],s=new Map,o=Math.max(0,Number(e.flushMs??24)),a=Math.max(1,Number(e.maxBatchSize??200)),d=e.insertAt??"end",c=typeof e.maxDocs=="number"&&e.maxDocs>0?Math.floor(e.maxDocs):void 0,m=String(e.idField??"id"),u=[],f=false,R=false,b=0,j,$=()=>{s.clear();for(let l=0;l<u.length;l+=1){let g=ne(u[l]);g&&s.set(g,l);}},ne=(l,g)=>{if(g)return g;if(l==null)return;if(typeof e.getId=="function"){let C=e.getId(l);if(typeof C=="string"&&C.length>0)return C}let y=l?.[m]??l?._id??l?.docId;if(typeof y=="string"&&y.length>0)return y},re=()=>{c==null||u.length<=c||(u=u.slice(0,c));},ie=()=>{typeof e.sort=="function"&&(u=u.slice().sort(e.sort));},se=(l,g)=>{b+=1;let y=u.slice(),C={reason:l,batchSize:g,version:b,ready:R};for(let M of Array.from(n))try{M(y,C);}catch{}},z=()=>{j!=null&&(clearTimeout(j),j=void 0);},be=l=>{if(l.operation==="delete"){let M=s.get(l.docId??"");if(M==null)return;u.splice(M,1),$();return}let g=l.data;if(g==null)return;let y=ne(g,l.docId);if(!y)return;let C=s.get(y);if(typeof C=="number"){u[C]=g;return}d==="start"?u.unshift(g):u.push(g),re(),$();},oe=()=>{if(f||i.length===0)return;z();let l=i.splice(0,i.length);for(let g of l)be(g);ie(),$(),se("change-batch",l.length);},ke=()=>{f||j!=null||(j=setTimeout(oe,o));},Q=this.conn.subscribe(this.name,void 0,t,l=>{if(!f){if(l.type==="snapshot"){u=Array.isArray(l.data)?[...l.data]:[],R=true,z(),i.length=0,ie(),re(),$(),se("snapshot",0);return}if(i.push({docId:l.docId,operation:l.operation,data:l.data??null}),i.length>=a){oe();return}ke();}}),K={subscribe(l,g=true){if(n.add(l),g){let y={reason:R?"change-batch":"snapshot",batchSize:0,version:b,ready:R};try{l(u.slice(),y);}catch{}}return ()=>{n.delete(l);}},getSnapshot(){return u.slice()},isReady(){return R},getVersion(){return b},close:()=>{f||(f=true,z(),i.length=0,n.clear(),Q());},onError(l){return Q.onError(l),K},onPermissionDenied(l){return Q.onPermissionDenied(l),K}};return K}asStore(e={}){let t=this.stream(e);return {subscribe:n=>t.subscribe(()=>{n();},false),getSnapshot:()=>t.getSnapshot(),getServerSnapshot:()=>[],stream:t,destroy:()=>{t.close();}}}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 U=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;this._state="disconnected";this._stateListeners=[];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._setState("connecting"),this._connect();}ready(){return this._readyPromise}get connectionState(){return this._state}onConnectionStateChange(e){return this._stateListeners.push(e),()=>{this._stateListeners=this._stateListeners.filter(t=>t!==e);}}disconnect(){this.shouldReconnect=false,this.ws?.close(1e3,"Admin disconnect"),this.ws=null,this.connected=false,this._setState("disconnected");}send(e,t){return new Promise((n,i)=>{let s=Z(),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===ye__default.default.OPEN?d():this.ready().then(d).catch(i);})}subscribe(e,t,n,i,s={}){let o=Z(),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=m=>{this.subscriptionErrorHandlers.get(o)?.add(m);let u=this.subscriptionLastErrors.get(o);if(u)try{m(u);}catch{}return c},c.onPermissionDenied=m=>{this.subscriptionPermissionHandlers.get(o)?.add(m);let u=this.subscriptionLastErrors.get(o);if(u?.permissionDenied)try{m(u);}catch{}return c},c.catch=m=>c.onError(m),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{}}}_setState(e){if(this._state!==e){this._state=e;for(let t of this._stateListeners.slice())try{t(e);}catch{}}}_connect(){this._readyPromise=new Promise(e=>{this._readyResolve=e;}),this.ws=new ye__default.default(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?(this._setState("reconnecting"),setTimeout(()=>{this.reconnectDelay=Math.min(this.reconnectDelay*2,3e4),this._connect();},this.reconnectDelay)):this._setState("disconnected");}),this.ws.on("error",()=>{this._setState("error");});}_handle(e){let t=e.type;if(t==="auth_ok"){this.connected||(this.connected=true,this.reconnectDelay=2e3,this._setState("connected"),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:v(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 N=class{constructor(e){this._ws=new U(e);}collection(e){return new L(this._ws,e)}ready(){return this._ws.ready()}get connectionState(){return this._ws.connectionState}onConnectionStateChange(e){return this._ws.onConnectionStateChange(e)}disconnect(){this._ws.disconnect();}};var mn="ServerTimeStamp",pn={$serverTimestamp:true};var te=class{constructor(e){this.cfg={defaultTtl:"24h",transport:"auto",...e,serverUrl:e.serverUrl.replace(/\/$/,""),httpBase:e.httpBase?.replace(/\/$/,"")??"",grpcUrl:e.grpcUrl??"",dataMapper:e.dataMapper??{}};}auth(){return this._auth??(this._auth=new _(this.cfg))}db(){return this._db??(this._db=new x(this.cfg))}live(){return this._conn??(this._conn=new N(this.cfg))}notifications(){return this._notifications??(this._notifications=new E(this.cfg))}storageService(){return this._storage??(this._storage=new G(this.cfg))}storage(){return this._storageS3||(this._storageS3=new D(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)}onConnectionStateChange(e){return this.live().onConnectionStateChange(e)}disconnect(){this._conn?.disconnect(),this._conn=void 0;}},T=new Map;function Sn(r,e="[DEFAULT]"){if(T.has(e))return T.get(e);let t=new te(r);return T.set(e,t),t}function J(r="[DEFAULT]"){let e=T.get(r);if(!e)throw new Error(`[flare-admin] No app named "${r}" found. Call connectApp() before getApp().`);return e}function wn(r="[DEFAULT]"){let e=T.get(r);return e?(e.disconnect(),T.delete(r),true):false}function Cn(){for(let r of T.values())r.disconnect();T.clear();}function vn(r="[DEFAULT]"){return J(r).auth()}function Tn(r="[DEFAULT]"){return J(r).db()}function Rn(r="[DEFAULT]"){return J(r).live()}function On(r="[DEFAULT]"){return J(r).notifications()}function In(r="[DEFAULT]"){return J(r).storage()}exports.AdminCollectionReference=I;exports.AdminDocumentReference=O;exports.AdminLiveCollectionReference=L;exports.AdminLiveDocumentReference=q;exports.AdminStorageSignedAction=V;exports.FlareAdminApp=te;exports.FlareAdminAuthService=_;exports.FlareAdminConnection=N;exports.FlareAdminDbService=x;exports.FlareAdminNotificationsService=E;exports.FlareAdminStorageS3=D;exports.FlareAdminWsConnection=U;exports.ServerTimeStamp=mn;exports.ServerTimeStampField=pn;exports.auth=vn;exports.connectApp=Sn;exports.db=Tn;exports.disconnectAllApps=Cn;exports.disconnectApp=wn;exports.getApp=J;exports.live=Rn;exports.notifications=On;exports.storage=In;
|
|
4
|
+
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 E=class{constructor(e){this.cfg=e;}get baseUrl(){return A(this.cfg,`/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 G=class{constructor(e){this.cfg=e;}base(e){return A(this.cfg,`/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 ee(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 Pe(r){return r===void 0?"":typeof r=="string"?ee(new TextEncoder().encode(r)):Buffer&&Buffer.isBuffer(r)?r.toString("base64"):r instanceof Uint8Array?ee(r):r instanceof ArrayBuffer?ee(new Uint8Array(r)):""}function Be(r){return Buffer?Buffer.from(String(r)).toString("base64"):btoa(String(r))}function je(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 Fe(r){return (String(r??"").split("/").pop()??"download").replace(/["\\\r\n]/g,"")||"download"}var D=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(f=>f.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}),m;typeof e.body=="string"?m=new TextEncoder().encode(e.body):m=e.body;let u=await fetch(c.url,{method:c.method??"PUT",headers:{...e.contentType?{"Content-Type":e.contentType}:{}},body:m});if(!u.ok){let f=await u.text().catch(()=>"");throw new Error(`[flare-admin] Signed-URL upload failed (HTTP ${u.status}): ${f}`)}return {ok:true,bucket:e.bucket,key:e.key,size:s??0,encrypted:!!(e.encrypt??true)}}let a=await Pe(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??Fe(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?je(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?Be(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 q=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 L=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 W(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 q(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}stream(e={}){let t=this._buildSq(),n=new Set,i=[],s=new Map,o=Math.max(0,Number(e.flushMs??24)),a=Math.max(1,Number(e.maxBatchSize??200)),d=e.insertAt??"end",c=typeof e.maxDocs=="number"&&e.maxDocs>0?Math.floor(e.maxDocs):void 0,m=String(e.idField??"id"),u=[],f=false,R=false,b=0,j,$=()=>{s.clear();for(let l=0;l<u.length;l+=1){let g=ne(u[l]);g&&s.set(g,l);}},ne=(l,g)=>{if(g)return g;if(l==null)return;if(typeof e.getId=="function"){let C=e.getId(l);if(typeof C=="string"&&C.length>0)return C}let y=l?.[m]??l?._id??l?.docId;if(typeof y=="string"&&y.length>0)return y},re=()=>{c==null||u.length<=c||(u=u.slice(0,c));},ie=()=>{typeof e.sort=="function"&&(u=u.slice().sort(e.sort));},se=(l,g)=>{b+=1;let y=u.slice(),C={reason:l,batchSize:g,version:b,ready:R};for(let M of Array.from(n))try{M(y,C);}catch{}},z=()=>{j!=null&&(clearTimeout(j),j=void 0);},be=l=>{if(l.operation==="delete"){let M=s.get(l.docId??"");if(M==null)return;u.splice(M,1),$();return}let g=l.data;if(g==null)return;let y=ne(g,l.docId);if(!y)return;let C=s.get(y);if(typeof C=="number"){u[C]=g;return}d==="start"?u.unshift(g):u.push(g),re(),$();},oe=()=>{if(f||i.length===0)return;z();let l=i.splice(0,i.length);for(let g of l)be(g);ie(),$(),se("change-batch",l.length);},Se=()=>{f||j!=null||(j=setTimeout(oe,o));},Q=this.conn.subscribe(this.name,void 0,t,l=>{if(!f){if(l.type==="snapshot"){u=Array.isArray(l.data)?[...l.data]:[],R=true,z(),i.length=0,ie(),re(),$(),se("snapshot",0);return}if(i.push({docId:l.docId,operation:l.operation,data:l.data??null}),i.length>=a){oe();return}Se();}}),K={subscribe(l,g=true){if(n.add(l),g){let y={reason:R?"change-batch":"snapshot",batchSize:0,version:b,ready:R};try{l(u.slice(),y);}catch{}}return ()=>{n.delete(l);}},getSnapshot(){return u.slice()},isReady(){return R},getVersion(){return b},close:()=>{f||(f=true,z(),i.length=0,n.clear(),Q());},onError(l){return Q.onError(l),K},onPermissionDenied(l){return Q.onPermissionDenied(l),K}};return K}asStore(e={}){let t=this.stream(e);return {subscribe:n=>t.subscribe(()=>{n();},false),getSnapshot:()=>t.getSnapshot(),getServerSnapshot:()=>[],stream:t,destroy:()=>{t.close();}}}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 U=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;this._state="disconnected";this._stateListeners=[];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._setState("connecting"),this._connect();}ready(){return this._readyPromise}get connectionState(){return this._state}onConnectionStateChange(e){return this._stateListeners.push(e),()=>{this._stateListeners=this._stateListeners.filter(t=>t!==e);}}disconnect(){this.shouldReconnect=false,this.ws?.close(1e3,"Admin disconnect"),this.ws=null,this.connected=false,this._setState("disconnected");}send(e,t){return new Promise((n,i)=>{let s=Z(),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===ye__default.default.OPEN?d():this.ready().then(d).catch(i);})}subscribe(e,t,n,i,s={}){let o=Z(),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=m=>{this.subscriptionErrorHandlers.get(o)?.add(m);let u=this.subscriptionLastErrors.get(o);if(u)try{m(u);}catch{}return c},c.onPermissionDenied=m=>{this.subscriptionPermissionHandlers.get(o)?.add(m);let u=this.subscriptionLastErrors.get(o);if(u?.permissionDenied)try{m(u);}catch{}return c},c.catch=m=>c.onError(m),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{}}}_setState(e){if(this._state!==e){this._state=e;for(let t of this._stateListeners.slice())try{t(e);}catch{}}}_connect(){this._readyPromise=new Promise(e=>{this._readyResolve=e;}),this.ws=new ye__default.default(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?(this._setState("reconnecting"),setTimeout(()=>{this.reconnectDelay=Math.min(this.reconnectDelay*2,3e4),this._connect();},this.reconnectDelay)):this._setState("disconnected");}),this.ws.on("error",()=>{this._setState("error");});}_handle(e){let t=e.type;if(t==="auth_ok"){this.connected||(this.connected=true,this.reconnectDelay=2e3,this._setState("connected"),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:v(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 N=class{constructor(e){this._ws=new U(e);}collection(e){return new L(this._ws,e)}ready(){return this._ws.ready()}get connectionState(){return this._ws.connectionState}onConnectionStateChange(e){return this._ws.onConnectionStateChange(e)}disconnect(){this._ws.disconnect();}};var mn="ServerTimeStamp",pn={$serverTimestamp:true};var te=class{constructor(e){this.cfg={defaultTtl:"24h",transport:"auto",...e,serverUrl:e.serverUrl.replace(/\/$/,""),httpBase:e.httpBase?.replace(/\/$/,"")??"",grpcUrl:e.grpcUrl??"",dataMapper:e.dataMapper??{}};}auth(){return this._auth??(this._auth=new _(this.cfg))}db(){return this._db??(this._db=new x(this.cfg))}live(){return this._conn??(this._conn=new N(this.cfg))}notifications(){return this._notifications??(this._notifications=new E(this.cfg))}storageService(){return this._storage??(this._storage=new G(this.cfg))}storage(){return this._storageS3||(this._storageS3=new D(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)}onConnectionStateChange(e){return this.live().onConnectionStateChange(e)}disconnect(){this._conn?.disconnect(),this._conn=void 0;}},T=new Map;function kn(r,e="[DEFAULT]"){if(T.has(e))return T.get(e);let t=new te(r);return T.set(e,t),t}function J(r="[DEFAULT]"){let e=T.get(r);if(!e)throw new Error(`[flare-admin] No app named "${r}" found. Call connectApp() before getApp().`);return e}function wn(r="[DEFAULT]"){let e=T.get(r);return e?(e.disconnect(),T.delete(r),true):false}function Cn(){for(let r of T.values())r.disconnect();T.clear();}function vn(r="[DEFAULT]"){return J(r).auth()}function Tn(r="[DEFAULT]"){return J(r).db()}function Rn(r="[DEFAULT]"){return J(r).live()}function On(r="[DEFAULT]"){return J(r).notifications()}function In(r="[DEFAULT]"){return J(r).storage()}exports.AdminCollectionReference=I;exports.AdminDocumentReference=O;exports.AdminLiveCollectionReference=L;exports.AdminLiveDocumentReference=q;exports.AdminStorageSignedAction=V;exports.FlareAdminApp=te;exports.FlareAdminAuthService=_;exports.FlareAdminConnection=N;exports.FlareAdminDbService=x;exports.FlareAdminNotificationsService=E;exports.FlareAdminStorageS3=D;exports.FlareAdminWsConnection=U;exports.ServerTimeStamp=mn;exports.ServerTimeStampField=pn;exports.auth=vn;exports.connectApp=kn;exports.db=Tn;exports.disconnectAllApps=Cn;exports.disconnectApp=wn;exports.getApp=J;exports.live=Rn;exports.notifications=On;exports.storage=In;
|
package/dist/index.d.cts
CHANGED
|
@@ -620,6 +620,7 @@ interface AdminCollectionShape<T> {
|
|
|
620
620
|
first(): Promise<T | null>;
|
|
621
621
|
last(): Promise<T | null>;
|
|
622
622
|
add(data: Partial<T>): Promise<AdminDocumentShape<T>>;
|
|
623
|
+
update(id: string, data: Partial<T>): Promise<AdminDocumentShape<T>>;
|
|
623
624
|
addMany(items: Iterable<Partial<T>> | AsyncIterable<Partial<T>>, options?: AdminBulkWriteOptions): Promise<AdminBulkWriteResult>;
|
|
624
625
|
updateMany(items: Iterable<AdminUpdateManyItem<T>> | AsyncIterable<AdminUpdateManyItem<T>>, options?: AdminBulkWriteOptions): Promise<AdminBulkWriteResult>;
|
|
625
626
|
deleteMany(docIds: Iterable<string> | AsyncIterable<string>, options?: AdminBulkWriteOptions): Promise<AdminBulkWriteResult>;
|
|
@@ -806,6 +807,10 @@ declare class AdminCollectionReference<T = Record<string, unknown>> {
|
|
|
806
807
|
* Create a single document and return its reference.
|
|
807
808
|
*/
|
|
808
809
|
add(data: Partial<T>): Promise<AdminDocumentReference<T>>;
|
|
810
|
+
/**
|
|
811
|
+
* Update a single document by id and return its reference.
|
|
812
|
+
*/
|
|
813
|
+
update(id: string, data: Partial<T>): Promise<AdminDocumentReference<T>>;
|
|
809
814
|
private ensureBulkOptions;
|
|
810
815
|
private toPercent;
|
|
811
816
|
private emitBulkProgress;
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import ve from'fs';import P from'path';import {fileURLToPath}from'url';import be from'ws';var Z=(i=>(i.Upload="upload",i.Download="download",i.Delete="delete",i.Edit="edit",i))(Z||{});function H(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:we(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 we(r){return isNaN(Number(r))?r==="true"?true:r==="false"?false:r==="null"?null:r:Number(r)}function X(){return Math.random().toString(36).slice(2,12)+Date.now().toString(36)}function Ce(r,e){let t=r.dataMapper;if(!t||typeof t!="object")return null;let n=t[e];return typeof n=="function"?n:null}function Y(r,e,t){let n=Ce(r,e);if(!n||t==null||typeof t!="object")return t;try{return n(t)}catch{return t}}function ee(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=>ee(r,c,o)):a&&typeof a=="object"&&(d=ee(r,a,o)),d=Array.isArray(d)?d.map(c=>Y(r,s,c)):Y(r,s,d),d!==a&&(n===e&&(n={...n}),n[s]=d);}return n}function T(r,e,t,n){let i=Array.isArray(n?.joins)?n.joins:[],s=o=>{let a=ee(r,o,i);return Y(r,e,a)};return Array.isArray(t)?t.map(o=>s(o)):s(t)}var Re=()=>typeof process<"u"&&!!process.versions?.node,f=r=>{if(r.transport==="http")return false;let e=!!(r.grpcUrl&&r.grpcUrl.trim().length>0),t=Re();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},j=r=>{try{return JSON.stringify(r??{})}catch{return "{}"}},x=r=>r?.field&&r?.op?{queryFilter:{field:String(r.field),op:String(r.op),valueJson:j(r.value)}}:Array.isArray(r?.or)?{orFilter:{or:r.or.map(e=>x(e))}}:Array.isArray(r?.and)?{andFilter:{and:r.and.map(e=>x(e))}}:{queryFilter:{field:"",op:"==",valueJson:"null"}},G=r=>{if(!(!r||!Array.isArray(r.values)))return {valuesJson:r.values.map(e=>j(e))}},ce=r=>({from:r.from,localField:r.localField,foreignField:r.foreignField,as:r.as,single:!!r.single,where:Array.isArray(r.where)?r.where.map(x):[],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(ce):[]}),Oe=r=>({where:Array.isArray(r.where)?r.where.map(x):[],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:G(r.startAt),startAfter:G(r.startAfter),endAt:G(r.endAt),endBefore:G(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(ce):[],select:Array.isArray(r.select)?r.select:[],distinctField:r.distinctField??""});async function S(r){let e=await import('@grpc/grpc-js'),t=await import('@grpc/proto-loader'),n=P.dirname(fileURLToPath(import.meta.url)),i=[P.resolve(n,"../../proto"),P.resolve(n,"../proto"),P.resolve(process.cwd(),"proto")],s=i.find(m=>ve.existsSync(P.join(m,"flare.proto")))??i[0],o=P.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 w(r,e,t){return new Promise((n,i)=>{r[e](t,(s,o)=>{if(s)return i(s);n(o??{});});})}function C(r,e){if(r.error)throw new Error(`[flare-admin][grpc] ${e} failed: ${r.errorDescription||r.error}`)}async function de(r,e,t){if(!f(r))return null;let n=await S(r.grpcUrl),i=await w(n,"AdminQuery",{app_id:r.appId,admin_key:r.adminKey,collection:e,query:Oe(t)});C(i,"admin_query");try{let s=JSON.parse(i.dataJson||"[]");return Array.isArray(s)?s:[]}catch{return []}}async function le(r,e,t){if(!f(r))return null;let n=await S(r.grpcUrl),i=await w(n,"CreateCustomToken",{app_id:r.appId,admin_key:r.adminKey,uid:e,role:t.role??"user",claims_json:j(t.claims??{}),ttl:t.ttl??r.defaultTtl});if(C(i,"create_custom_token"),!i.token)throw new Error("[flare-admin][grpc] create_custom_token returned empty token");return String(i.token)}async function ue(r,e,t){if(!f(r))return null;let n=await S(r.grpcUrl),i=await w(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 C(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 me(r,e,t){if(!f(r))return;let n=await S(r.grpcUrl),i=await w(n,"GetDocument",{app_id:r.appId,admin_key:r.adminKey,collection:e,doc_id:t});if(C(i,"get_document"),!i.found)return null;try{return JSON.parse(i.dataJson||"{}")}catch{return {}}}async function pe(r,e,t){if(!f(r))return null;let n=await S(r.grpcUrl),i=await w(n,"CreateDocument",{app_id:r.appId,admin_key:r.adminKey,collection:e,data_json:j(t)});return C(i,"create_document"),String(i.id??"")}async function ge(r,e,t,n){if(!f(r))return null;let i=await S(r.grpcUrl),s=await w(i,"ReplaceDocument",{app_id:r.appId,admin_key:r.adminKey,collection:e,doc_id:t,data_json:j(n)});return C(s,"replace_document"),true}async function he(r,e,t,n){if(!f(r))return null;let i=await S(r.grpcUrl),s=await w(i,"UpdateDocument",{app_id:r.appId,admin_key:r.adminKey,collection:e,doc_id:t,data_json:j(n)});return C(s,"update_document"),true}async function fe(r,e,t){if(!f(r))return null;let n=await S(r.grpcUrl),i=await w(n,"DeleteDocument",{app_id:r.appId,admin_key:r.adminKey,collection:e,doc_id:t});return C(i,"delete_document"),!!i.deleted}async function Ae(r,e,t){if(!f(r))return null;let n=await S(r.grpcUrl),i=await w(n,"DeleteMany",{app_id:r.appId,admin_key:r.adminKey,collection:e,where:(t??[]).map(x)});return C(i,"delete_many"),Number(i.deleted??0)}var ye=r=>r.replace(/\/$/,""),Ie=r=>{let e=String(r.httpBase??"").trim();return ye(e||r.serverUrl)},y=(r,e)=>{let t=Ie(r),n=e.startsWith("/")?e:`/${e}`;return `${t}${n}`};var I=class{constructor(e,t,n){this.cfg=e;this.collection=t;this.id=n;}get baseUrl(){return y(this.cfg,`/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 me(this.cfg,this.collection,this.id);if(e!==void 0)return e===null?null:T(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 T(this.cfg,this.collection,n.data)??null}async set(e){await ge(this.cfg,this.collection,this.id,e)===null&&await this.request("PUT",e);}async update(e){await he(this.cfg,this.collection,this.id,e)===null&&await this.request("PATCH",e);}async delete(){await fe(this.cfg,this.collection,this.id)===null&&await this.request("DELETE");}parent(){return new B(this.cfg,this.collection)}};var B=class r{constructor(e,t){this.cfg=e;this.name=t;this.sq={};this.opts={allowSensitiveAuthUserFields:true};}get baseUrl(){return y(this.cfg,`/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 H(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 de(this.cfg,this.name,this.sq);if(e)return T(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 T(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 pe(this.cfg,this.name,e);if(t!==null)return new I(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 I(this.cfg,this.name,i.id)}ensureBulkOptions(e){let t=Number(e?.batchSize??250),n=Number(e?.concurrency??1);return {...e,batchSize:Number.isFinite(t)&&t>0?Math.floor(t):250,concurrency:Number.isFinite(n)&&n>0?Math.floor(n):1,continueOnError:e?.continueOnError===true}}toPercent(e,t){if(!(typeof t!="number"||t<=0))return Math.round(e/t*100)}emitBulkProgress(e,t,n){n&&n({operation:e,...t,percent:this.toPercent(t.processed,t.total)});}async*chunkIterable(e,t){let n=[];for await(let i of e)n.push(i),n.length>=t&&(yield n,n=[]);n.length>0&&(yield n);}assertBulkSignal(e){if(e?.aborted)throw new Error("Bulk write aborted")}async runChunkWorkers(e,t,n,i,s,o,a=false,d){let c=0,m=async()=>{for(;c<t.length;){this.assertBulkSignal(d);let A=c;c+=1;let O=t[A];try{let k=await i(O);s.succeeded+=1,s.processed+=1,this.emitBulkProgress(e,{processed:s.processed,succeeded:s.succeeded,failed:s.failed,total:s.total,lastDocId:k.docId},o);}catch(k){if(s.failed+=1,s.processed+=1,this.emitBulkProgress(e,{processed:s.processed,succeeded:s.succeeded,failed:s.failed,total:s.total,lastError:k},o),!a)throw k}}},u=Math.max(1,Math.min(n,t.length));await Promise.all(Array.from({length:u},()=>m()));}async runBulkWrite(e,t,n,i){let s=this.ensureBulkOptions(i);this.assertBulkSignal(s.signal);let o={processed:0,succeeded:0,failed:0,total:Array.isArray(t)?t.length:void 0};this.emitBulkProgress(e,{processed:0,succeeded:0,failed:0,total:o.total},s.onProgress);for await(let a of this.chunkIterable(t,s.batchSize))this.assertBulkSignal(s.signal),await this.runChunkWorkers(e,a,s.concurrency,n,o,s.onProgress,s.continueOnError,s.signal);return {operation:e,processed:o.processed,succeeded:o.succeeded,failed:o.failed,total:o.total}}async addMany(e,t){return this.runBulkWrite("addMany",e,async n=>({docId:(await this.add(n)).id}),t)}async updateMany(e,t){return this.runBulkWrite("updateMany",e,async n=>(await this.doc(n.id).update(n.data),{docId:n.id}),t)}async deleteMany(e,t){return e==null?this.deleteManyByQuery():this.runBulkWrite("deleteMany",e,async n=>(await this.doc(n).delete(),{docId:n}),t)}async deleteManyByQuery(){let e=await Ae(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 I(this.cfg,this.name,e)}};var _=class{constructor(e){this.cfg=e;}collection(e){return new B(this.cfg,e)}};var E=class{constructor(e){this.cfg=e;}async createCustomToken(e,t={}){if(f(this.cfg)){let a=await le(this.cfg,String(e),t);if(!a)throw new Error("[flare-admin][grpc] create_custom_token returned empty token");return a}let n=y(this.cfg,"/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}
|
|
1
|
+
import ve from'fs';import B from'path';import {fileURLToPath}from'url';import be from'ws';var Z=(i=>(i.Upload="upload",i.Download="download",i.Delete="delete",i.Edit="edit",i))(Z||{});function H(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:we(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 we(r){return isNaN(Number(r))?r==="true"?true:r==="false"?false:r==="null"?null:r:Number(r)}function X(){return Math.random().toString(36).slice(2,12)+Date.now().toString(36)}function Ce(r,e){let t=r.dataMapper;if(!t||typeof t!="object")return null;let n=t[e];return typeof n=="function"?n:null}function Y(r,e,t){let n=Ce(r,e);if(!n||t==null||typeof t!="object")return t;try{return n(t)}catch{return t}}function ee(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=>ee(r,c,o)):a&&typeof a=="object"&&(d=ee(r,a,o)),d=Array.isArray(d)?d.map(c=>Y(r,s,c)):Y(r,s,d),d!==a&&(n===e&&(n={...n}),n[s]=d);}return n}function T(r,e,t,n){let i=Array.isArray(n?.joins)?n.joins:[],s=o=>{let a=ee(r,o,i);return Y(r,e,a)};return Array.isArray(t)?t.map(o=>s(o)):s(t)}var Re=()=>typeof process<"u"&&!!process.versions?.node,f=r=>{if(r.transport==="http")return false;let e=!!(r.grpcUrl&&r.grpcUrl.trim().length>0),t=Re();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},j=r=>{try{return JSON.stringify(r??{})}catch{return "{}"}},x=r=>r?.field&&r?.op?{queryFilter:{field:String(r.field),op:String(r.op),valueJson:j(r.value)}}:Array.isArray(r?.or)?{orFilter:{or:r.or.map(e=>x(e))}}:Array.isArray(r?.and)?{andFilter:{and:r.and.map(e=>x(e))}}:{queryFilter:{field:"",op:"==",valueJson:"null"}},G=r=>{if(!(!r||!Array.isArray(r.values)))return {valuesJson:r.values.map(e=>j(e))}},ce=r=>({from:r.from,localField:r.localField,foreignField:r.foreignField,as:r.as,single:!!r.single,where:Array.isArray(r.where)?r.where.map(x):[],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(ce):[]}),Oe=r=>({where:Array.isArray(r.where)?r.where.map(x):[],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:G(r.startAt),startAfter:G(r.startAfter),endAt:G(r.endAt),endBefore:G(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(ce):[],select:Array.isArray(r.select)?r.select:[],distinctField:r.distinctField??""});async function S(r){let e=await import('@grpc/grpc-js'),t=await import('@grpc/proto-loader'),n=B.dirname(fileURLToPath(import.meta.url)),i=[B.resolve(n,"../../proto"),B.resolve(n,"../proto"),B.resolve(process.cwd(),"proto")],s=i.find(m=>ve.existsSync(B.join(m,"flare.proto")))??i[0],o=B.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 w(r,e,t){return new Promise((n,i)=>{r[e](t,(s,o)=>{if(s)return i(s);n(o??{});});})}function C(r,e){if(r.error)throw new Error(`[flare-admin][grpc] ${e} failed: ${r.errorDescription||r.error}`)}async function de(r,e,t){if(!f(r))return null;let n=await S(r.grpcUrl),i=await w(n,"AdminQuery",{app_id:r.appId,admin_key:r.adminKey,collection:e,query:Oe(t)});C(i,"admin_query");try{let s=JSON.parse(i.dataJson||"[]");return Array.isArray(s)?s:[]}catch{return []}}async function le(r,e,t){if(!f(r))return null;let n=await S(r.grpcUrl),i=await w(n,"CreateCustomToken",{app_id:r.appId,admin_key:r.adminKey,uid:e,role:t.role??"user",claims_json:j(t.claims??{}),ttl:t.ttl??r.defaultTtl});if(C(i,"create_custom_token"),!i.token)throw new Error("[flare-admin][grpc] create_custom_token returned empty token");return String(i.token)}async function ue(r,e,t){if(!f(r))return null;let n=await S(r.grpcUrl),i=await w(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 C(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 me(r,e,t){if(!f(r))return;let n=await S(r.grpcUrl),i=await w(n,"GetDocument",{app_id:r.appId,admin_key:r.adminKey,collection:e,doc_id:t});if(C(i,"get_document"),!i.found)return null;try{return JSON.parse(i.dataJson||"{}")}catch{return {}}}async function pe(r,e,t){if(!f(r))return null;let n=await S(r.grpcUrl),i=await w(n,"CreateDocument",{app_id:r.appId,admin_key:r.adminKey,collection:e,data_json:j(t)});return C(i,"create_document"),String(i.id??"")}async function ge(r,e,t,n){if(!f(r))return null;let i=await S(r.grpcUrl),s=await w(i,"ReplaceDocument",{app_id:r.appId,admin_key:r.adminKey,collection:e,doc_id:t,data_json:j(n)});return C(s,"replace_document"),true}async function he(r,e,t,n){if(!f(r))return null;let i=await S(r.grpcUrl),s=await w(i,"UpdateDocument",{app_id:r.appId,admin_key:r.adminKey,collection:e,doc_id:t,data_json:j(n)});return C(s,"update_document"),true}async function fe(r,e,t){if(!f(r))return null;let n=await S(r.grpcUrl),i=await w(n,"DeleteDocument",{app_id:r.appId,admin_key:r.adminKey,collection:e,doc_id:t});return C(i,"delete_document"),!!i.deleted}async function Ae(r,e,t){if(!f(r))return null;let n=await S(r.grpcUrl),i=await w(n,"DeleteMany",{app_id:r.appId,admin_key:r.adminKey,collection:e,where:(t??[]).map(x)});return C(i,"delete_many"),Number(i.deleted??0)}var ye=r=>r.replace(/\/$/,""),Ie=r=>{let e=String(r.httpBase??"").trim();return ye(e||r.serverUrl)},y=(r,e)=>{let t=Ie(r),n=e.startsWith("/")?e:`/${e}`;return `${t}${n}`};var I=class{constructor(e,t,n){this.cfg=e;this.collection=t;this.id=n;}get baseUrl(){return y(this.cfg,`/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 me(this.cfg,this.collection,this.id);if(e!==void 0)return e===null?null:T(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 T(this.cfg,this.collection,n.data)??null}async set(e){await ge(this.cfg,this.collection,this.id,e)===null&&await this.request("PUT",e);}async update(e){await he(this.cfg,this.collection,this.id,e)===null&&await this.request("PATCH",e);}async delete(){await fe(this.cfg,this.collection,this.id)===null&&await this.request("DELETE");}parent(){return new P(this.cfg,this.collection)}};var P=class r{constructor(e,t){this.cfg=e;this.name=t;this.sq={};this.opts={allowSensitiveAuthUserFields:true};}get baseUrl(){return y(this.cfg,`/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 H(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 de(this.cfg,this.name,this.sq);if(e)return T(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 T(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 pe(this.cfg,this.name,e);if(t!==null)return new I(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 I(this.cfg,this.name,i.id)}async update(e,t){let n=this.doc(e);return await n.update(t),n}ensureBulkOptions(e){let t=Number(e?.batchSize??250),n=Number(e?.concurrency??1);return {...e,batchSize:Number.isFinite(t)&&t>0?Math.floor(t):250,concurrency:Number.isFinite(n)&&n>0?Math.floor(n):1,continueOnError:e?.continueOnError===true}}toPercent(e,t){if(!(typeof t!="number"||t<=0))return Math.round(e/t*100)}emitBulkProgress(e,t,n){n&&n({operation:e,...t,percent:this.toPercent(t.processed,t.total)});}async*chunkIterable(e,t){let n=[];for await(let i of e)n.push(i),n.length>=t&&(yield n,n=[]);n.length>0&&(yield n);}assertBulkSignal(e){if(e?.aborted)throw new Error("Bulk write aborted")}async runChunkWorkers(e,t,n,i,s,o,a=false,d){let c=0,m=async()=>{for(;c<t.length;){this.assertBulkSignal(d);let A=c;c+=1;let O=t[A];try{let k=await i(O);s.succeeded+=1,s.processed+=1,this.emitBulkProgress(e,{processed:s.processed,succeeded:s.succeeded,failed:s.failed,total:s.total,lastDocId:k.docId},o);}catch(k){if(s.failed+=1,s.processed+=1,this.emitBulkProgress(e,{processed:s.processed,succeeded:s.succeeded,failed:s.failed,total:s.total,lastError:k},o),!a)throw k}}},u=Math.max(1,Math.min(n,t.length));await Promise.all(Array.from({length:u},()=>m()));}async runBulkWrite(e,t,n,i){let s=this.ensureBulkOptions(i);this.assertBulkSignal(s.signal);let o={processed:0,succeeded:0,failed:0,total:Array.isArray(t)?t.length:void 0};this.emitBulkProgress(e,{processed:0,succeeded:0,failed:0,total:o.total},s.onProgress);for await(let a of this.chunkIterable(t,s.batchSize))this.assertBulkSignal(s.signal),await this.runChunkWorkers(e,a,s.concurrency,n,o,s.onProgress,s.continueOnError,s.signal);return {operation:e,processed:o.processed,succeeded:o.succeeded,failed:o.failed,total:o.total}}async addMany(e,t){return this.runBulkWrite("addMany",e,async n=>({docId:(await this.add(n)).id}),t)}async updateMany(e,t){return this.runBulkWrite("updateMany",e,async n=>(await this.doc(n.id).update(n.data),{docId:n.id}),t)}async deleteMany(e,t){return e==null?this.deleteManyByQuery():this.runBulkWrite("deleteMany",e,async n=>(await this.doc(n).delete(),{docId:n}),t)}async deleteManyByQuery(){let e=await Ae(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 I(this.cfg,this.name,e)}};var _=class{constructor(e){this.cfg=e;}collection(e){return new P(this.cfg,e)}};var E=class{constructor(e){this.cfg=e;}async createCustomToken(e,t={}){if(f(this.cfg)){let a=await le(this.cfg,String(e),t);if(!a)throw new Error("[flare-admin][grpc] create_custom_token returned empty token");return a}let n=y(this.cfg,"/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
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(f(this.cfg)){let d=await ue(this.cfg,String(e),t);if(!d)throw new Error("[flare-admin][grpc] create_auth_ticket returned empty payload");return d}let n=y(this.cfg,"/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 D=class{constructor(e){this.cfg=e;}get baseUrl(){return y(this.cfg,`/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 z=class{constructor(e){this.cfg=e;}base(e){return y(this.cfg,`/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 te(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 Be(r){return r===void 0?"":typeof r=="string"?te(new TextEncoder().encode(r)):Buffer&&Buffer.isBuffer(r)?r.toString("base64"):r instanceof Uint8Array?te(r):r instanceof ArrayBuffer?te(new Uint8Array(r)):""}function Pe(r){return Buffer?Buffer.from(String(r)).toString("base64"):btoa(String(r))}function je(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 Fe(r){return (String(r??"").split("/").pop()??"download").replace(/["\\\r\n]/g,"")||"download"}var q=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(A=>A.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}),m;typeof e.body=="string"?m=new TextEncoder().encode(e.body):m=e.body;let u=await fetch(c.url,{method:c.method??"PUT",headers:{...e.contentType?{"Content-Type":e.contentType}:{}},body:m});if(!u.ok){let A=await u.text().catch(()=>"");throw new Error(`[flare-admin] Signed-URL upload failed (HTTP ${u.status}): ${A}`)}return {ok:true,bucket:e.bucket,key:e.key,size:s??0,encrypted:!!(e.encrypt??true)}}let a=await Be(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??Fe(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?je(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?Pe(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 L=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 U=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 H(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 L(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}stream(e={}){let t=this._buildSq(),n=new Set,i=[],s=new Map,o=Math.max(0,Number(e.flushMs??24)),a=Math.max(1,Number(e.maxBatchSize??200)),d=e.insertAt??"end",c=typeof e.maxDocs=="number"&&e.maxDocs>0?Math.floor(e.maxDocs):void 0,m=String(e.idField??"id"),u=[],A=false,O=false,k=0,F,M=()=>{s.clear();for(let l=0;l<u.length;l+=1){let p=re(u[l]);p&&s.set(p,l);}},re=(l,p)=>{if(p)return p;if(l==null)return;if(typeof e.getId=="function"){let v=e.getId(l);if(typeof v=="string"&&v.length>0)return v}let b=l?.[m]??l?._id??l?.docId;if(typeof b=="string"&&b.length>0)return b},ie=()=>{c==null||u.length<=c||(u=u.slice(0,c));},se=()=>{typeof e.sort=="function"&&(u=u.slice().sort(e.sort));},oe=(l,p)=>{k+=1;let b=u.slice(),v={reason:l,batchSize:p,version:k,ready:O};for(let W of Array.from(n))try{W(b,v);}catch{}},Q=()=>{F!=null&&(clearTimeout(F),F=void 0);},ke=l=>{if(l.operation==="delete"){let W=s.get(l.docId??"");if(W==null)return;u.splice(W,1),M();return}let p=l.data;if(p==null)return;let b=re(p,l.docId);if(!b)return;let v=s.get(b);if(typeof v=="number"){u[v]=p;return}d==="start"?u.unshift(p):u.push(p),ie(),M();},ae=()=>{if(A||i.length===0)return;Q();let l=i.splice(0,i.length);for(let p of l)ke(p);se(),M(),oe("change-batch",l.length);},Se=()=>{A||F!=null||(F=setTimeout(ae,o));},K=this.conn.subscribe(this.name,void 0,t,l=>{if(!A){if(l.type==="snapshot"){u=Array.isArray(l.data)?[...l.data]:[],O=true,Q(),i.length=0,se(),ie(),M(),oe("snapshot",0);return}if(i.push({docId:l.docId,operation:l.operation,data:l.data??null}),i.length>=a){ae();return}Se();}}),V={subscribe(l,p=true){if(n.add(l),p){let b={reason:O?"change-batch":"snapshot",batchSize:0,version:k,ready:O};try{l(u.slice(),b);}catch{}}return ()=>{n.delete(l);}},getSnapshot(){return u.slice()},isReady(){return O},getVersion(){return k},close:()=>{A||(A=true,Q(),i.length=0,n.clear(),K());},onError(l){return K.onError(l),V},onPermissionDenied(l){return K.onPermissionDenied(l),V}};return V}asStore(e={}){let t=this.stream(e);return {subscribe:n=>t.subscribe(()=>{n();},false),getSnapshot:()=>t.getSnapshot(),getServerSnapshot:()=>[],stream:t,destroy:()=>{t.close();}}}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 N=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;this._state="disconnected";this._stateListeners=[];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._setState("connecting"),this._connect();}ready(){return this._readyPromise}get connectionState(){return this._state}onConnectionStateChange(e){return this._stateListeners.push(e),()=>{this._stateListeners=this._stateListeners.filter(t=>t!==e);}}disconnect(){this.shouldReconnect=false,this.ws?.close(1e3,"Admin disconnect"),this.ws=null,this.connected=false,this._setState("disconnected");}send(e,t){return new Promise((n,i)=>{let s=X(),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===be.OPEN?d():this.ready().then(d).catch(i);})}subscribe(e,t,n,i,s={}){let o=X(),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=m=>{this.subscriptionErrorHandlers.get(o)?.add(m);let u=this.subscriptionLastErrors.get(o);if(u)try{m(u);}catch{}return c},c.onPermissionDenied=m=>{this.subscriptionPermissionHandlers.get(o)?.add(m);let u=this.subscriptionLastErrors.get(o);if(u?.permissionDenied)try{m(u);}catch{}return c},c.catch=m=>c.onError(m),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{}}}_setState(e){if(this._state!==e){this._state=e;for(let t of this._stateListeners.slice())try{t(e);}catch{}}}_connect(){this._readyPromise=new Promise(e=>{this._readyResolve=e;}),this.ws=new be(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?(this._setState("reconnecting"),setTimeout(()=>{this.reconnectDelay=Math.min(this.reconnectDelay*2,3e4),this._connect();},this.reconnectDelay)):this._setState("disconnected");}),this.ws.on("error",()=>{this._setState("error");});}_handle(e){let t=e.type;if(t==="auth_ok"){this.connected||(this.connected=true,this.reconnectDelay=2e3,this._setState("connected"),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:T(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 J=class{constructor(e){this._ws=new N(e);}collection(e){return new U(this._ws,e)}ready(){return this._ws.ready()}get connectionState(){return this._ws.connectionState}onConnectionStateChange(e){return this._ws.onConnectionStateChange(e)}disconnect(){this._ws.disconnect();}};var un="ServerTimeStamp",mn={$serverTimestamp:true};var ne=class{constructor(e){this.cfg={defaultTtl:"24h",transport:"auto",...e,serverUrl:e.serverUrl.replace(/\/$/,""),httpBase:e.httpBase?.replace(/\/$/,"")??"",grpcUrl:e.grpcUrl??"",dataMapper:e.dataMapper??{}};}auth(){return this._auth??(this._auth=new E(this.cfg))}db(){return this._db??(this._db=new _(this.cfg))}live(){return this._conn??(this._conn=new J(this.cfg))}notifications(){return this._notifications??(this._notifications=new D(this.cfg))}storageService(){return this._storage??(this._storage=new z(this.cfg))}storage(){return this._storageS3||(this._storageS3=new q(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)}onConnectionStateChange(e){return this.live().onConnectionStateChange(e)}disconnect(){this._conn?.disconnect(),this._conn=void 0;}},R=new Map;function kn(r,e="[DEFAULT]"){if(R.has(e))return R.get(e);let t=new ne(r);return R.set(e,t),t}function $(r="[DEFAULT]"){let e=R.get(r);if(!e)throw new Error(`[flare-admin] No app named "${r}" found. Call connectApp() before getApp().`);return e}function Sn(r="[DEFAULT]"){let e=R.get(r);return e?(e.disconnect(),R.delete(r),true):false}function wn(){for(let r of R.values())r.disconnect();R.clear();}function Cn(r="[DEFAULT]"){return $(r).auth()}function vn(r="[DEFAULT]"){return $(r).db()}function Tn(r="[DEFAULT]"){return $(r).live()}function Rn(r="[DEFAULT]"){return $(r).notifications()}function On(r="[DEFAULT]"){return $(r).storage()}export{B as AdminCollectionReference,I as AdminDocumentReference,U as AdminLiveCollectionReference,L as AdminLiveDocumentReference,Z as AdminStorageSignedAction,ne as FlareAdminApp,E as FlareAdminAuthService,J as FlareAdminConnection,_ as FlareAdminDbService,D as FlareAdminNotificationsService,q as FlareAdminStorageS3,N as FlareAdminWsConnection,un as ServerTimeStamp,mn as ServerTimeStampField,Cn as auth,kn as connectApp,vn as db,wn as disconnectAllApps,Sn as disconnectApp,$ as getApp,Tn as live,Rn as notifications,On as storage};
|
|
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 D=class{constructor(e){this.cfg=e;}get baseUrl(){return y(this.cfg,`/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 z=class{constructor(e){this.cfg=e;}base(e){return y(this.cfg,`/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 te(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 Pe(r){return r===void 0?"":typeof r=="string"?te(new TextEncoder().encode(r)):Buffer&&Buffer.isBuffer(r)?r.toString("base64"):r instanceof Uint8Array?te(r):r instanceof ArrayBuffer?te(new Uint8Array(r)):""}function Be(r){return Buffer?Buffer.from(String(r)).toString("base64"):btoa(String(r))}function je(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 Fe(r){return (String(r??"").split("/").pop()??"download").replace(/["\\\r\n]/g,"")||"download"}var q=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(A=>A.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}),m;typeof e.body=="string"?m=new TextEncoder().encode(e.body):m=e.body;let u=await fetch(c.url,{method:c.method??"PUT",headers:{...e.contentType?{"Content-Type":e.contentType}:{}},body:m});if(!u.ok){let A=await u.text().catch(()=>"");throw new Error(`[flare-admin] Signed-URL upload failed (HTTP ${u.status}): ${A}`)}return {ok:true,bucket:e.bucket,key:e.key,size:s??0,encrypted:!!(e.encrypt??true)}}let a=await Pe(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??Fe(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?je(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?Be(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 L=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 U=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 H(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 L(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}stream(e={}){let t=this._buildSq(),n=new Set,i=[],s=new Map,o=Math.max(0,Number(e.flushMs??24)),a=Math.max(1,Number(e.maxBatchSize??200)),d=e.insertAt??"end",c=typeof e.maxDocs=="number"&&e.maxDocs>0?Math.floor(e.maxDocs):void 0,m=String(e.idField??"id"),u=[],A=false,O=false,k=0,F,M=()=>{s.clear();for(let l=0;l<u.length;l+=1){let p=re(u[l]);p&&s.set(p,l);}},re=(l,p)=>{if(p)return p;if(l==null)return;if(typeof e.getId=="function"){let v=e.getId(l);if(typeof v=="string"&&v.length>0)return v}let b=l?.[m]??l?._id??l?.docId;if(typeof b=="string"&&b.length>0)return b},ie=()=>{c==null||u.length<=c||(u=u.slice(0,c));},se=()=>{typeof e.sort=="function"&&(u=u.slice().sort(e.sort));},oe=(l,p)=>{k+=1;let b=u.slice(),v={reason:l,batchSize:p,version:k,ready:O};for(let W of Array.from(n))try{W(b,v);}catch{}},Q=()=>{F!=null&&(clearTimeout(F),F=void 0);},ke=l=>{if(l.operation==="delete"){let W=s.get(l.docId??"");if(W==null)return;u.splice(W,1),M();return}let p=l.data;if(p==null)return;let b=re(p,l.docId);if(!b)return;let v=s.get(b);if(typeof v=="number"){u[v]=p;return}d==="start"?u.unshift(p):u.push(p),ie(),M();},ae=()=>{if(A||i.length===0)return;Q();let l=i.splice(0,i.length);for(let p of l)ke(p);se(),M(),oe("change-batch",l.length);},Se=()=>{A||F!=null||(F=setTimeout(ae,o));},K=this.conn.subscribe(this.name,void 0,t,l=>{if(!A){if(l.type==="snapshot"){u=Array.isArray(l.data)?[...l.data]:[],O=true,Q(),i.length=0,se(),ie(),M(),oe("snapshot",0);return}if(i.push({docId:l.docId,operation:l.operation,data:l.data??null}),i.length>=a){ae();return}Se();}}),V={subscribe(l,p=true){if(n.add(l),p){let b={reason:O?"change-batch":"snapshot",batchSize:0,version:k,ready:O};try{l(u.slice(),b);}catch{}}return ()=>{n.delete(l);}},getSnapshot(){return u.slice()},isReady(){return O},getVersion(){return k},close:()=>{A||(A=true,Q(),i.length=0,n.clear(),K());},onError(l){return K.onError(l),V},onPermissionDenied(l){return K.onPermissionDenied(l),V}};return V}asStore(e={}){let t=this.stream(e);return {subscribe:n=>t.subscribe(()=>{n();},false),getSnapshot:()=>t.getSnapshot(),getServerSnapshot:()=>[],stream:t,destroy:()=>{t.close();}}}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 N=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;this._state="disconnected";this._stateListeners=[];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._setState("connecting"),this._connect();}ready(){return this._readyPromise}get connectionState(){return this._state}onConnectionStateChange(e){return this._stateListeners.push(e),()=>{this._stateListeners=this._stateListeners.filter(t=>t!==e);}}disconnect(){this.shouldReconnect=false,this.ws?.close(1e3,"Admin disconnect"),this.ws=null,this.connected=false,this._setState("disconnected");}send(e,t){return new Promise((n,i)=>{let s=X(),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===be.OPEN?d():this.ready().then(d).catch(i);})}subscribe(e,t,n,i,s={}){let o=X(),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=m=>{this.subscriptionErrorHandlers.get(o)?.add(m);let u=this.subscriptionLastErrors.get(o);if(u)try{m(u);}catch{}return c},c.onPermissionDenied=m=>{this.subscriptionPermissionHandlers.get(o)?.add(m);let u=this.subscriptionLastErrors.get(o);if(u?.permissionDenied)try{m(u);}catch{}return c},c.catch=m=>c.onError(m),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{}}}_setState(e){if(this._state!==e){this._state=e;for(let t of this._stateListeners.slice())try{t(e);}catch{}}}_connect(){this._readyPromise=new Promise(e=>{this._readyResolve=e;}),this.ws=new be(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?(this._setState("reconnecting"),setTimeout(()=>{this.reconnectDelay=Math.min(this.reconnectDelay*2,3e4),this._connect();},this.reconnectDelay)):this._setState("disconnected");}),this.ws.on("error",()=>{this._setState("error");});}_handle(e){let t=e.type;if(t==="auth_ok"){this.connected||(this.connected=true,this.reconnectDelay=2e3,this._setState("connected"),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:T(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 J=class{constructor(e){this._ws=new N(e);}collection(e){return new U(this._ws,e)}ready(){return this._ws.ready()}get connectionState(){return this._ws.connectionState}onConnectionStateChange(e){return this._ws.onConnectionStateChange(e)}disconnect(){this._ws.disconnect();}};var un="ServerTimeStamp",mn={$serverTimestamp:true};var ne=class{constructor(e){this.cfg={defaultTtl:"24h",transport:"auto",...e,serverUrl:e.serverUrl.replace(/\/$/,""),httpBase:e.httpBase?.replace(/\/$/,"")??"",grpcUrl:e.grpcUrl??"",dataMapper:e.dataMapper??{}};}auth(){return this._auth??(this._auth=new E(this.cfg))}db(){return this._db??(this._db=new _(this.cfg))}live(){return this._conn??(this._conn=new J(this.cfg))}notifications(){return this._notifications??(this._notifications=new D(this.cfg))}storageService(){return this._storage??(this._storage=new z(this.cfg))}storage(){return this._storageS3||(this._storageS3=new q(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)}onConnectionStateChange(e){return this.live().onConnectionStateChange(e)}disconnect(){this._conn?.disconnect(),this._conn=void 0;}},R=new Map;function kn(r,e="[DEFAULT]"){if(R.has(e))return R.get(e);let t=new ne(r);return R.set(e,t),t}function $(r="[DEFAULT]"){let e=R.get(r);if(!e)throw new Error(`[flare-admin] No app named "${r}" found. Call connectApp() before getApp().`);return e}function Sn(r="[DEFAULT]"){let e=R.get(r);return e?(e.disconnect(),R.delete(r),true):false}function wn(){for(let r of R.values())r.disconnect();R.clear();}function Cn(r="[DEFAULT]"){return $(r).auth()}function vn(r="[DEFAULT]"){return $(r).db()}function Tn(r="[DEFAULT]"){return $(r).live()}function Rn(r="[DEFAULT]"){return $(r).notifications()}function On(r="[DEFAULT]"){return $(r).storage()}export{P as AdminCollectionReference,I as AdminDocumentReference,U as AdminLiveCollectionReference,L as AdminLiveDocumentReference,Z as AdminStorageSignedAction,ne as FlareAdminApp,E as FlareAdminAuthService,J as FlareAdminConnection,_ as FlareAdminDbService,D as FlareAdminNotificationsService,q as FlareAdminStorageS3,N as FlareAdminWsConnection,un as ServerTimeStamp,mn as ServerTimeStampField,Cn as auth,kn as connectApp,vn as db,wn as disconnectAllApps,Sn as disconnectApp,$ as getApp,Tn as live,Rn as notifications,On as storage};
|
package/dist/types/index.d.ts
CHANGED
|
@@ -625,6 +625,7 @@ export interface AdminCollectionShape<T> {
|
|
|
625
625
|
first(): Promise<T | null>;
|
|
626
626
|
last(): Promise<T | null>;
|
|
627
627
|
add(data: Partial<T>): Promise<AdminDocumentShape<T>>;
|
|
628
|
+
update(id: string, data: Partial<T>): Promise<AdminDocumentShape<T>>;
|
|
628
629
|
addMany(items: Iterable<Partial<T>> | AsyncIterable<Partial<T>>, options?: AdminBulkWriteOptions): Promise<AdminBulkWriteResult>;
|
|
629
630
|
updateMany(items: Iterable<AdminUpdateManyItem<T>> | AsyncIterable<AdminUpdateManyItem<T>>, options?: AdminBulkWriteOptions): Promise<AdminBulkWriteResult>;
|
|
630
631
|
deleteMany(docIds: Iterable<string> | AsyncIterable<string>, options?: AdminBulkWriteOptions): Promise<AdminBulkWriteResult>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zuzjs/flare-admin",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"description": "Privileged server-side access for Flare. Designed for secure environments to perform administrative tasks, manage user identities at scale, and orchestrate system-wide notifications with full bypass of client-side security rules.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"flare",
|