xenopomp-essentials 0.5.0-canary.5 → 0.5.0-canary.6
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.cjs +1 -0
- package/cli-tools/index.d.cts +60 -0
- package/eslint/index.cjs +1 -0
- package/eslint/index.d.cts +40 -0
- package/eslint/index.d.ts +1 -1
- package/index.cjs +1 -0
- package/index.d.cts +610 -0
- package/next/index.cjs +11 -0
- package/next/index.d.cts +67 -0
- package/package.json +4 -1
- package/shared/xenopomp-essentials.CO5lcTlK.d.cts +14 -0
- package/vitest/index.cjs +1 -0
- package/vitest/index.d.cts +176 -0
- package/cli-tools/index.mjs +0 -1
- package/eslint/index.mjs +0 -1
- package/next/index.mjs +0 -11
- package/vitest/index.mjs +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const r$1=require("node:path"),zod=require("zod"),e=require("dotenv");var _documentCurrentScript=typeof document<"u"?document.currentScript:null;function _interopDefaultCompat(t){return t&&typeof t=="object"&&"default"in t?t.default:t}const r__default=_interopDefaultCompat(r$1),e__default=_interopDefaultCompat(e),o=zod.z.object({dirname:zod.z.string().optional()}),importMeta=o.parse({url:typeof document>"u"?require("url").pathToFileURL(__filename).href:_documentCurrentScript&&_documentCurrentScript.tagName.toUpperCase()==="SCRIPT"&&_documentCurrentScript.src||new URL("cli-tools/index.cjs",document.baseURI).href});e__default.config({quiet:!0});const r=zod.z.object({DISABLE_MINIFY:zod.z.string().optional().transform(t=>t==="true")});r.parse(process.env);class PathBuilder{paths=[];pushPaths(...s){return this.paths.push(...s),this}cd(...s){return this.pushPaths(...s)}file(s){return this.pushPaths(`./${s}`)}appSource(){return importMeta.dirname?this.pushPaths(r__default.join(r__default.dirname(importMeta.dirname),"../")):this.cwd()}cwd(){return this.pushPaths(process.cwd())}clear(){return this.paths=[],this}build(){return r__default.join(...this.paths)}}exports.PathBuilder=PathBuilder;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fluent interface for creating paths of application.
|
|
3
|
+
*
|
|
4
|
+
* @since 0.0.1
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* import { PathBuilder } from 'xenopomp-essentials/cli-tools';
|
|
8
|
+
*
|
|
9
|
+
* const builder = new PathBuilder();
|
|
10
|
+
*
|
|
11
|
+
* const res = builder
|
|
12
|
+
* .appSource()
|
|
13
|
+
* .cd('./dist/src')
|
|
14
|
+
* .file('.prettierrc')
|
|
15
|
+
* .build();
|
|
16
|
+
*
|
|
17
|
+
* console.log(res); //? C:/Projects/example/node_modules/xenopomp-essentials/dist/src/.prettierrc
|
|
18
|
+
*/
|
|
19
|
+
declare class PathBuilder {
|
|
20
|
+
private paths;
|
|
21
|
+
private pushPaths;
|
|
22
|
+
/**
|
|
23
|
+
* Pushes any custom paths to builder.
|
|
24
|
+
* @since 0.0.1
|
|
25
|
+
* @param paths
|
|
26
|
+
*/
|
|
27
|
+
cd(...paths: string[]): PathBuilder;
|
|
28
|
+
/**
|
|
29
|
+
* Pushes filename to paths.
|
|
30
|
+
* @since 0.0.1
|
|
31
|
+
* @param fileName
|
|
32
|
+
*/
|
|
33
|
+
file<T extends `${string}.${string}`>(fileName: T): PathBuilder;
|
|
34
|
+
/**
|
|
35
|
+
* Pushes path to compiled app directory.
|
|
36
|
+
* Is useful for cli tools that have to access files inside their bundles.
|
|
37
|
+
*
|
|
38
|
+
* It probably may take no effect (if import.meta is not available in a scope).
|
|
39
|
+
* If it is, will push cwd.
|
|
40
|
+
*
|
|
41
|
+
* @since 0.0.1
|
|
42
|
+
*/
|
|
43
|
+
appSource(): PathBuilder;
|
|
44
|
+
/**
|
|
45
|
+
* Gets path of directory where script is running. In cli tools it access
|
|
46
|
+
* path, where cli tool was started.
|
|
47
|
+
* @since 0.0.1
|
|
48
|
+
*/
|
|
49
|
+
cwd(): PathBuilder;
|
|
50
|
+
/**
|
|
51
|
+
* @since 0.0.1
|
|
52
|
+
*/
|
|
53
|
+
clear(): PathBuilder;
|
|
54
|
+
/**
|
|
55
|
+
* @since 0.0.1
|
|
56
|
+
*/
|
|
57
|
+
build(): string;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export { PathBuilder };
|
package/eslint/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const eslintConfig=require("@antfu/eslint-config"),deepmergeTs=require("deepmerge-ts"),t=require("globals"),e=require("eslint-plugin-prettier/recommended"),compat=require("@eslint/compat"),o=require("eslint-plugin-deprecation");function _interopDefaultCompat(n){return n&&typeof n=="object"&&"default"in n?n.default:n}const t__default=_interopDefaultCompat(t),e__default=_interopDefaultCompat(e),o__default=_interopDefaultCompat(o),AUTHOR_NAME="XenoPOMP",AUTHOR_NAME_LOWER=AUTHOR_NAME.toLowerCase();async function react(){return[{files:[eslintConfig.GLOB_JSX,eslintConfig.GLOB_TSX],name:`${AUTHOR_NAME_LOWER}:react`,rules:{"react-refresh/only-export-components":"off","react/no-clone-element":"off","react/no-missing-component-display-name":"off"}}]}async function next(){const n=await eslintConfig.interopDefault(import("@next/eslint-plugin-next"));return[{name:`${AUTHOR_NAME_LOWER}:next`,plugins:{"@next/next":n},rules:{"@next/next/google-font-display":"warn","@next/next/google-font-preconnect":"warn","@next/next/next-script-for-ga":"warn","@next/next/no-async-client-component":"warn","@next/next/no-before-interactive-script-outside-document":"warn","@next/next/no-css-tags":"warn","@next/next/no-head-element":"warn","@next/next/no-html-link-for-pages":"warn","@next/next/no-img-element":"warn","@next/next/no-page-custom-font":"warn","@next/next/no-styled-jsx-in-document":"warn","@next/next/no-sync-scripts":"warn","@next/next/no-title-in-document-head":"warn","@next/next/no-typos":"warn","@next/next/no-unwanted-polyfillio":"warn","@next/next/inline-script-id":"error","@next/next/no-assign-module-variable":"error","@next/next/no-document-import-in-page":"error","@next/next/no-duplicate-head":"error","@next/next/no-head-import-in-document":"error","@next/next/no-script-component-in-head":"error"}}]}async function markdown(){return[{name:`${AUTHOR_NAME_LOWER}:markdown`,files:[eslintConfig.GLOB_MARKDOWN_CODE],rules:{"import/no-unresolved":"off","unused-imports/no-unused-imports":"off","unused-imports/no-unused-vars":"off","no-alert":"off","no-console":"off","no-restricted-imports":"off","no-undef":"off","no-unused-expressions":"off","no-unused-vars":"off","antfu/no-cjs-exports":"off","antfu/no-ts-export-equal":"off","ts/no-redeclare":"off","ts/no-unused-vars":"off","ts/no-var-requires":"off","ts/consistent-type-imports":"off"}}]}async function all(){return[{name:`${AUTHOR_NAME_LOWER}:all`,rules:{"antfu/no-cjs-exports":"off","import/prefer-default-export":"off","import/extensions":"off","no-restricted-globals":"off","node/prefer-global/process":"off","jsonc/comma-dangle":"off","style/jsx-quotes":["error","prefer-double"],"style/jsx-one-expression-per-line":["error",{allow:"single-line"}],"style/arrow-parens":["error","as-needed"],"unused-imports/no-unused-imports":"error","unused-imports/no-unused-vars":["warn",{vars:"all",varsIgnorePattern:"^_",args:"after-used",argsIgnorePattern:"^_"}],"@stylistic/indent":["error",2,{ArrayExpression:1,CallExpression:{arguments:1},flatTernaryExpressions:!1,FunctionDeclaration:{body:1,parameters:1},FunctionExpression:{body:1,parameters:1},ignoreComments:!1,ignoredNodes:["TemplateLiteral *","TSIntersectionType","TSTypeParameterInstantiation","FunctionExpression > .params[decorators.length > 0]","FunctionExpression > .params > :matches(Decorator, :not(:first-child))","ClassBody.body > PropertyDefinition[decorators.length > 0] > .key"],ImportDeclaration:1,MemberExpression:1,ObjectExpression:1,offsetTernaryExpressions:!0,outerIIFEBody:1,SwitchCase:1,VariableDeclarator:1}]}}]}async function old(){return[{name:`${AUTHOR_NAME_LOWER}:old_config`,languageOptions:{globals:{...t__default.browser,...t__default.jquery,...t__default.node,document:"readonly",navigator:"readonly",window:"readonly"}},ignores:["**/.next/*","**/node_modules/*","**/.github/*","cypress","**/__tests__/e2e/*","*.json","**/*.d.ts",".eslintrc.js","eslint.config.js",".prettierrc",".stylelintrc.js","tsconfig.json","package.json","*.md","*.config.ts","*.config.js","*.md"]},{name:`${AUTHOR_NAME_LOWER}:rules_breakup_1`,rules:{"@next/next/no-duplicate-head":"off"}},{name:`${AUTHOR_NAME_LOWER}:rules_breakup_2`,rules:{"style/operator-linebreak":"off","test/consistent-test-it":"off","test/prefer-lowercase-title":"off","style/jsx-quotes":"off","style/multiline-ternary":"off","style/indent":"off"},ignores:["cypress"]},{name:`${AUTHOR_NAME_LOWER}:prettier`,rules:{"antfu/if-newline":"off"}}]}async function prettier(){return[e__default]}async function deprecation(n,s){return[{name:"Deprecation plugin",languageOptions:{parserOptions:{project:s?.tsconfigPath??"./tsconfig.json",projectSource:!0}},plugins:{deprecation:compat.fixupPluginRules(o__default)},rules:{"deprecation/deprecation":n},files:["**/*.ts","**/*.tsx"]}]}function m(n,...s){const r=[];return n={...n,react:deepmergeTs.deepmerge(!0,n?.react),vue:deepmergeTs.deepmerge(!1,n?.vue),jsonc:deepmergeTs.deepmerge(!1,n?.jsonc),yaml:deepmergeTs.deepmerge(!1,n?.yaml),stylistic:deepmergeTs.deepmerge({semi:!0,quotes:"single"},n?.stylistic),typescript:deepmergeTs.deepmerge({overrides:{"ts/consistent-type-definitions":["error","interface"],"ts/interface-name-prefix":"off","ts/explicit-function-return-type":"off","ts/explicit-module-boundary-types":"off","ts/no-explicit-any":"off"}},n?.typescript),rules:deepmergeTs.deepmerge({"import/order":"off","react/react-in-jsx-scope":"off","react/prop-types":"off","antfu/top-level-function":"off","perfectionist/sort-imports":"off","perfectionist/sort-named-imports":"off","perfectionist/sort-named-exports":"off","antfu/consistent-chaining":"off","perfectionist/sort-exports":"off","style/no-multiple-empty-lines":"off"},n?.rules),deprecation:n?.deprecation,tsconfigPath:n?.tsconfigPath},(n.react??!0)&&r.push(react()),(n.all??!0)&&r.push(all()),(n.next??!1)&&r.push(next()),(n.markdown??!0)&&r.push(markdown()),n?.deprecation&&r.push(deprecation(n?.deprecation??"warn",{tsconfigPath:n?.tsconfigPath})),r.push(old()),r.push(prettier()),eslintConfig.antfu(n,...r,...s)}module.exports=m;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { antfu, OptionsConfig, TypedFlatConfigItem } from '@antfu/eslint-config';
|
|
2
|
+
import { Linter } from 'eslint';
|
|
3
|
+
|
|
4
|
+
interface CustomConfig {
|
|
5
|
+
all?: boolean;
|
|
6
|
+
next?: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
type UserConfigItem = Parameters<typeof antfu>[1];
|
|
10
|
+
type Configs = ReturnType<typeof antfu>;
|
|
11
|
+
|
|
12
|
+
interface CustomOptions {
|
|
13
|
+
deprecation?: Linter.RuleEntry;
|
|
14
|
+
tsconfigPath?: string;
|
|
15
|
+
}
|
|
16
|
+
type Options = OptionsConfig & CustomConfig & TypedFlatConfigItem & CustomOptions;
|
|
17
|
+
/**
|
|
18
|
+
* XenoPOMP`s default ESLint config. Uses @antfu/eslint-config under the hood.
|
|
19
|
+
*
|
|
20
|
+
* @param options
|
|
21
|
+
* @param userConfigs
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* export default xenopomp(
|
|
25
|
+
* // Setup antfu config
|
|
26
|
+
* {
|
|
27
|
+
* react: true,
|
|
28
|
+
* next: false,
|
|
29
|
+
* },
|
|
30
|
+
* // User configs
|
|
31
|
+
* {
|
|
32
|
+
* name: 'My custom config',
|
|
33
|
+
* rules: { ... }
|
|
34
|
+
* },
|
|
35
|
+
* );
|
|
36
|
+
*/
|
|
37
|
+
declare function xenopomp(options?: Options, ...userConfigs: UserConfigItem[]): Configs;
|
|
38
|
+
|
|
39
|
+
export = xenopomp;
|
|
40
|
+
export type { Configs, CustomConfig, Options, UserConfigItem };
|
package/eslint/index.d.ts
CHANGED
|
@@ -36,5 +36,5 @@ type Options = OptionsConfig & CustomConfig & TypedFlatConfigItem & CustomOption
|
|
|
36
36
|
*/
|
|
37
37
|
declare function xenopomp(options?: Options, ...userConfigs: UserConfigItem[]): Configs;
|
|
38
38
|
|
|
39
|
-
export
|
|
39
|
+
export = xenopomp;
|
|
40
40
|
export type { Configs, CustomConfig, Options, UserConfigItem };
|
package/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const transliteration=require("transliteration");function pipe(t){function e(r){return t(r)}return e.pipe=r=>pipe(i=>r(t(i))),e}function capitalize(t){return t.charAt(0).toUpperCase()+t.slice(1)}function uncapitalize(t){return t.charAt(0).toLowerCase()+t.slice(1)}const parseVersion=t=>{const e=t.match(/(\d\.){2}\d/gi)?.at(0)||null,r=t.match(/(?<=-)\w+(?=\.\d)/gi)?.at(0),i=t.match(/(?<=((\d\.){2}\d-\w+\.))\d+/gi)?.at(0);return{version:e,preid:r,prerelease:i}},transliterate=transliteration.transliterate,minmax=(t,[e,r])=>e&&t<=e?e:r&&t>=r?r:t;function jsxDotNotation(t,e){return Object.assign(t,e)}exports.capitalize=capitalize,exports.jsxDotNotation=jsxDotNotation,exports.minmax=minmax,exports.parseVersion=parseVersion,exports.pipe=pipe,exports.transliterate=transliterate,exports.uncapitalize=uncapitalize;
|
package/index.d.cts
ADDED
|
@@ -0,0 +1,610 @@
|
|
|
1
|
+
export { O as Optional, P as PromiseOr, U as Undefinable } from './shared/xenopomp-essentials.CO5lcTlK.cjs';
|
|
2
|
+
import { ElementType, ComponentProps, FC, ReactNode, Dispatch, SetStateAction } from 'react';
|
|
3
|
+
import { Jsonifiable } from 'type-fest';
|
|
4
|
+
import * as transliteration from 'transliteration';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Matches any object but not arrays, class instances etc.
|
|
8
|
+
* @since 0.0.1
|
|
9
|
+
*/
|
|
10
|
+
type AnyObject = Record<PropertyKey, unknown>;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* This type stands for empty object type.
|
|
14
|
+
*
|
|
15
|
+
* @since 0.0.1
|
|
16
|
+
* @example
|
|
17
|
+
* const message: EmptyObject = { type: string; }; // Will cause error.
|
|
18
|
+
*/
|
|
19
|
+
type EmptyObject = Record<PropertyKey, never>;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Simple alias for creating function types. You can use it for type guards
|
|
23
|
+
* as representation of any function, also you can create cleaner type declarations
|
|
24
|
+
* for functions.
|
|
25
|
+
*
|
|
26
|
+
* @since 0.0.1
|
|
27
|
+
* @example
|
|
28
|
+
* type MyFn = Fn<[a: string, b: string], string>;
|
|
29
|
+
*/
|
|
30
|
+
type Fn<Args extends any[] = any[], Res = unknown> = (...args: Args) => Res;
|
|
31
|
+
|
|
32
|
+
type ParamObj<P extends string> = Record<P, string>;
|
|
33
|
+
/**
|
|
34
|
+
* Represents Next.js routing params.
|
|
35
|
+
* @since 0.0.1
|
|
36
|
+
*/
|
|
37
|
+
interface NextParams<P extends string> {
|
|
38
|
+
params: ParamObj<P>;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Represents Next.js routing search params.
|
|
42
|
+
* @since 0.0.1
|
|
43
|
+
*/
|
|
44
|
+
interface NextSearchParams<P extends string> {
|
|
45
|
+
searchParams: ParamObj<P>;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* This type describes Next error page params.
|
|
49
|
+
* @since 0.0.1
|
|
50
|
+
*/
|
|
51
|
+
interface NextErrorParams<E extends Error = any> {
|
|
52
|
+
error: E;
|
|
53
|
+
reset: () => void;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* This type wraps ComponentProps<A> to your FC.
|
|
58
|
+
*
|
|
59
|
+
* - __A__ - element type
|
|
60
|
+
* - __P__ - wrapping props
|
|
61
|
+
* - __Ex__ - excluded component props (for example, if you do not want to include 'children' prop in component)
|
|
62
|
+
*
|
|
63
|
+
* @since 0.0.1
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* type VariableComponentPropsWithChildren = ComponentProps<VariableFC<'div'>>;
|
|
67
|
+
* type VariableComponentPropsWithoutChildren = ComponentProps<VariableFC<'div', {}, 'children'>>;
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* // With children
|
|
71
|
+
* const VariableComponent: VariableFC<'section', { variant?: 'default' }> = ({ variant, ...props }) => {
|
|
72
|
+
* return <section {...props}></section>
|
|
73
|
+
* }
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* // Without children
|
|
77
|
+
* const VariableComponent: VariableFC<'section', { variant?: 'default' }, 'children'> = ({ variant, ...props }) => {
|
|
78
|
+
* return (
|
|
79
|
+
* <section {...props}>
|
|
80
|
+
* <div>Insert your own children</div>
|
|
81
|
+
* </section>
|
|
82
|
+
* );
|
|
83
|
+
* }
|
|
84
|
+
*/
|
|
85
|
+
type VariableFC<A extends ElementType, P = unknown, Ex extends keyof ComponentProps<A> | undefined = undefined> = FC<P & WeakOmit<ComponentProps<A>, Ex>>;
|
|
86
|
+
/**
|
|
87
|
+
* Works similar to {@link VariableFC}, but return type is Promise<ReactNode>;
|
|
88
|
+
* @since 0.0.1
|
|
89
|
+
*/
|
|
90
|
+
type AsyncVariableFC<A extends ElementType, P = unknown, Ex extends keyof ComponentProps<A> | undefined = undefined> = AsyncFC<P & WeakOmit<ComponentProps<A>, Ex>>;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Same as **FC** (or FunctionalComponent), but it returns Promise.
|
|
94
|
+
*
|
|
95
|
+
* @since 0.0.1
|
|
96
|
+
* @example
|
|
97
|
+
* const Header: AsyncFC<HeaderProps> = async ({}) => {
|
|
98
|
+
* // Do async stuff here...
|
|
99
|
+
*
|
|
100
|
+
* return <div></div>;
|
|
101
|
+
* };
|
|
102
|
+
*/
|
|
103
|
+
type AsyncFC<T = unknown> = ReplaceReturnType<FC<T>, Promise<ReactNode>>;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Type of set state function from useState.
|
|
107
|
+
*
|
|
108
|
+
* @since 0.0.1
|
|
109
|
+
* @example
|
|
110
|
+
* // typeof setState => SetState<string>
|
|
111
|
+
* const [state, setState] = useState<string>('example');
|
|
112
|
+
*/
|
|
113
|
+
type SetState<TType> = Dispatch<SetStateAction<TType>>;
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* This type allows you to make children that can be function.
|
|
117
|
+
*
|
|
118
|
+
* @since 0.0.1
|
|
119
|
+
* @example
|
|
120
|
+
* type Child = FunctionalChildren<[options: string]>;
|
|
121
|
+
* // ReactNode | ((options: string) => ReactNode)
|
|
122
|
+
*/
|
|
123
|
+
type FunctionalChildren<Args extends any[]> = ReactNode | ((...args: Args) => ReactNode);
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* @deprecated use {@link FCProps} instead.
|
|
127
|
+
*/
|
|
128
|
+
type FcProps<Comp> = FCProps<Comp>;
|
|
129
|
+
/**
|
|
130
|
+
* Extracts type of props from FC type.
|
|
131
|
+
*
|
|
132
|
+
* @since 0.0.1
|
|
133
|
+
* @example
|
|
134
|
+
* type Props = FcProps<FC<{ align?: boolean }>>;
|
|
135
|
+
* // ^? { align?: boolean }
|
|
136
|
+
*
|
|
137
|
+
* type VariableProps = FcProps<VariableFC<'button', { notAlign?: boolean }>>;
|
|
138
|
+
* // ^? {notAlign?: boolean} & Omit<ClassAttributes<HTMLButtonElement> & React.ButtonHTMLAttributes<HTMLButtonElement>, undefined>
|
|
139
|
+
*/
|
|
140
|
+
type FCProps<Comp> = Comp extends FC<infer Props> ? Props : never;
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Matches any proper React component.
|
|
144
|
+
*/
|
|
145
|
+
type AnyFC = FC<unknown>;
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Type that represents data-{attr} keys.
|
|
149
|
+
*/
|
|
150
|
+
type Attribute = `data-${string}`;
|
|
151
|
+
/**
|
|
152
|
+
* Matches any proper data-{attr} keys.
|
|
153
|
+
*/
|
|
154
|
+
type DataAttributeShape = Record<Attribute, any>;
|
|
155
|
+
/**
|
|
156
|
+
* Represents React`s data-{attr} properties for components.
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* type AdditionalAttributes = DataAttributes<{ 'data-disabled': boolean }>;
|
|
160
|
+
*
|
|
161
|
+
* const attrs: AdditionalAttributes = {
|
|
162
|
+
* 'data-disabled': false, // this attr is required
|
|
163
|
+
* };
|
|
164
|
+
*/
|
|
165
|
+
type DataAttributes<Shape extends DataAttributeShape> = Shape;
|
|
166
|
+
|
|
167
|
+
type VariableProps<A extends ElementType, P = unknown, Ex extends keyof ComponentProps<A> | undefined = undefined> = FCProps<VariableFC<A, P, Ex>>;
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Make any async func synchronous.
|
|
171
|
+
*
|
|
172
|
+
* Return never, if __Func__ is not a function, actually.
|
|
173
|
+
*
|
|
174
|
+
* @since 0.0.1
|
|
175
|
+
* @example
|
|
176
|
+
* type NormalFunc = Synchronous<(one: string, two: number) => void>; // (one: string, two: number) => void
|
|
177
|
+
* type AsyncFunc = Synchronous<(one: string, two: number) => Promise<void>>; // (one: string, two: number) => void
|
|
178
|
+
* type NotAFunc = Synchronous<'sus'>; // never
|
|
179
|
+
*/
|
|
180
|
+
type Synchronous<Func> = Func extends Fn ? Func extends (...args: any[]) => Promise<infer Result> ? ReplaceReturnType<Func, Result> : Func : never;
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Removes readonly from type.
|
|
184
|
+
* @since 0.0.1
|
|
185
|
+
*/
|
|
186
|
+
type Writeable<T> = {
|
|
187
|
+
-readonly [P in keyof T]: T[P];
|
|
188
|
+
};
|
|
189
|
+
/**
|
|
190
|
+
* @deprecated Use {@link WriteableDeep} instead.
|
|
191
|
+
*/
|
|
192
|
+
type DeepWriteable<T> = WriteableDeep<T>;
|
|
193
|
+
/**
|
|
194
|
+
* Removes readonly from type deeply.
|
|
195
|
+
* @since 0.0.1
|
|
196
|
+
*/
|
|
197
|
+
type WriteableDeep<T> = {
|
|
198
|
+
-readonly [P in keyof T]: DeepWriteable<T[P]>;
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Checks if type **T** matches type **M**.
|
|
203
|
+
*
|
|
204
|
+
* @since 0.0.1
|
|
205
|
+
*
|
|
206
|
+
* @example Not matching
|
|
207
|
+
* type ViewStyles = {
|
|
208
|
+
* paddingHorizontal: number
|
|
209
|
+
* }
|
|
210
|
+
*
|
|
211
|
+
* type Styles = MatchType<{}, ViewStyles>; // TSERROR
|
|
212
|
+
*
|
|
213
|
+
* @example Matching
|
|
214
|
+
* type ViewStyles = {
|
|
215
|
+
* paddingHorizontal: number;
|
|
216
|
+
* };
|
|
217
|
+
*
|
|
218
|
+
* // No error
|
|
219
|
+
* type Styles = MatchType<
|
|
220
|
+
* {
|
|
221
|
+
* paddingHorizontal: number;
|
|
222
|
+
* },
|
|
223
|
+
* ViewStyles
|
|
224
|
+
* >;
|
|
225
|
+
*/
|
|
226
|
+
type MatchType<T extends M, M> = T extends M ? T : never;
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* This type gets type of array`s item.
|
|
230
|
+
*
|
|
231
|
+
* @since 0.0.1
|
|
232
|
+
* @example
|
|
233
|
+
* type Super = ArrayType<string[]>; // string
|
|
234
|
+
*
|
|
235
|
+
* type Good = ArrayType<(string|number)[]>; // string | number
|
|
236
|
+
*/
|
|
237
|
+
type ArrayType<T> = T extends Array<infer A> ? A : never;
|
|
238
|
+
type ArrayItemType<T> = ArrayType<T>;
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Get return type of function that returns Promise ((...args: any) => Promise<any>).
|
|
242
|
+
*
|
|
243
|
+
* @since 0.0.1
|
|
244
|
+
* @example
|
|
245
|
+
* const doSomething = async (): Promise<string|number> => {
|
|
246
|
+
* return 'result';
|
|
247
|
+
* }
|
|
248
|
+
*
|
|
249
|
+
* type Something = PromiseReturnType<typeof doSomething>;
|
|
250
|
+
* // string|number
|
|
251
|
+
*/
|
|
252
|
+
type AsyncReturnType<F extends (...args: any[]) => Promise<any>> = Awaited<ReturnType<F>>;
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* @deprecated Use {@link InjectDeep} instead.
|
|
256
|
+
*/
|
|
257
|
+
type DeepInject<T, I extends AnyObject> = InjectDeep<T, I>;
|
|
258
|
+
/**
|
|
259
|
+
* Recursively add some type inside all keys of target type.
|
|
260
|
+
*
|
|
261
|
+
* @since 0.0.1
|
|
262
|
+
* @example
|
|
263
|
+
* type Sups = DeepInject<{ supa: { sups: number } }, { _ignore: boolean }>;
|
|
264
|
+
* const asp: Sups = { supa: { sups: 1, _ignore: false }, _ignore: false };
|
|
265
|
+
*/
|
|
266
|
+
type InjectDeep<T, I extends AnyObject> = T extends object ? {
|
|
267
|
+
[K in keyof T]: T[K] extends object ? T[K] & I & DeepInject<T[K], I> : T[K];
|
|
268
|
+
} & I : T;
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Removes undefined from union type.
|
|
272
|
+
* @since 0.0.1
|
|
273
|
+
* @deprecated Use {@link NonNullable} instead.
|
|
274
|
+
*/
|
|
275
|
+
type Defined<T> = Exclude<T, undefined>;
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Return never if type does not match JSON schema.
|
|
279
|
+
*
|
|
280
|
+
* @since 0.0.1
|
|
281
|
+
* @example
|
|
282
|
+
* type Schema = Jsonish<{ sus: string; am: string; }>; // OK
|
|
283
|
+
* type AlterSchema = Jsonish<{ sus: string; am: () => {}; }>; // Causes error
|
|
284
|
+
*/
|
|
285
|
+
type Jsonish<T extends Jsonifiable> = T extends Jsonifiable ? T : never;
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Modifies K (Key) in T (Type), replace it with R (Replacement).
|
|
289
|
+
*
|
|
290
|
+
* @since 0.0.1
|
|
291
|
+
* @example
|
|
292
|
+
* type ExcludedStore = Modify<IStore, 'appSettings', { appName: 'Simple name' }>; // Key in IStore has been replaced with new type.
|
|
293
|
+
*/
|
|
294
|
+
type Modify<T, K extends keyof T, R> = Omit<T, K> & {
|
|
295
|
+
[Key in K]: R;
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Make union type of T and null.
|
|
300
|
+
* @since 0.0.1
|
|
301
|
+
*/
|
|
302
|
+
type Nullable<T> = T | null;
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Get typeof key of Record.
|
|
306
|
+
*
|
|
307
|
+
* @since 0.0.1
|
|
308
|
+
* @example
|
|
309
|
+
* type Key = RecordKey<Record<string, number>>; // string
|
|
310
|
+
*/
|
|
311
|
+
type RecordKey<R extends Record<any, any>> = R extends Record<infer K, any> ? K : never;
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Get typeof value of Record.
|
|
315
|
+
*
|
|
316
|
+
* @since 0.0.1
|
|
317
|
+
* @example
|
|
318
|
+
* type Value = RecordValue<Record<string, number>>; // number
|
|
319
|
+
*/
|
|
320
|
+
type RecordValue<R extends Record<any, any>> = R extends Record<any, infer V> ? V : never;
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* This type replace return type of function with other type.
|
|
324
|
+
*
|
|
325
|
+
* @since 0.0.1
|
|
326
|
+
* @example
|
|
327
|
+
* type StringFC<T = {}> = ReplaceReturnType<FC<T>, string>;
|
|
328
|
+
*/
|
|
329
|
+
type ReplaceReturnType<TFn, TR> = TFn extends (...a: infer A) => any ? (...a: A) => TR : never;
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Works as Partial, but makes only specified keys partial.
|
|
333
|
+
*
|
|
334
|
+
* @since 0.0.1
|
|
335
|
+
* @example
|
|
336
|
+
* type Super = SelectivePartial<{
|
|
337
|
+
* name: string;
|
|
338
|
+
* address: {
|
|
339
|
+
* street: string;
|
|
340
|
+
* number: number
|
|
341
|
+
* }
|
|
342
|
+
* }, 'address'>;
|
|
343
|
+
*
|
|
344
|
+
* // Property 'address' will be partial.
|
|
345
|
+
*/
|
|
346
|
+
type SelectivePartial<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* The strict version of Omit. Allows to remove only
|
|
350
|
+
* keys that are presented in T type.
|
|
351
|
+
*
|
|
352
|
+
* @since 0.0.1
|
|
353
|
+
* @example
|
|
354
|
+
* type Tree = {
|
|
355
|
+
* height: number;
|
|
356
|
+
* age: number;
|
|
357
|
+
* name: string;
|
|
358
|
+
* };
|
|
359
|
+
*
|
|
360
|
+
* // TS2344: Type 'weight' does not satisfy the constraint keyof Tree
|
|
361
|
+
* type TreeInfo = StrictOmit<Tree, 'weight'>;
|
|
362
|
+
*
|
|
363
|
+
* // Works just like usual Omit
|
|
364
|
+
* type CorrectTreeInfo = StrictOmit<Tree, 'name'>;
|
|
365
|
+
*/
|
|
366
|
+
type StrictOmit<T, K extends keyof T> = Omit<T, K>;
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Extracts first type from two generics. Is helper type for {@link OneOf} type.
|
|
370
|
+
* @since 0.0.1
|
|
371
|
+
*/
|
|
372
|
+
type OnlyFirst<F, S> = F & {
|
|
373
|
+
[Key in keyof Omit<S, keyof F>]?: never;
|
|
374
|
+
};
|
|
375
|
+
/**
|
|
376
|
+
* Chooses only one of types array.
|
|
377
|
+
*
|
|
378
|
+
* @since 0.0.1
|
|
379
|
+
* @example
|
|
380
|
+
* type Email = {
|
|
381
|
+
* person: string;
|
|
382
|
+
* content: string;
|
|
383
|
+
* address: string;
|
|
384
|
+
* };
|
|
385
|
+
*
|
|
386
|
+
* type Mail = {
|
|
387
|
+
* person: string;
|
|
388
|
+
* content: string;
|
|
389
|
+
* postCode: number;
|
|
390
|
+
* };
|
|
391
|
+
*
|
|
392
|
+
* type Letter = OneOf<[Email, Mail]>;
|
|
393
|
+
*
|
|
394
|
+
* // Will error, cause address is not assignable to type never.
|
|
395
|
+
* const email: Letter = {
|
|
396
|
+
* person: 'person',
|
|
397
|
+
* content: 'content',
|
|
398
|
+
* address: '',
|
|
399
|
+
* postCode: 12,
|
|
400
|
+
* };
|
|
401
|
+
*/
|
|
402
|
+
type OneOf<TypesArray extends any[], Res = never, AllProperties = MergeTypes<TypesArray>> = TypesArray extends [infer Head, ...infer Rem] ? OneOf<Rem, Res | OnlyFirst<Head, AllProperties>, AllProperties> : Res;
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* Merge array of types to one type.
|
|
406
|
+
* @since 0.0.1
|
|
407
|
+
*/
|
|
408
|
+
type MergeTypes<TypesArray extends any[], Res = EmptyObject> = TypesArray extends [infer Head, ...infer Rem] ? MergeTypes<Rem, Res & Head> : Res;
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Allows to pass undefined as Omit`s generic. Weakly omits type.
|
|
412
|
+
*
|
|
413
|
+
* @since 0.0.1
|
|
414
|
+
* @example
|
|
415
|
+
* // Will not omit any keys
|
|
416
|
+
* type Lib = WeakOmit<{ bookCount: number; date: string }, undefined>;
|
|
417
|
+
*
|
|
418
|
+
* // Will omit
|
|
419
|
+
* type LibStrong = WeakOmit<{ bookCount: number; date: string }, 'date'>;
|
|
420
|
+
*/
|
|
421
|
+
type WeakOmit<Obj extends AnyObject, Keys extends keyof Obj | undefined = undefined> = Keys extends keyof Obj ? Omit<Obj, Keys> : Obj;
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* Makes types don`t merging in unions.
|
|
425
|
+
*
|
|
426
|
+
* @since 0.0.1
|
|
427
|
+
* @example
|
|
428
|
+
* type Languages = 'TypeScript' | 'JavaScript' | Lenient<string>;
|
|
429
|
+
* // ^? "TypeScript" | "JavaScript" | string
|
|
430
|
+
*/
|
|
431
|
+
type Lenient<T> = T & {};
|
|
432
|
+
/**
|
|
433
|
+
* This type allows any string, but also saves compiler`s autocomplete
|
|
434
|
+
* feature.
|
|
435
|
+
*
|
|
436
|
+
* @since 0.0.1
|
|
437
|
+
* @example
|
|
438
|
+
* type Languages = 'TypeScript' | 'JavaScript';
|
|
439
|
+
*
|
|
440
|
+
* function handleLanguage(lang: LenientAutocomplete<Languages>) {
|
|
441
|
+
* // ^? string (but autocomplete feature is still here)
|
|
442
|
+
* console.log(lang);
|
|
443
|
+
* }
|
|
444
|
+
*/
|
|
445
|
+
type LenientAutocomplete<T extends string> = T | Lenient<string>;
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Presents plain object in pretty form.
|
|
449
|
+
*/
|
|
450
|
+
type Prettify<T> = {
|
|
451
|
+
[K in keyof T]: T[K];
|
|
452
|
+
} & {};
|
|
453
|
+
/**
|
|
454
|
+
* Presents object in pretty form recursively.
|
|
455
|
+
*/
|
|
456
|
+
type PrettifyDeep<T> = {
|
|
457
|
+
[K in keyof T]: T[K] extends AnyObject ? Prettify<PrettifyDeep<T[K]>> : T[K];
|
|
458
|
+
};
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* Creates pipelines of functions that will be executed only
|
|
462
|
+
* when you will call whole pipeline.
|
|
463
|
+
*
|
|
464
|
+
* @since 0.0.1
|
|
465
|
+
*
|
|
466
|
+
* @param fn
|
|
467
|
+
*
|
|
468
|
+
* @example
|
|
469
|
+
* const stringToDateAndTime = pipe(Date.parse)
|
|
470
|
+
* .pipe(n => new Date(n))
|
|
471
|
+
* .pipe(d => d.toDateString())
|
|
472
|
+
* .pipe(s => s.split('T'))
|
|
473
|
+
* .pipe(([date, time]) => ({ date, time }));
|
|
474
|
+
*
|
|
475
|
+
* const res = stringToDateAndTime('Jan 1, 2024');
|
|
476
|
+
* // ^? { date: string | undefined; time: string | undefined }
|
|
477
|
+
*
|
|
478
|
+
* @see https://youtu.be/bH61wRMqp-o?si=D-2Az-_dUFBxG9HG&t=429
|
|
479
|
+
*/
|
|
480
|
+
declare function pipe<A, B>(fn: (a: A) => B): {
|
|
481
|
+
(a: A): B;
|
|
482
|
+
pipe<C>(fn2: (b: B) => C): {
|
|
483
|
+
(a: A): C;
|
|
484
|
+
pipe<C_1>(fn2: (b: C) => C_1): {
|
|
485
|
+
(a: A): C_1;
|
|
486
|
+
pipe<C_2>(fn2: (b: C_1) => C_2): {
|
|
487
|
+
(a: A): C_2;
|
|
488
|
+
pipe<C_3>(fn2: (b: C_2) => C_3): {
|
|
489
|
+
(a: A): C_3;
|
|
490
|
+
pipe<C_4>(fn2: (b: C_3) => C_4): {
|
|
491
|
+
(a: A): C_4;
|
|
492
|
+
pipe<C_5>(fn2: (b: C_4) => C_5): {
|
|
493
|
+
(a: A): C_5;
|
|
494
|
+
pipe<C_6>(fn2: (b: C_5) => C_6): {
|
|
495
|
+
(a: A): C_6;
|
|
496
|
+
pipe<C_7>(fn2: (b: C_6) => C_7): {
|
|
497
|
+
(a: A): C_7;
|
|
498
|
+
pipe<C_8>(fn2: (b: C_7) => C_8): {
|
|
499
|
+
(a: A): C_8;
|
|
500
|
+
pipe<C_9>(fn2: (b: C_8) => C_9): {
|
|
501
|
+
(a: A): C_9;
|
|
502
|
+
pipe<C_10>(fn2: (b: C_9) => C_10): /*elided*/ any;
|
|
503
|
+
};
|
|
504
|
+
};
|
|
505
|
+
};
|
|
506
|
+
};
|
|
507
|
+
};
|
|
508
|
+
};
|
|
509
|
+
};
|
|
510
|
+
};
|
|
511
|
+
};
|
|
512
|
+
};
|
|
513
|
+
};
|
|
514
|
+
|
|
515
|
+
/**
|
|
516
|
+
* Capitalizes string (makes first letter uppercase).
|
|
517
|
+
* @since 0.0.1
|
|
518
|
+
*/
|
|
519
|
+
declare function capitalize<T extends string>(str: T): Capitalize<T>;
|
|
520
|
+
/**
|
|
521
|
+
* Un-capitalizes string (makes first letter lowercase).
|
|
522
|
+
* @since 0.0.1
|
|
523
|
+
*/
|
|
524
|
+
declare function uncapitalize<T extends string>(str: T): Uncapitalize<T>;
|
|
525
|
+
|
|
526
|
+
type Preid = 'alpha' | 'beta' | 'rc';
|
|
527
|
+
interface VersionData {
|
|
528
|
+
/** Version in format: (__``x.x.x``__-beta.x) */
|
|
529
|
+
version: Nullable<string>;
|
|
530
|
+
/** Version preid. (x.x.x-__``beta``__.x) */
|
|
531
|
+
preid?: LenientAutocomplete<Preid>;
|
|
532
|
+
/** Number of pre-release. (x.x.x-beta.__``12``__) */
|
|
533
|
+
prerelease?: string;
|
|
534
|
+
}
|
|
535
|
+
/**
|
|
536
|
+
* Parses version with preid.
|
|
537
|
+
*
|
|
538
|
+
* @since 0.0.1
|
|
539
|
+
*
|
|
540
|
+
* @param raw
|
|
541
|
+
*
|
|
542
|
+
* @example
|
|
543
|
+
* const { version, preid } = parseVersion('0.0.0-beta.0');
|
|
544
|
+
* // version = '0.0.0'
|
|
545
|
+
* // preid = 'beta'
|
|
546
|
+
*/
|
|
547
|
+
declare const parseVersion: (raw: string) => VersionData;
|
|
548
|
+
|
|
549
|
+
/**
|
|
550
|
+
* Transforms any given string to transliterated variant.
|
|
551
|
+
*
|
|
552
|
+
* @since 0.0.1
|
|
553
|
+
*/
|
|
554
|
+
declare const transliterate: transliteration.TransliterateFunction;
|
|
555
|
+
|
|
556
|
+
/**
|
|
557
|
+
* Constraints number with min and max values.
|
|
558
|
+
*
|
|
559
|
+
* @example Min value
|
|
560
|
+
* console.log({
|
|
561
|
+
* ogNum: 1, // 1
|
|
562
|
+
* minmax: minmax(1, [2, undefined]), // 2
|
|
563
|
+
* });
|
|
564
|
+
*
|
|
565
|
+
* @example Max value
|
|
566
|
+
* console.log({
|
|
567
|
+
* ogNum: 1001, // 1001
|
|
568
|
+
* minmax: minmax(1001, [undefined, 900]), // 900
|
|
569
|
+
* });
|
|
570
|
+
*
|
|
571
|
+
* @example Min and max value
|
|
572
|
+
* console.log({
|
|
573
|
+
* ogNum: 600, // 600
|
|
574
|
+
* minmax: minmax(1001, [2, 900]), // 600
|
|
575
|
+
* });
|
|
576
|
+
*/
|
|
577
|
+
declare const minmax: (num: number, [min, max]: [min: number | undefined, max: number | undefined]) => number;
|
|
578
|
+
|
|
579
|
+
/**
|
|
580
|
+
* Creates properly type object with jsxDotNotation.
|
|
581
|
+
*
|
|
582
|
+
* @param comp
|
|
583
|
+
* @param rest
|
|
584
|
+
*
|
|
585
|
+
* @example
|
|
586
|
+
* const FlexComp: FC<PropsWithChildren> = ({ children }) => <div>{children}</div>;
|
|
587
|
+
* const FlexRow: FC<PropsWithChildren & { short?: boolean }> = ({ children }) => (
|
|
588
|
+
* <div>{children}</div>
|
|
589
|
+
* );
|
|
590
|
+
* const FlexCol: FC<PropsWithChildren> = ({ children }) => <div>{children}</div>;
|
|
591
|
+
*
|
|
592
|
+
* const Flex = jsxDotNotation(FlexComp, {
|
|
593
|
+
* Row: FlexRow,
|
|
594
|
+
* Col: FlexCol,
|
|
595
|
+
* });
|
|
596
|
+
*
|
|
597
|
+
* const Am = () => {
|
|
598
|
+
* return (
|
|
599
|
+
* <Flex>
|
|
600
|
+
* <Flex.Row short>
|
|
601
|
+
* <Flex.Col></Flex.Col>
|
|
602
|
+
* </Flex.Row>
|
|
603
|
+
* </Flex>
|
|
604
|
+
* );
|
|
605
|
+
* };
|
|
606
|
+
*/
|
|
607
|
+
declare function jsxDotNotation<Props = EmptyObject, Rest extends Record<string, FC<any>> = EmptyObject>(comp: FC<Props>, rest: Rest): FC<Props> & Rest;
|
|
608
|
+
|
|
609
|
+
export { capitalize, jsxDotNotation, minmax, parseVersion, pipe, transliterate, uncapitalize };
|
|
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/next/index.cjs
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";const i=require("next/script");function _interopDefaultCompat(t){return t&&typeof t=="object"&&"default"in t?t.default:t}const i__default=_interopDefaultCompat(i),ReactScan=()=>React.createElement("script",{src:"https://unpkg.com/react-scan/dist/auto.global.js",async:!0}),Metrika=({id:t,clickMap:e=!0,trackLinks:a=!0,accurateTrackBounce:c=!0})=>React.createElement(i__default,{id:"metrika-counter",strategy:"afterInteractive"},` (function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
|
|
2
|
+
m[i].l=1*new Date();
|
|
3
|
+
for (var j = 0; j < document.scripts.length; j++) {if (document.scripts[j].src === r) { return; }}
|
|
4
|
+
k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
|
|
5
|
+
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
|
|
6
|
+
|
|
7
|
+
ym(${t}, "init", {
|
|
8
|
+
clickmap:${e},
|
|
9
|
+
trackLinks:${a},
|
|
10
|
+
accurateTrackBounce:${c}
|
|
11
|
+
});`);exports.Metrika=Metrika,exports.ReactScan=ReactScan;
|
package/next/index.d.cts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Adds react-scan to your Next.js application.
|
|
5
|
+
* @constructor
|
|
6
|
+
* @since 0.0.1
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* import { ReactScan } from 'xenopomp-essentials/next';
|
|
10
|
+
*
|
|
11
|
+
* export default function RootLayout({
|
|
12
|
+
* children,
|
|
13
|
+
* }: {
|
|
14
|
+
* children: React.ReactNode
|
|
15
|
+
* }) {
|
|
16
|
+
* return (
|
|
17
|
+
* <html lang="en">
|
|
18
|
+
* <head>
|
|
19
|
+
* <ReactScan />
|
|
20
|
+
* </head>
|
|
21
|
+
* <body>{children}</body>
|
|
22
|
+
* </html>
|
|
23
|
+
* )
|
|
24
|
+
*}
|
|
25
|
+
*/
|
|
26
|
+
declare const ReactScan: FC<unknown>;
|
|
27
|
+
|
|
28
|
+
interface MetrikaProps {
|
|
29
|
+
/**
|
|
30
|
+
* ID of your Yandex.Metrika`s counter.
|
|
31
|
+
* Locate at dashboard.
|
|
32
|
+
*/
|
|
33
|
+
id: number;
|
|
34
|
+
clickMap?: boolean;
|
|
35
|
+
trackLinks?: boolean;
|
|
36
|
+
accurateTrackBounce?: boolean;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* This component allows you to use Yandex.Metrika
|
|
41
|
+
* in your Next.js projects.
|
|
42
|
+
*
|
|
43
|
+
* @since 0.0.1
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* import { Metrika } from 'xenopomp-essentials/next';
|
|
47
|
+
*
|
|
48
|
+
* export default function RootLayout({
|
|
49
|
+
* children,
|
|
50
|
+
* }: {
|
|
51
|
+
* children: React.ReactNode
|
|
52
|
+
* }) {
|
|
53
|
+
* return (
|
|
54
|
+
* <html lang="en">
|
|
55
|
+
* <head>
|
|
56
|
+
* <Metrika id={123456789} />
|
|
57
|
+
* </head>
|
|
58
|
+
* <body>{children}</body>
|
|
59
|
+
* </html>
|
|
60
|
+
* )
|
|
61
|
+
* }
|
|
62
|
+
*
|
|
63
|
+
* @see https://metrika.yandex.ru
|
|
64
|
+
*/
|
|
65
|
+
declare const Metrika: FC<MetrikaProps>;
|
|
66
|
+
|
|
67
|
+
export { Metrika, ReactScan };
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xenopomp-essentials",
|
|
3
|
-
"version": "0.5.0-canary.
|
|
3
|
+
"version": "0.5.0-canary.6",
|
|
4
4
|
"author": "XenoPOMP <101574433+XenoPOMP@users.noreply.github.com>",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"private": false,
|
|
7
|
+
"type": "commonjs",
|
|
7
8
|
"repository": {
|
|
8
9
|
"type": "git",
|
|
9
10
|
"url": "https://github.com/XenoPOMP/xenopomp-essentials-js.git"
|
|
@@ -13,6 +14,7 @@
|
|
|
13
14
|
},
|
|
14
15
|
"scripts": {
|
|
15
16
|
"build": "run-p build:**",
|
|
17
|
+
"postbuild": "cd ./dist ; rimraf **/*.mjs",
|
|
16
18
|
"build:main": "unbuild --config .config/build.config.ts",
|
|
17
19
|
"build:packages:cli": "echo CLI",
|
|
18
20
|
"lint": "run-p lint:**",
|
|
@@ -93,6 +95,7 @@
|
|
|
93
95
|
"pinst": "^3.0.0",
|
|
94
96
|
"prettier": "^3.4.2",
|
|
95
97
|
"react-dom": "^19.2.0",
|
|
98
|
+
"rimraf": "^6.1.2",
|
|
96
99
|
"tsd": "^0.31.2",
|
|
97
100
|
"unbuild": "^3.6.1",
|
|
98
101
|
"vite": "^7.2.4",
|
|
@@ -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.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const vitest=require("vitest"),react=require("@testing-library/react"),o=require("ansi-colors"),c=require("vitest-matchmedia-mock");function _interopDefaultCompat(t){return t&&typeof t=="object"&&"default"in t?t.default:t}const o__default=_interopDefaultCompat(o),c__default=_interopDefaultCompat(c),assertNotThrowing=t=>{vitest.expect(()=>t()).not.toThrow()},assertRendering=(...t)=>{assertNotThrowing(()=>react.render(...t))},assertHookRendering=(...t)=>{assertNotThrowing(()=>react.renderHook(...t))},mockEnv=t=>{vitest.vi.stubEnv("CANONICAL_URL","http://localhost:4242"),vitest.vi.stubEnv("IS_PRODUCTION","false"),t&&Object.entries(t).forEach(([e,s])=>vitest.vi.stubEnv(e,s))},clearMocks=()=>{vitest.vi.clearAllMocks(),vitest.vi.resetAllMocks(),vitest.vi.unstubAllEnvs(),vitest.vi.unstubAllGlobals()},mockRouter=()=>{vitest.vi.mock("next/navigation",()=>({useRouter:()=>({push(){}}),usePathname:()=>"/"}))},twApiMock={addBase:vitest.vi.fn(),addComponents:vitest.vi.fn(),addUtilities:vitest.vi.fn(),addVariant:vitest.vi.fn(),config:vitest.vi.fn(),corePlugins:vitest.vi.fn(),e:vitest.vi.fn(),matchComponents:vitest.vi.fn(),matchUtilities:vitest.vi.fn(),matchVariant:vitest.vi.fn(),theme:vitest.vi.fn()};class r{_executionContext;constructor(e){this._executionContext=e}call(...e){console.debug(`${o__default.blue(`[${this._executionContext}]`)} ${o__default.green(`Custom spy is called with these args: ${o__default.blueBright(e.map(s=>`${s}`).join(", "))}`)}`)}}function spyFactory(t){const e=new r(t),s=vitest.vi.spyOn(e,"call");return{expectToBeCalled:(...n)=>vitest.expect(s).toHaveBeenCalledWith(n),expectToBeNotCalled:(...n)=>vitest.expect(s).not.toHaveBeenCalledWith(n),spy:s,callSpy:(...n)=>e.call(n)}}const stubGlobal=(t,e)=>{vitest.vi.stubGlobal(t,e)},p={beforeAll:vitest.beforeAll,afterEach:vitest.afterEach},injectMocks=(t,e="beforeAll")=>{let s;p[e](()=>s=t()),vitest.afterAll(()=>{clearMocks(),s?.()})},injectMatchMediaMock=()=>{const t=new c__default;injectMocks(()=>(t.clear(),()=>t.destroy()),"afterEach")};exports.assertHookRendering=assertHookRendering,exports.assertNotThrowing=assertNotThrowing,exports.assertRendering=assertRendering,exports.clearMocks=clearMocks,exports.injectMatchMediaMock=injectMatchMediaMock,exports.injectMocks=injectMocks,exports.mockEnv=mockEnv,exports.mockRouter=mockRouter,exports.spyFactory=spyFactory,exports.stubGlobal=stubGlobal,exports.twApiMock=twApiMock;
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { P as PromiseOr, O as Optional } from '../shared/xenopomp-essentials.CO5lcTlK.cjs';
|
|
2
|
+
import { render, renderHook } from '@testing-library/react';
|
|
3
|
+
import * as vitest from 'vitest';
|
|
4
|
+
import { beforeAll, afterEach, Mock } from 'vitest';
|
|
5
|
+
import * as _vitest_spy from '@vitest/spy';
|
|
6
|
+
import { PartialDeep } from 'type-fest';
|
|
7
|
+
|
|
8
|
+
/** Executes function and expects that it won't throw. */
|
|
9
|
+
declare const assertNotThrowing: <T = void>(callable: () => PromiseOr<T>) => void;
|
|
10
|
+
|
|
11
|
+
type RenderArguments = Parameters<typeof render>;
|
|
12
|
+
type RenderHookArguments = Parameters<typeof renderHook>;
|
|
13
|
+
type RenderFunc<Args extends unknown[] = RenderArguments> = (...args: Args) => void;
|
|
14
|
+
/**
|
|
15
|
+
* Renders component and expects that it won`t throw.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* test('It renders', () => {
|
|
19
|
+
* test('It renders', () => {
|
|
20
|
+
* assertRendering(<MyComponent />, {
|
|
21
|
+
* wrapper: RQProvider,
|
|
22
|
+
* });
|
|
23
|
+
* });
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
*/
|
|
27
|
+
declare const assertRendering: RenderFunc;
|
|
28
|
+
/**
|
|
29
|
+
* Renders hook within test React component without having to create that component yourself.
|
|
30
|
+
* Expects that it won't throw error.
|
|
31
|
+
*
|
|
32
|
+
* @param props
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* test('It renders', () => {
|
|
36
|
+
* assertHookRendering(() => useExampleStore());
|
|
37
|
+
* });
|
|
38
|
+
*/
|
|
39
|
+
declare const assertHookRendering: RenderFunc<RenderHookArguments>;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Mocks .env file.
|
|
43
|
+
*
|
|
44
|
+
* @param additionalMocks key-value record of env variables that also have to be mocked.
|
|
45
|
+
*/
|
|
46
|
+
declare const mockEnv: (additionalMocks?: Record<string, string>) => void;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Clear all mocks from Vitest.
|
|
50
|
+
*/
|
|
51
|
+
declare const clearMocks: () => void;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Mock **next/navigation** package.
|
|
55
|
+
*/
|
|
56
|
+
declare const mockRouter: () => void;
|
|
57
|
+
|
|
58
|
+
declare const twApiMock: {
|
|
59
|
+
addBase: vitest.Mock<_vitest_spy.Procedure>;
|
|
60
|
+
addComponents: vitest.Mock<_vitest_spy.Procedure>;
|
|
61
|
+
addUtilities: vitest.Mock<_vitest_spy.Procedure>;
|
|
62
|
+
addVariant: vitest.Mock<_vitest_spy.Procedure>;
|
|
63
|
+
config: vitest.Mock<_vitest_spy.Procedure>;
|
|
64
|
+
corePlugins: vitest.Mock<_vitest_spy.Procedure>;
|
|
65
|
+
e: vitest.Mock<_vitest_spy.Procedure>;
|
|
66
|
+
matchComponents: vitest.Mock<_vitest_spy.Procedure>;
|
|
67
|
+
matchUtilities: vitest.Mock<_vitest_spy.Procedure>;
|
|
68
|
+
matchVariant: vitest.Mock<_vitest_spy.Procedure>;
|
|
69
|
+
theme: vitest.Mock<_vitest_spy.Procedure>;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
type Caller = (...args: any[]) => void;
|
|
73
|
+
/**
|
|
74
|
+
* Creates custom spy factory object that is callable.
|
|
75
|
+
* @param context
|
|
76
|
+
* @example
|
|
77
|
+
* const { callSpy, expectToBeCalled, expectToBeNotCalled } =
|
|
78
|
+
* spyFactory('spyFactory test');
|
|
79
|
+
*
|
|
80
|
+
* // Call spy with some args
|
|
81
|
+
* const args: any[] = [1, 'some', 'args', 2];
|
|
82
|
+
* callSpy(...args);
|
|
83
|
+
*
|
|
84
|
+
* // Run expectation func
|
|
85
|
+
* expectToBeCalled(...args);
|
|
86
|
+
* expectToBeNotCalled(2, 2, 7);
|
|
87
|
+
*/
|
|
88
|
+
declare function spyFactory(context: string): {
|
|
89
|
+
expectToBeCalled: Caller;
|
|
90
|
+
expectToBeNotCalled: Caller;
|
|
91
|
+
spy: vitest.Mock<(...args: any[]) => void>;
|
|
92
|
+
callSpy: Caller;
|
|
93
|
+
};
|
|
94
|
+
|
|
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/cli-tools/index.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import s from"node:path";import{z as r}from"zod";import h from"dotenv";const o=r.object({dirname:r.string().optional()}),e=o.parse(import.meta);h.config({quiet:!0});const a=r.object({DISABLE_MINIFY:r.string().optional().transform(i=>i==="true")});a.parse(process.env);class p{paths=[];pushPaths(...t){return this.paths.push(...t),this}cd(...t){return this.pushPaths(...t)}file(t){return this.pushPaths(`./${t}`)}appSource(){return e.dirname?this.pushPaths(s.join(s.dirname(e.dirname),"../")):this.cwd()}cwd(){return this.pushPaths(process.cwd())}clear(){return this.paths=[],this}build(){return s.join(...this.paths)}}export{p as PathBuilder};
|
package/eslint/index.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{GLOB_JSX as a,GLOB_TSX as i,interopDefault as f,GLOB_MARKDOWN_CODE as p,antfu as c}from"@antfu/eslint-config";import{deepmerge as o}from"deepmerge-ts";import s from"globals";import l from"eslint-plugin-prettier/recommended";import{fixupPluginRules as u}from"@eslint/compat";import m from"eslint-plugin-deprecation";const d="XenoPOMP",t=d.toLowerCase();async function x(){return[{files:[a,i],name:`${t}:react`,rules:{"react-refresh/only-export-components":"off","react/no-clone-element":"off","react/no-missing-component-display-name":"off"}}]}async function y(){const e=await f(import("@next/eslint-plugin-next"));return[{name:`${t}:next`,plugins:{"@next/next":e},rules:{"@next/next/google-font-display":"warn","@next/next/google-font-preconnect":"warn","@next/next/next-script-for-ga":"warn","@next/next/no-async-client-component":"warn","@next/next/no-before-interactive-script-outside-document":"warn","@next/next/no-css-tags":"warn","@next/next/no-head-element":"warn","@next/next/no-html-link-for-pages":"warn","@next/next/no-img-element":"warn","@next/next/no-page-custom-font":"warn","@next/next/no-styled-jsx-in-document":"warn","@next/next/no-sync-scripts":"warn","@next/next/no-title-in-document-head":"warn","@next/next/no-typos":"warn","@next/next/no-unwanted-polyfillio":"warn","@next/next/inline-script-id":"error","@next/next/no-assign-module-variable":"error","@next/next/no-document-import-in-page":"error","@next/next/no-duplicate-head":"error","@next/next/no-head-import-in-document":"error","@next/next/no-script-component-in-head":"error"}}]}async function g(){return[{name:`${t}:markdown`,files:[p],rules:{"import/no-unresolved":"off","unused-imports/no-unused-imports":"off","unused-imports/no-unused-vars":"off","no-alert":"off","no-console":"off","no-restricted-imports":"off","no-undef":"off","no-unused-expressions":"off","no-unused-vars":"off","antfu/no-cjs-exports":"off","antfu/no-ts-export-equal":"off","ts/no-redeclare":"off","ts/no-unused-vars":"off","ts/no-var-requires":"off","ts/consistent-type-imports":"off"}}]}async function w(){return[{name:`${t}:all`,rules:{"antfu/no-cjs-exports":"off","import/prefer-default-export":"off","import/extensions":"off","no-restricted-globals":"off","node/prefer-global/process":"off","jsonc/comma-dangle":"off","style/jsx-quotes":["error","prefer-double"],"style/jsx-one-expression-per-line":["error",{allow:"single-line"}],"style/arrow-parens":["error","as-needed"],"unused-imports/no-unused-imports":"error","unused-imports/no-unused-vars":["warn",{vars:"all",varsIgnorePattern:"^_",args:"after-used",argsIgnorePattern:"^_"}],"@stylistic/indent":["error",2,{ArrayExpression:1,CallExpression:{arguments:1},flatTernaryExpressions:!1,FunctionDeclaration:{body:1,parameters:1},FunctionExpression:{body:1,parameters:1},ignoreComments:!1,ignoredNodes:["TemplateLiteral *","TSIntersectionType","TSTypeParameterInstantiation","FunctionExpression > .params[decorators.length > 0]","FunctionExpression > .params > :matches(Decorator, :not(:first-child))","ClassBody.body > PropertyDefinition[decorators.length > 0] > .key"],ImportDeclaration:1,MemberExpression:1,ObjectExpression:1,offsetTernaryExpressions:!0,outerIIFEBody:1,SwitchCase:1,VariableDeclarator:1}]}}]}async function h(){return[{name:`${t}:old_config`,languageOptions:{globals:{...s.browser,...s.jquery,...s.node,document:"readonly",navigator:"readonly",window:"readonly"}},ignores:["**/.next/*","**/node_modules/*","**/.github/*","cypress","**/__tests__/e2e/*","*.json","**/*.d.ts",".eslintrc.js","eslint.config.js",".prettierrc",".stylelintrc.js","tsconfig.json","package.json","*.md","*.config.ts","*.config.js","*.md"]},{name:`${t}:rules_breakup_1`,rules:{"@next/next/no-duplicate-head":"off"}},{name:`${t}:rules_breakup_2`,rules:{"style/operator-linebreak":"off","test/consistent-test-it":"off","test/prefer-lowercase-title":"off","style/jsx-quotes":"off","style/multiline-ternary":"off","style/indent":"off"},ignores:["cypress"]},{name:`${t}:prettier`,rules:{"antfu/if-newline":"off"}}]}async function j(){return[l]}async function _(e,r){return[{name:"Deprecation plugin",languageOptions:{parserOptions:{project:r?.tsconfigPath??"./tsconfig.json",projectSource:!0}},plugins:{deprecation:u(m)},rules:{"deprecation/deprecation":e},files:["**/*.ts","**/*.tsx"]}]}function b(e,...r){const n=[];return e={...e,react:o(!0,e?.react),vue:o(!1,e?.vue),jsonc:o(!1,e?.jsonc),yaml:o(!1,e?.yaml),stylistic:o({semi:!0,quotes:"single"},e?.stylistic),typescript:o({overrides:{"ts/consistent-type-definitions":["error","interface"],"ts/interface-name-prefix":"off","ts/explicit-function-return-type":"off","ts/explicit-module-boundary-types":"off","ts/no-explicit-any":"off"}},e?.typescript),rules:o({"import/order":"off","react/react-in-jsx-scope":"off","react/prop-types":"off","antfu/top-level-function":"off","perfectionist/sort-imports":"off","perfectionist/sort-named-imports":"off","perfectionist/sort-named-exports":"off","antfu/consistent-chaining":"off","perfectionist/sort-exports":"off","style/no-multiple-empty-lines":"off"},e?.rules),deprecation:e?.deprecation,tsconfigPath:e?.tsconfigPath},(e.react??!0)&&n.push(x()),(e.all??!0)&&n.push(w()),(e.next??!1)&&n.push(y()),(e.markdown??!0)&&n.push(g()),e?.deprecation&&n.push(_(e?.deprecation??"warn",{tsconfigPath:e?.tsconfigPath})),n.push(h()),n.push(j()),c(e,...n,...r)}export{b as default};
|
package/next/index.mjs
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import r from"next/script";const n=()=>React.createElement("script",{src:"https://unpkg.com/react-scan/dist/auto.global.js",async:!0}),i=({id:t,clickMap:e=!0,trackLinks:a=!0,accurateTrackBounce:c=!0})=>React.createElement(r,{id:"metrika-counter",strategy:"afterInteractive"},` (function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
|
|
2
|
-
m[i].l=1*new Date();
|
|
3
|
-
for (var j = 0; j < document.scripts.length; j++) {if (document.scripts[j].src === r) { return; }}
|
|
4
|
-
k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
|
|
5
|
-
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
|
|
6
|
-
|
|
7
|
-
ym(${t}, "init", {
|
|
8
|
-
clickmap:${e},
|
|
9
|
-
trackLinks:${a},
|
|
10
|
-
accurateTrackBounce:${c}
|
|
11
|
-
});`);export{i as Metrika,n as ReactScan};
|
package/vitest/index.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{expect as c,vi as t,afterEach as f,beforeAll as u,afterAll as h}from"vitest";import{render as d,renderHook as m}from"@testing-library/react";import l from"ansi-colors";import p from"vitest-matchmedia-mock";const a=e=>{c(()=>e()).not.toThrow()},b=(...e)=>{a(()=>d(...e))},C=(...e)=>{a(()=>m(...e))},k=e=>{t.stubEnv("CANONICAL_URL","http://localhost:4242"),t.stubEnv("IS_PRODUCTION","false"),e&&Object.entries(e).forEach(([o,n])=>t.stubEnv(o,n))},r=()=>{t.clearAllMocks(),t.resetAllMocks(),t.unstubAllEnvs(),t.unstubAllGlobals()},x=()=>{t.mock("next/navigation",()=>({useRouter:()=>({push(){}}),usePathname:()=>"/"}))},A={addBase:t.fn(),addComponents:t.fn(),addUtilities:t.fn(),addVariant:t.fn(),config:t.fn(),corePlugins:t.fn(),e:t.fn(),matchComponents:t.fn(),matchUtilities:t.fn(),matchVariant:t.fn(),theme:t.fn()};class g{_executionContext;constructor(o){this._executionContext=o}call(...o){console.debug(`${l.blue(`[${this._executionContext}]`)} ${l.green(`Custom spy is called with these args: ${l.blueBright(o.map(n=>`${n}`).join(", "))}`)}`)}}function v(e){const o=new g(e),n=t.spyOn(o,"call");return{expectToBeCalled:(...s)=>c(n).toHaveBeenCalledWith(s),expectToBeNotCalled:(...s)=>c(n).not.toHaveBeenCalledWith(s),spy:n,callSpy:(...s)=>o.call(s)}}const E=(e,o)=>{t.stubGlobal(e,o)},M={beforeAll:u,afterEach:f},i=(e,o="beforeAll")=>{let n;M[o](()=>n=e()),h(()=>{r(),n?.()})},y=()=>{const e=new p;i(()=>(e.clear(),()=>e.destroy()),"afterEach")};export{C as assertHookRendering,a as assertNotThrowing,b as assertRendering,r as clearMocks,y as injectMatchMediaMock,i as injectMocks,k as mockEnv,x as mockRouter,v as spyFactory,E as stubGlobal,A as twApiMock};
|