Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add getAcceptLanguage #5

Merged
merged 1 commit into from
Sep 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ You can do `import { ... } from '@intlify/utils'` the above utilities
### HTTP

- `getAcceptLanguages`
- `getAcceptLanguage`
- `getLocale`
- `getCookieLocale`
- `setCookieLocale`
Expand Down
91 changes: 67 additions & 24 deletions src/h3.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { beforeEach, describe, expect, test } from 'vitest'
import { createApp, eventHandler, toNodeListener } from 'h3'
import supertest from 'supertest'
import {
getAcceptLanguage,
getAcceptLanguages,
getCookieLocale,
getLocale,
Expand All @@ -14,7 +15,7 @@ import type { SuperTest, Test } from 'supertest'

describe('getAcceptLanguages', () => {
test('basic', () => {
const eventMock = {
const mockEvent = {
node: {
req: {
method: 'GET',
Expand All @@ -24,11 +25,11 @@ describe('getAcceptLanguages', () => {
},
},
} as H3Event
expect(getAcceptLanguages(eventMock)).toEqual(['en-US', 'en', 'ja'])
expect(getAcceptLanguages(mockEvent)).toEqual(['en-US', 'en', 'ja'])
})

test('any language', () => {
const eventMock = {
const mockEvent = {
node: {
req: {
method: 'GET',
Expand All @@ -38,25 +39,67 @@ describe('getAcceptLanguages', () => {
},
},
} as H3Event
expect(getAcceptLanguages(eventMock)).toEqual([])
expect(getAcceptLanguages(mockEvent)).toEqual([])
})

test('empty', () => {
const eventMock = {
const mockEvent = {
node: {
req: {
method: 'GET',
headers: {},
},
},
} as H3Event
expect(getAcceptLanguages(eventMock)).toEqual([])
expect(getAcceptLanguages(mockEvent)).toEqual([])
})
})

describe('getAcceptLanguage', () => {
test('basic', () => {
const mockEvent = {
node: {
req: {
method: 'GET',
headers: {
'accept-language': 'en-US,en;q=0.9,ja;q=0.8',
},
},
},
} as H3Event
expect(getAcceptLanguage(mockEvent)).toEqual('en-US')
})

test('any language', () => {
const mockEvent = {
node: {
req: {
method: 'GET',
headers: {
'accept-language': '*',
},
},
},
} as H3Event
expect(getAcceptLanguage(mockEvent)).toEqual('')
})

test('empty', () => {
const mockEvent = {
node: {
req: {
method: 'GET',
headers: {},
},
},
} as H3Event
expect(getAcceptLanguage(mockEvent)).toEqual('')
})
})

describe('getLocale', () => {
test('basic', () => {
const eventMock = {
const mockEvent = {
node: {
req: {
method: 'GET',
Expand All @@ -66,15 +109,15 @@ describe('getLocale', () => {
},
},
} as H3Event
const locale = getLocale(eventMock)
const locale = getLocale(mockEvent)

expect(locale.baseName).toEqual('en-US')
expect(locale.language).toEqual('en')
expect(locale.region).toEqual('US')
})

test('accept-language is any language', () => {
const eventMock = {
const mockEvent = {
node: {
req: {
method: 'GET',
Expand All @@ -84,13 +127,13 @@ describe('getLocale', () => {
},
},
} as H3Event
const locale = getLocale(eventMock)
const locale = getLocale(mockEvent)

expect(locale.baseName).toEqual(DEFAULT_LANG_TAG)
})

test('specify default language', () => {
const eventMock = {
const mockEvent = {
node: {
req: {
method: 'GET',
Expand All @@ -100,13 +143,13 @@ describe('getLocale', () => {
},
},
} as H3Event
const locale = getLocale(eventMock, 'ja-JP')
const locale = getLocale(mockEvent, 'ja-JP')

expect(locale.baseName).toEqual('ja-JP')
})

test('RangeError', () => {
const eventMock = {
const mockEvent = {
node: {
req: {
method: 'GET',
Expand All @@ -117,13 +160,13 @@ describe('getLocale', () => {
},
} as H3Event

expect(() => getLocale(eventMock, 'ja-JP')).toThrowError(RangeError)
expect(() => getLocale(mockEvent, 'ja-JP')).toThrowError(RangeError)
})
})

describe('getCookieLocale', () => {
test('basic', () => {
const eventMock = {
const mockEvent = {
node: {
req: {
method: 'GET',
Expand All @@ -133,43 +176,43 @@ describe('getCookieLocale', () => {
},
},
} as H3Event
const locale = getCookieLocale(eventMock)
const locale = getCookieLocale(mockEvent)

expect(locale.baseName).toEqual('ja-US')
expect(locale.language).toEqual('ja')
expect(locale.region).toEqual('US')
})

test('cookie is empty', () => {
const eventMock = {
const mockEvent = {
node: {
req: {
method: 'GET',
headers: {},
},
},
} as H3Event
const locale = getCookieLocale(eventMock)
const locale = getCookieLocale(mockEvent)

expect(locale.baseName).toEqual(DEFAULT_LANG_TAG)
})

test('specify default language', () => {
const eventMock = {
const mockEvent = {
node: {
req: {
method: 'GET',
headers: {},
},
},
} as H3Event
const locale = getCookieLocale(eventMock, { lang: 'ja-JP' })
const locale = getCookieLocale(mockEvent, { lang: 'ja-JP' })

expect(locale.baseName).toEqual('ja-JP')
})

test('specify cookie name', () => {
const eventMock = {
const mockEvent = {
node: {
req: {
method: 'GET',
Expand All @@ -179,13 +222,13 @@ describe('getCookieLocale', () => {
},
},
} as H3Event
const locale = getCookieLocale(eventMock, { name: 'intlify_locale' })
const locale = getCookieLocale(mockEvent, { name: 'intlify_locale' })

expect(locale.baseName).toEqual('fr-FR')
})

test('RangeError', () => {
const eventMock = {
const mockEvent = {
node: {
req: {
method: 'GET',
Expand All @@ -196,7 +239,7 @@ describe('getCookieLocale', () => {
},
} as H3Event

expect(() => getCookieLocale(eventMock, { name: 'intlify_locale' }))
expect(() => getCookieLocale(mockEvent, { name: 'intlify_locale' }))
.toThrowError(RangeError)
})
})
Expand Down
11 changes: 11 additions & 0 deletions src/h3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,17 @@ export function getAcceptLanguages(event: H3Event): string[] {
return getAcceptLanguagesWithGetter(getter)
}

/**
* get accept language
*
* @param {H3Event} event The {@link H3Event | H3} event
*
* @returns {string} The **first language tag** of `accept-language` header, if `accept-language` header is not exists, or `*` (any language), return empty string.
*/
export function getAcceptLanguage(event: H3Event): string {
return getAcceptLanguages(event)[0] || ''
}

/**
* get locale
*
Expand Down
28 changes: 28 additions & 0 deletions src/node.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { describe, expect, test } from 'vitest'
import supertest from 'supertest'
import {
getAcceptLanguage,
getAcceptLanguages,
getCookieLocale,
getLocale,
Expand Down Expand Up @@ -36,6 +37,33 @@ describe('getAcceptLanguages', () => {
})
})

describe('getAcceptLanguage', () => {
test('basic', () => {
const mockRequest = {
headers: {
'accept-language': 'en-US,en;q=0.9,ja;q=0.8',
},
} as IncomingMessage
expect(getAcceptLanguage(mockRequest)).toBe('en-US')
})

test('any language', () => {
const mockRequest = {
headers: {
'accept-language': '*',
},
} as IncomingMessage
expect(getAcceptLanguage(mockRequest)).toBe('')
})

test('empty', () => {
const mockRequest = {
headers: {},
} as IncomingMessage
expect(getAcceptLanguage(mockRequest)).toBe('')
})
})

describe('getLocale', () => {
test('basic', () => {
const mockRequest = {
Expand Down
13 changes: 12 additions & 1 deletion src/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,22 @@ import type { CookieOptions } from './http.ts'
*
* @returns {Array<string>} The array of language tags, if `*` (any language) or empty string is detected, return an empty array.
*/
export function getAcceptLanguages(req: IncomingMessage) {
export function getAcceptLanguages(req: IncomingMessage): string[] {
const getter = () => req.headers['accept-language']
return getAcceptLanguagesWithGetter(getter)
}

/**
* get accept language
*
* @param {IncomingMessage} request The {@link IncomingMessage | request}
*
* @returns {string} The **first language tag** of `accept-language` header, if `accept-language` header is not exists, or `*` (any language), return empty string.
*/
export function getAcceptLanguage(req: IncomingMessage): string {
return getAcceptLanguages(req)[0] || ''
}

/**
* get locale
*
Expand Down
20 changes: 20 additions & 0 deletions src/web.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { describe, expect, test } from 'vitest'
import {
getAcceptLanguage,
getAcceptLanguages,
getCookieLocale,
getLocale,
Expand All @@ -26,6 +27,25 @@ describe('getAcceptLanguages', () => {
})
})

describe('getAcceptLanguage', () => {
test('basic', () => {
const mockRequest = new Request('https://example.com')
mockRequest.headers.set('accept-language', 'en-US,en;q=0.9,ja;q=0.8')
expect(getAcceptLanguage(mockRequest)).toBe('en-US')
})

test('any language', () => {
const mockRequest = new Request('https://example.com')
mockRequest.headers.set('accept-language', '*')
expect(getAcceptLanguage(mockRequest)).toBe('')
})

test('empty', () => {
const mockRequest = new Request('https://example.com')
expect(getAcceptLanguage(mockRequest)).toBe('')
})
})

describe('getLocale', () => {
test('basic', () => {
const mockRequest = new Request('https://example.com')
Expand Down
13 changes: 12 additions & 1 deletion src/web.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,22 @@ import type { CookieOptions } from './http.ts'
*
* @returns {Array<string>} The array of language tags, if `*` (any language) or empty string is detected, return an empty array.
*/
export function getAcceptLanguages(req: Request) {
export function getAcceptLanguages(req: Request): string[] {
const getter = () => req.headers.get('accept-language')
return getAcceptLanguagesWithGetter(getter)
}

/**
* get accept language
*
* @param {Request} request The {@link Request | request}
*
* @returns {string} The **first language tag** of `accept-language` header, if `accept-language` header is not exists, or `*` (any language), return empty string.
*/
export function getAcceptLanguage(req: Request): string {
return getAcceptLanguages(req)[0] || ''
}

/**
* get locale
*
Expand Down