@wener/utils 1.1.5 → 1.1.7

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 (137) hide show
  1. package/README.md +5 -1
  2. package/dist/cjs/index.js +1 -1
  3. package/dist/cjs/index.js.map +1 -1
  4. package/dist/cjs/server.js +1 -1
  5. package/dist/cjs/server.js.map +1 -1
  6. package/dist/esm/index.js +1 -1
  7. package/dist/esm/index.js.map +1 -1
  8. package/dist/esm/server.js +1 -1
  9. package/dist/esm/server.js.map +1 -1
  10. package/dist/system/index.js +1 -1
  11. package/dist/system/index.js.map +1 -1
  12. package/dist/system/server.js +1 -1
  13. package/dist/system/server.js.map +1 -1
  14. package/lib/arrays/MaybeArray.js.map +1 -1
  15. package/lib/asyncs/createLazyPromise.js +55 -0
  16. package/lib/asyncs/createLazyPromise.js.map +1 -0
  17. package/lib/asyncs/timeout.js +1 -1
  18. package/lib/asyncs/timeout.js.map +1 -1
  19. package/lib/browsers/copy.js +2 -3
  20. package/lib/browsers/copy.js.map +1 -1
  21. package/lib/browsers/loaders.js +6 -11
  22. package/lib/browsers/loaders.js.map +1 -1
  23. package/lib/crypto/{hex.js → base.js} +1 -1
  24. package/lib/crypto/base.js.map +1 -0
  25. package/lib/crypto/hashing.js +4 -4
  26. package/lib/crypto/hashing.js.map +1 -1
  27. package/lib/crypto/randomUUID.js +3 -5
  28. package/lib/crypto/randomUUID.js.map +1 -1
  29. package/lib/i18n/createTranslate.js +37 -0
  30. package/lib/i18n/createTranslate.js.map +1 -0
  31. package/lib/index.js +12 -7
  32. package/lib/index.js.map +1 -1
  33. package/lib/io/ArrayBuffers.js +164 -0
  34. package/lib/io/ArrayBuffers.js.map +1 -0
  35. package/lib/io/isBuffer.js +1 -1
  36. package/lib/io/isBuffer.js.map +1 -1
  37. package/lib/io/isTransferable.js +23 -0
  38. package/lib/io/isTransferable.js.map +1 -0
  39. package/lib/isomorphics/structuredClone.js +70 -0
  40. package/lib/isomorphics/structuredClone.js.map +1 -0
  41. package/lib/langs/classOf.js +6 -0
  42. package/lib/langs/classOf.js.map +1 -0
  43. package/lib/{validations/dequal.js → langs/deepEqual.js} +7 -7
  44. package/lib/langs/deepEqual.js.map +1 -0
  45. package/lib/{validations/shallow.js → langs/shallowEqual.js} +3 -3
  46. package/lib/langs/shallowEqual.js.map +1 -0
  47. package/lib/logging/createNoopLogger.js.map +1 -1
  48. package/lib/modules/isModule.js.map +1 -1
  49. package/lib/modules/parseModuleId.js +7 -5
  50. package/lib/modules/parseModuleId.js.map +1 -1
  51. package/lib/objects/parseObjectPath.js.map +1 -1
  52. package/lib/objects/set.js.map +1 -1
  53. package/lib/server/polyfillBrowser.js +12 -0
  54. package/lib/server/polyfillBrowser.js.map +1 -0
  55. package/lib/server/polyfillCrypto.js +10 -0
  56. package/lib/server/polyfillCrypto.js.map +1 -0
  57. package/lib/server/polyfillFetch.js +31 -0
  58. package/lib/server/polyfillFetch.js.map +1 -0
  59. package/lib/server/polyfillJsDom.js +49 -0
  60. package/lib/server/polyfillJsDom.js.map +1 -0
  61. package/lib/server.js +4 -1
  62. package/lib/server.js.map +1 -1
  63. package/lib/{formats → strings}/formatBytes.js +1 -1
  64. package/lib/{formats → strings}/formatBytes.js.map +1 -1
  65. package/lib/strings/renderTemplate.js +4 -2
  66. package/lib/strings/renderTemplate.js.map +1 -1
  67. package/lib/validations/isUUID.js +6 -0
  68. package/lib/validations/isUUID.js.map +1 -0
  69. package/package.json +14 -2
  70. package/src/arrays/MaybeArray.ts +1 -1
  71. package/src/asyncs/createLazyPromise.test.ts +39 -0
  72. package/src/asyncs/createLazyPromise.ts +63 -0
  73. package/src/asyncs/generatorOfStream.ts +1 -0
  74. package/src/asyncs/timeout.ts +1 -1
  75. package/src/browsers/copy.ts +6 -5
  76. package/src/browsers/loaders.ts +6 -11
  77. package/src/crypto/{hex.ts → base.ts} +3 -0
  78. package/src/crypto/hashing.test.ts +12 -8
  79. package/src/crypto/hashing.ts +4 -4
  80. package/src/crypto/randomUUID.ts +6 -4
  81. package/src/i18n/createTranslate.test.ts +155 -0
  82. package/src/i18n/createTranslate.ts +52 -0
  83. package/src/index.ts +22 -9
  84. package/src/io/AbstractEncoding.ts +21 -0
  85. package/src/io/ArrayBuffer.test-d.ts +4 -0
  86. package/src/io/ArrayBuffers.base64.test.ts +61 -0
  87. package/src/io/ArrayBuffers.test.ts +23 -0
  88. package/src/io/ArrayBuffers.ts +272 -0
  89. package/src/io/Buffer.ts +16 -0
  90. package/src/io/isBuffer.test.ts +9 -0
  91. package/src/io/isBuffer.ts +3 -8
  92. package/src/io/isTransferable.test.ts +10 -0
  93. package/src/io/isTransferable.ts +50 -0
  94. package/src/isomorphics/structuredClone.test.ts +14 -0
  95. package/src/isomorphics/structuredClone.ts +88 -0
  96. package/src/langs/classOf.ts +3 -0
  97. package/src/{validations/dequal.test.ts → langs/deepEqual.test.ts} +2 -2
  98. package/src/{validations/dequal.ts → langs/deepEqual.ts} +6 -5
  99. package/src/langs/langs.test.ts +23 -0
  100. package/src/{validations/shallow.ts → langs/shallowEqual.ts} +2 -2
  101. package/src/logging/Logger.ts +6 -0
  102. package/src/logging/createNoopLogger.ts +1 -1
  103. package/src/logging/logger.test.ts +3 -3
  104. package/src/modules/isModule.ts +3 -0
  105. package/src/modules/parseModuleId.test.ts +7 -2
  106. package/src/modules/parseModuleId.ts +15 -9
  107. package/src/objects/get.test-d.ts +51 -0
  108. package/src/objects/get.test.ts +2 -55
  109. package/src/objects/parseObjectPath.ts +4 -3
  110. package/src/objects/set.test.ts +32 -31
  111. package/src/objects/set.ts +2 -2
  112. package/src/server/polyfillBrowser.test.ts +15 -0
  113. package/src/server/polyfillBrowser.ts +17 -0
  114. package/src/server/polyfillCrypto.ts +7 -0
  115. package/src/server/polyfillFetch.ts +28 -0
  116. package/src/server/polyfillJsDom.ts +85 -0
  117. package/src/server.ts +4 -1
  118. package/src/{formats → strings}/formatBytes.ts +1 -1
  119. package/src/strings/renderTemplate.test.ts +1 -0
  120. package/src/strings/renderTemplate.ts +12 -6
  121. package/src/typedoc.ts +2 -0
  122. package/src/validations/isUUID.ts +3 -0
  123. package/tsconfig.json +2 -1
  124. package/lib/asyncs/LazyPromise.js +0 -27
  125. package/lib/asyncs/LazyPromise.js.map +0 -1
  126. package/lib/crypto/hex.js.map +0 -1
  127. package/lib/server/polyfill.js +0 -8
  128. package/lib/server/polyfill.js.map +0 -1
  129. package/lib/shim/urljoin.js +0 -51
  130. package/lib/shim/urljoin.js.map +0 -1
  131. package/lib/validations/dequal.js.map +0 -1
  132. package/lib/validations/shallow.js.map +0 -1
  133. package/src/asyncs/LazyPromise.ts +0 -29
  134. package/src/server/polyfill.ts +0 -5
  135. package/src/shim/urljoin.test.ts +0 -6
  136. package/src/shim/urljoin.ts +0 -75
  137. package/src/types.d.ts +0 -7
@@ -1,13 +1,8 @@
1
1
  /**
2
- * check {@code obj} is Buffer
2
+ * check {@link obj} is Buffer
3
3
  *
4
- * {@link https://github.com/feross/is-buffer feross/is-buffer}
4
+ * @see {@link https://github.com/feross/is-buffer feross/is-buffer}
5
5
  */
6
6
  export function isBuffer(obj: any): obj is Buffer {
7
- return (
8
- obj != null &&
9
- obj.constructor != null &&
10
- typeof obj.constructor.isBuffer === 'function' &&
11
- obj.constructor.isBuffer(obj)
12
- );
7
+ return obj?.constructor?.isBuffer?.(obj);
13
8
  }
@@ -0,0 +1,10 @@
1
+ import test from 'ava';
2
+ import { Buffer } from 'node:buffer';
3
+ import { isTransferable } from './isTransferable';
4
+
5
+ test('isTransferable', (t) => {
6
+ t.false(isTransferable(0));
7
+ t.false(isTransferable(Buffer.from('')));
8
+ t.true(new ArrayBuffer(0) instanceof ArrayBuffer);
9
+ t.true(isTransferable(new ArrayBuffer(0)));
10
+ });
@@ -0,0 +1,50 @@
1
+ /**
2
+ * transferable object pass between workers, can work with structuredClone
3
+ *
4
+ * - Chrome 87, FF 103, Safari X, NodeJS X
5
+ *
6
+ * @see {@link https://developer.mozilla.org/en-US/docs/Glossary/Transferable_objects | Transferable objects}
7
+ */
8
+ export function isTransferable(v: any): v is TransferableObject {
9
+ _ctors ||= ctors();
10
+ return _ctors.some((ctor) => v instanceof ctor);
11
+ }
12
+
13
+ let _ctors: any[];
14
+
15
+ function ctors() {
16
+ const o: any = globalThis.window || globalThis || global;
17
+ return [
18
+ o.ArrayBuffer,
19
+ o.MessagePort,
20
+ o.ReadableStream,
21
+ o.WritableStream,
22
+ o.TransformStream,
23
+ o.AudioData,
24
+ o.ImageBitmap,
25
+ o.VideoFrame,
26
+ o.OffscreenCanvas,
27
+ o.RTCDataChannel,
28
+ ].filter(Boolean);
29
+ }
30
+
31
+ export type TransferableObject =
32
+ | Transferable
33
+ | ArrayBuffer
34
+ | MessagePort
35
+ | ReadableStream
36
+ | WritableStream
37
+ | TransformStream
38
+ | AudioData
39
+ | ImageBitmap
40
+ | VideoFrame
41
+ | OffscreenCanvas
42
+ | RTCDataChannel;
43
+
44
+ declare global {
45
+ interface OffscreenCanvas {}
46
+
47
+ interface VideoFrame {}
48
+
49
+ interface AudioData {}
50
+ }
@@ -0,0 +1,14 @@
1
+ import test from 'ava';
2
+ import { classOf } from '../langs/classOf';
3
+ import { _clone } from './structuredClone';
4
+
5
+ test('structuredClone', (t) => {
6
+ for (const [k, v] of [
7
+ ['', ''],
8
+ [Number(1), 1],
9
+ ]) {
10
+ const c = _clone(k);
11
+ t.deepEqual(c, v);
12
+ t.is(classOf(c), classOf(v));
13
+ }
14
+ });
@@ -0,0 +1,88 @@
1
+ /* eslint no-proto:0 */
2
+ import { classOf } from '../langs/classOf';
3
+
4
+ /**
5
+ * Clone an object using structured cloning algorithm
6
+ *
7
+ * - Chrome 98, Safari 15.4
8
+ *
9
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/structuredClone structuredClone}
10
+ * @see {@link https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.structured-clone.js core-js}
11
+ */
12
+ export const structuredClone: <T>(value: T, options?: StructuredSerializeOptions) => T =
13
+ globalThis.structuredClone || _clone;
14
+
15
+ function set(obj: any, key: any, val: any) {
16
+ if (typeof val.value === 'object') val.value = _clone(val.value);
17
+ if (!val.enumerable || val.get || val.set || !val.configurable || !val.writable || key === '__proto__') {
18
+ Object.defineProperty(obj, key, val);
19
+ } else obj[key] = val.value;
20
+ }
21
+
22
+ /**
23
+ * @see {@link https://github.com/lukeed/klona/blob/master/src/full.js klona}
24
+ */
25
+ export function _clone(x: any): any {
26
+ // too complex
27
+ // https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.structured-clone.js
28
+
29
+ if (typeof x !== 'object') return x;
30
+
31
+ let i = 0;
32
+ let k;
33
+ let list;
34
+ let tmp: any;
35
+ const str = classOf(x);
36
+ switch (str) {
37
+ case 'Array':
38
+ tmp = Array(x.length);
39
+ break;
40
+ case 'Object':
41
+ tmp = Object.create(x.__proto__ || null);
42
+ break;
43
+ case 'Set':
44
+ tmp = new Set();
45
+ x.forEach(function (val: any) {
46
+ tmp.add(_clone(val));
47
+ });
48
+ break;
49
+ case 'Map':
50
+ tmp = new Map();
51
+ x.forEach(function (val: any, key: any) {
52
+ tmp.set(_clone(key), _clone(val));
53
+ });
54
+ break;
55
+ case 'Date':
56
+ tmp = new Date(+x);
57
+ break;
58
+ case 'RegExp':
59
+ tmp = new RegExp(x.source, x.flags);
60
+ break;
61
+ case 'DataView':
62
+ tmp = new x.constructor(_clone(x.buffer));
63
+ break;
64
+ case 'ArrayBuffer':
65
+ tmp = x.slice(0);
66
+ break;
67
+ default:
68
+ // typed arrays
69
+ if (str.endsWith('Array')) {
70
+ // ArrayBuffer.isView(x)
71
+ // ~> `new` bcuz `Buffer.slice` => ref
72
+ tmp = new x.constructor(x);
73
+ }
74
+ }
75
+
76
+ if (tmp) {
77
+ for (list = Object.getOwnPropertySymbols(x); i < list.length; i++) {
78
+ set(tmp, list[i], Object.getOwnPropertyDescriptor(x, list[i]));
79
+ }
80
+
81
+ for (i = 0, list = Object.getOwnPropertyNames(x); i < list.length; i++) {
82
+ if (Object.hasOwnProperty.call(tmp, (k = list[i])) && tmp[k] === x[k]) continue;
83
+ set(tmp, k, Object.getOwnPropertyDescriptor(x, k));
84
+ }
85
+ }
86
+
87
+ return tmp || x;
88
+ }
@@ -0,0 +1,3 @@
1
+ export function classOf(o: any) {
2
+ return Object.prototype.toString.call(o).slice(8, -1);
3
+ }
@@ -1,9 +1,9 @@
1
1
  import test from 'ava';
2
- import { dequal } from './dequal';
2
+ import { deepEqual } from './deepEqual';
3
3
 
4
4
  test('deep equal', (t) => {
5
5
  t.true(
6
- dequal(
6
+ deepEqual(
7
7
  {
8
8
  a: null,
9
9
  b: Infinity,
@@ -3,7 +3,7 @@ const hasElementType = typeof Element !== 'undefined';
3
3
 
4
4
  function find(iter: any, tar: any, key?: any) {
5
5
  for (key of iter.keys()) {
6
- if (dequal(key, tar)) return key;
6
+ if (deepEqual(key, tar)) return key;
7
7
  }
8
8
  }
9
9
 
@@ -12,7 +12,7 @@ function find(iter: any, tar: any, key?: any) {
12
12
  * @see {@link https://github.com/lukeed/dequal/blob/master/src/lite.js dequal/src/lite.js}
13
13
  * @see {@link https://github.com/FormidableLabs/react-fast-compare/blob/master/index.js react-fast-compare/index.js}
14
14
  */
15
- export function dequal(foo: any, bar: any) {
15
+ export function deepEqual(foo: any, bar: any) {
16
16
  let ctor, len, tmp;
17
17
  if (foo === bar) return true;
18
18
 
@@ -22,7 +22,7 @@ export function dequal(foo: any, bar: any) {
22
22
 
23
23
  if (ctor === Array) {
24
24
  if ((len = foo.length) === bar.length) {
25
- while (len-- && dequal(foo[len], bar[len]));
25
+ while (len-- && deepEqual(foo[len], bar[len]));
26
26
  }
27
27
  return len === -1;
28
28
  }
@@ -52,7 +52,7 @@ export function dequal(foo: any, bar: any) {
52
52
  tmp = find(bar, tmp);
53
53
  if (!tmp) return false;
54
54
  }
55
- if (!dequal(len[1], bar.get(tmp))) {
55
+ if (!deepEqual(len[1], bar.get(tmp))) {
56
56
  return false;
57
57
  }
58
58
  }
@@ -95,11 +95,12 @@ export function dequal(foo: any, bar: any) {
95
95
  }
96
96
 
97
97
  if (has.call(foo, ctor) && ++len && !has.call(bar, ctor)) return false;
98
- if (!(ctor in bar) || !dequal(foo[ctor], bar[ctor])) return false;
98
+ if (!(ctor in bar) || !deepEqual(foo[ctor], bar[ctor])) return false;
99
99
  }
100
100
  return Object.keys(bar).length === len;
101
101
  }
102
102
  }
103
103
 
104
+ // eslint-disable-next-line no-self-compare
104
105
  return foo !== foo && bar !== bar;
105
106
  }
@@ -0,0 +1,23 @@
1
+ import test from 'ava';
2
+ import { classOf } from './classOf';
3
+
4
+ test('classOf', (t) => {
5
+ for (const [k, v] of [
6
+ [0, 'Number'],
7
+ ['', 'String'],
8
+ [true, 'Boolean'],
9
+ [null, 'Null'],
10
+ [undefined, 'Undefined'],
11
+ [{}, 'Object'],
12
+ [[], 'Array'],
13
+ [new ArrayBuffer(0), 'ArrayBuffer'],
14
+ [new Map(), 'Map'],
15
+ [new Set(), 'Set'],
16
+ [new Date(), 'Date'],
17
+ [new RegExp(''), 'RegExp'],
18
+ [new DataView(new ArrayBuffer(0)), 'DataView'],
19
+ [new Int8Array(0), 'Int8Array'],
20
+ ]) {
21
+ t.is(classOf(k), v as any);
22
+ }
23
+ });
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * @see {@link https://github.com/pmndrs/zustand/blob/main/src/shallow.ts zustand/src/shallow.ts}
5
5
  */
6
- export function shallow<T, U>(objA: T, objB: U) {
6
+ export function shallowEqual<T, U>(objA: T, objB: U) {
7
7
  if (Object.is(objA, objB)) {
8
8
  return true;
9
9
  }
@@ -16,7 +16,7 @@ export function shallow<T, U>(objA: T, objB: U) {
16
16
  }
17
17
  for (let i = 0; i < keysA.length; i++) {
18
18
  if (
19
- !Object.prototype.hasOwnProperty.call(objB, keysA[i] as string) ||
19
+ !Object.prototype.hasOwnProperty.call(objB, keysA[i]) ||
20
20
  !Object.is(objA[keysA[i] as keyof T], objB[keysA[i] as keyof U])
21
21
  ) {
22
22
  return false;
@@ -1,3 +1,6 @@
1
+ /**
2
+ * Logger interface satisfies the `console`, `pino` logger interface.
3
+ */
1
4
  export interface Logger {
2
5
  trace(...data: any[]): void;
3
6
 
@@ -9,6 +12,9 @@ export interface Logger {
9
12
 
10
13
  error(...data: any[]): void;
11
14
 
15
+ /**
16
+ * create child logger with given context
17
+ */
12
18
  child?: (o: object) => Logger;
13
19
  }
14
20
 
@@ -1,7 +1,7 @@
1
1
  import { LoggerWithChild } from './Logger';
2
2
 
3
3
  export function createNoopLogger(): LoggerWithChild {
4
- const noop = (..._: any[]) => void 0;
4
+ const noop = (..._: any[]) => undefined;
5
5
  return {
6
6
  trace: noop,
7
7
  debug: noop,
@@ -4,9 +4,9 @@ import { createWriteLogger } from './createWriteLogger';
4
4
 
5
5
  test('logger', (t) => {
6
6
  {
7
- let logs: any[] = [];
7
+ const logs: any[] = [];
8
8
  const base = createWriteLogger((o) => logs.push(o));
9
- let l = createChildLogger(base, { c: 'test' });
9
+ const l = createChildLogger(base, { c: 'test' });
10
10
  l.info('hello');
11
11
  t.deepEqual(logs.shift(), { level: 'info', values: ['hello'], c: 'test' });
12
12
  l.child({ m: 1 }).trace('trace');
@@ -15,7 +15,7 @@ test('logger', (t) => {
15
15
  createChildLogger(console, { c: 'test' }).info('hello');
16
16
  {
17
17
  let pass = 0;
18
- let l = createWriteLogger(
18
+ const l = createWriteLogger(
19
19
  (o) => {
20
20
  pass++;
21
21
  t.log(`${o.level}: [${[o.m, o.c].filter(Boolean).join('.') || 'default'}]`, ...o.values);
@@ -1,3 +1,6 @@
1
+ /**
2
+ * Check is ESM Module
3
+ */
1
4
  export function isModule(o: any): o is Module {
2
5
  return o && o[Symbol.toStringTag] === 'Module';
3
6
  }
@@ -10,6 +10,7 @@ test('parseModuleId', (t) => {
10
10
  scoped: true,
11
11
  org: 'wener',
12
12
  pkg: 'reaction',
13
+ versioned: false,
13
14
  },
14
15
  reaction: {
15
16
  id: `reaction@latest`,
@@ -17,6 +18,7 @@ test('parseModuleId', (t) => {
17
18
  range: 'latest',
18
19
  pkg: 'reaction',
19
20
  scoped: false,
21
+ versioned: false,
20
22
  },
21
23
  'reaction@1': {
22
24
  id: `reaction@1`,
@@ -24,6 +26,7 @@ test('parseModuleId', (t) => {
24
26
  range: '1',
25
27
  pkg: 'reaction',
26
28
  scoped: false,
29
+ versioned: true,
27
30
  },
28
31
  'reaction@1.1.1': {
29
32
  id: `reaction@1.1.1`,
@@ -32,6 +35,7 @@ test('parseModuleId', (t) => {
32
35
  range: '1.1.1',
33
36
  pkg: 'reaction',
34
37
  scoped: false,
38
+ versioned: true,
35
39
  },
36
40
  'reaction@1.1.1-alpha': {
37
41
  id: `reaction@1.1.1-alpha`,
@@ -39,7 +43,7 @@ test('parseModuleId', (t) => {
39
43
  version: '1.1.1-alpha',
40
44
  range: '1.1.1-alpha',
41
45
  pkg: 'reaction',
42
-
46
+ versioned: true,
43
47
  scoped: false,
44
48
  },
45
49
  'reaction@1.1.1/index.js': {
@@ -49,7 +53,7 @@ test('parseModuleId', (t) => {
49
53
  range: '1.1.1',
50
54
  scoped: false,
51
55
  pkg: 'reaction',
52
-
56
+ versioned: true,
53
57
  path: '/index.js',
54
58
  },
55
59
  'reaction@1.1.1/': {
@@ -60,6 +64,7 @@ test('parseModuleId', (t) => {
60
64
  scoped: false,
61
65
  pkg: 'reaction',
62
66
  path: '/',
67
+ versioned: true,
63
68
  },
64
69
  };
65
70
  for (const [k, v] of Object.entries(tests)) {
@@ -9,18 +9,22 @@ export type ParsedModuleId = {
9
9
  range: string; // version, tag, range
10
10
  pkg: string;
11
11
  path?: string;
12
+ org?: string;
13
+ versioned: boolean; // is module id contain a version specifier
12
14
  } & (
13
15
  | { scoped: false }
14
16
  | {
15
17
  scoped: true;
16
- org?: string;
18
+ org: string;
17
19
  }
18
20
  );
19
21
 
20
22
  /**
21
23
  * Parse NPM module id
22
24
  *
23
- * parseModuleId('@wener/reaction@latest/index.js') // => { id: '@wener/reaction@latest', name: '@wener/reaction', version: 'latest', range: 'latest', pkg: 'reaction', path: '/index.js', scoped: true, org: 'wener' }
25
+ * @example
26
+ * parseModuleId('@wener/reaction@latest/index.js')
27
+ * // { id: '@wener/reaction@latest', name: '@wener/reaction', version: 'latest', range: 'latest', pkg: 'reaction', path: '/index.js', scoped: true, org: 'wener' }
24
28
  */
25
29
  export function parseModuleId(s: string): ParsedModuleId | undefined {
26
30
  const groups = s.match(regModuleId)?.groups;
@@ -28,24 +32,26 @@ export function parseModuleId(s: string): ParsedModuleId | undefined {
28
32
  return undefined;
29
33
  }
30
34
  const { n: name, v: version, p: path, org, pkg } = groups;
31
- let scoped = Boolean(org);
35
+ const scoped = Boolean(org);
32
36
  const v = /^\d+\.\d+\.\d+/.test(version) ? version : undefined;
33
- let range = version || 'latest';
34
- const o = {
37
+ const range = version || 'latest';
38
+ const o: ParsedModuleId = {
35
39
  id: `${name}@${range}`,
36
40
  name,
37
- range: range,
41
+ range,
38
42
  scoped,
39
43
  pkg,
40
- } as ParsedModuleId;
44
+ org,
45
+ versioned: Boolean(version),
46
+ };
41
47
  if (v) {
42
48
  o.version = v;
43
49
  }
44
50
  if (path) {
45
51
  o.path = path;
46
52
  }
47
- if (o.scoped) {
48
- o.org = org;
53
+ if (!o.scoped) {
54
+ delete o.org;
49
55
  }
50
56
  return o;
51
57
  }
@@ -0,0 +1,51 @@
1
+ import { expectType } from 'tsd';
2
+ import { get } from './get';
3
+
4
+ interface TestClass {
5
+ normal: string;
6
+ nested: {
7
+ a: number;
8
+ b: {
9
+ c: boolean;
10
+ };
11
+ };
12
+ arr: number[];
13
+ nestedArr: {
14
+ sum: number;
15
+ other: null;
16
+ }[];
17
+ deep: {
18
+ arr: string[];
19
+ };
20
+ deeplvl1: {
21
+ deeplvl2: {
22
+ deeplvl3: {
23
+ deeplvl4: {
24
+ value: RegExp;
25
+ };
26
+ }[];
27
+ };
28
+ }[];
29
+ }
30
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
31
+ const obj = {} as TestClass;
32
+
33
+ expectType<number>(get(obj, 'nested.a', null));
34
+ expectType<string>(get(obj, 'normal', null));
35
+ expectType<number>(get(obj, 'nested.a'));
36
+ expectType<boolean>(get(obj, 'nested.b.c'));
37
+ expectType<number[]>(get(obj, 'arr'));
38
+ expectType<number>(get(obj, 'arr[13]'));
39
+ expectType<number>(get(obj, 'arr.13'));
40
+ expectType<null>(get(obj, 'nestedArr[3].other'));
41
+ expectType<string[]>(get(obj, 'deep.deep'));
42
+ expectType<string>(get(obj, 'deep.arr[333]'));
43
+ expectType<number>(get(obj, 'deep.arr[333].length'));
44
+ expectType<boolean>(get(obj, 'nested["b"]["c"]'));
45
+ expectType<never>(get(obj, ''));
46
+ expectType<number>(get(obj, '', 3));
47
+ expectType<never>(get(obj, 'nested.asdfasdf'));
48
+ expectType<RegExp>(get(obj, 'deeplvl1[1].deeplvl2.deeplvl3[88].deeplvl4.value'));
49
+ expectType<never>(get(obj, 'deeplvl1[1].deeplvl2.deeplvl1[88].deeplvl4.value'));
50
+ expectType<TestClass>(get(obj, 'deeplvl1[1].deeplvl2.deeplvl1[88].deeplvl4.value', obj));
51
+ expectType<string>(get(obj, 'nested["dd"]', ''));
@@ -1,62 +1,9 @@
1
1
  import test from 'ava';
2
- import { expectType } from 'tsd';
3
2
  import { get } from './get';
4
3
  import { parseObjectPath } from './parseObjectPath';
5
4
 
6
- test('get typed', (t) => {
7
- interface TestClass {
8
- normal: string;
9
- nested: {
10
- a: number;
11
- b: {
12
- c: boolean;
13
- };
14
- };
15
- arr: number[];
16
- nestedArr: {
17
- sum: number;
18
- other: null;
19
- }[];
20
- deep: {
21
- arr: string[];
22
- };
23
- deeplvl1: {
24
- deeplvl2: {
25
- deeplvl3: {
26
- deeplvl4: {
27
- value: RegExp;
28
- };
29
- }[];
30
- };
31
- }[];
32
- }
33
-
34
- const obj = {} as TestClass;
35
-
36
- expectType<number>(get(obj, 'nested.a', null));
37
- expectType<string>(get(obj, 'normal', null));
38
- expectType<number>(get(obj, 'nested.a'));
39
- expectType<boolean>(get(obj, 'nested.b.c'));
40
- expectType<number[]>(get(obj, 'arr'));
41
- expectType<number>(get(obj, 'arr[13]'));
42
- expectType<number>(get(obj, 'arr.13'));
43
- expectType<null>(get(obj, 'nestedArr[3].other'));
44
- expectType<string[]>(get(obj, 'deep.deep'));
45
- expectType<string>(get(obj, 'deep.arr[333]'));
46
- expectType<number>(get(obj, 'deep.arr[333].length'));
47
- expectType<boolean>(get(obj, 'nested["b"]["c"]'));
48
- expectType<never>(get(obj, ''));
49
- expectType<number>(get(obj, '', 3));
50
- expectType<never>(get(obj, 'nested.asdfasdf'));
51
- expectType<RegExp>(get(obj, 'deeplvl1[1].deeplvl2.deeplvl3[88].deeplvl4.value'));
52
- expectType<never>(get(obj, 'deeplvl1[1].deeplvl2.deeplvl1[88].deeplvl4.value'));
53
- expectType<TestClass>(get(obj, 'deeplvl1[1].deeplvl2.deeplvl1[88].deeplvl4.value', obj));
54
- expectType<string>(get(obj, 'nested["dd"]', ''));
55
- t.pass();
56
- });
57
-
58
5
  test('get', (t) => {
59
- let obj = {
6
+ const obj = {
60
7
  undef: undefined,
61
8
  zero: 0,
62
9
  one: 1,
@@ -76,7 +23,7 @@ test('get', (t) => {
76
23
 
77
24
  function check(path: string, value: any, def?: any) {
78
25
  const out = get(obj, path, def);
79
- t.is(out, value, 'get(obj, "' + path + '") should be ' + value + ', got ' + out);
26
+ t.is(out, value, `get(obj, "${path}") should be ${value}, got ${out}`);
80
27
  if (path) {
81
28
  const arr = parseObjectPath(path);
82
29
  t.is(get(obj, arr, def), value, `get(obj,${JSON.stringify(arr)}, ${def})`);
@@ -5,9 +5,10 @@ export type ObjectPathLike = ObjectKey | ObjectPath;
5
5
  /**
6
6
  * Parse object path
7
7
  *
8
- * parseObjectPath('a.b.c') // => ['a', 'b', 'c']
9
- * parseObjectPath('a[0].b') // => ['a', 0, 'b']
10
- * parseObjectPath('a[0][1]') // => ['a', 0, 1]
8
+ * @example
9
+ * parseObjectPath('a.b.c') // => ['a', 'b', 'c']
10
+ * parseObjectPath('a[0].b') // => ['a', 0, 'b']
11
+ * parseObjectPath('a[0][1]') // => ['a', 0, 1]
11
12
  *
12
13
  */
13
14
  export function parseObjectPath(s: ObjectPathLike): ObjectPath {