@asaidimu/hestia 1.0.2 → 1.0.3

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/index.cjs CHANGED
@@ -4,5 +4,5 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require
4
4
  `).filter(e=>e.startsWith(`data:`)).map(e=>e.slice(5).trim());t.length>0&&n.onMessage(t.join(`
5
5
  `)),r=p.indexOf(`
6
6
 
7
- `)}}}catch(e){e instanceof Error&&e.name===`AbortError`||n.onError?.(e instanceof Error?e:Error(String(e)))}finally{n.onClose?.()}};return i(!1)}};const f={data:[],loading:!0,page:{number:1,size:20,count:0,total:0,pages:1}};function p(e,t,i,a){let o=i.page??1,s=i.size??20,c=i.sort,l=i.filter,u=new r.Debouncer({delay:50}),d=`${e}_pager_state_`;t.set({[d]:{data:[],loading:!1,error:n.DELETE_SYMBOL,page:{number:1,size:20,count:0,total:0,pages:1}}});let p=e=>{let t=e?.page??o,n=e?.size??s,r={pagination:{type:`offset`,offset:(t-1)*n,limit:n}},i=e?.sort??c;i&&(r.sort=Array.isArray(i)?i:[i]);let a=e?.filter??l;return a&&(r.filters=a),r},m=async e=>(await t.set({[d]:{loading:!0,error:n.DELETE_SYMBOL}}),await new Promise(n=>{n(u.do(async()=>{requestIdleCallback(()=>{requestIdleCallback(async()=>{try{let n=await a(p(e));await t.set({[d]:n})}catch(e){await t.set({[d]:{...f,error:e}})}finally{await t.set({[d]:{loading:!1}})}})})}))})),h=t.select(e=>e[d]),g=h.subscribe(()=>{});return{page:()=>h.get()??f,navigate:async e=>{if(e<1)throw Error(`Page number must be >= 1`);o=e,await m({page:e})},resize:async(e,t)=>{if(e<1)throw Error(`Page size must be >= 1`);s=e,o=t,await m()},sort:async e=>{c=Array.isArray(e)?e:[e],o=1,await m()},filter:async e=>{l=e,o=1,await m()},refresh:async e=>{await Promise.all([new Promise(t=>setTimeout(t,e?.delay||0)),m(e)])},subscribe:e=>h.subscribe(e),invalidate:async()=>{await t.set({[d]:n.DELETE_SYMBOL}),g()},id:()=>d}}var m=class{client;collectionName;defaultLimit;pagerOptions={};pager;constructor(e,t,r=50){this.client=e,this.collectionName=t,this.defaultLimit=r,this.pager=p(t,new n.ReactiveDataStore({}),this.pagerOptions,e=>this.find(e))}name(){return this.collectionName}get queryPath(){return`/system/collections/document/${encodeURIComponent(this.collectionName)}/query`}get documentsPath(){return`/system/collections/document/${encodeURIComponent(this.collectionName)}`}documentPath(e){return`${this.documentsPath}/${encodeURIComponent(e)}`}async find(e){let t=await this.client.post(this.queryPath,e??{}),n=t.data?.data??[];return{data:n,loading:!1,page:t.data?.metadata?.page??{number:1,size:n.length,count:n.length,total:n.length,pages:1},error:null}}async read(e){try{return(await this.client.get(this.documentPath(e))).data?.data}catch(e){if(e?.code===`SYNC-001-NF`||e?.code===`NOT_FOUND`)return;throw e}}async create(e){return(await this.client.post(this.documentsPath,e.data)).data.data}async update(e){let t=e.options;return(await this.client.patch(this.documentPath(t),e.data)).data.data}async delete(e){await this.client.delete(this.documentPath(e))}async list(e){return this.find(e??{pagination:{type:`offset`,offset:0,limit:this.defaultLimit}})}async upload(e){throw Error(`Upload not supported for collections`)}async subscribe(e,t){throw Error(`Subscription not implemented for dynamic collections`)}async notify(e){throw Error(`Notify not implemented for dynamic collections`)}stream(e,t){throw Error(`Stream not supported for collections`)}page(e){return this.pager}},h=class{client;provider;constructor(e,t){this.client=e,this.provider=t}async health(){return(await this.client.get(`/system/core/health`)).data.data}async login(e,t){let n=(await this.client.post(`/system/auth/session`,{email:e,password:t})).data.data;return this.provider.setIdentity(n.user),this.client.storeTokens(n.token.access,n.token.refresh),n}async register(e,t,n){return(await this.client.post(`/system/auth/user`,{email:e,password:t,name:n})).data.data}async refresh(e){let t=e?{refresh_token:e}:{};return(await this.client.patch(`/system/auth/session`,t)).data.data.token}async logout(){let e=this.provider.token(`refresh`),t=e?{refresh_token:e}:{};await this.client.delete(`/system/auth/session`,t),await this.provider.clear()}async requestPasswordReset(e){await this.client.post(`/system/auth/password`,{email:e})}async confirmPasswordReset(e,t){await this.client.patch(`/system/auth/password`,{password:t,token:e},{headers:{Authorization:`Bearer ${e}`}})}async bootstrap(e,t,n){await this.client.patch(`/system/auth/bootstrap`,{password:t,email:n},{headers:{"X-API-Key":e}})}},g=class{client;pagerOptions={};pager;constructor(e){this.client=e,this.pager=p(`users`,new n.ReactiveDataStore({}),this.pagerOptions,e=>this.find(e))}name(){return`users`}async find(e){let t=await this.client.post(`/system/users/user/query`,e??{}),n=t.data?.data??[];return{data:n,loading:!1,page:t.data?.metadata?.page??{number:1,size:n.length,count:n.length,total:n.length,pages:1}}}async list(e){return this.find(e??{pagination:{type:`offset`,offset:0,limit:50}})}async read(e){try{return(await this.client.get(`/system/users/user/${encodeURIComponent(e)}`)).data?.data}catch(e){if(e?.code===`SYNC-001-NF`)return;throw e}}async update(e){let t=e.options;return(await this.client.patch(`/system/users/user/${encodeURIComponent(t)}`,e.data)).data.data}async delete(e){await this.client.delete(`/system/users/user/${encodeURIComponent(e)}`)}async create(e){throw Error(`User creation requires email/password/name, use register endpoint`)}async upload(e){throw Error(`Upload not supported for users`)}async subscribe(e,t){throw Error(`Subscription not supported for users`)}async notify(e){throw Error(`Notify not supported for users`)}stream(e,t){throw Error(`Stream not supported for users`)}page(e){return this.pager}async changePassword(e,t,n){await this.client.patch(`/system/users/password/${encodeURIComponent(e)}`,{current:t,new:n})}},_=class{client;pager;constructor(e){this.client=e,this.pager=p(`_api_key_`,new n.ReactiveDataStore({}),{},e=>this.find(e))}basePath=`/system/apikeys/key`;async find(e){let t=await this.client.get(this.basePath),n=t.data?.data??[];return{data:n,loading:!1,page:t.data?.metadata?.page??{number:1,size:n.length,count:n.length,total:n.length,pages:1}}}async list(e){return e?this.find(e):this.find()}async read(e){try{return(await this.client.get(`${this.basePath}/${encodeURIComponent(e)}`)).data?.data}catch(e){if(e?.code===`SYNC-001-NF`||e?.code===`INTERNAL_ERROR`&&typeof e?.message==`string`&&e.message.includes(`not found`))return;throw e}}async create(e){return(await this.client.post(this.basePath,e.data)).data.data}async update(e){let t=e.options;return(await this.client.patch(`${this.basePath}/${encodeURIComponent(t)}`,e.data)).data.data}async delete(e){await this.client.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async upload(e){throw Error(`Upload not supported for API keys`)}async subscribe(e,t){throw Error(`Subscription not supported for API keys`)}async notify(e){throw Error(`Notify not supported for API keys`)}stream(e,t){throw Error(`Stream not supported for API keys`)}page(e){return this.pager}async rotate(e){return(await this.client.post(`${this.basePath}/${encodeURIComponent(e)}`)).data.data}},v=class{client;pager;operationsPath=`/system/policies/operation`;rulesPath=`/system/policies/rule`;constructor(e){this.client=e,this.pager=p(`policies`,new n.ReactiveDataStore({}),{},e=>this.find(e))}async collectionQuery(e,t){let n=await this.client.post(`/system/collections/document/${encodeURIComponent(e)}/query`,t??{}),r=n.data?.data??[];return{data:r,loading:!1,page:n.data?.metadata?.page??{number:1,size:r.length,count:r.length,total:r.length,pages:1},error:null}}async find(e){return this.collectionQuery(`_operation_policy_`,e)}async list(e){return this.find(e??{pagination:{type:`offset`,offset:0,limit:50}})}async read(e){try{return(await this.client.get(`${this.operationsPath}/${encodeURIComponent(e)}`)).data?.data}catch(e){if(e?.code===`SYNC-001-NF`||e?.code===`NOT_FOUND`||e?.code===`INTERNAL_ERROR`&&typeof e?.message==`string`&&e.message.includes(`not found`))return;throw e}}async create(e){let t=e.data.name;if(!t)throw Error(`Operation name is required for create`);return(await this.client.patch(`${this.operationsPath}/${encodeURIComponent(t)}`,e.data)).data.data}async update(e){let t=e.options;if(!t)throw Error(`Operation name is required for update`);return(await this.client.patch(`${this.operationsPath}/${encodeURIComponent(t)}`,e.data)).data.data}async delete(e){await this.client.delete(`${this.operationsPath}/${encodeURIComponent(e)}`)}async upsertOperation(e,t){return(await this.client.patch(`${this.operationsPath}/${encodeURIComponent(e)}`,t)).data.data}async getRule(e){try{return(await this.client.get(`${this.rulesPath}/${encodeURIComponent(e)}`)).data?.data}catch(e){if(e?.code===`SYNC-001-NF`||e?.code===`NOT_FOUND`||e?.code===`INTERNAL_ERROR`&&typeof e?.message==`string`&&e.message.includes(`not found`))return;throw e}}async upsertRule(e,t){return(await this.client.patch(`${this.rulesPath}/${encodeURIComponent(e)}`,t)).data.data}async deleteRule(e){await this.client.delete(`${this.rulesPath}/${encodeURIComponent(e)}`)}async listRules(e){return this.collectionQuery(`_iam_rule_`,e)}async validateRule(e){return(await this.client.post(`${this.rulesPath}/validate`,{expression:e})).data?.data?.valid??!1}async reload(){return(await this.client.get(`${this.rulesPath}/reload`)).data.data}async upload(e){throw Error(`Upload not supported for policies`)}async subscribe(e,t){throw Error(`Subscription not supported for policies`)}async notify(e){throw Error(`Notify not supported for policies`)}stream(e,t){throw Error(`Stream not supported for policies`)}page(e){return this.pager}},y=class{client;baseUrl;pagerOptions={};pager;apiPrefix;constructor(e,t,r=`/api`){this.client=e,this.baseUrl=t,this.apiPrefix=r,this.pager=p(`_audit_log_`,new n.ReactiveDataStore({}),this.pagerOptions,e=>this.find(e))}async find(e){let t=await this.client.post(`/system/audit/log/query`,e??{}),n=t.data?.data??[];return{data:n,loading:!1,page:t.data?.metadata?.page??{number:1,size:n.length,count:n.length,total:n.length,pages:1},error:null}}async list(e){return this.find(e??{pagination:{type:`offset`,offset:0,limit:50}})}async read(e){throw Error(`Read by ID not supported for audit logs; use find with filters`)}async create(e){throw Error(`Audit logs are write-only; entries are created by the system`)}async update(e){throw Error(`Audit logs are append-only; updates are not allowed`)}async delete(e){throw Error(`Audit logs are append-only; deletion is not allowed`)}async upload(e){throw Error(`Upload not supported for audit logs`)}async subscribe(e,t){throw Error(`Use stream() for real-time audit log entries`)}async notify(e){throw Error(`Notify not supported for audit logs`)}stream(e,t){let n=this.getStreamUrl(),r=null,i=`active`,a=null,o=async function*(){let e=[];r=new EventSource(n,{withCredentials:!0}),r.onmessage=t=>{for(let n of t.data.split(`
8
- `)){let t=n.trim();if(t)try{let n=JSON.parse(t);n?.data&&e.push(n.data)}catch{}}e.length>0&&a&&(a(),a=null)},r.onerror=()=>{i===`active`&&(i=`completed`),a&&=(a(),null)};try{for(;i===`active`;)e.length>0?yield e.shift():await new Promise(t=>{a=t,e.length>0&&(t(),a=null)})}finally{r?.close(),a&&=(a(),null),i===`active`&&(i=`completed`)}};return{stream:()=>o(),cancel:()=>{i===`active`&&(i=`cancelled`,r?.close())},status:()=>i}}page(e){return this.pager}getStreamUrl(){return`${this.baseUrl}${this.apiPrefix}/system/audit/log/stream`}};function b(e){return{_id_:e.key,_metadata_:{checksum:``,created:e.created_at,updated:e.updated_at??e.created_at,version:1},...e}}function x(e){return{number:1,size:e.length,count:e.length,total:e.length,pages:1}}var S=class{client;ns;pagerOptions={};pager;prefixFilter=``;constructor(e,t){this.client=e,this.ns=t,this.pager=p(`blobs_${t}`,new n.ReactiveDataStore({}),this.pagerOptions,e=>this.find(e))}name(){return this.ns}setPrefix(e){this.prefixFilter=e}basePath(){return`/system/blobs/blob/${encodeURIComponent(this.ns)}`}async find(e){let t=this.prefixFilter||e?.prefix||``,n=e?.limit??e?.pagination?.limit??0,r={};t&&(r.prefix=t),n&&(r.limit=n);let i=(await this.client.post(`${this.basePath()}/query`,r)).data?.data?.blobs??[];return{data:i.map(b),loading:!1,page:x(i),error:void 0}}async read(e){try{let t=await this.client.get(`${this.basePath()}/${encodeURIComponent(e)}`);return t.data?.data?b(t.data.data):void 0}catch(e){if(e?.code===`SYNC-001-NF`||e?.code===`INTERNAL_ERROR`&&typeof e?.message==`string`&&e.message.includes(`not found`))return;throw e}}async create(e){throw Error(`Use upload() to create blobs`)}async update(e){let t=e.options?.key;if(!t)throw Error(`options.key is required for blob update`);return b((await this.client.patch(`${this.basePath()}/${encodeURIComponent(t)}`,{custom:e.data})).data.data)}async delete(e){await this.client.delete(`${this.basePath()}/${encodeURIComponent(e)}`)}async list(e){return this.find(e??{})}async upload(e){let t=e.options?.key;if(!t)throw Error(`options.key is required for blob upload`);let n={},r=e.options?.contentType||e.file.type;return r&&(n[`Content-Type`]=r),b((await this.client.post(`${this.basePath()}/${encodeURIComponent(t)}`,e.file,{headers:n,bodyType:`blob`})).data.data)}async subscribe(e,t){throw Error(`Subscription not supported for blobs`)}async notify(e){throw Error(`Notify not supported for blobs`)}stream(e,t){throw Error(`Stream not supported for blobs`)}page(e){return this.pager}async download(e){let t=(await this.client.get(`${this.basePath()}/${encodeURIComponent(e)}`,{responseType:`blob`})).data;return{data:t,contentType:t.type}}},C=class{client;apiPrefix;constructor(e,t=`/api`){this.client=e,this.apiPrefix=t}nsBase=`/system/blobs`;async namespaces(){return(await this.client.post(`${this.nsBase}/namespace/query`)).data?.data?.namespaces??[]}async createNamespace(e){return(await this.client.post(`${this.nsBase}/namespace`,e)).data.data}async deleteNamespace(e){await this.client.delete(`${this.nsBase}/namespace/${encodeURIComponent(e)}`)}blob(e,t){return`${this.client.base()}${this.apiPrefix}${this.nsBase}/blob/${encodeURIComponent(e)}/${encodeURIComponent(t)}`}namespace(e){return new S(this.client,e)}},w=class{client;constructor(e){this.client=e}async find(e){let t=((await this.client.get(`/system/collections/collection`)).data?.data??[]).map(e=>({_id_:e.name,_metadata_:{checksum:``,created:e.created,updated:e.updated,version:1},name:e.name,schema:e.schema,created:e.created,updated:e.updated}));return{data:t,loading:!1,page:{number:1,size:t.length,count:t.length,total:t.length,pages:1}}}async read(e){try{let t=await this.client.get(`/system/collections/collection/${encodeURIComponent(e)}`);if(!t.data)return;let n=t.data.data;return{_id_:n.name,_metadata_:{checksum:``,created:n.created,updated:n.updated,version:1},name:n.name,schema:n.schema,created:n.created,updated:n.updated}}catch(e){if(e?.code===`SYNC-001-NF`)return;throw e}}async create(e){return(await this.client.post(`/system/collections/collection`,e.data)).data.data}async update(e){throw Error(`Collection update not implemented`)}async delete(e){await this.client.delete(`/system/collections/collection/${encodeURIComponent(e)}`)}async list(e){return this.find()}async upload(e){throw Error(`Upload not supported for collections`)}async subscribe(e,t){throw Error(`Subscription not supported for collections`)}async notify(e){throw Error(`Notify not supported for collections`)}stream(e,t){throw Error(`Stream not supported for collections`)}page(e){throw Error(`Pagination not supported for collection metadata; use documents(name)`)}documents(e){return new m(this.client,e)}},T=class{client;constructor(e){this.client=e}async find(e){let t=(await this.client.get(`/system/core/docs`)).data?.data??[];return{data:t,loading:!1,page:{number:1,size:t.length,count:t.length,total:t.length,pages:1}}}async read(e){throw Error(`Read by ID not supported for capabilities; use find()`)}async create(e){throw Error(`Capabilities are read-only`)}async update(e){throw Error(`Capabilities are read-only`)}async delete(e){throw Error(`Capabilities are read-only`)}async list(e){return this.find()}async upload(e){throw Error(`Upload not supported for capabilities`)}async subscribe(e,t){throw Error(`Subscription not supported for capabilities`)}async notify(e){throw Error(`Notify not supported for capabilities`)}stream(e,t){throw Error(`Stream not supported for capabilities`)}page(e){throw Error(`Pagination not supported for capabilities`)}},E=class{store;client;auth;users;keys;policies;logs;collections;blobs;capabilities;tokenProvider;onAuthStateChanged;constructor(e){this.store=new n.ReactiveDataStore({access:null,refresh:null,identity:null},e.persistence);let t={identity:()=>this.store.get().identity,token:e=>this.store.get()[e],setTokens:async(e,t)=>void await this.store.set({access:e,refresh:t}),setIdentity:async e=>void await this.store.set({identity:e}),clear:async()=>void await this.store.set({access:null,refresh:null})},r=e.apiPrefix??`/api`;this.tokenProvider=t,this.client=new d(e.baseUrl,r,t,()=>this.onAuthStateChanged?.()),this.auth=new h(this.client,t),this.users=new g(this.client),this.keys=new _(this.client),this.policies=new v(this.client),this.logs=new y(this.client,e.baseUrl,r),this.collections=new w(this.client),this.blobs=new C(this.client,r),this.capabilities=new T(this.client)}onAuthStateChange(e){this.onAuthStateChanged=e}authenticated(){return this.tokenProvider.token(`access`)!==null}collection(e){return this.collections.documents(e)}};function D(e){let t=`${e.collectionName}_array_pager_state_`,r=new n.ReactiveDataStore({}),a=[...e.initialData??[]],o=`collection`,s,c=e.page??1,l=e.size??20,u=[],d,f,{match:p}=(0,i.createMatcher)(e.customFunctions??{}),{sort:m}=(0,i.createSorter)(),h=r.select(e=>e[t]),g={data:[],loading:!0,error:void 0,page:{number:1,size:l,count:0,total:0,pages:1}},_=()=>({filters:d,sort:u,pagination:{type:`offset`,offset:(c-1)*l,limit:l}}),v=async(n=!0)=>{if(e.fetch){if(f=void 0,n){let e=h.get()??g;await r.set({[t]:{...e,loading:!0,error:void 0}})}try{let t=_(),n=await e.fetch(t);o=n.scope,s=n.total,a=n.replace?[...n.data]:[...a,...n.data]}catch(e){f=e}}let i=y(e.fetch?n:!1);await r.set({[t]:i})},y=e=>{let t=[...a];if(o===`collection`){d&&(t=t.filter(e=>p(e,d))),u.length>0&&(t=m(t,u));let n=t.length,r=Math.ceil(n/l)||1;c>r&&(c=r),c<1&&(c=1);let i=(c-1)*l,a=t.slice(i,i+l);return{data:a,loading:e,error:f,page:{number:c,size:l,count:a.length,total:n,pages:r}}}let n=s??t.length,r=Math.ceil(n/l)||1;return{data:t,loading:e,error:f,page:{number:c,size:l,count:t.length,total:n,pages:r}}};return v(!0),{id:()=>t,page:()=>h.get()??g,navigate:async e=>{if(e<1)throw Error(`Page number must be >= 1`);c=e,await v(!0)},resize:async(e,t)=>{if(e<1)throw Error(`Page size must be >= 1`);l=e,c=t,await v(!0)},sort:async e=>{u=Array.isArray(e)?e:[e],c=1,await v(!0)},filter:async e=>{d=e,c=1,await v(!0)},refresh:async e=>{let n=h.get()??g;await r.set({[t]:{...n,loading:!0}});let i=e?.delay??600;await Promise.all([new Promise(e=>setTimeout(e,i)),v(!1)]);let a=h.get()??g;await r.set({[t]:{...a,loading:!1}})},subscribe:e=>h.subscribe(t=>{e(t)}),invalidate:async()=>{await r.set({[t]:n.DELETE_SYMBOL}),a=[]}}}exports.BlobNamespace=S,exports.HestiaAuth=h,exports.HestiaBlobClient=C,exports.HestiaClient=E,exports.HestiaCollection=m,exports.HestiaCollections=w,exports.HestiaKeyStore=_,exports.HestiaLogs=y,exports.HestiaNetworkClient=d,exports.HestiaPolicies=v,exports.HestiaResponse=u,exports.HestiaUsers=g,exports.createArrayPager=D,exports.createPagedController=p,exports.internalError=l,exports.notFound=s,exports.parseErrorBody=a,exports.permissionDenied=c,exports.toSystemError=o;
7
+ `)}}}catch(e){e instanceof Error&&e.name===`AbortError`||n.onError?.(e instanceof Error?e:Error(String(e)))}finally{n.onClose?.()}};return i(!1)}};const f={data:[],loading:!0,page:{number:1,size:20,count:0,total:0,pages:1}};function p(e,t,i,a){let o=i.page??1,s=i.size??20,c=i.sort,l=i.filter,u=new r.Debouncer({delay:50}),d=`${e}_pager_state_`;t.set({[d]:{data:[],loading:!1,error:n.DELETE_SYMBOL,page:{number:1,size:20,count:0,total:0,pages:1}}});let p=e=>{let t=e?.page??o,n=e?.size??s,r={pagination:{type:`offset`,offset:(t-1)*n,limit:n}},i=e?.sort??c;i&&(r.sort=Array.isArray(i)?i:[i]);let a=e?.filter??l;return a&&(r.filters=a),r},m=async e=>(await t.set({[d]:{loading:!0,error:n.DELETE_SYMBOL}}),await new Promise(n=>{n(u.do(async()=>{requestIdleCallback(()=>{requestIdleCallback(async()=>{try{let n=await a(p(e));await t.set({[d]:n})}catch(e){await t.set({[d]:{...f,error:e}})}finally{await t.set({[d]:{loading:!1}})}})})}))})),h=t.select(e=>e[d]),g=h.subscribe(()=>{});return{page:()=>h.get()??f,navigate:async e=>{if(e<1)throw Error(`Page number must be >= 1`);o=e,await m({page:e})},resize:async(e,t)=>{if(e<1)throw Error(`Page size must be >= 1`);s=e,o=t,await m()},sort:async e=>{c=Array.isArray(e)?e:[e],o=1,await m()},filter:async e=>{l=e,o=1,await m()},refresh:async e=>{await Promise.all([new Promise(t=>setTimeout(t,e?.delay||0)),m(e)])},subscribe:e=>h.subscribe(e),invalidate:async()=>{await t.set({[d]:n.DELETE_SYMBOL}),g()},id:()=>d}}var m=class{client;collectionName;defaultLimit;pagerOptions={};pager;constructor(e,t,r=50){this.client=e,this.collectionName=t,this.defaultLimit=r,this.pager=p(t,new n.ReactiveDataStore({}),this.pagerOptions,e=>this.find(e))}name(){return this.collectionName}get queryPath(){return`/system/collections/document/${encodeURIComponent(this.collectionName)}/query`}get documentsPath(){return`/system/collections/document/${encodeURIComponent(this.collectionName)}`}documentPath(e){return`${this.documentsPath}/${encodeURIComponent(e)}`}async find(e){let t=await this.client.post(this.queryPath,e??{}),n=t.data?.data??[];return{data:n,loading:!1,page:t.data?.metadata?.page??{number:1,size:n.length,count:n.length,total:n.length,pages:1},error:null}}async read(e){try{return(await this.client.get(this.documentPath(e))).data?.data}catch(e){if(e?.code===`SYNC-001-NF`||e?.code===`NOT_FOUND`)return;throw e}}async create(e){return(await this.client.post(this.documentsPath,e.data)).data.data}async update(e){let t=e.options;return(await this.client.patch(this.documentPath(t),e.data)).data.data}async delete(e){await this.client.delete(this.documentPath(e))}async list(e){return this.find(e??{pagination:{type:`offset`,offset:0,limit:this.defaultLimit}})}async upload(e){throw Error(`Upload not supported for collections`)}async subscribe(e,t){throw Error(`Subscription not implemented for dynamic collections`)}async notify(e){throw Error(`Notify not implemented for dynamic collections`)}stream(e,t){throw Error(`Stream not supported for collections`)}page(e){return this.pager}},h=class{client;provider;constructor(e,t){this.client=e,this.provider=t}async health(){return(await this.client.get(`/system/core/health`)).data.data}async login(e,t){let n=(await this.client.post(`/system/auth/session`,{email:e,password:t})).data.data;return this.provider.setIdentity(n.user),this.client.storeTokens(n.token.access,n.token.refresh),n}async register(e,t,n){return(await this.client.post(`/system/auth/user`,{email:e,password:t,name:n})).data.data}async refresh(e){let t=e?{refresh_token:e}:{};return(await this.client.patch(`/system/auth/session`,t)).data.data.token}async logout(){let e=this.provider.token(`refresh`),t=e?{refresh_token:e}:{};await this.client.delete(`/system/auth/session`,t),await this.provider.clear()}async requestPasswordReset(e){await this.client.post(`/system/auth/password`,{email:e})}async confirmPasswordReset(e,t){await this.client.patch(`/system/auth/password`,{password:t,token:e},{headers:{Authorization:`Bearer ${e}`}})}async bootstrap(e,t,n){await this.client.patch(`/system/auth/bootstrap`,{password:t,email:n},{headers:{"X-API-Key":e}})}},g=class{client;pagerOptions={};pager;constructor(e){this.client=e,this.pager=p(`users`,new n.ReactiveDataStore({}),this.pagerOptions,e=>this.find(e))}name(){return`users`}async find(e){let t=await this.client.post(`/system/users/user/query`,e??{}),n=t.data?.data??[];return{data:n,loading:!1,page:t.data?.metadata?.page??{number:1,size:n.length,count:n.length,total:n.length,pages:1}}}async list(e){return this.find(e??{pagination:{type:`offset`,offset:0,limit:50}})}async read(e){try{return(await this.client.get(`/system/users/user/${encodeURIComponent(e)}`)).data?.data}catch(e){if(e?.code===`SYNC-001-NF`)return;throw e}}async update(e){let t=e.options;return(await this.client.patch(`/system/users/user/${encodeURIComponent(t)}`,e.data)).data.data}async delete(e){await this.client.delete(`/system/users/user/${encodeURIComponent(e)}`)}async create(e){throw Error(`User creation requires email/password/name, use register endpoint`)}async upload(e){throw Error(`Upload not supported for users`)}async subscribe(e,t){throw Error(`Subscription not supported for users`)}async notify(e){throw Error(`Notify not supported for users`)}stream(e,t){throw Error(`Stream not supported for users`)}page(e){return this.pager}async changePassword(e,t,n){await this.client.patch(`/system/users/password/${encodeURIComponent(e)}`,{current:t,new:n})}},_=class{client;pager;constructor(e){this.client=e,this.pager=p(`_api_key_`,new n.ReactiveDataStore({}),{},e=>this.find(e))}basePath=`/system/apikeys/key`;async find(e){let t=await this.client.get(this.basePath),n=t.data?.data??[];return{data:n,loading:!1,page:t.data?.metadata?.page??{number:1,size:n.length,count:n.length,total:n.length,pages:1}}}async list(e){return e?this.find(e):this.find()}async read(e){try{return(await this.client.get(`${this.basePath}/${encodeURIComponent(e)}`)).data?.data}catch(e){if(e?.code===`SYNC-001-NF`||e?.code===`INTERNAL_ERROR`&&typeof e?.message==`string`&&e.message.includes(`not found`))return;throw e}}async create(e){return(await this.client.post(this.basePath,e.data)).data.data}async update(e){let t=e.options;return(await this.client.patch(`${this.basePath}/${encodeURIComponent(t)}`,e.data)).data.data}async delete(e){await this.client.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async upload(e){throw Error(`Upload not supported for API keys`)}async subscribe(e,t){throw Error(`Subscription not supported for API keys`)}async notify(e){throw Error(`Notify not supported for API keys`)}stream(e,t){throw Error(`Stream not supported for API keys`)}page(e){return this.pager}async rotate(e){return(await this.client.post(`${this.basePath}/${encodeURIComponent(e)}`)).data.data}};const v=`/system/policies/operation`;var y=class{client;constructor(e){this.client=e}async list(){let e=(await this.client.get(v)).data?.data?.operations??[];return{data:e.map(e=>({data:e,metadata:{}})),loading:!1,page:{number:1,size:e.length,count:e.length,total:e.length,pages:1},error:null}}async read(e){try{let t=await this.client.get(`${v}/${encodeURIComponent(e)}`);return t.data?.data?{data:t.data.data,metadata:{}}:void 0}catch(e){if(e?.code===`SYNC-001-NF`||e?.code===`NOT_FOUND`)return;throw e}}};const b=`/system/policies/policy`;var x=class{client;pager;constructor(e){this.client=e,this.pager=p(`policies`,new n.ReactiveDataStore({}),{},e=>this.find(e))}async find(e){return this.query(e??{})}async query(e){let t=await this.client.post(`/system/collections/document/_operation_policy_/query`,e),n=t.data?.data??[],r=t.data?.metadata?.page;return{data:n.map(e=>({_id_:e._id_,_metadata_:e._metadata_,id:e._id_,operationName:e.operation??``,ruleName:e.rule??``,enabled:e.enabled??!0,protected:e.protected??!1})),loading:!1,page:r??{number:1,size:n.length,count:n.length,total:n.length,pages:1},error:null}}async list(e){let t=(await this.client.get(b)).data?.data?.policies??[];return{data:t.map(e=>({data:e,metadata:{}})),loading:!1,page:{number:1,size:t.length,count:t.length,total:t.length,pages:1},error:null}}async read(e){try{let t=await this.client.get(`${b}/${encodeURIComponent(e)}`);return t.data?.data?{data:t.data.data,metadata:{}}:void 0}catch(e){if(e?.code===`SYNC-001-NF`||e?.code===`NOT_FOUND`)return;throw e}}async create(e){let t=e.options??e.data.name;if(!t)throw Error(`Operation name is required for create`);let n={ruleName:e.data.ruleName??``},r=await this.client.post(`${b}/${encodeURIComponent(t)}`,n);if(r.data?.data)return{data:r.data.data,metadata:{}}}async update(e){let t=e.options;if(!t)throw Error(`Operation name is required for update`);let n=await this.client.patch(`${b}/${encodeURIComponent(t)}`,e.data);if(n.data?.data)return{data:n.data.data,metadata:{}}}async setEnabled(e,t){return{data:(await this.client.patch(`${b}/${encodeURIComponent(e)}`,{enabled:t})).data.data,metadata:{}}}async delete(e){throw Error(`Policies cannot be deleted; disable instead`)}async upload(e){throw Error(`Upload not supported for policies`)}async subscribe(e,t){throw Error(`Subscription not supported for policies`)}async notify(e){throw Error(`Notify not supported for policies`)}stream(e,t){throw Error(`Stream not supported for policies`)}page(e){return this.pager}};const S=`/system/policies/rule`;var C=class{client;constructor(e){this.client=e}async find(e){return this.list()}async list(e){let t=(await this.client.get(S)).data?.data?.rules??[];return{data:t.map(e=>({data:e,metadata:{}})),loading:!1,page:{number:1,size:t.length,count:t.length,total:t.length,pages:1},error:null}}async read(e){try{let t=await this.client.get(`${S}/${encodeURIComponent(e)}`);return t.data?.data?{data:t.data.data,metadata:{}}:void 0}catch(e){if(e?.code===`SYNC-001-NF`||e?.code===`NOT_FOUND`)return;throw e}}async create(e){let t=e.options;if(!t)throw Error(`Rule name is required for create`);let n=await this.client.post(`${S}/${encodeURIComponent(t)}`,e.data);if(n.data?.data)return{data:n.data.data,metadata:{}}}async update(e){let t=e.options;if(!t)throw Error(`Rule name is required for update`);let n=await this.client.patch(`${S}/${encodeURIComponent(t)}`,e.data);if(n.data?.data)return{data:n.data.data,metadata:{}}}async delete(e){await this.client.delete(`${S}/${encodeURIComponent(e)}`)}async validate(e){return(await this.client.post(`${S}/query`,{expression:e})).data?.data?.valid??!1}async reload(){return(await this.client.get(S)).data.data}async upload(e){throw Error(`Upload not supported for rules`)}async subscribe(e,t){throw Error(`Subscription not supported for rules`)}async notify(e){throw Error(`Notify not supported for rules`)}stream(e,t){throw Error(`Stream not supported for rules`)}page(e){throw Error(`Pagination not supported for rules`)}},w=class{client;baseUrl;pagerOptions={};pager;apiPrefix;constructor(e,t,r=`/api`){this.client=e,this.baseUrl=t,this.apiPrefix=r,this.pager=p(`_audit_log_`,new n.ReactiveDataStore({}),this.pagerOptions,e=>this.find(e))}async find(e){let t=await this.client.post(`/system/audit/log/query`,e??{}),n=t.data?.data??[];return{data:n,loading:!1,page:t.data?.metadata?.page??{number:1,size:n.length,count:n.length,total:n.length,pages:1},error:null}}async list(e){return this.find(e??{pagination:{type:`offset`,offset:0,limit:50}})}async read(e){throw Error(`Read by ID not supported for audit logs; use find with filters`)}async create(e){throw Error(`Audit logs are write-only; entries are created by the system`)}async update(e){throw Error(`Audit logs are append-only; updates are not allowed`)}async delete(e){throw Error(`Audit logs are append-only; deletion is not allowed`)}async upload(e){throw Error(`Upload not supported for audit logs`)}async subscribe(e,t){throw Error(`Use stream() for real-time audit log entries`)}async notify(e){throw Error(`Notify not supported for audit logs`)}stream(e,t){let n=this.getStreamUrl(),r=null,i=`active`,a=null,o=async function*(){let e=[];r=new EventSource(n,{withCredentials:!0}),r.onmessage=t=>{for(let n of t.data.split(`
8
+ `)){let t=n.trim();if(t)try{let n=JSON.parse(t);n?.data&&e.push(n.data)}catch{}}e.length>0&&a&&(a(),a=null)},r.onerror=()=>{i===`active`&&(i=`completed`),a&&=(a(),null)};try{for(;i===`active`;)e.length>0?yield e.shift():await new Promise(t=>{a=t,e.length>0&&(t(),a=null)})}finally{r?.close(),a&&=(a(),null),i===`active`&&(i=`completed`)}};return{stream:()=>o(),cancel:()=>{i===`active`&&(i=`cancelled`,r?.close())},status:()=>i}}page(e){return this.pager}getStreamUrl(){return`${this.baseUrl}${this.apiPrefix}/system/audit/log/stream`}};function T(e){return{_id_:e.key,_metadata_:{checksum:``,created:e.created_at,updated:e.updated_at??e.created_at,version:1},...e}}function E(e){return{number:1,size:e.length,count:e.length,total:e.length,pages:1}}var D=class{client;ns;pagerOptions={};pager;prefixFilter=``;constructor(e,t){this.client=e,this.ns=t,this.pager=p(`blobs_${t}`,new n.ReactiveDataStore({}),this.pagerOptions,e=>this.find(e))}name(){return this.ns}setPrefix(e){this.prefixFilter=e}basePath(){return`/system/blobs/blob/${encodeURIComponent(this.ns)}`}async find(e){let t=this.prefixFilter||e?.prefix||``,n=e?.limit??e?.pagination?.limit??0,r={};t&&(r.prefix=t),n&&(r.limit=n);let i=(await this.client.post(`${this.basePath()}/query`,r)).data?.data?.blobs??[];return{data:i.map(T),loading:!1,page:E(i),error:void 0}}async read(e){try{let t=await this.client.get(`${this.basePath()}/${encodeURIComponent(e)}`);return t.data?.data?T(t.data.data):void 0}catch(e){if(e?.code===`SYNC-001-NF`||e?.code===`INTERNAL_ERROR`&&typeof e?.message==`string`&&e.message.includes(`not found`))return;throw e}}async create(e){throw Error(`Use upload() to create blobs`)}async update(e){let t=e.options?.key;if(!t)throw Error(`options.key is required for blob update`);return T((await this.client.patch(`${this.basePath()}/${encodeURIComponent(t)}`,{custom:e.data})).data.data)}async delete(e){await this.client.delete(`${this.basePath()}/${encodeURIComponent(e)}`)}async list(e){return this.find(e??{})}async upload(e){let t=e.options?.key;if(!t)throw Error(`options.key is required for blob upload`);let n={},r=e.options?.contentType||e.file.type;return r&&(n[`Content-Type`]=r),T((await this.client.post(`${this.basePath()}/${encodeURIComponent(t)}`,e.file,{headers:n,bodyType:`blob`})).data.data)}async subscribe(e,t){throw Error(`Subscription not supported for blobs`)}async notify(e){throw Error(`Notify not supported for blobs`)}stream(e,t){throw Error(`Stream not supported for blobs`)}page(e){return this.pager}async download(e){let t=(await this.client.get(`${this.basePath()}/${encodeURIComponent(e)}`,{responseType:`blob`})).data;return{data:t,contentType:t.type}}},O=class{client;apiPrefix;constructor(e,t=`/api`){this.client=e,this.apiPrefix=t}nsBase=`/system/blobs`;async namespaces(){return(await this.client.post(`${this.nsBase}/namespace/query`)).data?.data?.namespaces??[]}async createNamespace(e){return(await this.client.post(`${this.nsBase}/namespace`,e)).data.data}async deleteNamespace(e){await this.client.delete(`${this.nsBase}/namespace/${encodeURIComponent(e)}`)}blob(e,t){return`${this.client.base()}${this.apiPrefix}${this.nsBase}/blob/${encodeURIComponent(e)}/${encodeURIComponent(t)}`}namespace(e){return new D(this.client,e)}},k=class{client;constructor(e){this.client=e}async find(e){let t=((await this.client.get(`/system/collections/collection`)).data?.data??[]).map(e=>({_id_:e.name,_metadata_:{checksum:``,created:e.created,updated:e.updated,version:1},name:e.name,schema:e.schema,created:e.created,updated:e.updated}));return{data:t,loading:!1,page:{number:1,size:t.length,count:t.length,total:t.length,pages:1}}}async read(e){try{let t=await this.client.get(`/system/collections/collection/${encodeURIComponent(e)}`);if(!t.data)return;let n=t.data.data;return{_id_:n.name,_metadata_:{checksum:``,created:n.created,updated:n.updated,version:1},name:n.name,schema:n.schema,created:n.created,updated:n.updated}}catch(e){if(e?.code===`SYNC-001-NF`)return;throw e}}async create(e){return(await this.client.post(`/system/collections/collection`,e.data)).data.data}async update(e){throw Error(`Collection update not implemented`)}async delete(e){await this.client.delete(`/system/collections/collection/${encodeURIComponent(e)}`)}async list(e){return this.find()}async upload(e){throw Error(`Upload not supported for collections`)}async subscribe(e,t){throw Error(`Subscription not supported for collections`)}async notify(e){throw Error(`Notify not supported for collections`)}stream(e,t){throw Error(`Stream not supported for collections`)}page(e){throw Error(`Pagination not supported for collection metadata; use documents(name)`)}documents(e){return new m(this.client,e)}},A=class{client;constructor(e){this.client=e}async find(e){let t=(await this.client.get(`/system/core/docs`)).data?.data??[];return{data:t,loading:!1,page:{number:1,size:t.length,count:t.length,total:t.length,pages:1}}}async read(e){throw Error(`Read by ID not supported for capabilities; use find()`)}async create(e){throw Error(`Capabilities are read-only`)}async update(e){throw Error(`Capabilities are read-only`)}async delete(e){throw Error(`Capabilities are read-only`)}async list(e){return this.find()}async upload(e){throw Error(`Upload not supported for capabilities`)}async subscribe(e,t){throw Error(`Subscription not supported for capabilities`)}async notify(e){throw Error(`Notify not supported for capabilities`)}stream(e,t){throw Error(`Stream not supported for capabilities`)}page(e){throw Error(`Pagination not supported for capabilities`)}},j=class{store;client;auth;users;keys;policies;logs;collections;blobs;capabilities;tokenProvider;onAuthStateChanged;constructor(e){this.store=new n.ReactiveDataStore({access:null,refresh:null,identity:null},e.persistence);let t={identity:()=>this.store.get().identity,token:e=>this.store.get()[e],setTokens:async(e,t)=>void await this.store.set({access:e,refresh:t}),setIdentity:async e=>void await this.store.set({identity:e}),clear:async()=>void await this.store.set({access:null,refresh:null})},r=e.apiPrefix??`/api`;this.tokenProvider=t,this.client=new d(e.baseUrl,r,t,()=>this.onAuthStateChanged?.()),this.auth=new h(this.client,t),this.users=new g(this.client),this.keys=new _(this.client),this.policies=new x(this.client),this.logs=new w(this.client,e.baseUrl,r),this.collections=new k(this.client),this.blobs=new O(this.client,r),this.capabilities=new A(this.client)}onAuthStateChange(e){this.onAuthStateChanged=e}authenticated(){return this.tokenProvider.token(`access`)!==null}collection(e){return this.collections.documents(e)}};function M(e){let t=`${e.collectionName}_array_pager_state_`,r=new n.ReactiveDataStore({}),a=[...e.initialData??[]],o=`collection`,s,c=e.page??1,l=e.size??20,u=[],d,f,{match:p}=(0,i.createMatcher)(e.customFunctions??{}),{sort:m}=(0,i.createSorter)(),h=r.select(e=>e[t]),g={data:[],loading:!0,error:void 0,page:{number:1,size:l,count:0,total:0,pages:1}},_=()=>({filters:d,sort:u,pagination:{type:`offset`,offset:(c-1)*l,limit:l}}),v=async(n=!0)=>{if(e.fetch){if(f=void 0,n){let e=h.get()??g;await r.set({[t]:{...e,loading:!0,error:void 0}})}try{let t=_(),n=await e.fetch(t);o=n.scope,s=n.total,a=n.replace?[...n.data]:[...a,...n.data]}catch(e){f=e}}let i=y(e.fetch?n:!1);await r.set({[t]:i})},y=e=>{let t=[...a];if(o===`collection`){d&&(t=t.filter(e=>p(e,d))),u.length>0&&(t=m(t,u));let n=t.length,r=Math.ceil(n/l)||1;c>r&&(c=r),c<1&&(c=1);let i=(c-1)*l,a=t.slice(i,i+l);return{data:a,loading:e,error:f,page:{number:c,size:l,count:a.length,total:n,pages:r}}}let n=s??t.length,r=Math.ceil(n/l)||1;return{data:t,loading:e,error:f,page:{number:c,size:l,count:t.length,total:n,pages:r}}};return v(!0),{id:()=>t,page:()=>h.get()??g,navigate:async e=>{if(e<1)throw Error(`Page number must be >= 1`);c=e,await v(!0)},resize:async(e,t)=>{if(e<1)throw Error(`Page size must be >= 1`);l=e,c=t,await v(!0)},sort:async e=>{u=Array.isArray(e)?e:[e],c=1,await v(!0)},filter:async e=>{d=e,c=1,await v(!0)},refresh:async e=>{let n=h.get()??g;await r.set({[t]:{...n,loading:!0}});let i=e?.delay??600;await Promise.all([new Promise(e=>setTimeout(e,i)),v(!1)]);let a=h.get()??g;await r.set({[t]:{...a,loading:!1}})},subscribe:e=>h.subscribe(t=>{e(t)}),invalidate:async()=>{await r.set({[t]:n.DELETE_SYMBOL}),a=[]}}}exports.BlobNamespace=D,exports.HestiaAuth=h,exports.HestiaBlobClient=O,exports.HestiaClient=j,exports.HestiaCollection=m,exports.HestiaCollections=k,exports.HestiaKeyStore=_,exports.HestiaLogs=w,exports.HestiaNetworkClient=d,exports.HestiaOperations=y,exports.HestiaPolicies=x,exports.HestiaResponse=u,exports.HestiaRules=C,exports.HestiaUsers=g,exports.createArrayPager=M,exports.createPagedController=p,exports.internalError=l,exports.notFound=s,exports.parseErrorBody=a,exports.permissionDenied=c,exports.toSystemError=o;
package/index.d.cts CHANGED
@@ -517,29 +517,104 @@ declare class HestiaKeyStore implements DocumentStore<APIKey, QueryDSL<APIKey>,
517
517
  rotate(id: string): Promise<Document<APIKeyWithSecret>>;
518
518
  }
519
519
  //#endregion
520
- //#region system/policies/types.d.ts
521
- interface OperationPolicy {
520
+ //#region system/operations/types.d.ts
521
+ interface Operation {
522
522
  name: string;
523
- ruleKey: string;
524
523
  description?: string;
525
- intentType?: "COMMAND" | "QUERY";
524
+ intentType?: string;
526
525
  }
527
- interface UpsertOperationRequest {
528
- ruleKey: string;
529
- description?: string;
530
- intentType?: "COMMAND" | "QUERY";
526
+ //#endregion
527
+ //#region system/operations/store.d.ts
528
+ declare class HestiaOperations {
529
+ private client;
530
+ constructor(client: HestiaNetworkClient);
531
+ list(): Promise<Page<Operation>>;
532
+ read(name: string): Promise<Document<Operation> | undefined>;
533
+ }
534
+ //#endregion
535
+ //#region system/policies/types.d.ts
536
+ interface Policy {
537
+ id: string;
538
+ operationName: string;
539
+ ruleName: string;
540
+ enabled: boolean;
541
+ protected: boolean;
542
+ }
543
+ interface CreatePolicyRequest {
544
+ ruleName: string;
545
+ }
546
+ interface UpdatePolicyRuleRequest {
547
+ ruleName: string;
548
+ }
549
+ interface SetPolicyEnabledRequest {
550
+ enabled: boolean;
531
551
  }
532
- interface IamRule {
552
+ //#endregion
553
+ //#region system/policies/store.d.ts
554
+ declare class HestiaPolicies implements DocumentStore<Policy, QueryDSL<Policy>, string, QueryDSL<Policy>, Record<string, unknown>, string, string, Record<string, unknown>> {
555
+ private client;
556
+ private pager;
557
+ constructor(client: HestiaNetworkClient);
558
+ find(_query?: QueryDSL<Policy>): Promise<Page<Policy>>;
559
+ query(qdsl: Record<string, unknown>): Promise<Page<Policy>>;
560
+ list(_options?: QueryDSL<Policy>): Promise<Page<Policy>>;
561
+ read(id: string): Promise<Document<Policy> | undefined>;
562
+ create(props: {
563
+ data: Partial<CreatePolicyRequest>;
564
+ options?: string;
565
+ }): Promise<Document<Policy> | undefined>;
566
+ update(props: {
567
+ data: UpdatePolicyRuleRequest;
568
+ options?: string;
569
+ }): Promise<Document<Policy> | undefined>;
570
+ setEnabled(name: string, enabled: boolean): Promise<Document<Policy>>;
571
+ delete(_id: string): Promise<void>;
572
+ upload(_props: {
573
+ file: File;
574
+ }): Promise<Document<Policy> | undefined>;
575
+ subscribe(_scope: string, _callback: (event: StoreEvent) => void): Promise<() => void>;
576
+ notify(_event: StoreEvent): Promise<void>;
577
+ stream(_options: Record<string, unknown>, _onStreamChange: () => void): {
578
+ stream: () => AsyncIterable<Document<Policy>>;
579
+ cancel: () => void;
580
+ status: () => "active" | "cancelled" | "completed";
581
+ };
582
+ page(_options?: Record<string, unknown>): PagedData<Policy>;
583
+ }
584
+ //#endregion
585
+ //#region system/rules/types.d.ts
586
+ interface PolicyRule {
587
+ id: string;
533
588
  name: string;
534
589
  ruleType?: string;
590
+ syntax?: string;
535
591
  expression?: string;
592
+ rules?: RuleNode;
536
593
  description?: string;
594
+ protected?: boolean;
537
595
  }
538
- interface UpsertRuleRequest {
539
- expression: string;
596
+ interface CreateRuleRequest {
540
597
  ruleType?: string;
598
+ syntax?: string;
599
+ expression?: string;
600
+ rules?: Record<string, unknown>;
541
601
  description?: string;
542
602
  }
603
+ interface UpdateRuleRequest {
604
+ ruleType?: string;
605
+ syntax?: string;
606
+ expression?: string;
607
+ rules?: Record<string, unknown>;
608
+ description?: string;
609
+ protected?: boolean;
610
+ }
611
+ interface RuleNode {
612
+ type?: string;
613
+ name?: string;
614
+ expression?: string;
615
+ operator?: string;
616
+ conditions?: RuleNode[];
617
+ }
543
618
  interface ValidateRuleRequest {
544
619
  expression: string;
545
620
  identity?: Record<string, unknown>;
@@ -548,7 +623,6 @@ interface ValidateRuleRequest {
548
623
  }
549
624
  interface ValidateRuleResult {
550
625
  valid: boolean;
551
- compile?: string;
552
626
  result?: boolean;
553
627
  }
554
628
  interface ReloadResult {
@@ -556,43 +630,35 @@ interface ReloadResult {
556
630
  rules: number;
557
631
  }
558
632
  //#endregion
559
- //#region system/policies/store.d.ts
560
- declare class HestiaPolicies implements DocumentStore<OperationPolicy, QueryDSL<OperationPolicy>, string, QueryDSL<OperationPolicy>, Record<string, unknown>, string, string, Record<string, unknown>> {
633
+ //#region system/rules/store.d.ts
634
+ declare class HestiaRules implements DocumentStore<PolicyRule, Record<string, unknown>, string, Record<string, unknown>, Record<string, unknown>, string, string, Record<string, unknown>> {
561
635
  private client;
562
- private pager;
563
- private operationsPath;
564
- private rulesPath;
565
636
  constructor(client: HestiaNetworkClient);
566
- private collectionQuery;
567
- find(query?: QueryDSL<OperationPolicy>): Promise<Page<OperationPolicy>>;
568
- list(options?: QueryDSL<OperationPolicy>): Promise<Page<OperationPolicy>>;
569
- read(id: string): Promise<Document<OperationPolicy> | undefined>;
637
+ find(_query?: Record<string, unknown>): Promise<Page<PolicyRule>>;
638
+ list(_options?: Record<string, unknown>): Promise<Page<PolicyRule>>;
639
+ read(id: string): Promise<Document<PolicyRule> | undefined>;
570
640
  create(props: {
571
- data: Partial<OperationPolicy>;
572
- }): Promise<Document<OperationPolicy> | undefined>;
641
+ data: Partial<CreateRuleRequest>;
642
+ options?: string;
643
+ }): Promise<Document<PolicyRule> | undefined>;
573
644
  update(props: {
574
- data: Partial<OperationPolicy>;
645
+ data: UpdateRuleRequest;
575
646
  options?: string;
576
- }): Promise<Document<OperationPolicy> | undefined>;
577
- delete(id: string): Promise<void>;
578
- upsertOperation(name: string, data: UpsertOperationRequest): Promise<Document<OperationPolicy>>;
579
- getRule(name: string): Promise<Document<IamRule> | undefined>;
580
- upsertRule(name: string, data: UpsertRuleRequest): Promise<Document<IamRule>>;
581
- deleteRule(name: string): Promise<void>;
582
- listRules(options?: Record<string, unknown>): Promise<Page<IamRule>>;
583
- validateRule(expression: string): Promise<boolean>;
647
+ }): Promise<Document<PolicyRule> | undefined>;
648
+ delete(name: string): Promise<void>;
649
+ validate(expression: string): Promise<boolean>;
584
650
  reload(): Promise<ReloadResult>;
585
651
  upload(_props: {
586
652
  file: File;
587
- }): Promise<Document<OperationPolicy> | undefined>;
653
+ }): Promise<Document<PolicyRule> | undefined>;
588
654
  subscribe(_scope: string, _callback: (event: StoreEvent) => void): Promise<() => void>;
589
655
  notify(_event: StoreEvent): Promise<void>;
590
656
  stream(_options: Record<string, unknown>, _onStreamChange: () => void): {
591
- stream: () => AsyncIterable<Document<OperationPolicy>>;
657
+ stream: () => AsyncIterable<Document<PolicyRule>>;
592
658
  cancel: () => void;
593
659
  status: () => "active" | "cancelled" | "completed";
594
660
  };
595
- page(_options?: Record<string, unknown>): PagedData<OperationPolicy>;
661
+ page(_options?: Record<string, unknown>): any;
596
662
  }
597
663
  //#endregion
598
664
  //#region system/logs/types.d.ts
@@ -917,4 +983,4 @@ interface ArrayPagerOptions<T extends Record<string, any>, F = any> {
917
983
  }
918
984
  declare function createArrayPager<T extends Record<string, any>, F = any>(options: ArrayPagerOptions<T, F>): PagedData<T>;
919
985
  //#endregion
920
- export { APIKey, APIKeyWithSecret, ArrayPagerOptions, AuditEntry, BlobDocument, BlobMeta, BlobNamespace, BootstrapPasswordRequest, ChangePasswordRequest, CollectionDocument, CollectionMeta, CreateKeyRequest, CreateNamespaceRequest, CreateUserRequest, Document, DocumentStore, FetchResult, HestiaAuth, HestiaBlobClient, HestiaClient, HestiaCollection, HestiaCollections, HestiaKeyStore, HestiaLogs, HestiaNetworkClient, HestiaPolicies, HestiaResponse, HestiaUsers, IamRule, IdentityProvider, ListBlobsRequest, LogFilter, LoginRequest, LoginResult, NamespaceInfo, OperationPolicy, Page, PagedData, PagerRefreshOptions, PaginationInfo, RefreshRequest, RegisterRequest, ReloadResult, RequestLogEntry, ServerHealth, StoreEvent, StreamHandlers, StreamOptions, TokenPair, UpdateKeyRequest, UpdateUserRequest, UpsertOperationRequest, UpsertRuleRequest, UserData, UserIdentity, ValidateRuleRequest, ValidateRuleResult, createArrayPager, createPagedController, internalError, notFound, parseErrorBody, permissionDenied, toSystemError };
986
+ export { APIKey, APIKeyWithSecret, ArrayPagerOptions, AuditEntry, BlobDocument, BlobMeta, BlobNamespace, BootstrapPasswordRequest, ChangePasswordRequest, CollectionDocument, CollectionMeta, CreateKeyRequest, CreateNamespaceRequest, CreatePolicyRequest, CreateRuleRequest, CreateUserRequest, Document, DocumentStore, FetchResult, HestiaAuth, HestiaBlobClient, HestiaClient, HestiaCollection, HestiaCollections, HestiaKeyStore, HestiaLogs, HestiaNetworkClient, HestiaOperations, HestiaPolicies, HestiaResponse, HestiaRules, HestiaUsers, IdentityProvider, ListBlobsRequest, LogFilter, LoginRequest, LoginResult, NamespaceInfo, Operation, Page, PagedData, PagerRefreshOptions, PaginationInfo, Policy, PolicyRule, RefreshRequest, RegisterRequest, ReloadResult, RequestLogEntry, RuleNode, ServerHealth, SetPolicyEnabledRequest, StoreEvent, StreamHandlers, StreamOptions, TokenPair, UpdateKeyRequest, UpdatePolicyRuleRequest, UpdateRuleRequest, UpdateUserRequest, UserData, UserIdentity, ValidateRuleRequest, ValidateRuleResult, createArrayPager, createPagedController, internalError, notFound, parseErrorBody, permissionDenied, toSystemError };
package/index.d.mts CHANGED
@@ -517,29 +517,104 @@ declare class HestiaKeyStore implements DocumentStore<APIKey, QueryDSL<APIKey>,
517
517
  rotate(id: string): Promise<Document<APIKeyWithSecret>>;
518
518
  }
519
519
  //#endregion
520
- //#region system/policies/types.d.ts
521
- interface OperationPolicy {
520
+ //#region system/operations/types.d.ts
521
+ interface Operation {
522
522
  name: string;
523
- ruleKey: string;
524
523
  description?: string;
525
- intentType?: "COMMAND" | "QUERY";
524
+ intentType?: string;
526
525
  }
527
- interface UpsertOperationRequest {
528
- ruleKey: string;
529
- description?: string;
530
- intentType?: "COMMAND" | "QUERY";
526
+ //#endregion
527
+ //#region system/operations/store.d.ts
528
+ declare class HestiaOperations {
529
+ private client;
530
+ constructor(client: HestiaNetworkClient);
531
+ list(): Promise<Page<Operation>>;
532
+ read(name: string): Promise<Document<Operation> | undefined>;
533
+ }
534
+ //#endregion
535
+ //#region system/policies/types.d.ts
536
+ interface Policy {
537
+ id: string;
538
+ operationName: string;
539
+ ruleName: string;
540
+ enabled: boolean;
541
+ protected: boolean;
542
+ }
543
+ interface CreatePolicyRequest {
544
+ ruleName: string;
545
+ }
546
+ interface UpdatePolicyRuleRequest {
547
+ ruleName: string;
548
+ }
549
+ interface SetPolicyEnabledRequest {
550
+ enabled: boolean;
531
551
  }
532
- interface IamRule {
552
+ //#endregion
553
+ //#region system/policies/store.d.ts
554
+ declare class HestiaPolicies implements DocumentStore<Policy, QueryDSL<Policy>, string, QueryDSL<Policy>, Record<string, unknown>, string, string, Record<string, unknown>> {
555
+ private client;
556
+ private pager;
557
+ constructor(client: HestiaNetworkClient);
558
+ find(_query?: QueryDSL<Policy>): Promise<Page<Policy>>;
559
+ query(qdsl: Record<string, unknown>): Promise<Page<Policy>>;
560
+ list(_options?: QueryDSL<Policy>): Promise<Page<Policy>>;
561
+ read(id: string): Promise<Document<Policy> | undefined>;
562
+ create(props: {
563
+ data: Partial<CreatePolicyRequest>;
564
+ options?: string;
565
+ }): Promise<Document<Policy> | undefined>;
566
+ update(props: {
567
+ data: UpdatePolicyRuleRequest;
568
+ options?: string;
569
+ }): Promise<Document<Policy> | undefined>;
570
+ setEnabled(name: string, enabled: boolean): Promise<Document<Policy>>;
571
+ delete(_id: string): Promise<void>;
572
+ upload(_props: {
573
+ file: File;
574
+ }): Promise<Document<Policy> | undefined>;
575
+ subscribe(_scope: string, _callback: (event: StoreEvent) => void): Promise<() => void>;
576
+ notify(_event: StoreEvent): Promise<void>;
577
+ stream(_options: Record<string, unknown>, _onStreamChange: () => void): {
578
+ stream: () => AsyncIterable<Document<Policy>>;
579
+ cancel: () => void;
580
+ status: () => "active" | "cancelled" | "completed";
581
+ };
582
+ page(_options?: Record<string, unknown>): PagedData<Policy>;
583
+ }
584
+ //#endregion
585
+ //#region system/rules/types.d.ts
586
+ interface PolicyRule {
587
+ id: string;
533
588
  name: string;
534
589
  ruleType?: string;
590
+ syntax?: string;
535
591
  expression?: string;
592
+ rules?: RuleNode;
536
593
  description?: string;
594
+ protected?: boolean;
537
595
  }
538
- interface UpsertRuleRequest {
539
- expression: string;
596
+ interface CreateRuleRequest {
540
597
  ruleType?: string;
598
+ syntax?: string;
599
+ expression?: string;
600
+ rules?: Record<string, unknown>;
541
601
  description?: string;
542
602
  }
603
+ interface UpdateRuleRequest {
604
+ ruleType?: string;
605
+ syntax?: string;
606
+ expression?: string;
607
+ rules?: Record<string, unknown>;
608
+ description?: string;
609
+ protected?: boolean;
610
+ }
611
+ interface RuleNode {
612
+ type?: string;
613
+ name?: string;
614
+ expression?: string;
615
+ operator?: string;
616
+ conditions?: RuleNode[];
617
+ }
543
618
  interface ValidateRuleRequest {
544
619
  expression: string;
545
620
  identity?: Record<string, unknown>;
@@ -548,7 +623,6 @@ interface ValidateRuleRequest {
548
623
  }
549
624
  interface ValidateRuleResult {
550
625
  valid: boolean;
551
- compile?: string;
552
626
  result?: boolean;
553
627
  }
554
628
  interface ReloadResult {
@@ -556,43 +630,35 @@ interface ReloadResult {
556
630
  rules: number;
557
631
  }
558
632
  //#endregion
559
- //#region system/policies/store.d.ts
560
- declare class HestiaPolicies implements DocumentStore<OperationPolicy, QueryDSL<OperationPolicy>, string, QueryDSL<OperationPolicy>, Record<string, unknown>, string, string, Record<string, unknown>> {
633
+ //#region system/rules/store.d.ts
634
+ declare class HestiaRules implements DocumentStore<PolicyRule, Record<string, unknown>, string, Record<string, unknown>, Record<string, unknown>, string, string, Record<string, unknown>> {
561
635
  private client;
562
- private pager;
563
- private operationsPath;
564
- private rulesPath;
565
636
  constructor(client: HestiaNetworkClient);
566
- private collectionQuery;
567
- find(query?: QueryDSL<OperationPolicy>): Promise<Page<OperationPolicy>>;
568
- list(options?: QueryDSL<OperationPolicy>): Promise<Page<OperationPolicy>>;
569
- read(id: string): Promise<Document<OperationPolicy> | undefined>;
637
+ find(_query?: Record<string, unknown>): Promise<Page<PolicyRule>>;
638
+ list(_options?: Record<string, unknown>): Promise<Page<PolicyRule>>;
639
+ read(id: string): Promise<Document<PolicyRule> | undefined>;
570
640
  create(props: {
571
- data: Partial<OperationPolicy>;
572
- }): Promise<Document<OperationPolicy> | undefined>;
641
+ data: Partial<CreateRuleRequest>;
642
+ options?: string;
643
+ }): Promise<Document<PolicyRule> | undefined>;
573
644
  update(props: {
574
- data: Partial<OperationPolicy>;
645
+ data: UpdateRuleRequest;
575
646
  options?: string;
576
- }): Promise<Document<OperationPolicy> | undefined>;
577
- delete(id: string): Promise<void>;
578
- upsertOperation(name: string, data: UpsertOperationRequest): Promise<Document<OperationPolicy>>;
579
- getRule(name: string): Promise<Document<IamRule> | undefined>;
580
- upsertRule(name: string, data: UpsertRuleRequest): Promise<Document<IamRule>>;
581
- deleteRule(name: string): Promise<void>;
582
- listRules(options?: Record<string, unknown>): Promise<Page<IamRule>>;
583
- validateRule(expression: string): Promise<boolean>;
647
+ }): Promise<Document<PolicyRule> | undefined>;
648
+ delete(name: string): Promise<void>;
649
+ validate(expression: string): Promise<boolean>;
584
650
  reload(): Promise<ReloadResult>;
585
651
  upload(_props: {
586
652
  file: File;
587
- }): Promise<Document<OperationPolicy> | undefined>;
653
+ }): Promise<Document<PolicyRule> | undefined>;
588
654
  subscribe(_scope: string, _callback: (event: StoreEvent) => void): Promise<() => void>;
589
655
  notify(_event: StoreEvent): Promise<void>;
590
656
  stream(_options: Record<string, unknown>, _onStreamChange: () => void): {
591
- stream: () => AsyncIterable<Document<OperationPolicy>>;
657
+ stream: () => AsyncIterable<Document<PolicyRule>>;
592
658
  cancel: () => void;
593
659
  status: () => "active" | "cancelled" | "completed";
594
660
  };
595
- page(_options?: Record<string, unknown>): PagedData<OperationPolicy>;
661
+ page(_options?: Record<string, unknown>): any;
596
662
  }
597
663
  //#endregion
598
664
  //#region system/logs/types.d.ts
@@ -917,4 +983,4 @@ interface ArrayPagerOptions<T extends Record<string, any>, F = any> {
917
983
  }
918
984
  declare function createArrayPager<T extends Record<string, any>, F = any>(options: ArrayPagerOptions<T, F>): PagedData<T>;
919
985
  //#endregion
920
- export { APIKey, APIKeyWithSecret, ArrayPagerOptions, AuditEntry, BlobDocument, BlobMeta, BlobNamespace, BootstrapPasswordRequest, ChangePasswordRequest, CollectionDocument, CollectionMeta, CreateKeyRequest, CreateNamespaceRequest, CreateUserRequest, Document, DocumentStore, FetchResult, HestiaAuth, HestiaBlobClient, HestiaClient, HestiaCollection, HestiaCollections, HestiaKeyStore, HestiaLogs, HestiaNetworkClient, HestiaPolicies, HestiaResponse, HestiaUsers, IamRule, IdentityProvider, ListBlobsRequest, LogFilter, LoginRequest, LoginResult, NamespaceInfo, OperationPolicy, Page, PagedData, PagerRefreshOptions, PaginationInfo, RefreshRequest, RegisterRequest, ReloadResult, RequestLogEntry, ServerHealth, StoreEvent, StreamHandlers, StreamOptions, TokenPair, UpdateKeyRequest, UpdateUserRequest, UpsertOperationRequest, UpsertRuleRequest, UserData, UserIdentity, ValidateRuleRequest, ValidateRuleResult, createArrayPager, createPagedController, internalError, notFound, parseErrorBody, permissionDenied, toSystemError };
986
+ export { APIKey, APIKeyWithSecret, ArrayPagerOptions, AuditEntry, BlobDocument, BlobMeta, BlobNamespace, BootstrapPasswordRequest, ChangePasswordRequest, CollectionDocument, CollectionMeta, CreateKeyRequest, CreateNamespaceRequest, CreatePolicyRequest, CreateRuleRequest, CreateUserRequest, Document, DocumentStore, FetchResult, HestiaAuth, HestiaBlobClient, HestiaClient, HestiaCollection, HestiaCollections, HestiaKeyStore, HestiaLogs, HestiaNetworkClient, HestiaOperations, HestiaPolicies, HestiaResponse, HestiaRules, HestiaUsers, IdentityProvider, ListBlobsRequest, LogFilter, LoginRequest, LoginResult, NamespaceInfo, Operation, Page, PagedData, PagerRefreshOptions, PaginationInfo, Policy, PolicyRule, RefreshRequest, RegisterRequest, ReloadResult, RequestLogEntry, RuleNode, ServerHealth, SetPolicyEnabledRequest, StoreEvent, StreamHandlers, StreamOptions, TokenPair, UpdateKeyRequest, UpdatePolicyRuleRequest, UpdateRuleRequest, UpdateUserRequest, UserData, UserIdentity, ValidateRuleRequest, ValidateRuleResult, createArrayPager, createPagedController, internalError, notFound, parseErrorBody, permissionDenied, toSystemError };
package/index.mjs CHANGED
@@ -4,5 +4,5 @@ import{createNetworkClient as e}from"@asaidimu/network-client";import{Errors as
4
4
  `).filter(e=>e.startsWith(`data:`)).map(e=>e.slice(5).trim());n.length>0&&t.onMessage(n.join(`
5
5
  `)),r=p.indexOf(`
6
6
 
7
- `)}}}catch(e){e instanceof Error&&e.name===`AbortError`||t.onError?.(e instanceof Error?e:Error(String(e)))}finally{t.onClose?.()}};return i(!1)}};const h={data:[],loading:!0,page:{number:1,size:20,count:0,total:0,pages:1}};function g(e,t,n,i){let o=n.page??1,s=n.size??20,c=n.sort,l=n.filter,u=new a({delay:50}),d=`${e}_pager_state_`;t.set({[d]:{data:[],loading:!1,error:r,page:{number:1,size:20,count:0,total:0,pages:1}}});let f=e=>{let t=e?.page??o,n=e?.size??s,r={pagination:{type:`offset`,offset:(t-1)*n,limit:n}},i=e?.sort??c;i&&(r.sort=Array.isArray(i)?i:[i]);let a=e?.filter??l;return a&&(r.filters=a),r},p=async e=>(await t.set({[d]:{loading:!0,error:r}}),await new Promise(n=>{n(u.do(async()=>{requestIdleCallback(()=>{requestIdleCallback(async()=>{try{let n=await i(f(e));await t.set({[d]:n})}catch(e){await t.set({[d]:{...h,error:e}})}finally{await t.set({[d]:{loading:!1}})}})})}))})),m=t.select(e=>e[d]),g=m.subscribe(()=>{});return{page:()=>m.get()??h,navigate:async e=>{if(e<1)throw Error(`Page number must be >= 1`);o=e,await p({page:e})},resize:async(e,t)=>{if(e<1)throw Error(`Page size must be >= 1`);s=e,o=t,await p()},sort:async e=>{c=Array.isArray(e)?e:[e],o=1,await p()},filter:async e=>{l=e,o=1,await p()},refresh:async e=>{await Promise.all([new Promise(t=>setTimeout(t,e?.delay||0)),p(e)])},subscribe:e=>m.subscribe(e),invalidate:async()=>{await t.set({[d]:r}),g()},id:()=>d}}var _=class{client;collectionName;defaultLimit;pagerOptions={};pager;constructor(e,t,n=50){this.client=e,this.collectionName=t,this.defaultLimit=n,this.pager=g(t,new i({}),this.pagerOptions,e=>this.find(e))}name(){return this.collectionName}get queryPath(){return`/system/collections/document/${encodeURIComponent(this.collectionName)}/query`}get documentsPath(){return`/system/collections/document/${encodeURIComponent(this.collectionName)}`}documentPath(e){return`${this.documentsPath}/${encodeURIComponent(e)}`}async find(e){let t=await this.client.post(this.queryPath,e??{}),n=t.data?.data??[];return{data:n,loading:!1,page:t.data?.metadata?.page??{number:1,size:n.length,count:n.length,total:n.length,pages:1},error:null}}async read(e){try{return(await this.client.get(this.documentPath(e))).data?.data}catch(e){if(e?.code===`SYNC-001-NF`||e?.code===`NOT_FOUND`)return;throw e}}async create(e){return(await this.client.post(this.documentsPath,e.data)).data.data}async update(e){let t=e.options;return(await this.client.patch(this.documentPath(t),e.data)).data.data}async delete(e){await this.client.delete(this.documentPath(e))}async list(e){return this.find(e??{pagination:{type:`offset`,offset:0,limit:this.defaultLimit}})}async upload(e){throw Error(`Upload not supported for collections`)}async subscribe(e,t){throw Error(`Subscription not implemented for dynamic collections`)}async notify(e){throw Error(`Notify not implemented for dynamic collections`)}stream(e,t){throw Error(`Stream not supported for collections`)}page(e){return this.pager}},v=class{client;provider;constructor(e,t){this.client=e,this.provider=t}async health(){return(await this.client.get(`/system/core/health`)).data.data}async login(e,t){let n=(await this.client.post(`/system/auth/session`,{email:e,password:t})).data.data;return this.provider.setIdentity(n.user),this.client.storeTokens(n.token.access,n.token.refresh),n}async register(e,t,n){return(await this.client.post(`/system/auth/user`,{email:e,password:t,name:n})).data.data}async refresh(e){let t=e?{refresh_token:e}:{};return(await this.client.patch(`/system/auth/session`,t)).data.data.token}async logout(){let e=this.provider.token(`refresh`),t=e?{refresh_token:e}:{};await this.client.delete(`/system/auth/session`,t),await this.provider.clear()}async requestPasswordReset(e){await this.client.post(`/system/auth/password`,{email:e})}async confirmPasswordReset(e,t){await this.client.patch(`/system/auth/password`,{password:t,token:e},{headers:{Authorization:`Bearer ${e}`}})}async bootstrap(e,t,n){await this.client.patch(`/system/auth/bootstrap`,{password:t,email:n},{headers:{"X-API-Key":e}})}},y=class{client;pagerOptions={};pager;constructor(e){this.client=e,this.pager=g(`users`,new i({}),this.pagerOptions,e=>this.find(e))}name(){return`users`}async find(e){let t=await this.client.post(`/system/users/user/query`,e??{}),n=t.data?.data??[];return{data:n,loading:!1,page:t.data?.metadata?.page??{number:1,size:n.length,count:n.length,total:n.length,pages:1}}}async list(e){return this.find(e??{pagination:{type:`offset`,offset:0,limit:50}})}async read(e){try{return(await this.client.get(`/system/users/user/${encodeURIComponent(e)}`)).data?.data}catch(e){if(e?.code===`SYNC-001-NF`)return;throw e}}async update(e){let t=e.options;return(await this.client.patch(`/system/users/user/${encodeURIComponent(t)}`,e.data)).data.data}async delete(e){await this.client.delete(`/system/users/user/${encodeURIComponent(e)}`)}async create(e){throw Error(`User creation requires email/password/name, use register endpoint`)}async upload(e){throw Error(`Upload not supported for users`)}async subscribe(e,t){throw Error(`Subscription not supported for users`)}async notify(e){throw Error(`Notify not supported for users`)}stream(e,t){throw Error(`Stream not supported for users`)}page(e){return this.pager}async changePassword(e,t,n){await this.client.patch(`/system/users/password/${encodeURIComponent(e)}`,{current:t,new:n})}},b=class{client;pager;constructor(e){this.client=e,this.pager=g(`_api_key_`,new i({}),{},e=>this.find(e))}basePath=`/system/apikeys/key`;async find(e){let t=await this.client.get(this.basePath),n=t.data?.data??[];return{data:n,loading:!1,page:t.data?.metadata?.page??{number:1,size:n.length,count:n.length,total:n.length,pages:1}}}async list(e){return e?this.find(e):this.find()}async read(e){try{return(await this.client.get(`${this.basePath}/${encodeURIComponent(e)}`)).data?.data}catch(e){if(e?.code===`SYNC-001-NF`||e?.code===`INTERNAL_ERROR`&&typeof e?.message==`string`&&e.message.includes(`not found`))return;throw e}}async create(e){return(await this.client.post(this.basePath,e.data)).data.data}async update(e){let t=e.options;return(await this.client.patch(`${this.basePath}/${encodeURIComponent(t)}`,e.data)).data.data}async delete(e){await this.client.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async upload(e){throw Error(`Upload not supported for API keys`)}async subscribe(e,t){throw Error(`Subscription not supported for API keys`)}async notify(e){throw Error(`Notify not supported for API keys`)}stream(e,t){throw Error(`Stream not supported for API keys`)}page(e){return this.pager}async rotate(e){return(await this.client.post(`${this.basePath}/${encodeURIComponent(e)}`)).data.data}},x=class{client;pager;operationsPath=`/system/policies/operation`;rulesPath=`/system/policies/rule`;constructor(e){this.client=e,this.pager=g(`policies`,new i({}),{},e=>this.find(e))}async collectionQuery(e,t){let n=await this.client.post(`/system/collections/document/${encodeURIComponent(e)}/query`,t??{}),r=n.data?.data??[];return{data:r,loading:!1,page:n.data?.metadata?.page??{number:1,size:r.length,count:r.length,total:r.length,pages:1},error:null}}async find(e){return this.collectionQuery(`_operation_policy_`,e)}async list(e){return this.find(e??{pagination:{type:`offset`,offset:0,limit:50}})}async read(e){try{return(await this.client.get(`${this.operationsPath}/${encodeURIComponent(e)}`)).data?.data}catch(e){if(e?.code===`SYNC-001-NF`||e?.code===`NOT_FOUND`||e?.code===`INTERNAL_ERROR`&&typeof e?.message==`string`&&e.message.includes(`not found`))return;throw e}}async create(e){let t=e.data.name;if(!t)throw Error(`Operation name is required for create`);return(await this.client.patch(`${this.operationsPath}/${encodeURIComponent(t)}`,e.data)).data.data}async update(e){let t=e.options;if(!t)throw Error(`Operation name is required for update`);return(await this.client.patch(`${this.operationsPath}/${encodeURIComponent(t)}`,e.data)).data.data}async delete(e){await this.client.delete(`${this.operationsPath}/${encodeURIComponent(e)}`)}async upsertOperation(e,t){return(await this.client.patch(`${this.operationsPath}/${encodeURIComponent(e)}`,t)).data.data}async getRule(e){try{return(await this.client.get(`${this.rulesPath}/${encodeURIComponent(e)}`)).data?.data}catch(e){if(e?.code===`SYNC-001-NF`||e?.code===`NOT_FOUND`||e?.code===`INTERNAL_ERROR`&&typeof e?.message==`string`&&e.message.includes(`not found`))return;throw e}}async upsertRule(e,t){return(await this.client.patch(`${this.rulesPath}/${encodeURIComponent(e)}`,t)).data.data}async deleteRule(e){await this.client.delete(`${this.rulesPath}/${encodeURIComponent(e)}`)}async listRules(e){return this.collectionQuery(`_iam_rule_`,e)}async validateRule(e){return(await this.client.post(`${this.rulesPath}/validate`,{expression:e})).data?.data?.valid??!1}async reload(){return(await this.client.get(`${this.rulesPath}/reload`)).data.data}async upload(e){throw Error(`Upload not supported for policies`)}async subscribe(e,t){throw Error(`Subscription not supported for policies`)}async notify(e){throw Error(`Notify not supported for policies`)}stream(e,t){throw Error(`Stream not supported for policies`)}page(e){return this.pager}},S=class{client;baseUrl;pagerOptions={};pager;apiPrefix;constructor(e,t,n=`/api`){this.client=e,this.baseUrl=t,this.apiPrefix=n,this.pager=g(`_audit_log_`,new i({}),this.pagerOptions,e=>this.find(e))}async find(e){let t=await this.client.post(`/system/audit/log/query`,e??{}),n=t.data?.data??[];return{data:n,loading:!1,page:t.data?.metadata?.page??{number:1,size:n.length,count:n.length,total:n.length,pages:1},error:null}}async list(e){return this.find(e??{pagination:{type:`offset`,offset:0,limit:50}})}async read(e){throw Error(`Read by ID not supported for audit logs; use find with filters`)}async create(e){throw Error(`Audit logs are write-only; entries are created by the system`)}async update(e){throw Error(`Audit logs are append-only; updates are not allowed`)}async delete(e){throw Error(`Audit logs are append-only; deletion is not allowed`)}async upload(e){throw Error(`Upload not supported for audit logs`)}async subscribe(e,t){throw Error(`Use stream() for real-time audit log entries`)}async notify(e){throw Error(`Notify not supported for audit logs`)}stream(e,t){let n=this.getStreamUrl(),r=null,i=`active`,a=null,o=async function*(){let e=[];r=new EventSource(n,{withCredentials:!0}),r.onmessage=t=>{for(let n of t.data.split(`
8
- `)){let t=n.trim();if(t)try{let n=JSON.parse(t);n?.data&&e.push(n.data)}catch{}}e.length>0&&a&&(a(),a=null)},r.onerror=()=>{i===`active`&&(i=`completed`),a&&=(a(),null)};try{for(;i===`active`;)e.length>0?yield e.shift():await new Promise(t=>{a=t,e.length>0&&(t(),a=null)})}finally{r?.close(),a&&=(a(),null),i===`active`&&(i=`completed`)}};return{stream:()=>o(),cancel:()=>{i===`active`&&(i=`cancelled`,r?.close())},status:()=>i}}page(e){return this.pager}getStreamUrl(){return`${this.baseUrl}${this.apiPrefix}/system/audit/log/stream`}};function C(e){return{_id_:e.key,_metadata_:{checksum:``,created:e.created_at,updated:e.updated_at??e.created_at,version:1},...e}}function w(e){return{number:1,size:e.length,count:e.length,total:e.length,pages:1}}var T=class{client;ns;pagerOptions={};pager;prefixFilter=``;constructor(e,t){this.client=e,this.ns=t,this.pager=g(`blobs_${t}`,new i({}),this.pagerOptions,e=>this.find(e))}name(){return this.ns}setPrefix(e){this.prefixFilter=e}basePath(){return`/system/blobs/blob/${encodeURIComponent(this.ns)}`}async find(e){let t=this.prefixFilter||e?.prefix||``,n=e?.limit??e?.pagination?.limit??0,r={};t&&(r.prefix=t),n&&(r.limit=n);let i=(await this.client.post(`${this.basePath()}/query`,r)).data?.data?.blobs??[];return{data:i.map(C),loading:!1,page:w(i),error:void 0}}async read(e){try{let t=await this.client.get(`${this.basePath()}/${encodeURIComponent(e)}`);return t.data?.data?C(t.data.data):void 0}catch(e){if(e?.code===`SYNC-001-NF`||e?.code===`INTERNAL_ERROR`&&typeof e?.message==`string`&&e.message.includes(`not found`))return;throw e}}async create(e){throw Error(`Use upload() to create blobs`)}async update(e){let t=e.options?.key;if(!t)throw Error(`options.key is required for blob update`);return C((await this.client.patch(`${this.basePath()}/${encodeURIComponent(t)}`,{custom:e.data})).data.data)}async delete(e){await this.client.delete(`${this.basePath()}/${encodeURIComponent(e)}`)}async list(e){return this.find(e??{})}async upload(e){let t=e.options?.key;if(!t)throw Error(`options.key is required for blob upload`);let n={},r=e.options?.contentType||e.file.type;return r&&(n[`Content-Type`]=r),C((await this.client.post(`${this.basePath()}/${encodeURIComponent(t)}`,e.file,{headers:n,bodyType:`blob`})).data.data)}async subscribe(e,t){throw Error(`Subscription not supported for blobs`)}async notify(e){throw Error(`Notify not supported for blobs`)}stream(e,t){throw Error(`Stream not supported for blobs`)}page(e){return this.pager}async download(e){let t=(await this.client.get(`${this.basePath()}/${encodeURIComponent(e)}`,{responseType:`blob`})).data;return{data:t,contentType:t.type}}},E=class{client;apiPrefix;constructor(e,t=`/api`){this.client=e,this.apiPrefix=t}nsBase=`/system/blobs`;async namespaces(){return(await this.client.post(`${this.nsBase}/namespace/query`)).data?.data?.namespaces??[]}async createNamespace(e){return(await this.client.post(`${this.nsBase}/namespace`,e)).data.data}async deleteNamespace(e){await this.client.delete(`${this.nsBase}/namespace/${encodeURIComponent(e)}`)}blob(e,t){return`${this.client.base()}${this.apiPrefix}${this.nsBase}/blob/${encodeURIComponent(e)}/${encodeURIComponent(t)}`}namespace(e){return new T(this.client,e)}},D=class{client;constructor(e){this.client=e}async find(e){let t=((await this.client.get(`/system/collections/collection`)).data?.data??[]).map(e=>({_id_:e.name,_metadata_:{checksum:``,created:e.created,updated:e.updated,version:1},name:e.name,schema:e.schema,created:e.created,updated:e.updated}));return{data:t,loading:!1,page:{number:1,size:t.length,count:t.length,total:t.length,pages:1}}}async read(e){try{let t=await this.client.get(`/system/collections/collection/${encodeURIComponent(e)}`);if(!t.data)return;let n=t.data.data;return{_id_:n.name,_metadata_:{checksum:``,created:n.created,updated:n.updated,version:1},name:n.name,schema:n.schema,created:n.created,updated:n.updated}}catch(e){if(e?.code===`SYNC-001-NF`)return;throw e}}async create(e){return(await this.client.post(`/system/collections/collection`,e.data)).data.data}async update(e){throw Error(`Collection update not implemented`)}async delete(e){await this.client.delete(`/system/collections/collection/${encodeURIComponent(e)}`)}async list(e){return this.find()}async upload(e){throw Error(`Upload not supported for collections`)}async subscribe(e,t){throw Error(`Subscription not supported for collections`)}async notify(e){throw Error(`Notify not supported for collections`)}stream(e,t){throw Error(`Stream not supported for collections`)}page(e){throw Error(`Pagination not supported for collection metadata; use documents(name)`)}documents(e){return new _(this.client,e)}},O=class{client;constructor(e){this.client=e}async find(e){let t=(await this.client.get(`/system/core/docs`)).data?.data??[];return{data:t,loading:!1,page:{number:1,size:t.length,count:t.length,total:t.length,pages:1}}}async read(e){throw Error(`Read by ID not supported for capabilities; use find()`)}async create(e){throw Error(`Capabilities are read-only`)}async update(e){throw Error(`Capabilities are read-only`)}async delete(e){throw Error(`Capabilities are read-only`)}async list(e){return this.find()}async upload(e){throw Error(`Upload not supported for capabilities`)}async subscribe(e,t){throw Error(`Subscription not supported for capabilities`)}async notify(e){throw Error(`Notify not supported for capabilities`)}stream(e,t){throw Error(`Stream not supported for capabilities`)}page(e){throw Error(`Pagination not supported for capabilities`)}},k=class{store;client;auth;users;keys;policies;logs;collections;blobs;capabilities;tokenProvider;onAuthStateChanged;constructor(e){this.store=new i({access:null,refresh:null,identity:null},e.persistence);let t={identity:()=>this.store.get().identity,token:e=>this.store.get()[e],setTokens:async(e,t)=>void await this.store.set({access:e,refresh:t}),setIdentity:async e=>void await this.store.set({identity:e}),clear:async()=>void await this.store.set({access:null,refresh:null})},n=e.apiPrefix??`/api`;this.tokenProvider=t,this.client=new m(e.baseUrl,n,t,()=>this.onAuthStateChanged?.()),this.auth=new v(this.client,t),this.users=new y(this.client),this.keys=new b(this.client),this.policies=new x(this.client),this.logs=new S(this.client,e.baseUrl,n),this.collections=new D(this.client),this.blobs=new E(this.client,n),this.capabilities=new O(this.client)}onAuthStateChange(e){this.onAuthStateChanged=e}authenticated(){return this.tokenProvider.token(`access`)!==null}collection(e){return this.collections.documents(e)}};function A(e){let t=`${e.collectionName}_array_pager_state_`,n=new i({}),a=[...e.initialData??[]],c=`collection`,l,u=e.page??1,d=e.size??20,f=[],p,m,{match:h}=o(e.customFunctions??{}),{sort:g}=s(),_=n.select(e=>e[t]),v={data:[],loading:!0,error:void 0,page:{number:1,size:d,count:0,total:0,pages:1}},y=()=>({filters:p,sort:f,pagination:{type:`offset`,offset:(u-1)*d,limit:d}}),b=async(r=!0)=>{if(e.fetch){if(m=void 0,r){let e=_.get()??v;await n.set({[t]:{...e,loading:!0,error:void 0}})}try{let t=y(),n=await e.fetch(t);c=n.scope,l=n.total,a=n.replace?[...n.data]:[...a,...n.data]}catch(e){m=e}}let i=x(e.fetch?r:!1);await n.set({[t]:i})},x=e=>{let t=[...a];if(c===`collection`){p&&(t=t.filter(e=>h(e,p))),f.length>0&&(t=g(t,f));let n=t.length,r=Math.ceil(n/d)||1;u>r&&(u=r),u<1&&(u=1);let i=(u-1)*d,a=t.slice(i,i+d);return{data:a,loading:e,error:m,page:{number:u,size:d,count:a.length,total:n,pages:r}}}let n=l??t.length,r=Math.ceil(n/d)||1;return{data:t,loading:e,error:m,page:{number:u,size:d,count:t.length,total:n,pages:r}}};return b(!0),{id:()=>t,page:()=>_.get()??v,navigate:async e=>{if(e<1)throw Error(`Page number must be >= 1`);u=e,await b(!0)},resize:async(e,t)=>{if(e<1)throw Error(`Page size must be >= 1`);d=e,u=t,await b(!0)},sort:async e=>{f=Array.isArray(e)?e:[e],u=1,await b(!0)},filter:async e=>{p=e,u=1,await b(!0)},refresh:async e=>{let r=_.get()??v;await n.set({[t]:{...r,loading:!0}});let i=e?.delay??600;await Promise.all([new Promise(e=>setTimeout(e,i)),b(!1)]);let a=_.get()??v;await n.set({[t]:{...a,loading:!1}})},subscribe:e=>_.subscribe(t=>{e(t)}),invalidate:async()=>{await n.set({[t]:r}),a=[]}}}export{T as BlobNamespace,v as HestiaAuth,E as HestiaBlobClient,k as HestiaClient,_ as HestiaCollection,D as HestiaCollections,b as HestiaKeyStore,S as HestiaLogs,m as HestiaNetworkClient,x as HestiaPolicies,p as HestiaResponse,y as HestiaUsers,A as createArrayPager,g as createPagedController,f as internalError,u as notFound,c as parseErrorBody,d as permissionDenied,l as toSystemError};
7
+ `)}}}catch(e){e instanceof Error&&e.name===`AbortError`||t.onError?.(e instanceof Error?e:Error(String(e)))}finally{t.onClose?.()}};return i(!1)}};const h={data:[],loading:!0,page:{number:1,size:20,count:0,total:0,pages:1}};function g(e,t,n,i){let o=n.page??1,s=n.size??20,c=n.sort,l=n.filter,u=new a({delay:50}),d=`${e}_pager_state_`;t.set({[d]:{data:[],loading:!1,error:r,page:{number:1,size:20,count:0,total:0,pages:1}}});let f=e=>{let t=e?.page??o,n=e?.size??s,r={pagination:{type:`offset`,offset:(t-1)*n,limit:n}},i=e?.sort??c;i&&(r.sort=Array.isArray(i)?i:[i]);let a=e?.filter??l;return a&&(r.filters=a),r},p=async e=>(await t.set({[d]:{loading:!0,error:r}}),await new Promise(n=>{n(u.do(async()=>{requestIdleCallback(()=>{requestIdleCallback(async()=>{try{let n=await i(f(e));await t.set({[d]:n})}catch(e){await t.set({[d]:{...h,error:e}})}finally{await t.set({[d]:{loading:!1}})}})})}))})),m=t.select(e=>e[d]),g=m.subscribe(()=>{});return{page:()=>m.get()??h,navigate:async e=>{if(e<1)throw Error(`Page number must be >= 1`);o=e,await p({page:e})},resize:async(e,t)=>{if(e<1)throw Error(`Page size must be >= 1`);s=e,o=t,await p()},sort:async e=>{c=Array.isArray(e)?e:[e],o=1,await p()},filter:async e=>{l=e,o=1,await p()},refresh:async e=>{await Promise.all([new Promise(t=>setTimeout(t,e?.delay||0)),p(e)])},subscribe:e=>m.subscribe(e),invalidate:async()=>{await t.set({[d]:r}),g()},id:()=>d}}var _=class{client;collectionName;defaultLimit;pagerOptions={};pager;constructor(e,t,n=50){this.client=e,this.collectionName=t,this.defaultLimit=n,this.pager=g(t,new i({}),this.pagerOptions,e=>this.find(e))}name(){return this.collectionName}get queryPath(){return`/system/collections/document/${encodeURIComponent(this.collectionName)}/query`}get documentsPath(){return`/system/collections/document/${encodeURIComponent(this.collectionName)}`}documentPath(e){return`${this.documentsPath}/${encodeURIComponent(e)}`}async find(e){let t=await this.client.post(this.queryPath,e??{}),n=t.data?.data??[];return{data:n,loading:!1,page:t.data?.metadata?.page??{number:1,size:n.length,count:n.length,total:n.length,pages:1},error:null}}async read(e){try{return(await this.client.get(this.documentPath(e))).data?.data}catch(e){if(e?.code===`SYNC-001-NF`||e?.code===`NOT_FOUND`)return;throw e}}async create(e){return(await this.client.post(this.documentsPath,e.data)).data.data}async update(e){let t=e.options;return(await this.client.patch(this.documentPath(t),e.data)).data.data}async delete(e){await this.client.delete(this.documentPath(e))}async list(e){return this.find(e??{pagination:{type:`offset`,offset:0,limit:this.defaultLimit}})}async upload(e){throw Error(`Upload not supported for collections`)}async subscribe(e,t){throw Error(`Subscription not implemented for dynamic collections`)}async notify(e){throw Error(`Notify not implemented for dynamic collections`)}stream(e,t){throw Error(`Stream not supported for collections`)}page(e){return this.pager}},v=class{client;provider;constructor(e,t){this.client=e,this.provider=t}async health(){return(await this.client.get(`/system/core/health`)).data.data}async login(e,t){let n=(await this.client.post(`/system/auth/session`,{email:e,password:t})).data.data;return this.provider.setIdentity(n.user),this.client.storeTokens(n.token.access,n.token.refresh),n}async register(e,t,n){return(await this.client.post(`/system/auth/user`,{email:e,password:t,name:n})).data.data}async refresh(e){let t=e?{refresh_token:e}:{};return(await this.client.patch(`/system/auth/session`,t)).data.data.token}async logout(){let e=this.provider.token(`refresh`),t=e?{refresh_token:e}:{};await this.client.delete(`/system/auth/session`,t),await this.provider.clear()}async requestPasswordReset(e){await this.client.post(`/system/auth/password`,{email:e})}async confirmPasswordReset(e,t){await this.client.patch(`/system/auth/password`,{password:t,token:e},{headers:{Authorization:`Bearer ${e}`}})}async bootstrap(e,t,n){await this.client.patch(`/system/auth/bootstrap`,{password:t,email:n},{headers:{"X-API-Key":e}})}},y=class{client;pagerOptions={};pager;constructor(e){this.client=e,this.pager=g(`users`,new i({}),this.pagerOptions,e=>this.find(e))}name(){return`users`}async find(e){let t=await this.client.post(`/system/users/user/query`,e??{}),n=t.data?.data??[];return{data:n,loading:!1,page:t.data?.metadata?.page??{number:1,size:n.length,count:n.length,total:n.length,pages:1}}}async list(e){return this.find(e??{pagination:{type:`offset`,offset:0,limit:50}})}async read(e){try{return(await this.client.get(`/system/users/user/${encodeURIComponent(e)}`)).data?.data}catch(e){if(e?.code===`SYNC-001-NF`)return;throw e}}async update(e){let t=e.options;return(await this.client.patch(`/system/users/user/${encodeURIComponent(t)}`,e.data)).data.data}async delete(e){await this.client.delete(`/system/users/user/${encodeURIComponent(e)}`)}async create(e){throw Error(`User creation requires email/password/name, use register endpoint`)}async upload(e){throw Error(`Upload not supported for users`)}async subscribe(e,t){throw Error(`Subscription not supported for users`)}async notify(e){throw Error(`Notify not supported for users`)}stream(e,t){throw Error(`Stream not supported for users`)}page(e){return this.pager}async changePassword(e,t,n){await this.client.patch(`/system/users/password/${encodeURIComponent(e)}`,{current:t,new:n})}},b=class{client;pager;constructor(e){this.client=e,this.pager=g(`_api_key_`,new i({}),{},e=>this.find(e))}basePath=`/system/apikeys/key`;async find(e){let t=await this.client.get(this.basePath),n=t.data?.data??[];return{data:n,loading:!1,page:t.data?.metadata?.page??{number:1,size:n.length,count:n.length,total:n.length,pages:1}}}async list(e){return e?this.find(e):this.find()}async read(e){try{return(await this.client.get(`${this.basePath}/${encodeURIComponent(e)}`)).data?.data}catch(e){if(e?.code===`SYNC-001-NF`||e?.code===`INTERNAL_ERROR`&&typeof e?.message==`string`&&e.message.includes(`not found`))return;throw e}}async create(e){return(await this.client.post(this.basePath,e.data)).data.data}async update(e){let t=e.options;return(await this.client.patch(`${this.basePath}/${encodeURIComponent(t)}`,e.data)).data.data}async delete(e){await this.client.delete(`${this.basePath}/${encodeURIComponent(e)}`)}async upload(e){throw Error(`Upload not supported for API keys`)}async subscribe(e,t){throw Error(`Subscription not supported for API keys`)}async notify(e){throw Error(`Notify not supported for API keys`)}stream(e,t){throw Error(`Stream not supported for API keys`)}page(e){return this.pager}async rotate(e){return(await this.client.post(`${this.basePath}/${encodeURIComponent(e)}`)).data.data}};const x=`/system/policies/operation`;var S=class{client;constructor(e){this.client=e}async list(){let e=(await this.client.get(x)).data?.data?.operations??[];return{data:e.map(e=>({data:e,metadata:{}})),loading:!1,page:{number:1,size:e.length,count:e.length,total:e.length,pages:1},error:null}}async read(e){try{let t=await this.client.get(`${x}/${encodeURIComponent(e)}`);return t.data?.data?{data:t.data.data,metadata:{}}:void 0}catch(e){if(e?.code===`SYNC-001-NF`||e?.code===`NOT_FOUND`)return;throw e}}};const C=`/system/policies/policy`;var w=class{client;pager;constructor(e){this.client=e,this.pager=g(`policies`,new i({}),{},e=>this.find(e))}async find(e){return this.query(e??{})}async query(e){let t=await this.client.post(`/system/collections/document/_operation_policy_/query`,e),n=t.data?.data??[],r=t.data?.metadata?.page;return{data:n.map(e=>({_id_:e._id_,_metadata_:e._metadata_,id:e._id_,operationName:e.operation??``,ruleName:e.rule??``,enabled:e.enabled??!0,protected:e.protected??!1})),loading:!1,page:r??{number:1,size:n.length,count:n.length,total:n.length,pages:1},error:null}}async list(e){let t=(await this.client.get(C)).data?.data?.policies??[];return{data:t.map(e=>({data:e,metadata:{}})),loading:!1,page:{number:1,size:t.length,count:t.length,total:t.length,pages:1},error:null}}async read(e){try{let t=await this.client.get(`${C}/${encodeURIComponent(e)}`);return t.data?.data?{data:t.data.data,metadata:{}}:void 0}catch(e){if(e?.code===`SYNC-001-NF`||e?.code===`NOT_FOUND`)return;throw e}}async create(e){let t=e.options??e.data.name;if(!t)throw Error(`Operation name is required for create`);let n={ruleName:e.data.ruleName??``},r=await this.client.post(`${C}/${encodeURIComponent(t)}`,n);if(r.data?.data)return{data:r.data.data,metadata:{}}}async update(e){let t=e.options;if(!t)throw Error(`Operation name is required for update`);let n=await this.client.patch(`${C}/${encodeURIComponent(t)}`,e.data);if(n.data?.data)return{data:n.data.data,metadata:{}}}async setEnabled(e,t){return{data:(await this.client.patch(`${C}/${encodeURIComponent(e)}`,{enabled:t})).data.data,metadata:{}}}async delete(e){throw Error(`Policies cannot be deleted; disable instead`)}async upload(e){throw Error(`Upload not supported for policies`)}async subscribe(e,t){throw Error(`Subscription not supported for policies`)}async notify(e){throw Error(`Notify not supported for policies`)}stream(e,t){throw Error(`Stream not supported for policies`)}page(e){return this.pager}};const T=`/system/policies/rule`;var E=class{client;constructor(e){this.client=e}async find(e){return this.list()}async list(e){let t=(await this.client.get(T)).data?.data?.rules??[];return{data:t.map(e=>({data:e,metadata:{}})),loading:!1,page:{number:1,size:t.length,count:t.length,total:t.length,pages:1},error:null}}async read(e){try{let t=await this.client.get(`${T}/${encodeURIComponent(e)}`);return t.data?.data?{data:t.data.data,metadata:{}}:void 0}catch(e){if(e?.code===`SYNC-001-NF`||e?.code===`NOT_FOUND`)return;throw e}}async create(e){let t=e.options;if(!t)throw Error(`Rule name is required for create`);let n=await this.client.post(`${T}/${encodeURIComponent(t)}`,e.data);if(n.data?.data)return{data:n.data.data,metadata:{}}}async update(e){let t=e.options;if(!t)throw Error(`Rule name is required for update`);let n=await this.client.patch(`${T}/${encodeURIComponent(t)}`,e.data);if(n.data?.data)return{data:n.data.data,metadata:{}}}async delete(e){await this.client.delete(`${T}/${encodeURIComponent(e)}`)}async validate(e){return(await this.client.post(`${T}/query`,{expression:e})).data?.data?.valid??!1}async reload(){return(await this.client.get(T)).data.data}async upload(e){throw Error(`Upload not supported for rules`)}async subscribe(e,t){throw Error(`Subscription not supported for rules`)}async notify(e){throw Error(`Notify not supported for rules`)}stream(e,t){throw Error(`Stream not supported for rules`)}page(e){throw Error(`Pagination not supported for rules`)}},D=class{client;baseUrl;pagerOptions={};pager;apiPrefix;constructor(e,t,n=`/api`){this.client=e,this.baseUrl=t,this.apiPrefix=n,this.pager=g(`_audit_log_`,new i({}),this.pagerOptions,e=>this.find(e))}async find(e){let t=await this.client.post(`/system/audit/log/query`,e??{}),n=t.data?.data??[];return{data:n,loading:!1,page:t.data?.metadata?.page??{number:1,size:n.length,count:n.length,total:n.length,pages:1},error:null}}async list(e){return this.find(e??{pagination:{type:`offset`,offset:0,limit:50}})}async read(e){throw Error(`Read by ID not supported for audit logs; use find with filters`)}async create(e){throw Error(`Audit logs are write-only; entries are created by the system`)}async update(e){throw Error(`Audit logs are append-only; updates are not allowed`)}async delete(e){throw Error(`Audit logs are append-only; deletion is not allowed`)}async upload(e){throw Error(`Upload not supported for audit logs`)}async subscribe(e,t){throw Error(`Use stream() for real-time audit log entries`)}async notify(e){throw Error(`Notify not supported for audit logs`)}stream(e,t){let n=this.getStreamUrl(),r=null,i=`active`,a=null,o=async function*(){let e=[];r=new EventSource(n,{withCredentials:!0}),r.onmessage=t=>{for(let n of t.data.split(`
8
+ `)){let t=n.trim();if(t)try{let n=JSON.parse(t);n?.data&&e.push(n.data)}catch{}}e.length>0&&a&&(a(),a=null)},r.onerror=()=>{i===`active`&&(i=`completed`),a&&=(a(),null)};try{for(;i===`active`;)e.length>0?yield e.shift():await new Promise(t=>{a=t,e.length>0&&(t(),a=null)})}finally{r?.close(),a&&=(a(),null),i===`active`&&(i=`completed`)}};return{stream:()=>o(),cancel:()=>{i===`active`&&(i=`cancelled`,r?.close())},status:()=>i}}page(e){return this.pager}getStreamUrl(){return`${this.baseUrl}${this.apiPrefix}/system/audit/log/stream`}};function O(e){return{_id_:e.key,_metadata_:{checksum:``,created:e.created_at,updated:e.updated_at??e.created_at,version:1},...e}}function k(e){return{number:1,size:e.length,count:e.length,total:e.length,pages:1}}var A=class{client;ns;pagerOptions={};pager;prefixFilter=``;constructor(e,t){this.client=e,this.ns=t,this.pager=g(`blobs_${t}`,new i({}),this.pagerOptions,e=>this.find(e))}name(){return this.ns}setPrefix(e){this.prefixFilter=e}basePath(){return`/system/blobs/blob/${encodeURIComponent(this.ns)}`}async find(e){let t=this.prefixFilter||e?.prefix||``,n=e?.limit??e?.pagination?.limit??0,r={};t&&(r.prefix=t),n&&(r.limit=n);let i=(await this.client.post(`${this.basePath()}/query`,r)).data?.data?.blobs??[];return{data:i.map(O),loading:!1,page:k(i),error:void 0}}async read(e){try{let t=await this.client.get(`${this.basePath()}/${encodeURIComponent(e)}`);return t.data?.data?O(t.data.data):void 0}catch(e){if(e?.code===`SYNC-001-NF`||e?.code===`INTERNAL_ERROR`&&typeof e?.message==`string`&&e.message.includes(`not found`))return;throw e}}async create(e){throw Error(`Use upload() to create blobs`)}async update(e){let t=e.options?.key;if(!t)throw Error(`options.key is required for blob update`);return O((await this.client.patch(`${this.basePath()}/${encodeURIComponent(t)}`,{custom:e.data})).data.data)}async delete(e){await this.client.delete(`${this.basePath()}/${encodeURIComponent(e)}`)}async list(e){return this.find(e??{})}async upload(e){let t=e.options?.key;if(!t)throw Error(`options.key is required for blob upload`);let n={},r=e.options?.contentType||e.file.type;return r&&(n[`Content-Type`]=r),O((await this.client.post(`${this.basePath()}/${encodeURIComponent(t)}`,e.file,{headers:n,bodyType:`blob`})).data.data)}async subscribe(e,t){throw Error(`Subscription not supported for blobs`)}async notify(e){throw Error(`Notify not supported for blobs`)}stream(e,t){throw Error(`Stream not supported for blobs`)}page(e){return this.pager}async download(e){let t=(await this.client.get(`${this.basePath()}/${encodeURIComponent(e)}`,{responseType:`blob`})).data;return{data:t,contentType:t.type}}},j=class{client;apiPrefix;constructor(e,t=`/api`){this.client=e,this.apiPrefix=t}nsBase=`/system/blobs`;async namespaces(){return(await this.client.post(`${this.nsBase}/namespace/query`)).data?.data?.namespaces??[]}async createNamespace(e){return(await this.client.post(`${this.nsBase}/namespace`,e)).data.data}async deleteNamespace(e){await this.client.delete(`${this.nsBase}/namespace/${encodeURIComponent(e)}`)}blob(e,t){return`${this.client.base()}${this.apiPrefix}${this.nsBase}/blob/${encodeURIComponent(e)}/${encodeURIComponent(t)}`}namespace(e){return new A(this.client,e)}},M=class{client;constructor(e){this.client=e}async find(e){let t=((await this.client.get(`/system/collections/collection`)).data?.data??[]).map(e=>({_id_:e.name,_metadata_:{checksum:``,created:e.created,updated:e.updated,version:1},name:e.name,schema:e.schema,created:e.created,updated:e.updated}));return{data:t,loading:!1,page:{number:1,size:t.length,count:t.length,total:t.length,pages:1}}}async read(e){try{let t=await this.client.get(`/system/collections/collection/${encodeURIComponent(e)}`);if(!t.data)return;let n=t.data.data;return{_id_:n.name,_metadata_:{checksum:``,created:n.created,updated:n.updated,version:1},name:n.name,schema:n.schema,created:n.created,updated:n.updated}}catch(e){if(e?.code===`SYNC-001-NF`)return;throw e}}async create(e){return(await this.client.post(`/system/collections/collection`,e.data)).data.data}async update(e){throw Error(`Collection update not implemented`)}async delete(e){await this.client.delete(`/system/collections/collection/${encodeURIComponent(e)}`)}async list(e){return this.find()}async upload(e){throw Error(`Upload not supported for collections`)}async subscribe(e,t){throw Error(`Subscription not supported for collections`)}async notify(e){throw Error(`Notify not supported for collections`)}stream(e,t){throw Error(`Stream not supported for collections`)}page(e){throw Error(`Pagination not supported for collection metadata; use documents(name)`)}documents(e){return new _(this.client,e)}},N=class{client;constructor(e){this.client=e}async find(e){let t=(await this.client.get(`/system/core/docs`)).data?.data??[];return{data:t,loading:!1,page:{number:1,size:t.length,count:t.length,total:t.length,pages:1}}}async read(e){throw Error(`Read by ID not supported for capabilities; use find()`)}async create(e){throw Error(`Capabilities are read-only`)}async update(e){throw Error(`Capabilities are read-only`)}async delete(e){throw Error(`Capabilities are read-only`)}async list(e){return this.find()}async upload(e){throw Error(`Upload not supported for capabilities`)}async subscribe(e,t){throw Error(`Subscription not supported for capabilities`)}async notify(e){throw Error(`Notify not supported for capabilities`)}stream(e,t){throw Error(`Stream not supported for capabilities`)}page(e){throw Error(`Pagination not supported for capabilities`)}},P=class{store;client;auth;users;keys;policies;logs;collections;blobs;capabilities;tokenProvider;onAuthStateChanged;constructor(e){this.store=new i({access:null,refresh:null,identity:null},e.persistence);let t={identity:()=>this.store.get().identity,token:e=>this.store.get()[e],setTokens:async(e,t)=>void await this.store.set({access:e,refresh:t}),setIdentity:async e=>void await this.store.set({identity:e}),clear:async()=>void await this.store.set({access:null,refresh:null})},n=e.apiPrefix??`/api`;this.tokenProvider=t,this.client=new m(e.baseUrl,n,t,()=>this.onAuthStateChanged?.()),this.auth=new v(this.client,t),this.users=new y(this.client),this.keys=new b(this.client),this.policies=new w(this.client),this.logs=new D(this.client,e.baseUrl,n),this.collections=new M(this.client),this.blobs=new j(this.client,n),this.capabilities=new N(this.client)}onAuthStateChange(e){this.onAuthStateChanged=e}authenticated(){return this.tokenProvider.token(`access`)!==null}collection(e){return this.collections.documents(e)}};function F(e){let t=`${e.collectionName}_array_pager_state_`,n=new i({}),a=[...e.initialData??[]],c=`collection`,l,u=e.page??1,d=e.size??20,f=[],p,m,{match:h}=o(e.customFunctions??{}),{sort:g}=s(),_=n.select(e=>e[t]),v={data:[],loading:!0,error:void 0,page:{number:1,size:d,count:0,total:0,pages:1}},y=()=>({filters:p,sort:f,pagination:{type:`offset`,offset:(u-1)*d,limit:d}}),b=async(r=!0)=>{if(e.fetch){if(m=void 0,r){let e=_.get()??v;await n.set({[t]:{...e,loading:!0,error:void 0}})}try{let t=y(),n=await e.fetch(t);c=n.scope,l=n.total,a=n.replace?[...n.data]:[...a,...n.data]}catch(e){m=e}}let i=x(e.fetch?r:!1);await n.set({[t]:i})},x=e=>{let t=[...a];if(c===`collection`){p&&(t=t.filter(e=>h(e,p))),f.length>0&&(t=g(t,f));let n=t.length,r=Math.ceil(n/d)||1;u>r&&(u=r),u<1&&(u=1);let i=(u-1)*d,a=t.slice(i,i+d);return{data:a,loading:e,error:m,page:{number:u,size:d,count:a.length,total:n,pages:r}}}let n=l??t.length,r=Math.ceil(n/d)||1;return{data:t,loading:e,error:m,page:{number:u,size:d,count:t.length,total:n,pages:r}}};return b(!0),{id:()=>t,page:()=>_.get()??v,navigate:async e=>{if(e<1)throw Error(`Page number must be >= 1`);u=e,await b(!0)},resize:async(e,t)=>{if(e<1)throw Error(`Page size must be >= 1`);d=e,u=t,await b(!0)},sort:async e=>{f=Array.isArray(e)?e:[e],u=1,await b(!0)},filter:async e=>{p=e,u=1,await b(!0)},refresh:async e=>{let r=_.get()??v;await n.set({[t]:{...r,loading:!0}});let i=e?.delay??600;await Promise.all([new Promise(e=>setTimeout(e,i)),b(!1)]);let a=_.get()??v;await n.set({[t]:{...a,loading:!1}})},subscribe:e=>_.subscribe(t=>{e(t)}),invalidate:async()=>{await n.set({[t]:r}),a=[]}}}export{A as BlobNamespace,v as HestiaAuth,j as HestiaBlobClient,P as HestiaClient,_ as HestiaCollection,M as HestiaCollections,b as HestiaKeyStore,D as HestiaLogs,m as HestiaNetworkClient,S as HestiaOperations,w as HestiaPolicies,p as HestiaResponse,E as HestiaRules,y as HestiaUsers,F as createArrayPager,g as createPagedController,f as internalError,u as notFound,c as parseErrorBody,d as permissionDenied,l as toSystemError};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asaidimu/hestia",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "TypeScript client SDK for the Hestia platform — auth, collections, API keys, policies, audit logs, blobs, and capabilities",
5
5
  "type": "module",
6
6
  "main": "./index.cjs",