1- import type { KVNamespace } from '@cloudflare/workers-types'
21import type { Context } from 'hono'
3- import { getContentFromKVAsset } from './workers-utils'
2+ import { getMimeType } from 'hono/utils/mime'
3+ import {
4+ getShopsData ,
5+ getShopInfo ,
6+ getAuthorInfo ,
7+ getShopImageResponse ,
8+ } from './data'
49
510export const BASE_URL = 'http://localhost/'
611
@@ -9,7 +14,9 @@ export type Env = {
914 BASE_URL : string
1015 }
1116 Bindings : {
12- __STATIC_CONTENT : KVNamespace
17+ ASSETS ?: Fetcher
18+ __STATIC_CONTENT ?: KVNamespace
19+ MCP_OBJECT ?: DurableObjectNamespace
1320 }
1421}
1522
@@ -52,7 +59,7 @@ type listShopsResult = {
5259 totalCount : number
5360}
5461
55- type listShopsWithPagerResult = {
62+ export type listShopsWithPagerResult = {
5663 shops : Shop [ ]
5764 totalCount : number
5865 pageInfo : pageInfo
@@ -106,11 +113,7 @@ export const listShops = async (
106113 options : Options
107114) : Promise < listShopsResult > => {
108115 const { limit = 10 , offset = 0 } = params
109- const c = options . c
110- const buffer = await getContentFromKVAsset ( 'shops.json' , {
111- namespace : c . env ? c . env . __STATIC_CONTENT : undefined ,
112- } )
113- const data = arrayBufferToJSON ( buffer )
116+ const data = await getShopsData ( options . c . env . ASSETS , options . c . req . url )
114117
115118 const shopIdsAll = data [ 'shopIds' ]
116119 const totalCount = shopIdsAll . length
@@ -147,29 +150,31 @@ export const findIndexFromId = async (
147150export const getShop = async ( id : string , options : Options ) : Promise < Shop > => {
148151 let shop : Shop
149152 try {
150- const c = options . c
151- const buffer = await getContentFromKVAsset ( `shops/${ id } /info.json` , {
152- namespace : c . env ? c . env . __STATIC_CONTENT : undefined ,
153- } )
154- shop = arrayBufferToJSON ( buffer )
155- } catch ( e ) {
156- throw new Error ( `"shops/${ id } /info.json" is not found: ${ e } ` )
157- }
153+ shop = ( await getShopInfo (
154+ id ,
155+ options . c . env . ASSETS ,
156+ options . c . req . url
157+ ) ) as Shop
158+ } catch { } // Do nothing
158159 if ( ! shop ) return
159160 shop . photos ?. map ( ( photo : Photo ) => {
160161 photo . url = fixPhotoURL ( { shopId : id , path : photo . name } , options )
161162 } )
162163 return shop
163164}
164165
165- export const getAuthor = async ( id : string ) : Promise < Author > => {
166+ export const getAuthor = async (
167+ id : string ,
168+ options ?: Options
169+ ) : Promise < Author > => {
166170 let author : Author
167171 try {
168- const buffer = await getContentFromKVAsset ( `authors/${ id } /info.json` )
169- author = arrayBufferToJSON ( buffer )
170- } catch ( e ) {
171- throw new Error ( `"authors/${ id } /info.json" is not found: ${ e } ` )
172- }
172+ author = ( await getAuthorInfo (
173+ id ,
174+ options ?. c . env ?. ASSETS ,
175+ options ?. c . req ?. url
176+ ) ) as Author
177+ } catch { } // Do nothing
173178 if ( ! author ) return
174179 return author
175180}
@@ -188,45 +193,35 @@ const fixPhotoURL = (
188193 return `${ options . c . var . BASE_URL } images/${ shopId } /${ path } `
189194}
190195
191- const arrayBufferToJSON = ( arrayBuffer : ArrayBuffer ) => {
192- if ( arrayBuffer instanceof ArrayBuffer ) {
193- const text = new TextDecoder ( ) . decode ( arrayBuffer )
194- if ( text ) return JSON . parse ( text )
195- } else {
196- return arrayBuffer
197- }
198- }
199-
200196export const getShopPhotosWithData = async (
201197 shopId : string ,
202198 options : Options
203199) : Promise < PhotoWithData [ ] > => {
204200 const shop = await getShop ( shopId , options )
205-
206- const photos = await Promise . all (
207- shop . photos ?. map ( async ( photo ) : Promise < PhotoWithData | null > => {
208- try {
209- const buffer = await getContentFromKVAsset (
210- `shops/${ shopId } /${ photo . name } ` ,
211- {
212- namespace : options . c . env
213- ? options . c . env . __STATIC_CONTENT
214- : undefined ,
215- }
216- )
217- const base64 = arrayBufferToBase64 ( buffer )
218- return {
201+ if ( ! shop || ! shop . photos ) return [ ]
202+
203+ const photos : PhotoWithData [ ] = [ ]
204+
205+ for ( const photo of shop . photos ) {
206+ try {
207+ const response = await getShopImageResponse (
208+ shopId ,
209+ photo . name ,
210+ options . c . env . ASSETS ,
211+ options . c . var . BASE_URL
212+ )
213+ if ( response . ok ) {
214+ const arrayBuffer = await response . arrayBuffer ( )
215+ const base64 = arrayBufferToBase64 ( arrayBuffer )
216+ photos . push ( {
219217 ...photo ,
220218 base64,
221- }
222- } catch ( e ) {
223- console . error ( `Failed to load image ${ photo . name } :` , e )
224- return null
219+ } )
225220 }
226- } ) || [ ]
227- )
221+ } catch { } // Do nothing
222+ }
228223
229- return photos . filter ( Boolean )
224+ return photos
230225}
231226
232227export const arrayBufferToBase64 = ( arrayBuffer : ArrayBuffer ) : string => {
@@ -237,3 +232,24 @@ export const arrayBufferToBase64 = (arrayBuffer: ArrayBuffer): string => {
237232 }
238233 return btoa ( binary )
239234}
235+
236+ export const getShopImage = async (
237+ shopId : string ,
238+ filename : string ,
239+ assets : Fetcher ,
240+ baseUrl : string
241+ ) : Promise < Response > => {
242+ const mimeType = getMimeType ( filename )
243+ const response = await getShopImageResponse ( shopId , filename , assets , baseUrl )
244+
245+ if ( response . ok ) {
246+ const content = await response . arrayBuffer ( )
247+ return new Response ( content , {
248+ headers : {
249+ 'Content-Type' : mimeType || 'application/octet-stream' ,
250+ } ,
251+ } )
252+ }
253+
254+ return new Response ( null , { status : 404 } )
255+ }
0 commit comments