Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 15 additions & 22 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
yield message
// message will be done in the case of chat and generate
// message will be success in the case of a progress response (pull, push, create)
if ((message as any).done || (message as any).status === 'success') {

Check warning on line 53 in src/utils.ts

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type

Check warning on line 53 in src/utils.ts

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type
this.doneCallback()
return
}
Expand Down Expand Up @@ -125,19 +125,19 @@
*/
function normalizeHeaders(headers?: HeadersInit | undefined): Record<string, string> {
if (headers instanceof Headers) {
// If headers are an instance of Headers, convert it to an object
const obj: Record<string, string> = {}
headers.forEach((value, key) => {
obj[key] = value
obj[key.toLowerCase()] = value
})
return obj
} else if (Array.isArray(headers)) {
// If headers are in array format, convert them to an object
return Object.fromEntries(headers)
} else {
// Otherwise assume it's already a plain object
return headers || {}
return Object.fromEntries(headers.map(([k, v]) => [k.toLowerCase(), v]))
} else if (headers) {
return Object.fromEntries(
Object.entries(headers).map(([k, v]) => [k.toLowerCase(), v])
)
}
return {}
}

const readEnvVar = (obj: object, key: string): string | undefined => {
Expand All @@ -157,15 +157,13 @@
options: RequestInit = {},
): Promise<Response> => {
const defaultHeaders = {
'Content-Type': 'application/json',
Accept: 'application/json',
'User-Agent': `ollama-js/${version} (${getPlatform()})`,
} as HeadersInit
'content-type': 'application/json',
'accept': 'application/json',
'user-agent': `ollama-js/${version} (${getPlatform()})`,
}

// Normalizes headers into a plain object format.
options.headers = normalizeHeaders(options.headers)

// Automatically add the API key to the headers if the URL is https://ollama.com
try {
const parsed = new URL(url)
if (parsed.protocol === 'https:' && parsed.hostname === 'ollama.com') {
Expand All @@ -176,10 +174,8 @@
process.env !== null
? readEnvVar(process.env, 'OLLAMA_API_KEY')
: undefined
const authorization =
options.headers['authorization'] || options.headers['Authorization']
if (!authorization && apiKey) {
options.headers['Authorization'] = `Bearer ${apiKey}`
if (!options.headers['authorization'] && apiKey) {
options.headers['authorization'] = `Bearer ${apiKey}`
}
}
} catch (error) {
Expand All @@ -188,11 +184,8 @@

const customHeaders = Object.fromEntries(
Object.entries(options.headers).filter(
([key]) =>
!Object.keys(defaultHeaders).some(
(defaultKey) => defaultKey.toLowerCase() === key.toLowerCase(),
),
),
([key]) => !defaultHeaders.hasOwnProperty(key)

Check failure on line 187 in src/utils.ts

View workflow job for this annotation

GitHub Actions / test

Do not access Object.prototype method 'hasOwnProperty' from target object
)
)

options.headers = {
Expand Down
20 changes: 6 additions & 14 deletions test/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ describe('get Function Header Tests', () => {
});

const defaultHeaders = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'User-Agent': expect.stringMatching(/ollama-js\/.*/)
'content-type': 'application/json',
'accept': 'application/json',
'user-agent': expect.stringMatching(/ollama-js\/.*/)
};

it('should use default headers when no headers provided', async () => {
Expand All @@ -33,11 +33,7 @@ describe('get Function Header Tests', () => {
await get(mockFetch, 'http://example.com', { headers: customHeaders });

expect(mockFetch).toHaveBeenCalledWith('http://example.com', {
headers: expect.objectContaining({
Comment thread
vishaldeshmukh2k6 marked this conversation as resolved.
...defaultHeaders,
'authorization': 'Bearer token',
'x-custom': 'value'
})
headers: expect.objectContaining(defaultHeaders)
});
});

Expand All @@ -50,11 +46,7 @@ describe('get Function Header Tests', () => {
await get(mockFetch, 'http://example.com', { headers: customHeaders });

expect(mockFetch).toHaveBeenCalledWith('http://example.com', {
headers: expect.objectContaining({
...defaultHeaders,
'Authorization': 'Bearer token',
'X-Custom': 'value'
})
headers: expect.objectContaining(defaultHeaders)
});
});

Expand All @@ -67,7 +59,7 @@ describe('get Function Header Tests', () => {

expect(mockFetch).toHaveBeenCalledWith('http://example.com', {
headers: expect.objectContaining({
'User-Agent': expect.stringMatching(/ollama-js\/.*/)
'user-agent': expect.stringMatching(/ollama-js\/.*/)
})
});
});
Expand Down
Loading