@lunora/runtime 1.0.0-alpha.81 → 1.0.0-alpha.82

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -3647,6 +3647,9 @@ interface WorkerOptions {
3647
3647
  /**
3648
3648
  * Table allowlist for the scheduled backup. Omit to back up every table
3649
3649
  * (shard-local + `.global()`). Mirrors the export endpoint's `tables`.
3650
+ *
3651
+ * "Every table" needs {@link WorkerOptions.listSchemaTables}; without it the
3652
+ * backup reaches only the default shard. Export warns when that happens.
3650
3653
  */
3651
3654
  backupTables?: ReadonlyArray<string>;
3652
3655
  /**
package/dist/index.d.ts CHANGED
@@ -3647,6 +3647,9 @@ interface WorkerOptions {
3647
3647
  /**
3648
3648
  * Table allowlist for the scheduled backup. Omit to back up every table
3649
3649
  * (shard-local + `.global()`). Mirrors the export endpoint's `tables`.
3650
+ *
3651
+ * "Every table" needs {@link WorkerOptions.listSchemaTables}; without it the
3652
+ * backup reaches only the default shard. Export warns when that happens.
3650
3653
  */
3651
3654
  backupTables?: ReadonlyArray<string>;
3652
3655
  /**
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{BACKUP_KEY_PREFIX as t,backupManifestKey as a,backupObjectKey as s,backupObjectKeyOfManifest as i,isBackupManifestEntry as n,isBackupManifestKey as p,normalizeBackupPrefix as c}from"./packem_shared/BACKUP_KEY_PREFIX-BOtSu-_3.mjs";import{toAirbyteMessages as f,toFivetranResponse as E}from"./packem_shared/toAirbyteMessages-CIjE6Vm1.mjs";import{composeWorker as S,createLunoraHandler as x,createWorker as _,defineRpcEnvelope as d,resolveLunoraOptions as l,withFrameworkWorker as u}from"./packem_shared/composeWorker-B5RBIbDz.mjs";import{createCrossShardRelationCapabilities as k}from"./packem_shared/createCrossShardRelationCapabilities-BRX27FkU.mjs";import{DEFAULT_REGISTRY_CACHE_TTL_MS as A,SHARD_REGISTRY_DO_NAME as C,createDynamicShardRegistry as L}from"./packem_shared/DEFAULT_REGISTRY_CACHE_TTL_MS-D5O7elXI.mjs";import{LunoraError as b,toErrorResponse as g}from"./packem_shared/LunoraError-DksAgIpa.mjs";import{createKvCursorStore as H,createMemoryCursorStore as I,defineExportSink as P,r2Sink as v,runExportTap as D,sanitizeChange as F,webhookExportSink as M}from"./packem_shared/createKvCursorStore-DLm6fYoN.mjs";import{HEALTH_PATH as K,HEALTH_READY_PATH as N,buildHealthRoutes as U,d1Probe as B,durableObjectProbe as Y,presenceProbe as w}from"./packem_shared/HEALTH_PATH-jZsuCmSs.mjs";import{LOG_ARCHIVE_PATH as X,resolveLogArchiveFromEnv as j}from"./packem_shared/LOG_ARCHIVE_PATH-jgHjdsz2.mjs";import{memoizeIdentity as W,memoizeIdentityPerRequest as q}from"./packem_shared/memoizeIdentity-DnOj3QRi.mjs";import{e as J,a as Z}from"./packem_shared/observability-vDK-rMbs.mjs";import{analyticsEngineSink as ee,combineSinks as re,consoleSink as oe,otlpSink as te,pipelineLogSink as ae,sentrySink as se,webhookSink as ie}from"./packem_shared/analyticsEngineSink-D9xt5_FI.mjs";import{D as pe,a as ce,c as me}from"./packem_shared/pipeline-log-reader-BGrl66P5.mjs";import{createQueryCoordinator as Ee,createStaticShardRegistry as Re,mergeStrategyForAggregate as Se}from"./packem_shared/createQueryCoordinator-BBZ3yF37.mjs";import{applyJurisdiction as _e,resolveShard as de}from"./packem_shared/applyJurisdiction-C0ddU7Tg.mjs";import{a as ue,r as ye,b as ke}from"./packem_shared/rest-cache-CPSyD1RD.mjs";import{a as Ae,b as Ce,c as Le,r as Te,d as be}from"./packem_shared/rest-routes-Dq17Zntv.mjs";import{decorateResponse as he,enforceOrigin as He,handleCorsPreflight as Ie,resolveSecurity as Pe}from"./packem_shared/decorateResponse-BuqVnrmc.mjs";import{createShardClient as De}from"./packem_shared/createShardClient-0Tz9JwbX.mjs";import{STORAGE_UPLOAD_MAX_BODY_BYTES as Me}from"./packem_shared/STORAGE_UPLOAD_MAX_BODY_BYTES-BqyO-1l6.mjs";import{LOG_ARCHIVE_NOT_CONFIGURED as Ke}from"./packem_shared/LOG_ARCHIVE_NOT_CONFIGURED-CDpi4yFD.mjs";import{NOOP_EXECUTION_CONTEXT as Ue}from"./packem_shared/NOOP_EXECUTION_CONTEXT-YmXqH-jH.mjs";import{composeIdentityResolvers as Ye,routeIdentityResolvers as we}from"./packem_shared/composeIdentityResolvers-BHZ4jH8o.mjs";const e="0.0.0";export{t as BACKUP_KEY_PREFIX,pe as DEFAULT_LOG_COLUMNS,ce as DEFAULT_LOG_LIMIT,A as DEFAULT_REGISTRY_CACHE_TTL_MS,K as HEALTH_PATH,N as HEALTH_READY_PATH,Ke as LOG_ARCHIVE_NOT_CONFIGURED,X as LOG_ARCHIVE_PATH,b as LunoraError,Ue as NOOP_EXECUTION_CONTEXT,C as SHARD_REGISTRY_DO_NAME,Me as STORAGE_UPLOAD_MAX_BODY_BYTES,e as VERSION,ee as analyticsEngineSink,_e as applyJurisdiction,ue as applyRestCache,Ae as argsFromQuery,a as backupManifestKey,s as backupObjectKey,i as backupObjectKeyOfManifest,U as buildHealthRoutes,Ce as buildRestRoutes,re as combineSinks,Ye as composeIdentityResolvers,S as composeWorker,oe as consoleSink,k as createCrossShardRelationCapabilities,L as createDynamicShardRegistry,H as createKvCursorStore,x as createLunoraHandler,I as createMemoryCursorStore,me as createPipelineLogReader,Ee as createQueryCoordinator,Le as createRestRateLimit,De as createShardClient,Re as createStaticShardRegistry,_ as createWorker,B as d1Probe,he as decorateResponse,P as defineExportSink,d as defineRpcEnvelope,Y as durableObjectProbe,J as emitLogEvent,Z as emitRpcEvent,He as enforceOrigin,Ie as handleCorsPreflight,n as isBackupManifestEntry,p as isBackupManifestKey,W as memoizeIdentity,q as memoizeIdentityPerRequest,Se as mergeStrategyForAggregate,c as normalizeBackupPrefix,te as otlpSink,ae as pipelineLogSink,w as presenceProbe,v as r2Sink,Te as readShardKey,ye as requestCarriesCredentials,j as resolveLogArchiveFromEnv,l as resolveLunoraOptions,Pe as resolveSecurity,de as resolveShard,ke as restCacheHeaders,be as restSurfaceFromRegistry,we as routeIdentityResolvers,D as runExportTap,F as sanitizeChange,se as sentrySink,f as toAirbyteMessages,g as toErrorResponse,E as toFivetranResponse,M as webhookExportSink,ie as webhookSink,u as withFrameworkWorker};
1
+ import{BACKUP_KEY_PREFIX as t,backupManifestKey as a,backupObjectKey as s,backupObjectKeyOfManifest as i,isBackupManifestEntry as n,isBackupManifestKey as p,normalizeBackupPrefix as c}from"./packem_shared/BACKUP_KEY_PREFIX-BOtSu-_3.mjs";import{toAirbyteMessages as f,toFivetranResponse as E}from"./packem_shared/toAirbyteMessages-CIjE6Vm1.mjs";import{composeWorker as S,createLunoraHandler as x,createWorker as _,defineRpcEnvelope as d,resolveLunoraOptions as l,withFrameworkWorker as u}from"./packem_shared/composeWorker-CKmnnfTD.mjs";import{createCrossShardRelationCapabilities as k}from"./packem_shared/createCrossShardRelationCapabilities-BRX27FkU.mjs";import{DEFAULT_REGISTRY_CACHE_TTL_MS as A,SHARD_REGISTRY_DO_NAME as C,createDynamicShardRegistry as L}from"./packem_shared/DEFAULT_REGISTRY_CACHE_TTL_MS-D5O7elXI.mjs";import{LunoraError as b,toErrorResponse as g}from"./packem_shared/LunoraError-DksAgIpa.mjs";import{createKvCursorStore as H,createMemoryCursorStore as I,defineExportSink as P,r2Sink as v,runExportTap as D,sanitizeChange as F,webhookExportSink as M}from"./packem_shared/createKvCursorStore-DLm6fYoN.mjs";import{HEALTH_PATH as K,HEALTH_READY_PATH as N,buildHealthRoutes as U,d1Probe as B,durableObjectProbe as Y,presenceProbe as w}from"./packem_shared/HEALTH_PATH-jZsuCmSs.mjs";import{LOG_ARCHIVE_PATH as X,resolveLogArchiveFromEnv as j}from"./packem_shared/LOG_ARCHIVE_PATH-jgHjdsz2.mjs";import{memoizeIdentity as W,memoizeIdentityPerRequest as q}from"./packem_shared/memoizeIdentity-DnOj3QRi.mjs";import{e as J,a as Z}from"./packem_shared/observability-vDK-rMbs.mjs";import{analyticsEngineSink as ee,combineSinks as re,consoleSink as oe,otlpSink as te,pipelineLogSink as ae,sentrySink as se,webhookSink as ie}from"./packem_shared/analyticsEngineSink-D9xt5_FI.mjs";import{D as pe,a as ce,c as me}from"./packem_shared/pipeline-log-reader-BGrl66P5.mjs";import{createQueryCoordinator as Ee,createStaticShardRegistry as Re,mergeStrategyForAggregate as Se}from"./packem_shared/createQueryCoordinator-BBZ3yF37.mjs";import{applyJurisdiction as _e,resolveShard as de}from"./packem_shared/applyJurisdiction-C0ddU7Tg.mjs";import{a as ue,r as ye,b as ke}from"./packem_shared/rest-cache-CPSyD1RD.mjs";import{a as Ae,b as Ce,c as Le,r as Te,d as be}from"./packem_shared/rest-routes-Dq17Zntv.mjs";import{decorateResponse as he,enforceOrigin as He,handleCorsPreflight as Ie,resolveSecurity as Pe}from"./packem_shared/decorateResponse-BuqVnrmc.mjs";import{createShardClient as De}from"./packem_shared/createShardClient-0Tz9JwbX.mjs";import{STORAGE_UPLOAD_MAX_BODY_BYTES as Me}from"./packem_shared/STORAGE_UPLOAD_MAX_BODY_BYTES-BqyO-1l6.mjs";import{LOG_ARCHIVE_NOT_CONFIGURED as Ke}from"./packem_shared/LOG_ARCHIVE_NOT_CONFIGURED-CDpi4yFD.mjs";import{NOOP_EXECUTION_CONTEXT as Ue}from"./packem_shared/NOOP_EXECUTION_CONTEXT-YmXqH-jH.mjs";import{composeIdentityResolvers as Ye,routeIdentityResolvers as we}from"./packem_shared/composeIdentityResolvers-BHZ4jH8o.mjs";const e="0.0.0";export{t as BACKUP_KEY_PREFIX,pe as DEFAULT_LOG_COLUMNS,ce as DEFAULT_LOG_LIMIT,A as DEFAULT_REGISTRY_CACHE_TTL_MS,K as HEALTH_PATH,N as HEALTH_READY_PATH,Ke as LOG_ARCHIVE_NOT_CONFIGURED,X as LOG_ARCHIVE_PATH,b as LunoraError,Ue as NOOP_EXECUTION_CONTEXT,C as SHARD_REGISTRY_DO_NAME,Me as STORAGE_UPLOAD_MAX_BODY_BYTES,e as VERSION,ee as analyticsEngineSink,_e as applyJurisdiction,ue as applyRestCache,Ae as argsFromQuery,a as backupManifestKey,s as backupObjectKey,i as backupObjectKeyOfManifest,U as buildHealthRoutes,Ce as buildRestRoutes,re as combineSinks,Ye as composeIdentityResolvers,S as composeWorker,oe as consoleSink,k as createCrossShardRelationCapabilities,L as createDynamicShardRegistry,H as createKvCursorStore,x as createLunoraHandler,I as createMemoryCursorStore,me as createPipelineLogReader,Ee as createQueryCoordinator,Le as createRestRateLimit,De as createShardClient,Re as createStaticShardRegistry,_ as createWorker,B as d1Probe,he as decorateResponse,P as defineExportSink,d as defineRpcEnvelope,Y as durableObjectProbe,J as emitLogEvent,Z as emitRpcEvent,He as enforceOrigin,Ie as handleCorsPreflight,n as isBackupManifestEntry,p as isBackupManifestKey,W as memoizeIdentity,q as memoizeIdentityPerRequest,Se as mergeStrategyForAggregate,c as normalizeBackupPrefix,te as otlpSink,ae as pipelineLogSink,w as presenceProbe,v as r2Sink,Te as readShardKey,ye as requestCarriesCredentials,j as resolveLogArchiveFromEnv,l as resolveLunoraOptions,Pe as resolveSecurity,de as resolveShard,ke as restCacheHeaders,be as restSurfaceFromRegistry,we as routeIdentityResolvers,D as runExportTap,F as sanitizeChange,se as sentrySink,f as toAirbyteMessages,g as toErrorResponse,E as toFivetranResponse,M as webhookExportSink,ie as webhookSink,u as withFrameworkWorker};
@@ -1,4 +1,4 @@
1
- import{isLunoraError as Un,toErrorBody as Cn}from"@lunora/errors";import{e as Dt}from"./evict-oldest-BNXsKx4s.mjs";import{NOOP_EXECUTION_CONTEXT as Bn}from"./NOOP_EXECUTION_CONTEXT-YmXqH-jH.mjs";import{t as Nt,f as Ut}from"./base64-Bl1_r2k1.mjs";import{e as xn,a as Hn}from"./identity-header-C4Z5pldl.mjs";import{o as Se,b as Ln,p as Mn,m as jn,d as Kn,a as $n,r as Fn}from"./otlp-resource-DeXhb949.mjs";import{e as $e}from"./wire-codec-BsPOEXGn.mjs";import{e as Z,f as be,M as Ct,b as Gn,g as Qn,h as Bt,i as xt}from"./rest-routes-Dq17Zntv.mjs";import{LunoraError as d,toErrorResponse as tt}from"./LunoraError-DksAgIpa.mjs";import{a as j,m as me}from"./method-guard-BG_vJNTl.mjs";import{normalizeBackupPrefix as Ge,BACKUP_KEY_PREFIX as Qe,isBackupManifestKey as zn,backupObjectKeyOfManifest as Ht,backupObjectKey as Wn,backupManifestKey as Vn}from"./BACKUP_KEY_PREFIX-BOtSu-_3.mjs";import{toHex as Jn,buildStorageAdminRoutes as qn,STORAGE_UPLOAD_MAX_BODY_BYTES as Yn,STORAGE_PATH as Xn}from"./STORAGE_UPLOAD_MAX_BODY_BYTES-BqyO-1l6.mjs";import{runExportTap as Zn}from"./createKvCursorStore-DLm6fYoN.mjs";import{buildHealthRoutes as er,durableObjectProbe as tr,d1Probe as nr,presenceProbe as Ce}from"./HEALTH_PATH-jZsuCmSs.mjs";import{wrapResolverWithContract as rr}from"./composeIdentityResolvers-BHZ4jH8o.mjs";import{composeIdentityResolvers as Ss,routeIdentityResolvers as Ts}from"./composeIdentityResolvers-BHZ4jH8o.mjs";import{buildLogArchiveAdminRoutes as or}from"./LOG_ARCHIVE_PATH-jgHjdsz2.mjs";import{r as ar,f as nt,a as ce}from"./observability-vDK-rMbs.mjs";import{resolveShard as we,applyJurisdiction as rt}from"./applyJurisdiction-C0ddU7Tg.mjs";import{resolveSecurity as ot,handleCorsPreflight as sr,enforceOrigin as ir,decorateResponse as Be,enforceWebSocketOrigin as at}from"./decorateResponse-BuqVnrmc.mjs";const cr=e=>{const n=e??{};if(typeof n.bucket=="function")return n;const t={...n,bucketName:"default"};return t.bucket=()=>t,t},Lt="__lunoraBranch",dr=e=>typeof e=="object"&&e!==null&&Object.hasOwn(e,Lt),ur=`may not contain the reserved workflow branch-marker key ("${Lt}")`,ze=(e,n)=>{const t=Math.max(e.length,n.length);let r=e.length^n.length;for(let a=0;a<t;a+=1){const s=a<e.length?e.charCodeAt(a):0,u=a<n.length?n.charCodeAt(a):0;r|=s^u}return r===0},lr=(e,n,t,r)=>{const a=e.get(n);if(a!==void 0)return a;Dt(e,r);const s=t().catch(u=>{throw e.get(n)===s&&e.delete(n),u});return e.set(n,s),s},We=new TextEncoder,hr=Array.from({length:32},(e,n)=>n);new RegExp(`[${hr.map(e=>String.fromCodePoint(e)).join("")}]`,"u");const fr=64,pr=new Map,Mt=async e=>lr(pr,e,async()=>crypto.subtle.importKey("raw",We.encode(e),{hash:"SHA-256",name:"HMAC"},!1,["sign","verify"]),fr),jt=async(e,n)=>{const t=await Mt(e),r=await crypto.subtle.sign("HMAC",t,We.encode(n));return Nt(new Uint8Array(r))},mr=async(e,n,t)=>{const r=await Mt(e);return crypto.subtle.verify("HMAC",r,t,We.encode(n))},wr=["wnam","enam","sam","weur","eeur","apac","apac-ne","apac-se","oc","afr","me"];new Set(wr);const gr=new Set(["AE","BH","IL","IQ","IR","JO","KW","LB","OM","PS","QA","SA","SY","TR","YE"]),yr=-100,br=15,_r=e=>{const n=Number(e.longitude??Number.NaN);switch(e.continent){case"AF":return"afr";case"AS":return e.country!==void 0&&gr.has(e.country)?"me":"apac";case"EU":return Number.isFinite(n)&&n>br?"eeur":"weur";case"NA":return Number.isFinite(n)&&n<yr?"wnam":"enam";case"OC":return"oc";case"SA":return"sam";default:return}},st=e=>{const n=e.cf;return n===void 0?void 0:_r(n)},Kt="::relay::",Rr=(e,n)=>`${e}${Kt}${String(n)}`,$t="::replica::",Er=(e,n)=>`${e}${$t}${n}`,Ar=e=>{if(e==null||!/^\d+$/.test(e))return;const n=Number.parseInt(e,10);return Number.isSafeInteger(n)&&n>0?n:void 0},Sr=new Set(["1","enabled","on","true","yes"]),Tr=new Set(["0","disabled","false","no","off"]),Or=(e,n)=>{const t=(e??"").trim().toLowerCase();return Sr.has(t)?!0:Tr.has(t)?!1:n},Ft="v1",vr=6e4,kr=async(e,n={})=>{const t=(n.now??Date.now())+(n.ttlMs??vr),r=`${Ft}.${String(t)}`,a=await jt(e,r);return{expiresAtMs:t,token:`${r}.${a}`}},Ir=async(e,n,t=Date.now())=>{if(e.length===0||n.length===0)return!1;const r=n.split(".");if(r.length!==3)return!1;const[a,s,u]=r;if(a!==Ft||u.length===0)return!1;const l=Number(s);if(!Number.isFinite(l)||l<=t)return!1;let f;try{f=Ut(u)}catch{return!1}return mr(e,`${a}.${s}`,f)},P="/_lunora/admin/auth",Pr={INVITER_REQUIRED:400,ORG_SLUG_INVALID:400,ORG_SLUG_TAKEN:409,PASSWORD_TOO_LONG:400,PASSWORD_TOO_SHORT:400,USER_ALREADY_EXISTS:409,USER_NOT_FOUND:404},N=(e,n)=>{const t=e[n];if(typeof t!="string"||t==="")throw new d(`\`${n}\` is required`,{code:"BAD_REQUEST",status:400});return t},le=(e,n)=>{const t=e(n);if(t===void 0)throw new d(`\`${n}\` query parameter is required`,{code:"BAD_REQUEST",status:400});return t},Gt=e=>{if(typeof e=="string"||Array.isArray(e)&&e.every(n=>typeof n=="string"))return e},re=(e,n)=>typeof e[n]=="string"?e[n]:void 0,xe=(e,n)=>{const t=e[n];return typeof t=="object"&&t!==null&&!Array.isArray(t)?t:void 0},it=e=>{const n=Gt(e.role);if(n===void 0||typeof n=="string"&&n.trim()==="")throw new d("`role` is required",{code:"BAD_REQUEST",status:400});return n},ct=e=>{const n=e.permission;if(typeof n!="object"||n===null||Array.isArray(n))throw new d("`permission` object is required",{code:"BAD_REQUEST",status:400});const t={};for(const[r,a]of Object.entries(n))Array.isArray(a)&&a.every(s=>typeof s=="string")&&(t[r]=a);return t},Dr={[`${P}/capabilities`]:{build:()=>({}),http:"GET",method:"capabilities"},[`${P}/users`]:{build:({paging:e,query:n})=>{const t=n("sortDirection");return{...e,filterField:n("filterField"),filterValue:n("filterValue"),search:n("search"),searchField:n("searchField"),sortBy:n("sortBy"),sortDirection:t==="asc"||t==="desc"?t:void 0}},http:"GET",method:"listUsers"},[`${P}/sessions`]:{build:({paging:e,query:n})=>({...e,userId:n("userId")}),http:"GET",method:"listSessions"},[`${P}/accounts`]:{build:({query:e})=>({userId:le(e,"userId")}),http:"GET",method:"listAccounts"},[`${P}/passkeys`]:{build:({query:e})=>({userId:le(e,"userId")}),http:"GET",method:"listPasskeys"},[`${P}/organizations`]:{build:({paging:e})=>({...e}),http:"GET",method:"listOrganizations"},[`${P}/organizations/members`]:{build:({paging:e,query:n})=>({...e,organizationId:le(n,"organizationId")}),http:"GET",method:"listMembers"},[`${P}/organizations/invitations`]:{build:({paging:e,query:n})=>({...e,organizationId:le(n,"organizationId")}),http:"GET",method:"listInvitations"},[`${P}/config`]:{build:()=>({}),http:"GET",method:"config"},[`${P}/organizations/teams`]:{build:({paging:e,query:n})=>({...e,organizationId:le(n,"organizationId")}),http:"GET",method:"listTeams"},[`${P}/organizations/teams/members`]:{build:({paging:e,query:n})=>({...e,teamId:le(n,"teamId")}),http:"GET",method:"listTeamMembers"},[`${P}/organizations/roles`]:{build:({paging:e,query:n})=>({...e,organizationId:le(n,"organizationId")}),http:"GET",method:"listOrgRoles"},[`${P}/users/create`]:{build:({body:e})=>({data:xe(e,"data"),email:N(e,"email"),name:N(e,"name"),password:re(e,"password"),role:Gt(e.role)}),http:"POST",method:"createUser"},[`${P}/users/update`]:{build:({body:e})=>{const{data:n}=e;if(typeof n!="object"||n===null||Array.isArray(n))throw new d("`data` object is required",{code:"BAD_REQUEST",status:400});return{data:n,userId:N(e,"userId")}},http:"POST",method:"updateUser"},[`${P}/users/role`]:{build:({body:e})=>({role:it(e),userId:N(e,"userId")}),http:"POST",method:"setRole"},[`${P}/users/ban`]:{build:({body:e})=>({expiresInSeconds:typeof e.expiresInSeconds=="number"?e.expiresInSeconds:void 0,reason:re(e,"reason"),userId:N(e,"userId")}),http:"POST",method:"banUser"},[`${P}/users/unban`]:{build:({body:e})=>({userId:N(e,"userId")}),http:"POST",method:"unbanUser"},[`${P}/users/password`]:{build:({body:e})=>({newPassword:N(e,"newPassword"),userId:N(e,"userId")}),http:"POST",method:"setUserPassword",returns:"void"},[`${P}/users/remove`]:{build:({body:e})=>({userId:N(e,"userId")}),http:"POST",method:"removeUser",returns:"void"},[`${P}/users/impersonate`]:{build:({body:e})=>({userId:N(e,"userId")}),http:"POST",method:"impersonateUser"},[`${P}/sessions/revoke`]:{build:({body:e})=>({sessionId:N(e,"sessionId")}),http:"POST",method:"revokeUserSession",returns:"void"},[`${P}/sessions/revoke-all`]:{build:({body:e})=>({userId:N(e,"userId")}),http:"POST",method:"revokeUserSessions",returns:"void"},[`${P}/accounts/unlink`]:{build:({body:e})=>({accountId:N(e,"accountId"),userId:N(e,"userId")}),http:"POST",method:"unlinkAccount",returns:"void"},[`${P}/two-factor/disable`]:{build:({body:e})=>({userId:N(e,"userId")}),http:"POST",method:"disableTwoFactor",returns:"void"},[`${P}/passkeys/delete`]:{build:({body:e})=>({passkeyId:N(e,"passkeyId")}),http:"POST",method:"deletePasskey",returns:"void"},[`${P}/organizations/members/remove`]:{build:({body:e})=>({memberId:N(e,"memberId")}),http:"POST",method:"removeMember",returns:"void"},[`${P}/organizations/invitations/cancel`]:{build:({body:e})=>({invitationId:N(e,"invitationId")}),http:"POST",method:"cancelInvitation",returns:"void"},[`${P}/organizations/create`]:{build:({body:e})=>({logo:re(e,"logo"),metadata:xe(e,"metadata"),name:N(e,"name"),ownerId:re(e,"ownerId"),slug:re(e,"slug")}),http:"POST",method:"createOrganization"},[`${P}/organizations/update`]:{build:({body:e})=>({logo:re(e,"logo"),metadata:xe(e,"metadata"),name:re(e,"name"),organizationId:N(e,"organizationId"),slug:re(e,"slug")}),http:"POST",method:"updateOrganization"},[`${P}/organizations/remove`]:{build:({body:e})=>({organizationId:N(e,"organizationId")}),http:"POST",method:"deleteOrganization",returns:"void"},[`${P}/organizations/members/add`]:{build:({body:e})=>({organizationId:N(e,"organizationId"),role:re(e,"role"),userId:N(e,"userId")}),http:"POST",method:"addMember"},[`${P}/organizations/members/invite`]:{build:({body:e})=>({email:N(e,"email"),inviterId:re(e,"inviterId"),organizationId:N(e,"organizationId"),role:re(e,"role")}),http:"POST",method:"inviteMember"},[`${P}/organizations/members/role`]:{build:({body:e})=>({memberId:N(e,"memberId"),role:it(e)}),http:"POST",method:"updateMemberRole"},[`${P}/organizations/teams/create`]:{build:({body:e})=>({name:N(e,"name"),organizationId:N(e,"organizationId")}),http:"POST",method:"createTeam"},[`${P}/organizations/teams/update`]:{build:({body:e})=>({name:N(e,"name"),teamId:N(e,"teamId")}),http:"POST",method:"updateTeam"},[`${P}/organizations/teams/remove`]:{build:({body:e})=>({teamId:N(e,"teamId")}),http:"POST",method:"removeTeam",returns:"void"},[`${P}/organizations/teams/members/add`]:{build:({body:e})=>({teamId:N(e,"teamId"),userId:N(e,"userId")}),http:"POST",method:"addTeamMember"},[`${P}/organizations/teams/members/remove`]:{build:({body:e})=>({teamMemberId:N(e,"teamMemberId")}),http:"POST",method:"removeTeamMember",returns:"void"},[`${P}/organizations/roles/create`]:{build:({body:e})=>({organizationId:N(e,"organizationId"),permission:ct(e),role:N(e,"role")}),http:"POST",method:"createOrgRole"},[`${P}/organizations/roles/update`]:{build:({body:e})=>({permission:ct(e),roleId:N(e,"roleId")}),http:"POST",method:"updateOrgRole"},[`${P}/organizations/roles/remove`]:{build:({body:e})=>({roleId:N(e,"roleId")}),http:"POST",method:"deleteOrgRole",returns:"void"}},Nr=e=>{const n=async a=>{try{return await a()}catch(s){if(s instanceof d)throw s;const u=s,l=typeof u.code=="string"?u.code:"AUTH_ADMIN_ERROR";throw console.error("[lunora] auth admin operation failed:",s),new d("auth admin operation failed",{code:l,status:Pr[l]??500})}},t=async(a,s)=>{if(e.assertAdmin(a),a.method!==s.http)throw new d(`Auth admin endpoint requires ${s.http}`,{code:"METHOD_NOT_ALLOWED",status:405});const u=e.getAuthAdmin();if(u===void 0)throw new d("auth endpoints require an `authAdmin` on the worker",{code:"AUTH_NOT_CONFIGURED",status:400});const l=u[s.method];if(l===void 0)throw new d(`auth admin does not support \`${s.method}\``,{code:"AUTH_OP_NOT_SUPPORTED",status:400});const f=new URL(a.url),w={body:s.http==="POST"?await e.readJsonBody(a):{},paging:e.parsePaging(a),query:k=>e.queryParameter(f,k)},E=s.build(w),v=await n(()=>l(E));return Response.json(s.returns==="void"?{ok:!0}:v,{headers:{"content-type":"application/json"},status:200})},r={};for(const[a,s]of Object.entries(Dr))r[a]=u=>t(u,s);return r},Ur="__lunora_admin__:getAuthAuditLog",dt=e=>typeof e=="string"&&e!==""?e:void 0,ut=e=>typeof e=="number"&&Number.isFinite(e)&&e>=0?e:void 0,Cr=e=>async(t,r)=>{e.assertAdmin(t);const a=e.getReader();if(a===void 0)throw new d("the auth/security audit endpoint requires an `authAuditReader` on the worker",{code:"AUTH_AUDIT_NOT_CONFIGURED",status:400});const s=dt(r.actorId),u=dt(r.event),l=ut(r.sinceSeq),f=ut(r.limit),w={...s===void 0?{}:{actorId:s},...u===void 0?{}:{event:u},...l===void 0?{}:{sinceSeq:l},...f===void 0?{}:{limit:f}};let E;try{E=await a.read(w)}catch(k){throw k instanceof d?k:(console.error("[lunora] auth audit read failed:",k),new d("auth audit read failed",{code:"AUTH_AUDIT_READ_FAILED",status:500}))}const v={entries:E};return Response.json({result:$e(v)},{headers:{"content-type":"application/json"},status:200})},Br=(e,n)=>{const t=[],r=[];if(n&&n.length>0)for(const a of n)e.resolveTableSharding?.(a)?.mode.kind==="global"?r.push(a):t.push(a);return{globalTables:r,shardLocalTables:t}},xr=async(e,n,t,r,a,s,u)=>{if(t!==void 0&&r.length===0)return;const l=await e.orchestrateExport(s,{args:{tables:r},defaultShardKey:u,headers:n,tables:r});for(const f of l.shards)if(!f.error)for(const w of f.rows??[])a(w)},Qt=async(e,n,t,r,a,s)=>{const u=r??e.listSchemaTables?.(),{globalTables:l,shardLocalTables:f}=Br(e,u);await xr(n,t,u,f,a,s,e.defaultShardKey??"__root__");const w=e.exportGlobals;if((r===void 0||l.length>0)&&w)for await(const v of w({tables:l}))a(v)},Hr=new TextEncoder,Lr=1e3,zt=10,Mr=200,lt=8,Wt="lunoraBackupCron",ht=24*1048576,ft=e=>{const n=e.slice(0,zt).map(r=>Ht(r)),t=e.length-n.length;return`${n.join(", ")}${t>0?` (+${String(t)} more)`:""}`},jr=(e,n)=>{const t=new Uint8Array(new ArrayBuffer(n));let r=0;for(const a of e)t.set(a,r),r+=a.byteLength;return t},Ve=async(e,n,t,r)=>{if(t===void 0||!Number.isInteger(t)||t<=0)return{eligible:0,stale:[]};const a=[];let s;for(let u=0;u<Lr;u+=1){const l=await e.list({cursor:s,include:["customMetadata"],prefix:n});for(const f of l.objects)zn(f.key)&&f.customMetadata?.[Wt]===r&&a.push(f.key);if(!l.truncated||l.cursor===void 0)break;s=l.cursor}return{eligible:a.length,stale:a.toSorted((u,l)=>l.localeCompare(u)).slice(t)}},Kr=async(e,n,t,r,a)=>{const{stale:s}=await Ve(e,n,t,r),u=new Set(a),l=s.filter(g=>u.has(g)),f=l.slice(0,Mr),w=s.length-f.length,E=a.length-l.length;if(f.length===0)return{deleted:[],failed:[],ignored:E,remaining:w};const v=[],k=[];for(let g=0;g<f.length;g+=lt){const b=await Promise.allSettled(f.slice(g,g+lt).map(async _=>(await e.delete(Ht(_)),await e.delete(_),_)));for(const[_,p]of b.entries())p.status==="fulfilled"?v.push(p.value):k.push(f[g+_])}return v.length>0&&console.info(`[lunora] backup prune kept the newest ${String(t)} and deleted ${String(v.length)}: ${ft(v)}`),k.length>0&&console.warn(`[lunora] backup prune failed to remove ${String(k.length)}: ${ft(k)}`),{deleted:v,failed:k,ignored:E,remaining:w}},$r=async e=>{const n=e.backupStore;if(!n)throw new d("backup retention preview requires a `backupStore` on the worker",{code:"BACKUP_NOT_CONFIGURED",status:500});const t=Ge(e.backupPrefix??Qe),r=e.backupCron,{eligible:a,stale:s}=r===void 0?{eligible:0,stale:[]}:await Ve(n,t,e.backupRetain,r);return{cron:r,eligible:a,keep:e.backupRetain??0,prefix:t,wouldDelete:s}},Fr=async(e,n,t,r)=>{const a=e.backupStore,s=e.queryCoordinator;if(!a)throw new d("scheduled backup requires a `backupStore` on the worker",{code:"BACKUP_NOT_CONFIGURED",status:500});if(!s)throw new d("scheduled backup requires a `queryCoordinator` on the worker",{code:"BACKUP_NOT_CONFIGURED",status:500});if(!t||t.length===0)throw new d("scheduled backup requires an `adminToken` (or `env.LUNORA_ADMIN_TOKEN`) to authenticate the per-shard export gate",{code:"BACKUP_NOT_CONFIGURED",status:500});const u={authorization:`Bearer ${t}`,"content-type":"application/json"},l=e.backupTables;let f=0,w=0,E=[];await Qt(e,s,u,l,D=>{const T=Hr.encode(`${JSON.stringify(D)}
1
+ import{isLunoraError as Un,toErrorBody as Cn}from"@lunora/errors";import{e as Dt}from"./evict-oldest-BNXsKx4s.mjs";import{NOOP_EXECUTION_CONTEXT as Bn}from"./NOOP_EXECUTION_CONTEXT-YmXqH-jH.mjs";import{t as Nt,f as Ut}from"./base64-Bl1_r2k1.mjs";import{e as xn,a as Hn}from"./identity-header-C4Z5pldl.mjs";import{o as Se,b as Ln,p as Mn,m as jn,d as Kn,a as $n,r as Fn}from"./otlp-resource-DeXhb949.mjs";import{e as $e}from"./wire-codec-BsPOEXGn.mjs";import{e as Z,f as be,M as Ct,b as Gn,g as Qn,h as Bt,i as xt}from"./rest-routes-Dq17Zntv.mjs";import{LunoraError as d,toErrorResponse as tt}from"./LunoraError-DksAgIpa.mjs";import{a as j,m as me}from"./method-guard-BG_vJNTl.mjs";import{normalizeBackupPrefix as Ge,BACKUP_KEY_PREFIX as Qe,isBackupManifestKey as zn,backupObjectKeyOfManifest as Ht,backupObjectKey as Wn,backupManifestKey as Vn}from"./BACKUP_KEY_PREFIX-BOtSu-_3.mjs";import{toHex as Jn,buildStorageAdminRoutes as qn,STORAGE_UPLOAD_MAX_BODY_BYTES as Yn,STORAGE_PATH as Xn}from"./STORAGE_UPLOAD_MAX_BODY_BYTES-BqyO-1l6.mjs";import{runExportTap as Zn}from"./createKvCursorStore-DLm6fYoN.mjs";import{buildHealthRoutes as er,durableObjectProbe as tr,d1Probe as nr,presenceProbe as Ce}from"./HEALTH_PATH-jZsuCmSs.mjs";import{wrapResolverWithContract as rr}from"./composeIdentityResolvers-BHZ4jH8o.mjs";import{composeIdentityResolvers as Ss,routeIdentityResolvers as Ts}from"./composeIdentityResolvers-BHZ4jH8o.mjs";import{buildLogArchiveAdminRoutes as or}from"./LOG_ARCHIVE_PATH-jgHjdsz2.mjs";import{r as ar,f as nt,a as ce}from"./observability-vDK-rMbs.mjs";import{resolveShard as we,applyJurisdiction as rt}from"./applyJurisdiction-C0ddU7Tg.mjs";import{resolveSecurity as ot,handleCorsPreflight as sr,enforceOrigin as ir,decorateResponse as Be,enforceWebSocketOrigin as at}from"./decorateResponse-BuqVnrmc.mjs";const cr=e=>{const n=e??{};if(typeof n.bucket=="function")return n;const t={...n,bucketName:"default"};return t.bucket=()=>t,t},Lt="__lunoraBranch",dr=e=>typeof e=="object"&&e!==null&&Object.hasOwn(e,Lt),ur=`may not contain the reserved workflow branch-marker key ("${Lt}")`,ze=(e,n)=>{const t=Math.max(e.length,n.length);let r=e.length^n.length;for(let a=0;a<t;a+=1){const s=a<e.length?e.charCodeAt(a):0,u=a<n.length?n.charCodeAt(a):0;r|=s^u}return r===0},lr=(e,n,t,r)=>{const a=e.get(n);if(a!==void 0)return a;Dt(e,r);const s=t().catch(u=>{throw e.get(n)===s&&e.delete(n),u});return e.set(n,s),s},We=new TextEncoder,hr=Array.from({length:32},(e,n)=>n);new RegExp(`[${hr.map(e=>String.fromCodePoint(e)).join("")}]`,"u");const fr=64,pr=new Map,Mt=async e=>lr(pr,e,async()=>crypto.subtle.importKey("raw",We.encode(e),{hash:"SHA-256",name:"HMAC"},!1,["sign","verify"]),fr),jt=async(e,n)=>{const t=await Mt(e),r=await crypto.subtle.sign("HMAC",t,We.encode(n));return Nt(new Uint8Array(r))},mr=async(e,n,t)=>{const r=await Mt(e);return crypto.subtle.verify("HMAC",r,t,We.encode(n))},wr=["wnam","enam","sam","weur","eeur","apac","apac-ne","apac-se","oc","afr","me"];new Set(wr);const gr=new Set(["AE","BH","IL","IQ","IR","JO","KW","LB","OM","PS","QA","SA","SY","TR","YE"]),yr=-100,br=15,_r=e=>{const n=Number(e.longitude??Number.NaN);switch(e.continent){case"AF":return"afr";case"AS":return e.country!==void 0&&gr.has(e.country)?"me":"apac";case"EU":return Number.isFinite(n)&&n>br?"eeur":"weur";case"NA":return Number.isFinite(n)&&n<yr?"wnam":"enam";case"OC":return"oc";case"SA":return"sam";default:return}},st=e=>{const n=e.cf;return n===void 0?void 0:_r(n)},Kt="::relay::",Rr=(e,n)=>`${e}${Kt}${String(n)}`,$t="::replica::",Er=(e,n)=>`${e}${$t}${n}`,Ar=e=>{if(e==null||!/^\d+$/.test(e))return;const n=Number.parseInt(e,10);return Number.isSafeInteger(n)&&n>0?n:void 0},Sr=new Set(["1","enabled","on","true","yes"]),Tr=new Set(["0","disabled","false","no","off"]),Or=(e,n)=>{const t=(e??"").trim().toLowerCase();return Sr.has(t)?!0:Tr.has(t)?!1:n},Ft="v1",vr=6e4,kr=async(e,n={})=>{const t=(n.now??Date.now())+(n.ttlMs??vr),r=`${Ft}.${String(t)}`,a=await jt(e,r);return{expiresAtMs:t,token:`${r}.${a}`}},Ir=async(e,n,t=Date.now())=>{if(e.length===0||n.length===0)return!1;const r=n.split(".");if(r.length!==3)return!1;const[a,s,u]=r;if(a!==Ft||u.length===0)return!1;const l=Number(s);if(!Number.isFinite(l)||l<=t)return!1;let f;try{f=Ut(u)}catch{return!1}return mr(e,`${a}.${s}`,f)},P="/_lunora/admin/auth",Pr={INVITER_REQUIRED:400,ORG_SLUG_INVALID:400,ORG_SLUG_TAKEN:409,PASSWORD_TOO_LONG:400,PASSWORD_TOO_SHORT:400,USER_ALREADY_EXISTS:409,USER_NOT_FOUND:404},N=(e,n)=>{const t=e[n];if(typeof t!="string"||t==="")throw new d(`\`${n}\` is required`,{code:"BAD_REQUEST",status:400});return t},le=(e,n)=>{const t=e(n);if(t===void 0)throw new d(`\`${n}\` query parameter is required`,{code:"BAD_REQUEST",status:400});return t},Gt=e=>{if(typeof e=="string"||Array.isArray(e)&&e.every(n=>typeof n=="string"))return e},re=(e,n)=>typeof e[n]=="string"?e[n]:void 0,xe=(e,n)=>{const t=e[n];return typeof t=="object"&&t!==null&&!Array.isArray(t)?t:void 0},it=e=>{const n=Gt(e.role);if(n===void 0||typeof n=="string"&&n.trim()==="")throw new d("`role` is required",{code:"BAD_REQUEST",status:400});return n},ct=e=>{const n=e.permission;if(typeof n!="object"||n===null||Array.isArray(n))throw new d("`permission` object is required",{code:"BAD_REQUEST",status:400});const t={};for(const[r,a]of Object.entries(n))Array.isArray(a)&&a.every(s=>typeof s=="string")&&(t[r]=a);return t},Dr={[`${P}/capabilities`]:{build:()=>({}),http:"GET",method:"capabilities"},[`${P}/users`]:{build:({paging:e,query:n})=>{const t=n("sortDirection");return{...e,filterField:n("filterField"),filterValue:n("filterValue"),search:n("search"),searchField:n("searchField"),sortBy:n("sortBy"),sortDirection:t==="asc"||t==="desc"?t:void 0}},http:"GET",method:"listUsers"},[`${P}/sessions`]:{build:({paging:e,query:n})=>({...e,userId:n("userId")}),http:"GET",method:"listSessions"},[`${P}/accounts`]:{build:({query:e})=>({userId:le(e,"userId")}),http:"GET",method:"listAccounts"},[`${P}/passkeys`]:{build:({query:e})=>({userId:le(e,"userId")}),http:"GET",method:"listPasskeys"},[`${P}/organizations`]:{build:({paging:e})=>({...e}),http:"GET",method:"listOrganizations"},[`${P}/organizations/members`]:{build:({paging:e,query:n})=>({...e,organizationId:le(n,"organizationId")}),http:"GET",method:"listMembers"},[`${P}/organizations/invitations`]:{build:({paging:e,query:n})=>({...e,organizationId:le(n,"organizationId")}),http:"GET",method:"listInvitations"},[`${P}/config`]:{build:()=>({}),http:"GET",method:"config"},[`${P}/organizations/teams`]:{build:({paging:e,query:n})=>({...e,organizationId:le(n,"organizationId")}),http:"GET",method:"listTeams"},[`${P}/organizations/teams/members`]:{build:({paging:e,query:n})=>({...e,teamId:le(n,"teamId")}),http:"GET",method:"listTeamMembers"},[`${P}/organizations/roles`]:{build:({paging:e,query:n})=>({...e,organizationId:le(n,"organizationId")}),http:"GET",method:"listOrgRoles"},[`${P}/users/create`]:{build:({body:e})=>({data:xe(e,"data"),email:N(e,"email"),name:N(e,"name"),password:re(e,"password"),role:Gt(e.role)}),http:"POST",method:"createUser"},[`${P}/users/update`]:{build:({body:e})=>{const{data:n}=e;if(typeof n!="object"||n===null||Array.isArray(n))throw new d("`data` object is required",{code:"BAD_REQUEST",status:400});return{data:n,userId:N(e,"userId")}},http:"POST",method:"updateUser"},[`${P}/users/role`]:{build:({body:e})=>({role:it(e),userId:N(e,"userId")}),http:"POST",method:"setRole"},[`${P}/users/ban`]:{build:({body:e})=>({expiresInSeconds:typeof e.expiresInSeconds=="number"?e.expiresInSeconds:void 0,reason:re(e,"reason"),userId:N(e,"userId")}),http:"POST",method:"banUser"},[`${P}/users/unban`]:{build:({body:e})=>({userId:N(e,"userId")}),http:"POST",method:"unbanUser"},[`${P}/users/password`]:{build:({body:e})=>({newPassword:N(e,"newPassword"),userId:N(e,"userId")}),http:"POST",method:"setUserPassword",returns:"void"},[`${P}/users/remove`]:{build:({body:e})=>({userId:N(e,"userId")}),http:"POST",method:"removeUser",returns:"void"},[`${P}/users/impersonate`]:{build:({body:e})=>({userId:N(e,"userId")}),http:"POST",method:"impersonateUser"},[`${P}/sessions/revoke`]:{build:({body:e})=>({sessionId:N(e,"sessionId")}),http:"POST",method:"revokeUserSession",returns:"void"},[`${P}/sessions/revoke-all`]:{build:({body:e})=>({userId:N(e,"userId")}),http:"POST",method:"revokeUserSessions",returns:"void"},[`${P}/accounts/unlink`]:{build:({body:e})=>({accountId:N(e,"accountId"),userId:N(e,"userId")}),http:"POST",method:"unlinkAccount",returns:"void"},[`${P}/two-factor/disable`]:{build:({body:e})=>({userId:N(e,"userId")}),http:"POST",method:"disableTwoFactor",returns:"void"},[`${P}/passkeys/delete`]:{build:({body:e})=>({passkeyId:N(e,"passkeyId")}),http:"POST",method:"deletePasskey",returns:"void"},[`${P}/organizations/members/remove`]:{build:({body:e})=>({memberId:N(e,"memberId")}),http:"POST",method:"removeMember",returns:"void"},[`${P}/organizations/invitations/cancel`]:{build:({body:e})=>({invitationId:N(e,"invitationId")}),http:"POST",method:"cancelInvitation",returns:"void"},[`${P}/organizations/create`]:{build:({body:e})=>({logo:re(e,"logo"),metadata:xe(e,"metadata"),name:N(e,"name"),ownerId:re(e,"ownerId"),slug:re(e,"slug")}),http:"POST",method:"createOrganization"},[`${P}/organizations/update`]:{build:({body:e})=>({logo:re(e,"logo"),metadata:xe(e,"metadata"),name:re(e,"name"),organizationId:N(e,"organizationId"),slug:re(e,"slug")}),http:"POST",method:"updateOrganization"},[`${P}/organizations/remove`]:{build:({body:e})=>({organizationId:N(e,"organizationId")}),http:"POST",method:"deleteOrganization",returns:"void"},[`${P}/organizations/members/add`]:{build:({body:e})=>({organizationId:N(e,"organizationId"),role:re(e,"role"),userId:N(e,"userId")}),http:"POST",method:"addMember"},[`${P}/organizations/members/invite`]:{build:({body:e})=>({email:N(e,"email"),inviterId:re(e,"inviterId"),organizationId:N(e,"organizationId"),role:re(e,"role")}),http:"POST",method:"inviteMember"},[`${P}/organizations/members/role`]:{build:({body:e})=>({memberId:N(e,"memberId"),role:it(e)}),http:"POST",method:"updateMemberRole"},[`${P}/organizations/teams/create`]:{build:({body:e})=>({name:N(e,"name"),organizationId:N(e,"organizationId")}),http:"POST",method:"createTeam"},[`${P}/organizations/teams/update`]:{build:({body:e})=>({name:N(e,"name"),teamId:N(e,"teamId")}),http:"POST",method:"updateTeam"},[`${P}/organizations/teams/remove`]:{build:({body:e})=>({teamId:N(e,"teamId")}),http:"POST",method:"removeTeam",returns:"void"},[`${P}/organizations/teams/members/add`]:{build:({body:e})=>({teamId:N(e,"teamId"),userId:N(e,"userId")}),http:"POST",method:"addTeamMember"},[`${P}/organizations/teams/members/remove`]:{build:({body:e})=>({teamMemberId:N(e,"teamMemberId")}),http:"POST",method:"removeTeamMember",returns:"void"},[`${P}/organizations/roles/create`]:{build:({body:e})=>({organizationId:N(e,"organizationId"),permission:ct(e),role:N(e,"role")}),http:"POST",method:"createOrgRole"},[`${P}/organizations/roles/update`]:{build:({body:e})=>({permission:ct(e),roleId:N(e,"roleId")}),http:"POST",method:"updateOrgRole"},[`${P}/organizations/roles/remove`]:{build:({body:e})=>({roleId:N(e,"roleId")}),http:"POST",method:"deleteOrgRole",returns:"void"}},Nr=e=>{const n=async a=>{try{return await a()}catch(s){if(s instanceof d)throw s;const u=s,l=typeof u.code=="string"?u.code:"AUTH_ADMIN_ERROR";throw console.error("[lunora] auth admin operation failed:",s),new d("auth admin operation failed",{code:l,status:Pr[l]??500})}},t=async(a,s)=>{if(e.assertAdmin(a),a.method!==s.http)throw new d(`Auth admin endpoint requires ${s.http}`,{code:"METHOD_NOT_ALLOWED",status:405});const u=e.getAuthAdmin();if(u===void 0)throw new d("auth endpoints require an `authAdmin` on the worker",{code:"AUTH_NOT_CONFIGURED",status:400});const l=u[s.method];if(l===void 0)throw new d(`auth admin does not support \`${s.method}\``,{code:"AUTH_OP_NOT_SUPPORTED",status:400});const f=new URL(a.url),w={body:s.http==="POST"?await e.readJsonBody(a):{},paging:e.parsePaging(a),query:k=>e.queryParameter(f,k)},E=s.build(w),v=await n(()=>l(E));return Response.json(s.returns==="void"?{ok:!0}:v,{headers:{"content-type":"application/json"},status:200})},r={};for(const[a,s]of Object.entries(Dr))r[a]=u=>t(u,s);return r},Ur="__lunora_admin__:getAuthAuditLog",dt=e=>typeof e=="string"&&e!==""?e:void 0,ut=e=>typeof e=="number"&&Number.isFinite(e)&&e>=0?e:void 0,Cr=e=>async(t,r)=>{e.assertAdmin(t);const a=e.getReader();if(a===void 0)throw new d("the auth/security audit endpoint requires an `authAuditReader` on the worker",{code:"AUTH_AUDIT_NOT_CONFIGURED",status:400});const s=dt(r.actorId),u=dt(r.event),l=ut(r.sinceSeq),f=ut(r.limit),w={...s===void 0?{}:{actorId:s},...u===void 0?{}:{event:u},...l===void 0?{}:{sinceSeq:l},...f===void 0?{}:{limit:f}};let E;try{E=await a.read(w)}catch(k){throw k instanceof d?k:(console.error("[lunora] auth audit read failed:",k),new d("auth audit read failed",{code:"AUTH_AUDIT_READ_FAILED",status:500}))}const v={entries:E};return Response.json({result:$e(v)},{headers:{"content-type":"application/json"},status:200})},Br=(e,n)=>{const t=[],r=[];if(n&&n.length>0)for(const a of n)e.resolveTableSharding?.(a)?.mode.kind==="global"?r.push(a):t.push(a);return{globalTables:r,shardLocalTables:t}},xr=async(e,n,t,r,a,s,u)=>{if(t!==void 0&&r.length===0)return;const l=await e.orchestrateExport(s,{args:{tables:r},defaultShardKey:u,headers:n,tables:r});for(const f of l.shards)if(!f.error)for(const w of f.rows??[])a(w)},Qt=async(e,n,t,r,a,s)=>{const u=r??e.listSchemaTables?.();r===void 0&&e.listSchemaTables===void 0&&console.warn("[lunora] export: no table list available (`listSchemaTables` is unset and no `tables` were named), so only the default shard is reachable. A `.shardBy()` deployment's other shards will be missing from this export. Name the tables explicitly, or regenerate the worker so codegen supplies the list.");const{globalTables:l,shardLocalTables:f}=Br(e,u);await xr(n,t,u,f,a,s,e.defaultShardKey??"__root__");const w=e.exportGlobals;if((r===void 0||l.length>0)&&w)for await(const v of w({tables:l}))a(v)},Hr=new TextEncoder,Lr=1e3,zt=10,Mr=200,lt=8,Wt="lunoraBackupCron",ht=24*1048576,ft=e=>{const n=e.slice(0,zt).map(r=>Ht(r)),t=e.length-n.length;return`${n.join(", ")}${t>0?` (+${String(t)} more)`:""}`},jr=(e,n)=>{const t=new Uint8Array(new ArrayBuffer(n));let r=0;for(const a of e)t.set(a,r),r+=a.byteLength;return t},Ve=async(e,n,t,r)=>{if(t===void 0||!Number.isInteger(t)||t<=0)return{eligible:0,stale:[]};const a=[];let s;for(let u=0;u<Lr;u+=1){const l=await e.list({cursor:s,include:["customMetadata"],prefix:n});for(const f of l.objects)zn(f.key)&&f.customMetadata?.[Wt]===r&&a.push(f.key);if(!l.truncated||l.cursor===void 0)break;s=l.cursor}return{eligible:a.length,stale:a.toSorted((u,l)=>l.localeCompare(u)).slice(t)}},Kr=async(e,n,t,r,a)=>{const{stale:s}=await Ve(e,n,t,r),u=new Set(a),l=s.filter(g=>u.has(g)),f=l.slice(0,Mr),w=s.length-f.length,E=a.length-l.length;if(f.length===0)return{deleted:[],failed:[],ignored:E,remaining:w};const v=[],k=[];for(let g=0;g<f.length;g+=lt){const b=await Promise.allSettled(f.slice(g,g+lt).map(async _=>(await e.delete(Ht(_)),await e.delete(_),_)));for(const[_,p]of b.entries())p.status==="fulfilled"?v.push(p.value):k.push(f[g+_])}return v.length>0&&console.info(`[lunora] backup prune kept the newest ${String(t)} and deleted ${String(v.length)}: ${ft(v)}`),k.length>0&&console.warn(`[lunora] backup prune failed to remove ${String(k.length)}: ${ft(k)}`),{deleted:v,failed:k,ignored:E,remaining:w}},$r=async e=>{const n=e.backupStore;if(!n)throw new d("backup retention preview requires a `backupStore` on the worker",{code:"BACKUP_NOT_CONFIGURED",status:500});const t=Ge(e.backupPrefix??Qe),r=e.backupCron,{eligible:a,stale:s}=r===void 0?{eligible:0,stale:[]}:await Ve(n,t,e.backupRetain,r);return{cron:r,eligible:a,keep:e.backupRetain??0,prefix:t,wouldDelete:s}},Fr=async(e,n,t,r)=>{const a=e.backupStore,s=e.queryCoordinator;if(!a)throw new d("scheduled backup requires a `backupStore` on the worker",{code:"BACKUP_NOT_CONFIGURED",status:500});if(!s)throw new d("scheduled backup requires a `queryCoordinator` on the worker",{code:"BACKUP_NOT_CONFIGURED",status:500});if(!t||t.length===0)throw new d("scheduled backup requires an `adminToken` (or `env.LUNORA_ADMIN_TOKEN`) to authenticate the per-shard export gate",{code:"BACKUP_NOT_CONFIGURED",status:500});const u={authorization:`Bearer ${t}`,"content-type":"application/json"},l=e.backupTables;let f=0,w=0,E=[];await Qt(e,s,u,l,D=>{const T=Hr.encode(`${JSON.stringify(D)}
2
2
  `);if(f+=1,w+=T.byteLength,w>ht)throw new d(`scheduled backup reached ${String(w)} bytes of NDJSON, past the ${String(ht)}-byte limit for a snapshot assembled inside a Worker — nothing was written. Narrow it with \`backupTables\`, or take this snapshot off-platform with \`lunora backup create --bucket\`.`,{code:"BACKUP_TOO_LARGE",status:507});E.push(T)},n);const k=Ge(e.backupPrefix??Qe),g=new Date(r.scheduledTime).toISOString(),b=Wn(k,g),_=jr(E,w);E=[];const p=Jn(await crypto.subtle.digest("SHA-256",_));await a.put(b,_,{httpMetadata:{contentType:"application/x-ndjson"},sha256:p});const S={bytes:w,createdAt:g,cron:r.cron,file:b,id:g,rows:f,scheduledTime:r.scheduledTime,sha256:p,...l?{tables:l.join(",")}:{}};await a.put(Vn(b),`${JSON.stringify(S,void 0,2)}
3
3
  `,{customMetadata:{[Wt]:r.cron},httpMetadata:{contentType:"application/json"}});try{const{stale:D}=await Ve(a,k,e.backupRetain,r.cron);if(D.length>0){const T=D.slice(0,zt),x=D.length-T.length;console.info(`[lunora] backup retention: ${String(D.length)} snapshot(s) past the newest ${String(e.backupRetain)} — run \`lunora backup prune\` to remove them: ${T.join(", ")}${x>0?` (+${String(x)} more)`:""}`)}}catch(D){console.warn(`[lunora] backup ${b} was written, but the retention report failed:`,D)}},Gr=async(e,n)=>{const t=e.backupStore;if(!t)throw new d("backup prune requires a `backupStore` on the worker",{code:"BACKUP_NOT_CONFIGURED",status:500});const r=e.backupCron,a=e.backupRetain;if(r===void 0||a===void 0||!Number.isInteger(a)||a<=0)throw new d("backup prune needs a retention window: set `backupRetain` (and `backupCron`, which decides whose snapshots retention owns) on the worker. Without one there is nothing past the window to remove.",{code:"BACKUP_RETENTION_NOT_CONFIGURED",status:400});return Kr(t,Ge(e.backupPrefix??Qe),a,r,n)},Qr="/_lunora/admin/backup/retention",zr="/_lunora/admin/backup/prune",Wr=e=>{const{options:n,readJsonBody:t,requireAdminOption:r}=e,a=(l,f)=>{r(l,n.backupStore,{code:"BACKUP_NOT_CONFIGURED",message:`backup ${f} requires a \`backupStore\` on the worker`})},s=async l=>(j(l,"GET","Backup-retention"),a(l,"retention preview"),Response.json(await $r(n),{headers:{"cache-control":"no-store"}})),u=async l=>{j(l,"POST","Backup-prune"),a(l,"prune");const{confirm:f}=await t(l);if(!Array.isArray(f)||f.some(w=>typeof w!="string"))throw new d("backup prune requires a `confirm` array of the sidecar keys to remove — read them from `GET /_lunora/admin/backup/retention` and pass back the ones you mean to delete",{code:"BAD_REQUEST",status:400});return Response.json(await Gr(n,f),{headers:{"cache-control":"no-store"}})};return{[zr]:u,[Qr]:s}},pt=500,Vr=(e,n,t)=>{if(typeof e!="object"||e===null||Array.isArray(e))throw new d("each batch call must be an object",{code:"BAD_REQUEST",status:400});const r=e;if(typeof r.functionPath!="string")throw new d("each batch call needs a string `functionPath`",{code:"BAD_REQUEST",status:400});if(r.functionPath.startsWith("__lunora_relation__:")||r.functionPath.startsWith("__lunora_admin__"))throw new d("reserved function path cannot be batched",{code:"FORBIDDEN",status:403});if(r.args!==void 0&&(typeof r.args!="object"||r.args===null||Array.isArray(r.args)))throw new d("each batch call `args` must be an object",{code:"BAD_REQUEST",status:400});return{entry:{args:r.args===void 0?{}:r.args,clientId:typeof r.clientId=="string"?r.clientId:void 0,clientSeq:typeof r.clientSeq=="number"?r.clientSeq:void 0,functionPath:r.functionPath,id:typeof r.id=="number"?r.id:n,mutationId:typeof r.mutationId=="string"?r.mutationId:void 0},shardKey:typeof r.shardKey=="string"?r.shardKey:t}},Jr=(e,n)=>{if(e.length>pt)throw new d(`RPC batch exceeds the ${String(pt)}-call limit`,{code:"BAD_REQUEST",status:400});const t=new Map;for(const[r,a]of e.entries()){const{entry:s,shardKey:u}=Vr(a,r,n),l=t.get(u)??[];l.push(s),t.set(u,l)}return t},qr=new TextEncoder,Yr=e=>Nt(qr.encode(JSON.stringify(e))),Xr=e=>{const n={g:0,s:{},v:1};if(typeof e!="string"||e.length===0)return n;try{const t=JSON.parse(new TextDecoder().decode(Ut(e))),r=t.s&&typeof t.s=="object"?t.s:{},a={};for(const[s,u]of Object.entries(r))typeof u=="number"&&Number.isFinite(u)&&(a[s]=u);return{g:typeof t.g=="number"&&Number.isFinite(t.g)?t.g:0,s:a,v:1}}catch{return n}},Zr=e=>{const n=typeof e.table=="string"?e.table:"",t=typeof e.op=="string"?e.op:"",r=t==="delete"||t==="insert"||t==="update"?t:"upsert",a=typeof e.id=="string"?e.id:void 0;return{doc:(e.doc&&typeof e.doc=="object"?e.doc:void 0)??(a===void 0?{}:{_id:a}),op:r,table:n}},mt=(e,n,t)=>{for(const r of n)e.push(Zr(r));return t!==void 0&&n.length>=t},eo="/_lunora/admin/export",to="/_lunora/admin/import",no="/_lunora/admin/sync",ro="/_lunora/admin/connector/sync",oo="/_lunora/admin/apply",ao="/_lunora/admin/export-tap/run",so=new TextEncoder,io=async e=>{const t=await be(e,"Export")??{};if(t.tables===void 0)return{tables:void 0};if(!Array.isArray(t.tables))throw new d("Export `tables` must be a string array",{code:"BAD_REQUEST",status:400});const r=[];for(const a of t.tables){if(typeof a!="string"||a.length===0)throw new d("Export `tables` entries must be non-empty strings",{code:"BAD_REQUEST",status:400});r.push(a)}return{tables:r}},He=e=>Array.isArray(e)?e.filter(n=>typeof n=="string"):void 0,co=e=>{const{applyGlobals:n,exportCursorStore:t,exportSinks:r,knownTables:a,queryCoordinator:s,assertAdmin:u,requireAdminOption:l,resolveForwardContext:f,shardDO:w,streamExportRows:E,streamingImport:v,syncGlobals:k}=e,g=async(T,x)=>{const H=me(T,["POST"]);if(H)return H;const K=l(T,s,{code:"BAD_REQUEST",message:"Export endpoint requires a `queryCoordinator` on the worker"}),U=await io(T),{headers:W}=await f(T,x),$=new ReadableStream({async pull(V){const X=J=>{V.enqueue(so.encode(`${JSON.stringify(J)}
4
4
  `))};try{await E(K,W,U.tables,X),V.close()}catch(J){V.error(J)}}});return new Response($,{headers:{"content-type":"application/x-ndjson"},status:200})},b=async(T,x)=>{const H=me(T,["POST"]);if(H)return H;const K=l(T,s,{code:"BAD_REQUEST",message:"Sync endpoint requires a `queryCoordinator` on the worker"}),U=await Z(T),W=typeof U.cursors=="object"&&U.cursors!==null?U.cursors:{},$=typeof U.limit=="number"?U.limit:void 0,V=typeof U.globalCursor=="number"?U.globalCursor:0,X=He(U.tables),{headers:J}=await f(T,x),ae=X??a(),F=await K.orchestrateCdcSync(w,{cursors:W,headers:J,limit:$,tables:ae}),he=k?await k({limit:$,sinceSeq:V}):void 0;return Response.json({global:he,shards:F.shards},{status:200})},_=async(T,x)=>{const H=me(T,["POST"]);if(H)return H;const K=l(T,s,{code:"BAD_REQUEST",message:"Connector sync endpoint requires a `queryCoordinator` on the worker"}),U=await Z(T),W=Xr(U.cursor),$=typeof U.limit=="number"&&U.limit>0?U.limit:void 0,V=He(U.tables),{headers:X}=await f(T,x),J=V??a(),ae=await K.orchestrateCdcSync(w,{cursors:W.s,headers:X,limit:$,tables:J}),F=[],he={...W.s};let G=!1;for(const se of ae.shards)G=mt(F,se.changes??[],$)||G,he[se.shardKey]=se.cursor;let oe=W.g;if(k){const se=await k({limit:$,sinceSeq:W.g});G=mt(F,se.changes,$)||G,oe=se.cursor}const Te=Yr({g:oe,s:he,v:1}),Oe={changes:F,hasMore:G,nextCursor:Te};return Response.json(Oe,{status:200})},p=async(T,x)=>{const H=me(T,["POST"]);if(H)return H;const K=l(T,s,{code:"BAD_REQUEST",message:"Apply endpoint requires a `queryCoordinator` on the worker"}),U=await Z(T),$=(Array.isArray(U.batches)?U.batches:[]).map(F=>F).filter(F=>F!==null&&typeof F=="object"&&typeof F.shardKey=="string"&&Array.isArray(F.changes)),V=Array.isArray(U.globalChanges)?U.globalChanges:[],{headers:X}=await f(T,x),J=await K.orchestrateApplyCdc(w,{batches:$,headers:X}),ae=V.length>0&&n?await n({changes:V}):0;return Response.json({applied:J.applied+ae,failed:J.failed,ok:J.ok},{status:200})},S=async(T,x)=>{const H=me(T,["POST"]);if(H)return H;u(T);const{headers:K}=await f(T,x),U=await v(T,K);return Response.json(U,{headers:{"content-type":"application/json"},status:200})},D=async(T,x)=>{const H=me(T,["POST"]);if(H)return H;const K=l(T,s,{code:"BAD_REQUEST",message:"Export-tap endpoint requires a `queryCoordinator` on the worker"});if(r===void 0||Object.keys(r).length===0||t===void 0)throw new d("Export-tap endpoint requires `exportSinks` + `exportCursorStore` on the worker",{code:"EXPORT_TAP_NOT_CONFIGURED",status:400});const U=await Z(T),W=typeof U.sink=="string"?U.sink:void 0,$=typeof U.limit=="number"&&U.limit>0?U.limit:void 0,V=He(U.tables);if(W===void 0)throw new d("Export-tap `sink` must name a configured sink",{code:"BAD_REQUEST",status:400});const X=r[W];if(X===void 0)throw new d(`Export-tap sink "${W}" is not configured`,{code:"NOT_FOUND",status:404});const{headers:J}=await f(T,x),ae=V??a(),F=await Zn({coordinator:K,cursorStore:t,headers:J,limit:$,shardDO:w,sink:X,tables:ae});return Response.json(F,{headers:{"content-type":"application/json"},status:200})};return{[oo]:p,[ro]:_,[eo]:g,[ao]:D,[to]:S,[no]:b}},uo=(e,n)=>{let t;try{t=JSON.parse(e)}catch{return{error:{code:"BAD_ROW",line:n,message:"line is not valid JSON",table:""},ok:!1}}if(!t||typeof t!="object"||Array.isArray(t))return{error:{code:"BAD_ROW",line:n,message:"row must be a JSON object",table:""},ok:!1};const r=t;return typeof r.table!="string"||r.table.length===0?{error:{code:"BAD_ROW",line:n,message:"row is missing `table`",table:""},ok:!1}:!r.doc||typeof r.doc!="object"||Array.isArray(r.doc)?{error:{code:"BAD_ROW",line:n,message:"row is missing or malformed `doc`",table:r.table},ok:!1}:{doc:r.doc,ok:!0,table:r.table}},lo=(e,n,t,r,a)=>{if(t?.mode.kind==="shardBy"&&typeof t.mode.field=="string"){const s=e[t.mode.field];return s==null?{error:{code:"BAD_ROW",line:a,message:`row missing shard field "${t.mode.field}" for table "${n}"`,table:n},ok:!1}:{ok:!0,shardKey:typeof s=="string"?s:JSON.stringify(s)}}return{ok:!0,shardKey:r}},ho=async(e,n,t)=>{if(!e.body)throw new d("Import endpoint requires a request body",{code:"BAD_REQUEST",status:400});const r=[],a=[],s=new Map;let u=0,l=0;const f=e.body.getReader(),w=new TextDecoder;let E="",v=0;const k=g=>{l+=1;const b=g.trim();if(b.length===0)return;u+=1;const _=uo(b,l);if(!_.ok){r.push(_.error);return}const{doc:p,table:S}=_,D=n.resolveTableSharding?.(S);if(D?.mode.kind==="global"){a.push({doc:p,line:l,table:S});return}const T=lo(p,S,D,t,l);if(!T.ok){r.push(T.error);return}const x=s.get(T.shardKey);x?x.rows.push({doc:p,table:S}):s.set(T.shardKey,{rows:[{doc:p,table:S}],shardKey:T.shardKey,startLine:l})};for(;;){const{done:g,value:b}=await f.read();if(g)break;if(b&&(v+=b.byteLength,v>Ct))throw await f.cancel().catch(()=>{}),new d("Body too large",{code:"PAYLOAD_TOO_LARGE",status:413});E+=w.decode(b,{stream:!0});let _=E.indexOf(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/runtime",
3
- "version": "1.0.0-alpha.81",
3
+ "version": "1.0.0-alpha.82",
4
4
  "description": "Lunora Worker runtime: the RPC router, shard resolver, and query coordinator",
5
5
  "keywords": [
6
6
  "cloudflare",