11export async function KVStorage ( {
22 runtime = 'node' ,
33 databaseName = 'kvstorage' ,
4- storageName = 'storage'
4+ storageName = 'storage' ,
5+ databaseBindings
56 } :{
67 runtime ?:string ,
78 storageName ?:string ,
8- databaseName ?:string
9+ databaseName ?:string ,
10+ databaseBindings ?:any
911 } ) : Promise < any > {
1012
1113 function isAlphanumeric ( str :string ) {
@@ -17,27 +19,32 @@ export async function KVStorage({
1719 }
1820
1921 if ( ! isAlphanumeric ( runtime ) ) showError ( 'Runtime must be Alphanumeric' )
22+ if ( ! isAlphanumeric ( databaseName ) ) showError ( 'storageName must be Alphanumeric' )
2023 if ( ! isAlphanumeric ( storageName ) ) showError ( 'storageName must be Alphanumeric' )
2124
2225 switch ( runtime . toLowerCase ( ) ) {
2326 case 'node' :
24- const runnode = await import ( './node-kv-storage' )
27+ let nodepkg = './node-kv-storage'
28+ if ( typeof caches !== "undefined" && typeof global === "undefined" && typeof window === "undefined" ) nodepkg = ''
29+ const runnode = await import ( nodepkg )
2530 const dbnode = await runnode . NodeKVStorage . init ( {
2631 dataDirName :databaseName ,
2732 storageName
2833 } )
2934 return dbnode
3035 break
3136 case 'deno' :
32- const rundeno = await import ( './deno-kv-storage' )
37+ let denopkg = './deno-kv-storage'
38+ const rundeno = await import ( denopkg )
3339 const dbdeno = await rundeno . DenoKVStorage . init ( {
3440 dataDirName :databaseName ,
3541 storageName
3642 } )
3743 return dbdeno
3844 break
3945 case 'bun' :
40- const runbun = await import ( './bun-kv-storage' )
46+ let bunpkg = './bun-kv-storage'
47+ const runbun = await import ( bunpkg )
4148 const dbbun = await runbun . BunKVStorage . init ( {
4249 dataDirName :databaseName ,
4350 storageName
@@ -46,17 +53,165 @@ export async function KVStorage({
4653 break
4754 case 'browser' :
4855 let browserpkg = './browser-kv-storage'
49- if ( window ) browserpkg = './browser-kv-storage.js'
56+ if ( typeof window !== "undefined" && typeof window . document !== "undefined" ) browserpkg = './browser-kv-storage.js'
5057 const runbrowser = await import ( browserpkg )
51- //const runbrowser = await import('./browser-kv-storage')
5258 const dbbrowser = await runbrowser . BrowserKVStorage . init ( {
5359 databaseName,
5460 storageName
5561 } )
5662 return dbbrowser
5763 break
64+ case 'cloudflare' :
65+ //let cloudflarepkg = 'server.js'
66+ //if(typeof caches !== "undefined" && typeof global === "undefined" && typeof window === "undefined")cloudflarepkg = './cloudflare-kv-storage'
67+ //const runcloudflare = await import(cloudflarepkg)
68+ const dbcloudflare = await CloudflareKVStorage . init ( {
69+ databaseBindings,
70+ storageName
71+ } )
72+ return dbcloudflare
73+ break
5874 default :
5975 showError ( 'Runtime unknown' )
6076 }
6177
6278}
79+
80+ class CloudflareKVStorage {
81+
82+ private _storageName :string
83+ private _databaseBindings :any
84+
85+ private constructor ( {
86+ databaseBindings,
87+ storageName
88+ } :{
89+ databaseBindings :any ,
90+ storageName :string
91+ } ) {
92+
93+ this . _databaseBindings = databaseBindings
94+ this . _storageName = storageName
95+ }
96+
97+ private isAlphanumeric ( str :string ) {
98+ return / ^ [ a - z A - Z 0 - 9 ] + $ / . test ( str ) ;
99+ }
100+
101+ private showError ( msg :string = 'Error' ) {
102+ throw new Error ( msg )
103+ }
104+
105+ public static async init ( {
106+ databaseBindings,
107+ storageName,
108+ } :{
109+ databaseBindings :any ,
110+ storageName :string
111+ } ) : Promise < CloudflareKVStorage > {
112+
113+ function isAlphanumeric ( str :string ) {
114+ return / ^ [ a - z A - Z 0 - 9 ] + $ / . test ( str ) ;
115+ }
116+
117+ function showError ( msg :string = 'Error' ) {
118+ throw new Error ( msg )
119+ }
120+
121+ if ( ! isAlphanumeric ( storageName ) ) showError ( 'storageName must be Alphanumeric' )
122+
123+ const stmt = databaseBindings . prepare ( 'CREATE TABLE IF NOT EXISTS ' + storageName + ' (key text NOT NULL PRIMARY KEY,value text NOT NULL)' )
124+
125+ const values = await stmt . run ( )
126+
127+ return new CloudflareKVStorage ( { databaseBindings, storageName} )
128+ }
129+
130+ public async put ( key :string , value :string ) {
131+
132+ if ( ! this . isAlphanumeric ( key ) ) this . showError ( 'Key must be Alphanumeric' )
133+
134+ const stmt = this . _databaseBindings . prepare ( 'SELECT value FROM ' + this . _storageName + ' WHERE key = ?1' ) . bind ( key ) ;
135+ const values = await stmt . first ( )
136+ if ( values == null ) {
137+ const stmt = this . _databaseBindings . prepare ( 'INSERT INTO ' + this . _storageName + ' (key,value) VALUES (?1,?2)' ) . bind ( key , value ) ;
138+ const values = await stmt . run ( )
139+ return values . succes
140+ } else {
141+ const stmt = this . _databaseBindings . prepare ( 'UPDATE ' + this . _storageName + ' SET value = ?2 WHERE key = ?1' ) . bind ( key , value ) ;
142+ const values = await stmt . run ( )
143+ return values . success
144+ }
145+
146+ }
147+
148+ public async get ( key :string ) {
149+
150+ if ( ! this . isAlphanumeric ( key ) ) this . showError ( 'Key must be Alphanumeric' )
151+
152+ const stmt = this . _databaseBindings . prepare ( 'SELECT value FROM ' + this . _storageName + ' WHERE key = ?1' ) . bind ( key ) ;
153+ const values = await stmt . first ( ) ;
154+ let output
155+ if ( values == null ) {
156+ output = false
157+ } else {
158+ output = values . value
159+ }
160+ return output
161+
162+ }
163+
164+ public async delete ( key :string ) {
165+
166+ if ( ! this . isAlphanumeric ( key ) ) this . showError ( 'Key must be Alphanumeric' )
167+
168+ const stmt = this . _databaseBindings . prepare ( 'DELETE FROM ' + this . _storageName + ' WHERE key = ?1' ) . bind ( key ) ;
169+ const values = await stmt . first ( ) ;
170+ let output
171+ if ( values == null ) {
172+ output = false
173+ } else {
174+ output = true
175+ }
176+ return output
177+
178+ }
179+
180+ public async has ( key :string ) {
181+
182+ if ( ! this . isAlphanumeric ( key ) ) this . showError ( 'Key must be Alphanumeric' )
183+
184+ const stmt = this . _databaseBindings . prepare ( 'SELECT value FROM ' + this . _storageName + ' WHERE key = ?1' ) . bind ( key ) ;
185+ const values = await stmt . first ( ) ;
186+ let output
187+ if ( values == null ) {
188+ output = false
189+ } else {
190+ output = true
191+ }
192+ return output
193+
194+ }
195+
196+ public async list ( ) {
197+
198+ const stmt = this . _databaseBindings . prepare ( 'SELECT key FROM ' + this . _storageName ) . bind ( ) ;
199+ const values = await stmt . all ( ) ;
200+ let output
201+ if ( values . success ) {
202+ let keys :Array < string > = [ ]
203+ values . results . forEach ( ( obj :any ) => {
204+ keys . push ( obj . key )
205+ } )
206+ let result = {
207+ keys :keys ,
208+ complete :true
209+ }
210+
211+ output = result
212+ } else {
213+ output = false
214+ }
215+ return output
216+ }
217+ }
0 commit comments