fix(core): text files missclassified as binary
This commit is contained in:
@@ -166,7 +166,6 @@ export namespace File {
|
|||||||
"efi",
|
"efi",
|
||||||
"rom",
|
"rom",
|
||||||
"com",
|
"com",
|
||||||
"bat",
|
|
||||||
"cmd",
|
"cmd",
|
||||||
"ps1",
|
"ps1",
|
||||||
"sh",
|
"sh",
|
||||||
@@ -203,11 +202,77 @@ export namespace File {
|
|||||||
"x3f",
|
"x3f",
|
||||||
])
|
])
|
||||||
|
|
||||||
|
const textExtensions = new Set([
|
||||||
|
"ts",
|
||||||
|
"tsx",
|
||||||
|
"mts",
|
||||||
|
"cts",
|
||||||
|
"mtsx",
|
||||||
|
"ctsx",
|
||||||
|
"js",
|
||||||
|
"jsx",
|
||||||
|
"mjs",
|
||||||
|
"cjs",
|
||||||
|
"sh",
|
||||||
|
"bash",
|
||||||
|
"zsh",
|
||||||
|
"fish",
|
||||||
|
"ps1",
|
||||||
|
"psm1",
|
||||||
|
"cmd",
|
||||||
|
"bat",
|
||||||
|
"json",
|
||||||
|
"jsonc",
|
||||||
|
"json5",
|
||||||
|
"yaml",
|
||||||
|
"yml",
|
||||||
|
"toml",
|
||||||
|
"md",
|
||||||
|
"mdx",
|
||||||
|
"txt",
|
||||||
|
"xml",
|
||||||
|
"html",
|
||||||
|
"htm",
|
||||||
|
"css",
|
||||||
|
"scss",
|
||||||
|
"sass",
|
||||||
|
"less",
|
||||||
|
"graphql",
|
||||||
|
"gql",
|
||||||
|
"sql",
|
||||||
|
"ini",
|
||||||
|
"cfg",
|
||||||
|
"conf",
|
||||||
|
"env",
|
||||||
|
])
|
||||||
|
|
||||||
|
const textNames = new Set([
|
||||||
|
"dockerfile",
|
||||||
|
"makefile",
|
||||||
|
".gitignore",
|
||||||
|
".gitattributes",
|
||||||
|
".editorconfig",
|
||||||
|
".npmrc",
|
||||||
|
".nvmrc",
|
||||||
|
".prettierrc",
|
||||||
|
".eslintrc",
|
||||||
|
])
|
||||||
|
|
||||||
function isImageByExtension(filepath: string): boolean {
|
function isImageByExtension(filepath: string): boolean {
|
||||||
const ext = path.extname(filepath).toLowerCase().slice(1)
|
const ext = path.extname(filepath).toLowerCase().slice(1)
|
||||||
return imageExtensions.has(ext)
|
return imageExtensions.has(ext)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isTextByExtension(filepath: string): boolean {
|
||||||
|
const ext = path.extname(filepath).toLowerCase().slice(1)
|
||||||
|
return textExtensions.has(ext)
|
||||||
|
}
|
||||||
|
|
||||||
|
function isTextByName(filepath: string): boolean {
|
||||||
|
const name = path.basename(filepath).toLowerCase()
|
||||||
|
return textNames.has(name)
|
||||||
|
}
|
||||||
|
|
||||||
function getImageMimeType(filepath: string): string {
|
function getImageMimeType(filepath: string): string {
|
||||||
const ext = path.extname(filepath).toLowerCase().slice(1)
|
const ext = path.extname(filepath).toLowerCase().slice(1)
|
||||||
const mimeTypes: Record<string, string> = {
|
const mimeTypes: Record<string, string> = {
|
||||||
@@ -445,7 +510,9 @@ export namespace File {
|
|||||||
return { type: "text", content: "" }
|
return { type: "text", content: "" }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isBinaryByExtension(file)) {
|
const text = isTextByExtension(file) || isTextByName(file)
|
||||||
|
|
||||||
|
if (isBinaryByExtension(file) && !text) {
|
||||||
return { type: "binary", content: "" }
|
return { type: "binary", content: "" }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -454,7 +521,7 @@ export namespace File {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const mimeType = Filesystem.mimeType(full)
|
const mimeType = Filesystem.mimeType(full)
|
||||||
const encode = await shouldEncode(mimeType)
|
const encode = text ? false : await shouldEncode(mimeType)
|
||||||
|
|
||||||
if (encode && !isImage(mimeType)) {
|
if (encode && !isImage(mimeType)) {
|
||||||
return { type: "binary", content: "", mimeType }
|
return { type: "binary", content: "", mimeType }
|
||||||
|
|||||||
@@ -283,6 +283,66 @@ describe("file/index Bun.file patterns", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe("shouldEncode() logic", () => {
|
describe("shouldEncode() logic", () => {
|
||||||
|
test("treats .ts files as text", async () => {
|
||||||
|
await using tmp = await tmpdir()
|
||||||
|
const filepath = path.join(tmp.path, "test.ts")
|
||||||
|
await fs.writeFile(filepath, "export const value = 1", "utf-8")
|
||||||
|
|
||||||
|
await Instance.provide({
|
||||||
|
directory: tmp.path,
|
||||||
|
fn: async () => {
|
||||||
|
const result = await File.read("test.ts")
|
||||||
|
expect(result.type).toBe("text")
|
||||||
|
expect(result.content).toBe("export const value = 1")
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test("treats .mts files as text", async () => {
|
||||||
|
await using tmp = await tmpdir()
|
||||||
|
const filepath = path.join(tmp.path, "test.mts")
|
||||||
|
await fs.writeFile(filepath, "export const value = 1", "utf-8")
|
||||||
|
|
||||||
|
await Instance.provide({
|
||||||
|
directory: tmp.path,
|
||||||
|
fn: async () => {
|
||||||
|
const result = await File.read("test.mts")
|
||||||
|
expect(result.type).toBe("text")
|
||||||
|
expect(result.content).toBe("export const value = 1")
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test("treats .sh files as text", async () => {
|
||||||
|
await using tmp = await tmpdir()
|
||||||
|
const filepath = path.join(tmp.path, "test.sh")
|
||||||
|
await fs.writeFile(filepath, "#!/usr/bin/env bash\necho hello", "utf-8")
|
||||||
|
|
||||||
|
await Instance.provide({
|
||||||
|
directory: tmp.path,
|
||||||
|
fn: async () => {
|
||||||
|
const result = await File.read("test.sh")
|
||||||
|
expect(result.type).toBe("text")
|
||||||
|
expect(result.content).toBe("#!/usr/bin/env bash\necho hello")
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test("treats Dockerfile as text", async () => {
|
||||||
|
await using tmp = await tmpdir()
|
||||||
|
const filepath = path.join(tmp.path, "Dockerfile")
|
||||||
|
await fs.writeFile(filepath, "FROM alpine:3.20", "utf-8")
|
||||||
|
|
||||||
|
await Instance.provide({
|
||||||
|
directory: tmp.path,
|
||||||
|
fn: async () => {
|
||||||
|
const result = await File.read("Dockerfile")
|
||||||
|
expect(result.type).toBe("text")
|
||||||
|
expect(result.content).toBe("FROM alpine:3.20")
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
test("returns encoding info for text files", async () => {
|
test("returns encoding info for text files", async () => {
|
||||||
await using tmp = await tmpdir()
|
await using tmp = await tmpdir()
|
||||||
const filepath = path.join(tmp.path, "test.txt")
|
const filepath = path.join(tmp.path, "test.txt")
|
||||||
|
|||||||
Reference in New Issue
Block a user