Skip to content

Commit

Permalink
feat: add getQueryLanguage and getQueryLocale (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
kazupon authored Sep 27, 2023
1 parent 1777a4d commit f5216a0
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 3 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ You can do `import { ... } from '@intlify/utils'` the above utilities
- `setCookieLocale`
- `getPathLanguage`
- `getPathLocale`
- `getQueryLanguage`
- `getQueryLocale`

The about utilies functions accpet Web APIs such as
[Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) and
Expand Down
51 changes: 50 additions & 1 deletion src/http.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { describe, expect, test } from 'vitest'
import { getPathLanguage, getPathLocale } from './http.ts'
import {
getPathLanguage,
getPathLocale,
getQueryLanguage,
getQueryLocale,
} from './http.ts'

describe('getPathLanguage', () => {
test('basic', () => {
Expand Down Expand Up @@ -38,3 +43,47 @@ describe('getPathLocale', () => {
)
})
})

describe('getQueryLanguage', () => {
test('basic', () => {
expect(getQueryLanguage('lang=en-US&flag=1')).toBe('en-US')
})

test('URL instance', () => {
const url = new URL('https://example.com/?locale=ja-JP')
expect(getQueryLanguage(url, 'locale')).toBe('ja-JP')
})

test('URLSearchParams instance', () => {
const params = new URLSearchParams('lang=ja-JP')
params.set('flag', '1')
expect(getQueryLanguage(params)).toBe('ja-JP')
})

test('empty', () => {
const params = new URLSearchParams()
expect(getQueryLanguage(params)).toBe('')
})
})

describe('getQueryLocale', () => {
test('basic', () => {
expect(getQueryLocale('lang=en-US&flag=1', 'lang').toString()).toBe('en-US')
})

test('URL instance', () => {
const url = new URL('https://example.com/?locale=ja-JP')
expect(getQueryLocale(url).toString()).toBe('ja-JP')
})

test('URLSearchParams instance', () => {
const params = new URLSearchParams('lang=ja-JP')
params.set('flag', '1')
expect(getQueryLocale(params, 'lang').toString()).toBe('ja-JP')
})

test('RangeError', () => {
const params = new URLSearchParams()
expect(() => getQueryLocale(params)).toThrowError(RangeError)
})
})
49 changes: 48 additions & 1 deletion src/http.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import {
isLocale,
isURL,
isURLSearchParams,
parseAcceptLanguage,
pathLanguageParser,
validateLanguageTag,
Expand Down Expand Up @@ -158,7 +160,7 @@ export function getExistCookies(
* @param {string | URL} path the target path
* @param {PathLanguageParser} parser the path language parser, optional
*
* @returns {string} the language that is parsed by the path language parser
* @returns {string} the language that is parsed by the path language parser, if the language is not detected, return an empty string.
*/
export function getPathLanguage(
path: string | URL,
Expand All @@ -184,3 +186,48 @@ export function getPathLocale(
): Intl.Locale {
return new Intl.Locale(getPathLanguage(path, parser))
}

function getURLSearchParams(
input: string | URL | URLSearchParams,
): URLSearchParams {
if (isURLSearchParams(input)) {
return input
} else if (isURL(input)) {
return input.searchParams
} else {
return new URLSearchParams(input)
}
}

/**
* get the language from the query
*
* @param {string | URL | URLSearchParams} query the target query
* @param {string} name the query param name, default `'lang'`
*
* @returns {string} the language from query, if the language is not detected, return an empty string.
*/
export function getQueryLanguage(
query: string | URL | URLSearchParams,
name = 'lang',
): string {
const queryParams = getURLSearchParams(query)
return queryParams.get(name) || ''
}

/**
* get the locale from the query
*
* @param {string | URL | URLSearchParams} query the target query
* @param {string} name the query param name, default `'locale'`
*
* @throws {RangeError} Throws the {@link RangeError} if the language in the query, that is not a well-formed BCP 47 language tag.
*
* @returns {Intl.Locale} The locale that resolved from query
*/
export function getQueryLocale(
query: string | URL | URLSearchParams,
name = 'locale',
): Intl.Locale {
return new Intl.Locale(getQueryLanguage(query, name))
}
7 changes: 6 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,10 @@ export {
registerPathLanguageParser,
validateLanguageTag,
} from './shared.ts'
export { getPathLanguage, getPathLocale } from './http.ts'
export {
getPathLanguage,
getPathLocale,
getQueryLanguage,
getQueryLocale,
} from './http.ts'
export * from './web.ts'
8 changes: 8 additions & 0 deletions src/shared.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
const objectToString = Object.prototype.toString
const toTypeString = (value: unknown): string => objectToString.call(value)

export function isURL(val: unknown): val is URL {
return toTypeString(val) === '[object URL]'
}

export function isURLSearchParams(val: unknown): val is URLSearchParams {
return toTypeString(val) === '[object URLSearchParams]'
}

/**
* check whether the value is a {@link Intl.Locale} instance
*
Expand Down

0 comments on commit f5216a0

Please sign in to comment.