@oscarpalmer/atoms 0.181.0 → 0.182.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.
- package/dist/index.d.mts +113 -1
- package/dist/index.mjs +193 -7
- package/dist/kalas.d.mts +61 -0
- package/dist/kalas.mjs +93 -0
- package/dist/string/case.mjs +10 -4
- package/dist/string/normalize.d.mts +55 -0
- package/dist/string/normalize.mjs +93 -0
- package/package.json +1 -1
- package/src/index.ts +3 -0
- package/src/kalas.ts +167 -0
- package/src/string/case.ts +20 -4
- package/src/string/normalize.ts +169 -0
package/dist/index.d.mts
CHANGED
|
@@ -2876,6 +2876,64 @@ declare function setValue<Data extends PlainObject, Path extends NestedKeys<Data
|
|
|
2876
2876
|
*/
|
|
2877
2877
|
declare function setValue<Data extends PlainObject>(data: Data, path: string, value: unknown, ignoreCase?: boolean): Data;
|
|
2878
2878
|
//#endregion
|
|
2879
|
+
//#region src/kalas.d.ts
|
|
2880
|
+
declare class Events<Map extends Record<string, GenericCallback>> {
|
|
2881
|
+
#private;
|
|
2882
|
+
constructor(kalas: Kalas<Map>);
|
|
2883
|
+
/**
|
|
2884
|
+
* Subscribe to an event with a callback
|
|
2885
|
+
* @param event Event name
|
|
2886
|
+
* @param callback Callback function
|
|
2887
|
+
* @returns Unsubscriber function
|
|
2888
|
+
*/
|
|
2889
|
+
subscribe<Event extends keyof Map>(event: Event, callback: Map[Event]): Unsubscriber;
|
|
2890
|
+
/**
|
|
2891
|
+
* Unsubscribe from an event with a callback _(or all callbacks, if no callback is provided)_
|
|
2892
|
+
* @param event Event name
|
|
2893
|
+
* @param callback Callback function
|
|
2894
|
+
* @returns Unsubscriber function
|
|
2895
|
+
*/
|
|
2896
|
+
unsubscribe<Event extends keyof Map>(event: Event, callback?: Map[Event]): void;
|
|
2897
|
+
}
|
|
2898
|
+
declare class Kalas<Map extends Record<string, GenericCallback>> {
|
|
2899
|
+
#private;
|
|
2900
|
+
/**
|
|
2901
|
+
* Events interface for subscribing and unsubscribing to events
|
|
2902
|
+
*/
|
|
2903
|
+
readonly events: Events<Map>;
|
|
2904
|
+
constructor(names: (keyof Map)[]);
|
|
2905
|
+
/**
|
|
2906
|
+
* Remove all event subscribers
|
|
2907
|
+
*/
|
|
2908
|
+
clear(): void;
|
|
2909
|
+
/**
|
|
2910
|
+
* Emit an event with parameters
|
|
2911
|
+
* @param event Event name
|
|
2912
|
+
* @param parameters Event parameters
|
|
2913
|
+
*/
|
|
2914
|
+
emit<Event extends keyof Map>(event: Event, ...parameters: Parameters<Map[Event]>): void;
|
|
2915
|
+
/**
|
|
2916
|
+
* Subscribe to an event with a callback
|
|
2917
|
+
* @param event Event name
|
|
2918
|
+
* @param callback Callback function
|
|
2919
|
+
* @returns Unsubscriber function
|
|
2920
|
+
*/
|
|
2921
|
+
subscribe<Event extends keyof Map>(event: Event, callback: Map[Event]): Unsubscriber;
|
|
2922
|
+
/**
|
|
2923
|
+
* Unsubscribe from an event with a callback _(or all callbacks, if no callback is provided)_
|
|
2924
|
+
* @param event Event name
|
|
2925
|
+
* @param callback Callback function
|
|
2926
|
+
*/
|
|
2927
|
+
unsubscribe<Event extends keyof Map>(event: Event, callback?: Map[Event]): void;
|
|
2928
|
+
}
|
|
2929
|
+
type Unsubscriber = () => void;
|
|
2930
|
+
/**
|
|
2931
|
+
* Create a Kalas _(party)_ for named events
|
|
2932
|
+
* @param names Event names
|
|
2933
|
+
* @returns Kalas instance
|
|
2934
|
+
*/
|
|
2935
|
+
declare function kalas<Events extends Record<string, GenericCallback>>(names: (keyof Events)[]): Kalas<Events>;
|
|
2936
|
+
//#endregion
|
|
2879
2937
|
//#region src/string/case.d.ts
|
|
2880
2938
|
/**
|
|
2881
2939
|
* Convert a string to camel case _(thisIsCamelCase)_
|
|
@@ -3099,6 +3157,60 @@ declare function includes(haystack: string, needle: string, ignoreCase?: boolean
|
|
|
3099
3157
|
*/
|
|
3100
3158
|
declare function startsWith(haystack: string, needle: string, ignoreCase?: boolean): boolean;
|
|
3101
3159
|
//#endregion
|
|
3160
|
+
//#region src/string/normalize.d.ts
|
|
3161
|
+
/**
|
|
3162
|
+
* Options for normalizing a string
|
|
3163
|
+
*/
|
|
3164
|
+
type NormalizeOptions = {
|
|
3165
|
+
/**
|
|
3166
|
+
* Remove diacritical marks from the string? _(defaults to `true`)_
|
|
3167
|
+
*/
|
|
3168
|
+
deburr?: boolean;
|
|
3169
|
+
/**
|
|
3170
|
+
* Convert the string to lower case? _(defaults to `true`)_
|
|
3171
|
+
*/
|
|
3172
|
+
lowerCase?: boolean;
|
|
3173
|
+
/**
|
|
3174
|
+
* Trim the string? _(defaults to `true`)_
|
|
3175
|
+
*/
|
|
3176
|
+
trim?: boolean;
|
|
3177
|
+
};
|
|
3178
|
+
/**
|
|
3179
|
+
* String normalizer function
|
|
3180
|
+
*/
|
|
3181
|
+
type Normalizer = {
|
|
3182
|
+
/**
|
|
3183
|
+
* Normalize a string
|
|
3184
|
+
* @param value String to normalize
|
|
3185
|
+
* @returns Normalized string
|
|
3186
|
+
*/
|
|
3187
|
+
(value: string): string;
|
|
3188
|
+
};
|
|
3189
|
+
/**
|
|
3190
|
+
* Deburr a string, removing diacritical marks
|
|
3191
|
+
* @param value String to deburr
|
|
3192
|
+
* @returns Deburred string
|
|
3193
|
+
*/
|
|
3194
|
+
declare function deburr(value: string): string;
|
|
3195
|
+
/**
|
|
3196
|
+
* Initialize a string normalizer
|
|
3197
|
+
* @param options Normalization options
|
|
3198
|
+
* @returns Normalizer function
|
|
3199
|
+
*/
|
|
3200
|
+
declare function initializeNormalizer(options?: NormalizeOptions): Normalizer;
|
|
3201
|
+
/**
|
|
3202
|
+
* Normalize a string
|
|
3203
|
+
*
|
|
3204
|
+
* By default, the string will be trimmed, deburred, and then lowercased
|
|
3205
|
+
* @param value String to normalize
|
|
3206
|
+
* @param options Normalization options
|
|
3207
|
+
* @returns Normalized string
|
|
3208
|
+
*/
|
|
3209
|
+
declare function normalize(value: string, options?: NormalizeOptions): string;
|
|
3210
|
+
declare namespace normalize {
|
|
3211
|
+
var initialize: typeof initializeNormalizer;
|
|
3212
|
+
}
|
|
3213
|
+
//#endregion
|
|
3102
3214
|
//#region src/string/template.d.ts
|
|
3103
3215
|
/**
|
|
3104
3216
|
* Options for templating strings
|
|
@@ -5207,4 +5319,4 @@ declare class SizedSet<Value = unknown> extends Set<Value> {
|
|
|
5207
5319
|
get(value: Value, update?: boolean): Value | undefined;
|
|
5208
5320
|
}
|
|
5209
5321
|
//#endregion
|
|
5210
|
-
export { AnyResult, ArrayComparisonSorter, ArrayKeySorter, ArrayOrPlainObject, ArrayPosition, ArrayValueSorter, Asserter, AsyncCancelableCallback, AttemptFlow, AttemptFlowPromise, type Beacon, type BeaconOptions, BuiltIns, CancelableCallback, CancelablePromise, type Color, Constructor, DiffOptions, DiffResult, DiffValue, EqualOptions, Err, EventPosition, ExtendedErr, ExtendedResult, Flow, FlowPromise, FulfilledPromise, FuzzyConfiguration, FuzzyOptions, FuzzyResult, FuzzySearchOptions, GenericAsyncCallback, GenericCallback, type HSLAColor, type HSLColor, Key$1 as Key, KeyedValue, type Logger, type Memoized, type MemoizedOptions, MergeOptions, Merger, NestedArray, NestedKeys, NestedPartial, NestedValue, NestedValues, NumericalKeys, NumericalValues, type Observable, type Observer, Ok, OnceAsyncCallback, OnceCallback, PROMISE_ABORT_EVENT, PROMISE_ABORT_OPTIONS, PROMISE_ERROR_NAME, PROMISE_MESSAGE_EXPECTATION_ATTEMPT, PROMISE_MESSAGE_EXPECTATION_RESULT, PROMISE_MESSAGE_EXPECTATION_TIMED, PROMISE_MESSAGE_TIMEOUT, PROMISE_STRATEGY_ALL, PROMISE_STRATEGY_DEFAULT, PROMISE_TYPE_FULFILLED, PROMISE_TYPE_REJECTED, PlainObject, Primitive, PromiseData, PromiseHandlers, PromiseOptions, PromiseParameters, PromiseStrategy, PromiseTimeoutError, PromisesItems, PromisesOptions, PromisesResult, PromisesUnwrapped, PromisesValue, PromisesValues, type Queue, QueueError, type QueueOptions, type Queued, type QueuedResult, type RGBAColor, type RGBColor, RejectedPromise, RequiredKeys, Result, ResultMatch, RetryError, RetryOptions, SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING, Shaken, Simplify, SizedMap, SizedSet, Smushed, SortDirection, Sorter, type Subscription, TemplateOptions, type Time, ToString, TypedArray, Unsmushed, UnwrapValue, assert, assertCondition, assertDefined, assertInstanceOf, assertIs, asyncAttempt, asyncDebounce, asyncFlow, asyncMatchResult, asyncOnce, asyncPipe, asyncThrottle, attempt, attemptAsyncFlow, attemptAsyncPipe, attemptFlow, attemptPipe, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, count, debounce, dedent, delay, deregisterCloner, deregisterComparator, deregisterEqualizer, diff, difference, drop, endsWith, endsWithArray, equal, error, exclude, exists, filter, find, findLast, first, firstOrDefault, flatten, floor, flow, fromQuery, toPromise as fromResult, toPromise, fuzzy, fuzzyMatch, getArray, getArrayPosition, getColor, getError, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getSortedIndex, getString, getTimedPromise, getUuid, getValue, groupArraysBy, groupBy, handleResult, hasValue, hexToHsl, hexToHsla, hexToRgb, hexToRgba, hslToHex, hslToRgb, hslToRgba, ignoreKey, inMap, inSet, includes, includesArray, indexOf, indexOfArray, initializeEqualizer, initializeMerger, initializeSorter, initializeTemplater, insert, intersection, isArrayOrPlainObject, isColor, isConstructor, isEmpty, isError, isFulfilled, isHexColor, isHslColor, isHslLike, isHslaColor, isInstanceOf, isKey, isNonArrayOrPlainObject, isNonConstructor, isNonEmpty, isNonInstanceOf, isNonKey, isNonNullable, isNonNullableOrEmpty, isNonNullableOrWhitespace, isNonNumber, isNonNumerical, isNonObject, isNonPlainObject, isNonPrimitive, isNonTypedArray, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isOk, isPlainObject, isPrimitive, isRejected, isResult, isRgbColor, isRgbLike, isRgbaColor, isSorted, isTypedArray, join, kebabCase, last, lastIndexOf, lastOrDefault, logger, lowerCase, matchResult, max, median, memoize, merge, min, move, moveIndices, moveToIndex, noop, ok, omit, once, parse, partition, pascalCase, pick, pipe, promises, push, queue, range, registerCloner, registerComparator, registerEqualizer, resultPromises, retry, reverse, rgbToHex, rgbToHsl, rgbToHsla, round, select, setValue, settlePromise, shake, shuffle, single, slice, smush, snakeCase, sort, splice, startsWith, startsWithArray, sum, swap, take, template, throttle, timed, times, titleCase, toMap, toMapArrays, toQuery, toRecord, toRecordArrays, toResult, toSet, toggle, trim, truncate, tryDecode, tryEncode, union, unique, unsmush, unwrap, update, upperCase, words };
|
|
5322
|
+
export { AnyResult, ArrayComparisonSorter, ArrayKeySorter, ArrayOrPlainObject, ArrayPosition, ArrayValueSorter, Asserter, AsyncCancelableCallback, AttemptFlow, AttemptFlowPromise, type Beacon, type BeaconOptions, BuiltIns, CancelableCallback, CancelablePromise, type Color, Constructor, DiffOptions, DiffResult, DiffValue, EqualOptions, Err, EventPosition, type Events, ExtendedErr, ExtendedResult, Flow, FlowPromise, FulfilledPromise, FuzzyConfiguration, FuzzyOptions, FuzzyResult, FuzzySearchOptions, GenericAsyncCallback, GenericCallback, type HSLAColor, type HSLColor, type Kalas, Key$1 as Key, KeyedValue, type Logger, type Memoized, type MemoizedOptions, MergeOptions, Merger, NestedArray, NestedKeys, NestedPartial, NestedValue, NestedValues, NormalizeOptions, Normalizer, NumericalKeys, NumericalValues, type Observable, type Observer, Ok, OnceAsyncCallback, OnceCallback, PROMISE_ABORT_EVENT, PROMISE_ABORT_OPTIONS, PROMISE_ERROR_NAME, PROMISE_MESSAGE_EXPECTATION_ATTEMPT, PROMISE_MESSAGE_EXPECTATION_RESULT, PROMISE_MESSAGE_EXPECTATION_TIMED, PROMISE_MESSAGE_TIMEOUT, PROMISE_STRATEGY_ALL, PROMISE_STRATEGY_DEFAULT, PROMISE_TYPE_FULFILLED, PROMISE_TYPE_REJECTED, PlainObject, Primitive, PromiseData, PromiseHandlers, PromiseOptions, PromiseParameters, PromiseStrategy, PromiseTimeoutError, PromisesItems, PromisesOptions, PromisesResult, PromisesUnwrapped, PromisesValue, PromisesValues, type Queue, QueueError, type QueueOptions, type Queued, type QueuedResult, type RGBAColor, type RGBColor, RejectedPromise, RequiredKeys, Result, ResultMatch, RetryError, RetryOptions, SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING, Shaken, Simplify, SizedMap, SizedSet, Smushed, SortDirection, Sorter, type Subscription, TemplateOptions, type Time, ToString, TypedArray, Unsmushed, Unsubscriber, UnwrapValue, assert, assertCondition, assertDefined, assertInstanceOf, assertIs, asyncAttempt, asyncDebounce, asyncFlow, asyncMatchResult, asyncOnce, asyncPipe, asyncThrottle, attempt, attemptAsyncFlow, attemptAsyncPipe, attemptFlow, attemptPipe, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, count, debounce, deburr, dedent, delay, deregisterCloner, deregisterComparator, deregisterEqualizer, diff, difference, drop, endsWith, endsWithArray, equal, error, exclude, exists, filter, find, findLast, first, firstOrDefault, flatten, floor, flow, fromQuery, toPromise as fromResult, toPromise, fuzzy, fuzzyMatch, getArray, getArrayPosition, getColor, getError, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getSortedIndex, getString, getTimedPromise, getUuid, getValue, groupArraysBy, groupBy, handleResult, hasValue, hexToHsl, hexToHsla, hexToRgb, hexToRgba, hslToHex, hslToRgb, hslToRgba, ignoreKey, inMap, inSet, includes, includesArray, indexOf, indexOfArray, initializeEqualizer, initializeMerger, initializeNormalizer, initializeSorter, initializeTemplater, insert, intersection, isArrayOrPlainObject, isColor, isConstructor, isEmpty, isError, isFulfilled, isHexColor, isHslColor, isHslLike, isHslaColor, isInstanceOf, isKey, isNonArrayOrPlainObject, isNonConstructor, isNonEmpty, isNonInstanceOf, isNonKey, isNonNullable, isNonNullableOrEmpty, isNonNullableOrWhitespace, isNonNumber, isNonNumerical, isNonObject, isNonPlainObject, isNonPrimitive, isNonTypedArray, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isOk, isPlainObject, isPrimitive, isRejected, isResult, isRgbColor, isRgbLike, isRgbaColor, isSorted, isTypedArray, join, kalas, kebabCase, last, lastIndexOf, lastOrDefault, logger, lowerCase, matchResult, max, median, memoize, merge, min, move, moveIndices, moveToIndex, noop, normalize, ok, omit, once, parse, partition, pascalCase, pick, pipe, promises, push, queue, range, registerCloner, registerComparator, registerEqualizer, resultPromises, retry, reverse, rgbToHex, rgbToHsl, rgbToHsla, round, select, setValue, settlePromise, shake, shuffle, single, slice, smush, snakeCase, sort, splice, startsWith, startsWithArray, sum, swap, take, template, throttle, timed, times, titleCase, toMap, toMapArrays, toQuery, toRecord, toRecordArrays, toResult, toSet, toggle, trim, truncate, tryDecode, tryEncode, union, unique, unsmush, unwrap, update, upperCase, words };
|
package/dist/index.mjs
CHANGED
|
@@ -620,10 +620,10 @@ function select(array, ...parameters) {
|
|
|
620
620
|
//#region src/array/single.ts
|
|
621
621
|
function single(array, ...parameters) {
|
|
622
622
|
const { matched } = findValues("all", array, parameters);
|
|
623
|
-
if (matched.length > 1) throw new Error(MESSAGE);
|
|
623
|
+
if (matched.length > 1) throw new Error(MESSAGE$1);
|
|
624
624
|
return matched[0];
|
|
625
625
|
}
|
|
626
|
-
const MESSAGE = "Multiple items were found";
|
|
626
|
+
const MESSAGE$1 = "Multiple items were found";
|
|
627
627
|
//#endregion
|
|
628
628
|
//#region src/array/slice.ts
|
|
629
629
|
function drop(array, first, second) {
|
|
@@ -2289,6 +2289,97 @@ function setValue(data, path, value, ignoreCase) {
|
|
|
2289
2289
|
}
|
|
2290
2290
|
const EXPRESSION_INDEX = /^\d+$/;
|
|
2291
2291
|
//#endregion
|
|
2292
|
+
//#region src/kalas.ts
|
|
2293
|
+
var Events = class {
|
|
2294
|
+
#kalas;
|
|
2295
|
+
constructor(kalas) {
|
|
2296
|
+
this.#kalas = kalas;
|
|
2297
|
+
}
|
|
2298
|
+
/**
|
|
2299
|
+
* Subscribe to an event with a callback
|
|
2300
|
+
* @param event Event name
|
|
2301
|
+
* @param callback Callback function
|
|
2302
|
+
* @returns Unsubscriber function
|
|
2303
|
+
*/
|
|
2304
|
+
subscribe(event, callback) {
|
|
2305
|
+
return this.#kalas.subscribe(event, callback);
|
|
2306
|
+
}
|
|
2307
|
+
/**
|
|
2308
|
+
* Unsubscribe from an event with a callback _(or all callbacks, if no callback is provided)_
|
|
2309
|
+
* @param event Event name
|
|
2310
|
+
* @param callback Callback function
|
|
2311
|
+
* @returns Unsubscriber function
|
|
2312
|
+
*/
|
|
2313
|
+
unsubscribe(event, callback) {
|
|
2314
|
+
return this.#kalas.unsubscribe(event, callback);
|
|
2315
|
+
}
|
|
2316
|
+
};
|
|
2317
|
+
var Kalas = class {
|
|
2318
|
+
#names;
|
|
2319
|
+
#subscribers = /* @__PURE__ */ new Map();
|
|
2320
|
+
constructor(names) {
|
|
2321
|
+
this.#names = new Set(names);
|
|
2322
|
+
Object.defineProperty(this, "events", { value: new Events(this) });
|
|
2323
|
+
}
|
|
2324
|
+
/**
|
|
2325
|
+
* Remove all event subscribers
|
|
2326
|
+
*/
|
|
2327
|
+
clear() {
|
|
2328
|
+
this.#subscribers.clear();
|
|
2329
|
+
}
|
|
2330
|
+
/**
|
|
2331
|
+
* Emit an event with parameters
|
|
2332
|
+
* @param event Event name
|
|
2333
|
+
* @param parameters Event parameters
|
|
2334
|
+
*/
|
|
2335
|
+
emit(event, ...parameters) {
|
|
2336
|
+
const subscribers = this.#subscribers.get(event);
|
|
2337
|
+
if (subscribers == null) return;
|
|
2338
|
+
for (const callback of subscribers) callback(...parameters);
|
|
2339
|
+
}
|
|
2340
|
+
/**
|
|
2341
|
+
* Subscribe to an event with a callback
|
|
2342
|
+
* @param event Event name
|
|
2343
|
+
* @param callback Callback function
|
|
2344
|
+
* @returns Unsubscriber function
|
|
2345
|
+
*/
|
|
2346
|
+
subscribe(event, callback) {
|
|
2347
|
+
if (!this.#names.has(event) || typeof callback !== "function") return noop;
|
|
2348
|
+
let subscribers = this.#subscribers.get(event);
|
|
2349
|
+
if (subscribers == null) {
|
|
2350
|
+
subscribers = /* @__PURE__ */ new Set();
|
|
2351
|
+
this.#subscribers.set(event, subscribers);
|
|
2352
|
+
}
|
|
2353
|
+
subscribers.add(callback);
|
|
2354
|
+
return () => {
|
|
2355
|
+
subscribers?.delete(callback);
|
|
2356
|
+
};
|
|
2357
|
+
}
|
|
2358
|
+
/**
|
|
2359
|
+
* Unsubscribe from an event with a callback _(or all callbacks, if no callback is provided)_
|
|
2360
|
+
* @param event Event name
|
|
2361
|
+
* @param callback Callback function
|
|
2362
|
+
*/
|
|
2363
|
+
unsubscribe(event, callback) {
|
|
2364
|
+
if (!this.#names.has(event) || (callback != null ? typeof callback !== "function" : false)) return;
|
|
2365
|
+
const subscribers = this.#subscribers.get(event);
|
|
2366
|
+
if (subscribers == null) return;
|
|
2367
|
+
if (callback == null) subscribers.clear();
|
|
2368
|
+
else subscribers.delete(callback);
|
|
2369
|
+
if (callback == null || subscribers.size === 0) this.#subscribers.delete(event);
|
|
2370
|
+
}
|
|
2371
|
+
};
|
|
2372
|
+
/**
|
|
2373
|
+
* Create a Kalas _(party)_ for named events
|
|
2374
|
+
* @param names Event names
|
|
2375
|
+
* @returns Kalas instance
|
|
2376
|
+
*/
|
|
2377
|
+
function kalas(names) {
|
|
2378
|
+
if (!Array.isArray(names) || names.length === 0 || !names.every((name) => typeof name === "string")) throw new Error(MESSAGE);
|
|
2379
|
+
return new Kalas(names);
|
|
2380
|
+
}
|
|
2381
|
+
const MESSAGE = "Kalas requires an array of event names.";
|
|
2382
|
+
//#endregion
|
|
2292
2383
|
//#region src/string/case.ts
|
|
2293
2384
|
/**
|
|
2294
2385
|
* Convert a string to camel case _(thisIsCamelCase)_
|
|
@@ -2322,7 +2413,9 @@ function kebabCase(value) {
|
|
|
2322
2413
|
* @returns Lower-cased string
|
|
2323
2414
|
*/
|
|
2324
2415
|
function lowerCase(value) {
|
|
2325
|
-
|
|
2416
|
+
if (typeof value !== "string") return "";
|
|
2417
|
+
memoizedLowerCase ??= memoize((v) => v.toLocaleLowerCase());
|
|
2418
|
+
return memoizedLowerCase.run(value);
|
|
2326
2419
|
}
|
|
2327
2420
|
/**
|
|
2328
2421
|
* Convert a string to pascal case _(ThisIsPascalCase)_
|
|
@@ -2346,8 +2439,8 @@ function snakeCase(value) {
|
|
|
2346
2439
|
* @returns Title-cased string
|
|
2347
2440
|
*/
|
|
2348
2441
|
function titleCase(value) {
|
|
2349
|
-
if (typeof value !== "string") return "";
|
|
2350
|
-
memoizedTitleCase ??= memoize((v) => v.length <
|
|
2442
|
+
if (typeof value !== "string" || value.length === 0) return "";
|
|
2443
|
+
memoizedTitleCase ??= memoize((v) => v.length < 2 ? capitalize(v) : join(words(v).map(capitalize), " "));
|
|
2351
2444
|
return memoizedTitleCase.run(value);
|
|
2352
2445
|
}
|
|
2353
2446
|
function toCase(type, value, capitalizeAny, capitalizeFirst) {
|
|
@@ -2387,7 +2480,9 @@ function toCaseCallback(value) {
|
|
|
2387
2480
|
* @returns Upper-cased string
|
|
2388
2481
|
*/
|
|
2389
2482
|
function upperCase(value) {
|
|
2390
|
-
|
|
2483
|
+
if (typeof value !== "string" || value.length === 0) return "";
|
|
2484
|
+
memoizedUpperCase ??= memoize((v) => v.toLocaleUpperCase());
|
|
2485
|
+
return memoizedUpperCase.run(value);
|
|
2391
2486
|
}
|
|
2392
2487
|
const CASE_CAMEL = "camel";
|
|
2393
2488
|
const CASE_KEBAB = "kebab";
|
|
@@ -2408,7 +2503,9 @@ const delimiters = {
|
|
|
2408
2503
|
[CASE_SNAKE]: DELIMITER_UNDERSCORE
|
|
2409
2504
|
};
|
|
2410
2505
|
let memoizedCapitalize;
|
|
2506
|
+
let memoizedLowerCase;
|
|
2411
2507
|
let memoizedTitleCase;
|
|
2508
|
+
let memoizedUpperCase;
|
|
2412
2509
|
//#endregion
|
|
2413
2510
|
//#region src/is.ts
|
|
2414
2511
|
/**
|
|
@@ -2822,6 +2919,95 @@ function truncate(value, length, suffix) {
|
|
|
2822
2919
|
}
|
|
2823
2920
|
const ZERO = "0";
|
|
2824
2921
|
//#endregion
|
|
2922
|
+
//#region src/string/normalize.ts
|
|
2923
|
+
/**
|
|
2924
|
+
* Deburr a string, removing diacritical marks
|
|
2925
|
+
* @param value String to deburr
|
|
2926
|
+
* @returns Deburred string
|
|
2927
|
+
*/
|
|
2928
|
+
function deburr(value) {
|
|
2929
|
+
if (typeof value !== "string") return "";
|
|
2930
|
+
deburrMemoizer ??= memoize((value) => {
|
|
2931
|
+
let deburred = value.normalize(DEBURR_NORMALIZATION).replace(DEBURR_PATTERN_SIMPLE, "");
|
|
2932
|
+
deburred = deburred.replace(DEBURR_PATTERN_CHARACTERS, (_, character) => DEBURR_CHARACTERS[character]);
|
|
2933
|
+
return deburred;
|
|
2934
|
+
});
|
|
2935
|
+
return deburrMemoizer.run(value);
|
|
2936
|
+
}
|
|
2937
|
+
function getNormalizeOptions(input) {
|
|
2938
|
+
const options = isPlainObject(input) ? input : {};
|
|
2939
|
+
return {
|
|
2940
|
+
deburr: options.deburr !== false,
|
|
2941
|
+
lowerCase: options.lowerCase !== false,
|
|
2942
|
+
trim: options.trim !== false
|
|
2943
|
+
};
|
|
2944
|
+
}
|
|
2945
|
+
/**
|
|
2946
|
+
* Initialize a string normalizer
|
|
2947
|
+
* @param options Normalization options
|
|
2948
|
+
* @returns Normalizer function
|
|
2949
|
+
*/
|
|
2950
|
+
function initializeNormalizer(options) {
|
|
2951
|
+
const normalization = getNormalizeOptions(options);
|
|
2952
|
+
return (value) => normalizeString(value, normalization);
|
|
2953
|
+
}
|
|
2954
|
+
/**
|
|
2955
|
+
* Normalize a string
|
|
2956
|
+
*
|
|
2957
|
+
* By default, the string will be trimmed, deburred, and then lowercased
|
|
2958
|
+
* @param value String to normalize
|
|
2959
|
+
* @param options Normalization options
|
|
2960
|
+
* @returns Normalized string
|
|
2961
|
+
*/
|
|
2962
|
+
function normalize(value, options) {
|
|
2963
|
+
return normalizeString(value, getNormalizeOptions(options));
|
|
2964
|
+
}
|
|
2965
|
+
normalize.initialize = initializeNormalizer;
|
|
2966
|
+
function normalizeString(value, options) {
|
|
2967
|
+
if (typeof value !== "string") return "";
|
|
2968
|
+
let result = value;
|
|
2969
|
+
if (options.trim) result = result.trim();
|
|
2970
|
+
if (options.deburr) result = deburr(result);
|
|
2971
|
+
if (options.lowerCase) result = lowerCase(result);
|
|
2972
|
+
return result;
|
|
2973
|
+
}
|
|
2974
|
+
const DEBURR_CHARACTERS = {
|
|
2975
|
+
Æ: "AE",
|
|
2976
|
+
æ: "ae",
|
|
2977
|
+
Ð: "D",
|
|
2978
|
+
ð: "d",
|
|
2979
|
+
Đ: "D",
|
|
2980
|
+
đ: "d",
|
|
2981
|
+
Ħ: "H",
|
|
2982
|
+
ħ: "h",
|
|
2983
|
+
IJ: "IJ",
|
|
2984
|
+
ij: "ij",
|
|
2985
|
+
İ: "I",
|
|
2986
|
+
ı: "i",
|
|
2987
|
+
ĸ: "k",
|
|
2988
|
+
Ŀ: "L",
|
|
2989
|
+
ŀ: "l",
|
|
2990
|
+
Ł: "L",
|
|
2991
|
+
ł: "l",
|
|
2992
|
+
Ŋ: "N",
|
|
2993
|
+
ŋ: "n",
|
|
2994
|
+
ʼn: "'n",
|
|
2995
|
+
Œ: "OE",
|
|
2996
|
+
œ: "oe",
|
|
2997
|
+
Ø: "O",
|
|
2998
|
+
ø: "o",
|
|
2999
|
+
ſ: "s",
|
|
3000
|
+
ß: "ss",
|
|
3001
|
+
Þ: "TH",
|
|
3002
|
+
þ: "th",
|
|
3003
|
+
Ŧ: "T",
|
|
3004
|
+
ŧ: "t"
|
|
3005
|
+
};
|
|
3006
|
+
const DEBURR_NORMALIZATION = "NFD";
|
|
3007
|
+
const DEBURR_PATTERN_CHARACTERS = new RegExp(`(${Object.keys(DEBURR_CHARACTERS).join("|")})`, "g");
|
|
3008
|
+
const DEBURR_PATTERN_SIMPLE = /[\u0300-\u036f]/g;
|
|
3009
|
+
let deburrMemoizer;
|
|
3010
|
+
//#endregion
|
|
2825
3011
|
//#region src/string/template.ts
|
|
2826
3012
|
function getTemplateOptions(input) {
|
|
2827
3013
|
const options = isPlainObject(input) ? input : {};
|
|
@@ -5054,4 +5240,4 @@ var SizedSet = class extends Set {
|
|
|
5054
5240
|
}
|
|
5055
5241
|
};
|
|
5056
5242
|
//#endregion
|
|
5057
|
-
export { CancelablePromise, PROMISE_ABORT_EVENT, PROMISE_ABORT_OPTIONS, PROMISE_ERROR_NAME, PROMISE_MESSAGE_EXPECTATION_ATTEMPT, PROMISE_MESSAGE_EXPECTATION_RESULT, PROMISE_MESSAGE_EXPECTATION_TIMED, PROMISE_MESSAGE_TIMEOUT, PROMISE_STRATEGY_ALL, PROMISE_STRATEGY_DEFAULT, PROMISE_TYPE_FULFILLED, PROMISE_TYPE_REJECTED, PromiseTimeoutError, QueueError, RetryError, SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING, SizedMap, SizedSet, assert, assertCondition, assertDefined, assertInstanceOf, assertIs, asyncAttempt, asyncDebounce, asyncFlow, asyncMatchResult, asyncOnce, asyncPipe, asyncThrottle, attempt, attemptAsyncFlow, attemptAsyncPipe, attemptFlow, attemptPipe, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, count, debounce, dedent, delay, deregisterCloner, deregisterComparator, deregisterEqualizer, diff, difference, drop, endsWith, endsWithArray, equal, error, exclude, exists, filter, find, findLast, first, firstOrDefault, flatten, floor, flow, fromQuery, toPromise as fromResult, toPromise, fuzzy, fuzzyMatch, getArray, getArrayPosition, getColor, getError, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getSortedIndex, getString, getTimedPromise, getUuid, getValue, groupArraysBy, groupBy, handleResult, hasValue, hexToHsl, hexToHsla, hexToRgb, hexToRgba, hslToHex, hslToRgb, hslToRgba, ignoreKey, inMap, inSet, includes, includesArray, indexOf, indexOfArray, initializeEqualizer, initializeMerger, initializeSorter, initializeTemplater, insert, intersection, isArrayOrPlainObject, isColor, isConstructor, isEmpty, isError, isFulfilled, isHexColor, isHslColor, isHslLike, isHslaColor, isInstanceOf, isKey, isNonArrayOrPlainObject, isNonConstructor, isNonEmpty, isNonInstanceOf, isNonKey, isNonNullable, isNonNullableOrEmpty, isNonNullableOrWhitespace, isNonNumber, isNonNumerical, isNonObject, isNonPlainObject, isNonPrimitive, isNonTypedArray, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isOk, isPlainObject, isPrimitive, isRejected, isResult, isRgbColor, isRgbLike, isRgbaColor, isSorted, isTypedArray, join, kebabCase, last, lastIndexOf, lastOrDefault, logger, lowerCase, matchResult, max, median, memoize, merge, min, move, moveIndices, moveToIndex, noop, ok, omit, once, parse, partition, pascalCase, pick, pipe, promises, push, queue, range, registerCloner, registerComparator, registerEqualizer, resultPromises, retry, reverse, rgbToHex, rgbToHsl, rgbToHsla, round, select, setValue, settlePromise, shake, shuffle, single, slice, smush, snakeCase, sort, splice, startsWith, startsWithArray, sum, swap, take, template, throttle, timed, times, titleCase, toMap, toMapArrays, toQuery, toRecord, toRecordArrays, toResult, toSet, toggle, trim, truncate, tryDecode, tryEncode, union, unique, unsmush, unwrap, update, upperCase, words };
|
|
5243
|
+
export { CancelablePromise, PROMISE_ABORT_EVENT, PROMISE_ABORT_OPTIONS, PROMISE_ERROR_NAME, PROMISE_MESSAGE_EXPECTATION_ATTEMPT, PROMISE_MESSAGE_EXPECTATION_RESULT, PROMISE_MESSAGE_EXPECTATION_TIMED, PROMISE_MESSAGE_TIMEOUT, PROMISE_STRATEGY_ALL, PROMISE_STRATEGY_DEFAULT, PROMISE_TYPE_FULFILLED, PROMISE_TYPE_REJECTED, PromiseTimeoutError, QueueError, RetryError, SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING, SizedMap, SizedSet, assert, assertCondition, assertDefined, assertInstanceOf, assertIs, asyncAttempt, asyncDebounce, asyncFlow, asyncMatchResult, asyncOnce, asyncPipe, asyncThrottle, attempt, attemptAsyncFlow, attemptAsyncPipe, attemptFlow, attemptPipe, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, count, debounce, deburr, dedent, delay, deregisterCloner, deregisterComparator, deregisterEqualizer, diff, difference, drop, endsWith, endsWithArray, equal, error, exclude, exists, filter, find, findLast, first, firstOrDefault, flatten, floor, flow, fromQuery, toPromise as fromResult, toPromise, fuzzy, fuzzyMatch, getArray, getArrayPosition, getColor, getError, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getSortedIndex, getString, getTimedPromise, getUuid, getValue, groupArraysBy, groupBy, handleResult, hasValue, hexToHsl, hexToHsla, hexToRgb, hexToRgba, hslToHex, hslToRgb, hslToRgba, ignoreKey, inMap, inSet, includes, includesArray, indexOf, indexOfArray, initializeEqualizer, initializeMerger, initializeNormalizer, initializeSorter, initializeTemplater, insert, intersection, isArrayOrPlainObject, isColor, isConstructor, isEmpty, isError, isFulfilled, isHexColor, isHslColor, isHslLike, isHslaColor, isInstanceOf, isKey, isNonArrayOrPlainObject, isNonConstructor, isNonEmpty, isNonInstanceOf, isNonKey, isNonNullable, isNonNullableOrEmpty, isNonNullableOrWhitespace, isNonNumber, isNonNumerical, isNonObject, isNonPlainObject, isNonPrimitive, isNonTypedArray, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isOk, isPlainObject, isPrimitive, isRejected, isResult, isRgbColor, isRgbLike, isRgbaColor, isSorted, isTypedArray, join, kalas, kebabCase, last, lastIndexOf, lastOrDefault, logger, lowerCase, matchResult, max, median, memoize, merge, min, move, moveIndices, moveToIndex, noop, normalize, ok, omit, once, parse, partition, pascalCase, pick, pipe, promises, push, queue, range, registerCloner, registerComparator, registerEqualizer, resultPromises, retry, reverse, rgbToHex, rgbToHsl, rgbToHsla, round, select, setValue, settlePromise, shake, shuffle, single, slice, smush, snakeCase, sort, splice, startsWith, startsWithArray, sum, swap, take, template, throttle, timed, times, titleCase, toMap, toMapArrays, toQuery, toRecord, toRecordArrays, toResult, toSet, toggle, trim, truncate, tryDecode, tryEncode, union, unique, unsmush, unwrap, update, upperCase, words };
|
package/dist/kalas.d.mts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { GenericCallback } from "./models.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/kalas.d.ts
|
|
4
|
+
declare class Events<Map extends Record<string, GenericCallback>> {
|
|
5
|
+
#private;
|
|
6
|
+
constructor(kalas: Kalas<Map>);
|
|
7
|
+
/**
|
|
8
|
+
* Subscribe to an event with a callback
|
|
9
|
+
* @param event Event name
|
|
10
|
+
* @param callback Callback function
|
|
11
|
+
* @returns Unsubscriber function
|
|
12
|
+
*/
|
|
13
|
+
subscribe<Event extends keyof Map>(event: Event, callback: Map[Event]): Unsubscriber;
|
|
14
|
+
/**
|
|
15
|
+
* Unsubscribe from an event with a callback _(or all callbacks, if no callback is provided)_
|
|
16
|
+
* @param event Event name
|
|
17
|
+
* @param callback Callback function
|
|
18
|
+
* @returns Unsubscriber function
|
|
19
|
+
*/
|
|
20
|
+
unsubscribe<Event extends keyof Map>(event: Event, callback?: Map[Event]): void;
|
|
21
|
+
}
|
|
22
|
+
declare class Kalas<Map extends Record<string, GenericCallback>> {
|
|
23
|
+
#private;
|
|
24
|
+
/**
|
|
25
|
+
* Events interface for subscribing and unsubscribing to events
|
|
26
|
+
*/
|
|
27
|
+
readonly events: Events<Map>;
|
|
28
|
+
constructor(names: (keyof Map)[]);
|
|
29
|
+
/**
|
|
30
|
+
* Remove all event subscribers
|
|
31
|
+
*/
|
|
32
|
+
clear(): void;
|
|
33
|
+
/**
|
|
34
|
+
* Emit an event with parameters
|
|
35
|
+
* @param event Event name
|
|
36
|
+
* @param parameters Event parameters
|
|
37
|
+
*/
|
|
38
|
+
emit<Event extends keyof Map>(event: Event, ...parameters: Parameters<Map[Event]>): void;
|
|
39
|
+
/**
|
|
40
|
+
* Subscribe to an event with a callback
|
|
41
|
+
* @param event Event name
|
|
42
|
+
* @param callback Callback function
|
|
43
|
+
* @returns Unsubscriber function
|
|
44
|
+
*/
|
|
45
|
+
subscribe<Event extends keyof Map>(event: Event, callback: Map[Event]): Unsubscriber;
|
|
46
|
+
/**
|
|
47
|
+
* Unsubscribe from an event with a callback _(or all callbacks, if no callback is provided)_
|
|
48
|
+
* @param event Event name
|
|
49
|
+
* @param callback Callback function
|
|
50
|
+
*/
|
|
51
|
+
unsubscribe<Event extends keyof Map>(event: Event, callback?: Map[Event]): void;
|
|
52
|
+
}
|
|
53
|
+
type Unsubscriber = () => void;
|
|
54
|
+
/**
|
|
55
|
+
* Create a Kalas _(party)_ for named events
|
|
56
|
+
* @param names Event names
|
|
57
|
+
* @returns Kalas instance
|
|
58
|
+
*/
|
|
59
|
+
declare function kalas<Events extends Record<string, GenericCallback>>(names: (keyof Events)[]): Kalas<Events>;
|
|
60
|
+
//#endregion
|
|
61
|
+
export { type Events, type Kalas, Unsubscriber, kalas };
|
package/dist/kalas.mjs
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { noop } from "./internal/function/misc.mjs";
|
|
2
|
+
//#region src/kalas.ts
|
|
3
|
+
var Events = class {
|
|
4
|
+
#kalas;
|
|
5
|
+
constructor(kalas) {
|
|
6
|
+
this.#kalas = kalas;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Subscribe to an event with a callback
|
|
10
|
+
* @param event Event name
|
|
11
|
+
* @param callback Callback function
|
|
12
|
+
* @returns Unsubscriber function
|
|
13
|
+
*/
|
|
14
|
+
subscribe(event, callback) {
|
|
15
|
+
return this.#kalas.subscribe(event, callback);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Unsubscribe from an event with a callback _(or all callbacks, if no callback is provided)_
|
|
19
|
+
* @param event Event name
|
|
20
|
+
* @param callback Callback function
|
|
21
|
+
* @returns Unsubscriber function
|
|
22
|
+
*/
|
|
23
|
+
unsubscribe(event, callback) {
|
|
24
|
+
return this.#kalas.unsubscribe(event, callback);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
var Kalas = class {
|
|
28
|
+
#names;
|
|
29
|
+
#subscribers = /* @__PURE__ */ new Map();
|
|
30
|
+
constructor(names) {
|
|
31
|
+
this.#names = new Set(names);
|
|
32
|
+
Object.defineProperty(this, "events", { value: new Events(this) });
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Remove all event subscribers
|
|
36
|
+
*/
|
|
37
|
+
clear() {
|
|
38
|
+
this.#subscribers.clear();
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Emit an event with parameters
|
|
42
|
+
* @param event Event name
|
|
43
|
+
* @param parameters Event parameters
|
|
44
|
+
*/
|
|
45
|
+
emit(event, ...parameters) {
|
|
46
|
+
const subscribers = this.#subscribers.get(event);
|
|
47
|
+
if (subscribers == null) return;
|
|
48
|
+
for (const callback of subscribers) callback(...parameters);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Subscribe to an event with a callback
|
|
52
|
+
* @param event Event name
|
|
53
|
+
* @param callback Callback function
|
|
54
|
+
* @returns Unsubscriber function
|
|
55
|
+
*/
|
|
56
|
+
subscribe(event, callback) {
|
|
57
|
+
if (!this.#names.has(event) || typeof callback !== "function") return noop;
|
|
58
|
+
let subscribers = this.#subscribers.get(event);
|
|
59
|
+
if (subscribers == null) {
|
|
60
|
+
subscribers = /* @__PURE__ */ new Set();
|
|
61
|
+
this.#subscribers.set(event, subscribers);
|
|
62
|
+
}
|
|
63
|
+
subscribers.add(callback);
|
|
64
|
+
return () => {
|
|
65
|
+
subscribers?.delete(callback);
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Unsubscribe from an event with a callback _(or all callbacks, if no callback is provided)_
|
|
70
|
+
* @param event Event name
|
|
71
|
+
* @param callback Callback function
|
|
72
|
+
*/
|
|
73
|
+
unsubscribe(event, callback) {
|
|
74
|
+
if (!this.#names.has(event) || (callback != null ? typeof callback !== "function" : false)) return;
|
|
75
|
+
const subscribers = this.#subscribers.get(event);
|
|
76
|
+
if (subscribers == null) return;
|
|
77
|
+
if (callback == null) subscribers.clear();
|
|
78
|
+
else subscribers.delete(callback);
|
|
79
|
+
if (callback == null || subscribers.size === 0) this.#subscribers.delete(event);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* Create a Kalas _(party)_ for named events
|
|
84
|
+
* @param names Event names
|
|
85
|
+
* @returns Kalas instance
|
|
86
|
+
*/
|
|
87
|
+
function kalas(names) {
|
|
88
|
+
if (!Array.isArray(names) || names.length === 0 || !names.every((name) => typeof name === "string")) throw new Error(MESSAGE);
|
|
89
|
+
return new Kalas(names);
|
|
90
|
+
}
|
|
91
|
+
const MESSAGE = "Kalas requires an array of event names.";
|
|
92
|
+
//#endregion
|
|
93
|
+
export { kalas };
|
package/dist/string/case.mjs
CHANGED
|
@@ -33,7 +33,9 @@ function kebabCase(value) {
|
|
|
33
33
|
* @returns Lower-cased string
|
|
34
34
|
*/
|
|
35
35
|
function lowerCase(value) {
|
|
36
|
-
|
|
36
|
+
if (typeof value !== "string") return "";
|
|
37
|
+
memoizedLowerCase ??= memoize((v) => v.toLocaleLowerCase());
|
|
38
|
+
return memoizedLowerCase.run(value);
|
|
37
39
|
}
|
|
38
40
|
/**
|
|
39
41
|
* Convert a string to pascal case _(ThisIsPascalCase)_
|
|
@@ -57,8 +59,8 @@ function snakeCase(value) {
|
|
|
57
59
|
* @returns Title-cased string
|
|
58
60
|
*/
|
|
59
61
|
function titleCase(value) {
|
|
60
|
-
if (typeof value !== "string") return "";
|
|
61
|
-
memoizedTitleCase ??= memoize((v) => v.length <
|
|
62
|
+
if (typeof value !== "string" || value.length === 0) return "";
|
|
63
|
+
memoizedTitleCase ??= memoize((v) => v.length < 2 ? capitalize(v) : join(words(v).map(capitalize), " "));
|
|
62
64
|
return memoizedTitleCase.run(value);
|
|
63
65
|
}
|
|
64
66
|
function toCase(type, value, capitalizeAny, capitalizeFirst) {
|
|
@@ -98,7 +100,9 @@ function toCaseCallback(value) {
|
|
|
98
100
|
* @returns Upper-cased string
|
|
99
101
|
*/
|
|
100
102
|
function upperCase(value) {
|
|
101
|
-
|
|
103
|
+
if (typeof value !== "string" || value.length === 0) return "";
|
|
104
|
+
memoizedUpperCase ??= memoize((v) => v.toLocaleUpperCase());
|
|
105
|
+
return memoizedUpperCase.run(value);
|
|
102
106
|
}
|
|
103
107
|
const CASE_CAMEL = "camel";
|
|
104
108
|
const CASE_KEBAB = "kebab";
|
|
@@ -119,6 +123,8 @@ const delimiters = {
|
|
|
119
123
|
[CASE_SNAKE]: DELIMITER_UNDERSCORE
|
|
120
124
|
};
|
|
121
125
|
let memoizedCapitalize;
|
|
126
|
+
let memoizedLowerCase;
|
|
122
127
|
let memoizedTitleCase;
|
|
128
|
+
let memoizedUpperCase;
|
|
123
129
|
//#endregion
|
|
124
130
|
export { camelCase, capitalize, kebabCase, lowerCase, pascalCase, snakeCase, titleCase, upperCase };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
//#region src/string/normalize.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Options for normalizing a string
|
|
4
|
+
*/
|
|
5
|
+
type NormalizeOptions = {
|
|
6
|
+
/**
|
|
7
|
+
* Remove diacritical marks from the string? _(defaults to `true`)_
|
|
8
|
+
*/
|
|
9
|
+
deburr?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Convert the string to lower case? _(defaults to `true`)_
|
|
12
|
+
*/
|
|
13
|
+
lowerCase?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Trim the string? _(defaults to `true`)_
|
|
16
|
+
*/
|
|
17
|
+
trim?: boolean;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* String normalizer function
|
|
21
|
+
*/
|
|
22
|
+
type Normalizer = {
|
|
23
|
+
/**
|
|
24
|
+
* Normalize a string
|
|
25
|
+
* @param value String to normalize
|
|
26
|
+
* @returns Normalized string
|
|
27
|
+
*/
|
|
28
|
+
(value: string): string;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Deburr a string, removing diacritical marks
|
|
32
|
+
* @param value String to deburr
|
|
33
|
+
* @returns Deburred string
|
|
34
|
+
*/
|
|
35
|
+
declare function deburr(value: string): string;
|
|
36
|
+
/**
|
|
37
|
+
* Initialize a string normalizer
|
|
38
|
+
* @param options Normalization options
|
|
39
|
+
* @returns Normalizer function
|
|
40
|
+
*/
|
|
41
|
+
declare function initializeNormalizer(options?: NormalizeOptions): Normalizer;
|
|
42
|
+
/**
|
|
43
|
+
* Normalize a string
|
|
44
|
+
*
|
|
45
|
+
* By default, the string will be trimmed, deburred, and then lowercased
|
|
46
|
+
* @param value String to normalize
|
|
47
|
+
* @param options Normalization options
|
|
48
|
+
* @returns Normalized string
|
|
49
|
+
*/
|
|
50
|
+
declare function normalize(value: string, options?: NormalizeOptions): string;
|
|
51
|
+
declare namespace normalize {
|
|
52
|
+
var initialize: typeof initializeNormalizer;
|
|
53
|
+
}
|
|
54
|
+
//#endregion
|
|
55
|
+
export { NormalizeOptions, Normalizer, deburr, initializeNormalizer, normalize };
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { isPlainObject } from "../internal/is.mjs";
|
|
2
|
+
import { memoize } from "../function/memoize.mjs";
|
|
3
|
+
import { lowerCase } from "./case.mjs";
|
|
4
|
+
//#region src/string/normalize.ts
|
|
5
|
+
/**
|
|
6
|
+
* Deburr a string, removing diacritical marks
|
|
7
|
+
* @param value String to deburr
|
|
8
|
+
* @returns Deburred string
|
|
9
|
+
*/
|
|
10
|
+
function deburr(value) {
|
|
11
|
+
if (typeof value !== "string") return "";
|
|
12
|
+
deburrMemoizer ??= memoize((value) => {
|
|
13
|
+
let deburred = value.normalize(DEBURR_NORMALIZATION).replace(DEBURR_PATTERN_SIMPLE, "");
|
|
14
|
+
deburred = deburred.replace(DEBURR_PATTERN_CHARACTERS, (_, character) => DEBURR_CHARACTERS[character]);
|
|
15
|
+
return deburred;
|
|
16
|
+
});
|
|
17
|
+
return deburrMemoizer.run(value);
|
|
18
|
+
}
|
|
19
|
+
function getNormalizeOptions(input) {
|
|
20
|
+
const options = isPlainObject(input) ? input : {};
|
|
21
|
+
return {
|
|
22
|
+
deburr: options.deburr !== false,
|
|
23
|
+
lowerCase: options.lowerCase !== false,
|
|
24
|
+
trim: options.trim !== false
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Initialize a string normalizer
|
|
29
|
+
* @param options Normalization options
|
|
30
|
+
* @returns Normalizer function
|
|
31
|
+
*/
|
|
32
|
+
function initializeNormalizer(options) {
|
|
33
|
+
const normalization = getNormalizeOptions(options);
|
|
34
|
+
return (value) => normalizeString(value, normalization);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Normalize a string
|
|
38
|
+
*
|
|
39
|
+
* By default, the string will be trimmed, deburred, and then lowercased
|
|
40
|
+
* @param value String to normalize
|
|
41
|
+
* @param options Normalization options
|
|
42
|
+
* @returns Normalized string
|
|
43
|
+
*/
|
|
44
|
+
function normalize(value, options) {
|
|
45
|
+
return normalizeString(value, getNormalizeOptions(options));
|
|
46
|
+
}
|
|
47
|
+
normalize.initialize = initializeNormalizer;
|
|
48
|
+
function normalizeString(value, options) {
|
|
49
|
+
if (typeof value !== "string") return "";
|
|
50
|
+
let result = value;
|
|
51
|
+
if (options.trim) result = result.trim();
|
|
52
|
+
if (options.deburr) result = deburr(result);
|
|
53
|
+
if (options.lowerCase) result = lowerCase(result);
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
const DEBURR_CHARACTERS = {
|
|
57
|
+
Æ: "AE",
|
|
58
|
+
æ: "ae",
|
|
59
|
+
Ð: "D",
|
|
60
|
+
ð: "d",
|
|
61
|
+
Đ: "D",
|
|
62
|
+
đ: "d",
|
|
63
|
+
Ħ: "H",
|
|
64
|
+
ħ: "h",
|
|
65
|
+
IJ: "IJ",
|
|
66
|
+
ij: "ij",
|
|
67
|
+
İ: "I",
|
|
68
|
+
ı: "i",
|
|
69
|
+
ĸ: "k",
|
|
70
|
+
Ŀ: "L",
|
|
71
|
+
ŀ: "l",
|
|
72
|
+
Ł: "L",
|
|
73
|
+
ł: "l",
|
|
74
|
+
Ŋ: "N",
|
|
75
|
+
ŋ: "n",
|
|
76
|
+
ʼn: "'n",
|
|
77
|
+
Œ: "OE",
|
|
78
|
+
œ: "oe",
|
|
79
|
+
Ø: "O",
|
|
80
|
+
ø: "o",
|
|
81
|
+
ſ: "s",
|
|
82
|
+
ß: "ss",
|
|
83
|
+
Þ: "TH",
|
|
84
|
+
þ: "th",
|
|
85
|
+
Ŧ: "T",
|
|
86
|
+
ŧ: "t"
|
|
87
|
+
};
|
|
88
|
+
const DEBURR_NORMALIZATION = "NFD";
|
|
89
|
+
const DEBURR_PATTERN_CHARACTERS = new RegExp(`(${Object.keys(DEBURR_CHARACTERS).join("|")})`, "g");
|
|
90
|
+
const DEBURR_PATTERN_SIMPLE = /[\u0300-\u036f]/g;
|
|
91
|
+
let deburrMemoizer;
|
|
92
|
+
//#endregion
|
|
93
|
+
export { deburr, initializeNormalizer, normalize };
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -25,10 +25,13 @@ export * from './internal/value/get';
|
|
|
25
25
|
export * from './internal/value/has';
|
|
26
26
|
export * from './internal/value/set';
|
|
27
27
|
|
|
28
|
+
export * from './kalas';
|
|
29
|
+
|
|
28
30
|
export * from './string/case';
|
|
29
31
|
export * from './string/fuzzy';
|
|
30
32
|
export * from './string/index';
|
|
31
33
|
export * from './string/match';
|
|
34
|
+
export * from './string/normalize';
|
|
32
35
|
export * from './string/template';
|
|
33
36
|
|
|
34
37
|
export * from './value/clone';
|
package/src/kalas.ts
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import {noop} from './internal/function/misc';
|
|
2
|
+
import type {GenericCallback} from './models';
|
|
3
|
+
|
|
4
|
+
// #region Types
|
|
5
|
+
|
|
6
|
+
class Events<Map extends Record<string, GenericCallback>> {
|
|
7
|
+
readonly #kalas: Kalas<Map>;
|
|
8
|
+
|
|
9
|
+
constructor(kalas: Kalas<Map>) {
|
|
10
|
+
this.#kalas = kalas;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Subscribe to an event with a callback
|
|
15
|
+
* @param event Event name
|
|
16
|
+
* @param callback Callback function
|
|
17
|
+
* @returns Unsubscriber function
|
|
18
|
+
*/
|
|
19
|
+
subscribe<Event extends keyof Map>(event: Event, callback: Map[Event]): Unsubscriber {
|
|
20
|
+
return this.#kalas.subscribe(event, callback);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Unsubscribe from an event with a callback _(or all callbacks, if no callback is provided)_
|
|
25
|
+
* @param event Event name
|
|
26
|
+
* @param callback Callback function
|
|
27
|
+
* @returns Unsubscriber function
|
|
28
|
+
*/
|
|
29
|
+
unsubscribe<Event extends keyof Map>(event: Event, callback?: Map[Event]): void {
|
|
30
|
+
return this.#kalas.unsubscribe(event, callback);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
class Kalas<Map extends Record<string, GenericCallback>> {
|
|
35
|
+
readonly #names: Set<keyof Map>;
|
|
36
|
+
|
|
37
|
+
readonly #subscribers = new Map<keyof Map, Set<Map[keyof Map]>>();
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Events interface for subscribing and unsubscribing to events
|
|
41
|
+
*/
|
|
42
|
+
declare readonly events: Events<Map>;
|
|
43
|
+
|
|
44
|
+
constructor(names: (keyof Map)[]) {
|
|
45
|
+
this.#names = new Set(names);
|
|
46
|
+
|
|
47
|
+
Object.defineProperty(this, 'events', {
|
|
48
|
+
value: new Events(this),
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Remove all event subscribers
|
|
54
|
+
*/
|
|
55
|
+
clear(): void {
|
|
56
|
+
this.#subscribers.clear();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Emit an event with parameters
|
|
61
|
+
* @param event Event name
|
|
62
|
+
* @param parameters Event parameters
|
|
63
|
+
*/
|
|
64
|
+
emit<Event extends keyof Map>(event: Event, ...parameters: Parameters<Map[Event]>) {
|
|
65
|
+
const subscribers = this.#subscribers.get(event);
|
|
66
|
+
|
|
67
|
+
if (subscribers == null) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
for (const callback of subscribers) {
|
|
72
|
+
callback(...parameters);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Subscribe to an event with a callback
|
|
78
|
+
* @param event Event name
|
|
79
|
+
* @param callback Callback function
|
|
80
|
+
* @returns Unsubscriber function
|
|
81
|
+
*/
|
|
82
|
+
subscribe<Event extends keyof Map>(event: Event, callback: Map[Event]): Unsubscriber {
|
|
83
|
+
if (!this.#names.has(event) || typeof callback !== 'function') {
|
|
84
|
+
return noop;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
let subscribers = this.#subscribers.get(event);
|
|
88
|
+
|
|
89
|
+
if (subscribers == null) {
|
|
90
|
+
subscribers = new Set();
|
|
91
|
+
|
|
92
|
+
this.#subscribers.set(event, subscribers);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
subscribers.add(callback);
|
|
96
|
+
|
|
97
|
+
return () => {
|
|
98
|
+
subscribers?.delete(callback);
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Unsubscribe from an event with a callback _(or all callbacks, if no callback is provided)_
|
|
104
|
+
* @param event Event name
|
|
105
|
+
* @param callback Callback function
|
|
106
|
+
*/
|
|
107
|
+
unsubscribe<Event extends keyof Map>(event: Event, callback?: Map[Event]): void {
|
|
108
|
+
if (!this.#names.has(event) || (callback != null ? typeof callback !== 'function' : false)) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const subscribers = this.#subscribers.get(event);
|
|
113
|
+
|
|
114
|
+
if (subscribers == null) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (callback == null) {
|
|
119
|
+
subscribers.clear();
|
|
120
|
+
} else {
|
|
121
|
+
subscribers.delete(callback);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (callback == null || subscribers.size === 0) {
|
|
125
|
+
this.#subscribers.delete(event);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export type Unsubscriber = () => void;
|
|
131
|
+
|
|
132
|
+
// #endregion
|
|
133
|
+
|
|
134
|
+
// #region Functions
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Create a Kalas _(party)_ for named events
|
|
138
|
+
* @param names Event names
|
|
139
|
+
* @returns Kalas instance
|
|
140
|
+
*/
|
|
141
|
+
export function kalas<Events extends Record<string, GenericCallback>>(
|
|
142
|
+
names: (keyof Events)[],
|
|
143
|
+
): Kalas<Events> {
|
|
144
|
+
if (
|
|
145
|
+
!Array.isArray(names) ||
|
|
146
|
+
names.length === 0 ||
|
|
147
|
+
!names.every(name => typeof name === 'string')
|
|
148
|
+
) {
|
|
149
|
+
throw new Error(MESSAGE);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return new Kalas<Events>(names);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// #endregion
|
|
156
|
+
|
|
157
|
+
// #region Variables
|
|
158
|
+
|
|
159
|
+
const MESSAGE = 'Kalas requires an array of event names.';
|
|
160
|
+
|
|
161
|
+
// #endregion
|
|
162
|
+
|
|
163
|
+
// #region Exports
|
|
164
|
+
|
|
165
|
+
export {type Events, type Kalas};
|
|
166
|
+
|
|
167
|
+
// #endregion
|
package/src/string/case.ts
CHANGED
|
@@ -58,7 +58,13 @@ export function kebabCase(value: string): string {
|
|
|
58
58
|
* @returns Lower-cased string
|
|
59
59
|
*/
|
|
60
60
|
export function lowerCase(value: string): string {
|
|
61
|
-
|
|
61
|
+
if (typeof value !== 'string') {
|
|
62
|
+
return '';
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
memoizedLowerCase ??= memoize(v => v.toLocaleLowerCase());
|
|
66
|
+
|
|
67
|
+
return memoizedLowerCase.run(value);
|
|
62
68
|
}
|
|
63
69
|
|
|
64
70
|
/**
|
|
@@ -85,12 +91,12 @@ export function snakeCase(value: string): string {
|
|
|
85
91
|
* @returns Title-cased string
|
|
86
92
|
*/
|
|
87
93
|
export function titleCase(value: string): string {
|
|
88
|
-
if (typeof value !== 'string') {
|
|
94
|
+
if (typeof value !== 'string' || value.length === 0) {
|
|
89
95
|
return '';
|
|
90
96
|
}
|
|
91
97
|
|
|
92
98
|
memoizedTitleCase ??= memoize(v =>
|
|
93
|
-
v.length <
|
|
99
|
+
v.length < 2 ? capitalize(v) : join(words(v).map(capitalize), ' '),
|
|
94
100
|
);
|
|
95
101
|
|
|
96
102
|
return memoizedTitleCase.run(value);
|
|
@@ -167,7 +173,13 @@ function toCaseCallback(this: Options, value: string): string {
|
|
|
167
173
|
* @returns Upper-cased string
|
|
168
174
|
*/
|
|
169
175
|
export function upperCase(value: string): string {
|
|
170
|
-
|
|
176
|
+
if (typeof value !== 'string' || value.length === 0) {
|
|
177
|
+
return '';
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
memoizedUpperCase ??= memoize(v => v.toLocaleUpperCase());
|
|
181
|
+
|
|
182
|
+
return memoizedUpperCase.run(value);
|
|
171
183
|
}
|
|
172
184
|
|
|
173
185
|
// #endregion
|
|
@@ -207,6 +219,10 @@ const delimiters: Record<Case, string> = {
|
|
|
207
219
|
|
|
208
220
|
let memoizedCapitalize: Memoized<(value: string) => string>;
|
|
209
221
|
|
|
222
|
+
let memoizedLowerCase: Memoized<(value: string) => string>;
|
|
223
|
+
|
|
210
224
|
let memoizedTitleCase: Memoized<(value: string) => string>;
|
|
211
225
|
|
|
226
|
+
let memoizedUpperCase: Memoized<(value: string) => string>;
|
|
227
|
+
|
|
212
228
|
// #endregion
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import {memoize, type Memoized} from '../function/memoize';
|
|
2
|
+
import {isPlainObject} from '../internal/is';
|
|
3
|
+
import {lowerCase} from './case';
|
|
4
|
+
|
|
5
|
+
// #region Types
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Options for normalizing a string
|
|
9
|
+
*/
|
|
10
|
+
export type NormalizeOptions = {
|
|
11
|
+
/**
|
|
12
|
+
* Remove diacritical marks from the string? _(defaults to `true`)_
|
|
13
|
+
*/
|
|
14
|
+
deburr?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Convert the string to lower case? _(defaults to `true`)_
|
|
17
|
+
*/
|
|
18
|
+
lowerCase?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Trim the string? _(defaults to `true`)_
|
|
21
|
+
*/
|
|
22
|
+
trim?: boolean;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* String normalizer function
|
|
27
|
+
*/
|
|
28
|
+
export type Normalizer = {
|
|
29
|
+
/**
|
|
30
|
+
* Normalize a string
|
|
31
|
+
* @param value String to normalize
|
|
32
|
+
* @returns Normalized string
|
|
33
|
+
*/
|
|
34
|
+
(value: string): string;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
type Options = Required<NormalizeOptions>;
|
|
38
|
+
|
|
39
|
+
// #endregion
|
|
40
|
+
|
|
41
|
+
// #region Functions
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Deburr a string, removing diacritical marks
|
|
45
|
+
* @param value String to deburr
|
|
46
|
+
* @returns Deburred string
|
|
47
|
+
*/
|
|
48
|
+
export function deburr(value: string): string {
|
|
49
|
+
if (typeof value !== 'string') {
|
|
50
|
+
return '';
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
deburrMemoizer ??= memoize(value => {
|
|
54
|
+
let deburred = value.normalize(DEBURR_NORMALIZATION).replace(DEBURR_PATTERN_SIMPLE, '');
|
|
55
|
+
|
|
56
|
+
deburred = deburred.replace(
|
|
57
|
+
DEBURR_PATTERN_CHARACTERS,
|
|
58
|
+
(_, character) => DEBURR_CHARACTERS[character as keyof typeof DEBURR_CHARACTERS],
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
return deburred;
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
return deburrMemoizer.run(value);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function getNormalizeOptions(input?: NormalizeOptions): Options {
|
|
68
|
+
const options = isPlainObject(input) ? input : {};
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
deburr: options.deburr !== false,
|
|
72
|
+
lowerCase: options.lowerCase !== false,
|
|
73
|
+
trim: options.trim !== false,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Initialize a string normalizer
|
|
79
|
+
* @param options Normalization options
|
|
80
|
+
* @returns Normalizer function
|
|
81
|
+
*/
|
|
82
|
+
export function initializeNormalizer(options?: NormalizeOptions): Normalizer {
|
|
83
|
+
const normalization = getNormalizeOptions(options);
|
|
84
|
+
|
|
85
|
+
return (value: string) => normalizeString(value, normalization);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Normalize a string
|
|
90
|
+
*
|
|
91
|
+
* By default, the string will be trimmed, deburred, and then lowercased
|
|
92
|
+
* @param value String to normalize
|
|
93
|
+
* @param options Normalization options
|
|
94
|
+
* @returns Normalized string
|
|
95
|
+
*/
|
|
96
|
+
export function normalize(value: string, options?: NormalizeOptions): string {
|
|
97
|
+
return normalizeString(value, getNormalizeOptions(options));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
normalize.initialize = initializeNormalizer;
|
|
101
|
+
|
|
102
|
+
function normalizeString(value: string, options: Options): string {
|
|
103
|
+
if (typeof value !== 'string') {
|
|
104
|
+
return '';
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
let result = value;
|
|
108
|
+
|
|
109
|
+
if (options.trim) {
|
|
110
|
+
result = result.trim();
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (options.deburr) {
|
|
114
|
+
result = deburr(result);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (options.lowerCase) {
|
|
118
|
+
result = lowerCase(result);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// #endregion
|
|
125
|
+
|
|
126
|
+
// #region Variables
|
|
127
|
+
|
|
128
|
+
const DEBURR_CHARACTERS = {
|
|
129
|
+
Æ: 'AE',
|
|
130
|
+
æ: 'ae',
|
|
131
|
+
Ð: 'D',
|
|
132
|
+
ð: 'd',
|
|
133
|
+
Đ: 'D',
|
|
134
|
+
đ: 'd',
|
|
135
|
+
Ħ: 'H',
|
|
136
|
+
ħ: 'h',
|
|
137
|
+
IJ: 'IJ',
|
|
138
|
+
ij: 'ij',
|
|
139
|
+
İ: 'I',
|
|
140
|
+
ı: 'i',
|
|
141
|
+
ĸ: 'k',
|
|
142
|
+
Ŀ: 'L',
|
|
143
|
+
ŀ: 'l',
|
|
144
|
+
Ł: 'L',
|
|
145
|
+
ł: 'l',
|
|
146
|
+
Ŋ: 'N',
|
|
147
|
+
ŋ: 'n',
|
|
148
|
+
ʼn: "'n",
|
|
149
|
+
Œ: 'OE',
|
|
150
|
+
œ: 'oe',
|
|
151
|
+
Ø: 'O',
|
|
152
|
+
ø: 'o',
|
|
153
|
+
ſ: 's',
|
|
154
|
+
ß: 'ss',
|
|
155
|
+
Þ: 'TH',
|
|
156
|
+
þ: 'th',
|
|
157
|
+
Ŧ: 'T',
|
|
158
|
+
ŧ: 't',
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
const DEBURR_NORMALIZATION = 'NFD';
|
|
162
|
+
|
|
163
|
+
const DEBURR_PATTERN_CHARACTERS = new RegExp(`(${Object.keys(DEBURR_CHARACTERS).join('|')})`, 'g');
|
|
164
|
+
|
|
165
|
+
const DEBURR_PATTERN_SIMPLE = /[\u0300-\u036f]/g;
|
|
166
|
+
|
|
167
|
+
let deburrMemoizer: Memoized<typeof deburr>;
|
|
168
|
+
|
|
169
|
+
// #endregion
|