UNPKG

bknd

Version:

Lightweight Firebase/Supabase alternative built to run anywhere — incl. Next.js, React Router, Astro, Cloudflare, Bun, Node, AWS Lambda & more.

2 lines (1 loc) 4.09 kB
import E from"node:path";import{createRuntimeApp as x}from"bknd/adapter";import{config as A}from"bknd";import{serveStatic as $}from"hono/bun";async function R({distPath:r,serveStatic:t,...e}={},n=Bun.env){let a=E.resolve(r??"./node_modules/bknd/dist","static");return h(),await x({serveStatic:t??$({root:a}),...e},n)}function P(r={},t=Bun.env){let e;return async n=>(e||(e=await R(r,t)),e.fetch(n))}function z({app:r,distPath:t,connection:e,config:n,options:a,port:s=A.server.default_port,onBuilt:o,buildConfig:i,adminOptions:l,serveStatic:c,beforeBuild:u,...f}={},m=Bun.env){Bun.serve({...f,port:s,fetch:P({app:r,connection:e,config:n,options:a,onBuilt:o,buildConfig:i,adminOptions:l,distPath:t,serveStatic:c,beforeBuild:u},m)}),console.info(`Server is running on http://localhost:${s}`)}import{registries as k}from"bknd";import{readFile as y,readdir as F,stat as g,unlink as L,writeFile as O}from"node:fs/promises";import{StorageAdapter as q,guessMimeType as v}from"bknd";import{parse as j,s as w,isFile as b}from"bknd/utils";var B=w.object({path:w.string({default:"./"})},{title:"Local",description:"Local file system storage",additionalProperties:!1}),p=class extends q{config;constructor(t={}){super(),this.config=j(B,t)}getSchema(){return B}getName(){return"local"}async listObjects(t){let e=await F(this.config.path);return await Promise.all(e.filter(a=>!t||a.startsWith(t)).map(async a=>{let s=await g(`${this.config.path}/${a}`);return{key:a,last_modified:s.mtime,size:s.size}}))}async computeEtag(t){let e=b(t)?t:new Response(t),n=await crypto.subtle.digest("SHA-256",await e.arrayBuffer());return`"${Array.from(new Uint8Array(n)).map(o=>o.toString(16).padStart(2,"0")).join("")}"`}async putObject(t,e){if(e===null)throw new Error("Body is empty");let n=`${this.config.path}/${t}`;return await O(n,b(e)?e.stream():e),await this.computeEtag(e)}async deleteObject(t){try{await L(`${this.config.path}/${t}`)}catch{}}async objectExists(t){try{return(await g(`${this.config.path}/${t}`)).isFile()}catch{return!1}}parseRangeHeader(t,e){let n=t.match(/^bytes=(\d*)-(\d*)$/);if(!n)return null;let[,a,s]=n,o=a?Number.parseInt(a,10):0,i=s?Number.parseInt(s,10):e-1;return!a&&s&&(o=Math.max(0,e-Number.parseInt(s,10)),i=e-1),o<0||i>=e||o>i?null:{start:o,end:i}}async getObject(t,e){try{let n=`${this.config.path}/${t}`,s=(await g(n)).size,o=v(t),i=new Headers({"Accept-Ranges":"bytes","Content-Type":o||"application/octet-stream"}),l=e.get("range");if(l){let c=this.parseRangeHeader(l,s);if(!c)return i.set("Content-Range",`bytes */${s}`),new Response("",{status:416,headers:i});let{start:u,end:f}=c,d=(await y(n,{encoding:null})).slice(u,f+1);return i.set("Content-Range",`bytes ${u}-${f}/${s}`),i.set("Content-Length",d.length.toString()),new Response(d,{status:206,headers:i})}else{let c=await y(n);return i.set("Content-Length",c.length.toString()),new Response(c,{status:200,headers:i})}}catch{return new Response("",{status:404})}}getObjectUrl(t){throw new Error("Method not implemented.")}async getObjectMeta(t){let e=await g(`${this.config.path}/${t}`);return{type:v(t)||"application/octet-stream",size:e.size}}toJSON(t){return{type:this.getName(),config:this.config}}};var C=!1;function h(){return C||(k.media.register("local",p),C=!0),(r={})=>new p(r).toJSON(!0)}import{Database as S}from"bun:sqlite";import{genericSqlite as H}from"bknd";import{omitKeys as M}from"bknd/utils";function nt(r){let t;return r&&("database"in r&&r.database?t=r.database:r.url&&(t=new S(r.url))),t||(t=new S(":memory:")),H("bun-sqlite",t,e=>{let n=a=>t.prepare(a);return{db:t,query:e.buildQueryFn({all:(a,s)=>n(a).all(...s||[]),run:(a,s)=>{let{changes:o,lastInsertRowid:i}=n(a).run(...s||[]);return{insertId:e.parseBigInt(i),numAffectedRows:e.parseBigInt(o)}}}),close:()=>t.close()}},M(r??{},["database","url","name","supports"]))}async function at(r,t){await Bun.write(r,t)}async function st(r){return await Bun.file(r).text()}export{p as StorageLocalAdapter,nt as bunSqlite,R as createApp,P as createHandler,B as localAdapterConfig,st as reader,h as registerLocalMediaAdapter,z as serve,at as writer};