@onivoro/isomorphic-common 0.1.1 → 0.2.1

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 (142) hide show
  1. package/cjs/jest.config.js +19 -0
  2. package/cjs/src/index.js +45 -0
  3. package/cjs/src/lib/constants/millis-per-day.constant.js +5 -0
  4. package/cjs/src/lib/constants/millis-per-hour.constant.js +5 -0
  5. package/cjs/src/lib/constants/millis-per-minute.constant.js +4 -0
  6. package/cjs/src/lib/functions/add-offset.function.js +14 -0
  7. package/cjs/src/lib/functions/add-offset.function.spec.js +13 -0
  8. package/cjs/src/lib/functions/camel-case.function.js +31 -0
  9. package/cjs/src/lib/functions/convert-object-to-literal.function.js +10 -0
  10. package/cjs/src/lib/functions/convert-object-to-literal.function.spec.js +11 -0
  11. package/cjs/src/lib/functions/from-boolean-string.function.js +7 -0
  12. package/cjs/src/lib/functions/from-calendar-date.function.js +8 -0
  13. package/cjs/src/lib/functions/from-calendar-date.function.spec.js +12 -0
  14. package/cjs/src/lib/functions/from-csv-string.function.js +7 -0
  15. package/cjs/src/lib/functions/get-tag.function.js +12 -0
  16. package/cjs/src/lib/functions/is-symbol.function.js +11 -0
  17. package/cjs/src/lib/functions/kebab-case.function.js +8 -0
  18. package/cjs/src/lib/functions/parse-bool.function.js +7 -0
  19. package/cjs/src/lib/functions/properties-to-array.function.js +19 -0
  20. package/cjs/src/lib/functions/sanitize-filename.function.js +11 -0
  21. package/cjs/src/lib/functions/snake-case.function.js +32 -0
  22. package/cjs/src/lib/functions/subtract-offset.function.js +14 -0
  23. package/cjs/src/lib/functions/subtract-offset.function.spec.js +13 -0
  24. package/cjs/src/lib/functions/to-boolean-string.function.js +7 -0
  25. package/cjs/src/lib/functions/to-calendar-date.function.js +12 -0
  26. package/cjs/src/lib/functions/to-csv-string.function.js +7 -0
  27. package/cjs/src/lib/functions/to-decimal-base.function.js +22 -0
  28. package/cjs/src/lib/functions/to-dollars-and-cents.function.js +15 -0
  29. package/cjs/src/lib/functions/to-dollars-and-cents.function.spec.js +8 -0
  30. package/cjs/src/lib/functions/to-string.function.js +26 -0
  31. package/cjs/src/lib/functions/to-unique-array.function.js +7 -0
  32. package/cjs/src/lib/functions/to-unique-array.function.spec.js +35 -0
  33. package/cjs/src/lib/functions/to-words.function.js +90 -0
  34. package/cjs/src/lib/functions/to-words.function.spec.js +8 -0
  35. package/cjs/src/lib/functions/try-parse-date.function.js +17 -0
  36. package/cjs/src/lib/functions/try-parse-date.function.spec.js +13 -0
  37. package/cjs/src/lib/functions/unicode-words.const.js +69 -0
  38. package/cjs/src/lib/functions/upper-first.function.js +13 -0
  39. package/cjs/src/lib/functions/upper-first.function.spec.js +16 -0
  40. package/cjs/src/lib/functions/words.function.js +35 -0
  41. package/cjs/src/lib/interfaces/axios-wrapped-nest-exception.interface.js +2 -0
  42. package/cjs/src/lib/interfaces/entity-provider.interface.js +2 -0
  43. package/cjs/src/lib/interfaces/keys-of.type.js +2 -0
  44. package/dist +22 -0
  45. package/esm/jest.config.js +17 -0
  46. package/esm/package.json +1 -0
  47. package/esm/src/index.js +29 -0
  48. package/esm/src/lib/constants/millis-per-day.constant.js +2 -0
  49. package/esm/src/lib/constants/millis-per-hour.constant.js +2 -0
  50. package/esm/src/lib/constants/millis-per-minute.constant.js +1 -0
  51. package/esm/src/lib/functions/add-offset.function.js +10 -0
  52. package/esm/src/lib/functions/add-offset.function.spec.js +11 -0
  53. package/esm/src/lib/functions/camel-case.function.js +27 -0
  54. package/esm/src/lib/functions/convert-object-to-literal.function.js +6 -0
  55. package/esm/src/lib/functions/convert-object-to-literal.function.spec.js +9 -0
  56. package/esm/src/lib/functions/from-boolean-string.function.js +3 -0
  57. package/esm/src/lib/functions/from-calendar-date.function.js +4 -0
  58. package/esm/src/lib/functions/from-calendar-date.function.spec.js +10 -0
  59. package/esm/src/lib/functions/from-csv-string.function.js +3 -0
  60. package/esm/src/lib/functions/get-tag.function.js +8 -0
  61. package/esm/src/lib/functions/is-symbol.function.js +7 -0
  62. package/esm/src/lib/functions/kebab-case.function.js +4 -0
  63. package/esm/src/lib/functions/parse-bool.function.js +3 -0
  64. package/esm/src/lib/functions/properties-to-array.function.js +15 -0
  65. package/esm/src/lib/functions/sanitize-filename.function.js +7 -0
  66. package/esm/src/lib/functions/snake-case.function.js +28 -0
  67. package/esm/src/lib/functions/subtract-offset.function.js +10 -0
  68. package/esm/src/lib/functions/subtract-offset.function.spec.js +11 -0
  69. package/esm/src/lib/functions/to-boolean-string.function.js +3 -0
  70. package/esm/src/lib/functions/to-calendar-date.function.js +8 -0
  71. package/esm/src/lib/functions/to-csv-string.function.js +3 -0
  72. package/esm/src/lib/functions/to-decimal-base.function.js +18 -0
  73. package/esm/src/lib/functions/to-dollars-and-cents.function.js +11 -0
  74. package/esm/src/lib/functions/to-dollars-and-cents.function.spec.js +6 -0
  75. package/esm/src/lib/functions/to-string.function.js +22 -0
  76. package/esm/src/lib/functions/to-unique-array.function.js +3 -0
  77. package/esm/src/lib/functions/to-unique-array.function.spec.js +33 -0
  78. package/esm/src/lib/functions/to-words.function.js +86 -0
  79. package/esm/src/lib/functions/to-words.function.spec.js +6 -0
  80. package/esm/src/lib/functions/try-parse-date.function.js +13 -0
  81. package/esm/src/lib/functions/try-parse-date.function.spec.js +11 -0
  82. package/esm/src/lib/functions/unicode-words.const.js +65 -0
  83. package/esm/src/lib/functions/upper-first.function.js +9 -0
  84. package/esm/src/lib/functions/upper-first.function.spec.js +14 -0
  85. package/esm/src/lib/functions/words.function.js +31 -0
  86. package/esm/src/lib/interfaces/axios-wrapped-nest-exception.interface.js +1 -0
  87. package/esm/src/lib/interfaces/entity-provider.interface.js +1 -0
  88. package/esm/src/lib/interfaces/keys-of.type.js +1 -0
  89. package/jest.config.ts +17 -0
  90. package/package.json +16 -6
  91. package/src/index.ts +31 -0
  92. package/src/lib/constants/millis-per-day.constant.ts +3 -0
  93. package/src/lib/constants/millis-per-hour.constant.ts +3 -0
  94. package/src/lib/constants/millis-per-minute.constant.ts +1 -0
  95. package/src/lib/functions/__snapshots__/add-offset.function.spec.ts.snap +5 -0
  96. package/src/lib/functions/__snapshots__/convert-object-to-literal.function.spec.ts.snap +3 -0
  97. package/src/lib/functions/__snapshots__/from-calendar-date.function.spec.ts.snap +3 -0
  98. package/src/lib/functions/__snapshots__/subtract-offset.function.spec.ts.snap +5 -0
  99. package/src/lib/functions/__snapshots__/to-dollars-and-cents.function.spec.ts.snap +3 -0
  100. package/src/lib/functions/__snapshots__/to-words.function.spec.ts.snap +3 -0
  101. package/src/lib/functions/__snapshots__/try-parse-date.function.spec.ts.snap +5 -0
  102. package/src/lib/functions/__snapshots__/upper-first.function.spec.ts.snap +13 -0
  103. package/src/lib/functions/add-offset.function.spec.ts +12 -0
  104. package/src/lib/functions/add-offset.function.ts +14 -0
  105. package/src/lib/functions/camel-case.function.ts +30 -0
  106. package/src/lib/functions/convert-object-to-literal.function.spec.ts +16 -0
  107. package/src/lib/functions/convert-object-to-literal.function.ts +10 -0
  108. package/src/lib/functions/from-boolean-string.function.ts +3 -0
  109. package/src/lib/functions/from-calendar-date.function.spec.ts +11 -0
  110. package/src/lib/functions/from-calendar-date.function.ts +5 -0
  111. package/src/lib/functions/from-csv-string.function.ts +3 -0
  112. package/src/lib/functions/get-tag.function.ts +10 -0
  113. package/src/lib/functions/is-symbol.function.ts +11 -0
  114. package/src/lib/functions/kebab-case.function.ts +5 -0
  115. package/src/lib/functions/parse-bool.function.ts +3 -0
  116. package/src/lib/functions/properties-to-array.function.ts +21 -0
  117. package/src/lib/functions/sanitize-filename.function.ts +9 -0
  118. package/src/lib/functions/snake-case.function.ts +34 -0
  119. package/src/lib/functions/subtract-offset.function.spec.ts +12 -0
  120. package/src/lib/functions/subtract-offset.function.ts +14 -0
  121. package/src/lib/functions/to-boolean-string.function.ts +3 -0
  122. package/src/lib/functions/to-calendar-date.function.ts +11 -0
  123. package/src/lib/functions/to-csv-string.function.ts +3 -0
  124. package/src/lib/functions/to-decimal-base.function.ts +23 -0
  125. package/src/lib/functions/to-dollars-and-cents.function.spec.ts +7 -0
  126. package/src/lib/functions/to-dollars-and-cents.function.ts +15 -0
  127. package/src/lib/functions/to-string.function.ts +25 -0
  128. package/src/lib/functions/to-unique-array.function.spec.ts +45 -0
  129. package/src/lib/functions/to-unique-array.function.ts +3 -0
  130. package/src/lib/functions/to-words.function.spec.ts +7 -0
  131. package/src/lib/functions/to-words.function.ts +105 -0
  132. package/src/lib/functions/try-parse-date.function.spec.ts +12 -0
  133. package/src/lib/functions/try-parse-date.function.ts +17 -0
  134. package/src/lib/functions/unicode-words.const.ts +70 -0
  135. package/src/lib/functions/upper-first.function.spec.ts +16 -0
  136. package/src/lib/functions/upper-first.function.ts +10 -0
  137. package/src/lib/functions/words.function.ts +38 -0
  138. package/src/lib/interfaces/axios-wrapped-nest-exception.interface.ts +5 -0
  139. package/src/lib/interfaces/entity-provider.interface.ts +9 -0
  140. package/src/lib/interfaces/keys-of.type.ts +1 -0
  141. package/tsconfig.json +16 -0
  142. package/index.cjs.js +0 -465
@@ -0,0 +1,86 @@
1
+ const MAX_SAFE_INTEGER = 9007199254740991;
2
+ const TEN = 10;
3
+ const ONE_HUNDRED = 100;
4
+ const ONE_THOUSAND = 1000;
5
+ const ONE_MILLION = 1000000;
6
+ const ONE_BILLION = 1000000000;
7
+ const ONE_TRILLION = 1000000000000;
8
+ const ONE_QUADRILLION = 1000000000000000;
9
+ const MAX = MAX_SAFE_INTEGER + 1;
10
+ const LESS_THAN_TWENTY = [
11
+ 'zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten',
12
+ 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'
13
+ ];
14
+ const TENTHS_LESS_THAN_HUNDRED = [
15
+ 'zero', 'ten', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety'
16
+ ];
17
+ export function toWords(number) {
18
+ let words;
19
+ const num = parseInt(number, 10);
20
+ if (!isFinite(num)) {
21
+ throw new TypeError('Not a finite number: ' + number + ' (' + typeof number + ')');
22
+ }
23
+ if (!isSafeNumber(num)) {
24
+ throw new RangeError('Input is not a safe number, it\'s either too large or too small.');
25
+ }
26
+ words = generateWords(num);
27
+ return words;
28
+ }
29
+ function generateWords(number, words) {
30
+ let remainder, word;
31
+ if (number === 0) {
32
+ return !words ? 'zero' : words.join(' ').replace(/,$/, '');
33
+ }
34
+ if (!words) {
35
+ words = [];
36
+ }
37
+ if (number < 0) {
38
+ words.push('minus');
39
+ number = Math.abs(number);
40
+ }
41
+ if (number < 20) {
42
+ remainder = 0;
43
+ word = LESS_THAN_TWENTY[number];
44
+ }
45
+ else if (number < ONE_HUNDRED) {
46
+ remainder = number % TEN;
47
+ word = TENTHS_LESS_THAN_HUNDRED[Math.floor(number / TEN)];
48
+ if (remainder) {
49
+ word += '-' + LESS_THAN_TWENTY[remainder];
50
+ remainder = 0;
51
+ }
52
+ }
53
+ else if (number < ONE_THOUSAND) {
54
+ remainder = number % ONE_HUNDRED;
55
+ word = generateWords(Math.floor(number / ONE_HUNDRED)) + ' hundred';
56
+ }
57
+ else if (number < ONE_MILLION) {
58
+ remainder = number % ONE_THOUSAND;
59
+ word = generateWords(Math.floor(number / ONE_THOUSAND)) + ' thousand,';
60
+ }
61
+ else if (number < ONE_BILLION) {
62
+ remainder = number % ONE_MILLION;
63
+ word = generateWords(Math.floor(number / ONE_MILLION)) + ' million,';
64
+ }
65
+ else if (number < ONE_TRILLION) {
66
+ remainder = number % ONE_BILLION;
67
+ word = generateWords(Math.floor(number / ONE_BILLION)) + ' billion,';
68
+ }
69
+ else if (number < ONE_QUADRILLION) {
70
+ remainder = number % ONE_TRILLION;
71
+ word = generateWords(Math.floor(number / ONE_TRILLION)) + ' trillion,';
72
+ }
73
+ else if (number <= MAX) {
74
+ remainder = number % ONE_QUADRILLION;
75
+ word = generateWords(Math.floor(number / ONE_QUADRILLION)) +
76
+ ' quadrillion,';
77
+ }
78
+ words.push(word);
79
+ return generateWords(remainder, words);
80
+ }
81
+ function isFinite(value) {
82
+ return !(typeof value !== 'number' || value !== value || value === Infinity || value === -Infinity);
83
+ }
84
+ function isSafeNumber(value) {
85
+ return typeof value === 'number' && Math.abs(value) <= MAX_SAFE_INTEGER;
86
+ }
@@ -0,0 +1,6 @@
1
+ import { toWords } from "./to-words.function";
2
+ describe('toWords', () => {
3
+ it('worx', () => {
4
+ expect(toWords(337)).toMatchSnapshot();
5
+ });
6
+ });
@@ -0,0 +1,13 @@
1
+ export function tryParseDate(input) {
2
+ if (!input) {
3
+ return;
4
+ }
5
+ if (input instanceof Date) {
6
+ return input;
7
+ }
8
+ const date = new Date(input);
9
+ if (date == 'Invalid Date') {
10
+ return;
11
+ }
12
+ return date;
13
+ }
@@ -0,0 +1,11 @@
1
+ import { tryParseDate } from './try-parse-date.function';
2
+ describe('tryParseDate', () => {
3
+ describe('GIVEN input is partial or full ISO8601', () => {
4
+ it.each([
5
+ '2023-12-23',
6
+ '2023-12-23T00:00:00.000',
7
+ ])('%j', (input) => {
8
+ expect(tryParseDate(input)).toMatchSnapshot();
9
+ });
10
+ });
11
+ });
@@ -0,0 +1,65 @@
1
+ // source https://github.com/lodash/lodash/blob/master/.internal/unicodeWords.js
2
+ /** Used to compose unicode character classes. */
3
+ const rsAstralRange = '\\ud800-\\udfff';
4
+ const rsComboMarksRange = '\\u0300-\\u036f';
5
+ const reComboHalfMarksRange = '\\ufe20-\\ufe2f';
6
+ const rsComboSymbolsRange = '\\u20d0-\\u20ff';
7
+ const rsComboMarksExtendedRange = '\\u1ab0-\\u1aff';
8
+ const rsComboMarksSupplementRange = '\\u1dc0-\\u1dff';
9
+ const rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange + rsComboMarksExtendedRange + rsComboMarksSupplementRange;
10
+ const rsDingbatRange = '\\u2700-\\u27bf';
11
+ const rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff';
12
+ const rsMathOpRange = '\\xac\\xb1\\xd7\\xf7';
13
+ const rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf';
14
+ const rsPunctuationRange = '\\u2000-\\u206f';
15
+ const rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000';
16
+ const rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde';
17
+ const rsVarRange = '\\ufe0e\\ufe0f';
18
+ const rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange;
19
+ /** Used to compose unicode capture groups. */
20
+ const rsApos = "['\u2019]";
21
+ const rsBreak = `[${rsBreakRange}]`;
22
+ const rsCombo = `[${rsComboRange}]`;
23
+ const rsDigit = '\\d';
24
+ const rsDingbat = `[${rsDingbatRange}]`;
25
+ const rsLower = `[${rsLowerRange}]`;
26
+ const rsMisc = `[^${rsAstralRange}${rsBreakRange + rsDigit + rsDingbatRange + rsLowerRange + rsUpperRange}]`;
27
+ const rsFitz = '\\ud83c[\\udffb-\\udfff]';
28
+ const rsModifier = `(?:${rsCombo}|${rsFitz})`;
29
+ const rsNonAstral = `[^${rsAstralRange}]`;
30
+ const rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}';
31
+ const rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]';
32
+ const rsUpper = `[${rsUpperRange}]`;
33
+ const rsZWJ = '\\u200d';
34
+ /** Used to compose unicode regexes. */
35
+ const rsMiscLower = `(?:${rsLower}|${rsMisc})`;
36
+ const rsMiscUpper = `(?:${rsUpper}|${rsMisc})`;
37
+ const rsOptContrLower = `(?:${rsApos}(?:d|ll|m|re|s|t|ve))?`;
38
+ const rsOptContrUpper = `(?:${rsApos}(?:D|LL|M|RE|S|T|VE))?`;
39
+ const reOptMod = `${rsModifier}?`;
40
+ const rsOptVar = `[${rsVarRange}]?`;
41
+ const rsOptJoin = `(?:${rsZWJ}(?:${[rsNonAstral, rsRegional, rsSurrPair].join('|')})${rsOptVar + reOptMod})*`;
42
+ const rsOrdLower = '\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])';
43
+ const rsOrdUpper = '\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])';
44
+ const rsSeq = rsOptVar + reOptMod + rsOptJoin;
45
+ const rsEmoji = `(?:${[rsDingbat, rsRegional, rsSurrPair].join('|')})${rsSeq}`;
46
+ const reUnicodeWords = RegExp([
47
+ `${rsUpper}?${rsLower}+${rsOptContrLower}(?=${[rsBreak, rsUpper, '$'].join('|')})`,
48
+ `${rsMiscUpper}+${rsOptContrUpper}(?=${[rsBreak, rsUpper + rsMiscLower, '$'].join('|')})`,
49
+ `${rsUpper}?${rsMiscLower}+${rsOptContrLower}`,
50
+ `${rsUpper}+${rsOptContrUpper}`,
51
+ rsOrdUpper,
52
+ rsOrdLower,
53
+ `${rsDigit}+`,
54
+ rsEmoji
55
+ ].join('|'), 'g');
56
+ /**
57
+ * Splits a Unicode `string` into an array of its words.
58
+ *
59
+ * @private
60
+ * @param {string} The string to inspect.
61
+ * @returns {Array} Returns the words of `string`.
62
+ */
63
+ export function unicodeWords(string) {
64
+ return string.match(reUnicodeWords);
65
+ }
@@ -0,0 +1,9 @@
1
+ export function upperFirst(string) {
2
+ if (!string) {
3
+ return string;
4
+ }
5
+ return string
6
+ .split('')
7
+ .map((curr, i) => curr[!i ? 'toUpperCase' : 'toLowerCase']())
8
+ .join('');
9
+ }
@@ -0,0 +1,14 @@
1
+ import { upperFirst } from './upper-first.function';
2
+ describe('upperFirst', () => {
3
+ it.each([
4
+ 'asdf',
5
+ 'XCVB'
6
+ ])('GIVEN %j, does what u expect', (input) => {
7
+ expect(upperFirst(input)).toMatchSnapshot();
8
+ });
9
+ it.each([
10
+ null, undefined, 0, false
11
+ ])('GIVEN falsey input %j, does what u expect', (input) => {
12
+ expect(upperFirst(input)).toMatchSnapshot();
13
+ });
14
+ });
@@ -0,0 +1,31 @@
1
+ // source https://github.com/lodash/lodash/blob/master/words.js
2
+ import { unicodeWords } from './unicode-words.const';
3
+ const hasUnicodeWord = RegExp.prototype.test.bind(/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/);
4
+ /** Used to match words composed of alphanumeric characters. */
5
+ const reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
6
+ function asciiWords(string) {
7
+ return string.match(reAsciiWord);
8
+ }
9
+ /**
10
+ * Splits `string` into an array of its words.
11
+ *
12
+ * @since 3.0.0
13
+ * @category String
14
+ * @param {string} [string=''] The string to inspect.
15
+ * @param {RegExp|string} [pattern] The pattern to match words.
16
+ * @returns {Array} Returns the words of `string`.
17
+ * @example
18
+ *
19
+ * words('fred, barney, & pebbles')
20
+ * // => ['fred', 'barney', 'pebbles']
21
+ *
22
+ * words('fred, barney, & pebbles', /[^, ]+/g)
23
+ * // => ['fred', 'barney', '&', 'pebbles']
24
+ */
25
+ export function words(string, pattern) {
26
+ if (pattern === undefined) {
27
+ const result = hasUnicodeWord(string) ? unicodeWords(string) : asciiWords(string);
28
+ return result || [];
29
+ }
30
+ return string.match(pattern) || [];
31
+ }
@@ -0,0 +1 @@
1
+ export {};
package/jest.config.ts ADDED
@@ -0,0 +1,17 @@
1
+ /* eslint-disable */
2
+ export default {
3
+ displayName: 'isomorphic-common',
4
+ preset: '../../jest.preset.js',
5
+ globals: {},
6
+ testEnvironment: 'node',
7
+ transform: {
8
+ '^.+\\.[tj]sx?$': [
9
+ 'ts-jest',
10
+ {
11
+ tsconfig: '<rootDir>/tsconfig.spec.json',
12
+ },
13
+ ],
14
+ },
15
+ moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
16
+ coverageDirectory: '../../coverage/libs/isomorphic-common',
17
+ };
package/package.json CHANGED
@@ -1,12 +1,22 @@
1
1
  {
2
2
  "name": "@onivoro/isomorphic-common",
3
- "version": "0.1.1",
4
- "main": "index.cjs.js",
5
- "module": "index.cjs.js",
3
+ "version": "0.2.1",
4
+ "module": "esm/index.js",
5
+ "type": "module",
6
+ "main": "cjs/index.js",
7
+ "scripts": {
8
+ "esb": "npx esbuild src/index.ts --bundle --platform=node --target=node16.20.2 > dist/index.cjs.js",
9
+ "ts": "npx tsc --module es2022 --outDir esm/ && echo '{\"type\": \"module\"}' > esm/package.json",
10
+ "push": "npm run ts && cp package.json dist && npm publish --access public"
11
+ },
6
12
  "exports": {
7
13
  ".": {
8
- "import": "./index.cjs.js",
9
- "require": "./index.cjs.js"
14
+ "require": "./cjs/index.js",
15
+ "import": "./esm/index.js"
10
16
  }
17
+ },
18
+ "devDependencies": {
19
+ "@types/jest": "^29.5.12",
20
+ "typescript": "^5.3.3"
11
21
  }
12
- }
22
+ }
package/src/index.ts ADDED
@@ -0,0 +1,31 @@
1
+ export * from './lib/constants/millis-per-day.constant';
2
+ export * from './lib/constants/millis-per-hour.constant';
3
+ export * from './lib/constants/millis-per-minute.constant';
4
+
5
+ export * from './lib/functions/add-offset.function';
6
+ export * from './lib/functions/camel-case.function';
7
+ export * from './lib/functions/convert-object-to-literal.function';
8
+ export * from './lib/functions/from-boolean-string.function';
9
+ export * from './lib/functions/from-calendar-date.function';
10
+ export * from './lib/functions/from-csv-string.function';
11
+ export * from './lib/functions/kebab-case.function';
12
+ export * from './lib/functions/parse-bool.function';
13
+ export * from './lib/functions/properties-to-array.function';
14
+ export * from './lib/functions/sanitize-filename.function';
15
+ export * from './lib/functions/snake-case.function';
16
+ export * from './lib/functions/subtract-offset.function';
17
+ export * from './lib/functions/to-boolean-string.function';
18
+ export * from './lib/functions/to-calendar-date.function';
19
+ export * from './lib/functions/to-csv-string.function';
20
+ export * from './lib/functions/to-decimal-base.function';
21
+ export * from './lib/functions/to-dollars-and-cents.function';
22
+ export * from './lib/functions/to-unique-array.function';
23
+ export * from './lib/functions/to-words.function';
24
+ export * from './lib/functions/try-parse-date.function';
25
+ export * from './lib/functions/unicode-words.const';
26
+ export * from './lib/functions/upper-first.function';
27
+ export * from './lib/functions/words.function';
28
+
29
+ export * from './lib/interfaces/axios-wrapped-nest-exception.interface';
30
+ export * from './lib/interfaces/entity-provider.interface';
31
+ export * from './lib/interfaces/keys-of.type';
@@ -0,0 +1,3 @@
1
+ import { MILLIS_PER_HOUR } from "./millis-per-hour.constant";
2
+
3
+ export const MILLIS_PER_DAY = MILLIS_PER_HOUR * 24;
@@ -0,0 +1,3 @@
1
+ import { MILLIS_PER_MINUTE } from "./millis-per-minute.constant";
2
+
3
+ export const MILLIS_PER_HOUR = MILLIS_PER_MINUTE * 60;
@@ -0,0 +1 @@
1
+ export const MILLIS_PER_MINUTE = 1000 * 60;
@@ -0,0 +1,5 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`addOffset GIVEN input is partial or full ISO8601 "2023-12-23" 1`] = `2023-12-23T06:00:00.000Z`;
4
+
5
+ exports[`addOffset GIVEN input is partial or full ISO8601 "2023-12-23T00:00:00.000" 1`] = `2023-12-23T12:00:00.000Z`;
@@ -0,0 +1,3 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`/Users/lee/github.com/onivoro/onivoro/libs/isomorphic-common/src/lib/functions/convert-object-to-literal.function.spec.ts converts an object to a string 1`] = `"qty=337 AND price=100 AND product=flux-capacitor"`;
@@ -0,0 +1,3 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`fromCalendarDate GIVEN input is partial or full ISO8601 "2023-12-23" 1`] = `2023-12-22T12:00:00.000Z`;
@@ -0,0 +1,5 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`subtractOffset GIVEN input is partial or full ISO8601 "2023-12-23" 1`] = `2023-12-22T18:00:00.000Z`;
4
+
5
+ exports[`subtractOffset GIVEN input is partial or full ISO8601 "2023-12-23T00:00:00.000" 1`] = `2023-12-23T00:00:00.000Z`;
@@ -0,0 +1,3 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`toDollarsAndCents worx 1`] = `"three hundred thirty-seven dollars and thirty-three cents"`;
@@ -0,0 +1,3 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`toWords worx 1`] = `"three hundred thirty-seven"`;
@@ -0,0 +1,5 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`tryParseDate GIVEN input is partial or full ISO8601 "2023-12-23" 1`] = `2023-12-23T00:00:00.000Z`;
4
+
5
+ exports[`tryParseDate GIVEN input is partial or full ISO8601 "2023-12-23T00:00:00.000" 1`] = `2023-12-23T06:00:00.000Z`;
@@ -0,0 +1,13 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`upperFirst GIVEN "XCVB", does what u expect 1`] = `"Xcvb"`;
4
+
5
+ exports[`upperFirst GIVEN "asdf", does what u expect 1`] = `"Asdf"`;
6
+
7
+ exports[`upperFirst GIVEN falsey input 0, does what u expect 1`] = `0`;
8
+
9
+ exports[`upperFirst GIVEN falsey input false, does what u expect 1`] = `false`;
10
+
11
+ exports[`upperFirst GIVEN falsey input null, does what u expect 1`] = `null`;
12
+
13
+ exports[`upperFirst GIVEN falsey input undefined, does what u expect 1`] = `undefined`;
@@ -0,0 +1,12 @@
1
+ import { addOffset } from './add-offset.function';
2
+
3
+ describe('addOffset', () => {
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(addOffset(input)).toMatchSnapshot();
10
+ });
11
+ });
12
+ });
@@ -0,0 +1,14 @@
1
+ import { MILLIS_PER_MINUTE } from '../constants/millis-per-minute.constant';
2
+ import { tryParseDate } from './try-parse-date.function';
3
+
4
+ export function addOffset(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
+ }
@@ -0,0 +1,30 @@
1
+ // https://github.com/lodash/lodash/blob/main/src/camelCase.ts
2
+
3
+ import { toString } from './to-string.function';
4
+ import { upperFirst } from './upper-first.function';
5
+ import { words } from './words.function';
6
+
7
+ /**
8
+ * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
9
+ *
10
+ * @since 3.0.0
11
+ * @category String
12
+ * @param {string} [string=''] The string to convert.
13
+ * @returns {string} Returns the camel cased string.
14
+ * @see lowerCase, kebabCase, snakeCase, startCase, upperCase, upperFirst
15
+ * @example
16
+ *
17
+ * camelCase('Foo Bar')
18
+ * // => 'fooBar'
19
+ *
20
+ * camelCase('--foo-bar--')
21
+ * // => 'fooBar'
22
+ *
23
+ * camelCase('__FOO_BAR__')
24
+ * // => 'fooBar'
25
+ */
26
+ export const camelCase = (string: string): string =>
27
+ words(toString(string).replace(/['\u2019]/g, '')).reduce((result: string, word: string, index: number) => {
28
+ word = word.toLowerCase();
29
+ return result + (index ? upperFirst(word) : word);
30
+ }, '');
@@ -0,0 +1,16 @@
1
+ import { convertObjectToLiteral } from './convert-object-to-literal.function';
2
+
3
+ const qty = 337;
4
+ const price = 100;
5
+ const product = 'flux-capacitor';
6
+
7
+ describe(__filename, () => {
8
+ it.each([[(k, v) => `${k}=${v}`, ' AND ', { qty, price, product }]])(
9
+ 'converts an object to a string',
10
+ (literalFn, delimiter, obj) => {
11
+ expect(
12
+ convertObjectToLiteral(literalFn, delimiter, obj)
13
+ ).toMatchSnapshot();
14
+ }
15
+ );
16
+ });
@@ -0,0 +1,10 @@
1
+ export function convertObjectToLiteral(
2
+ literalFn: (k: string, v: any) => string,
3
+ delimiter: string,
4
+ keyValuePairs: Record<string, any>
5
+ ) {
6
+ return Object.entries(keyValuePairs)
7
+ .filter(([, v]) => !!v || v === 0 || v === false)
8
+ .map(([k, v]) => literalFn(k, v?.toString?.()))
9
+ .join(delimiter);
10
+ }
@@ -0,0 +1,3 @@
1
+ export function fromBooleanString(value?: string) {
2
+ return value === 'true';
3
+ }
@@ -0,0 +1,11 @@
1
+ import { fromCalendarDate } from './from-calendar-date.function';
2
+
3
+ describe('fromCalendarDate', () => {
4
+ describe('GIVEN input is partial or full ISO8601', () => {
5
+ it.each([
6
+ '2023-12-23',
7
+ ])('%j', (input) => {
8
+ expect(fromCalendarDate(input)).toMatchSnapshot();
9
+ });
10
+ });
11
+ });
@@ -0,0 +1,5 @@
1
+ import { addOffset } from "./add-offset.function";
2
+
3
+ export function fromCalendarDate(input: string | Date | undefined | null): Date | null {
4
+ return addOffset(input) || null;
5
+ }
@@ -0,0 +1,3 @@
1
+ export function fromCsvString(value?: string) {
2
+ return value ? value.split(',').map((v) => v.trim()) : [];
3
+ }
@@ -0,0 +1,10 @@
1
+ // https://github.com/lodash/lodash/blob/main/src/.internal/getTag.ts
2
+
3
+ const toString = Object.prototype.toString
4
+
5
+ export function getTag(value: any): string {
6
+ if (value == null) {
7
+ return value === undefined ? '[object Undefined]' : '[object Null]'
8
+ }
9
+ return toString.call(value)
10
+ }
@@ -0,0 +1,11 @@
1
+ // https://github.com/lodash/lodash/blob/main/src/isSymbol.ts
2
+
3
+ import { getTag } from './get-tag.function';
4
+
5
+ export function isSymbol(value: any): boolean {
6
+ const type = typeof value;
7
+ return (
8
+ type === 'symbol' ||
9
+ (type === 'object' && value != null && getTag(value) === '[object Symbol]')
10
+ );
11
+ }
@@ -0,0 +1,5 @@
1
+ import { snakeCase } from "./snake-case.function";
2
+
3
+ export function kebabCase(string) {
4
+ return snakeCase(string).replace(/_/g, '-');
5
+ }
@@ -0,0 +1,3 @@
1
+ export function parseBool(asc: string | boolean | null | undefined) {
2
+ return asc ? asc === true || asc === 'true' : false;
3
+ }
@@ -0,0 +1,21 @@
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) {
4
+ const isObject = val =>
5
+ val && typeof val === 'object' && !Array.isArray(val);
6
+
7
+ const addDelimiter = (a, b) =>
8
+ a ? `${a}.${b}` : b;
9
+
10
+ const paths = (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
+ }
@@ -0,0 +1,9 @@
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
+ }
@@ -0,0 +1,34 @@
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) {
29
+ return (
30
+ words(string.replace(/['\u2019]/g, '')).reduce((result, word, index) => (
31
+ result + (index ? '_' : '') + word.toLowerCase()
32
+ ), '')
33
+ );
34
+ }
@@ -0,0 +1,12 @@
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
+ });