@onivoro/isomorphic-common 24.14.0 → 24.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/package.json +8 -2
  2. package/jest.config.ts +0 -11
  3. package/project.json +0 -33
  4. package/src/index.ts +0 -80
  5. package/src/lib/constants/api-id-header.constant.ts +0 -1
  6. package/src/lib/constants/api-key-header.constant.ts +0 -1
  7. package/src/lib/constants/auth-cookie-name.constant.ts +0 -2
  8. package/src/lib/constants/millis-per-day.constant.ts +0 -3
  9. package/src/lib/constants/millis-per-hour.constant.ts +0 -3
  10. package/src/lib/constants/millis-per-minute.constant.ts +0 -1
  11. package/src/lib/constants/regexes.constant.ts +0 -30
  12. package/src/lib/functions/__snapshots__/chunk.function.spec.ts.snap +0 -94
  13. package/src/lib/functions/__snapshots__/split-date-range-into-days.function.spec.ts.snap +0 -50
  14. package/src/lib/functions/add-offset.function.spec.ts +0 -12
  15. package/src/lib/functions/add-offset.function.ts +0 -14
  16. package/src/lib/functions/arrange-act-assert.function.ts +0 -23
  17. package/src/lib/functions/camel-case.function.ts +0 -30
  18. package/src/lib/functions/chunk.function.spec.ts +0 -20
  19. package/src/lib/functions/chunk.function.ts +0 -25
  20. package/src/lib/functions/convert-object-to-literal.function.spec.ts +0 -16
  21. package/src/lib/functions/convert-object-to-literal.function.ts +0 -10
  22. package/src/lib/functions/format-usd.function.ts +0 -4
  23. package/src/lib/functions/from-boolean-string.function.ts +0 -3
  24. package/src/lib/functions/from-calendar-date.function.spec.ts +0 -11
  25. package/src/lib/functions/from-calendar-date.function.ts +0 -5
  26. package/src/lib/functions/from-csv-string.function.ts +0 -3
  27. package/src/lib/functions/get-date-last-month.function.ts +0 -6
  28. package/src/lib/functions/get-date-range-for-month.function copy.ts +0 -8
  29. package/src/lib/functions/get-date-range-for-month.function.ts +0 -8
  30. package/src/lib/functions/get-tag.function.ts +0 -10
  31. package/src/lib/functions/get-user-full-name.function.ts +0 -5
  32. package/src/lib/functions/is-symbol.function.ts +0 -11
  33. package/src/lib/functions/is-valid-date.function.ts +0 -5
  34. package/src/lib/functions/kebab-case.function.ts +0 -5
  35. package/src/lib/functions/map-entities-to-options.function.ts +0 -11
  36. package/src/lib/functions/map-enum-to-array-of-values.function copy.ts +0 -3
  37. package/src/lib/functions/map-enum-to-array-of-values.function.ts +0 -3
  38. package/src/lib/functions/map-enum-to-lookup-array.function.ts +0 -6
  39. package/src/lib/functions/map-enum-to-options.function copy.ts +0 -7
  40. package/src/lib/functions/map-enum-to-options.function.ts +0 -7
  41. package/src/lib/functions/mock-calls.function.ts +0 -4
  42. package/src/lib/functions/money.function.spec.ts +0 -10
  43. package/src/lib/functions/money.function.ts +0 -22
  44. package/src/lib/functions/parse-bool.function.ts +0 -3
  45. package/src/lib/functions/properties-to-array.function.ts +0 -21
  46. package/src/lib/functions/remove-alpha-chars.function.spec.ts +0 -11
  47. package/src/lib/functions/remove-alpha-chars.function.ts +0 -9
  48. package/src/lib/functions/remove-element-at-index.function copy.ts +0 -9
  49. package/src/lib/functions/remove-element-at-index.function.ts +0 -9
  50. package/src/lib/functions/round.function copy.ts +0 -4
  51. package/src/lib/functions/round.function.ts +0 -4
  52. package/src/lib/functions/sanitize-filename.function.ts +0 -9
  53. package/src/lib/functions/sleep.function.ts +0 -3
  54. package/src/lib/functions/snake-case.function.ts +0 -34
  55. package/src/lib/functions/sort-by-created-at.function.ts +0 -7
  56. package/src/lib/functions/sort-by-full-name.function.ts +0 -6
  57. package/src/lib/functions/sort-by-id.function.ts +0 -3
  58. package/src/lib/functions/sort-by-name.function.ts +0 -3
  59. package/src/lib/functions/sort-numbers.function.ts +0 -3
  60. package/src/lib/functions/split-date-range-into-days.function.spec.ts +0 -17
  61. package/src/lib/functions/split-date-range-into-days.function.ts +0 -26
  62. package/src/lib/functions/subtract-offset.function.spec.ts +0 -12
  63. package/src/lib/functions/subtract-offset.function.ts +0 -14
  64. package/src/lib/functions/to-boolean-string.function.ts +0 -3
  65. package/src/lib/functions/to-calendar-date.function.ts +0 -11
  66. package/src/lib/functions/to-csv-string.function.ts +0 -3
  67. package/src/lib/functions/to-decimal-base.function.ts +0 -23
  68. package/src/lib/functions/to-dollars-and-cents.function.spec.ts +0 -7
  69. package/src/lib/functions/to-dollars-and-cents.function.ts +0 -17
  70. package/src/lib/functions/to-string.function.ts +0 -25
  71. package/src/lib/functions/to-unique-array.function.spec.ts +0 -45
  72. package/src/lib/functions/to-unique-array.function.ts +0 -3
  73. package/src/lib/functions/to-words.function.spec.ts +0 -7
  74. package/src/lib/functions/to-words.function.ts +0 -108
  75. package/src/lib/functions/try-json-parse.spec.ts +0 -37
  76. package/src/lib/functions/try-json-parse.ts +0 -11
  77. package/src/lib/functions/try-json-stringify.spec.ts +0 -44
  78. package/src/lib/functions/try-json-stringify.ts +0 -11
  79. package/src/lib/functions/try-parse-date.function.spec.ts +0 -12
  80. package/src/lib/functions/try-parse-date.function.ts +0 -17
  81. package/src/lib/functions/unicode-words.const.ts +0 -70
  82. package/src/lib/functions/upper-first.function.spec.ts +0 -16
  83. package/src/lib/functions/upper-first.function.ts +0 -10
  84. package/src/lib/functions/use-date.function.ts +0 -21
  85. package/src/lib/functions/words.function.ts +0 -38
  86. package/src/lib/types/access-token.interface.ts +0 -8
  87. package/src/lib/types/axios-wrapped-nest-exception.interface.ts +0 -5
  88. package/src/lib/types/company.type.ts +0 -18
  89. package/src/lib/types/createable.type.ts +0 -1
  90. package/src/lib/types/entity-provider.interface.ts +0 -9
  91. package/src/lib/types/keys-of.type copy.ts +0 -1
  92. package/src/lib/types/keys-of.type.ts +0 -1
  93. package/src/lib/types/lookup.interface copy.ts +0 -4
  94. package/src/lib/types/lookup.interface.ts +0 -4
  95. package/src/lib/types/nameable.type.ts +0 -4
  96. package/tsconfig.json +0 -13
  97. package/tsconfig.lib.json +0 -10
  98. package/tsconfig.spec.json +0 -14
@@ -1,7 +0,0 @@
1
- export function mapEnumToOptions<TEntity extends object>(enumeration: TEntity, includeBlank = true) {
2
- const enumArray = Object.entries(enumeration).map(([key, value]) => ({ value, display: key.replace(/_/g, ' ') }))
3
-
4
- return includeBlank
5
- ? [{ display: '', value: '' }, ...enumArray]
6
- : enumArray;
7
- }
@@ -1,7 +0,0 @@
1
- export function mapEnumToOptions<TEntity extends object>(enumeration: TEntity, includeBlank = true) {
2
- const enumArray = Object.entries(enumeration).map(([key, value]) => ({ value, display: key.replace(/_/g, ' ') }))
3
-
4
- return includeBlank
5
- ? [{ display: '', value: '' }, ...enumArray]
6
- : enumArray;
7
- }
@@ -1,4 +0,0 @@
1
- export function mockCalls(jestFn: any, label = 'mock-calls') {
2
- const calls = jestFn?.mock?.calls || [];
3
- return { [`${label} -->> ${calls.length} invocation(s)`]: calls };
4
- }
@@ -1,10 +0,0 @@
1
- import { money } from './money.function';
2
-
3
- describe('money', () => {
4
- it('worx', () => {
5
- expect(money('1234.567')).toMatchSnapshot();
6
- expect(money(987.65)).toMatchSnapshot();
7
- expect(money('$337.65')).toMatchSnapshot();
8
- expect(money('$1,234.56')).toMatchSnapshot();
9
- })
10
- });
@@ -1,22 +0,0 @@
1
- import { removeAlphaChars } from "./remove-alpha-chars.function";
2
-
3
- export function money(rawValue: number | string) {
4
- if(!rawValue) {
5
- return;
6
- }
7
-
8
- const scrubbed = removeAlphaChars(rawValue);
9
-
10
- const amount = Number(scrubbed);
11
-
12
- if(!amount && amount !== 0) {
13
- return;
14
- }
15
-
16
- const formatter = new Intl.NumberFormat('en-US', {
17
- style: 'currency',
18
- currency: 'USD'
19
- });
20
-
21
- return formatter.format(Number(amount));
22
- }
@@ -1,3 +0,0 @@
1
- export function parseBool(asc: string | boolean | null | undefined) {
2
- return asc ? asc === true || asc === 'true' : false;
3
- }
@@ -1,21 +0,0 @@
1
- // credit https://stackoverflow.com/questions/15690706/recursively-looping-through-an-object-to-build-a-property-list/53620876#53620876
2
-
3
- export function propertiesToArray(obj: Record<string, any>) {
4
- const isObject = (val: any) =>
5
- val && typeof val === 'object' && !Array.isArray(val);
6
-
7
- const addDelimiter = (a: any, b: any) =>
8
- a ? `${a}.${b}` : b;
9
-
10
- const paths: any = (obj = {}, head = '') => {
11
- return Object.entries(obj)
12
- .reduce((product, [key, value]) => {
13
- let fullPath = addDelimiter(head, key)
14
- return isObject(value) ?
15
- product.concat(paths(value, fullPath))
16
- : product.concat(fullPath)
17
- }, []);
18
- }
19
-
20
- return paths(obj);
21
- }
@@ -1,11 +0,0 @@
1
- import { removeAlphaChars } from './remove-alpha-chars.function';
2
-
3
- describe('removeAlphaChars', () => {
4
- it('worx', () => {
5
- expect(removeAlphaChars('1234.567')).toMatchSnapshot();
6
- expect(removeAlphaChars(987.65)).toMatchSnapshot();
7
- expect(removeAlphaChars('$337.65')).toMatchSnapshot();
8
- expect(removeAlphaChars('$1,234.56')).toMatchSnapshot();
9
- expect(removeAlphaChars('dollarzzz$1,234.5six')).toMatchSnapshot();
10
- })
11
- });
@@ -1,9 +0,0 @@
1
- import { decimalRegex } from "../constants/regexes.constant";
2
-
3
- export function removeAlphaChars(input?: string | number) {
4
- if (!input) {
5
- return;
6
- }
7
-
8
- return input.toString().match(decimalRegex)?.join?.('');
9
- }
@@ -1,9 +0,0 @@
1
- export function removeElementAtIndex<T>(array: T[], indexToRemove: number): T[] {
2
- const newArray: T[] = [];
3
- (array || []).forEach((element, index) => {
4
- if(index !== indexToRemove) {
5
- newArray.push(element);
6
- }
7
- });
8
- return newArray;
9
- }
@@ -1,9 +0,0 @@
1
- export function removeElementAtIndex<T>(array: T[], indexToRemove: number): T[] {
2
- const newArray: T[] = [];
3
- (array || []).forEach((element, index) => {
4
- if(index !== indexToRemove) {
5
- newArray.push(element);
6
- }
7
- });
8
- return newArray;
9
- }
@@ -1,4 +0,0 @@
1
- export function round(numberToRound: number, scalingFactor: number) {
2
- const scaledServingDose = numberToRound * scalingFactor;
3
- return Math.round(scaledServingDose) / scalingFactor;
4
- }
@@ -1,4 +0,0 @@
1
- export function round(numberToRound: number, scalingFactor: number) {
2
- const scaledServingDose = numberToRound * scalingFactor;
3
- return Math.round(scaledServingDose) / scalingFactor;
4
- }
@@ -1,9 +0,0 @@
1
- /* eslint-disable no-control-regex */
2
-
3
- const _ = '_';
4
- const asciiReplacementRegX = /\/|\?|:|\\|{|\^|'|\}|%|`|]|>|\[|~|<|#|\||"|!|\*/g;
5
- const unicodeReplacementRegX = /[^\u0000-\u007F]/g;
6
-
7
- export function sanitizeFilename(filename: string) {
8
- return filename.replace(unicodeReplacementRegX, _).replace(asciiReplacementRegX, _).replace(/_+/g, _).trim();
9
- }
@@ -1,3 +0,0 @@
1
- export async function sleep(milliseconds = 0) {
2
- return await new Promise(resolve => setTimeout(resolve, milliseconds));
3
- }
@@ -1,34 +0,0 @@
1
- // source https://github.com/lodash/lodash/blob/master/snakeCase.js
2
-
3
- import { words } from "./words.function";
4
-
5
- /**
6
- * Converts `string` to
7
- * [snake case](https://en.wikipedia.org/wiki/Snake_case).
8
- *
9
- * @since 3.0.0
10
- * @category String
11
- * @param {string} [string=''] The string to convert.
12
- * @returns {string} Returns the snake cased string.
13
- * @see camelCase, lowerCase, kebabCase, startCase, upperCase, upperFirst
14
- * @example
15
- *
16
- * snakeCase('Foo Bar')
17
- * // => 'foo_bar'
18
- *
19
- * snakeCase('fooBar')
20
- * // => 'foo_bar'
21
- *
22
- * snakeCase('--FOO-BAR--')
23
- * // => 'foo_bar'
24
- *
25
- * snakeCase('foo2bar')
26
- * // => 'foo_2_bar'
27
- */
28
- export function snakeCase(string: string) {
29
- return (
30
- (words(string.replace(/['\u2019]/g, '')) as string[]).reduce((result: string, word: string, index: number) => (
31
- result + (index ? '_' : '') + word.toLowerCase()
32
- ), '')
33
- );
34
- }
@@ -1,7 +0,0 @@
1
- import { TCreateable } from "../types/createable.type";
2
-
3
- export function sortByCreatedAt<TEntity extends TCreateable>(a: TEntity, b: TEntity) {
4
- const isLessThan = a.createdAt < b.createdAt;
5
-
6
- return isLessThan ? -1 : 1;
7
- }
@@ -1,6 +0,0 @@
1
- import { TNameable } from "../types/nameable.type";
2
- import { getUserFullName } from "./get-user-full-name.function";
3
-
4
- export function sortByFullName<TEntity extends TNameable>(a: TEntity, b: TEntity) {
5
- return getUserFullName(a).localeCompare(getUserFullName(b)) || 0;
6
- }
@@ -1,3 +0,0 @@
1
- export function sortById<TEntity extends { id: string }>(a: TEntity, b: TEntity) {
2
- return a?.id?.localeCompare(b?.id || '') || 0;
3
- }
@@ -1,3 +0,0 @@
1
- export function sortByName<TEntity extends { name: string }>(a: TEntity, b: TEntity) {
2
- return a?.name?.localeCompare(b?.name || '') || 0;
3
- }
@@ -1,3 +0,0 @@
1
- export const sortNumbers = (a: number, b: number) => {
2
- return Number(a) < Number(b) ? -1 : 1;
3
- };
@@ -1,17 +0,0 @@
1
- import { splitDateRangeIntoDays } from './split-date-range-into-days.function';
2
- import { arrangeActAssert } from '../functions/arrange-act-assert.function';
3
- describe('splitDateRangeIntoDays', () => {
4
- it.each([
5
- [{ from: '', to: '' }],
6
- [{ from: 'asdf', to: '2345' }],
7
- [{ from: '2024-01-01', to: '2024-01-01' }],
8
- [{ from: '2024-01-01', to: '2024-02-01' }],
9
- [{ from: '2025-01-01', to: '' }],
10
- ])('given %j, returns an array of days', async (_) => await arrangeActAssert({
11
- arrange: () => ({ subject: splitDateRangeIntoDays }),
12
- act: ({ subject }) => subject(_),
13
- assert: ({ result }) => {
14
- expect(result).toMatchSnapshot();
15
- }
16
- }));
17
- });
@@ -1,26 +0,0 @@
1
- import { MILLIS_PER_DAY } from "../constants/millis-per-day.constant";
2
-
3
- const iso8601Regex = /\d{4}-\d{2}-\d{2}/;
4
-
5
- export function splitDateRangeIntoDays(_: { from: string, to: string }): string[] {
6
- const { from = '', to = '' } = _;
7
- const days: Date[] = [];
8
-
9
- if (!from || !to || !iso8601Regex.test(from) || !iso8601Regex.test(to)) {
10
- return days as any[];
11
- }
12
-
13
- const _from = new Date(from);
14
- const _to = new Date(to);
15
-
16
- let current = _from;
17
-
18
- while (current < _to) {
19
- days.push(current);
20
- current = new Date(+current + MILLIS_PER_DAY);
21
- }
22
-
23
- days.push(_to);
24
-
25
- return days.map(day => day.toISOString().split('T')[0]);
26
- }
@@ -1,12 +0,0 @@
1
- import { subtractOffset } from './subtract-offset.function';
2
-
3
- describe('subtractOffset', () => {
4
- describe('GIVEN input is partial or full ISO8601', () => {
5
- it.each([
6
- '2023-12-23',
7
- '2023-12-23T00:00:00.000',
8
- ])('%j', (input) => {
9
- expect(subtractOffset(input)).toMatchSnapshot();
10
- });
11
- });
12
- });
@@ -1,14 +0,0 @@
1
- import { MILLIS_PER_MINUTE } from '../constants/millis-per-minute.constant';
2
- import { tryParseDate } from './try-parse-date.function';
3
-
4
- export function subtractOffset(input: string | Date | undefined | null): Date | undefined {
5
- const parsed = tryParseDate(input);
6
-
7
- if(!parsed) {
8
- return;
9
- }
10
-
11
- const offset = (parsed).getTimezoneOffset();
12
-
13
- return new Date(parsed.valueOf() - offset * MILLIS_PER_MINUTE);
14
- }
@@ -1,3 +0,0 @@
1
- export function toBooleanString(val?: boolean) {
2
- return (!!(val || false)).toString() as 'true' | 'false';
3
- }
@@ -1,11 +0,0 @@
1
- import { subtractOffset } from "./subtract-offset.function";
2
-
3
- export function toCalendarDate(input: string | Date | undefined | null): string | undefined {
4
- const parsed = subtractOffset(input);
5
-
6
- if (!parsed) {
7
- return;
8
- }
9
-
10
- return parsed?.toISOString().split('T')[0];
11
- }
@@ -1,3 +0,0 @@
1
- export function toCsvString(val?: string[]) {
2
- return (val || []).join(',');
3
- }
@@ -1,23 +0,0 @@
1
- export function toDecimalBase(n: string | number, base = 16) {
2
- const digits = n.toString().split('');
3
-
4
- let answer = 0;
5
-
6
- digits.reverse().forEach(function (d, i) {
7
- let actualNumber = Number(d);
8
-
9
- if (!actualNumber && actualNumber !== 0) {
10
- const codeAt = d.charCodeAt(0);
11
-
12
- if (codeAt >= 97) {
13
- actualNumber = codeAt - 87;
14
- } else {
15
- actualNumber = codeAt - 55;
16
- }
17
- }
18
-
19
- answer = answer + actualNumber * Math.pow(base, i);
20
- });
21
-
22
- return answer;
23
- }
@@ -1,7 +0,0 @@
1
- import { toDollarsAndCents } from './to-dollars-and-cents.function';
2
-
3
- describe('toDollarsAndCents', () => {
4
- it('worx', () => {
5
- expect(toDollarsAndCents(337.33)).toMatchSnapshot();
6
- });
7
- });
@@ -1,17 +0,0 @@
1
- import { removeAlphaChars } from "./remove-alpha-chars.function";
2
- import { toWords } from "./to-words.function";
3
-
4
- export function toDollarsAndCents(input: string | number): string {
5
- const number = removeAlphaChars(input);
6
- const num = Number(number);
7
- const decimal = (Math.round((num % 1) * 100)) / 100;
8
- const int = num - decimal;
9
-
10
- const dollars = `${toWords(int)} dollars`;
11
-
12
- if (!decimal) {
13
- return dollars;
14
- }
15
-
16
- return `${dollars} and ${toWords(decimal * 100)} cents`;
17
- }
@@ -1,25 +0,0 @@
1
- // https://github.com/lodash/lodash/blob/main/src/toString.ts
2
-
3
- import { isSymbol } from './is-symbol.function';
4
-
5
- /** Used as references for various `Number` constants. */
6
- const INFINITY = 1 / 0;
7
-
8
- export function toString(value: any): string {
9
- if (value == null) {
10
- return '';
11
- }
12
- // Exit early for strings to avoid a performance hit in some environments.
13
- if (typeof value === 'string') {
14
- return value;
15
- }
16
- if (Array.isArray(value)) {
17
- // Recursively convert values (susceptible to call stack limits).
18
- return `${value.map((other) => (other == null ? other : toString(other)))}`;
19
- }
20
- if (isSymbol(value)) {
21
- return value.toString();
22
- }
23
- const result = `${value}`;
24
- return result === '0' && 1 / value === -INFINITY ? '-0' : result;
25
- }
@@ -1,45 +0,0 @@
1
- import { toUniqueArray } from './to-unique-array.function';
2
-
3
- describe('toUniqueArray', () => {
4
- it.each([
5
- [
6
- [1, 2, 3],
7
- [1, 2, 3],
8
- ],
9
- [[1, 1, 1], [1]],
10
- ])(
11
- 'GIVEN array of numbers: %j, returns a unique array without duplicate elements',
12
- (array, expected) => {
13
- expect(toUniqueArray(array)).toEqual(expected);
14
- }
15
- );
16
-
17
- it.each([
18
- [
19
- ['one', 'two', 'three'],
20
- ['one', 'two', 'three'],
21
- ],
22
- [['one', 'one', 'one'], ['one']],
23
- ])(
24
- 'GIVEN array of strings: %j, returns a unique array without duplicate elements',
25
- (array, expected) => {
26
- expect(toUniqueArray(array)).toEqual(expected);
27
- }
28
- );
29
-
30
- it.each([
31
- [
32
- ['one', 'two', 'three', undefined, undefined],
33
- ['one', 'two', 'three', undefined],
34
- ],
35
- [
36
- ['one', 'one', 'one', null, null],
37
- ['one', null],
38
- ],
39
- ])(
40
- 'GIVEN array with falsey values: %j, returns a unique array without duplicate elements including falsey values',
41
- (array, expected) => {
42
- expect(toUniqueArray(array)).toEqual(expected);
43
- }
44
- );
45
- });
@@ -1,3 +0,0 @@
1
- export function toUniqueArray<TElement>(elements: TElement[]): TElement[] {
2
- return Array.from(new Set(elements));
3
- }
@@ -1,7 +0,0 @@
1
- import { toWords } from "./to-words.function";
2
-
3
- describe('toWords', () => {
4
- it('worx', () => {
5
- expect(toWords(337)).toMatchSnapshot();
6
- });
7
- });
@@ -1,108 +0,0 @@
1
- import { removeAlphaChars } from "./remove-alpha-chars.function";
2
-
3
- const MAX_SAFE_INTEGER = 9007199254740991;
4
-
5
- const TEN = 10;
6
- const ONE_HUNDRED = 100;
7
- const ONE_THOUSAND = 1000;
8
- const ONE_MILLION = 1000000;
9
- const ONE_BILLION = 1000000000;
10
- const ONE_TRILLION = 1000000000000;
11
- const ONE_QUADRILLION = 1000000000000000;
12
- const MAX = MAX_SAFE_INTEGER + 1;
13
- const LESS_THAN_TWENTY = [
14
- 'zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten',
15
- 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'
16
- ];
17
- const TENTHS_LESS_THAN_HUNDRED = [
18
- 'zero', 'ten', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety'
19
- ];
20
-
21
- export function toWords(input: number | string): string {
22
- let words: string;
23
- const number = removeAlphaChars(input) || '0';
24
- const num = parseInt(number, 10);
25
-
26
- if (!isFinite(num)) {
27
- throw new TypeError(
28
- 'Not a finite number: ' + number + ' (' + typeof number + ')'
29
- );
30
- }
31
-
32
- if (!isSafeNumber(num)) {
33
- throw new RangeError(
34
- 'Input is not a safe number, it\'s either too large or too small.'
35
- );
36
- }
37
-
38
- words = generateWords(num);
39
-
40
- return words;
41
- }
42
-
43
- function generateWords(number: any, words?: any[]): string {
44
- let remainder, word;
45
-
46
- if (number === 0) {
47
- return !words ? 'zero' : words.join(' ').replace(/,$/, '');
48
- }
49
-
50
- if (!words) {
51
- words = [];
52
- }
53
-
54
- if (number < 0) {
55
- words.push('minus');
56
- number = Math.abs(number);
57
- }
58
-
59
- if (number < 20) {
60
- remainder = 0;
61
- word = LESS_THAN_TWENTY[number];
62
-
63
- } else if (number < ONE_HUNDRED) {
64
- remainder = number % TEN;
65
- word = TENTHS_LESS_THAN_HUNDRED[Math.floor(number / TEN)];
66
-
67
- if (remainder) {
68
- word += '-' + LESS_THAN_TWENTY[remainder];
69
- remainder = 0;
70
- }
71
-
72
- } else if (number < ONE_THOUSAND) {
73
- remainder = number % ONE_HUNDRED;
74
- word = generateWords(Math.floor(number / ONE_HUNDRED)) + ' hundred';
75
-
76
- } else if (number < ONE_MILLION) {
77
- remainder = number % ONE_THOUSAND;
78
- word = generateWords(Math.floor(number / ONE_THOUSAND)) + ' thousand,';
79
-
80
- } else if (number < ONE_BILLION) {
81
- remainder = number % ONE_MILLION;
82
- word = generateWords(Math.floor(number / ONE_MILLION)) + ' million,';
83
-
84
- } else if (number < ONE_TRILLION) {
85
- remainder = number % ONE_BILLION;
86
- word = generateWords(Math.floor(number / ONE_BILLION)) + ' billion,';
87
-
88
- } else if (number < ONE_QUADRILLION) {
89
- remainder = number % ONE_TRILLION;
90
- word = generateWords(Math.floor(number / ONE_TRILLION)) + ' trillion,';
91
-
92
- } else if (number <= MAX) {
93
- remainder = number % ONE_QUADRILLION;
94
- word = generateWords(Math.floor(number / ONE_QUADRILLION)) +
95
- ' quadrillion,';
96
- }
97
-
98
- words.push(word);
99
- return generateWords(remainder, words);
100
- }
101
-
102
- function isFinite(value: any) {
103
- return !(typeof value !== 'number' || value !== value || value === Infinity || value === -Infinity);
104
- }
105
-
106
- function isSafeNumber(value: any) {
107
- return typeof value === 'number' && Math.abs(value) <= MAX_SAFE_INTEGER;
108
- }
@@ -1,37 +0,0 @@
1
- import { tryJsonParse } from './try-json-parse';
2
-
3
- describe('tryJsonParse', () => {
4
- describe('GIVEN input is parseable', () => {
5
- describe.each([
6
- [0, 0],
7
- ['0', 0],
8
- [337, expect.any(Number)],
9
- [`${337}`, expect.any(Number)],
10
- [false, false],
11
- ['false', false],
12
- [true, true],
13
- ['true', true],
14
- [`{ "test": ${337} }`, expect.objectContaining({ test: expect.any(Number) })],
15
- [`{ "test": "${337}" }`, expect.objectContaining({ test: expect.stringMatching(/\d/) })],
16
- ])('WHEN input is: %j', (input, expectedOutput) => {
17
- it(`returns ${expectedOutput}`, () => {
18
- expect(tryJsonParse(input as any)).toEqual(expectedOutput);
19
- });
20
- });
21
- });
22
-
23
- describe('GIVEN input is not parseable', () => {
24
- describe.each([
25
- ['', null],
26
- [null, null],
27
- [undefined, null],
28
- [NaN, null],
29
- ['randomness', null],
30
- ['totally random', null],
31
- ])('WHEN input is: %j', (input, expectedOutput) => {
32
- it(`returns ${expectedOutput}`, () => {
33
- expect(tryJsonParse(input as any)).toEqual(expectedOutput);
34
- });
35
- });
36
- });
37
- });
@@ -1,11 +0,0 @@
1
- export function tryJsonParse<T>(parseable: string | null | undefined): T | null {
2
- if (typeof parseable === 'undefined') {
3
- return null;
4
- }
5
-
6
- try {
7
- return JSON.parse(parseable as any) as T;
8
- } catch (_e) {
9
- return null;
10
- }
11
- }