Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
kazupon committed Sep 22, 2023
1 parent 1e92327 commit 6de36dc
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 28 deletions.
20 changes: 19 additions & 1 deletion src/h3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ import type { CookieOptions } from './http.ts'
*
* const app = createApp()
* app.use(eventHandler(event) => {
* const acceptLanguages = getAcceptLanguages(event)
* const langTags = getAcceptLanguages(event)
* // ...
* return `accepted languages: ${acceptLanguages.join(', ')}`
* })
* ```
*
Expand All @@ -43,6 +44,23 @@ export function getAcceptLanguages(event: H3Event): string[] {
/**
* get accept language
*
* @description parse `accept-language` header string, this function retuns the **first language tag** of `accept-language` header.
*
* @example
* example for h3:
*
* ```ts
* import { createApp, eventHandler } from 'h3'
* import { getAcceptLanguage } from '@intlify/utils/h3'
*
* const app = createApp()
* app.use(eventHandler(event) => {
* const langTag = getAcceptLanguage(event)
* // ...
* return `accepted language: ${langTag}`
* })
* ```
*
* @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.
Expand Down
45 changes: 32 additions & 13 deletions src/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,29 +23,48 @@ import type { CookieOptions } from './http.ts'
* import { getAcceptLanguages } from '@intlify/utils/node'
*
* const server = createServer((req, res) => {
* const acceptLanguages = getAcceptLanguages(req)
* const langTags = getAcceptLanguages(req)
* // ...
* res.writeHead(200)
* res.end(`detect accpect-languages: ${langTags.join(', ')}`)
* })
* ```
*
* @param {IncomingMessage} request The {@link IncomingMessage | request}
*
* @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): string[] {
const getter = () => req.headers['accept-language']
export function getAcceptLanguages(request: IncomingMessage): string[] {
const getter = () => request.headers['accept-language']
return getAcceptLanguagesWithGetter(getter)
}

/**
* get accept language
*
* @description parse `accept-language` header string, this function retuns the **first language tag** of `accept-language` header.
*
* @example
* example for Node.js request:
*
* ```ts
* import { createServer } from 'node:http'
* import { getAcceptLanguage } from '@intlify/utils/node'
*
* const server = createServer((req, res) => {
* const langTag = getAcceptLanguage(req)
* // ...
* res.writeHead(200)
* res.end(`detect accpect-language: ${langTag}`)
* })
* ```
*
* @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] || ''
export function getAcceptLanguage(request: IncomingMessage): string {
return getAcceptLanguages(request)[0] || ''
}

/**
Expand Down Expand Up @@ -73,10 +92,10 @@ export function getAcceptLanguage(req: IncomingMessage): string {
* @returns {Intl.Locale} The first locale that resolved from `accept-language` header string, first language tag is used. if `*` (any language) or empty string is detected, return `en-US`.
*/
export function getLocale(
req: IncomingMessage,
request: IncomingMessage,
lang = DEFAULT_LANG_TAG,
): Intl.Locale {
return getLocaleWithGetter(() => getAcceptLanguages(req)[0] || lang)
return getLocaleWithGetter(() => getAcceptLanguages(request)[0] || lang)
}

/**
Expand Down Expand Up @@ -105,11 +124,11 @@ export function getLocale(
* @returns The locale that resolved from cookie
*/
export function getCookieLocale(
req: IncomingMessage,
request: IncomingMessage,
{ lang = DEFAULT_LANG_TAG, name = DEFAULT_COOKIE_NAME } = {},
): Intl.Locale {
const getter = () => {
const cookieRaw = req.headers.cookie
const cookieRaw = request.headers.cookie
const cookie = parse(cookieRaw || '')
return cookie[name] || lang
}
Expand All @@ -132,25 +151,25 @@ export function getCookieLocale(
* })
* ```
*
* @param {OutgoingMessage} res The {@link OutgoingMessage | response}
* @param {OutgoingMessage} response The {@link OutgoingMessage | response}
* @param {string | Intl.Locale} locale The locale value
* @param {CookieOptions} options The cookie options, `name` option is `i18n_locale` as default, and `path` option is `/` as default.
*
* @throws {SyntaxError} Throws the {@link SyntaxError} if `locale` is invalid.
*/
export function setCookieLocale(
res: OutgoingMessage,
response: OutgoingMessage,
locale: string | Intl.Locale,
options: CookieOptions = { name: DEFAULT_COOKIE_NAME },
): void {
validateLocale(locale)
const setCookies = getExistCookies(
options.name!,
() => res.getHeader('set-cookie'),
() => response.getHeader('set-cookie'),
)
const target = serialize(options.name!, locale.toString(), {
path: '/',
...options,
})
res.setHeader('set-cookie', [...setCookies, target])
response.setHeader('set-cookie', [...setCookies, target])
}
48 changes: 34 additions & 14 deletions src/web.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,30 +23,47 @@ import type { CookieOptions } from './http.ts'
* Deno.serve({
* port: 8080,
* }, (req) => {
* const acceptLanguages = getAcceptLanguages(req)
* const langTags = getAcceptLanguages(req)
* // ...
* return new Response('Hello World!')
* return new Response(`accepted languages: ${langTags.join(', ')}`
* })
* ```
*
* @param {Request} request The {@link Request | request}
*
* @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): string[] {
const getter = () => req.headers.get('accept-language')
export function getAcceptLanguages(request: Request): string[] {
const getter = () => request.headers.get('accept-language')
return getAcceptLanguagesWithGetter(getter)
}

/**
* get accept language
*
* @description parse `accept-language` header string, this function retuns the **first language tag** of `accept-language` header.
*
* @example
* example for Web API request on Deno:
*
* ```ts
* import { getAcceptLanguage } from 'https://esm.sh/@intlify/utils/web'
*
* Deno.serve({
* port: 8080,
* }, (req) => {
* const langTag = getAcceptLanguage(req)
* // ...
* return new Response(`accepted language: ${langTag}`
* })
* ```
*
* @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] || ''
export function getAcceptLanguage(request: Request): string {
return getAcceptLanguages(request)[0] || ''
}

/**
Expand All @@ -73,8 +90,11 @@ export function getAcceptLanguage(req: Request): string {
*
* @returns {Intl.Locale} The first locale that resolved from `accept-language` header string, first language tag is used. if `*` (any language) or empty string is detected, return `en-US`.
*/
export function getLocale(req: Request, lang = DEFAULT_LANG_TAG): Intl.Locale {
return getLocaleWithGetter(() => getAcceptLanguages(req)[0] || lang)
export function getLocale(
request: Request,
lang = DEFAULT_LANG_TAG,
): Intl.Locale {
return getLocaleWithGetter(() => getAcceptLanguages(request)[0] || lang)
}

/**
Expand Down Expand Up @@ -104,11 +124,11 @@ export function getLocale(req: Request, lang = DEFAULT_LANG_TAG): Intl.Locale {
* @returns The locale that resolved from cookie
*/
export function getCookieLocale(
req: Request,
request: Request,
{ lang = DEFAULT_LANG_TAG, name = DEFAULT_COOKIE_NAME } = {},
): Intl.Locale {
const getter = () => {
const cookieRaw = req.headers.get('cookie')
const cookieRaw = request.headers.get('cookie')
const cookie = parse(cookieRaw || '')
return cookie[name] || lang
}
Expand All @@ -135,25 +155,25 @@ export function getCookieLocale(
* })
* ```
*
* @param {Response} res The {@link Response | response}
* @param {Response} response The {@link Response | response}
* @param {string | Intl.Locale} locale The locale value
* @param {CookieOptions} options The cookie options, `name` option is `i18n_locale` as default, and `path` option is `/` as default.
*
* @throws {SyntaxError} Throws the {@link SyntaxError} if `locale` is invalid.
*/
export function setCookieLocale(
res: Response,
response: Response,
locale: string | Intl.Locale,
options: CookieOptions = { name: DEFAULT_COOKIE_NAME },
): void {
validateLocale(locale)
const setCookies = getExistCookies(
options.name!,
() => res.headers.getSetCookie(),
() => response.headers.getSetCookie(),
)
const target = serialize(options.name!, locale.toString(), {
path: '/',
...options,
})
res.headers.set('set-cookie', [...setCookies, target].join('; '))
response.headers.set('set-cookie', [...setCookies, target].join('; '))
}

0 comments on commit 6de36dc

Please sign in to comment.