xenopomp-essentials 0.5.0-canary.3 → 0.5.0-rc.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/cli-tools/index.mjs +76 -1
- package/eslint/index.mjs +303 -1
- package/index.d.mts +2 -13
- package/index.d.ts +2 -13
- package/index.mjs +45 -1
- package/next/index.mjs +34 -6
- package/package.json +3 -1
- package/shared/xenopomp-essentials.CO5lcTlK.d.mts +14 -0
- package/shared/xenopomp-essentials.CO5lcTlK.d.ts +14 -0
- package/vitest/index.d.mts +85 -2
- package/vitest/index.d.ts +85 -2
- package/vitest/index.mjs +121 -1
- package/shared/xenopomp-essentials.B-Vt61jj.d.mts +0 -3
- package/shared/xenopomp-essentials.B-Vt61jj.d.ts +0 -3
package/cli-tools/index.mjs
CHANGED
|
@@ -1 +1,76 @@
|
|
|
1
|
-
import
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import dotenv from 'dotenv';
|
|
4
|
+
|
|
5
|
+
const importMetaSchema = z.object({
|
|
6
|
+
dirname: z.string().optional()
|
|
7
|
+
});
|
|
8
|
+
const importMeta = importMetaSchema.parse(import.meta);
|
|
9
|
+
|
|
10
|
+
dotenv.config({ quiet: true });
|
|
11
|
+
const envSchema = z.object({
|
|
12
|
+
DISABLE_MINIFY: z.string().transform((arg) => arg === "true")
|
|
13
|
+
});
|
|
14
|
+
envSchema.parse(process.env);
|
|
15
|
+
|
|
16
|
+
class PathBuilder {
|
|
17
|
+
paths = [];
|
|
18
|
+
pushPaths(...paths) {
|
|
19
|
+
this.paths.push(...paths);
|
|
20
|
+
return this;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Pushes any custom paths to builder.
|
|
24
|
+
* @since 0.0.1
|
|
25
|
+
* @param paths
|
|
26
|
+
*/
|
|
27
|
+
cd(...paths) {
|
|
28
|
+
return this.pushPaths(...paths);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Pushes filename to paths.
|
|
32
|
+
* @since 0.0.1
|
|
33
|
+
* @param fileName
|
|
34
|
+
*/
|
|
35
|
+
file(fileName) {
|
|
36
|
+
return this.pushPaths(`./${fileName}`);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Pushes path to compiled app directory.
|
|
40
|
+
* Is useful for cli tools that have to access files inside their bundles.
|
|
41
|
+
*
|
|
42
|
+
* It probably may take no effect (if import.meta is not available in a scope).
|
|
43
|
+
* If it is, will push cwd.
|
|
44
|
+
*
|
|
45
|
+
* @since 0.0.1
|
|
46
|
+
*/
|
|
47
|
+
appSource() {
|
|
48
|
+
if (!importMeta.dirname) {
|
|
49
|
+
return this.cwd();
|
|
50
|
+
}
|
|
51
|
+
return this.pushPaths(path.join(path.dirname(importMeta.dirname), "../"));
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Gets path of directory where script is running. In cli tools it access
|
|
55
|
+
* path, where cli tool was started.
|
|
56
|
+
* @since 0.0.1
|
|
57
|
+
*/
|
|
58
|
+
cwd() {
|
|
59
|
+
return this.pushPaths(process.cwd());
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* @since 0.0.1
|
|
63
|
+
*/
|
|
64
|
+
clear() {
|
|
65
|
+
this.paths = [];
|
|
66
|
+
return this;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* @since 0.0.1
|
|
70
|
+
*/
|
|
71
|
+
build() {
|
|
72
|
+
return path.join(...this.paths);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export { PathBuilder };
|
package/eslint/index.mjs
CHANGED
|
@@ -1 +1,303 @@
|
|
|
1
|
-
import{GLOB_JSX
|
|
1
|
+
import { GLOB_JSX, GLOB_TSX, interopDefault, GLOB_MARKDOWN_CODE, antfu } from '@antfu/eslint-config';
|
|
2
|
+
import { deepmerge } from 'deepmerge-ts';
|
|
3
|
+
import globals from 'globals';
|
|
4
|
+
import recommended from 'eslint-plugin-prettier/recommended';
|
|
5
|
+
import { fixupPluginRules } from '@eslint/compat';
|
|
6
|
+
import plugin from 'eslint-plugin-deprecation';
|
|
7
|
+
|
|
8
|
+
const AUTHOR_NAME = "XenoPOMP";
|
|
9
|
+
const AUTHOR_NAME_LOWER = AUTHOR_NAME.toLowerCase();
|
|
10
|
+
|
|
11
|
+
async function react() {
|
|
12
|
+
return [
|
|
13
|
+
{
|
|
14
|
+
files: [GLOB_JSX, GLOB_TSX],
|
|
15
|
+
name: `${AUTHOR_NAME_LOWER}:react`,
|
|
16
|
+
rules: {
|
|
17
|
+
"react-refresh/only-export-components": "off",
|
|
18
|
+
"react/no-clone-element": "off",
|
|
19
|
+
"react/no-missing-component-display-name": "off"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async function next() {
|
|
26
|
+
const next2 = await interopDefault(import('@next/eslint-plugin-next'));
|
|
27
|
+
return [
|
|
28
|
+
{
|
|
29
|
+
name: `${AUTHOR_NAME_LOWER}:next`,
|
|
30
|
+
plugins: { "@next/next": next2 },
|
|
31
|
+
rules: {
|
|
32
|
+
"@next/next/google-font-display": "warn",
|
|
33
|
+
"@next/next/google-font-preconnect": "warn",
|
|
34
|
+
"@next/next/next-script-for-ga": "warn",
|
|
35
|
+
"@next/next/no-async-client-component": "warn",
|
|
36
|
+
"@next/next/no-before-interactive-script-outside-document": "warn",
|
|
37
|
+
"@next/next/no-css-tags": "warn",
|
|
38
|
+
"@next/next/no-head-element": "warn",
|
|
39
|
+
"@next/next/no-html-link-for-pages": "warn",
|
|
40
|
+
"@next/next/no-img-element": "warn",
|
|
41
|
+
"@next/next/no-page-custom-font": "warn",
|
|
42
|
+
"@next/next/no-styled-jsx-in-document": "warn",
|
|
43
|
+
"@next/next/no-sync-scripts": "warn",
|
|
44
|
+
"@next/next/no-title-in-document-head": "warn",
|
|
45
|
+
"@next/next/no-typos": "warn",
|
|
46
|
+
"@next/next/no-unwanted-polyfillio": "warn",
|
|
47
|
+
// errors
|
|
48
|
+
"@next/next/inline-script-id": "error",
|
|
49
|
+
"@next/next/no-assign-module-variable": "error",
|
|
50
|
+
"@next/next/no-document-import-in-page": "error",
|
|
51
|
+
"@next/next/no-duplicate-head": "error",
|
|
52
|
+
"@next/next/no-head-import-in-document": "error",
|
|
53
|
+
"@next/next/no-script-component-in-head": "error"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async function markdown() {
|
|
60
|
+
return [
|
|
61
|
+
{
|
|
62
|
+
name: `${AUTHOR_NAME_LOWER}:markdown`,
|
|
63
|
+
files: [GLOB_MARKDOWN_CODE],
|
|
64
|
+
rules: {
|
|
65
|
+
"import/no-unresolved": "off",
|
|
66
|
+
"unused-imports/no-unused-imports": "off",
|
|
67
|
+
"unused-imports/no-unused-vars": "off",
|
|
68
|
+
"no-alert": "off",
|
|
69
|
+
"no-console": "off",
|
|
70
|
+
"no-restricted-imports": "off",
|
|
71
|
+
"no-undef": "off",
|
|
72
|
+
"no-unused-expressions": "off",
|
|
73
|
+
"no-unused-vars": "off",
|
|
74
|
+
"antfu/no-cjs-exports": "off",
|
|
75
|
+
"antfu/no-ts-export-equal": "off",
|
|
76
|
+
"ts/no-redeclare": "off",
|
|
77
|
+
"ts/no-unused-vars": "off",
|
|
78
|
+
"ts/no-var-requires": "off",
|
|
79
|
+
"ts/consistent-type-imports": "off"
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async function all() {
|
|
86
|
+
return [
|
|
87
|
+
{
|
|
88
|
+
name: `${AUTHOR_NAME_LOWER}:all`,
|
|
89
|
+
rules: {
|
|
90
|
+
"antfu/no-cjs-exports": "off",
|
|
91
|
+
"import/prefer-default-export": "off",
|
|
92
|
+
"import/extensions": "off",
|
|
93
|
+
"no-restricted-globals": "off",
|
|
94
|
+
"node/prefer-global/process": "off",
|
|
95
|
+
"jsonc/comma-dangle": "off",
|
|
96
|
+
"style/jsx-quotes": ["error", "prefer-double"],
|
|
97
|
+
"style/jsx-one-expression-per-line": [
|
|
98
|
+
"error",
|
|
99
|
+
{ allow: "single-line" }
|
|
100
|
+
],
|
|
101
|
+
"style/arrow-parens": ["error", "as-needed"],
|
|
102
|
+
"unused-imports/no-unused-imports": "error",
|
|
103
|
+
"unused-imports/no-unused-vars": [
|
|
104
|
+
"warn",
|
|
105
|
+
{
|
|
106
|
+
vars: "all",
|
|
107
|
+
varsIgnorePattern: "^_",
|
|
108
|
+
args: "after-used",
|
|
109
|
+
argsIgnorePattern: "^_"
|
|
110
|
+
}
|
|
111
|
+
],
|
|
112
|
+
"@stylistic/indent": [
|
|
113
|
+
"error",
|
|
114
|
+
2,
|
|
115
|
+
{
|
|
116
|
+
ArrayExpression: 1,
|
|
117
|
+
CallExpression: {
|
|
118
|
+
arguments: 1
|
|
119
|
+
},
|
|
120
|
+
flatTernaryExpressions: false,
|
|
121
|
+
FunctionDeclaration: {
|
|
122
|
+
body: 1,
|
|
123
|
+
parameters: 1
|
|
124
|
+
},
|
|
125
|
+
FunctionExpression: {
|
|
126
|
+
body: 1,
|
|
127
|
+
parameters: 1
|
|
128
|
+
},
|
|
129
|
+
ignoreComments: false,
|
|
130
|
+
ignoredNodes: [
|
|
131
|
+
"TemplateLiteral *",
|
|
132
|
+
"TSIntersectionType",
|
|
133
|
+
"TSTypeParameterInstantiation",
|
|
134
|
+
"FunctionExpression > .params[decorators.length > 0]",
|
|
135
|
+
"FunctionExpression > .params > :matches(Decorator, :not(:first-child))",
|
|
136
|
+
"ClassBody.body > PropertyDefinition[decorators.length > 0] > .key"
|
|
137
|
+
],
|
|
138
|
+
ImportDeclaration: 1,
|
|
139
|
+
MemberExpression: 1,
|
|
140
|
+
ObjectExpression: 1,
|
|
141
|
+
offsetTernaryExpressions: true,
|
|
142
|
+
outerIIFEBody: 1,
|
|
143
|
+
SwitchCase: 1,
|
|
144
|
+
VariableDeclarator: 1
|
|
145
|
+
}
|
|
146
|
+
]
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async function old() {
|
|
153
|
+
return [
|
|
154
|
+
{
|
|
155
|
+
name: `${AUTHOR_NAME_LOWER}:old_config`,
|
|
156
|
+
languageOptions: {
|
|
157
|
+
globals: {
|
|
158
|
+
...globals.browser,
|
|
159
|
+
...globals.jquery,
|
|
160
|
+
...globals.node,
|
|
161
|
+
// Rewrite globals anyway
|
|
162
|
+
document: "readonly",
|
|
163
|
+
navigator: "readonly",
|
|
164
|
+
window: "readonly"
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
// Ignore patterns
|
|
168
|
+
ignores: [
|
|
169
|
+
"**/.next/*",
|
|
170
|
+
"**/node_modules/*",
|
|
171
|
+
"**/.github/*",
|
|
172
|
+
"cypress",
|
|
173
|
+
"**/__tests__/e2e/*",
|
|
174
|
+
"*.json",
|
|
175
|
+
"**/*.d.ts",
|
|
176
|
+
".eslintrc.js",
|
|
177
|
+
"eslint.config.js",
|
|
178
|
+
".prettierrc",
|
|
179
|
+
".stylelintrc.js",
|
|
180
|
+
"tsconfig.json",
|
|
181
|
+
"package.json",
|
|
182
|
+
"*.md",
|
|
183
|
+
"*.config.ts",
|
|
184
|
+
"*.config.js",
|
|
185
|
+
"*.md"
|
|
186
|
+
]
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
name: `${AUTHOR_NAME_LOWER}:rules_breakup_1`,
|
|
190
|
+
rules: { "@next/next/no-duplicate-head": "off" }
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
name: `${AUTHOR_NAME_LOWER}:rules_breakup_2`,
|
|
194
|
+
rules: {
|
|
195
|
+
"style/operator-linebreak": "off",
|
|
196
|
+
"test/consistent-test-it": "off",
|
|
197
|
+
"test/prefer-lowercase-title": "off",
|
|
198
|
+
"style/jsx-quotes": "off",
|
|
199
|
+
"style/multiline-ternary": "off",
|
|
200
|
+
"style/indent": "off"
|
|
201
|
+
},
|
|
202
|
+
ignores: ["cypress"]
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
name: `${AUTHOR_NAME_LOWER}:prettier`,
|
|
206
|
+
rules: {
|
|
207
|
+
"antfu/if-newline": "off"
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
];
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
async function prettier() {
|
|
214
|
+
return [recommended];
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
async function deprecation(severity, options) {
|
|
218
|
+
return [
|
|
219
|
+
{
|
|
220
|
+
name: "Deprecation plugin",
|
|
221
|
+
languageOptions: {
|
|
222
|
+
parserOptions: {
|
|
223
|
+
project: options?.tsconfigPath ?? "./tsconfig.json",
|
|
224
|
+
projectSource: true
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
plugins: {
|
|
228
|
+
// @ts-expect-error Wrong library types
|
|
229
|
+
deprecation: fixupPluginRules(plugin)
|
|
230
|
+
},
|
|
231
|
+
rules: {
|
|
232
|
+
"deprecation/deprecation": severity
|
|
233
|
+
},
|
|
234
|
+
files: ["**/*.ts", "**/*.tsx"]
|
|
235
|
+
}
|
|
236
|
+
];
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function xenopomp(options, ...userConfigs) {
|
|
240
|
+
const configs = [];
|
|
241
|
+
options = {
|
|
242
|
+
...options,
|
|
243
|
+
react: deepmerge(true, options?.react),
|
|
244
|
+
vue: deepmerge(
|
|
245
|
+
false,
|
|
246
|
+
options?.vue
|
|
247
|
+
),
|
|
248
|
+
jsonc: deepmerge(false, options?.jsonc),
|
|
249
|
+
yaml: deepmerge(false, options?.yaml),
|
|
250
|
+
stylistic: deepmerge(
|
|
251
|
+
{
|
|
252
|
+
semi: true,
|
|
253
|
+
quotes: "single"
|
|
254
|
+
},
|
|
255
|
+
options?.stylistic
|
|
256
|
+
),
|
|
257
|
+
typescript: deepmerge(
|
|
258
|
+
{
|
|
259
|
+
overrides: {
|
|
260
|
+
"ts/consistent-type-definitions": ["error", "interface"],
|
|
261
|
+
"ts/interface-name-prefix": "off",
|
|
262
|
+
"ts/explicit-function-return-type": "off",
|
|
263
|
+
"ts/explicit-module-boundary-types": "off",
|
|
264
|
+
"ts/no-explicit-any": "off"
|
|
265
|
+
}
|
|
266
|
+
},
|
|
267
|
+
options?.typescript
|
|
268
|
+
),
|
|
269
|
+
rules: deepmerge(
|
|
270
|
+
{
|
|
271
|
+
"import/order": "off",
|
|
272
|
+
"react/react-in-jsx-scope": "off",
|
|
273
|
+
"react/prop-types": "off",
|
|
274
|
+
"antfu/top-level-function": "off",
|
|
275
|
+
"perfectionist/sort-imports": "off",
|
|
276
|
+
"perfectionist/sort-named-imports": "off",
|
|
277
|
+
"perfectionist/sort-named-exports": "off",
|
|
278
|
+
"antfu/consistent-chaining": "off",
|
|
279
|
+
"perfectionist/sort-exports": "off",
|
|
280
|
+
"style/no-multiple-empty-lines": "off"
|
|
281
|
+
},
|
|
282
|
+
options?.rules
|
|
283
|
+
),
|
|
284
|
+
deprecation: options?.deprecation,
|
|
285
|
+
tsconfigPath: options?.tsconfigPath
|
|
286
|
+
};
|
|
287
|
+
if (options.react ?? true) configs.push(react());
|
|
288
|
+
if (options.all ?? true) configs.push(all());
|
|
289
|
+
if (options.next ?? false) configs.push(next());
|
|
290
|
+
if (options.markdown ?? true) configs.push(markdown());
|
|
291
|
+
if (options?.deprecation) {
|
|
292
|
+
configs.push(
|
|
293
|
+
deprecation(options?.deprecation ?? "warn", {
|
|
294
|
+
tsconfigPath: options?.tsconfigPath
|
|
295
|
+
})
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
configs.push(old());
|
|
299
|
+
configs.push(prettier());
|
|
300
|
+
return antfu(options, ...configs, ...userConfigs);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
export { xenopomp as default };
|
package/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { P as PromiseOr } from './shared/xenopomp-essentials.
|
|
1
|
+
export { O as Optional, P as PromiseOr, U as Undefinable } from './shared/xenopomp-essentials.CO5lcTlK.mjs';
|
|
2
2
|
import { ElementType, ComponentProps, FC, ReactNode, Dispatch, SetStateAction } from 'react';
|
|
3
3
|
import { Jsonifiable } from 'type-fest';
|
|
4
4
|
import * as transliteration from 'transliteration';
|
|
@@ -345,17 +345,6 @@ type ReplaceReturnType<TFn, TR> = TFn extends (...a: infer A) => any ? (...a: A)
|
|
|
345
345
|
*/
|
|
346
346
|
type SelectivePartial<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
|
|
347
347
|
|
|
348
|
-
/**
|
|
349
|
-
* Makes type union of type T and undefined
|
|
350
|
-
* @since 0.0.1
|
|
351
|
-
* @deprecated Renamed to {@link Optional}.
|
|
352
|
-
*/
|
|
353
|
-
type Undefinable<T> = T | undefined;
|
|
354
|
-
/**
|
|
355
|
-
* Marks type as optional (undefinable).
|
|
356
|
-
*/
|
|
357
|
-
type Optional<T> = T | undefined;
|
|
358
|
-
|
|
359
348
|
/**
|
|
360
349
|
* The strict version of Omit. Allows to remove only
|
|
361
350
|
* keys that are presented in T type.
|
|
@@ -618,4 +607,4 @@ declare const minmax: (num: number, [min, max]: [min: number | undefined, max: n
|
|
|
618
607
|
declare function jsxDotNotation<Props = EmptyObject, Rest extends Record<string, FC<any>> = EmptyObject>(comp: FC<Props>, rest: Rest): FC<Props> & Rest;
|
|
619
608
|
|
|
620
609
|
export { capitalize, jsxDotNotation, minmax, parseVersion, pipe, transliterate, uncapitalize };
|
|
621
|
-
export type { AnyFC, AnyObject, ArrayItemType, ArrayType, AsyncFC, AsyncReturnType, AsyncVariableFC, DataAttributes, Defined, EmptyObject, FCProps, FcProps, Fn, FunctionalChildren, InjectDeep, Jsonish, Lenient, LenientAutocomplete, MatchType, MergeTypes, Modify, NextErrorParams, NextParams, NextSearchParams, Nullable, OneOf, OnlyFirst,
|
|
610
|
+
export type { AnyFC, AnyObject, ArrayItemType, ArrayType, AsyncFC, AsyncReturnType, AsyncVariableFC, DataAttributes, Defined, EmptyObject, FCProps, FcProps, Fn, FunctionalChildren, InjectDeep, Jsonish, Lenient, LenientAutocomplete, MatchType, MergeTypes, Modify, NextErrorParams, NextParams, NextSearchParams, Nullable, OneOf, OnlyFirst, Preid, Prettify, PrettifyDeep, RecordKey, RecordValue, ReplaceReturnType, SelectivePartial, SetState, StrictOmit, Synchronous, VariableFC, VariableProps, VersionData, WeakOmit, Writeable, WriteableDeep };
|
package/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { P as PromiseOr } from './shared/xenopomp-essentials.
|
|
1
|
+
export { O as Optional, P as PromiseOr, U as Undefinable } from './shared/xenopomp-essentials.CO5lcTlK.js';
|
|
2
2
|
import { ElementType, ComponentProps, FC, ReactNode, Dispatch, SetStateAction } from 'react';
|
|
3
3
|
import { Jsonifiable } from 'type-fest';
|
|
4
4
|
import * as transliteration from 'transliteration';
|
|
@@ -345,17 +345,6 @@ type ReplaceReturnType<TFn, TR> = TFn extends (...a: infer A) => any ? (...a: A)
|
|
|
345
345
|
*/
|
|
346
346
|
type SelectivePartial<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
|
|
347
347
|
|
|
348
|
-
/**
|
|
349
|
-
* Makes type union of type T and undefined
|
|
350
|
-
* @since 0.0.1
|
|
351
|
-
* @deprecated Renamed to {@link Optional}.
|
|
352
|
-
*/
|
|
353
|
-
type Undefinable<T> = T | undefined;
|
|
354
|
-
/**
|
|
355
|
-
* Marks type as optional (undefinable).
|
|
356
|
-
*/
|
|
357
|
-
type Optional<T> = T | undefined;
|
|
358
|
-
|
|
359
348
|
/**
|
|
360
349
|
* The strict version of Omit. Allows to remove only
|
|
361
350
|
* keys that are presented in T type.
|
|
@@ -618,4 +607,4 @@ declare const minmax: (num: number, [min, max]: [min: number | undefined, max: n
|
|
|
618
607
|
declare function jsxDotNotation<Props = EmptyObject, Rest extends Record<string, FC<any>> = EmptyObject>(comp: FC<Props>, rest: Rest): FC<Props> & Rest;
|
|
619
608
|
|
|
620
609
|
export { capitalize, jsxDotNotation, minmax, parseVersion, pipe, transliterate, uncapitalize };
|
|
621
|
-
export type { AnyFC, AnyObject, ArrayItemType, ArrayType, AsyncFC, AsyncReturnType, AsyncVariableFC, DataAttributes, Defined, EmptyObject, FCProps, FcProps, Fn, FunctionalChildren, InjectDeep, Jsonish, Lenient, LenientAutocomplete, MatchType, MergeTypes, Modify, NextErrorParams, NextParams, NextSearchParams, Nullable, OneOf, OnlyFirst,
|
|
610
|
+
export type { AnyFC, AnyObject, ArrayItemType, ArrayType, AsyncFC, AsyncReturnType, AsyncVariableFC, DataAttributes, Defined, EmptyObject, FCProps, FcProps, Fn, FunctionalChildren, InjectDeep, Jsonish, Lenient, LenientAutocomplete, MatchType, MergeTypes, Modify, NextErrorParams, NextParams, NextSearchParams, Nullable, OneOf, OnlyFirst, Preid, Prettify, PrettifyDeep, RecordKey, RecordValue, ReplaceReturnType, SelectivePartial, SetState, StrictOmit, Synchronous, VariableFC, VariableProps, VersionData, WeakOmit, Writeable, WriteableDeep };
|
package/index.mjs
CHANGED
|
@@ -1 +1,45 @@
|
|
|
1
|
-
import{transliterate as
|
|
1
|
+
import { transliterate as transliterate$1 } from 'transliteration';
|
|
2
|
+
|
|
3
|
+
function pipe(fn) {
|
|
4
|
+
function run(a) {
|
|
5
|
+
return fn(a);
|
|
6
|
+
}
|
|
7
|
+
run.pipe = (fn2) => pipe((a) => fn2(fn(a)));
|
|
8
|
+
return run;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function capitalize(str) {
|
|
12
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
13
|
+
}
|
|
14
|
+
function uncapitalize(str) {
|
|
15
|
+
return str.charAt(0).toLowerCase() + str.slice(1);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const parseVersion = (raw) => {
|
|
19
|
+
const version = raw.match(/(\d\.){2}\d/gi)?.at(0) || null;
|
|
20
|
+
const preid = raw.match(/(?<=-)\w+(?=\.\d)/gi)?.at(0);
|
|
21
|
+
const prerelease = raw.match(/(?<=((\d\.){2}\d-\w+\.))\d+/gi)?.at(0);
|
|
22
|
+
return {
|
|
23
|
+
version,
|
|
24
|
+
preid,
|
|
25
|
+
prerelease
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const transliterate = transliterate$1;
|
|
30
|
+
|
|
31
|
+
const minmax = (num, [min, max]) => {
|
|
32
|
+
if (!!min && num <= min) {
|
|
33
|
+
return min;
|
|
34
|
+
}
|
|
35
|
+
if (!!max && num >= max) {
|
|
36
|
+
return max;
|
|
37
|
+
}
|
|
38
|
+
return num;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
function jsxDotNotation(comp, rest) {
|
|
42
|
+
return Object.assign(comp, rest);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export { capitalize, jsxDotNotation, minmax, parseVersion, pipe, transliterate, uncapitalize };
|
package/next/index.mjs
CHANGED
|
@@ -1,11 +1,39 @@
|
|
|
1
|
-
import
|
|
1
|
+
import Script from 'next/script';
|
|
2
|
+
|
|
3
|
+
const ReactScan = () => {
|
|
4
|
+
return /* @__PURE__ */ React.createElement(
|
|
5
|
+
"script",
|
|
6
|
+
{
|
|
7
|
+
src: "https://unpkg.com/react-scan/dist/auto.global.js",
|
|
8
|
+
async: true
|
|
9
|
+
}
|
|
10
|
+
);
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const Metrika = ({
|
|
14
|
+
id,
|
|
15
|
+
clickMap = true,
|
|
16
|
+
trackLinks = true,
|
|
17
|
+
accurateTrackBounce = true
|
|
18
|
+
}) => {
|
|
19
|
+
return /* @__PURE__ */ React.createElement(
|
|
20
|
+
Script,
|
|
21
|
+
{
|
|
22
|
+
id: "metrika-counter",
|
|
23
|
+
strategy: "afterInteractive"
|
|
24
|
+
},
|
|
25
|
+
` (function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
|
|
2
26
|
m[i].l=1*new Date();
|
|
3
27
|
for (var j = 0; j < document.scripts.length; j++) {if (document.scripts[j].src === r) { return; }}
|
|
4
28
|
k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
|
|
5
29
|
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
|
|
6
30
|
|
|
7
|
-
ym(${
|
|
8
|
-
clickmap:${
|
|
9
|
-
trackLinks:${
|
|
10
|
-
accurateTrackBounce:${
|
|
11
|
-
});`
|
|
31
|
+
ym(${id}, "init", {
|
|
32
|
+
clickmap:${clickMap},
|
|
33
|
+
trackLinks:${trackLinks},
|
|
34
|
+
accurateTrackBounce:${accurateTrackBounce}
|
|
35
|
+
});`
|
|
36
|
+
);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export { Metrika, ReactScan };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xenopomp-essentials",
|
|
3
|
-
"version": "0.5.0-
|
|
3
|
+
"version": "0.5.0-rc.0",
|
|
4
4
|
"author": "XenoPOMP <101574433+XenoPOMP@users.noreply.github.com>",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -56,6 +56,7 @@
|
|
|
56
56
|
"@vitest/spy": "^4.0.14",
|
|
57
57
|
"ansi-colors": "^4.1.3",
|
|
58
58
|
"deepmerge-ts": "^7.1.5",
|
|
59
|
+
"dotenv": "^17.2.3",
|
|
59
60
|
"eslint": "^9.22.0",
|
|
60
61
|
"eslint-config-prettier": "^10.1.1",
|
|
61
62
|
"eslint-plugin-deprecation": "^3.0.0",
|
|
@@ -69,6 +70,7 @@
|
|
|
69
70
|
"type-fest": "^4.33.0",
|
|
70
71
|
"typescript": "^5.7.3",
|
|
71
72
|
"vitest": "^4.0.14",
|
|
73
|
+
"vitest-matchmedia-mock": "^2.0.3",
|
|
72
74
|
"zod": "^3.24.1"
|
|
73
75
|
},
|
|
74
76
|
"devDependencies": {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
type PromiseOr<T> = T | Promise<T>;
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Makes type union of type T and undefined
|
|
5
|
+
* @since 0.0.1
|
|
6
|
+
* @deprecated Renamed to {@link Optional}.
|
|
7
|
+
*/
|
|
8
|
+
type Undefinable<T> = T | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Marks type as optional (undefinable).
|
|
11
|
+
*/
|
|
12
|
+
type Optional<T> = T | undefined;
|
|
13
|
+
|
|
14
|
+
export type { Optional as O, PromiseOr as P, Undefinable as U };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
type PromiseOr<T> = T | Promise<T>;
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Makes type union of type T and undefined
|
|
5
|
+
* @since 0.0.1
|
|
6
|
+
* @deprecated Renamed to {@link Optional}.
|
|
7
|
+
*/
|
|
8
|
+
type Undefinable<T> = T | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Marks type as optional (undefinable).
|
|
11
|
+
*/
|
|
12
|
+
type Optional<T> = T | undefined;
|
|
13
|
+
|
|
14
|
+
export type { Optional as O, PromiseOr as P, Undefinable as U };
|
package/vitest/index.d.mts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { P as PromiseOr } from '../shared/xenopomp-essentials.
|
|
1
|
+
import { P as PromiseOr, O as Optional } from '../shared/xenopomp-essentials.CO5lcTlK.mjs';
|
|
2
2
|
import { render, renderHook } from '@testing-library/react';
|
|
3
3
|
import * as vitest from 'vitest';
|
|
4
|
+
import { beforeAll, afterEach, Mock } from 'vitest';
|
|
4
5
|
import * as _vitest_spy from '@vitest/spy';
|
|
6
|
+
import { PartialDeep } from 'type-fest';
|
|
5
7
|
|
|
6
8
|
/** Executes function and expects that it won't throw. */
|
|
7
9
|
declare const assertNotThrowing: <T = void>(callable: () => PromiseOr<T>) => void;
|
|
@@ -90,4 +92,85 @@ declare function spyFactory(context: string): {
|
|
|
90
92
|
callSpy: Caller;
|
|
91
93
|
};
|
|
92
94
|
|
|
93
|
-
|
|
95
|
+
/**
|
|
96
|
+
* Mocks global scope object.
|
|
97
|
+
*
|
|
98
|
+
* @param name
|
|
99
|
+
* @param stub
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* stubGlobal<typeof navigator>('navigator', {
|
|
103
|
+
* clipboard: {
|
|
104
|
+
* writeText: async (text: string) => vi.fn(),
|
|
105
|
+
* },
|
|
106
|
+
* });
|
|
107
|
+
*/
|
|
108
|
+
declare const stubGlobal: <Global extends object>(name: string, stub: PartialDeep<Stub<Global>>) => void;
|
|
109
|
+
|
|
110
|
+
type Fn = () => void;
|
|
111
|
+
type Strategy = keyof typeof strategies;
|
|
112
|
+
type AfterAllCallback = Optional<Fn> | void;
|
|
113
|
+
/**
|
|
114
|
+
* Map of all available strategies for
|
|
115
|
+
* injectMocks function.
|
|
116
|
+
*/
|
|
117
|
+
declare const strategies: {
|
|
118
|
+
beforeAll: typeof beforeAll;
|
|
119
|
+
afterEach: typeof afterEach;
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* Inserts mocks according to selected strategy
|
|
123
|
+
* (default is `beforeAll`).
|
|
124
|
+
*
|
|
125
|
+
* This function takes approach of useEffect hook
|
|
126
|
+
* from React. You define mocks inside function body,
|
|
127
|
+
* then you return function, that will be called
|
|
128
|
+
* in `afterAll` event.
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* injectMocks(() => {
|
|
132
|
+
* mockRouter();
|
|
133
|
+
*
|
|
134
|
+
* return () => {
|
|
135
|
+
* console.log('This is printed from injectMocks func (afterAll event).');
|
|
136
|
+
* };
|
|
137
|
+
* });
|
|
138
|
+
*/
|
|
139
|
+
declare const injectMocks: (func: () => AfterAllCallback, strategy?: Strategy) => void;
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Mocks stuff related to window.matchMedia.
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* describe('Root layout test', () => {
|
|
146
|
+
* // Use it inside describe suite. Place it to top
|
|
147
|
+
* injectMatchMediaMock();
|
|
148
|
+
*
|
|
149
|
+
* injectMocks(() => {
|
|
150
|
+
* vi.mock('next/font/google', () => ({
|
|
151
|
+
* Inter: FONT_MOCK,
|
|
152
|
+
* }));
|
|
153
|
+
* });
|
|
154
|
+
*
|
|
155
|
+
* testNextPage(<RootLayout children={undefined} />, {
|
|
156
|
+
* generateMetadata,
|
|
157
|
+
* });
|
|
158
|
+
* });
|
|
159
|
+
*/
|
|
160
|
+
declare const injectMatchMediaMock: () => void;
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Recursevely changes all keys` types inside T to R.
|
|
164
|
+
*/
|
|
165
|
+
type TypeReplaceDeep<T extends object, R> = {
|
|
166
|
+
[K in keyof T]: T[K] extends object ? TypeReplaceDeep<T[K], R> : R;
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
type StubValue = Mock | (() => Mock) | (() => Promise<Mock>);
|
|
170
|
+
/**
|
|
171
|
+
* Represents vi stub object.
|
|
172
|
+
*/
|
|
173
|
+
type Stub<T extends object> = TypeReplaceDeep<T, StubValue>;
|
|
174
|
+
|
|
175
|
+
export { assertHookRendering, assertNotThrowing, assertRendering, clearMocks, injectMatchMediaMock, injectMocks, mockEnv, mockRouter, spyFactory, stubGlobal, twApiMock };
|
|
176
|
+
export type { Stub, TypeReplaceDeep };
|
package/vitest/index.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { P as PromiseOr } from '../shared/xenopomp-essentials.
|
|
1
|
+
import { P as PromiseOr, O as Optional } from '../shared/xenopomp-essentials.CO5lcTlK.js';
|
|
2
2
|
import { render, renderHook } from '@testing-library/react';
|
|
3
3
|
import * as vitest from 'vitest';
|
|
4
|
+
import { beforeAll, afterEach, Mock } from 'vitest';
|
|
4
5
|
import * as _vitest_spy from '@vitest/spy';
|
|
6
|
+
import { PartialDeep } from 'type-fest';
|
|
5
7
|
|
|
6
8
|
/** Executes function and expects that it won't throw. */
|
|
7
9
|
declare const assertNotThrowing: <T = void>(callable: () => PromiseOr<T>) => void;
|
|
@@ -90,4 +92,85 @@ declare function spyFactory(context: string): {
|
|
|
90
92
|
callSpy: Caller;
|
|
91
93
|
};
|
|
92
94
|
|
|
93
|
-
|
|
95
|
+
/**
|
|
96
|
+
* Mocks global scope object.
|
|
97
|
+
*
|
|
98
|
+
* @param name
|
|
99
|
+
* @param stub
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* stubGlobal<typeof navigator>('navigator', {
|
|
103
|
+
* clipboard: {
|
|
104
|
+
* writeText: async (text: string) => vi.fn(),
|
|
105
|
+
* },
|
|
106
|
+
* });
|
|
107
|
+
*/
|
|
108
|
+
declare const stubGlobal: <Global extends object>(name: string, stub: PartialDeep<Stub<Global>>) => void;
|
|
109
|
+
|
|
110
|
+
type Fn = () => void;
|
|
111
|
+
type Strategy = keyof typeof strategies;
|
|
112
|
+
type AfterAllCallback = Optional<Fn> | void;
|
|
113
|
+
/**
|
|
114
|
+
* Map of all available strategies for
|
|
115
|
+
* injectMocks function.
|
|
116
|
+
*/
|
|
117
|
+
declare const strategies: {
|
|
118
|
+
beforeAll: typeof beforeAll;
|
|
119
|
+
afterEach: typeof afterEach;
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* Inserts mocks according to selected strategy
|
|
123
|
+
* (default is `beforeAll`).
|
|
124
|
+
*
|
|
125
|
+
* This function takes approach of useEffect hook
|
|
126
|
+
* from React. You define mocks inside function body,
|
|
127
|
+
* then you return function, that will be called
|
|
128
|
+
* in `afterAll` event.
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* injectMocks(() => {
|
|
132
|
+
* mockRouter();
|
|
133
|
+
*
|
|
134
|
+
* return () => {
|
|
135
|
+
* console.log('This is printed from injectMocks func (afterAll event).');
|
|
136
|
+
* };
|
|
137
|
+
* });
|
|
138
|
+
*/
|
|
139
|
+
declare const injectMocks: (func: () => AfterAllCallback, strategy?: Strategy) => void;
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Mocks stuff related to window.matchMedia.
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* describe('Root layout test', () => {
|
|
146
|
+
* // Use it inside describe suite. Place it to top
|
|
147
|
+
* injectMatchMediaMock();
|
|
148
|
+
*
|
|
149
|
+
* injectMocks(() => {
|
|
150
|
+
* vi.mock('next/font/google', () => ({
|
|
151
|
+
* Inter: FONT_MOCK,
|
|
152
|
+
* }));
|
|
153
|
+
* });
|
|
154
|
+
*
|
|
155
|
+
* testNextPage(<RootLayout children={undefined} />, {
|
|
156
|
+
* generateMetadata,
|
|
157
|
+
* });
|
|
158
|
+
* });
|
|
159
|
+
*/
|
|
160
|
+
declare const injectMatchMediaMock: () => void;
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Recursevely changes all keys` types inside T to R.
|
|
164
|
+
*/
|
|
165
|
+
type TypeReplaceDeep<T extends object, R> = {
|
|
166
|
+
[K in keyof T]: T[K] extends object ? TypeReplaceDeep<T[K], R> : R;
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
type StubValue = Mock | (() => Mock) | (() => Promise<Mock>);
|
|
170
|
+
/**
|
|
171
|
+
* Represents vi stub object.
|
|
172
|
+
*/
|
|
173
|
+
type Stub<T extends object> = TypeReplaceDeep<T, StubValue>;
|
|
174
|
+
|
|
175
|
+
export { assertHookRendering, assertNotThrowing, assertRendering, clearMocks, injectMatchMediaMock, injectMocks, mockEnv, mockRouter, spyFactory, stubGlobal, twApiMock };
|
|
176
|
+
export type { Stub, TypeReplaceDeep };
|
package/vitest/index.mjs
CHANGED
|
@@ -1 +1,121 @@
|
|
|
1
|
-
import{expect
|
|
1
|
+
import { expect, vi, afterEach, beforeAll, afterAll } from 'vitest';
|
|
2
|
+
import { render, renderHook } from '@testing-library/react';
|
|
3
|
+
import c from 'ansi-colors';
|
|
4
|
+
import MatchMediaMock from 'vitest-matchmedia-mock';
|
|
5
|
+
|
|
6
|
+
const assertNotThrowing = (callable) => {
|
|
7
|
+
expect(() => callable()).not.toThrow();
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const assertRendering = (...props) => {
|
|
11
|
+
assertNotThrowing(() => render(...props));
|
|
12
|
+
};
|
|
13
|
+
const assertHookRendering = (...props) => {
|
|
14
|
+
assertNotThrowing(() => renderHook(...props));
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const mockEnv = (additionalMocks) => {
|
|
18
|
+
vi.stubEnv("CANONICAL_URL", "http://localhost:4242");
|
|
19
|
+
vi.stubEnv("IS_PRODUCTION", "false");
|
|
20
|
+
if (additionalMocks) {
|
|
21
|
+
Object.entries(additionalMocks).forEach(
|
|
22
|
+
([key, value]) => vi.stubEnv(key, value)
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const clearMocks = () => {
|
|
28
|
+
vi.clearAllMocks();
|
|
29
|
+
vi.resetAllMocks();
|
|
30
|
+
vi.unstubAllEnvs();
|
|
31
|
+
vi.unstubAllGlobals();
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const mockRouter = () => {
|
|
35
|
+
vi.mock("next/navigation", () => {
|
|
36
|
+
return {
|
|
37
|
+
/** Mock implementation for useRouter */
|
|
38
|
+
useRouter: () => {
|
|
39
|
+
return {
|
|
40
|
+
/** Mock implementation for useRouter().push */
|
|
41
|
+
push() {
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
},
|
|
45
|
+
/** Mock implementation for usePathname */
|
|
46
|
+
usePathname: () => {
|
|
47
|
+
return "/";
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const twApiMock = {
|
|
54
|
+
addBase: vi.fn(),
|
|
55
|
+
addComponents: vi.fn(),
|
|
56
|
+
addUtilities: vi.fn(),
|
|
57
|
+
addVariant: vi.fn(),
|
|
58
|
+
config: vi.fn(),
|
|
59
|
+
corePlugins: vi.fn(),
|
|
60
|
+
e: vi.fn(),
|
|
61
|
+
matchComponents: vi.fn(),
|
|
62
|
+
matchUtilities: vi.fn(),
|
|
63
|
+
matchVariant: vi.fn(),
|
|
64
|
+
theme: vi.fn()
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
class CustomSpyCaller {
|
|
68
|
+
_executionContext;
|
|
69
|
+
constructor(context) {
|
|
70
|
+
this._executionContext = context;
|
|
71
|
+
}
|
|
72
|
+
call(...args) {
|
|
73
|
+
console.debug(
|
|
74
|
+
`${c.blue(`[${this._executionContext}]`)} ${c.green(
|
|
75
|
+
`Custom spy is called with these args: ${c.blueBright(
|
|
76
|
+
args.map((s) => `${s}`).join(", ")
|
|
77
|
+
)}`
|
|
78
|
+
)}`
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function spyFactory(context) {
|
|
83
|
+
const caller = new CustomSpyCaller(context);
|
|
84
|
+
const spy = vi.spyOn(caller, "call");
|
|
85
|
+
const expectToBeCalled = (...args) => expect(spy).toHaveBeenCalledWith(args);
|
|
86
|
+
const expectToBeNotCalled = (...args) => expect(spy).not.toHaveBeenCalledWith(args);
|
|
87
|
+
const callSpy = (...args) => caller.call(args);
|
|
88
|
+
return {
|
|
89
|
+
expectToBeCalled,
|
|
90
|
+
expectToBeNotCalled,
|
|
91
|
+
spy,
|
|
92
|
+
callSpy
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const stubGlobal = (name, stub) => {
|
|
97
|
+
vi.stubGlobal(name, stub);
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const strategies = {
|
|
101
|
+
beforeAll,
|
|
102
|
+
afterEach
|
|
103
|
+
};
|
|
104
|
+
const injectMocks = (func, strategy = "beforeAll") => {
|
|
105
|
+
let afterFn;
|
|
106
|
+
strategies[strategy](() => afterFn = func());
|
|
107
|
+
afterAll(() => {
|
|
108
|
+
clearMocks();
|
|
109
|
+
afterFn?.();
|
|
110
|
+
});
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const injectMatchMediaMock = () => {
|
|
114
|
+
const matcher = new MatchMediaMock();
|
|
115
|
+
injectMocks(() => {
|
|
116
|
+
matcher.clear();
|
|
117
|
+
return () => matcher.destroy();
|
|
118
|
+
}, "afterEach");
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
export { assertHookRendering, assertNotThrowing, assertRendering, clearMocks, injectMatchMediaMock, injectMocks, mockEnv, mockRouter, spyFactory, stubGlobal, twApiMock };
|