Skip to content

Commit 5a8e891

Browse files
committed
fix(manifest): write manifest keys with / on every platform
path.relative yields backslashes on Windows and those strings become arweave/paths keys verbatim, so a deploy from Windows 404s every nested asset and never matches the dir/index.html directory-index rule.
1 parent 1aa3571 commit 5a8e891

2 files changed

Lines changed: 22 additions & 5 deletions

File tree

src/utils/__tests__/cache.test.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ describe('cache', () => {
239239
const files = getAllFiles(tempDir)
240240
expect(files).toHaveLength(2)
241241
expect(files).toContain('root.txt')
242-
expect(files).toContain(path.join('subdir', 'nested.txt'))
242+
expect(files).toContain('subdir/nested.txt')
243243
})
244244

245245
it('should handle deeply nested directories', () => {
@@ -249,7 +249,19 @@ describe('cache', () => {
249249

250250
const files = getAllFiles(tempDir)
251251
expect(files).toHaveLength(1)
252-
expect(files).toContain(path.join('a', 'b', 'c', 'deep.txt'))
252+
expect(files).toContain('a/b/c/deep.txt')
253+
})
254+
255+
it('always separates with / so manifest keys are portable', () => {
256+
const deepDir = path.join(tempDir, 'assets', 'img')
257+
fs.mkdirSync(deepDir, { recursive: true })
258+
fs.writeFileSync(path.join(deepDir, 'logo.svg'), '<svg />')
259+
260+
// These strings become arweave/paths manifest keys verbatim. A gateway
261+
// resolves `assets/img/logo.svg`; a backslash key would 404.
262+
const files = getAllFiles(tempDir)
263+
expect(files).toEqual(['assets/img/logo.svg'])
264+
expect(files.every((f) => !f.includes('\\'))).toBe(true)
253265
})
254266
})
255267
})

src/utils/cache.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,13 @@ export async function hashFile(filePath: string): Promise<string> {
6969
}
7070

7171
/**
72-
* Recursively get all files in a directory
73-
* Returns relative paths from the base directory
72+
* Recursively get all files in a directory.
73+
*
74+
* Returns paths relative to the base directory, always separated by `/`.
75+
* `path.relative` yields backslashes on Windows, and these strings become
76+
* manifest keys — a gateway looks up `assets/app.js`, so a manifest written
77+
* as `assets\app.js` 404s every nested asset. Normalizing here also keeps
78+
* the `dir/index.html` directory-index check working on every platform.
7479
*/
7580
export function getAllFiles(dirPath: string, basePath: string = dirPath): string[] {
7681
const files: string[] = []
@@ -83,7 +88,7 @@ export function getAllFiles(dirPath: string, basePath: string = dirPath): string
8388
files.push(...getAllFiles(fullPath, basePath))
8489
} else {
8590
// Store relative path for consistent hashing
86-
files.push(path.relative(basePath, fullPath))
91+
files.push(path.relative(basePath, fullPath).split(path.sep).join('/'))
8792
}
8893
}
8994

0 commit comments

Comments
 (0)