Skip to content

Commit

Permalink
Merge pull request #546 from hateablestream/feat/parse-bigint
Browse files Browse the repository at this point in the history
  • Loading branch information
niieani committed May 24, 2023
2 parents 1c41dd1 + b6eb110 commit bcbf47f
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 19 deletions.
46 changes: 34 additions & 12 deletions src/tests/bigint.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,42 @@ const hashids = new Hashids()
const _BigInt = typeof BigInt === 'function' ? BigInt : undefined

describe('BigInt environment', () => {
beforeAll(() => {
// @ts-expect-error wrong output
delete global.BigInt
})
describe('BigInt on unsupported environment', () => {
beforeAll(() => {
// @ts-expect-error wrong output
delete global.BigInt
})

afterAll(() => {
if (_BigInt) global.BigInt = _BigInt
})

afterAll(() => {
if (_BigInt) global.BigInt = _BigInt
it('throws decoding BigInt on unsupported environment', () => {
expect(() =>
hashids.decode('N95VW0Lo06rQBvJDOE2BVvREP86AqvYN4O9g9p'),
).toThrowErrorMatchingInlineSnapshot(
`"Unable to decode the provided string, due to lack of support for BigInt numbers in the current environment"`,
)
})

it('throws encoding a big numeric string on unsupported environment', () => {
expect(() =>
hashids.encode('90071992547409910123456789'),
).toThrowErrorMatchingInlineSnapshot(
`"Unable to encode the provided BigInt string without loss of information due to lack of support for BigInt type in the current environment"`,
)
})
})

it('throws decoding BigInt on unsupported environment', () => {
expect(() =>
hashids.decode('N95VW0Lo06rQBvJDOE2BVvREP86AqvYN4O9g9p'),
).toThrowErrorMatchingInlineSnapshot(
`"Unable to decode the provided string, due to lack of support for BigInt numbers in the current environment"`,
)
describe('BigInt on supported environment', () => {
it('decodes big numeric string on supported environment', () => {
const id = '90071992547409910123456789'
const encodedId = hashids.encode(id)
const [decodedId] = hashids.decode(encodedId)

expect(encodedId).toBeTruthy()
expect(decodedId).toBeTruthy()
expect(id).toBe(decodedId?.toString())
})
})
})
36 changes: 29 additions & 7 deletions src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,19 +92,33 @@ export const fromAlphabet = (
if (isSafeValue) {
return value
}
if (typeof BigInt === 'function') {
return BigInt(carry) * BigInt(alphabetChars.length) + BigInt(index)
}
// we do not have support for BigInt:
throw new Error(

throwIfBigIntNotAvailable(
`Unable to decode the provided string, due to lack of support for BigInt numbers in the current environment`,
)

return BigInt(carry) * BigInt(alphabetChars.length) + BigInt(index)
}, 0)

const safeToParseNumberRegExp = /^\+?\d+$/

export const safeParseInt10 = (str: string) =>
safeToParseNumberRegExp.test(str) ? Number.parseInt(str, 10) : Number.NaN
export const safeParseInt10 = (str: string) => {
if (!safeToParseNumberRegExp.test(str)) {
return Number.NaN
}

const int10 = Number.parseInt(str, 10)

if (Number.isSafeInteger(int10)) {
return int10
}

throwIfBigIntNotAvailable(
'Unable to encode the provided BigInt string without loss of information due to lack of support for BigInt type in the current environment',
)

return BigInt(str)
}

export const splitAtIntervalAndMap = <T>(
str: string,
Expand Down Expand Up @@ -137,3 +151,11 @@ export const makeAtLeastSomeCharRegExp = (chars: string[]) =>

const escapeRegExp = (text: string) =>
text.replace(/[\s#$()*+,.?[\\\]^{|}-]/g, '\\$&')

const throwIfBigIntNotAvailable = (
errorMessage: string = 'BigInt is not available in this environment',
) => {
if (typeof BigInt !== 'function') {
throw new TypeError(errorMessage)
}
}

0 comments on commit bcbf47f

Please sign in to comment.