@sv443-network/userutils 8.3.3 → 9.0.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/lib/dom.d.ts CHANGED
@@ -1,73 +1,74 @@
1
1
  /**
2
- * Returns `unsafeWindow` if the `@grant unsafeWindow` is given, otherwise falls back to the regular `window`
2
+ * Returns `unsafeWindow` if the `@grant unsafeWindow` is given, otherwise falls back to the regular `window`
3
3
  */
4
4
  export declare function getUnsafeWindow(): Window;
5
5
  /**
6
- * Adds a parent container around the provided element
7
- * @returns Returns the new parent element
6
+ * Adds a parent container around the provided element
7
+ * @returns Returns the new parent element
8
8
  */
9
9
  export declare function addParent<TElem extends Element, TParentElem extends Element>(element: TElem, newParent: TParentElem): TParentElem;
10
10
  /**
11
- * Adds global CSS style in the form of a `<style>` element in the document's `<head>`
12
- * This needs to be run after the `DOMContentLoaded` event has fired on the document object (or instantly if `@run-at document-end` is used).
13
- * @param style CSS string
14
- * @returns Returns the created style element
11
+ * Adds global CSS style in the form of a `<style>` element in the document's `<head>`
12
+ * This needs to be run after the `DOMContentLoaded` event has fired on the document object (or instantly if `@run-at document-end` is used).
13
+ * @param style CSS string
14
+ * @returns Returns the created style element
15
15
  */
16
16
  export declare function addGlobalStyle(style: string): HTMLStyleElement;
17
17
  /**
18
- * Preloads an array of image URLs so they can be loaded instantly from the browser cache later on
19
- * @param rejects If set to `true`, the returned PromiseSettledResults will contain rejections for any of the images that failed to load
20
- * @returns Returns an array of `PromiseSettledResult` - each resolved result will contain the loaded image element, while each rejected result will contain an `ErrorEvent`
18
+ * Preloads an array of image URLs so they can be loaded instantly from the browser cache later on
19
+ * @param rejects If set to `true`, the returned PromiseSettledResults will contain rejections for any of the images that failed to load
20
+ * @returns Returns an array of `PromiseSettledResult` - each resolved result will contain the loaded image element, while each rejected result will contain an `ErrorEvent`
21
21
  */
22
22
  export declare function preloadImages(srcUrls: string[], rejects?: boolean): Promise<PromiseSettledResult<HTMLImageElement>[]>;
23
23
  /**
24
- * Tries to use `GM.openInTab` to open the given URL in a new tab, otherwise if the grant is not given, creates an invisible anchor element and clicks it.
25
- * For the fallback to work, this function needs to be run in response to a user interaction event, else the browser might reject it.
26
- * @param href The URL to open in a new tab
27
- * @param background If set to `true`, the tab will be opened in the background - set to `undefined` (default) to use the browser's default behavior
24
+ * Tries to use `GM.openInTab` to open the given URL in a new tab, otherwise if the grant is not given, creates an invisible anchor element and clicks it.
25
+ * For the fallback to work, this function needs to be run in response to a user interaction event, else the browser might reject it.
26
+ * @param href The URL to open in a new tab
27
+ * @param background If set to `true`, the tab will be opened in the background - set to `undefined` (default) to use the browser's default behavior
28
+ * @param additionalProps Additional properties to set on the anchor element (only applies when `GM.openInTab` is not available)
28
29
  */
29
- export declare function openInNewTab(href: string, background?: boolean): void;
30
+ export declare function openInNewTab(href: string, background?: boolean, additionalProps?: Partial<HTMLAnchorElement>): void;
30
31
  /**
31
- * Intercepts the specified event on the passed object and prevents it from being called if the called {@linkcode predicate} function returns a truthy value.
32
- * If no predicate is specified, all events will be discarded.
33
- * This function should be called as soon as possible (I recommend using `@run-at document-start`), as it will only intercept events that are added after this function is called.
34
- * Calling this function will set `Error.stackTraceLimit = 100` (if not already higher) to ensure the stack trace is preserved.
32
+ * Intercepts the specified event on the passed object and prevents it from being called if the called {@linkcode predicate} function returns a truthy value.
33
+ * If no predicate is specified, all events will be discarded.
34
+ * This function should be called as soon as possible (I recommend using `@run-at document-start`), as it will only intercept events that are added after this function is called.
35
+ * Calling this function will set `Error.stackTraceLimit = 100` (if not already higher) to ensure the stack trace is preserved.
35
36
  */
36
37
  export declare function interceptEvent<TEvtObj extends EventTarget, TPredicateEvt extends Event>(eventObject: TEvtObj, eventName: Parameters<TEvtObj["addEventListener"]>[0], predicate?: (event: TPredicateEvt) => boolean): void;
37
38
  /**
38
- * Intercepts the specified event on the window object and prevents it from being called if the called {@linkcode predicate} function returns a truthy value.
39
- * If no predicate is specified, all events will be discarded.
40
- * This function should be called as soon as possible (I recommend using `@run-at document-start`), as it will only intercept events that are added after this function is called.
41
- * Calling this function will set `Error.stackTraceLimit = 100` (if not already higher) to ensure the stack trace is preserved.
39
+ * Intercepts the specified event on the window object and prevents it from being called if the called {@linkcode predicate} function returns a truthy value.
40
+ * If no predicate is specified, all events will be discarded.
41
+ * This function should be called as soon as possible (I recommend using `@run-at document-start`), as it will only intercept events that are added after this function is called.
42
+ * Calling this function will set `Error.stackTraceLimit = 100` (if not already higher) to ensure the stack trace is preserved.
42
43
  */
43
44
  export declare function interceptWindowEvent<TEvtKey extends keyof WindowEventMap>(eventName: TEvtKey, predicate?: (event: WindowEventMap[TEvtKey]) => boolean): void;
44
45
  /** Checks if an element is scrollable in the horizontal and vertical directions */
45
46
  export declare function isScrollable(element: Element): Record<"vertical" | "horizontal", boolean>;
46
47
  /**
47
- * Executes the callback when the passed element's property changes.
48
- * Contrary to an element's attributes, properties can usually not be observed with a MutationObserver.
49
- * This function shims the getter and setter of the property to invoke the callback.
50
- *
51
- * [Source](https://stackoverflow.com/a/61975440)
52
- * @param property The name of the property to observe
53
- * @param callback Callback to execute when the value is changed
48
+ * Executes the callback when the passed element's property changes.
49
+ * Contrary to an element's attributes, properties can usually not be observed with a MutationObserver.
50
+ * This function shims the getter and setter of the property to invoke the callback.
51
+ *
52
+ * [Source](https://stackoverflow.com/a/61975440)
53
+ * @param property The name of the property to observe
54
+ * @param callback Callback to execute when the value is changed
54
55
  */
55
56
  export declare function observeElementProp<TElem extends Element = HTMLElement, TPropKey extends keyof TElem = keyof TElem>(element: TElem, property: TPropKey, callback: (oldVal: TElem[TPropKey], newVal: TElem[TPropKey]) => void): void;
56
57
  /**
57
- * Returns a "frame" of the closest siblings of the {@linkcode refElement}, based on the passed amount of siblings and {@linkcode refElementAlignment}
58
- * @param refElement The reference element to return the relative closest siblings from
59
- * @param siblingAmount The amount of siblings to return
60
- * @param refElementAlignment Can be set to `center-top` (default), `center-bottom`, `top`, or `bottom`, which will determine where the relative location of the provided {@linkcode refElement} is in the returned array
61
- * @param includeRef If set to `true` (default), the provided {@linkcode refElement} will be included in the returned array at the corresponding position
62
- * @template TSibling The type of the sibling elements that are returned
63
- * @returns An array of sibling elements
58
+ * Returns a "frame" of the closest siblings of the {@linkcode refElement}, based on the passed amount of siblings and {@linkcode refElementAlignment}
59
+ * @param refElement The reference element to return the relative closest siblings from
60
+ * @param siblingAmount The amount of siblings to return
61
+ * @param refElementAlignment Can be set to `center-top` (default), `center-bottom`, `top`, or `bottom`, which will determine where the relative location of the provided {@linkcode refElement} is in the returned array
62
+ * @param includeRef If set to `true` (default), the provided {@linkcode refElement} will be included in the returned array at the corresponding position
63
+ * @template TSibling The type of the sibling elements that are returned
64
+ * @returns An array of sibling elements
64
65
  */
65
66
  export declare function getSiblingsFrame<TSibling extends Element = HTMLElement>(refElement: Element, siblingAmount: number, refElementAlignment?: "center-top" | "center-bottom" | "top" | "bottom", includeRef?: boolean): TSibling[];
66
67
  /**
67
- * Sets the innerHTML property of the provided element without any sanitation or validation.
68
- * Uses a [Trusted Types policy](https://developer.mozilla.org/en-US/docs/Web/API/Trusted_Types_API) on Chromium-based browsers to trick the browser into thinking the HTML is safe.
69
- * Use this if the page makes use of the CSP directive `require-trusted-types-for 'script'` and throws a "This document requires 'TrustedHTML' assignment" error on Chromium-based browsers.
70
- *
71
- * ⚠️ This function does not perform any sanitization and should thus be used with utmost caution, as it can easily lead to XSS vulnerabilities!
68
+ * Sets the innerHTML property of the provided element without any sanitation or validation.
69
+ * Uses a [Trusted Types policy](https://developer.mozilla.org/en-US/docs/Web/API/Trusted_Types_API) on Chromium-based browsers to trick the browser into thinking the HTML is safe.
70
+ * Use this if the page makes use of the CSP directive `require-trusted-types-for 'script'` and throws a "This document requires 'TrustedHTML' assignment" error on Chromium-based browsers.
71
+ *
72
+ * - ⚠️ This function does not perform any sanitization and should thus be used with utmost caution, as it can easily lead to XSS vulnerabilities!
72
73
  */
73
74
  export declare function setInnerHtmlUnsafe<TElement extends Element = HTMLElement>(element: TElement, html: string): TElement;
@@ -3,6 +3,7 @@ export * from "./colors.js";
3
3
  export * from "./crypto.js";
4
4
  export * from "./DataStore.js";
5
5
  export * from "./DataStoreSerializer.js";
6
+ export * from "./Debouncer.js";
6
7
  export * from "./Dialog.js";
7
8
  export * from "./dom.js";
8
9
  export * from "./math.js";
@@ -1,22 +1,27 @@
1
+ import type { Stringifiable } from "./types.js";
1
2
  /** Ensures the passed {@linkcode value} always stays between {@linkcode min} and {@linkcode max} */
2
3
  export declare function clamp(value: number, min: number, max: number): number;
4
+ /** Ensures the passed {@linkcode value} always stays between 0 and {@linkcode max} */
5
+ export declare function clamp(value: number, max: number): number;
3
6
  /**
4
- * Transforms the value parameter from the numerical range `range1min` to `range1max` to the numerical range `range2min` to `range2max`
5
- * For example, you can map the value 2 in the range of 0-5 to the range of 0-10 and you'd get a 4 as a result.
7
+ * Transforms the value parameter from the numerical range `range1min` to `range1max` to the numerical range `range2min` to `range2max`
8
+ * For example, you can map the value 2 in the range of 0-5 to the range of 0-10 and you'd get a 4 as a result.
6
9
  */
7
10
  export declare function mapRange(value: number, range1min: number, range1max: number, range2min: number, range2max: number): number;
8
11
  /**
9
- * Transforms the value parameter from the numerical range `0` to `range1max` to the numerical range `0` to `range2max`
10
- * For example, you can map the value 2 in the range of 0-5 to the range of 0-10 and you'd get a 4 as a result.
12
+ * Transforms the value parameter from the numerical range `0` to `range1max` to the numerical range `0` to `range2max`
13
+ * For example, you can map the value 2 in the range of 0-5 to the range of 0-10 and you'd get a 4 as a result.
11
14
  */
12
15
  export declare function mapRange(value: number, range1max: number, range2max: number): number;
13
16
  /**
14
- * Returns a random number between {@linkcode min} and {@linkcode max} (inclusive)
15
- * Set {@linkcode enhancedEntropy} to true to use `crypto.getRandomValues()` for better cryptographic randomness (this also makes it take longer to generate)
17
+ * Returns a random number between {@linkcode min} and {@linkcode max} (inclusive)
18
+ * Set {@linkcode enhancedEntropy} to true to use `crypto.getRandomValues()` for better cryptographic randomness (this also makes it take longer to generate)
16
19
  */
17
20
  export declare function randRange(min: number, max: number, enhancedEntropy?: boolean): number;
18
21
  /**
19
- * Returns a random number between 0 and {@linkcode max} (inclusive)
20
- * Set {@linkcode enhancedEntropy} to true to use `crypto.getRandomValues()` for better cryptographic randomness (this also makes it take longer to generate)
22
+ * Returns a random number between 0 and {@linkcode max} (inclusive)
23
+ * Set {@linkcode enhancedEntropy} to true to use `crypto.getRandomValues()` for better cryptographic randomness (this also makes it take longer to generate)
21
24
  */
22
25
  export declare function randRange(max: number, enhancedEntropy?: boolean): number;
26
+ /** Calculates the amount of digits in the given number - the given number or string will be passed to the `Number()` constructor. Returns NaN if the number is invalid. */
27
+ export declare function digitCount(num: number | Stringifiable): number;
@@ -1,32 +1,44 @@
1
1
  import type { Prettify, Stringifiable } from "./types.js";
2
2
  /**
3
- * Automatically appends an `s` to the passed {@linkcode word}, if {@linkcode num} is not equal to 1
4
- * @param word A word in singular form, to auto-convert to plural
5
- * @param num If this is an array or NodeList, the amount of items is used
3
+ * Automatically appends an `s` to the passed {@linkcode word}, if {@linkcode num} is not equal to 1
4
+ * @param word A word in singular form, to auto-convert to plural
5
+ * @param num If this is an array or NodeList, the amount of items is used
6
6
  */
7
7
  export declare function autoPlural(word: Stringifiable, num: number | unknown[] | NodeList): string;
8
8
  /**
9
- * Inserts the passed values into a string at the respective placeholders.
10
- * The placeholder format is `%n`, where `n` is the 1-indexed argument number.
11
- * @param input The string to insert the values into
12
- * @param values The values to insert, in order, starting at `%1`
9
+ * Inserts the passed values into a string at the respective placeholders.
10
+ * The placeholder format is `%n`, where `n` is the 1-indexed argument number.
11
+ * @param input The string to insert the values into
12
+ * @param values The values to insert, in order, starting at `%1`
13
13
  */
14
14
  export declare function insertValues(input: string, ...values: Stringifiable[]): string;
15
15
  /** Pauses async execution for the specified time in ms */
16
16
  export declare function pauseFor(time: number): Promise<void>;
17
- /**
18
- * Calls the passed {@linkcode func} after the specified {@linkcode timeout} in ms (defaults to 300).
19
- * Any subsequent calls to this function will reset the timer and discard all previous calls.
20
- * @param func The function to call after the timeout
21
- * @param timeout The time in ms to wait before calling the function
22
- * @param edge Whether to call the function at the very first call ("rising" edge) or the very last call ("falling" edge, default)
23
- */
24
- export declare function debounce<TFunc extends (...args: TArgs[]) => void, // eslint-disable-next-line @typescript-eslint/no-explicit-any
25
- TArgs = any>(func: TFunc, timeout?: number, edge?: "rising" | "falling"): (...args: TArgs[]) => void;
26
17
  /** Options for the `fetchAdvanced()` function */
27
18
  export type FetchAdvancedOpts = Prettify<Partial<{
28
19
  /** Timeout in milliseconds after which the fetch call will be canceled with an AbortController signal */
29
20
  timeout: number;
30
21
  }> & RequestInit>;
31
22
  /** Calls the fetch API with special options like a timeout */
32
- export declare function fetchAdvanced(input: RequestInfo | URL, options?: FetchAdvancedOpts): Promise<Response>;
23
+ export declare function fetchAdvanced(input: string | RequestInfo | URL, options?: FetchAdvancedOpts): Promise<Response>;
24
+ /**
25
+ * A ValueGen value is either its type, a promise that resolves to its type, or a function that returns its type, either synchronous or asynchronous.
26
+ * ValueGen allows for the utmost flexibility when applied to any type, as long as {@linkcode consumeGen()} is used to get the final value.
27
+ * @template TValueType The type of the value that the ValueGen should yield
28
+ */
29
+ export type ValueGen<TValueType> = TValueType | Promise<TValueType> | (() => TValueType | Promise<TValueType>);
30
+ /**
31
+ * Turns a {@linkcode ValueGen} into its final value.
32
+ * @template TValueType The type of the value that the ValueGen should yield
33
+ */
34
+ export declare function consumeGen<TValueType>(valGen: ValueGen<TValueType>): Promise<TValueType>;
35
+ /**
36
+ * A StringGen value is either a string, anything that can be converted to a string, or a function that returns one of the previous two, either synchronous or asynchronous, or a promise that returns a string.
37
+ * StringGen allows for the utmost flexibility when dealing with strings, as long as {@linkcode consumeStringGen()} is used to get the final string.
38
+ */
39
+ export type StringGen = ValueGen<Stringifiable>;
40
+ /**
41
+ * Turns a {@linkcode StringGen} into its final string value.
42
+ * @template TStrUnion The union of strings that the StringGen should yield - this allows for finer type control compared to {@linkcode consumeGen()}
43
+ */
44
+ export declare function consumeStringGen<TStrUnion extends string>(strGen: StringGen): Promise<TStrUnion>;
@@ -1,19 +1,145 @@
1
1
  import type { Stringifiable } from "./types.js";
2
2
  /**
3
- * Returns the translated text for the specified key in the current language set by {@linkcode tr.setLanguage()}
4
- * Use {@linkcode tr.forLang()} to get the translation for a specific language instead of the currently set one.
5
- * If the key is not found in the currently set language, the key itself is returned.
6
- *
7
- * ⚠️ Remember to register a language with {@linkcode tr.addLanguage()} and set it as active with {@linkcode tr.setLanguage()} before using this function, otherwise it will always return the key itself.
8
- * @param key Key of the translation to return
9
- * @param args Optional arguments to be passed to the translated text. They will replace placeholders in the format `%n`, where `n` is the 1-indexed argument number
3
+ * Translation object to pass to {@linkcode tr.addTranslations()}
4
+ * Can be a flat object of identifier keys and the translation text as the value, or an infinitely nestable object containing the same.
5
+ *
6
+ * @example
7
+ * // Flat object:
8
+ * const tr_en: TrObject = {
9
+ * hello: "Hello, %1!",
10
+ * foo: "Foo",
11
+ * };
12
+ *
13
+ * // Nested object:
14
+ * const tr_de: TrObject = {
15
+ * hello: "Hallo, %1!",
16
+ * foo: {
17
+ * bar: "Foo bar",
18
+ * },
19
+ * };
10
20
  */
11
- declare function tr(key: string, ...args: Stringifiable[]): string;
12
- declare namespace tr {
13
- var forLang: (language: string, key: string, ...args: Stringifiable[]) => string;
14
- var addLanguage: (language: string, translations: Record<string, string>) => void;
15
- var setLanguage: (language: string) => void;
16
- var getLanguage: () => string;
17
- var getTranslations: (language?: string | undefined) => Record<string, string> | undefined;
21
+ export interface TrObject {
22
+ [key: string]: string | TrObject;
18
23
  }
24
+ /** Properties for the transform function that transforms a matched translation string into something else */
25
+ export type TransformFnProps<TTrKey extends string = string> = {
26
+ /** The current language - empty string if not set yet */
27
+ language: string;
28
+ /** The matches as returned by `RegExp.exec()` */
29
+ matches: RegExpExecArray[];
30
+ /** The translation key */
31
+ trKey: TTrKey;
32
+ /** Translation value before any transformations */
33
+ trValue: string;
34
+ /** Current value, possibly in-between transformations */
35
+ currentValue: string;
36
+ /** Arguments passed to the translation function */
37
+ trArgs: (Stringifiable | Record<string, Stringifiable>)[];
38
+ };
39
+ /** Function that transforms a matched translation string into another string */
40
+ export type TransformFn<TTrKey extends string = string> = (props: TransformFnProps<TTrKey>) => Stringifiable;
41
+ /** Transform pattern and function in tuple form */
42
+ export type TransformTuple<TTrKey extends string = string> = [RegExp, TransformFn<TTrKey>];
43
+ /**
44
+ * Pass a recursive or flat translation object to this generic type to get all keys in the object.
45
+ * @example ```ts
46
+ * type Keys = TrKeys<{ a: { b: "foo" }, c: "bar" }>;
47
+ * // result: type Keys = "a.b" | "c"
48
+ * ```
49
+ */
50
+ export type TrKeys<TTrObj, P extends string = ""> = {
51
+ [K in keyof TTrObj]: K extends string | number | boolean | null | undefined ? TTrObj[K] extends object ? TrKeys<TTrObj[K], `${P}${K}.`> : `${P}${K}` : never;
52
+ }[keyof TTrObj];
53
+ /**
54
+ * Registers a new language and its translations - if the language already exists, it will be overwritten.
55
+ * The translations are a key-value pair where the key is the translation key and the value is the translated text.
56
+ * The translations can also be infinitely nested objects, resulting in a dot-separated key.
57
+ * @param language Language code or name to register - I recommend sticking to a standard like [ISO 639](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) or [BCP 47](https://en.wikipedia.org/wiki/IETF_language_tag)
58
+ * @param translations Translations for the specified language
59
+ * @example ```ts
60
+ * tr.addTranslations("en", {
61
+ * hello: "Hello, %1!",
62
+ * foo: {
63
+ * bar: "Foo bar",
64
+ * },
65
+ * });
66
+ * ```
67
+ */
68
+ declare function addTranslations(language: string, translations: TrObject): void;
69
+ /**
70
+ * Returns the translation object for the specified language or currently active one.
71
+ * If the language is not registered with {@linkcode tr.addTranslations()}, this function will return `undefined`.
72
+ * @param language Language code or name to get translations for - defaults to the currently active language (set by {@linkcode tr.setLanguage()})
73
+ * @returns Translations for the specified language
74
+ */
75
+ declare function getTranslations(language?: string): TrObject | undefined;
76
+ /**
77
+ * The fallback language to use when a translation key is not found in the currently active language.
78
+ * Leave undefined to disable fallbacks and just return the translation key if translations are not found.
79
+ */
80
+ declare function setFallbackLanguage(fallbackLanguage?: string): void;
81
+ /** Returns the fallback language set by {@linkcode tr.setFallbackLanguage()} */
82
+ declare function getFallbackLanguage(): string | undefined;
83
+ /**
84
+ * Adds a transform function that gets called after resolving a translation for any language.
85
+ * Use it to enable dynamic values in translations, for example to insert custom global values from the application or to denote a section that could be encapsulated by rich text.
86
+ * Each function will receive the RegExpMatchArray [see MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match) and the current language as arguments.
87
+ * After all %n-formatted values have been injected, the transform functions will be called sequentially in the order they were added.
88
+ * @example
89
+ * ```ts
90
+ * tr.addTranslations("en", {
91
+ * "greeting": {
92
+ * "with_username": "Hello, ${USERNAME}",
93
+ * "headline_html": "Hello, ${USERNAME}<br><c=red>You have ${UNREAD_NOTIFS} unread notifications.</c>"
94
+ * }
95
+ * });
96
+ *
97
+ * // replace ${PATTERN}
98
+ * tr.addTransform(/<\$([A-Z_]+)>/g, ({ matches }) => {
99
+ * switch(matches?.[1]) {
100
+ * default: return "<UNKNOWN_PATTERN>";
101
+ * // these would be grabbed from elsewhere in the application:
102
+ * case "USERNAME": return "JohnDoe45";
103
+ * case "UNREAD_NOTIFS": return 5;
104
+ * }
105
+ * });
106
+ *
107
+ * // replace <c=red>...</c> with <span class="color red">...</span>
108
+ * tr.addTransform(/<c=([a-z]+)>(.*?)<\/c>/g, ({ matches }) => {
109
+ * const color = matches?.[1];
110
+ * const content = matches?.[2];
111
+ *
112
+ * return "<span class=\"color " + color + "\">" + content + "</span>";
113
+ * });
114
+ *
115
+ * tr.setLanguage("en");
116
+ *
117
+ * tr("greeting.with_username"); // "Hello, JohnDoe45"
118
+ * tr("greeting.headline"); // "<b>Hello, JohnDoe45</b>\nYou have 5 unread notifications."
119
+ * ```
120
+ * @param args A tuple containing the regular expression to match and the transform function to call if the pattern is found in a translation string
121
+ */
122
+ declare function addTransform<TTrKey extends string = string>(transform: TransformTuple<TTrKey>): void;
123
+ /**
124
+ * Deletes the first transform function from the list of registered transform functions.
125
+ * @param patternOrFn A reference to the regular expression of the transform function, a string matching the original pattern, or a reference to the transform function to delete
126
+ * @returns Returns true if the transform function was found and deleted, false if it wasn't found
127
+ */
128
+ declare function deleteTransform(patternOrFn: RegExp | string | TransformFn): boolean;
129
+ declare const tr: {
130
+ for: <TTrKey extends string = string>(language: string, key: TTrKey, ...args: (Stringifiable | Record<string, Stringifiable>)[]) => string;
131
+ use: <TTrKey extends string = string>(language: string) => (key: TTrKey, ...args: (Stringifiable | Record<string, Stringifiable>)[]) => string;
132
+ hasKey: <TTrKey extends string = string>(language: string | undefined, key: TTrKey) => boolean;
133
+ addTranslations: typeof addTranslations;
134
+ getTranslations: typeof getTranslations;
135
+ deleteTranslations: (language: string) => boolean;
136
+ setFallbackLanguage: typeof setFallbackLanguage;
137
+ getFallbackLanguage: typeof getFallbackLanguage;
138
+ addTransform: typeof addTransform;
139
+ deleteTransform: typeof deleteTransform;
140
+ transforms: {
141
+ templateLiteral: [RegExp, ({ matches, trArgs, trValue }: TransformFnProps<string>) => string];
142
+ percent: [RegExp, ({ matches, trArgs, trValue }: TransformFnProps<string>) => string];
143
+ };
144
+ };
19
145
  export { tr };
@@ -1,23 +1,25 @@
1
1
  /** Represents any value that is either a string itself or can be converted to one (implicitly and explicitly) because it has a toString() method */
2
2
  export type Stringifiable = string | {
3
3
  toString(): string;
4
- };
4
+ } | {
5
+ [Symbol.toStringTag]: string;
6
+ } | number | boolean | null | undefined;
5
7
  /**
6
- * A type that offers autocomplete for the passed union but also allows any arbitrary value of the same type to be passed.
7
- * Supports unions of strings, numbers and objects.
8
+ * A type that offers autocomplete for the passed union but also allows any arbitrary value of the same type to be passed.
9
+ * Supports unions of strings, numbers and objects.
8
10
  */
9
11
  export type LooseUnion<TUnion extends string | number | object> = (TUnion) | (TUnion extends string ? (string & {}) : (TUnion extends number ? (number & {}) : (TUnion extends Record<keyof any, unknown> ? (object & {}) : never)));
10
12
  /**
11
- * A type that allows all strings except for empty ones
12
- * @example
13
- * function foo<T extends string>(bar: NonEmptyString<T>) {
14
- * console.log(bar);
15
- * }
13
+ * A type that allows all strings except for empty ones
14
+ * @example
15
+ * function foo<T extends string>(bar: NonEmptyString<T>) {
16
+ * console.log(bar);
17
+ * }
16
18
  */
17
19
  export type NonEmptyString<TString extends string> = TString extends "" ? never : TString;
18
20
  /**
19
- * Makes the structure of a type more readable by expanding it.
20
- * This can be useful for debugging or for improving the readability of complex types.
21
+ * Makes the structure of a type more readable by expanding it.
22
+ * This can be useful for debugging or for improving the readability of complex types.
21
23
  */
22
24
  export type Prettify<T> = {
23
25
  [K in keyof T]: T[K];
package/package.json CHANGED
@@ -1,38 +1,20 @@
1
1
  {
2
2
  "name": "@sv443-network/userutils",
3
3
  "libName": "UserUtils",
4
- "version": "8.3.3",
5
- "description": "Library with various utilities for userscripts - register listeners for when CSS selectors exist, intercept events, create persistent & synchronous data stores, modify the DOM more easily and more",
4
+ "version": "9.0.0",
5
+ "description": "Lightweight library with various utilities for userscripts - register listeners for when CSS selectors exist, intercept events, create persistent & synchronous data stores, modify the DOM more easily and much more",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",
8
8
  "types": "dist/lib/index.d.ts",
9
9
  "exports": {
10
10
  ".": {
11
- "import": "./dist/index.js",
12
- "require": "./dist/index.cjs",
13
11
  "browser": "./dist/index.global.js",
14
- "types": "./dist/lib/index.d.ts"
12
+ "types": "./dist/lib/index.d.ts",
13
+ "require": "./dist/index.cjs",
14
+ "import": "./dist/index.js"
15
15
  }
16
16
  },
17
17
  "type": "module",
18
- "scripts": {
19
- "lint": "tsc --noEmit && eslint .",
20
- "build-types": "tsc --emitDeclarationOnly --declaration --outDir dist",
21
- "build-common": "tsup lib/index.ts --format cjs,esm --clean --treeshake",
22
- "build-all": "tsup lib/index.ts --format cjs,esm,iife --treeshake --onSuccess \"npm run build-types && npm run post-build-global && echo Finished building.\"",
23
- "build": "npm run build-common -- && npm run build-types",
24
- "post-build-global": "npm run node-ts -- ./tools/post-build-global.mts",
25
- "dev": "npm run build-common -- --sourcemap --watch --onSuccess \"npm run build-types && echo Finished building.\"",
26
- "dev-all": "npm run build-all -- --watch",
27
- "update-jsr-version": "npm run node-ts -- ./tools/update-jsr-version.mts",
28
- "publish-package": "changeset publish",
29
- "publish-package-jsr": "npm run update-jsr-version && npx jsr publish --allow-dirty",
30
- "change": "changeset",
31
- "node-ts": "node --no-warnings=ExperimentalWarning --enable-source-maps --loader ts-node/esm",
32
- "test-serve": "npm run node-ts -- ./test/TestPage/server.mts",
33
- "test-dev": "cd test/TestScript && npm run dev",
34
- "test": "concurrently \"npm run test-serve\" \"npm run test-dev\""
35
- },
36
18
  "repository": {
37
19
  "type": "git",
38
20
  "url": "git+https://github.com/Sv443-Network/UserUtils.git"
@@ -51,32 +33,55 @@
51
33
  },
52
34
  "homepage": "https://github.com/Sv443-Network/UserUtils",
53
35
  "dependencies": {
54
- "nanoevents": "^9.0.0"
36
+ "nanoevents": "^9.1.0"
55
37
  },
56
38
  "devDependencies": {
57
- "@changesets/cli": "^2.26.2",
58
- "@types/express": "^4.17.19",
59
- "@types/greasemonkey": "^4.0.4",
60
- "@types/node": "^20.5.9",
61
- "@typescript-eslint/eslint-plugin": "^6.2.1",
62
- "@typescript-eslint/parser": "^6.2.1",
63
- "concurrently": "^8.2.1",
64
- "eslint": "^8.46.0",
65
- "express": "^4.18.2",
66
- "ts-node": "^10.9.1",
67
- "tslib": "^2.6.1",
68
- "tsup": "^7.1.0",
69
- "typescript": "^5.1.6"
39
+ "@changesets/cli": "^2.27.11",
40
+ "@eslint/eslintrc": "^3.2.0",
41
+ "@types/express": "^4.17.21",
42
+ "@types/greasemonkey": "^4.0.7",
43
+ "@types/node": "^22.10.5",
44
+ "@types/tx2": "^1.0.3",
45
+ "@typescript-eslint/eslint-plugin": "^8.21.0",
46
+ "@typescript-eslint/parser": "^8.21.0",
47
+ "@typescript-eslint/utils": "^8.21.0",
48
+ "concurrently": "^8.2.2",
49
+ "eslint": "^9.18.0",
50
+ "express": "^4.21.2",
51
+ "globals": "^15.14.0",
52
+ "kleur": "^4.1.5",
53
+ "tslib": "^2.8.1",
54
+ "tsup": "^8.3.5",
55
+ "tsx": "^4.19.2",
56
+ "typescript": "^5.7.3"
70
57
  },
71
58
  "files": [
72
59
  "/dist/index.js",
73
60
  "/dist/index.cjs",
74
61
  "/dist/index.mjs",
75
62
  "/dist/index.global.js",
63
+ "/dist/index.umd.js",
76
64
  "/dist/lib/**.d.ts",
77
65
  "/package.json",
78
- "/README.md",
66
+ "/README-summary.md",
79
67
  "/CHANGELOG.md",
80
68
  "/LICENSE.txt"
81
- ]
69
+ ],
70
+ "scripts": {
71
+ "lint": "eslint . && tsc --noEmit",
72
+ "build-types": "tsc --emitDeclarationOnly --declaration --outDir dist && node --import tsx ./tools/fix-dts.mts",
73
+ "build-common": "tsup lib/index.ts --format cjs,esm --clean --treeshake",
74
+ "build-all": "tsup lib/index.ts --format cjs,esm,iife --treeshake --onSuccess \"pnpm build-types && pnpm post-build-global\"",
75
+ "build": "pnpm build-common -- && pnpm build-types",
76
+ "post-build-global": "node --import tsx ./tools/post-build-global.mts",
77
+ "dev": "pnpm build-common -- --sourcemap --watch --onSuccess \"pnpm build-types\"",
78
+ "dev-all": "pnpm build-all -- --watch",
79
+ "update-jsr-version": "node --import tsx ./tools/update-jsr-version.mts",
80
+ "publish-package": "changeset publish",
81
+ "publish-package-jsr": "pnpm update-jsr-version && npx jsr publish --allow-dirty",
82
+ "change": "changeset",
83
+ "test-serve": "node --import tsx ./test/TestPage/server.mts",
84
+ "test-dev": "cd test/TestScript && pnpm dev",
85
+ "test": "concurrently \"pnpm test-serve\" \"pnpm test-dev\""
86
+ }
82
87
  }