Skip to content

Commit 265d245

Browse files
committed
Add auth
1 parent c4e1613 commit 265d245

File tree

5 files changed

+506
-1072
lines changed

5 files changed

+506
-1072
lines changed

package.json

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,19 @@
22
"name": "generic-filehandle2",
33
"description": "uniform interface for accessing binary data from local files, remote HTTP resources, and browser Blob data",
44
"version": "2.0.3",
5-
"main": "dist/index.js",
6-
"module": "esm/index.js",
5+
"type": "module",
6+
"main": "./esm/index.js",
7+
"exports": {
8+
".": {
9+
"import": "./esm/index.js",
10+
"require": "./dist/index.js"
11+
},
12+
"./localFile.js": {
13+
"import": "./esm/localFile.js",
14+
"require": "./dist/localFile.js",
15+
"browser": null
16+
}
17+
},
718
"repository": "GMOD/generic-filehandle2",
819
"license": "MIT",
920
"author": {
@@ -12,23 +23,19 @@
1223
"url": "https://github.com/cmdcolin"
1324
},
1425
"engines": {
15-
"node": ">=12"
26+
"node": ">=14"
1627
},
1728
"files": [
18-
"dist",
1929
"esm",
2030
"src"
2131
],
2232
"scripts": {
2333
"test": "vitest",
2434
"coverage": "yarn test --coverage",
2535
"lint": "eslint --report-unused-disable-directives --max-warnings 0 src test",
26-
"clean": "rimraf dist esm",
36+
"clean": "rimraf esm",
2737
"prebuild": "yarn clean",
28-
"build:esm": "tsc --outDir esm",
29-
"build:es5": "tsc --module commonjs --outDir dist",
30-
"build": "yarn build:esm && yarn build:es5",
31-
"postbuild:es5": "echo '{\"type\": \"commonjs\"}' > dist/package.json",
38+
"build": "tsc --outDir esm",
3239
"preversion": "yarn lint && yarn test --run && yarn build",
3340
"postversion": "git push --follow-tags"
3441
},
@@ -39,28 +46,22 @@
3946
"genomics"
4047
],
4148
"devDependencies": {
42-
"@types/fetch-mock": "^7.3.8",
4349
"@types/node": "^22.15.3",
4450
"@types/range-parser": "^1.2.7",
4551
"@vitest/coverage-v8": "^3.0.1",
4652
"eslint": "^9.16.0",
4753
"eslint-plugin-import": "^2.31.0",
4854
"eslint-plugin-unicorn": "^59.0.0",
49-
"fetch-mock": "^9.0.0",
5055
"node-fetch": "^2.0.0",
5156
"prettier": "^3.4.1",
5257
"range-parser": "^1.2.1",
5358
"rimraf": "^6.0.0",
54-
"standard-changelog": "^6.0.0",
59+
"standard-changelog": "^7.0.1",
5560
"typescript": "^5.7.0",
5661
"typescript-eslint": "^8.18.0",
5762
"vitest": "^3.0.1"
5863
},
5964
"publishConfig": {
6065
"access": "public"
61-
},
62-
"browser": {
63-
"./dist/localFile.js": false,
64-
"./esm/localFile.js": false
6566
}
6667
}

test/auth.test.ts

Lines changed: 58 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,66 @@
11
import { TextDecoder } from 'util'
22

3-
import fetchMock from 'fetch-mock'
4-
import { afterEach, expect, test } from 'vitest'
3+
import { afterEach, beforeEach, expect, test, vi } from 'vitest'
54

65
import { RemoteFile } from '../src/'
76

8-
fetchMock.config.sendAsJson = false
9-
107
function toString(a: Uint8Array<ArrayBuffer>) {
118
return new TextDecoder('utf8').decode(a)
129
}
13-
afterEach(() => fetchMock.restore())
10+
11+
// Create a Response object from a buffer or string
12+
function createResponse(
13+
body: Uint8Array<ArrayBuffer> | string,
14+
status: number,
15+
headers: Record<string, string> = {},
16+
) {
17+
return {
18+
ok: status >= 200 && status < 300,
19+
status,
20+
headers: {
21+
get(name: string) {
22+
return headers[name] || null
23+
},
24+
},
25+
arrayBuffer: async () => {
26+
if (typeof body === 'string') {
27+
const encoder = new TextEncoder()
28+
return encoder.encode(body).buffer
29+
}
30+
return body.buffer
31+
},
32+
text: async () => {
33+
if (typeof body === 'string') {
34+
return body
35+
}
36+
return toString(body)
37+
},
38+
}
39+
}
40+
41+
// Mock implementation for fetch
42+
let mockFetch: (input: RequestInfo, init?: RequestInit) => Promise<Response>
43+
44+
beforeEach(() => {
45+
// Reset the mock fetch implementation before each test
46+
mockFetch = vi.fn().mockImplementation(async (url: string) => {
47+
throw new Error(`Unhandled fetch request to ${url}`)
48+
})
49+
})
50+
51+
afterEach(() => {
52+
vi.resetAllMocks()
53+
})
1454

1555
test('auth token', async () => {
16-
fetchMock.mock('http://fakehost/test.txt', (url: string, args: any) => {
56+
mockFetch = vi.fn().mockImplementation(async (_url: string, args: any) => {
1757
return args.headers.Authorization
18-
? {
19-
status: 200,
20-
body: 'hello world',
21-
}
22-
: {
23-
status: 403,
24-
}
58+
? createResponse('hello world', 200)
59+
: createResponse('Unauthorized', 403)
2560
})
61+
2662
const f = new RemoteFile('http://fakehost/test.txt', {
63+
fetch: mockFetch,
2764
overrides: {
2865
headers: {
2966
Authorization: 'Basic YWxhZGRpbjpvcGVuc2VzYW1l',
@@ -33,20 +70,21 @@ test('auth token', async () => {
3370
const stat = await f.readFile('utf8')
3471
expect(stat).toBe('hello world')
3572
})
73+
3674
test('auth token with range request', async () => {
37-
fetchMock.mock('http://fakehost/test.txt', (url: string, args: any) => {
75+
mockFetch = vi.fn().mockImplementation(async (_url: string, args: any) => {
3876
if (args.headers.Authorization && args.headers.range) {
39-
return {
40-
status: 206,
41-
body: 'hello',
42-
}
77+
return createResponse('hello', 206)
4378
} else if (!args.headers.Authorization) {
44-
return { status: 403 }
79+
return createResponse('Unauthorized', 403)
4580
} else if (!args.headers.Range) {
46-
return { status: 400 }
81+
return createResponse('Bad Request', 400)
4782
}
83+
return createResponse('Unknown error', 500)
4884
})
85+
4986
const f = new RemoteFile('http://fakehost/test.txt', {
87+
fetch: mockFetch,
5088
overrides: {
5189
headers: {
5290
Authorization: 'Basic YWxhZGRpbjpvcGVuc2VzYW1l',

test/index.test.ts

Lines changed: 0 additions & 24 deletions
This file was deleted.

0 commit comments

Comments
 (0)