@@ -2,15 +2,14 @@ import { createHmac } from 'node:crypto'
22import { createReadStream , promises as fs } from 'node:fs'
33import { tmpdir } from 'node:os'
44import { dirname , join , relative , resolve , sep } from 'node:path'
5- import { platform } from 'node:process'
65
76import { HTTPServer } from '@netlify/dev-utils'
87
98import { ListResponse } from './backend/list.ts'
109import { SIGNED_URL_ACCEPT_HEADER } from './client.ts'
1110import { decodeMetadata , encodeMetadata , METADATA_HEADER_INTERNAL } from './metadata.ts'
1211import { HTTPMethod } from './types.ts'
13- import { isNodeError , Logger } from './util.ts'
12+ import { decodeName , encodeName , isNodeError , Logger } from './util.ts'
1413
1514const API_URL_PATH = / \/ a p i \/ v 1 \/ b l o b s \/ (?< site_id > [ ^ / ] + ) \/ (?< store_name > [ ^ / ] + ) \/ ? (?< key > [ ^ ? ] * ) /
1615const LEGACY_API_URL_PATH = / \/ a p i \/ v 1 \/ s i t e s \/ (?< site_id > [ ^ / ] + ) \/ b l o b s \/ ? (?< key > [ ^ ? ] * ) /
@@ -231,7 +230,7 @@ export class BlobsServer {
231230 req : Request
232231 url : URL
233232 } ) : Promise < Response > {
234- const { dataPath, rootPath, req , url } = options
233+ const { dataPath, rootPath, url } = options
235234 const directories = url . searchParams . get ( 'directories' ) === 'true'
236235 const prefix = url . searchParams . get ( 'prefix' ) ?? ''
237236 const result : ListResponse = {
@@ -259,10 +258,7 @@ export class BlobsServer {
259258 private async listStores ( rootPath : string , prefix : string ) : Promise < Response > {
260259 try {
261260 const allStores = await fs . readdir ( rootPath )
262- const filteredStores = allStores
263- // Store names are URI-encoded on Windows, so we must decode them first.
264- . map ( ( store ) => ( platform === 'win32' ? decodeURIComponent ( store ) : store ) )
265- . filter ( ( store ) => store . startsWith ( prefix ) )
261+ const filteredStores = allStores . map ( decodeName ) . filter ( ( store ) => store . startsWith ( prefix ) )
266262
267263 return Response . json ( { stores : filteredStores } )
268264 } catch ( error ) {
@@ -364,7 +360,7 @@ export class BlobsServer {
364360 parts = parts . slice ( 1 )
365361 }
366362
367- const [ siteID , rawStoreName , ...key ] = parts
363+ const [ siteID , rawStoreName , ...rawKey ] = parts
368364
369365 if ( ! siteID ) {
370366 return { }
@@ -376,9 +372,9 @@ export class BlobsServer {
376372 return { rootPath }
377373 }
378374
379- // On Windows, file paths can't include the `:` character, so we URI-encode
380- // them.
381- const storeName = platform === 'win32' ? encodeURIComponent ( rawStoreName ) : rawStoreName
375+ const key = rawKey . map ( encodeName )
376+
377+ const storeName = encodeName ( rawStoreName )
382378 const storePath = resolve ( rootPath , storeName )
383379 const dataPath = resolve ( storePath , ...key )
384380 const metadataPath = resolve ( this . directory , 'metadata' , siteID , storeName , ...key )
0 commit comments