xenopomp-essentials 0.3.1 → 0.3.2
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/.config/.lintstagedrc.json +3 -0
- package/.config/build.config.ts +41 -0
- package/.config/testing-exclusions/index.ts +2 -0
- package/.config/testing-exclusions/istanbul-exclusions.ts +1 -0
- package/.config/testing-exclusions/vitest-exclusions.ts +8 -0
- package/.config/ts/tsconfig.lint.json +10 -0
- package/.config/vitest.config.ts +18 -0
- package/.gitattributes +25 -0
- package/.github/workflows/ci.yml +54 -0
- package/.github/workflows/npm-publish.yml +27 -0
- package/.husky/pre-commit +1 -0
- package/.idea/codeStyles/Project.xml +59 -0
- package/.idea/codeStyles/codeStyleConfig.xml +5 -0
- package/.idea/inspectionProfiles/Project_Default.xml +6 -0
- package/.idea/modules.xml +8 -0
- package/.idea/prettier.xml +7 -0
- package/.idea/runConfigurations/_template__of_Vitest.xml +9 -0
- package/.idea/runConfigurations/build.xml +13 -0
- package/.idea/runConfigurations/coverage.xml +12 -0
- package/.idea/runConfigurations/lint.xml +13 -0
- package/.idea/runConfigurations/lint_code.xml +13 -0
- package/.idea/vcs.xml +6 -0
- package/.idea/xenopomp-essentials-js.iml +14 -0
- package/.prettierrc +20 -0
- package/README.md +0 -0
- package/__tests__/assets/assertions/expect-deep-equal.ts +14 -0
- package/__tests__/assets/assertions/expect-to-render.ts +26 -0
- package/__tests__/assets/assertions/index.ts +3 -0
- package/__tests__/assets/assertions/not-throwing.ts +6 -0
- package/__tests__/assets/index.ts +1 -0
- package/__tests__/data/index.ts +1 -0
- package/__tests__/data/parseVersion.data.ts +52 -0
- package/__tests__/unit/cli/path-builder.test.ts +39 -0
- package/__tests__/unit/components/hoc/jsx-dot-notation/component.test-source.tsx +24 -0
- package/__tests__/unit/components/hoc/jsx-dot-notation/hoc.test.tsx +11 -0
- package/__tests__/unit/components/metrika.test.tsx +14 -0
- package/__tests__/unit/components/react-scan.test.tsx +10 -0
- package/__tests__/unit/eslint/config.test.tsx +41 -0
- package/__tests__/unit/utils/capitalize.test.ts +17 -0
- package/__tests__/unit/utils/minmax.test.ts +21 -0
- package/__tests__/unit/utils/parseVersion.test.ts +22 -0
- package/__tests__/unit/utils/pipe.test.ts +23 -0
- package/__tests__/unit/utils/transliterate.test.ts +17 -0
- package/_templates/generator/help/index.ejs.t +5 -0
- package/_templates/generator/new/hello.ejs.t +18 -0
- package/_templates/generator/with-prompt/hello.ejs.t +18 -0
- package/_templates/generator/with-prompt/prompt.ejs.t +14 -0
- package/_templates/init/repo/new-repo.ejs.t +4 -0
- package/_templates/type/new/module.ejs.t +7 -0
- package/_templates/type/new/type.ejs.t +7 -0
- package/_templates/util/new/func.ejs.t +7 -0
- package/_templates/util/new/module.ejs.t +7 -0
- package/_templates/util/new/test.ejs.t +13 -0
- package/eslint.config.ts +17 -0
- package/package.json +4 -3
- package/src/cli-tools/changeFile.ts +1 -0
- package/src/cli-tools/index.ts +2 -0
- package/src/cli-tools/pathBuilder.ts +89 -0
- package/src/eslint/config.ts +145 -0
- package/src/eslint/configs/all.ts +74 -0
- package/src/eslint/configs/deprecation.ts +33 -0
- package/src/eslint/configs/index.ts +7 -0
- package/src/eslint/configs/markdown.ts +30 -0
- package/src/eslint/configs/next.ts +40 -0
- package/src/eslint/configs/old.ts +67 -0
- package/src/eslint/configs/prettier.ts +6 -0
- package/src/eslint/configs/react.ts +18 -0
- package/src/eslint/index.ts +7 -0
- package/src/eslint/prefixes/author.ts +2 -0
- package/src/eslint/prefixes/index.ts +1 -0
- package/src/eslint/types/configs.ts +4 -0
- package/src/eslint/types/custom-config.ts +4 -0
- package/src/eslint/types/index.ts +2 -0
- package/src/index.ts +3 -0
- package/src/next/Metrika/Metrika.props.ts +11 -0
- package/src/next/Metrika/Metrika.tsx +56 -0
- package/src/next/ReactScan/ReactScan.tsx +33 -0
- package/src/next/index.ts +2 -0
- package/src/react/hoc/index.ts +1 -0
- package/src/react/hoc/jsxDotNotation.tsx +38 -0
- package/src/react/index.ts +1 -0
- package/src/repo-eslint-rules/deep-type-naming.rule.ts +49 -0
- package/src/repo-eslint-rules/index.ts +9 -0
- package/src/schemas/import-meta.schema.ts +12 -0
- package/src/schemas/index.ts +1 -0
- package/src/types/aliases/AnyObject.ts +5 -0
- package/src/types/aliases/EmptyObject.ts +8 -0
- package/src/types/aliases/Fn.ts +12 -0
- package/src/types/aliases/index.ts +3 -0
- package/src/types/index.ts +4 -0
- package/src/types/next/NextParams.ts +26 -0
- package/src/types/next/index.ts +1 -0
- package/src/types/react/AnyFc.ts +6 -0
- package/src/types/react/AsyncFC.ts +16 -0
- package/src/types/react/DataAttributes.ts +21 -0
- package/src/types/react/FCProps.ts +19 -0
- package/src/types/react/FunctionalChildren.ts +13 -0
- package/src/types/react/SetState.ts +11 -0
- package/src/types/react/VariableFC.ts +48 -0
- package/src/types/react/VariableProps.ts +9 -0
- package/src/types/react/index.ts +8 -0
- package/src/types/utilities/ArrayType.ts +12 -0
- package/src/types/utilities/AsyncReturnType.ts +14 -0
- package/src/types/utilities/DeepInject.ts +22 -0
- package/src/types/utilities/Defined.ts +5 -0
- package/src/types/utilities/Jsonish.ts +11 -0
- package/src/types/utilities/LenientAutocomplete.ts +24 -0
- package/src/types/utilities/MatchType.ts +26 -0
- package/src/types/utilities/MergeTypes.ts +12 -0
- package/src/types/utilities/Modify.ts +10 -0
- package/src/types/utilities/Nullable.ts +5 -0
- package/src/types/utilities/OneOf.ts +42 -0
- package/src/types/utilities/Prettify.ts +15 -0
- package/src/types/utilities/RecordKey.ts +9 -0
- package/src/types/utilities/RecordValue.ts +9 -0
- package/src/types/utilities/ReplaceReturnType.ts +10 -0
- package/src/types/utilities/SelectivePartial.ts +17 -0
- package/src/types/utilities/StrictOmit.ts +19 -0
- package/src/types/utilities/Synchronous.ts +18 -0
- package/src/types/utilities/Undefinable.ts +5 -0
- package/src/types/utilities/WeakOmit.ts +17 -0
- package/src/types/utilities/Writeable.ts +18 -0
- package/src/types/utilities/index.ts +24 -0
- package/src/utils/capitalize.ts +15 -0
- package/src/utils/index.ts +7 -0
- package/src/utils/minmax.ts +35 -0
- package/src/utils/parseVersion.ts +42 -0
- package/src/utils/pipe.ts +29 -0
- package/src/utils/transliterate.ts +8 -0
- package/tsconfig.json +43 -0
- package/cli-tools/index.d.mts +0 -60
- package/cli-tools/index.d.ts +0 -60
- package/cli-tools/index.mjs +0 -1
- package/eslint/index.d.mts +0 -39
- package/eslint/index.d.ts +0 -39
- package/eslint/index.mjs +0 -3
- package/index.d.mts +0 -611
- package/index.d.ts +0 -611
- package/index.mjs +0 -1
- package/next/index.d.mts +0 -67
- package/next/index.d.ts +0 -67
- package/next/index.mjs +0 -11
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { expectType } from 'tsd';
|
|
2
|
+
import { describe, expect, test } from 'vitest';
|
|
3
|
+
|
|
4
|
+
import type { Configs, Options, UserConfigItem } from '@/eslint';
|
|
5
|
+
import xenopomp from '@/eslint';
|
|
6
|
+
import { next } from '@/eslint/configs';
|
|
7
|
+
import type { Fn } from '@/types';
|
|
8
|
+
|
|
9
|
+
import { assertNotThrowing } from '@test/assets';
|
|
10
|
+
|
|
11
|
+
type ExpectedType = Fn<
|
|
12
|
+
[options?: Options, ...userConfigs: UserConfigItem[]],
|
|
13
|
+
Configs
|
|
14
|
+
>;
|
|
15
|
+
|
|
16
|
+
describe('xenopomp ESLint config', () => {
|
|
17
|
+
test('Expected types are not any', () => {
|
|
18
|
+
expectType<ExpectedType>(xenopomp);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('It does not throw', () => {
|
|
22
|
+
assertNotThrowing(() => xenopomp());
|
|
23
|
+
|
|
24
|
+
assertNotThrowing(() =>
|
|
25
|
+
xenopomp({
|
|
26
|
+
react: undefined,
|
|
27
|
+
}),
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
assertNotThrowing(() =>
|
|
31
|
+
xenopomp({
|
|
32
|
+
next: true,
|
|
33
|
+
}),
|
|
34
|
+
);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test('Next.js integration', async () => {
|
|
38
|
+
const config = await next();
|
|
39
|
+
expect(config.length).toBeGreaterThan(0);
|
|
40
|
+
});
|
|
41
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { describe, expect, test } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { capitalize, uncapitalize } from '@/utils';
|
|
4
|
+
|
|
5
|
+
describe('Capitalize/uncapitalize utilities', () => {
|
|
6
|
+
test('Capitalize works', () => {
|
|
7
|
+
const og = 'alex';
|
|
8
|
+
const cap = capitalize(og);
|
|
9
|
+
expect(cap).toBe('Alex');
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
test('Uncapitalize works', () => {
|
|
13
|
+
const og = 'Alex';
|
|
14
|
+
const cap = uncapitalize(og);
|
|
15
|
+
expect(cap).toBe('alex');
|
|
16
|
+
});
|
|
17
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { describe, expect, test } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { minmax } from '@/utils';
|
|
4
|
+
|
|
5
|
+
describe('minmax util', () => {
|
|
6
|
+
test('Min value', () => {
|
|
7
|
+
expect(minmax(1, [2, undefined])).toBe(2);
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
test('Max value', () => {
|
|
11
|
+
expect(minmax(1001, [undefined, 900])).toBe(900);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test('Min/Max', () => {
|
|
15
|
+
const constraint = (num: number) => minmax(num, [100, 500]);
|
|
16
|
+
|
|
17
|
+
expect(constraint(1)).toBe(100);
|
|
18
|
+
expect(constraint(352)).toBe(352);
|
|
19
|
+
expect(constraint(1000)).toBe(500);
|
|
20
|
+
});
|
|
21
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { describe, test } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { parseVersion } from '@/utils';
|
|
4
|
+
import type { VersionData } from '@/utils';
|
|
5
|
+
|
|
6
|
+
import { assertNotThrowing, expectToDeepEqual } from '@test/assets';
|
|
7
|
+
import { testCases } from '@test/data';
|
|
8
|
+
|
|
9
|
+
describe('parseVersion util', () => {
|
|
10
|
+
const testParseVersion = (raw: string, expected: VersionData) => {
|
|
11
|
+
expectToDeepEqual(parseVersion(raw), expected);
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
test('It does not throw', () => assertNotThrowing(() => parseVersion('')));
|
|
15
|
+
|
|
16
|
+
test.each(testCases)(
|
|
17
|
+
'Test case: input=$input, version=$version, preid=$preid, prerelease=$prerelease',
|
|
18
|
+
({ input, ...versionData }) => {
|
|
19
|
+
testParseVersion(input, versionData);
|
|
20
|
+
},
|
|
21
|
+
);
|
|
22
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { expectAssignable } from 'tsd';
|
|
2
|
+
import { describe, test } from 'vitest';
|
|
3
|
+
|
|
4
|
+
import { pipe } from '@/utils';
|
|
5
|
+
|
|
6
|
+
import { assertNotThrowing } from '@test/assets';
|
|
7
|
+
|
|
8
|
+
describe('Pipe function', () => {
|
|
9
|
+
const testFn = pipe(Date.parse)
|
|
10
|
+
.pipe(n => new Date(n))
|
|
11
|
+
.pipe(d => d.toDateString())
|
|
12
|
+
.pipe(s => s.split('T'))
|
|
13
|
+
.pipe(([date, time]) => ({ date, time }));
|
|
14
|
+
|
|
15
|
+
test('It won`t throw', () => {
|
|
16
|
+
assertNotThrowing(() => testFn('Jan 1, 2024'));
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test('Type inference works just fine', () => {
|
|
20
|
+
const date = testFn('Jan 1, 2024');
|
|
21
|
+
expectAssignable<{ date?: string; time?: string }>(date);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { describe, expect, test } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { transliterate } from '@/utils';
|
|
4
|
+
|
|
5
|
+
import { assertNotThrowing } from '@test/assets';
|
|
6
|
+
|
|
7
|
+
describe('transliterate util', () => {
|
|
8
|
+
test('It does not throw', () =>
|
|
9
|
+
assertNotThrowing(() => transliterate('Я русский')));
|
|
10
|
+
|
|
11
|
+
test('It correctly transliterates text', () => {
|
|
12
|
+
expect(transliterate('Я русский')).toBe('Ya russkiy');
|
|
13
|
+
expect(transliterate('Ya betonovaya милашка')).toBe(
|
|
14
|
+
'Ya betonovaya milashka',
|
|
15
|
+
);
|
|
16
|
+
});
|
|
17
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
to: _templates/<%= name %>/<%= action || 'new' %>/hello.ejs.t
|
|
3
|
+
---
|
|
4
|
+
---
|
|
5
|
+
to: app/hello.js
|
|
6
|
+
---
|
|
7
|
+
const hello = ```
|
|
8
|
+
Hello!
|
|
9
|
+
This is your first hygen template.
|
|
10
|
+
|
|
11
|
+
Learn what it can do here:
|
|
12
|
+
|
|
13
|
+
https://github.com/jondot/hygen
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
console.log(hello)
|
|
17
|
+
|
|
18
|
+
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
to: _templates/<%= name %>/<%= action || 'new' %>/hello.ejs.t
|
|
3
|
+
---
|
|
4
|
+
---
|
|
5
|
+
to: app/hello.js
|
|
6
|
+
---
|
|
7
|
+
const hello = ```
|
|
8
|
+
Hello!
|
|
9
|
+
This is your first prompt based hygen template.
|
|
10
|
+
|
|
11
|
+
Learn what it can do here:
|
|
12
|
+
|
|
13
|
+
https://github.com/jondot/hygen
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
console.log(hello)
|
|
17
|
+
|
|
18
|
+
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
to: _templates/<%= name %>/<%= action || 'new' %>/prompt.js
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
// see types of prompts:
|
|
6
|
+
// https://github.com/enquirer/enquirer/tree/master/examples
|
|
7
|
+
//
|
|
8
|
+
module.exports = [
|
|
9
|
+
{
|
|
10
|
+
type: 'input',
|
|
11
|
+
name: 'message',
|
|
12
|
+
message: "What's your message?"
|
|
13
|
+
}
|
|
14
|
+
]
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
to: __tests__/unit/utils/<%= h.changeCase.camelCase(name) %>.test.ts
|
|
3
|
+
---
|
|
4
|
+
import { describe, test } from 'vitest';
|
|
5
|
+
|
|
6
|
+
import { <%= h.changeCase.camelCase(name) %> } from '@/utils';
|
|
7
|
+
|
|
8
|
+
import { assertNotThrowing } from '@test/assets';
|
|
9
|
+
|
|
10
|
+
describe('<%= h.changeCase.camelCase(name) %> util', () => {
|
|
11
|
+
test('It does not throw', () => assertNotThrowing(() => <%= h.changeCase.camelCase(name) %>()));
|
|
12
|
+
});
|
|
13
|
+
|
package/eslint.config.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import xenopomp from './src/eslint';
|
|
2
|
+
import repoEslintPlugin from './src/repo-eslint-rules';
|
|
3
|
+
|
|
4
|
+
export default xenopomp(
|
|
5
|
+
{
|
|
6
|
+
deprecation: 'warn',
|
|
7
|
+
tsconfigPath: './.config/ts/tsconfig.lint.json',
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
plugins: {
|
|
11
|
+
repo: repoEslintPlugin,
|
|
12
|
+
},
|
|
13
|
+
rules: {
|
|
14
|
+
'repo/deep-type-naming': 'warn',
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xenopomp-essentials",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"author": "XenoPOMP <101574433+XenoPOMP@users.noreply.github.com>",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -13,13 +13,14 @@
|
|
|
13
13
|
"node": "20 || >=22"
|
|
14
14
|
},
|
|
15
15
|
"scripts": {
|
|
16
|
-
"build": "run-p build
|
|
16
|
+
"build": "run-p build:**",
|
|
17
17
|
"build:main": "unbuild --config .config/build.config.ts",
|
|
18
18
|
"build:packages:cli": "echo CLI",
|
|
19
19
|
"lint": "run-s lint:*",
|
|
20
20
|
"lint:code": "eslint",
|
|
21
21
|
"coverage": "vitest run --coverage -c ./.config/vitest.config.ts",
|
|
22
|
-
"prepare": "husky"
|
|
22
|
+
"prepare": "husky",
|
|
23
|
+
"publish": "yarn install --frozen-lockfile && yarn build"
|
|
23
24
|
},
|
|
24
25
|
"main": "./index.mjs",
|
|
25
26
|
"types": "./index.d.ts",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
// export function changeFile() {}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
|
|
3
|
+
import { importMeta } from '@/schemas';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Fluent interface for creating paths of application.
|
|
7
|
+
*
|
|
8
|
+
* @since 0.0.1
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* import { PathBuilder } from 'xenopomp-essentials/cli-tools';
|
|
12
|
+
*
|
|
13
|
+
* const builder = new PathBuilder();
|
|
14
|
+
*
|
|
15
|
+
* const res = builder
|
|
16
|
+
* .appSource()
|
|
17
|
+
* .cd('./dist/src')
|
|
18
|
+
* .file('.prettierrc')
|
|
19
|
+
* .build();
|
|
20
|
+
*
|
|
21
|
+
* console.log(res); //? C:/Projects/example/node_modules/xenopomp-essentials/dist/src/.prettierrc
|
|
22
|
+
*/
|
|
23
|
+
export class PathBuilder {
|
|
24
|
+
private paths: string[] = [];
|
|
25
|
+
|
|
26
|
+
private pushPaths(...paths: string[]): PathBuilder {
|
|
27
|
+
this.paths.push(...paths);
|
|
28
|
+
return this;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Pushes any custom paths to builder.
|
|
33
|
+
* @since 0.0.1
|
|
34
|
+
* @param paths
|
|
35
|
+
*/
|
|
36
|
+
cd(...paths: string[]) {
|
|
37
|
+
return this.pushPaths(...paths);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Pushes filename to paths.
|
|
42
|
+
* @since 0.0.1
|
|
43
|
+
* @param fileName
|
|
44
|
+
*/
|
|
45
|
+
file<T extends `${string}.${string}`>(fileName: T) {
|
|
46
|
+
return this.pushPaths(`./${fileName}`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Pushes path to compiled app directory.
|
|
51
|
+
* Is useful for cli tools that have to access files inside their bundles.
|
|
52
|
+
*
|
|
53
|
+
* It probably may take no effect (if import.meta is not available in a scope).
|
|
54
|
+
* If it is, will push cwd.
|
|
55
|
+
*
|
|
56
|
+
* @since 0.0.1
|
|
57
|
+
*/
|
|
58
|
+
appSource(): PathBuilder {
|
|
59
|
+
if (!importMeta.dirname) {
|
|
60
|
+
return this.cwd();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return this.pushPaths(path.join(path.dirname(importMeta.dirname), '../'));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Gets path of directory where script is running. In cli tools it access
|
|
68
|
+
* path, where cli tool was started.
|
|
69
|
+
* @since 0.0.1
|
|
70
|
+
*/
|
|
71
|
+
cwd(): PathBuilder {
|
|
72
|
+
return this.pushPaths(process.cwd());
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @since 0.0.1
|
|
77
|
+
*/
|
|
78
|
+
clear(): PathBuilder {
|
|
79
|
+
this.paths = [];
|
|
80
|
+
return this;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @since 0.0.1
|
|
85
|
+
*/
|
|
86
|
+
build(): string {
|
|
87
|
+
return path.join(...this.paths);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Awaitable,
|
|
3
|
+
OptionsConfig,
|
|
4
|
+
TypedFlatConfigItem,
|
|
5
|
+
} from '@antfu/eslint-config';
|
|
6
|
+
import { antfu } from '@antfu/eslint-config';
|
|
7
|
+
import { deepmerge } from 'deepmerge-ts';
|
|
8
|
+
import type { Linter } from 'eslint';
|
|
9
|
+
|
|
10
|
+
import type { Undefinable } from '@/types';
|
|
11
|
+
|
|
12
|
+
import {
|
|
13
|
+
all,
|
|
14
|
+
deprecation,
|
|
15
|
+
markdown,
|
|
16
|
+
next,
|
|
17
|
+
old,
|
|
18
|
+
prettier,
|
|
19
|
+
react,
|
|
20
|
+
} from './configs';
|
|
21
|
+
import type { Configs, CustomConfig, UserConfigItem } from './types';
|
|
22
|
+
|
|
23
|
+
interface CustomOptions {
|
|
24
|
+
deprecation?: Linter.RuleEntry;
|
|
25
|
+
tsconfigPath?: string;
|
|
26
|
+
}
|
|
27
|
+
export type Options = OptionsConfig &
|
|
28
|
+
CustomConfig &
|
|
29
|
+
TypedFlatConfigItem &
|
|
30
|
+
CustomOptions;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* XenoPOMP`s default ESLint config. Uses @antfu/eslint-config under the hood.
|
|
34
|
+
*
|
|
35
|
+
* @param options
|
|
36
|
+
* @param userConfigs
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* export default xenopomp(
|
|
40
|
+
* // Setup antfu config
|
|
41
|
+
* {
|
|
42
|
+
* react: true,
|
|
43
|
+
* next: false,
|
|
44
|
+
* },
|
|
45
|
+
* // User configs
|
|
46
|
+
* {
|
|
47
|
+
* name: 'My custom config',
|
|
48
|
+
* rules: { ... }
|
|
49
|
+
* },
|
|
50
|
+
* );
|
|
51
|
+
*/
|
|
52
|
+
export default function xenopomp(
|
|
53
|
+
options?: Options,
|
|
54
|
+
...userConfigs: UserConfigItem[]
|
|
55
|
+
): Configs {
|
|
56
|
+
const configs: Awaitable<TypedFlatConfigItem[]>[] = [];
|
|
57
|
+
|
|
58
|
+
options = {
|
|
59
|
+
...options,
|
|
60
|
+
react: deepmerge<
|
|
61
|
+
[Undefinable<Options['react']>, Undefinable<Options['react']>]
|
|
62
|
+
>(true, options?.react),
|
|
63
|
+
|
|
64
|
+
vue: deepmerge<[Undefinable<Options['vue']>, Undefinable<Options['vue']>]>(
|
|
65
|
+
false,
|
|
66
|
+
options?.vue,
|
|
67
|
+
),
|
|
68
|
+
|
|
69
|
+
jsonc: deepmerge<
|
|
70
|
+
[Undefinable<Options['jsonc']>, Undefinable<Options['jsonc']>]
|
|
71
|
+
>(false, options?.jsonc),
|
|
72
|
+
|
|
73
|
+
yaml: deepmerge<
|
|
74
|
+
[Undefinable<Options['yaml']>, Undefinable<Options['yaml']>]
|
|
75
|
+
>(false, options?.yaml),
|
|
76
|
+
|
|
77
|
+
stylistic: deepmerge<
|
|
78
|
+
[Undefinable<Options['stylistic']>, Undefinable<Options['stylistic']>]
|
|
79
|
+
>(
|
|
80
|
+
{
|
|
81
|
+
semi: true,
|
|
82
|
+
quotes: 'single',
|
|
83
|
+
},
|
|
84
|
+
options?.stylistic,
|
|
85
|
+
),
|
|
86
|
+
|
|
87
|
+
typescript: deepmerge<
|
|
88
|
+
[Undefinable<Options['typescript']>, Undefinable<Options['typescript']>]
|
|
89
|
+
>(
|
|
90
|
+
{
|
|
91
|
+
overrides: {
|
|
92
|
+
'ts/consistent-type-definitions': ['error', 'interface'],
|
|
93
|
+
'ts/interface-name-prefix': 'off',
|
|
94
|
+
'ts/explicit-function-return-type': 'off',
|
|
95
|
+
'ts/explicit-module-boundary-types': 'off',
|
|
96
|
+
'ts/no-explicit-any': 'off',
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
options?.typescript,
|
|
100
|
+
),
|
|
101
|
+
|
|
102
|
+
rules: deepmerge<
|
|
103
|
+
[Undefinable<Options['rules']>, Undefinable<Options['rules']>]
|
|
104
|
+
>(
|
|
105
|
+
{
|
|
106
|
+
'import/order': 'off',
|
|
107
|
+
'react/react-in-jsx-scope': 'off',
|
|
108
|
+
'react/prop-types': 'off',
|
|
109
|
+
'antfu/top-level-function': 'off',
|
|
110
|
+
'perfectionist/sort-imports': 'off',
|
|
111
|
+
'perfectionist/sort-named-imports': 'off',
|
|
112
|
+
'perfectionist/sort-named-exports': 'off',
|
|
113
|
+
'antfu/consistent-chaining': 'off',
|
|
114
|
+
'perfectionist/sort-exports': 'off',
|
|
115
|
+
'style/no-multiple-empty-lines': 'off',
|
|
116
|
+
},
|
|
117
|
+
options?.rules,
|
|
118
|
+
),
|
|
119
|
+
|
|
120
|
+
deprecation: options?.deprecation,
|
|
121
|
+
tsconfigPath: options?.tsconfigPath,
|
|
122
|
+
} satisfies Options;
|
|
123
|
+
|
|
124
|
+
if (options.react ?? true) configs.push(react());
|
|
125
|
+
|
|
126
|
+
if (options.all ?? true) configs.push(all());
|
|
127
|
+
|
|
128
|
+
if (options.next ?? false) configs.push(next());
|
|
129
|
+
|
|
130
|
+
if (options.markdown ?? true) configs.push(markdown());
|
|
131
|
+
|
|
132
|
+
if (options?.deprecation) {
|
|
133
|
+
configs.push(
|
|
134
|
+
deprecation(options?.deprecation ?? 'warn', {
|
|
135
|
+
tsconfigPath: options?.tsconfigPath,
|
|
136
|
+
}),
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Apply other configs
|
|
141
|
+
configs.push(old());
|
|
142
|
+
configs.push(prettier());
|
|
143
|
+
|
|
144
|
+
return antfu(options, ...configs, ...userConfigs);
|
|
145
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { TypedFlatConfigItem } from '@antfu/eslint-config';
|
|
2
|
+
|
|
3
|
+
import { AUTHOR_NAME_LOWER } from '../prefixes';
|
|
4
|
+
|
|
5
|
+
export async function all(): Promise<TypedFlatConfigItem[]> {
|
|
6
|
+
return [
|
|
7
|
+
{
|
|
8
|
+
name: `${AUTHOR_NAME_LOWER}:all`,
|
|
9
|
+
rules: {
|
|
10
|
+
'antfu/no-cjs-exports': 'off',
|
|
11
|
+
|
|
12
|
+
'import/prefer-default-export': 'off',
|
|
13
|
+
'import/extensions': 'off',
|
|
14
|
+
'no-restricted-globals': 'off',
|
|
15
|
+
|
|
16
|
+
'node/prefer-global/process': 'off',
|
|
17
|
+
|
|
18
|
+
'jsonc/comma-dangle': 'off',
|
|
19
|
+
'style/jsx-quotes': ['error', 'prefer-double'],
|
|
20
|
+
'style/jsx-one-expression-per-line': [
|
|
21
|
+
'error',
|
|
22
|
+
{ allow: 'single-line' },
|
|
23
|
+
],
|
|
24
|
+
'style/arrow-parens': ['error', 'as-needed'],
|
|
25
|
+
|
|
26
|
+
'unused-imports/no-unused-imports': 'error',
|
|
27
|
+
'unused-imports/no-unused-vars': [
|
|
28
|
+
'warn',
|
|
29
|
+
{
|
|
30
|
+
vars: 'all',
|
|
31
|
+
varsIgnorePattern: '^_',
|
|
32
|
+
args: 'after-used',
|
|
33
|
+
argsIgnorePattern: '^_',
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
'@stylistic/indent': [
|
|
37
|
+
'error',
|
|
38
|
+
2,
|
|
39
|
+
{
|
|
40
|
+
ArrayExpression: 1,
|
|
41
|
+
CallExpression: {
|
|
42
|
+
arguments: 1,
|
|
43
|
+
},
|
|
44
|
+
flatTernaryExpressions: false,
|
|
45
|
+
FunctionDeclaration: {
|
|
46
|
+
body: 1,
|
|
47
|
+
parameters: 1,
|
|
48
|
+
},
|
|
49
|
+
FunctionExpression: {
|
|
50
|
+
body: 1,
|
|
51
|
+
parameters: 1,
|
|
52
|
+
},
|
|
53
|
+
ignoreComments: false,
|
|
54
|
+
ignoredNodes: [
|
|
55
|
+
'TemplateLiteral *',
|
|
56
|
+
'TSIntersectionType',
|
|
57
|
+
'TSTypeParameterInstantiation',
|
|
58
|
+
'FunctionExpression > .params[decorators.length > 0]',
|
|
59
|
+
'FunctionExpression > .params > :matches(Decorator, :not(:first-child))',
|
|
60
|
+
'ClassBody.body > PropertyDefinition[decorators.length > 0] > .key',
|
|
61
|
+
],
|
|
62
|
+
ImportDeclaration: 1,
|
|
63
|
+
MemberExpression: 1,
|
|
64
|
+
ObjectExpression: 1,
|
|
65
|
+
offsetTernaryExpressions: true,
|
|
66
|
+
outerIIFEBody: 1,
|
|
67
|
+
SwitchCase: 1,
|
|
68
|
+
VariableDeclarator: 1,
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
];
|
|
74
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { TypedFlatConfigItem } from '@antfu/eslint-config';
|
|
2
|
+
import { fixupPluginRules } from '@eslint/compat';
|
|
3
|
+
import type { Linter } from 'eslint';
|
|
4
|
+
import plugin from 'eslint-plugin-deprecation';
|
|
5
|
+
|
|
6
|
+
import type { Options as ConfigOptions } from '../config';
|
|
7
|
+
|
|
8
|
+
type Options = Pick<ConfigOptions, 'tsconfigPath'>;
|
|
9
|
+
|
|
10
|
+
export async function deprecation(
|
|
11
|
+
severity: Linter.RuleEntry,
|
|
12
|
+
options?: Options,
|
|
13
|
+
): Promise<TypedFlatConfigItem[]> {
|
|
14
|
+
return [
|
|
15
|
+
{
|
|
16
|
+
name: 'Deprecation plugin',
|
|
17
|
+
languageOptions: {
|
|
18
|
+
parserOptions: {
|
|
19
|
+
project: options?.tsconfigPath ?? './tsconfig.json',
|
|
20
|
+
projectSource: true,
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
plugins: {
|
|
24
|
+
// @ts-expect-error Wrong library types
|
|
25
|
+
deprecation: fixupPluginRules(plugin),
|
|
26
|
+
},
|
|
27
|
+
rules: {
|
|
28
|
+
'deprecation/deprecation': severity,
|
|
29
|
+
},
|
|
30
|
+
files: ['**/*.ts', '**/*.tsx'],
|
|
31
|
+
},
|
|
32
|
+
];
|
|
33
|
+
}
|