utilitish 0.0.18 → 0.0.20

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.
@@ -1,11 +1,9 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const core_utils_1 = require("../utils/core.utils");
4
- const slugify_config_1 = require("../utils/slugify.config");
1
+ import { defineIfNotExists, utilitishError } from '../utils/core.utils';
2
+ import { slugifyString } from '../utils/slugify.config';
5
3
  /**
6
4
  * @see String.prototype.splitWords
7
5
  */
8
- (0, core_utils_1.defineIfNotExists)(String.prototype, 'splitWords', function () {
6
+ defineIfNotExists(String.prototype, 'splitWords', function () {
9
7
  return this.replace(/([a-z0-9])([A-Z])/g, '$1 $2') // helloWorld → hello World
10
8
  .replace(/([A-Z])([A-Z][a-z])/g, '$1 $2') // HTMLParser → HTML Parser
11
9
  .replace(/[^\p{L}\p{N}]+/gu, ' ')
@@ -16,7 +14,7 @@ const slugify_config_1 = require("../utils/slugify.config");
16
14
  /**
17
15
  * @see String.prototype.camelCase
18
16
  */
19
- (0, core_utils_1.defineIfNotExists)(String.prototype, 'camelCase', function () {
17
+ defineIfNotExists(String.prototype, 'camelCase', function () {
20
18
  const words = this.splitWords().map((w) => w.toLowerCase());
21
19
  return words
22
20
  .map((word, i) => (i === 0 ? word : word.charAt(0).toUpperCase() + word.slice(1)))
@@ -25,7 +23,7 @@ const slugify_config_1 = require("../utils/slugify.config");
25
23
  /**
26
24
  * @see String.prototype.kebabCase
27
25
  */
28
- (0, core_utils_1.defineIfNotExists)(String.prototype, 'kebabCase', function () {
26
+ defineIfNotExists(String.prototype, 'kebabCase', function () {
29
27
  return this.splitWords()
30
28
  .map((w) => w.toLowerCase())
31
29
  .join('-');
@@ -33,7 +31,7 @@ const slugify_config_1 = require("../utils/slugify.config");
33
31
  /**
34
32
  * @see String.prototype.snakeCase
35
33
  */
36
- (0, core_utils_1.defineIfNotExists)(String.prototype, 'snakeCase', function () {
34
+ defineIfNotExists(String.prototype, 'snakeCase', function () {
37
35
  return this.splitWords()
38
36
  .map((w) => w.toLowerCase())
39
37
  .join('_');
@@ -41,7 +39,7 @@ const slugify_config_1 = require("../utils/slugify.config");
41
39
  /**
42
40
  * @see String.prototype.sentenceCase
43
41
  */
44
- (0, core_utils_1.defineIfNotExists)(String.prototype, 'sentenceCase', function () {
42
+ defineIfNotExists(String.prototype, 'sentenceCase', function () {
45
43
  return this.splitWords()
46
44
  .map((w) => w.toLowerCase())
47
45
  .join(' ');
@@ -49,7 +47,7 @@ const slugify_config_1 = require("../utils/slugify.config");
49
47
  /**
50
48
  * @see String.prototype.titleCase
51
49
  */
52
- (0, core_utils_1.defineIfNotExists)(String.prototype, 'titleCase', function () {
50
+ defineIfNotExists(String.prototype, 'titleCase', function () {
53
51
  return this.splitWords()
54
52
  .map((w) => w.toLowerCase().capitalize())
55
53
  .join(' ');
@@ -57,37 +55,37 @@ const slugify_config_1 = require("../utils/slugify.config");
57
55
  /**
58
56
  * @see String.prototype.truncate
59
57
  */
60
- (0, core_utils_1.defineIfNotExists)(String.prototype, 'truncate', function (n) {
58
+ defineIfNotExists(String.prototype, 'truncate', function (n) {
61
59
  if (typeof n !== 'number')
62
- (0, core_utils_1.utilitishError)('String.prototype.truncate', 'n must be a number', n);
60
+ utilitishError('String.prototype.truncate', 'n must be a number', n);
63
61
  if (!Number.isInteger(n))
64
- (0, core_utils_1.utilitishError)('String.prototype.truncate', 'n must be an integer', n);
62
+ utilitishError('String.prototype.truncate', 'n must be an integer', n);
65
63
  if (n < 0)
66
- (0, core_utils_1.utilitishError)('String.prototype.truncate', 'n must be non-negative', n);
64
+ utilitishError('String.prototype.truncate', 'n must be non-negative', n);
67
65
  return this.length > n ? this.slice(0, n) + '...' : this.toString();
68
66
  });
69
67
  /**
70
68
  * @see String.prototype.reverse
71
69
  */
72
- (0, core_utils_1.defineIfNotExists)(String.prototype, 'reverse', function () {
70
+ defineIfNotExists(String.prototype, 'reverse', function () {
73
71
  return [...this].reverse().join('');
74
72
  });
75
73
  /**
76
74
  * @see String.prototype.isEmpty
77
75
  */
78
- (0, core_utils_1.defineIfNotExists)(String.prototype, 'isEmpty', function () {
76
+ defineIfNotExists(String.prototype, 'isEmpty', function () {
79
77
  return this.trim().length === 0;
80
78
  });
81
79
  /**
82
80
  * @see String.prototype.slugify
83
81
  */
84
- (0, core_utils_1.defineIfNotExists)(String.prototype, 'slugify', function (config) {
85
- return (0, slugify_config_1.slugifyString)(this, config);
82
+ defineIfNotExists(String.prototype, 'slugify', function (config) {
83
+ return slugifyString(this, config);
86
84
  });
87
85
  /**
88
86
  * @see String.prototype.capitalize
89
87
  */
90
- (0, core_utils_1.defineIfNotExists)(String.prototype, 'capitalize', function () {
88
+ defineIfNotExists(String.prototype, 'capitalize', function () {
91
89
  if (this.length === 0)
92
90
  return '';
93
91
  return this.charAt(0).toUpperCase() + this.slice(1);
@@ -95,62 +93,62 @@ const slugify_config_1 = require("../utils/slugify.config");
95
93
  /**
96
94
  * @see String.prototype.slugifyEquals
97
95
  */
98
- (0, core_utils_1.defineIfNotExists)(String.prototype, 'slugifyEquals', function (other) {
96
+ defineIfNotExists(String.prototype, 'slugifyEquals', function (other) {
99
97
  if (typeof other !== 'string')
100
- (0, core_utils_1.utilitishError)('String.prototype.slugifyEquals', 'other must be a string', other);
98
+ utilitishError('String.prototype.slugifyEquals', 'other must be a string', other);
101
99
  return this.slugify() === other.slugify();
102
100
  });
103
101
  /**
104
102
  * @see String.prototype.slugifyIncludes
105
103
  */
106
- (0, core_utils_1.defineIfNotExists)(String.prototype, 'slugifyIncludes', function (other) {
104
+ defineIfNotExists(String.prototype, 'slugifyIncludes', function (other) {
107
105
  if (typeof other !== 'string')
108
- (0, core_utils_1.utilitishError)('String.prototype.slugifyIncludes', 'other must be a string', other);
106
+ utilitishError('String.prototype.slugifyIncludes', 'other must be a string', other);
109
107
  return this.slugify().includes(other.slugify());
110
108
  });
111
109
  /**
112
110
  * @see String.prototype.slugifyStartsWith
113
111
  */
114
- (0, core_utils_1.defineIfNotExists)(String.prototype, 'slugifyStartsWith', function (other) {
112
+ defineIfNotExists(String.prototype, 'slugifyStartsWith', function (other) {
115
113
  if (typeof other !== 'string')
116
- (0, core_utils_1.utilitishError)('String.prototype.slugifyStartsWith', 'other must be a string', other);
114
+ utilitishError('String.prototype.slugifyStartsWith', 'other must be a string', other);
117
115
  return this.slugify().startsWith(other.slugify());
118
116
  });
119
117
  /**
120
118
  * @see String.prototype.slugifyEndsWith
121
119
  */
122
- (0, core_utils_1.defineIfNotExists)(String.prototype, 'slugifyEndsWith', function (other) {
120
+ defineIfNotExists(String.prototype, 'slugifyEndsWith', function (other) {
123
121
  if (typeof other !== 'string')
124
- (0, core_utils_1.utilitishError)('String.prototype.slugifyEndsWith', 'other must be a string', other);
122
+ utilitishError('String.prototype.slugifyEndsWith', 'other must be a string', other);
125
123
  return this.slugify().endsWith(other.slugify());
126
124
  });
127
125
  /**
128
126
  * @see String.prototype.slugifyIn
129
127
  */
130
- (0, core_utils_1.defineIfNotExists)(String.prototype, 'slugifyIn', function (list) {
128
+ defineIfNotExists(String.prototype, 'slugifyIn', function (list) {
131
129
  if (!Array.isArray(list))
132
- (0, core_utils_1.utilitishError)('String.prototype.slugifyIn', 'list must be an array', list);
130
+ utilitishError('String.prototype.slugifyIn', 'list must be an array', list);
133
131
  if (!list.every((item) => typeof item === 'string'))
134
- (0, core_utils_1.utilitishError)('String.prototype.slugifyIn', 'list must be an array of strings', list);
132
+ utilitishError('String.prototype.slugifyIn', 'list must be an array of strings', list);
135
133
  const slugified = this.slugify();
136
134
  return list.some((item) => item.slugify() === slugified);
137
135
  });
138
136
  /**
139
137
  * @see String.prototype.replaceRange
140
138
  */
141
- (0, core_utils_1.defineIfNotExists)(String.prototype, 'replaceRange', function (start, end, replaceString = '') {
139
+ defineIfNotExists(String.prototype, 'replaceRange', function (start, end, replaceString = '') {
142
140
  if (!Number.isInteger(start))
143
- (0, core_utils_1.utilitishError)('String.prototype.replaceRange', 'start must be an integer', start);
141
+ utilitishError('String.prototype.replaceRange', 'start must be an integer', start);
144
142
  if (!Number.isInteger(end))
145
- (0, core_utils_1.utilitishError)('String.prototype.replaceRange', 'end must be an integer', end);
143
+ utilitishError('String.prototype.replaceRange', 'end must be an integer', end);
146
144
  if (start < 0)
147
- (0, core_utils_1.utilitishError)('String.prototype.replaceRange', 'start cannot be negative', start, RangeError);
145
+ utilitishError('String.prototype.replaceRange', 'start cannot be negative', start, RangeError);
148
146
  if (end < 0)
149
- (0, core_utils_1.utilitishError)('String.prototype.replaceRange', 'end cannot be negative', end, RangeError);
147
+ utilitishError('String.prototype.replaceRange', 'end cannot be negative', end, RangeError);
150
148
  if (start > this.length)
151
- (0, core_utils_1.utilitishError)('String.prototype.replaceRange', 'start is out of bounds', start, RangeError);
149
+ utilitishError('String.prototype.replaceRange', 'start is out of bounds', start, RangeError);
152
150
  if (end > this.length)
153
- (0, core_utils_1.utilitishError)('String.prototype.replaceRange', 'end is out of bounds', end, RangeError);
151
+ utilitishError('String.prototype.replaceRange', 'end is out of bounds', end, RangeError);
154
152
  if (start > end)
155
153
  [start, end] = [end, start];
156
154
  return this.slice(0, start) + (replaceString ?? '') + this.slice(end);
@@ -1,7 +1,5 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- require("../string/string-prototype");
4
- const slugify_config_1 = require("../utils/slugify.config");
1
+ import '../string/string-prototype';
2
+ import { resetSlugifyConfig, setSlugifyConfig, SlugifyConfig } from '../utils/slugify.config';
5
3
  describe('String.prototype', () => {
6
4
  describe('capitalize()', () => {
7
5
  it('should capitalize the first character', () => {
@@ -94,7 +92,7 @@ describe('String.prototype', () => {
94
92
  });
95
93
  describe('slugify()', () => {
96
94
  beforeEach(() => {
97
- (0, slugify_config_1.resetSlugifyConfig)(); // Reset to defaults before each test
95
+ resetSlugifyConfig(); // Reset to defaults before each test
98
96
  });
99
97
  it('should slugify a string with default config', () => {
100
98
  expect('Hello World!'.slugify()).toBe('hello-world');
@@ -103,73 +101,73 @@ describe('String.prototype', () => {
103
101
  });
104
102
  describe('custom replacements', () => {
105
103
  it('should apply custom replacements per call', () => {
106
- expect('Test ♀'.slugify(slugify_config_1.SlugifyConfig.builder().withCustomReplacements({ '♀': 'feminin' }).build())).toBe('test-feminin');
107
- expect('User♂@domain.com'.slugify(slugify_config_1.SlugifyConfig.builder().withCustomReplacements({ '♂': 'masculin', '@': 'at' }).build())).toBe('usermasculinatdomain-com');
104
+ expect('Test ♀'.slugify(SlugifyConfig.builder().withCustomReplacements({ '♀': 'feminin' }).build())).toBe('test-feminin');
105
+ expect('User♂@domain.com'.slugify(SlugifyConfig.builder().withCustomReplacements({ '♂': 'masculin', '@': 'at' }).build())).toBe('usermasculinatdomain-com');
108
106
  });
109
107
  it('should handle special regex characters in replacements', () => {
110
- expect('Test [bracket]'.slugify(slugify_config_1.SlugifyConfig.builder().withCustomReplacements({ '[': 'left', ']': 'right' }).build())).toBe('test-leftbracketright');
108
+ expect('Test [bracket]'.slugify(SlugifyConfig.builder().withCustomReplacements({ '[': 'left', ']': 'right' }).build())).toBe('test-leftbracketright');
111
109
  });
112
110
  });
113
111
  describe('separator customization', () => {
114
112
  it('should use custom separator globally', () => {
115
- (0, slugify_config_1.setSlugifyConfig)(slugify_config_1.SlugifyConfig.builder().withSeparator('_').build());
113
+ setSlugifyConfig(SlugifyConfig.builder().withSeparator('_').build());
116
114
  expect('Hello World'.slugify()).toBe('hello_world');
117
115
  expect('Test String'.slugify()).toBe('test_string');
118
116
  });
119
117
  it('should use custom separator per call', () => {
120
- expect('Hello World'.slugify(slugify_config_1.SlugifyConfig.builder().withSeparator('_').build())).toBe('hello_world');
121
- expect('Test String'.slugify(slugify_config_1.SlugifyConfig.builder().withSeparator('__').build())).toBe('test__string');
118
+ expect('Hello World'.slugify(SlugifyConfig.builder().withSeparator('_').build())).toBe('hello_world');
119
+ expect('Test String'.slugify(SlugifyConfig.builder().withSeparator('__').build())).toBe('test__string');
122
120
  });
123
121
  });
124
122
  describe('case transformation', () => {
125
123
  it('should respect lowercase setting globally', () => {
126
- (0, slugify_config_1.setSlugifyConfig)(slugify_config_1.SlugifyConfig.builder().withCase('default').build());
124
+ setSlugifyConfig(SlugifyConfig.builder().withCase('default').build());
127
125
  expect('Hello World'.slugify()).toBe('Hello-World');
128
126
  });
129
127
  it('should respect lowercase setting per call', () => {
130
- expect('Hello World'.slugify(slugify_config_1.SlugifyConfig.builder().withCase('default').build())).toBe('Hello-World');
128
+ expect('Hello World'.slugify(SlugifyConfig.builder().withCase('default').build())).toBe('Hello-World');
131
129
  });
132
130
  });
133
131
  describe('accent removal', () => {
134
132
  it('should respect removeAccents setting per call', () => {
135
- expect('Éléphant'.slugify(slugify_config_1.SlugifyConfig.builder().withRemoveAccents(false).build())).toBe('éléphant');
133
+ expect('Éléphant'.slugify(SlugifyConfig.builder().withRemoveAccents(false).build())).toBe('éléphant');
136
134
  });
137
135
  });
138
136
  describe('allowed characters', () => {
139
137
  it('should use custom allowed characters', () => {
140
- expect('Hello123!@#'.slugify(slugify_config_1.SlugifyConfig.builder()
138
+ expect('Hello123!@#'.slugify(SlugifyConfig.builder()
141
139
  .withAllowedChars(/[a-zA-Z0-9_]/)
142
140
  .build())).toBe('hello123');
143
141
  });
144
142
  it('should throw for invalid allowedChars regex in call', () => {
145
- expect(() => slugify_config_1.SlugifyConfig.builder()
143
+ expect(() => SlugifyConfig.builder()
146
144
  .withAllowedChars(/foo|bar/)
147
145
  .build()).toThrowError(/Invalid allowedChars:/);
148
146
  });
149
147
  it('should throw for invalid allowedChars regex in global config', () => {
150
- expect(() => (0, slugify_config_1.setSlugifyConfig)(slugify_config_1.SlugifyConfig.builder()
148
+ expect(() => setSlugifyConfig(SlugifyConfig.builder()
151
149
  .withAllowedChars(/foo|bar/)
152
150
  .build())).toThrowError(/Invalid allowedChars:/);
153
151
  });
154
152
  });
155
153
  describe('separator special characters', () => {
156
154
  it('should handle regex-special separators without breaking', () => {
157
- expect('a b+c'.slugify(slugify_config_1.SlugifyConfig.builder().withSeparator('.').build())).toBe('a.b.c');
158
- expect('a.b.c'.slugify(slugify_config_1.SlugifyConfig.builder().withSeparator('*').build())).toBe('a*b*c');
155
+ expect('a b+c'.slugify(SlugifyConfig.builder().withSeparator('.').build())).toBe('a.b.c');
156
+ expect('a.b.c'.slugify(SlugifyConfig.builder().withSeparator('*').build())).toBe('a*b*c');
159
157
  });
160
158
  });
161
159
  describe('max length', () => {
162
160
  it('should truncate to max length', () => {
163
- expect('very-long-string-here'.slugify(slugify_config_1.SlugifyConfig.builder().withMaxLength(10).build())).toBe('very-long');
164
- expect('short'.slugify(slugify_config_1.SlugifyConfig.builder().withMaxLength(10).build())).toBe('short');
161
+ expect('very-long-string-here'.slugify(SlugifyConfig.builder().withMaxLength(10).build())).toBe('very-long');
162
+ expect('short'.slugify(SlugifyConfig.builder().withMaxLength(10).build())).toBe('short');
165
163
  });
166
164
  it('should remove trailing separator after truncation', () => {
167
- expect('hello-world-test'.slugify(slugify_config_1.SlugifyConfig.builder().withMaxLength(8).build())).toBe('hello-wo');
165
+ expect('hello-world-test'.slugify(SlugifyConfig.builder().withMaxLength(8).build())).toBe('hello-wo');
168
166
  });
169
167
  });
170
168
  describe('custom transformers', () => {
171
169
  it('should apply custom transformers', () => {
172
- const config = slugify_config_1.SlugifyConfig.builder()
170
+ const config = SlugifyConfig.builder()
173
171
  .withTransformers([
174
172
  (str) => str.replace(/test/g, 'example'),
175
173
  (str) => str.toUpperCase(),
@@ -182,13 +180,13 @@ describe('String.prototype', () => {
182
180
  describe('configuration merging', () => {
183
181
  it('should merge global and local config correctly', () => {
184
182
  // Local config should override global defaults
185
- expect('Test ♀'.slugify(slugify_config_1.SlugifyConfig.builder().withSeparator('_').withCustomReplacements({ '♀': 'female' }).build())).toBe('test_female');
183
+ expect('Test ♀'.slugify(SlugifyConfig.builder().withSeparator('_').withCustomReplacements({ '♀': 'female' }).build())).toBe('test_female');
186
184
  });
187
185
  });
188
186
  });
189
187
  describe('slugifyEquals()', () => {
190
188
  beforeEach(() => {
191
- (0, slugify_config_1.resetSlugifyConfig)(); // Reset to defaults before each test
189
+ resetSlugifyConfig(); // Reset to defaults before each test
192
190
  });
193
191
  it('should return true when slugified strings are equal', () => {
194
192
  expect('Hello World'.slugifyEquals('hello-world')).toBe(true);
@@ -1,9 +1,3 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.utilitishError = exports.defineStaticIfNotExists = exports.defineIfNotExists = void 0;
4
- exports.resolveSelector = resolveSelector;
5
- exports.assertValidSelector = assertValidSelector;
6
- exports.isNumberOrString = isNumberOrString;
7
1
  /**
8
2
  * Defines a **non-enumerable, non-writable, non-configurable** property on a prototype
9
3
  * if it does not already exist, or if the existing property is writable or configurable.
@@ -25,7 +19,7 @@ exports.isNumberOrString = isNumberOrString;
25
19
  * @remarks
26
20
  * Use this function to safely add prototype methods without overwriting stable or built-in ones.
27
21
  */
28
- const defineIfNotExists = (prototype, name, fn) => {
22
+ export const defineIfNotExists = (prototype, name, fn) => {
29
23
  const descriptor = Object.getOwnPropertyDescriptor(prototype, name);
30
24
  if (!descriptor || descriptor.writable || descriptor.configurable) {
31
25
  Object.defineProperty(prototype, name, {
@@ -36,7 +30,6 @@ const defineIfNotExists = (prototype, name, fn) => {
36
30
  });
37
31
  }
38
32
  };
39
- exports.defineIfNotExists = defineIfNotExists;
40
33
  /**
41
34
  * Defines a **static** property on a constructor if it does not already exist,
42
35
  * or if the existing property is writable or configurable.
@@ -58,7 +51,7 @@ exports.defineIfNotExists = defineIfNotExists;
58
51
  * @remarks
59
52
  * To forcefully replace an existing property, delete it first or use `Object.defineProperty` directly.
60
53
  */
61
- const defineStaticIfNotExists = (constructor, name, fn) => {
54
+ export const defineStaticIfNotExists = (constructor, name, fn) => {
62
55
  const descriptor = Object.getOwnPropertyDescriptor(constructor, name);
63
56
  if (!descriptor || descriptor.writable || descriptor.configurable) {
64
57
  Object.defineProperty(constructor, name, {
@@ -69,7 +62,6 @@ const defineStaticIfNotExists = (constructor, name, fn) => {
69
62
  });
70
63
  }
71
64
  };
72
- exports.defineStaticIfNotExists = defineStaticIfNotExists;
73
65
  /**
74
66
  * Resolves a selector parameter into a function that extracts a value from an item.
75
67
  *
@@ -98,7 +90,7 @@ exports.defineStaticIfNotExists = defineStaticIfNotExists;
98
90
  * @throws {TypeError} If the selector is not a function or string key.
99
91
  * @throws {TypeError} If no selector is provided and no fallback is given.
100
92
  */
101
- function resolveSelector(selector, fallback, name = 'selector') {
93
+ export function resolveSelector(selector, fallback, name = 'selector') {
102
94
  assertValidSelector(selector);
103
95
  if (typeof selector === 'function') {
104
96
  return selector;
@@ -134,7 +126,7 @@ function resolveSelector(selector, fallback, name = 'selector') {
134
126
  * @remarks
135
127
  * Used internally by `resolveSelector` to provide clearer type safety and errors.
136
128
  */
137
- function assertValidSelector(selector, name = 'selector') {
129
+ export function assertValidSelector(selector, name = 'selector') {
138
130
  const isValid = typeof selector === 'function' || typeof selector === 'string';
139
131
  if (selector !== undefined && !isValid) {
140
132
  throw new TypeError(`${name} must be a function or a string key`);
@@ -151,11 +143,10 @@ function assertValidSelector(selector, name = 'selector') {
151
143
  * @param {unknown} value The value to test.
152
144
  * @returns {value is string | number} True if the value is a string or number, else false.
153
145
  */
154
- function isNumberOrString(value) {
146
+ export function isNumberOrString(value) {
155
147
  return typeof value === 'string' || typeof value === 'number';
156
148
  }
157
- const utilitishError = (method, message, received, ErrorClass = TypeError) => {
149
+ export const utilitishError = (method, message, received, ErrorClass = TypeError) => {
158
150
  const receivedInfo = received !== undefined ? `, received ${ErrorClass === RangeError ? received : typeof received}` : '';
159
151
  throw new ErrorClass(`[Utilitish] ${method}: ${message}${receivedInfo}`);
160
152
  };
161
- exports.utilitishError = utilitishError;
@@ -1,11 +1,9 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const core_utils_1 = require("./core.utils");
1
+ import { assertValidSelector, defineIfNotExists, defineStaticIfNotExists, isNumberOrString, resolveSelector, utilitishError, } from './core.utils';
4
2
  describe('core.utils', () => {
5
3
  describe('defineIfNotExists()', () => {
6
4
  it('should define a new method on a prototype', () => {
7
5
  const proto = {};
8
- (0, core_utils_1.defineIfNotExists)(proto, 'hello', () => 'world');
6
+ defineIfNotExists(proto, 'hello', () => 'world');
9
7
  expect(proto.hello()).toBe('world');
10
8
  });
11
9
  it('should not overwrite a non-configurable non-writable property', () => {
@@ -15,7 +13,7 @@ describe('core.utils', () => {
15
13
  writable: false,
16
14
  configurable: false,
17
15
  });
18
- (0, core_utils_1.defineIfNotExists)(proto, 'locked', () => 'overwritten');
16
+ defineIfNotExists(proto, 'locked', () => 'overwritten');
19
17
  expect(proto.locked()).toBe('original');
20
18
  });
21
19
  it('should overwrite a writable property', () => {
@@ -25,7 +23,7 @@ describe('core.utils', () => {
25
23
  writable: true,
26
24
  configurable: false,
27
25
  });
28
- (0, core_utils_1.defineIfNotExists)(proto, 'flexible', () => 'overwritten');
26
+ defineIfNotExists(proto, 'flexible', () => 'overwritten');
29
27
  expect(proto.flexible()).toBe('overwritten');
30
28
  });
31
29
  it('should overwrite a configurable property', () => {
@@ -35,19 +33,19 @@ describe('core.utils', () => {
35
33
  writable: false,
36
34
  configurable: true,
37
35
  });
38
- (0, core_utils_1.defineIfNotExists)(proto, 'flexible', () => 'overwritten');
36
+ defineIfNotExists(proto, 'flexible', () => 'overwritten');
39
37
  expect(proto.flexible()).toBe('overwritten');
40
38
  });
41
39
  it('should define the property as non-enumerable', () => {
42
40
  const proto = {};
43
- (0, core_utils_1.defineIfNotExists)(proto, 'hidden', () => 'value');
41
+ defineIfNotExists(proto, 'hidden', () => 'value');
44
42
  expect(Object.keys(proto)).not.toContain('hidden');
45
43
  });
46
44
  });
47
45
  describe('defineStaticIfNotExists()', () => {
48
46
  it('should define a new static method on a constructor', () => {
49
47
  const ctor = {};
50
- (0, core_utils_1.defineStaticIfNotExists)(ctor, 'create', () => 'created');
48
+ defineStaticIfNotExists(ctor, 'create', () => 'created');
51
49
  expect(ctor.create()).toBe('created');
52
50
  });
53
51
  it('should not overwrite a non-configurable non-writable static property', () => {
@@ -57,94 +55,94 @@ describe('core.utils', () => {
57
55
  writable: false,
58
56
  configurable: false,
59
57
  });
60
- (0, core_utils_1.defineStaticIfNotExists)(ctor, 'locked', () => 'overwritten');
58
+ defineStaticIfNotExists(ctor, 'locked', () => 'overwritten');
61
59
  expect(ctor.locked()).toBe('original');
62
60
  });
63
61
  it('should define the property as non-enumerable', () => {
64
62
  const ctor = {};
65
- (0, core_utils_1.defineStaticIfNotExists)(ctor, 'hidden', () => 'value');
63
+ defineStaticIfNotExists(ctor, 'hidden', () => 'value');
66
64
  expect(Object.keys(ctor)).not.toContain('hidden');
67
65
  });
68
66
  });
69
67
  describe('resolveSelector()', () => {
70
68
  describe('with function selector', () => {
71
69
  it('should return a function that applies the selector', () => {
72
- const sel = (0, core_utils_1.resolveSelector)((item) => item.x);
70
+ const sel = resolveSelector((item) => item.x);
73
71
  expect(sel({ x: 42 })).toBe(42);
74
72
  });
75
73
  });
76
74
  describe('with string key selector', () => {
77
75
  it('should return a function that extracts the property', () => {
78
- const sel = (0, core_utils_1.resolveSelector)('name');
76
+ const sel = resolveSelector('name');
79
77
  expect(sel({ name: 'Alice' })).toBe('Alice');
80
78
  });
81
79
  });
82
80
  describe('with fallback', () => {
83
81
  it('should return the fallback function when no selector is provided', () => {
84
- const sel = (0, core_utils_1.resolveSelector)(undefined, (item) => item.toString());
82
+ const sel = resolveSelector(undefined, (item) => item.toString());
85
83
  expect(sel(42)).toBe('42');
86
84
  });
87
85
  });
88
86
  describe('error handling', () => {
89
87
  it('should throw TypeError when selector is invalid', () => {
90
- expect(() => (0, core_utils_1.resolveSelector)(123)).toThrow(TypeError);
88
+ expect(() => resolveSelector(123)).toThrow(TypeError);
91
89
  });
92
90
  it('should throw TypeError when no selector and no fallback', () => {
93
- expect(() => (0, core_utils_1.resolveSelector)(undefined, undefined)).toThrow(TypeError);
91
+ expect(() => resolveSelector(undefined, undefined)).toThrow(TypeError);
94
92
  });
95
93
  });
96
94
  });
97
95
  describe('assertValidSelector()', () => {
98
96
  it('should not throw when selector is a function', () => {
99
- expect(() => (0, core_utils_1.assertValidSelector)(() => { })).not.toThrow();
97
+ expect(() => assertValidSelector(() => { })).not.toThrow();
100
98
  });
101
99
  it('should not throw when selector is a string', () => {
102
- expect(() => (0, core_utils_1.assertValidSelector)('name')).not.toThrow();
100
+ expect(() => assertValidSelector('name')).not.toThrow();
103
101
  });
104
102
  it('should not throw when selector is undefined', () => {
105
- expect(() => (0, core_utils_1.assertValidSelector)(undefined)).not.toThrow();
103
+ expect(() => assertValidSelector(undefined)).not.toThrow();
106
104
  });
107
105
  describe('error handling', () => {
108
106
  it('should throw TypeError when selector is a number', () => {
109
- expect(() => (0, core_utils_1.assertValidSelector)(123)).toThrow(TypeError);
107
+ expect(() => assertValidSelector(123)).toThrow(TypeError);
110
108
  });
111
109
  it('should throw TypeError when selector is an object', () => {
112
- expect(() => (0, core_utils_1.assertValidSelector)({})).toThrow(TypeError);
110
+ expect(() => assertValidSelector({})).toThrow(TypeError);
113
111
  });
114
112
  });
115
113
  });
116
114
  describe('isNumberOrString()', () => {
117
115
  it('should return true for a string', () => {
118
- expect((0, core_utils_1.isNumberOrString)('hello')).toBe(true);
116
+ expect(isNumberOrString('hello')).toBe(true);
119
117
  });
120
118
  it('should return true for a number', () => {
121
- expect((0, core_utils_1.isNumberOrString)(42)).toBe(true);
119
+ expect(isNumberOrString(42)).toBe(true);
122
120
  });
123
121
  it('should return false for a boolean', () => {
124
- expect((0, core_utils_1.isNumberOrString)(true)).toBe(false);
122
+ expect(isNumberOrString(true)).toBe(false);
125
123
  });
126
124
  it('should return false for null', () => {
127
- expect((0, core_utils_1.isNumberOrString)(null)).toBe(false);
125
+ expect(isNumberOrString(null)).toBe(false);
128
126
  });
129
127
  it('should return false for an object', () => {
130
- expect((0, core_utils_1.isNumberOrString)({})).toBe(false);
128
+ expect(isNumberOrString({})).toBe(false);
131
129
  });
132
130
  });
133
131
  describe('utilitishError()', () => {
134
132
  it('should throw a TypeError by default', () => {
135
- expect(() => (0, core_utils_1.utilitishError)('method', 'message')).toThrow(TypeError);
133
+ expect(() => utilitishError('method', 'message')).toThrow(TypeError);
136
134
  });
137
135
  it('should throw a RangeError when specified', () => {
138
- expect(() => (0, core_utils_1.utilitishError)('method', 'message', undefined, RangeError)).toThrow(RangeError);
136
+ expect(() => utilitishError('method', 'message', undefined, RangeError)).toThrow(RangeError);
139
137
  });
140
138
  it('should include method and message in the error message', () => {
141
- expect(() => (0, core_utils_1.utilitishError)('String.prototype.test', 'value must be a string')).toThrow('[Utilitish] String.prototype.test: value must be a string');
139
+ expect(() => utilitishError('String.prototype.test', 'value must be a string')).toThrow('[Utilitish] String.prototype.test: value must be a string');
142
140
  });
143
141
  it('should include received type in the error message when provided', () => {
144
- expect(() => (0, core_utils_1.utilitishError)('String.prototype.test', 'value must be a string', 42)).toThrow('[Utilitish] String.prototype.test: value must be a string, received number');
142
+ expect(() => utilitishError('String.prototype.test', 'value must be a string', 42)).toThrow('[Utilitish] String.prototype.test: value must be a string, received number');
145
143
  });
146
144
  it('should not include received info when received is undefined', () => {
147
- expect(() => (0, core_utils_1.utilitishError)('String.prototype.test', 'value must be a string', undefined)).toThrow('[Utilitish] String.prototype.test: value must be a string');
145
+ expect(() => utilitishError('String.prototype.test', 'value must be a string', undefined)).toThrow('[Utilitish] String.prototype.test: value must be a string');
148
146
  });
149
147
  });
150
148
  });
@@ -1,22 +1,19 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.sortBy = sortBy;
4
- const core_utils_1 = require("./core.utils");
5
- function sortBy(arr, direction, selector) {
1
+ import { isNumberOrString, resolveSelector } from './core.utils';
2
+ export function sortBy(arr, direction, selector) {
6
3
  if (arr.length === 0)
7
4
  return arr.slice();
8
- const getValue = (0, core_utils_1.resolveSelector)(selector, (item) => item);
5
+ const getValue = resolveSelector(selector, (item) => item);
9
6
  const sample = getValue(arr[0]);
10
- if (!(0, core_utils_1.isNumberOrString)(sample)) {
7
+ if (!isNumberOrString(sample)) {
11
8
  throw new TypeError('Selector must return number or string');
12
9
  }
13
- if (!selector && !arr.every((item) => (0, core_utils_1.isNumberOrString)(item))) {
10
+ if (!selector && !arr.every((item) => isNumberOrString(item))) {
14
11
  throw new TypeError('Array elements must be number or string if no selector is provided');
15
12
  }
16
13
  return arr.slice().sort((a, b) => {
17
14
  const valA = getValue(a);
18
15
  const valB = getValue(b);
19
- if (!(0, core_utils_1.isNumberOrString)(valA) || !(0, core_utils_1.isNumberOrString)(valB)) {
16
+ if (!isNumberOrString(valA) || !isNumberOrString(valB)) {
20
17
  throw new TypeError('Selector must return number or string');
21
18
  }
22
19
  if (valA > valB)