Compare commits

...

451 Commits
v0.1.4 ... main

Author SHA1 Message Date
a275b5bd94 chore: release v0.40.11 2023-08-15 19:42:00 +08:00
15b1011230 chore: release v0.40.10 2023-08-15 19:40:53 +08:00
0ba93481db chore: release v0.40.9 2023-08-15 19:40:30 +08:00
1296d158c9 chore: release v0.40.8 2023-08-15 19:39:42 +08:00
8b98365ad0 chore: release v0.40.7 2023-08-15 19:39:00 +08:00
4d6dd79325 chore: release v0.40.6 2023-08-15 19:36:52 +08:00
bc0a817dd1 chore: release v0.40.5 2023-08-15 19:36:08 +08:00
6bf6d00b90 chore: release v0.40.4 2023-08-15 19:34:09 +08:00
13796c251c chore: release v0.40.3 2023-08-15 19:31:18 +08:00
f80fdbe613 去掉 markdown lint 2023-08-15 19:28:35 +08:00
toryz
1ae6ec8527
fix(basic): ignore vitepress cache files (#233) 2023-08-11 20:12:47 +02:00
Anthony Fu
c22a36bbec chore: release v0.40.2 2023-08-07 15:57:18 +02:00
Anthony Fu
71e8f0c3b2 chore: upgrade eslint-plugin-i 2023-08-07 15:57:14 +02:00
Anthony Fu
e0071450be chore: release v0.40.1 2023-08-07 15:41:59 +02:00
Anthony Fu
bfa0e2bb80 chore: lint 2023-08-07 15:41:55 +02:00
Anthony Fu
49b9b7f7db chore: update deps, migrate tests 2023-08-07 15:41:19 +02:00
Anthony Fu
3a2c549110 fix(plugin): named-tuple-spacing handling, close #232 2023-08-07 15:41:02 +02:00
Anthony Fu
59308e8e36 chore: release v0.40.0 2023-08-01 17:00:05 +02:00
曾明健
cf1240c847
feat: add rule no-import-node-modules-by-path (#219) 2023-08-01 16:59:19 +02:00
Ted Xu
0ff5e45fdd
feat: format for named tuple (#229) 2023-08-01 16:58:56 +02:00
Anthony Fu
effc708692 feat: add default in exports 2023-08-01 16:58:10 +02:00
Anthony Fu
ea307c91e5 fix: put import before require in exports 2023-08-01 16:56:25 +02:00
曾明健
b7ce1614d8
docs: make config correct (#224) 2023-07-20 14:44:19 +02:00
Cloyd Lau
bf390b0693
docs: add code style badge (#220)
Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
2023-07-17 16:53:38 +02:00
Anthony Fu
500fe9df8d chore: release v0.39.8 2023-07-16 00:20:35 +02:00
Anthony Fu
5be2b3fd39 chore: update deps 2023-07-16 00:20:31 +02:00
三咲智子 Kevin Deng
5821926148
fix(plugin): allow empty type import (#218) 2023-07-16 00:18:20 +02:00
曾明健
3ef955d56f
feat(basic): prefer non global process object (#214) 2023-07-12 12:39:07 +02:00
Marshall Thompson
1b25322bf5
docs: VS Code config example (#215) 2023-07-10 03:02:20 +02:00
曾明健
2ed8536b85
feat(basic): ban self import (#213) 2023-07-05 11:50:02 +02:00
Anthony Fu
4edff9cd15 chore: release v0.39.7 2023-07-04 11:32:56 +02:00
Anthony Fu
f245939bfa chore: update deps 2023-07-04 11:32:40 +02:00
曾明健
be5bc8009c
feat: ban new Array (#209) 2023-07-04 10:52:53 +02:00
曾明健
d4a9ebcc17
feat(ts): enable @typescript-eslint/ban-types (#210) 2023-07-03 21:19:59 +02:00
Anthony Fu
c1355234c0 chore: release v0.39.6 2023-06-28 14:10:34 +02:00
Julian Meinking
6dfc773b05
docs: add eslint.validate to enable linting for supported filetypes with VSCode ESLint (#204)
Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
2023-06-28 14:10:01 +02:00
曾明健
2bf0c8d727
feat(ts): ban const enum (#201) 2023-06-28 14:05:23 +02:00
arily
504de8392a
feat: switch to eslint-plugin-i (#205) 2023-06-28 14:04:55 +02:00
Mert
6cf4794985
docs: update organizeImports config for VS Code (#202) 2023-06-18 12:42:25 +02:00
曾明健
bbed70b969
refactor: use existing rules (#198) 2023-06-06 18:01:05 +02:00
Kirk Lin
f553c519f6
feat(vue): enforce order of define macros (#196) 2023-06-06 11:32:33 +02:00
Anthony Fu
4e77637da4 chore: release v0.39.5 2023-06-04 16:20:46 +02:00
Anthony Fu
abf5c27385 fix: disable @typescript-eslint/consistent-type-assertions 2023-06-04 16:20:42 +02:00
曾明健
7b48da27dc
chore(basic): refesh standard.js (#193) 2023-06-02 16:04:48 +02:00
曾明健
0947ddb151
feat(basic): ban deprecated syntax (#194) 2023-06-02 16:04:01 +02:00
L.Rain
0a9c9b0384
chore: simplified off rules (#192) 2023-06-01 16:08:06 +02:00
曾明健
84ae087ea0
chore(basic): add the missing restricted rules about window object (#191) 2023-05-31 14:40:11 +02:00
Anthony Fu
5d908028ca chore: release v0.39.4 2023-05-31 09:53:19 +02:00
Anthony Fu
610d886afd chore: remove window restriction 2023-05-31 09:52:26 +02:00
曾明健
aefa76e48a
feat(basic): ban some deprecated global functions (#190) 2023-05-31 09:51:21 +02:00
曾明健
e787e9a647
feat(basic): ban global variable (#189) 2023-05-26 17:39:10 +02:00
曾明健
a3598d36d2
feat(ts): enable @typescript-eslint/consistent-type-assertions (#188) 2023-05-26 17:38:54 +02:00
Anthony Fu
7b399a63db chore: release v0.39.3 2023-05-23 13:39:23 +02:00
Anthony Fu
bb09e1d6b4 fix(vue): disable vue/no-dupe-keys 2023-05-23 13:39:17 +02:00
Anthony Fu
f97f7ef7de chore: release v0.39.2 2023-05-23 12:42:39 +02:00
Anthony Fu
0a19d26da6 chore: update deps 2023-05-23 12:42:31 +02:00
Kaivan Wong
ec494867f9
feat: update eslint-plugin-vue version (#186) 2023-05-23 12:41:23 +02:00
Anthony Fu
656f91ae61 chore: release v0.39.1 2023-05-21 14:19:13 +02:00
Anthony Fu
cdb02c8fa1 fix: turn off cjs-check in markdown 2023-05-21 14:19:11 +02:00
Anthony Fu
3f2f335e42 chore: release v0.39.0 2023-05-19 10:32:15 +02:00
曾明健
3ca0e7ea8b
feat(ts): ban cjs exports in ts file (#167) 2023-05-19 10:29:54 +02:00
曾明健
96dd9a1797
feat: validate jsonc file (#184) 2023-05-19 10:29:15 +02:00
Anthony Fu
2db56ec8f0 chore: release v0.38.6 2023-05-05 18:36:15 +02:00
Anthony Fu
6503a153d8 fix: relax markdown lint 2023-05-05 18:35:51 +02:00
cany748
10306427d9
chore: run lint script typo (#180) 2023-05-05 12:27:27 +02:00
Anthony Fu
e6cb79994e fix: exclude vitepress cache 2023-04-19 02:29:07 +02:00
Anthony Fu
a602eb1b4f chore: release v0.38.5 2023-04-18 14:01:56 +02:00
Anthony Fu
9114acddf6 chore: update build 2023-04-18 13:56:51 +02:00
Anthony Fu
e8cec1e2d5 chore: update deps 2023-04-18 13:56:00 +02:00
曾明健
506d17c3f7
feat(plugin): allow some one-line arrow functions (#172) 2023-04-18 13:54:50 +02:00
曾明健
ff74d69719
feat: enable no-invalid-this (#173) 2023-04-18 13:42:48 +02:00
曾明健
e28861a247
fix(basic): allow require imports in js file (#169) 2023-04-11 09:50:52 +02:00
曾明健
9fde0f404f
feat(ts): ban namespace in ts file (#166) 2023-04-10 17:45:46 +02:00
曾明健
78b405f91a
feat: ban requrie imports in ts file (#165) 2023-04-10 17:39:06 +02:00
曾明健
ebb96c422e
feat(basic): consider comments for newline-after-import (#164) 2023-04-10 13:57:57 +02:00
Anthony Fu
5240f68454 chore: release v0.38.4 2023-04-04 08:56:34 +02:00
Anthony Fu
79c8de557e chore: update deps 2023-04-04 08:56:29 +02:00
曾明健
3f13db706b
refactor: remove eslint-plugin-node (#162) 2023-04-04 08:55:00 +02:00
Anthony Fu
7a5daf6f38 chore: update lock 2023-04-03 17:19:24 +02:00
Anthony Fu
79b63bc0c9 chore: enable hoist 2023-04-03 14:43:41 +02:00
Anthony Fu
60002c33fd chore: release v0.38.3 2023-04-03 14:42:06 +02:00
曾明健
502f6b0c37
feat(basic): prefer non global object of node (#159)
Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
2023-04-03 14:41:41 +02:00
曾明健
d1cd722857
feat(basic): new line after import (#161) 2023-04-03 14:30:54 +02:00
Anthony Fu
d2150eec3b fix(top-level-function): narrow warning range 2023-03-30 11:02:49 +02:00
Anthony Fu
d3c3e1b84d chore: update lock 2023-03-30 10:57:04 +02:00
Anthony Fu
3963633712 chore: release v0.38.2 2023-03-30 10:53:40 +02:00
Anthony Fu
e9193343e8 chore: format 2023-03-30 10:53:36 +02:00
Anthony Fu
e8d73f737e chore: release v0.38.1 2023-03-30 10:51:35 +02:00
Anthony Fu
3a74c8e351 fix(top-level-function): support async function 2023-03-30 10:51:29 +02:00
Anthony Fu
3fa861730d test: add more test case 2023-03-30 01:08:42 +02:00
Anthony Fu
ebbc1a7f78 chore: rebuild lock file 2023-03-29 15:52:45 +02:00
Anthony Fu
417b60c18b chore: release v0.38.0 2023-03-29 15:47:19 +02:00
Anthony Fu
9768ccd35e chore: update deps 2023-03-29 15:47:03 +02:00
Anthony Fu
87d26fb63a feat: enforce to use function declaration on top-level 2023-03-29 15:46:16 +02:00
Anthony Fu
e17d2f8f52 docs: update 2023-03-24 10:08:38 +01:00
Anthony Fu
4ef978a092 refactor: rename folders 2023-03-24 10:01:44 +01:00
Anthony Fu
ab850b0ae4 chore: release v0.37.0 2023-03-18 22:01:51 +01:00
Anthony Fu
7632765715 feat: upgrade deps, support typescript 5.0 2023-03-18 22:01:39 +01:00
Ivan Demchuk
d3c1119dbe
feat: enable vue/no-unused-refs (#158) 2023-03-16 11:34:58 +01:00
Anthony Fu
421d406e4f chore: release v0.36.0 2023-03-04 15:23:57 +01:00
Anthony Fu
447d326997 feat: enable prefer-node-protocol 2023-03-04 15:23:51 +01:00
Anthony Fu
6c0f76e229 chore: release v0.35.3 2023-02-24 23:59:15 +01:00
Anthony Fu
564db7d3c4 chore: update deps 2023-02-24 23:59:07 +01:00
Anthony Fu
4167a78419 feat: add ignore list for lint-staged 2023-02-24 23:56:13 +01:00
zoeyzhao19
37a4d762c3
chore: typo (#157)
Co-authored-by: 赵龙生 <zhaolongsheng@tenwit.com>
2023-02-10 10:00:01 +01:00
Anthony Fu
f62730648a chore: release v0.35.2 2023-02-07 14:40:21 +01:00
Anthony Fu
229b6cb188 chore: update deps 2023-02-07 14:37:18 +01:00
Anthony Fu
7a2d63cf3a fix: disable vue/no-v-text-v-html-on-component 2023-02-05 13:12:32 +01:00
Anthony Fu
2cf571c341 chore: release v0.35.1 2023-01-29 15:15:46 +01:00
Anthony Fu
4b57638f82 fix: disable @typescript-eslint/no-unused-vars 2023-01-29 15:15:30 +01:00
Anthony Fu
d8f05127c6 chore: release v0.35.0 2023-01-29 01:59:20 +01:00
Anthony Fu
f466ac5446 feat: auto fix for unused imports 2023-01-29 01:58:08 +01:00
Anthony Fu
6e750c6000 chore: release v0.34.2 2023-01-29 00:36:44 +01:00
Anthony Fu
39795b47a4 chore: upgrade deps 2023-01-29 00:36:40 +01:00
Anthony Fu
f45a0d9bd3 feat: allow require() in cjs 2023-01-29 00:35:25 +01:00
Percy Ma
44bcb19269
fix: group &&, || and ?: (#152) 2023-01-12 16:04:23 +01:00
Anthony Fu
1b0dc92b90 chore: release v0.34.1 2023-01-09 11:01:22 +01:00
Anthony Fu
ae61022028 chore: update deps 2023-01-09 11:01:19 +01:00
三咲智子 Kevin Deng
2a224ef301
fix: prefer const when all variables in destructuring should be const (#149) 2023-01-09 10:58:26 +01:00
曾明健
42dddba96d
chore: synchronize config of standardjs (#143) 2022-12-16 15:00:41 +01:00
曾明健
5d5b3c338a
fix: allow void as statement in ts file (#142) 2022-12-16 11:48:11 +01:00
曾明健
2ad3503022
feat(ts): enable jest/unbound-method (#141) 2022-12-15 10:04:50 +01:00
Anthony Fu
559f5f43d2 chore: remove changelog 2022-12-12 18:25:49 +01:00
Anthony Fu
a0f388b4a9 chore: release v0.34.0 2022-12-12 18:05:13 +01:00
Anthony Fu
00c3c6d1cd chore: update deps 2022-12-12 18:05:07 +01:00
曾明健
fe73faf458
feat(ts): can change tsconfig by env (#136) 2022-12-12 18:01:40 +01:00
Kirk Lin
b93f48f429
feat(ts): add TypeScript Aware Rules from @typescript-eslint/recommen… (#135) 2022-12-12 18:01:22 +01:00
曾明健
4d38bd0293
fix(basic): disallow multi empty lines at the end of file (#137) 2022-12-12 18:00:59 +01:00
曾明健
b58283d3d6
feat(basic): disable consistent-type-imports in markdown file (#138) 2022-12-12 17:59:58 +01:00
Michaël
151a6ef338
Added 'out' to ignorePatterns (#140) 2022-12-12 17:59:31 +01:00
Anthony Fu
fce5e8dc3a chore: release v0.33.1 2022-11-30 21:16:29 +08:00
曾明健
3486d0d6c0
fix(ts): fix parerOptions (#134) 2022-11-30 21:16:09 +08:00
Anthony Fu
40817389a1 chore: release v0.33.0 2022-11-30 09:04:46 +08:00
Anthony Fu
79da8986db docs: add principle note 2022-11-30 09:04:41 +08:00
Anthony Fu
1c4260a937 fix: type aware linting when trigged by tsconfig.eslint.json 2022-11-30 09:02:21 +08:00
Anthony Fu
afc680cb29 chore: release v0.32.0 2022-11-29 20:11:52 +08:00
曾明健
7c769fee49
feat(ts): add rules that required parserOptions (#131)
Closes https://github.com/antfu/eslint-config/issues/112
2022-11-29 20:02:35 +08:00
Anthony Fu
6189a9225c chore: release v0.31.1 2022-11-29 17:33:07 +08:00
Anthony Fu
46a39e1506 chore: update deps 2022-11-29 17:33:00 +08:00
lainbo
1c37b247c5
feat: support TS 4.9 (#133) 2022-11-29 17:27:36 +08:00
Anthony Fu
2a1e59f43b chore: release v0.31.0 2022-11-17 01:27:39 +08:00
Anthony Fu
94b5fdddad chore: update deps 2022-11-17 01:27:16 +08:00
曾明健
65aec3f101
feat(basic): add max-statements-per-line (#129) 2022-11-17 01:25:16 +08:00
Anthony Fu
b53ffae83e chore: release v0.30.1 2022-11-12 15:06:28 +08:00
Anthony Fu
20c01380c9 fix: move deps 2022-11-12 15:06:25 +08:00
Anthony Fu
6b3f6e620b chore: release v0.30.0 2022-11-12 15:04:52 +08:00
Anthony Fu
693eba91a8 chore: update deps 2022-11-12 15:04:41 +08:00
Anthony Fu
b820b0fd92 feat: auto JS fallback 2022-11-12 15:03:35 +08:00
Anthony Fu
f8014b745e chore: release v0.29.4 2022-11-07 21:04:08 +08:00
Anthony Fu
95e28e4a4a fix(generic-spacing): improve cases 2022-11-07 21:03:56 +08:00
Anthony Fu
54b234f4ef chore: release v0.29.3 2022-11-02 17:21:31 +08:00
Anthony Fu
ff6a1fad6a fix(generic-spacing): improve cases 2022-11-02 17:21:24 +08:00
Anthony Fu
e13613fd5f chore: release v0.29.2 2022-11-01 04:01:12 +08:00
Anthony Fu
e111029e0a feat(generic-spacing): remove space before generic 2022-11-01 04:00:59 +08:00
Anthony Fu
254f8194df chore: release v0.29.1 2022-11-01 03:38:15 +08:00
Anthony Fu
4119f52750 fix(generic-spacing): avoid overriding extends 2022-11-01 03:38:06 +08:00
Anthony Fu
4b51ef2eba chore: release v0.29.0 2022-11-01 03:34:28 +08:00
Anthony Fu
588494cc01 feat: format for generics spacing 2022-11-01 03:34:15 +08:00
Anthony Fu
3c1207657f chore: release v0.28.0 2022-11-01 02:35:18 +08:00
KylinDC
da59484756
feat(basic): add rules to prevent .only in tests (#127) 2022-11-01 02:28:00 +08:00
Zhou Yunliang
501ff74200
chore: add missing dependency (#125) 2022-10-26 16:42:07 +08:00
zhangenming
adaf70b651
docs: add install extension tip (#123)
Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
2022-10-22 17:09:14 +08:00
Anthony Fu
3ed0230512
docs: prefer to blog post 2022-10-10 07:33:09 +08:00
Marvin
ac3f63086d
docs: suggest to disable format on save (#118) 2022-10-01 02:45:37 +08:00
Anthony Fu
f7a5571259 chore: update readme 2022-09-19 10:30:50 +08:00
Anthony Fu
a452fe4a81 chore: release v0.27.0 2022-09-19 10:29:09 +08:00
Anthony Fu
61ef0a0570 feat!: exclude react config from default package 2022-09-19 10:28:57 +08:00
Anthony Fu
b25d6e98bc chore: update 2022-09-19 10:27:44 +08:00
曾明健
ae4e44e588
fix: improve indent for decorators (#114) 2022-09-19 10:25:42 +08:00
max
ae904df91e
feat(react): rules of hooks (#117)
Co-authored-by: nnmax <hi.max@foxemail.com>
2022-09-19 10:24:45 +08:00
Anthony Fu
e9f0988b4d chore: update fixture 2022-09-06 10:04:27 +08:00
Anthony Fu
f3f41914c3 chore: release v0.26.3 2022-09-03 13:03:44 +08:00
Anthony Fu
0bf8393588 feat: support TS 4.8, close #111 2022-09-03 13:03:40 +08:00
Anthony Fu
39820a3f06 chore: release v0.26.2 2022-08-29 08:50:45 +08:00
Anthony Fu
083c719361 chore: update deps 2022-08-29 08:50:41 +08:00
Oumar Barry
b34da44baf
chore(basic): fix typo (#107) 2022-08-23 14:14:23 +08:00
Anthony Fu
e2c094d1d3 chore: release v0.26.1 2022-08-10 16:53:28 +08:00
karasu
339866483a
fix: rule renamed (#106) 2022-08-10 16:52:59 +08:00
Anthony Fu
fa24ca77a4 chore: release v0.26.0 2022-08-08 18:17:10 +08:00
Anthony Fu
8bceb3ef50 chore: update deps 2022-08-08 18:15:43 +08:00
Anthony Fu
108f55bbe8 chore: add release script 2022-07-10 10:46:19 +08:00
Anthony Fu
87419670fd docs: update license section 2022-07-10 10:44:34 +08:00
Anthony Fu
cdb1849476 release v0.25.2 2022-06-25 01:03:09 +08:00
Anthony Fu
55ffba3288 fix: ignore .d.ts by default 2022-06-25 01:03:04 +08:00
Anthony Fu
8ddaee3bf8 release v0.25.1 2022-06-03 22:08:51 +08:00
Anthony Fu
af2c3273cf fix: disable consistent-indexed-object-style 2022-06-03 22:08:48 +08:00
Anthony Fu
12e57fce54 release v0.25.0 2022-05-29 23:01:40 +08:00
Anthony Fu
b08b769a8a feat: enable reportUnusedDisableDirectives by default 2022-05-29 23:01:36 +08:00
Anthony Fu
65cef9437a release v0.24.3 2022-05-29 15:54:04 +08:00
QiroNT
f1b9dc396b
fix: prioritize require (#98) 2022-05-29 15:53:45 +08:00
Anthony Fu
b8fe7fe4e7 release v0.24.2 2022-05-25 07:02:48 +08:00
Anthony Fu
001de3b060 feat: improve package.json sorting 2022-05-25 07:02:45 +08:00
Anthony Fu
761a0ce4ee release v0.24.1 2022-05-25 05:31:09 +08:00
Anthony Fu
a9d330cac3 fix: disable vue/prefer-import-from-vue 2022-05-25 05:31:00 +08:00
Anthony Fu
540786d482 release v0.24.0 2022-05-25 05:09:42 +08:00
Anthony Fu
b876b7b1d9 chore: update deps 2022-05-25 05:09:36 +08:00
N
d463449db4
fix: deprecated-rules (#93)
unicorn/prefer-exponentiation-operator was deprecated since 16.0 [deprecated-rules](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/deprecated-rules.md#prefer-exponentiation-operator)
2022-05-14 11:36:03 +08:00
N
37d30e9e7d
fix: rule renamed (#94) 2022-05-14 11:35:44 +08:00
Anthony Fu
58b8383d4c release v0.23.1 2022-05-13 23:22:44 +08:00
Anthony Fu
35a5d3ef9d chore: disable rules 2022-05-13 23:15:35 +08:00
zz
f618005402
fix: add missing extension rules (#90) 2022-05-05 23:51:20 +08:00
Anthony Fu
a9b6d5f9ee release v0.23.0 2022-05-03 01:12:25 +08:00
Anthony Fu
e6a4d6db8b chore: update deps 2022-05-03 01:12:21 +08:00
QiroNT
ed0f5b1d76
feat: vue extensions (#89) 2022-05-03 01:07:25 +08:00
zz
65222e2e3a
fix: remove deprecated rules (#88) 2022-05-03 00:10:59 +08:00
Anthony Fu
a1e890844f release v0.22.0 2022-05-01 08:53:43 +08:00
QiroNT
a2de527401
fix: complete typescript overrides (#87)
* fix: complete typescript overrides

* chore: typo
2022-05-01 08:53:21 +08:00
Anthony Fu
6080d3f74d release v0.21.1 2022-04-26 01:43:55 +08:00
liuq
b996c58bac
fix: fixed rules not works (#86)
Co-authored-by: linka <lqadm@qq.com>
2022-04-26 01:43:26 +08:00
Anthony Fu
b8fe1fabea release v0.21.0 2022-04-25 13:26:25 +08:00
Anthony Fu
0ab9f88603 feat(eslint-plugin): new import dedupe rule 2022-04-25 13:26:07 +08:00
liyujun
17670e8e38
fix: space-before-function-paren allows space in anonymous and asyncArrow function. (#84) 2022-04-25 01:02:25 +08:00
Coder Zhao
686f285a37
chore: replace no-leading-newline with no-multiple-empty-lines (#82) 2022-04-24 22:11:01 +08:00
Anthony Fu
2d9efd4df6 release v0.20.7 2022-04-23 09:23:16 +08:00
Anthony Fu
b8e6cdf047 chore: updete deps 2022-04-23 09:23:11 +08:00
Anthony Fu
50c962197b release v0.20.6 2022-04-17 13:17:38 +08:00
Anthony Fu
bf19dc0adb fix: indents 2022-04-17 13:17:35 +08:00
Anthony Fu
38f64ae9af release v0.20.5 2022-04-17 13:15:15 +08:00
Anthony Fu
22527f61de fix: SwitchCase indent 2022-04-17 13:15:12 +08:00
Anthony Fu
1ff53f2f04 release v0.20.4 2022-04-17 12:49:51 +08:00
Anthony Fu
316bbd903b fix: ts indent ingores 2022-04-17 12:49:48 +08:00
Anthony Fu
bce5016b53 release v0.20.3 2022-04-16 09:03:18 +08:00
Anthony Fu
ddd34a9465 fix: do not require comma-dangle in markdown 2022-04-16 09:02:55 +08:00
Anthony Fu
2f1c785eef release v0.20.2 2022-04-07 06:14:31 +08:00
Anthony Fu
4eb7aee28e chore: disable prefer-inline-type-import by default 2022-04-07 06:14:22 +08:00
Anthony Fu
769bee0139 release v0.20.1 2022-04-07 06:06:58 +08:00
Anthony Fu
07a15be095 fix(inline-type): ignore default import 2022-04-07 06:06:50 +08:00
Anthony Fu
0af15d4bf4 release v0.20.0 2022-04-07 05:53:53 +08:00
Anthony Fu
d23abea648 feat: add prefer-inline-type-import 2022-04-07 05:53:48 +08:00
Anthony Fu
eaff018580
Update README.md 2022-04-06 20:45:50 +08:00
Anthony Fu
327ab9dd35
chore: update 2022-04-05 04:45:55 +08:00
Anthony Fu
ea70c5c6aa release v0.19.4 2022-04-02 23:51:48 +08:00
Anthony Fu
2e9948029c feat: new if-newline rule 2022-04-02 23:51:24 +08:00
Anthony Fu
a6692cc074 release v0.19.3 2022-04-02 23:18:43 +08:00
Anthony Fu
ded3cf2da2 feat: custom plugin 2022-04-02 23:18:36 +08:00
Anthony Fu
f1644757c8 release v0.19.2 2022-03-31 22:19:38 +08:00
Anthony Fu
a695d58bd0 chore: bye lerna 2022-03-31 22:19:27 +08:00
CondorHero
5f05cfcfd6
fix: eslint-plugin-import support TypeScript (#77)
Co-authored-by: CondorHero <love2xinwei@gmail.com>
2022-03-31 22:19:07 +08:00
Anthony Fu
25668d5d1c v0.19.1 2022-03-30 16:57:53 +08:00
Anthony Fu
0cc68e6219 fix: missing file, close #76 2022-03-30 16:57:42 +08:00
Anthony Fu
a93e26642d v0.19.0 2022-03-30 04:32:50 +08:00
Anthony Fu
9653a33381 fix: inline eslint-config-standard 2022-03-30 04:32:30 +08:00
Anthony Fu
95a2c10b3a chore: update 2022-03-30 04:27:14 +08:00
Anthony Fu
d4538f42b1 feat: vue sfc tags order 2022-03-30 04:20:16 +08:00
Anthony Fu
782ab7abb1 v0.18.9 2022-03-20 16:03:41 +08:00
Anthony Fu
a5ec18a973 chore: update deps 2022-03-20 16:03:34 +08:00
Anthony Fu
0a1f8c5612 fix(vue): disable vue/no-setup-props-destructure 2022-03-18 16:42:49 +08:00
Anthony Fu
73a790c1d0 fix: disable yml/no-empty-document 2022-03-11 06:13:25 +08:00
Anthony Fu
0349a41506 v0.18.8 2022-03-11 06:11:59 +08:00
Anthony Fu
a3c897a9ec fix: disable spaced-comment in yaml 2022-03-11 06:11:07 +08:00
Anthony Fu
774757b0e5 fix: disable no-var-requires in markdown 2022-03-11 06:00:29 +08:00
Anthony Fu
83db65f464 v0.18.7 2022-03-11 05:56:30 +08:00
Anthony Fu
2e962a2785 feat: improve no-unused-vars rule 2022-03-11 05:55:22 +08:00
Anthony Fu
625e845c80 chore: update 2022-03-11 04:46:10 +08:00
Anthony Fu
38c927024b chore: improve docs 2022-03-11 04:43:17 +08:00
Anthony Fu
18e673f773 v0.18.6 2022-03-10 20:33:15 +08:00
Anthony Fu
98708f1996 fix: ignore lock files 2022-03-10 20:33:09 +08:00
Anthony Fu
8b0a239f8f chore: package.json keys 2022-03-10 20:29:48 +08:00
Anthony Fu
a60cd80ba9 chore: lint 2022-03-10 20:28:42 +08:00
Anthony Fu
48cc619ec2 v0.18.5 2022-03-10 20:26:37 +08:00
Anthony Fu
97975dafc5 fix: package.json keys order 2022-03-10 20:26:31 +08:00
Anthony Fu
b425b251ea chore: update readme 2022-03-10 20:22:02 +08:00
Anthony Fu
9346e47d92 v0.18.4 2022-03-10 20:20:02 +08:00
Anthony Fu
b6133dcd42 fix: package.json key orders 2022-03-10 20:19:52 +08:00
Anthony Fu
b7cff5d6a2 chore: update ignore pattern 2022-03-10 20:16:17 +08:00
Anthony Fu
e54ac17e09 fix: imporve markdown rules 2022-03-09 19:00:11 +08:00
Anthony Fu
8f51445a67 fix: lint vitepress by default 2022-03-09 18:58:38 +08:00
Anthony Fu
4a0c791207 v0.18.3 2022-03-08 03:29:02 +08:00
Anthony Fu
8e1140aef2 fix: disable no-callback-literal 2022-03-08 03:28:56 +08:00
Anthony Fu
a46866b102 v0.18.2 2022-03-08 03:24:07 +08:00
Anthony Fu
0117961e43 fix: update markdown rules 2022-03-08 03:24:01 +08:00
Anthony Fu
22b5593306 v0.18.1 2022-03-08 03:18:09 +08:00
Anthony Fu
a50bd851d1 fix: markdown parser 2022-03-08 03:17:55 +08:00
Anthony Fu
c477c8d0e2 v0.18.0 2022-03-07 16:47:52 +08:00
Anthony Fu
48a0d78824 feat: add markdown plugin 2022-03-07 16:47:31 +08:00
Anthony Fu
1ccdd44162 v0.17.0 2022-03-07 16:03:58 +08:00
Anthony Fu
83a54e07d5 feat: update deps 2022-03-07 16:03:52 +08:00
Anthony Fu
9e7ba7b131 v0.16.1 2022-01-27 17:30:03 +08:00
Anthony Fu
7cedbd1aa4 chore: update deps 2022-01-27 17:29:35 +08:00
Anthony Fu
54dd689664 v0.16.0 2022-01-14 16:40:18 +08:00
Anthony Fu
d33ec89b76 feat: upgrade eslint-config-standard 2022-01-14 16:40:06 +08:00
Anthony Fu
d9af1bef22 v0.15.0 2022-01-07 03:23:21 +08:00
Anthony Fu
13c90b5150 feat: update ts rules 2022-01-07 03:23:12 +08:00
Anthony Fu
e6ffa98249 v0.14.2 2021-12-28 02:51:07 +08:00
Anthony Fu
7b71c7852d fix: upgrade deps, close #68 2021-12-28 02:50:58 +08:00
Anthony Fu
a8d7a3401b v0.14.1 2021-12-27 17:04:59 +08:00
Anthony Fu
46e9ea35b9 fix: disable vue attrs wrap 2021-12-27 17:04:52 +08:00
Anthony Fu
392f70ffc4 v0.14.0 2021-12-18 11:43:39 +08:00
Anthony Fu
d45487e1f6 feat: enable sort-imports 2021-12-18 11:42:52 +08:00
Anthony Fu
37439ec91a v0.13.1 2021-12-12 08:21:05 +08:00
Anthony Fu
0722603cfe fix: no-use-before-define for functions 2021-12-12 08:20:58 +08:00
Anthony Fu
25602827e3 v0.13.0 2021-12-12 08:17:59 +08:00
Anthony Fu
dd76d5d8d9 feat: update ts rules, enforce import type 2021-12-12 08:17:49 +08:00
Anthony Fu
7993f922db v0.12.2 2021-12-07 23:46:31 +08:00
Anthony Fu
2ccdc6f2a5 fix(react): disable react/react-in-jsx-scope 2021-12-07 23:46:24 +08:00
Anthony Fu
1eb8214bb1 v0.12.1 2021-12-06 05:40:44 +08:00
Anthony Fu
6373bc7ec9 fix: rules 2021-12-06 05:40:37 +08:00
Anthony Fu
cc47ac65e6 v0.12.0 2021-12-04 23:56:56 +08:00
Anthony Fu
2e07691eeb feat: rules for tests 2021-12-04 23:56:37 +08:00
Anthony Fu
92540f2135 v0.11.1 2021-11-28 01:09:54 +08:00
Anthony Fu
eb76d9b8bb fix(vue): disable vue/multi-word-component-names 2021-11-28 01:09:24 +08:00
Anthony Fu
8b15a8349f v0.11.0 2021-11-28 01:02:05 +08:00
Anthony Fu
ffe704965f chore: update deps 2021-11-28 01:01:34 +08:00
云游君
3ac8a75af3
docs: add README (#66) 2021-10-31 22:58:00 +08:00
Anthony Fu
c4a8f9ef5f v0.10.0 2021-10-16 21:50:10 +08:00
Anthony Fu
e9027d5e20 feat: support eslint v8 2021-10-16 21:50:00 +08:00
HBS
3b079f9425
feat: use yaml-eslint-parser (#63) 2021-10-09 12:32:28 +08:00
Anthony Fu
cc873c7f12 v0.9.0 2021-09-14 10:19:03 +08:00
Anthony Fu
d701469a55 fix: improve rules for specific files 2021-09-14 10:18:34 +08:00
Anthony Fu
63ade1f6d1 v0.8.2 2021-09-13 11:31:13 +08:00
Anthony Fu
dcb4a67de2 fix: disable rules 2021-09-13 11:31:02 +08:00
Anthony Fu
5c12c1f8c9 v0.8.1 2021-09-08 20:10:13 +08:00
nirtamir2
92c3e62135
fix: eqeqeq rule deprecated option allow-null (#61)
* fix: `eqeqeq` rule deprecated option allow-null

https://eslint.org/docs/rules/eqeqeq#allow-null

* Update packages/basic/index.js

Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
2021-09-08 20:09:23 +08:00
Anthony Fu
e3e97d18d5 v0.8.0 2021-09-08 05:17:30 +08:00
Anthony Fu
d086aff8a8 chore: update deps 2021-09-08 05:16:50 +08:00
Anthony Fu
b46157c63b v0.7.0 2021-07-05 11:12:21 +08:00
Anthony Fu
10f094a3ab chore: update deps 2021-07-05 11:10:54 +08:00
Anthony Fu
46a8d7acde fix: disable no-undef for vue files 2021-07-05 11:09:54 +08:00
Han(ハン)
5bc11e42e6
fix: typescript-eslint conflict with indent rule (#59) 2021-06-24 20:57:50 +08:00
Anthony Fu
7998ef85f8 v0.6.6 2021-06-11 16:11:09 +08:00
Anthony Fu
8dce7d171d fix: no-console allow warn and error 2021-06-11 16:10:56 +08:00
云游君
8952ede579
refactor: simplify eslint-plugin-import extend (#58) 2021-06-08 22:21:31 +08:00
Anthony Fu
5a67962e25 v0.6.5 2021-05-09 15:45:45 +08:00
Anthony Fu
ab21039962 fix: no-console 2021-05-09 15:45:31 +08:00
JserWang
c968eccbcd
fix: no-spaced-func was deprecated in v3.3.0 (#57) 2021-04-26 10:21:39 +08:00
Anthony Fu
6646d1c08c v0.6.4 2021-04-20 07:03:25 +08:00
Anthony Fu
8f3f8f5a42 fix: overrides 2021-04-20 07:03:18 +08:00
Anthony Fu
db0dfbfe0a v0.6.3 2021-04-20 05:46:56 +08:00
Anthony Fu
19d9122e6a chore: apply lint 2021-04-20 05:46:47 +08:00
Ininit
412d8480d9
fix: eslint-basic rules do not take effect (#56) 2021-04-20 05:45:40 +08:00
Anthony Fu
52d7e70514 v0.6.2 2021-03-16 00:30:18 +08:00
Anthony Fu
67595932e4 fix: only disable no-unused-vars on vue file 2021-03-16 00:30:01 +08:00
Anthony Fu
31505698e4 fix: bring back eslint-plugin-html 2021-03-16 00:28:30 +08:00
Anthony Fu
3b9bd2a3df v0.6.1 2021-03-15 01:58:57 +08:00
Anthony Fu
9847ac276b chore: fix 2021-03-15 01:58:43 +08:00
Anthony Fu
3915e81640 chore: fix 2021-03-15 01:57:00 +08:00
Anthony Fu
2b691b3662 v0.6.0 2021-03-15 01:53:48 +08:00
Anthony Fu
d11174c6dd feat: overhaul 2021-03-15 01:53:40 +08:00
Anthony Fu
072c61bfa6 v0.5.1 2021-03-14 02:27:06 +08:00
Anthony Fu
fb338afe62 chore: deps 2021-03-14 02:26:59 +08:00
Anthony Fu
03ce850ef4 v0.5.0 2021-03-13 21:11:42 +08:00
Anthony Fu
c4a684032b chore: update deps 2021-03-13 21:11:35 +08:00
Anthony Fu
5678d9f5c3 feat: no unused disable 2021-03-13 21:09:53 +08:00
Anthony Fu
3f7f753a5a v0.4.3 2020-10-21 15:09:21 +08:00
Anthony Fu
4cc878512b chore: update 2020-10-21 15:09:11 +08:00
Anthony Fu
a3dd80c160 v0.4.2 2020-10-21 14:49:52 +08:00
Anthony Fu
33b93946af chore: update 2020-10-21 14:49:38 +08:00
Anthony Fu
4c35e1bbb8 v0.4.1 2020-10-21 14:43:08 +08:00
Anthony Fu
4c7e189fcd chore: update 2020-10-21 14:42:56 +08:00
Anthony Fu
0378f3d423 v0.4.0 2020-10-21 14:39:50 +08:00
Anthony Fu
9755c28da2 chore!: update 2020-10-21 14:38:36 +08:00
Anthony Fu
7ce57bfbf1 v0.3.4 2020-10-20 12:21:58 +08:00
Anthony Fu
c0c3070075 chore: update deps 2020-10-20 12:21:44 +08:00
Anthony Fu
91a8757a8c v0.3.3 2020-08-22 00:07:57 +08:00
Anthony Fu
245001d081 fix: disable import/no-absolute-path 2020-08-22 00:02:01 +08:00
Anthony Fu
e25761fcfc v0.3.2 2020-08-12 20:09:11 +08:00
Anthony Fu
7dd8ffaed0 chore: lint 2020-08-12 20:08:06 +08:00
Anthony Fu
24e025c12d v0.3.1 2020-08-12 19:56:23 +08:00
Anthony Fu
e53f3ec8db fix: ref 2020-08-12 19:51:00 +08:00
Anthony Fu
14e207d392 v0.3.0 2020-08-12 19:44:16 +08:00
Anthony Fu
c665c58309 chore: script 2020-08-12 19:43:48 +08:00
Anthony Fu
f7c8146857 chore: lerna 2020-08-12 19:42:30 +08:00
Anthony Fu
54cb86ec3b chore: remove renovate 2020-08-12 19:25:59 +08:00
Anthony Fu
a7fbdcad4b feat: add react and all 2020-08-12 19:24:32 +08:00
Renovate Bot
f82ee6fce9 fix(deps): update all non-major dependencies 2020-08-10 01:14:31 +00:00
Renovate Bot
2243bf67fa fix(deps): update all non-major dependencies 2020-08-03 02:26:15 +00:00
Renovate Bot
3a6b4ea59e fix(deps): update dependency @typescript-eslint/eslint-plugin to v3.7.0 2020-07-27 02:06:34 +00:00
Renovate Bot
e0b59f271f fix(deps): update dependency eslint-plugin-vue to v7.0.0-beta.0 2020-07-20 01:29:43 +00:00
Anthony Fu
b962266ba1 chore: updates 2020-07-18 22:13:58 +08:00
Anthony Fu
9b7f5ce9d1 v0.2.14 2020-07-18 22:10:55 +08:00
Anthony Fu
c5ca025ff8 chore: switch to pnpm and update deps 2020-07-18 22:08:29 +08:00
Anthony Fu
cd4bed781f v0.2.13 2020-06-09 19:10:22 +08:00
Anthony Fu
093620f3b3 Merge branch 'master' of https://github.com/antfu/eslint-config 2020-06-09 19:09:59 +08:00
Anthony Fu
88b8b1ef6b chore: remove unicorn/recommand 2020-06-09 19:09:54 +08:00
Renovate Bot
494d99c2bb fix(deps): update dependency @typescript-eslint/eslint-plugin to v3.1.0 2020-06-08 02:25:58 +00:00
Anthony Fu
7ba01e3d5b v0.2.12 2020-06-04 12:49:41 +08:00
Anthony Fu
ca6b89bd88 chore: update 2020-06-04 12:49:19 +08:00
Renovate Bot
214c0be029 fix(deps): update dependency @typescript-eslint/eslint-plugin to v3.0.2 2020-06-01 04:28:34 +00:00
Renovate Bot
ebb18209d5 fix(deps): update typescript-eslint monorepo to v3 2020-05-25 01:56:05 +00:00
Renovate Bot
7a2af88bd9 fix(deps): update dependency eslint-plugin-unicorn to v20 2020-05-18 03:40:23 +00:00
Renovate Bot
f5d6ebda7c fix(deps): update dependency eslint-plugin-nuxt to v1 2020-05-18 02:28:21 +00:00
Renovate Bot
d8575375f6 fix(deps): update dependency @typescript-eslint/eslint-plugin to v2.33.0 2020-05-18 01:56:47 +00:00
Renovate Bot
977cbd6058 chore(deps): update dependency eslint to v7 2020-05-11 03:16:53 +00:00
Renovate Bot
2fb885521b fix(deps): update dependency @typescript-eslint/eslint-plugin to v2.31.0 2020-05-11 01:33:08 +00:00
Renovate Bot
cabb0999cd fix(deps): update dependency @typescript-eslint/eslint-plugin to v2.30.0 2020-05-04 01:53:08 +00:00
Renovate Bot
cbd45fdcf9 fix(deps): update dependency eslint-plugin-unicorn to v19 2020-04-27 01:45:58 +00:00
Renovate Bot
5e6585335d fix(deps): update dependency @typescript-eslint/eslint-plugin to v2.29.0 2020-04-27 01:19:32 +00:00
Renovate Bot
e42c5767f6 fix(deps): update dependency @typescript-eslint/eslint-plugin to v2.28.0 2020-04-20 01:49:52 +00:00
Renovate Bot
dc00c77075 fix(deps): update dependency @typescript-eslint/eslint-plugin to v2.27.0 2020-04-13 00:59:52 +00:00
Renovate Bot
9c666715c2 fix(deps): update dependency @typescript-eslint/eslint-plugin to v2.26.0 2020-04-06 01:48:49 +00:00
Renovate Bot
05334ab400 fix(deps): update dependency eslint-plugin-unicorn to v18 2020-03-30 03:59:53 +00:00
Renovate Bot
da8bfed5c5 fix(deps): update dependency @typescript-eslint/eslint-plugin to v2.25.0 2020-03-30 02:45:51 +00:00
Renovate Bot
ae3acb40f3 fix(deps): update all non-major dependencies 2020-03-23 02:34:44 +00:00
Renovate Bot
ae8dee6035 fix(deps): update dependency @typescript-eslint/eslint-plugin to v2.23.0 2020-03-16 01:37:05 +00:00
Renovate Bot
96856537cd fix(deps): update dependency eslint-plugin-unicorn to v17 2020-03-09 04:25:37 +00:00
Renovate Bot
367c663eb0 fix(deps): update all non-major dependencies 2020-03-09 01:18:03 +00:00
Renovate Bot
ae238f275c fix(deps): update dependency @typescript-eslint/eslint-plugin to v2.21.0 2020-03-02 01:50:40 +00:00
Renovate Bot
d938b1d714 fix(deps): update all non-major dependencies 2020-02-24 02:00:19 +00:00
Renovate Bot
8bda49afb3 fix(deps): update all non-major dependencies 2020-02-17 01:55:27 +00:00
Renovate Bot
cd48d476bf fix(deps): update all non-major dependencies 2020-02-10 01:32:09 +00:00
Renovate Bot
8bb46879d8 fix(deps): update dependency eslint-plugin-unicorn to v16 2020-02-03 01:34:16 +00:00
Anthony Fu
0efcea4b03 v0.2.11 2020-01-30 17:47:36 +08:00
Anthony Fu
ce7f9ec968 fix: update 2020-01-30 16:08:22 +08:00
Renovate Bot
faa9b11d52 fix(deps): update all non-major dependencies 2020-01-29 01:28:28 +00:00
renovate[bot]
b6c068cf01
fix(deps): update dependency eslint-plugin-unicorn to v15 (#18)
Co-authored-by: WhiteSource Renovate <renovatebot@gmail.com>
2020-01-29 09:25:58 +08:00
renovate[bot]
d37b5cc912
fix(deps): update dependency eslint-plugin-node to v11 (#19)
Co-authored-by: WhiteSource Renovate <renovatebot@gmail.com>
2020-01-29 09:25:47 +08:00
Anthony Fu
78ed60fbae
Update renovate.json 2020-01-29 09:25:29 +08:00
Anthony Fu
714ed22495 v0.2.10 2019-12-12 02:21:34 +08:00
Anthony Fu
1b7b4314bb chore: allow lock files 2019-12-12 02:21:20 +08:00
Anthony Fu
b2ce2c2fb7 chore: release 2019-12-12 02:19:14 +08:00
Anthony Fu
c773e5e043 fix: dependencies 2019-12-12 02:15:06 +08:00
renovate[bot]
49f5108fb2 fix(deps): update dependency eslint-plugin-unicorn to v14 (#16) 2019-12-12 02:11:45 +08:00
renovate[bot]
0583881754 fix(deps): update all non-major dependencies (#14) 2019-12-04 11:55:00 +08:00
renovate[bot]
5d0dacae0a fix(deps): update dependency eslint-plugin-vue to v6 (#13) 2019-11-12 13:57:14 +08:00
renovate[bot]
e09cd415f1 fix(deps): update all non-major dependencies (#12) 2019-11-12 13:22:42 +08:00
Anthony Fu
5107849741 v0.2.8 2019-10-29 09:38:18 +08:00
Anthony Fu
15362aaa29 chore: update packages
v0.2.7

update packages
2019-10-29 09:35:48 +08:00
renovate[bot]
d5341a2507 fix(deps): update dependency @typescript-eslint/eslint-plugin to v2.5.0 (#11) 2019-10-23 01:22:59 +08:00
Anthony Fu
50e989f82d
Merge pull request #10 from antfu/renovate/eslint-plugin-unicorn-12.x
fix(deps): update dependency eslint-plugin-unicorn to v12
2019-10-02 15:14:59 +08:00
Renovate Bot
f565a2f86e
fix(deps): update dependency eslint-plugin-unicorn to v12 2019-09-30 00:45:44 +00:00
Anthony Fu
7a4a64e9bd
Merge pull request #8 from antfu/renovate/all-minor-patch
fix(deps): update dependency @typescript-eslint/eslint-plugin to v2.3.1
2019-09-26 09:10:38 +08:00
Renovate Bot
8c12e7e8cb
fix(deps): update dependency @typescript-eslint/eslint-plugin to v2.3.1 2019-09-23 17:09:32 +00:00
Anthony Fu
dc7c6393c2
Merge pull request #6 from antfu/renovate/all-minor-patch
fix(deps): update dependency @typescript-eslint/eslint-plugin to v2.1.0
2019-09-09 17:48:19 +08:00
Anthony Fu
2eb6bb2954
Merge pull request #7 from antfu/renovate/eslint-plugin-node-10.x
fix(deps): update dependency eslint-plugin-node to v10
2019-09-09 17:48:08 +08:00
Renovate Bot
2e4bef3927
fix(deps): update dependency eslint-plugin-node to v10 2019-09-09 00:52:22 +00:00
Renovate Bot
99a5c38fec
fix(deps): update dependency @typescript-eslint/eslint-plugin to v2.1.0 2019-09-09 00:52:14 +00:00
Anthony Fu
6c3c583ebd
Merge pull request #5 from antfu/renovate/eslint-config-standard-14.x
fix(deps): update dependency eslint-config-standard to v14
2019-08-27 12:16:45 +08:00
Renovate Bot
d8d11aa4ff
fix(deps): update dependency eslint-config-standard to v14 2019-08-26 01:29:04 +00:00
Anthony Fu
65626a180f v0.2.6 2019-08-23 00:20:12 +08:00
Anthony Fu
0a2b8cdede fix: update ts config 2019-08-23 00:19:43 +08:00
Anthony Fu
d2aae84352
Merge pull request #3 from antfu/renovate/eslint-plugin-unicorn-10.x
fix(deps): update dependency eslint-plugin-unicorn to v10
2019-08-23 00:14:29 +08:00
Anthony Fu
d93b98c721
Merge pull request #4 from antfu/renovate/major-typescript-eslint-monorepo
fix(deps): update typescript-eslint monorepo to v2 (major)
2019-08-23 00:14:09 +08:00
Renovate Bot
1f4250e75e
fix(deps): update typescript-eslint monorepo to v2 2019-08-19 00:29:32 +00:00
Renovate Bot
b4b704fb81
fix(deps): update dependency eslint-plugin-unicorn to v10 2019-07-29 00:42:25 +00:00
Anthony Fu
23506b57c1 v0.2.5 2019-07-19 15:53:28 +08:00
Anthony Fu
be4d232fb8 fix: vue 2019-07-19 15:53:07 +08:00
Anthony Fu
2e208c4d05 v0.2.4 2019-07-19 15:51:40 +08:00
Anthony Fu
03b3d7a295 fix: vue deps 2019-07-19 15:51:21 +08:00
Anthony Fu
559d60c3ec v0.2.3 2019-07-19 15:33:05 +08:00
Anthony Fu
cbf7bca6d2 fix: update vue config 2019-07-19 15:32:43 +08:00
Anthony Fu
7105b268ee chore: release -y 2019-07-19 14:42:36 +08:00
Anthony Fu
c8c6f07341 v0.2.2 2019-07-19 14:42:00 +08:00
Anthony Fu
5d507f1d93 fix: update ts rules 2019-07-19 14:41:36 +08:00
Anthony Fu
9153f9e759 v0.2.1 2019-07-18 04:43:25 +08:00
Anthony Fu
0b40222ae9 fix: extends order 2019-07-18 04:43:03 +08:00
Anthony Fu
e6e7a00698 chore(ci): add renovate config 2019-07-18 04:22:48 +08:00
Anthony Fu
5b47b8f0aa docs: add license
fix
2019-07-18 04:14:53 +08:00
Anthony Fu
b63428da1a v0.2.0 2019-07-18 04:12:18 +08:00
Anthony Fu
b025b09a5f feat: add ts config 2019-07-18 04:11:55 +08:00
Anthony Fu
25922716ee v0.1.5 2019-07-18 03:48:25 +08:00
Anthony Fu
2022fc2a1f fix: npm access public 2019-07-18 03:47:50 +08:00
91 changed files with 8020 additions and 212 deletions

3
.eslintrc.json Normal file
View File

@ -0,0 +1,3 @@
{
"extends": "@antfu"
}

22
.github/workflows/release.yml vendored Normal file
View File

@ -0,0 +1,22 @@
name: Release
on:
push:
tags:
- 'v*'
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: actions/setup-node@v3
with:
node-version: 16.x
- run: npx changelogithub
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}

3
.gitignore vendored
View File

@ -77,5 +77,4 @@ dist
# IDE
.idea
package-lock.json
*.learna_backup
*.lerna_backup

2
.npmrc Normal file
View File

@ -0,0 +1,2 @@
strict-peer-dependencies=false
shamefully-hoist=true

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019-PRESENT Anthony Fu<https://github.com/antfu>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

160
README.md Normal file
View File

@ -0,0 +1,160 @@
# @antfu/eslint-config
[![npm](https://img.shields.io/npm/v/@antfu/eslint-config?color=444&label=)](https://npmjs.com/package/@antfu/eslint-config) [![code style](https://antfu.me/badge-code-style.svg)](https://github.com/antfu/eslint-config)
- Single quotes, no semi
- Auto fix for formatting (aimed to be used standalone **without** Prettier)
- Designed to work with TypeScript, Vue out-of-box
- Lint also for json, yaml, markdown
- Sorted imports, dangling commas
- Reasonable defaults, best practices, only one-line of config
- **Style principle**: Minimal for reading, stable for diff
## Usage
### Install
```bash
pnpm add -D eslint @antfu/eslint-config
```
### Config `.eslintrc`
```json
{
"extends": "@antfu"
}
```
> You don't need `.eslintignore` normally as it has been provided by the preset.
### Add script for package.json
For example:
```json
{
"scripts": {
"lint": "eslint .",
"lint:fix": "eslint . --fix"
}
}
```
### VS Code support (auto fix)
Install [VS Code ESLint extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint)
Add the following settings to your `settings.json`:
```jsonc
{
"prettier.enable": false,
"editor.formatOnSave": false,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
"source.organizeImports": false
},
// The following is optional.
// It's better to put under project setting `.vscode/settings.json`
// to avoid conflicts with working with different eslint configs
// that does not support all formats.
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
"vue",
"html",
"markdown",
"json",
"jsonc",
"yaml"
]
}
```
### TypeScript Aware Rules
Type aware rules are enabled when a `tsconfig.eslint.json` is found in the project root, which will introduce some stricter rules into your project. If you want to enable it while have no `tsconfig.eslint.json` in the project root, you can change tsconfig name by modifying `ESLINT_TSCONFIG` env.
```js
// .eslintrc.js
const process = require('node:process')
process.env.ESLINT_TSCONFIG = 'tsconfig.json'
module.exports = {
extends: '@antfu'
}
```
### Lint Staged
If you want to apply lint and auto-fix before every commit, you can add the following to your `package.json`:
```json
{
"simple-git-hooks": {
"pre-commit": "pnpm lint-staged"
},
"lint-staged": {
"*": "eslint --fix"
}
}
```
and then
```bash
npm i -D lint-staged simple-git-hooks
```
## Badge
If you enjoy this code style, and would like to mention it in your project, here is the badge you can use:
```md
[![code style](https://antfu.me/badge-code-style.svg)](https://github.com/antfu/eslint-config)
```
[![code style](https://antfu.me/badge-code-style.svg)](https://github.com/antfu/eslint-config)
## FAQ
### Prettier?
[Why I don't use Prettier](https://antfu.me/posts/why-not-prettier)
### How to lint CSS?
This config does NOT lint CSS. I personally use [UnoCSS](https://github.com/unocss/unocss) so I don't write CSS. If you still prefer CSS, you can use [stylelint](https://stylelint.io/) for CSS linting.
### I prefer XXX...
Sure, you can override the rules in your `.eslintrc` file.
<!-- eslint-skip -->
```jsonc
{
"extends": "@antfu",
"rules": {
// your rules...
}
}
```
Or you can always fork this repo and make your own.
## Check Also
- [antfu/dotfiles](https://github.com/antfu/dotfiles) - My dotfiles
- [antfu/vscode-settings](https://github.com/antfu/vscode-settings) - My VS Code settings
- [antfu/ts-starter](https://github.com/antfu/ts-starter) - My starter template for TypeScript library
- [antfu/vitesse](https://github.com/antfu/vitesse) - My starter template for Vue & Vite app
## License
[MIT](./LICENSE) License &copy; 2019-PRESENT [Anthony Fu](https://github.com/antfu)

View File

@ -0,0 +1,9 @@
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

9
fixtures/vitesse/.gitignore vendored Normal file
View File

@ -0,0 +1,9 @@
.DS_Store
.vite-ssg-dist
.vite-ssg-temp
*.local
dist
dist-ssr
node_modules
.idea/
*.log

21
fixtures/vitesse/LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020-2021 Anthony Fu
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1 @@
This is a fixture cloned from https://github.com/antfu/vitesse. It's only for lint checking and does not run.

View File

@ -0,0 +1,10 @@
import { defineConfig } from 'cypress'
export default defineConfig({
e2e: {
baseUrl: 'http://localhost:3333',
chromeWebSecurity: false,
specPattern: 'cypress/e2e/**/*.spec.*',
supportFile: false,
},
})

View File

@ -0,0 +1,36 @@
context('Basic', () => {
beforeEach(() => {
cy.visit('/')
})
it('basic nav', () => {
cy.url()
.should('eq', 'http://localhost:3333/')
cy.contains('[Home Layout]')
.should('exist')
cy.get('#input')
.type('Vitesse{Enter}')
.url()
.should('eq', 'http://localhost:3333/hi/Vitesse')
cy.contains('[Default Layout]')
.should('exist')
cy.get('[btn]')
.click()
.url()
.should('eq', 'http://localhost:3333/')
})
it('markdown', () => {
cy.get('[title="About"]')
.click()
.url()
.should('eq', 'http://localhost:3333/about')
cy.get('.shiki')
.should('exist')
})
})

View File

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="apple-touch-icon" href="/pwa-192x192.png">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#00aba9">
<meta name="msapplication-TileColor" content="#00aba9">
<script>
(function () {
const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
const setting = localStorage.getItem('vueuse-color-scheme') || 'auto'
if (setting === 'dark' || (prefersDark && setting !== 'light'))
document.documentElement.classList.toggle('dark', true)
})()
</script>
</head>
<body class="font-sans">
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

View File

@ -0,0 +1,62 @@
{
"type": "module",
"private": true,
"packageManager": "pnpm@8.6.12",
"scripts": {
"build": "vite-ssg build",
"dev": "vite --port 3333 --open",
"lint": "eslint .",
"preview": "vite preview",
"preview-https": "serve dist",
"test": "vitest",
"test:e2e": "cypress open",
"test:unit": "vitest",
"typecheck": "vue-tsc --noEmit",
"up": "taze major -I"
},
"dependencies": {
"@unocss/reset": "^0.54.2",
"@vueuse/core": "^10.3.0",
"@vueuse/head": "^1.1.26",
"nprogress": "^0.2.0",
"pinia": "^2.1.6",
"vue": "^3.3.4",
"vue-demi": "^0.14.5",
"vue-i18n": "^9.2.2",
"vue-router": "^4.2.4"
},
"devDependencies": {
"@antfu/eslint-config": "^0.40.0",
"@iconify-json/carbon": "^1.1.19",
"@intlify/vite-plugin-vue-i18n": "^7.0.0",
"@types/markdown-it-link-attributes": "^3.0.1",
"@types/nprogress": "^0.2.0",
"@vitejs/plugin-vue": "^4.2.3",
"@vue/test-utils": "^2.4.1",
"critters": "^0.0.20",
"cross-env": "^7.0.3",
"cypress": "^12.17.3",
"eslint": "^8.46.0",
"eslint-plugin-cypress": "^2.13.3",
"https-localhost": "^4.7.1",
"markdown-it-link-attributes": "^4.0.1",
"markdown-it-shiki": "^0.9.0",
"pnpm": "^8.6.12",
"shiki": "^0.14.3",
"taze": "^0.11.2",
"typescript": "^5.1.6",
"unocss": "^0.54.2",
"unplugin-auto-import": "^0.16.6",
"unplugin-vue-components": "^0.25.1",
"vite": "^4.4.9",
"vite-plugin-inspect": "^0.7.35",
"vite-plugin-pages": "^0.31.0",
"vite-plugin-pwa": "^0.16.4",
"vite-plugin-vue-layouts": "^0.8.0",
"vite-plugin-vue-markdown": "^0.23.7",
"vite-ssg": "^0.23.1",
"vite-ssg-sitemap": "^0.5.1",
"vitest": "^0.34.1",
"vue-tsc": "^1.8.8"
}
}

View File

@ -0,0 +1,26 @@
<script setup lang="ts">
// https://github.com/vueuse/head
// you can use this to manipulate the document head in any components,
// they will be rendered correctly in the html results with vite-ssg
useHead({
title: 'Vitesse',
meta: [
{ name: 'description', content: 'Opinionated Vite Starter Template' },
{
name: 'theme-color',
content: computed(() => isDark.value ? '#00aba9' : '#ffffff'),
},
],
link: [
{
rel: 'icon',
type: 'image/svg+xml',
href: computed(() => preferredDark.value ? '/favicon-dark.svg' : '/favicon.svg'),
},
],
})
</script>
<template>
<RouterView />
</template>

546
fixtures/vitesse/src/auto-imports.d.ts vendored Normal file
View File

@ -0,0 +1,546 @@
// Generated by 'unplugin-auto-import'
export {}
declare global {
const $$: typeof import('vue/macros')['$$']
const $: typeof import('vue/macros')['$']
const $computed: typeof import('vue/macros')['$computed']
const $customRef: typeof import('vue/macros')['$customRef']
const $ref: typeof import('vue/macros')['$ref']
const $shallowRef: typeof import('vue/macros')['$shallowRef']
const $toRef: typeof import('vue/macros')['$toRef']
const EffectScope: typeof import('vue')['EffectScope']
const asyncComputed: typeof import('@vueuse/core')['asyncComputed']
const autoResetRef: typeof import('@vueuse/core')['autoResetRef']
const computed: typeof import('vue')['computed']
const computedAsync: typeof import('@vueuse/core')['computedAsync']
const computedEager: typeof import('@vueuse/core')['computedEager']
const computedInject: typeof import('@vueuse/core')['computedInject']
const computedWithControl: typeof import('@vueuse/core')['computedWithControl']
const controlledComputed: typeof import('@vueuse/core')['controlledComputed']
const controlledRef: typeof import('@vueuse/core')['controlledRef']
const createApp: typeof import('vue')['createApp']
const createEventHook: typeof import('@vueuse/core')['createEventHook']
const createGlobalState: typeof import('@vueuse/core')['createGlobalState']
const createInjectionState: typeof import('@vueuse/core')['createInjectionState']
const createReactiveFn: typeof import('@vueuse/core')['createReactiveFn']
const createSharedComposable: typeof import('@vueuse/core')['createSharedComposable']
const createUnrefFn: typeof import('@vueuse/core')['createUnrefFn']
const customRef: typeof import('vue')['customRef']
const debouncedRef: typeof import('@vueuse/core')['debouncedRef']
const debouncedWatch: typeof import('@vueuse/core')['debouncedWatch']
const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
const defineComponent: typeof import('vue')['defineComponent']
const eagerComputed: typeof import('@vueuse/core')['eagerComputed']
const effectScope: typeof import('vue')['effectScope']
const extendRef: typeof import('@vueuse/core')['extendRef']
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
const getCurrentScope: typeof import('vue')['getCurrentScope']
const h: typeof import('vue')['h']
const ignorableWatch: typeof import('@vueuse/core')['ignorableWatch']
const inject: typeof import('vue')['inject']
const isDark: typeof import('./composables/dark')['isDark']
const isDefined: typeof import('@vueuse/core')['isDefined']
const isProxy: typeof import('vue')['isProxy']
const isReactive: typeof import('vue')['isReactive']
const isReadonly: typeof import('vue')['isReadonly']
const isRef: typeof import('vue')['isRef']
const makeDestructurable: typeof import('@vueuse/core')['makeDestructurable']
const markRaw: typeof import('vue')['markRaw']
const nextTick: typeof import('vue')['nextTick']
const onActivated: typeof import('vue')['onActivated']
const onBeforeMount: typeof import('vue')['onBeforeMount']
const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']
const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']
const onClickOutside: typeof import('@vueuse/core')['onClickOutside']
const onDeactivated: typeof import('vue')['onDeactivated']
const onErrorCaptured: typeof import('vue')['onErrorCaptured']
const onKeyStroke: typeof import('@vueuse/core')['onKeyStroke']
const onLongPress: typeof import('@vueuse/core')['onLongPress']
const onMounted: typeof import('vue')['onMounted']
const onRenderTracked: typeof import('vue')['onRenderTracked']
const onRenderTriggered: typeof import('vue')['onRenderTriggered']
const onScopeDispose: typeof import('vue')['onScopeDispose']
const onServerPrefetch: typeof import('vue')['onServerPrefetch']
const onStartTyping: typeof import('@vueuse/core')['onStartTyping']
const onUnmounted: typeof import('vue')['onUnmounted']
const onUpdated: typeof import('vue')['onUpdated']
const pausableWatch: typeof import('@vueuse/core')['pausableWatch']
const preferredDark: typeof import('./composables/dark')['preferredDark']
const provide: typeof import('vue')['provide']
const reactify: typeof import('@vueuse/core')['reactify']
const reactifyObject: typeof import('@vueuse/core')['reactifyObject']
const reactive: typeof import('vue')['reactive']
const reactiveComputed: typeof import('@vueuse/core')['reactiveComputed']
const reactiveOmit: typeof import('@vueuse/core')['reactiveOmit']
const reactivePick: typeof import('@vueuse/core')['reactivePick']
const readonly: typeof import('vue')['readonly']
const ref: typeof import('vue')['ref']
const refAutoReset: typeof import('@vueuse/core')['refAutoReset']
const refDebounced: typeof import('@vueuse/core')['refDebounced']
const refDefault: typeof import('@vueuse/core')['refDefault']
const refThrottled: typeof import('@vueuse/core')['refThrottled']
const refWithControl: typeof import('@vueuse/core')['refWithControl']
const resolveComponent: typeof import('vue')['resolveComponent']
const resolveRef: typeof import('@vueuse/core')['resolveRef']
const resolveUnref: typeof import('@vueuse/core')['resolveUnref']
const shallowReactive: typeof import('vue')['shallowReactive']
const shallowReadonly: typeof import('vue')['shallowReadonly']
const shallowRef: typeof import('vue')['shallowRef']
const syncRef: typeof import('@vueuse/core')['syncRef']
const syncRefs: typeof import('@vueuse/core')['syncRefs']
const templateRef: typeof import('@vueuse/core')['templateRef']
const throttledRef: typeof import('@vueuse/core')['throttledRef']
const throttledWatch: typeof import('@vueuse/core')['throttledWatch']
const toRaw: typeof import('vue')['toRaw']
const toReactive: typeof import('@vueuse/core')['toReactive']
const toRef: typeof import('vue')['toRef']
const toRefs: typeof import('vue')['toRefs']
const toggleDark: typeof import('./composables/dark')['toggleDark']
const triggerRef: typeof import('vue')['triggerRef']
const tryOnBeforeMount: typeof import('@vueuse/core')['tryOnBeforeMount']
const tryOnBeforeUnmount: typeof import('@vueuse/core')['tryOnBeforeUnmount']
const tryOnMounted: typeof import('@vueuse/core')['tryOnMounted']
const tryOnScopeDispose: typeof import('@vueuse/core')['tryOnScopeDispose']
const tryOnUnmounted: typeof import('@vueuse/core')['tryOnUnmounted']
const unref: typeof import('vue')['unref']
const unrefElement: typeof import('@vueuse/core')['unrefElement']
const until: typeof import('@vueuse/core')['until']
const useActiveElement: typeof import('@vueuse/core')['useActiveElement']
const useArrayEvery: typeof import('@vueuse/core')['useArrayEvery']
const useArrayFilter: typeof import('@vueuse/core')['useArrayFilter']
const useArrayFind: typeof import('@vueuse/core')['useArrayFind']
const useArrayFindIndex: typeof import('@vueuse/core')['useArrayFindIndex']
const useArrayJoin: typeof import('@vueuse/core')['useArrayJoin']
const useArrayMap: typeof import('@vueuse/core')['useArrayMap']
const useArrayReduce: typeof import('@vueuse/core')['useArrayReduce']
const useArraySome: typeof import('@vueuse/core')['useArraySome']
const useAsyncQueue: typeof import('@vueuse/core')['useAsyncQueue']
const useAsyncState: typeof import('@vueuse/core')['useAsyncState']
const useAttrs: typeof import('vue')['useAttrs']
const useBase64: typeof import('@vueuse/core')['useBase64']
const useBattery: typeof import('@vueuse/core')['useBattery']
const useBluetooth: typeof import('@vueuse/core')['useBluetooth']
const useBreakpoints: typeof import('@vueuse/core')['useBreakpoints']
const useBroadcastChannel: typeof import('@vueuse/core')['useBroadcastChannel']
const useBrowserLocation: typeof import('@vueuse/core')['useBrowserLocation']
const useCached: typeof import('@vueuse/core')['useCached']
const useClipboard: typeof import('@vueuse/core')['useClipboard']
const useColorMode: typeof import('@vueuse/core')['useColorMode']
const useConfirmDialog: typeof import('@vueuse/core')['useConfirmDialog']
const useCounter: typeof import('@vueuse/core')['useCounter']
const useCssModule: typeof import('vue')['useCssModule']
const useCssVar: typeof import('@vueuse/core')['useCssVar']
const useCssVars: typeof import('vue')['useCssVars']
const useCurrentElement: typeof import('@vueuse/core')['useCurrentElement']
const useCycleList: typeof import('@vueuse/core')['useCycleList']
const useDark: typeof import('@vueuse/core')['useDark']
const useDateFormat: typeof import('@vueuse/core')['useDateFormat']
const useDebounce: typeof import('@vueuse/core')['useDebounce']
const useDebounceFn: typeof import('@vueuse/core')['useDebounceFn']
const useDebouncedRefHistory: typeof import('@vueuse/core')['useDebouncedRefHistory']
const useDeviceMotion: typeof import('@vueuse/core')['useDeviceMotion']
const useDeviceOrientation: typeof import('@vueuse/core')['useDeviceOrientation']
const useDevicePixelRatio: typeof import('@vueuse/core')['useDevicePixelRatio']
const useDevicesList: typeof import('@vueuse/core')['useDevicesList']
const useDisplayMedia: typeof import('@vueuse/core')['useDisplayMedia']
const useDocumentVisibility: typeof import('@vueuse/core')['useDocumentVisibility']
const useDraggable: typeof import('@vueuse/core')['useDraggable']
const useDropZone: typeof import('@vueuse/core')['useDropZone']
const useElementBounding: typeof import('@vueuse/core')['useElementBounding']
const useElementByPoint: typeof import('@vueuse/core')['useElementByPoint']
const useElementHover: typeof import('@vueuse/core')['useElementHover']
const useElementSize: typeof import('@vueuse/core')['useElementSize']
const useElementVisibility: typeof import('@vueuse/core')['useElementVisibility']
const useEventBus: typeof import('@vueuse/core')['useEventBus']
const useEventListener: typeof import('@vueuse/core')['useEventListener']
const useEventSource: typeof import('@vueuse/core')['useEventSource']
const useEyeDropper: typeof import('@vueuse/core')['useEyeDropper']
const useFavicon: typeof import('@vueuse/core')['useFavicon']
const useFetch: typeof import('@vueuse/core')['useFetch']
const useFileDialog: typeof import('@vueuse/core')['useFileDialog']
const useFileSystemAccess: typeof import('@vueuse/core')['useFileSystemAccess']
const useFocus: typeof import('@vueuse/core')['useFocus']
const useFocusWithin: typeof import('@vueuse/core')['useFocusWithin']
const useFps: typeof import('@vueuse/core')['useFps']
const useFullscreen: typeof import('@vueuse/core')['useFullscreen']
const useGamepad: typeof import('@vueuse/core')['useGamepad']
const useGeolocation: typeof import('@vueuse/core')['useGeolocation']
const useHead: typeof import('@vueuse/head')['useHead']
const useI18n: typeof import('vue-i18n')['useI18n']
const useIdle: typeof import('@vueuse/core')['useIdle']
const useImage: typeof import('@vueuse/core')['useImage']
const useInfiniteScroll: typeof import('@vueuse/core')['useInfiniteScroll']
const useIntersectionObserver: typeof import('@vueuse/core')['useIntersectionObserver']
const useInterval: typeof import('@vueuse/core')['useInterval']
const useIntervalFn: typeof import('@vueuse/core')['useIntervalFn']
const useKeyModifier: typeof import('@vueuse/core')['useKeyModifier']
const useLastChanged: typeof import('@vueuse/core')['useLastChanged']
const useLocalStorage: typeof import('@vueuse/core')['useLocalStorage']
const useMagicKeys: typeof import('@vueuse/core')['useMagicKeys']
const useManualRefHistory: typeof import('@vueuse/core')['useManualRefHistory']
const useMediaControls: typeof import('@vueuse/core')['useMediaControls']
const useMediaQuery: typeof import('@vueuse/core')['useMediaQuery']
const useMemoize: typeof import('@vueuse/core')['useMemoize']
const useMemory: typeof import('@vueuse/core')['useMemory']
const useMounted: typeof import('@vueuse/core')['useMounted']
const useMouse: typeof import('@vueuse/core')['useMouse']
const useMouseInElement: typeof import('@vueuse/core')['useMouseInElement']
const useMousePressed: typeof import('@vueuse/core')['useMousePressed']
const useMutationObserver: typeof import('@vueuse/core')['useMutationObserver']
const useNavigatorLanguage: typeof import('@vueuse/core')['useNavigatorLanguage']
const useNetwork: typeof import('@vueuse/core')['useNetwork']
const useNow: typeof import('@vueuse/core')['useNow']
const useObjectUrl: typeof import('@vueuse/core')['useObjectUrl']
const useOffsetPagination: typeof import('@vueuse/core')['useOffsetPagination']
const useOnline: typeof import('@vueuse/core')['useOnline']
const usePageLeave: typeof import('@vueuse/core')['usePageLeave']
const useParallax: typeof import('@vueuse/core')['useParallax']
const usePermission: typeof import('@vueuse/core')['usePermission']
const usePointer: typeof import('@vueuse/core')['usePointer']
const usePointerSwipe: typeof import('@vueuse/core')['usePointerSwipe']
const usePreferredColorScheme: typeof import('@vueuse/core')['usePreferredColorScheme']
const usePreferredDark: typeof import('@vueuse/core')['usePreferredDark']
const usePreferredLanguages: typeof import('@vueuse/core')['usePreferredLanguages']
const usePreferredReducedMotion: typeof import('@vueuse/core')['usePreferredReducedMotion']
const useRafFn: typeof import('@vueuse/core')['useRafFn']
const useRefHistory: typeof import('@vueuse/core')['useRefHistory']
const useResizeObserver: typeof import('@vueuse/core')['useResizeObserver']
const useRoute: typeof import('vue-router')['useRoute']
const useRouter: typeof import('vue-router')['useRouter']
const useScreenOrientation: typeof import('@vueuse/core')['useScreenOrientation']
const useScreenSafeArea: typeof import('@vueuse/core')['useScreenSafeArea']
const useScriptTag: typeof import('@vueuse/core')['useScriptTag']
const useScroll: typeof import('@vueuse/core')['useScroll']
const useScrollLock: typeof import('@vueuse/core')['useScrollLock']
const useSessionStorage: typeof import('@vueuse/core')['useSessionStorage']
const useShare: typeof import('@vueuse/core')['useShare']
const useSlots: typeof import('vue')['useSlots']
const useSpeechRecognition: typeof import('@vueuse/core')['useSpeechRecognition']
const useSpeechSynthesis: typeof import('@vueuse/core')['useSpeechSynthesis']
const useStepper: typeof import('@vueuse/core')['useStepper']
const useStorage: typeof import('@vueuse/core')['useStorage']
const useStorageAsync: typeof import('@vueuse/core')['useStorageAsync']
const useStyleTag: typeof import('@vueuse/core')['useStyleTag']
const useSupported: typeof import('@vueuse/core')['useSupported']
const useSwipe: typeof import('@vueuse/core')['useSwipe']
const useTemplateRefsList: typeof import('@vueuse/core')['useTemplateRefsList']
const useTextDirection: typeof import('@vueuse/core')['useTextDirection']
const useTextSelection: typeof import('@vueuse/core')['useTextSelection']
const useTextareaAutosize: typeof import('@vueuse/core')['useTextareaAutosize']
const useThrottle: typeof import('@vueuse/core')['useThrottle']
const useThrottleFn: typeof import('@vueuse/core')['useThrottleFn']
const useThrottledRefHistory: typeof import('@vueuse/core')['useThrottledRefHistory']
const useTimeAgo: typeof import('@vueuse/core')['useTimeAgo']
const useTimeout: typeof import('@vueuse/core')['useTimeout']
const useTimeoutFn: typeof import('@vueuse/core')['useTimeoutFn']
const useTimeoutPoll: typeof import('@vueuse/core')['useTimeoutPoll']
const useTimestamp: typeof import('@vueuse/core')['useTimestamp']
const useTitle: typeof import('@vueuse/core')['useTitle']
const useToNumber: typeof import('@vueuse/core')['useToNumber']
const useToString: typeof import('@vueuse/core')['useToString']
const useToggle: typeof import('@vueuse/core')['useToggle']
const useTransition: typeof import('@vueuse/core')['useTransition']
const useUrlSearchParams: typeof import('@vueuse/core')['useUrlSearchParams']
const useUserMedia: typeof import('@vueuse/core')['useUserMedia']
const useUserStore: typeof import('./store/user')['useUserStore']
const useVModel: typeof import('@vueuse/core')['useVModel']
const useVModels: typeof import('@vueuse/core')['useVModels']
const useVibrate: typeof import('@vueuse/core')['useVibrate']
const useVirtualList: typeof import('@vueuse/core')['useVirtualList']
const useWakeLock: typeof import('@vueuse/core')['useWakeLock']
const useWebNotification: typeof import('@vueuse/core')['useWebNotification']
const useWebSocket: typeof import('@vueuse/core')['useWebSocket']
const useWebWorker: typeof import('@vueuse/core')['useWebWorker']
const useWebWorkerFn: typeof import('@vueuse/core')['useWebWorkerFn']
const useWindowFocus: typeof import('@vueuse/core')['useWindowFocus']
const useWindowScroll: typeof import('@vueuse/core')['useWindowScroll']
const useWindowSize: typeof import('@vueuse/core')['useWindowSize']
const watch: typeof import('vue')['watch']
const watchArray: typeof import('@vueuse/core')['watchArray']
const watchAtMost: typeof import('@vueuse/core')['watchAtMost']
const watchDebounced: typeof import('@vueuse/core')['watchDebounced']
const watchEffect: typeof import('vue')['watchEffect']
const watchIgnorable: typeof import('@vueuse/core')['watchIgnorable']
const watchOnce: typeof import('@vueuse/core')['watchOnce']
const watchPausable: typeof import('@vueuse/core')['watchPausable']
const watchPostEffect: typeof import('vue')['watchPostEffect']
const watchSyncEffect: typeof import('vue')['watchSyncEffect']
const watchThrottled: typeof import('@vueuse/core')['watchThrottled']
const watchTriggerable: typeof import('@vueuse/core')['watchTriggerable']
const watchWithFilter: typeof import('@vueuse/core')['watchWithFilter']
const whenever: typeof import('@vueuse/core')['whenever']
}
// for vue template auto import
import { UnwrapRef } from 'vue'
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
readonly $$: UnwrapRef<typeof import('vue/macros')['$$']>
readonly $: UnwrapRef<typeof import('vue/macros')['$']>
readonly $computed: UnwrapRef<typeof import('vue/macros')['$computed']>
readonly $customRef: UnwrapRef<typeof import('vue/macros')['$customRef']>
readonly $ref: UnwrapRef<typeof import('vue/macros')['$ref']>
readonly $shallowRef: UnwrapRef<typeof import('vue/macros')['$shallowRef']>
readonly $toRef: UnwrapRef<typeof import('vue/macros')['$toRef']>
readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']>
readonly asyncComputed: UnwrapRef<typeof import('@vueuse/core')['asyncComputed']>
readonly autoResetRef: UnwrapRef<typeof import('@vueuse/core')['autoResetRef']>
readonly computed: UnwrapRef<typeof import('vue')['computed']>
readonly computedAsync: UnwrapRef<typeof import('@vueuse/core')['computedAsync']>
readonly computedEager: UnwrapRef<typeof import('@vueuse/core')['computedEager']>
readonly computedInject: UnwrapRef<typeof import('@vueuse/core')['computedInject']>
readonly computedWithControl: UnwrapRef<typeof import('@vueuse/core')['computedWithControl']>
readonly controlledComputed: UnwrapRef<typeof import('@vueuse/core')['controlledComputed']>
readonly controlledRef: UnwrapRef<typeof import('@vueuse/core')['controlledRef']>
readonly createApp: UnwrapRef<typeof import('vue')['createApp']>
readonly createEventHook: UnwrapRef<typeof import('@vueuse/core')['createEventHook']>
readonly createGlobalState: UnwrapRef<typeof import('@vueuse/core')['createGlobalState']>
readonly createInjectionState: UnwrapRef<typeof import('@vueuse/core')['createInjectionState']>
readonly createReactiveFn: UnwrapRef<typeof import('@vueuse/core')['createReactiveFn']>
readonly createSharedComposable: UnwrapRef<typeof import('@vueuse/core')['createSharedComposable']>
readonly createUnrefFn: UnwrapRef<typeof import('@vueuse/core')['createUnrefFn']>
readonly customRef: UnwrapRef<typeof import('vue')['customRef']>
readonly debouncedRef: UnwrapRef<typeof import('@vueuse/core')['debouncedRef']>
readonly debouncedWatch: UnwrapRef<typeof import('@vueuse/core')['debouncedWatch']>
readonly defineAsyncComponent: UnwrapRef<typeof import('vue')['defineAsyncComponent']>
readonly defineComponent: UnwrapRef<typeof import('vue')['defineComponent']>
readonly eagerComputed: UnwrapRef<typeof import('@vueuse/core')['eagerComputed']>
readonly effectScope: UnwrapRef<typeof import('vue')['effectScope']>
readonly extendRef: UnwrapRef<typeof import('@vueuse/core')['extendRef']>
readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']>
readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']>
readonly h: UnwrapRef<typeof import('vue')['h']>
readonly ignorableWatch: UnwrapRef<typeof import('@vueuse/core')['ignorableWatch']>
readonly inject: UnwrapRef<typeof import('vue')['inject']>
readonly isDark: UnwrapRef<typeof import('./composables/dark')['isDark']>
readonly isDefined: UnwrapRef<typeof import('@vueuse/core')['isDefined']>
readonly isProxy: UnwrapRef<typeof import('vue')['isProxy']>
readonly isReactive: UnwrapRef<typeof import('vue')['isReactive']>
readonly isReadonly: UnwrapRef<typeof import('vue')['isReadonly']>
readonly isRef: UnwrapRef<typeof import('vue')['isRef']>
readonly makeDestructurable: UnwrapRef<typeof import('@vueuse/core')['makeDestructurable']>
readonly markRaw: UnwrapRef<typeof import('vue')['markRaw']>
readonly nextTick: UnwrapRef<typeof import('vue')['nextTick']>
readonly onActivated: UnwrapRef<typeof import('vue')['onActivated']>
readonly onBeforeMount: UnwrapRef<typeof import('vue')['onBeforeMount']>
readonly onBeforeUnmount: UnwrapRef<typeof import('vue')['onBeforeUnmount']>
readonly onBeforeUpdate: UnwrapRef<typeof import('vue')['onBeforeUpdate']>
readonly onClickOutside: UnwrapRef<typeof import('@vueuse/core')['onClickOutside']>
readonly onDeactivated: UnwrapRef<typeof import('vue')['onDeactivated']>
readonly onErrorCaptured: UnwrapRef<typeof import('vue')['onErrorCaptured']>
readonly onKeyStroke: UnwrapRef<typeof import('@vueuse/core')['onKeyStroke']>
readonly onLongPress: UnwrapRef<typeof import('@vueuse/core')['onLongPress']>
readonly onMounted: UnwrapRef<typeof import('vue')['onMounted']>
readonly onRenderTracked: UnwrapRef<typeof import('vue')['onRenderTracked']>
readonly onRenderTriggered: UnwrapRef<typeof import('vue')['onRenderTriggered']>
readonly onScopeDispose: UnwrapRef<typeof import('vue')['onScopeDispose']>
readonly onServerPrefetch: UnwrapRef<typeof import('vue')['onServerPrefetch']>
readonly onStartTyping: UnwrapRef<typeof import('@vueuse/core')['onStartTyping']>
readonly onUnmounted: UnwrapRef<typeof import('vue')['onUnmounted']>
readonly onUpdated: UnwrapRef<typeof import('vue')['onUpdated']>
readonly pausableWatch: UnwrapRef<typeof import('@vueuse/core')['pausableWatch']>
readonly preferredDark: UnwrapRef<typeof import('./composables/dark')['preferredDark']>
readonly provide: UnwrapRef<typeof import('vue')['provide']>
readonly reactify: UnwrapRef<typeof import('@vueuse/core')['reactify']>
readonly reactifyObject: UnwrapRef<typeof import('@vueuse/core')['reactifyObject']>
readonly reactive: UnwrapRef<typeof import('vue')['reactive']>
readonly reactiveComputed: UnwrapRef<typeof import('@vueuse/core')['reactiveComputed']>
readonly reactiveOmit: UnwrapRef<typeof import('@vueuse/core')['reactiveOmit']>
readonly reactivePick: UnwrapRef<typeof import('@vueuse/core')['reactivePick']>
readonly readonly: UnwrapRef<typeof import('vue')['readonly']>
readonly ref: UnwrapRef<typeof import('vue')['ref']>
readonly refAutoReset: UnwrapRef<typeof import('@vueuse/core')['refAutoReset']>
readonly refDebounced: UnwrapRef<typeof import('@vueuse/core')['refDebounced']>
readonly refDefault: UnwrapRef<typeof import('@vueuse/core')['refDefault']>
readonly refThrottled: UnwrapRef<typeof import('@vueuse/core')['refThrottled']>
readonly refWithControl: UnwrapRef<typeof import('@vueuse/core')['refWithControl']>
readonly resolveComponent: UnwrapRef<typeof import('vue')['resolveComponent']>
readonly resolveRef: UnwrapRef<typeof import('@vueuse/core')['resolveRef']>
readonly resolveUnref: UnwrapRef<typeof import('@vueuse/core')['resolveUnref']>
readonly shallowReactive: UnwrapRef<typeof import('vue')['shallowReactive']>
readonly shallowReadonly: UnwrapRef<typeof import('vue')['shallowReadonly']>
readonly shallowRef: UnwrapRef<typeof import('vue')['shallowRef']>
readonly syncRef: UnwrapRef<typeof import('@vueuse/core')['syncRef']>
readonly syncRefs: UnwrapRef<typeof import('@vueuse/core')['syncRefs']>
readonly templateRef: UnwrapRef<typeof import('@vueuse/core')['templateRef']>
readonly throttledRef: UnwrapRef<typeof import('@vueuse/core')['throttledRef']>
readonly throttledWatch: UnwrapRef<typeof import('@vueuse/core')['throttledWatch']>
readonly toRaw: UnwrapRef<typeof import('vue')['toRaw']>
readonly toReactive: UnwrapRef<typeof import('@vueuse/core')['toReactive']>
readonly toRef: UnwrapRef<typeof import('vue')['toRef']>
readonly toRefs: UnwrapRef<typeof import('vue')['toRefs']>
readonly toggleDark: UnwrapRef<typeof import('./composables/dark')['toggleDark']>
readonly triggerRef: UnwrapRef<typeof import('vue')['triggerRef']>
readonly tryOnBeforeMount: UnwrapRef<typeof import('@vueuse/core')['tryOnBeforeMount']>
readonly tryOnBeforeUnmount: UnwrapRef<typeof import('@vueuse/core')['tryOnBeforeUnmount']>
readonly tryOnMounted: UnwrapRef<typeof import('@vueuse/core')['tryOnMounted']>
readonly tryOnScopeDispose: UnwrapRef<typeof import('@vueuse/core')['tryOnScopeDispose']>
readonly tryOnUnmounted: UnwrapRef<typeof import('@vueuse/core')['tryOnUnmounted']>
readonly unref: UnwrapRef<typeof import('vue')['unref']>
readonly unrefElement: UnwrapRef<typeof import('@vueuse/core')['unrefElement']>
readonly until: UnwrapRef<typeof import('@vueuse/core')['until']>
readonly useActiveElement: UnwrapRef<typeof import('@vueuse/core')['useActiveElement']>
readonly useArrayEvery: UnwrapRef<typeof import('@vueuse/core')['useArrayEvery']>
readonly useArrayFilter: UnwrapRef<typeof import('@vueuse/core')['useArrayFilter']>
readonly useArrayFind: UnwrapRef<typeof import('@vueuse/core')['useArrayFind']>
readonly useArrayFindIndex: UnwrapRef<typeof import('@vueuse/core')['useArrayFindIndex']>
readonly useArrayJoin: UnwrapRef<typeof import('@vueuse/core')['useArrayJoin']>
readonly useArrayMap: UnwrapRef<typeof import('@vueuse/core')['useArrayMap']>
readonly useArrayReduce: UnwrapRef<typeof import('@vueuse/core')['useArrayReduce']>
readonly useArraySome: UnwrapRef<typeof import('@vueuse/core')['useArraySome']>
readonly useAsyncQueue: UnwrapRef<typeof import('@vueuse/core')['useAsyncQueue']>
readonly useAsyncState: UnwrapRef<typeof import('@vueuse/core')['useAsyncState']>
readonly useAttrs: UnwrapRef<typeof import('vue')['useAttrs']>
readonly useBase64: UnwrapRef<typeof import('@vueuse/core')['useBase64']>
readonly useBattery: UnwrapRef<typeof import('@vueuse/core')['useBattery']>
readonly useBluetooth: UnwrapRef<typeof import('@vueuse/core')['useBluetooth']>
readonly useBreakpoints: UnwrapRef<typeof import('@vueuse/core')['useBreakpoints']>
readonly useBroadcastChannel: UnwrapRef<typeof import('@vueuse/core')['useBroadcastChannel']>
readonly useBrowserLocation: UnwrapRef<typeof import('@vueuse/core')['useBrowserLocation']>
readonly useCached: UnwrapRef<typeof import('@vueuse/core')['useCached']>
readonly useClipboard: UnwrapRef<typeof import('@vueuse/core')['useClipboard']>
readonly useColorMode: UnwrapRef<typeof import('@vueuse/core')['useColorMode']>
readonly useConfirmDialog: UnwrapRef<typeof import('@vueuse/core')['useConfirmDialog']>
readonly useCounter: UnwrapRef<typeof import('@vueuse/core')['useCounter']>
readonly useCssModule: UnwrapRef<typeof import('vue')['useCssModule']>
readonly useCssVar: UnwrapRef<typeof import('@vueuse/core')['useCssVar']>
readonly useCssVars: UnwrapRef<typeof import('vue')['useCssVars']>
readonly useCurrentElement: UnwrapRef<typeof import('@vueuse/core')['useCurrentElement']>
readonly useCycleList: UnwrapRef<typeof import('@vueuse/core')['useCycleList']>
readonly useDark: UnwrapRef<typeof import('@vueuse/core')['useDark']>
readonly useDateFormat: UnwrapRef<typeof import('@vueuse/core')['useDateFormat']>
readonly useDebounce: UnwrapRef<typeof import('@vueuse/core')['useDebounce']>
readonly useDebounceFn: UnwrapRef<typeof import('@vueuse/core')['useDebounceFn']>
readonly useDebouncedRefHistory: UnwrapRef<typeof import('@vueuse/core')['useDebouncedRefHistory']>
readonly useDeviceMotion: UnwrapRef<typeof import('@vueuse/core')['useDeviceMotion']>
readonly useDeviceOrientation: UnwrapRef<typeof import('@vueuse/core')['useDeviceOrientation']>
readonly useDevicePixelRatio: UnwrapRef<typeof import('@vueuse/core')['useDevicePixelRatio']>
readonly useDevicesList: UnwrapRef<typeof import('@vueuse/core')['useDevicesList']>
readonly useDisplayMedia: UnwrapRef<typeof import('@vueuse/core')['useDisplayMedia']>
readonly useDocumentVisibility: UnwrapRef<typeof import('@vueuse/core')['useDocumentVisibility']>
readonly useDraggable: UnwrapRef<typeof import('@vueuse/core')['useDraggable']>
readonly useDropZone: UnwrapRef<typeof import('@vueuse/core')['useDropZone']>
readonly useElementBounding: UnwrapRef<typeof import('@vueuse/core')['useElementBounding']>
readonly useElementByPoint: UnwrapRef<typeof import('@vueuse/core')['useElementByPoint']>
readonly useElementHover: UnwrapRef<typeof import('@vueuse/core')['useElementHover']>
readonly useElementSize: UnwrapRef<typeof import('@vueuse/core')['useElementSize']>
readonly useElementVisibility: UnwrapRef<typeof import('@vueuse/core')['useElementVisibility']>
readonly useEventBus: UnwrapRef<typeof import('@vueuse/core')['useEventBus']>
readonly useEventListener: UnwrapRef<typeof import('@vueuse/core')['useEventListener']>
readonly useEventSource: UnwrapRef<typeof import('@vueuse/core')['useEventSource']>
readonly useEyeDropper: UnwrapRef<typeof import('@vueuse/core')['useEyeDropper']>
readonly useFavicon: UnwrapRef<typeof import('@vueuse/core')['useFavicon']>
readonly useFetch: UnwrapRef<typeof import('@vueuse/core')['useFetch']>
readonly useFileDialog: UnwrapRef<typeof import('@vueuse/core')['useFileDialog']>
readonly useFileSystemAccess: UnwrapRef<typeof import('@vueuse/core')['useFileSystemAccess']>
readonly useFocus: UnwrapRef<typeof import('@vueuse/core')['useFocus']>
readonly useFocusWithin: UnwrapRef<typeof import('@vueuse/core')['useFocusWithin']>
readonly useFps: UnwrapRef<typeof import('@vueuse/core')['useFps']>
readonly useFullscreen: UnwrapRef<typeof import('@vueuse/core')['useFullscreen']>
readonly useGamepad: UnwrapRef<typeof import('@vueuse/core')['useGamepad']>
readonly useGeolocation: UnwrapRef<typeof import('@vueuse/core')['useGeolocation']>
readonly useHead: UnwrapRef<typeof import('@vueuse/head')['useHead']>
readonly useI18n: UnwrapRef<typeof import('vue-i18n')['useI18n']>
readonly useIdle: UnwrapRef<typeof import('@vueuse/core')['useIdle']>
readonly useImage: UnwrapRef<typeof import('@vueuse/core')['useImage']>
readonly useInfiniteScroll: UnwrapRef<typeof import('@vueuse/core')['useInfiniteScroll']>
readonly useIntersectionObserver: UnwrapRef<typeof import('@vueuse/core')['useIntersectionObserver']>
readonly useInterval: UnwrapRef<typeof import('@vueuse/core')['useInterval']>
readonly useIntervalFn: UnwrapRef<typeof import('@vueuse/core')['useIntervalFn']>
readonly useKeyModifier: UnwrapRef<typeof import('@vueuse/core')['useKeyModifier']>
readonly useLastChanged: UnwrapRef<typeof import('@vueuse/core')['useLastChanged']>
readonly useLocalStorage: UnwrapRef<typeof import('@vueuse/core')['useLocalStorage']>
readonly useMagicKeys: UnwrapRef<typeof import('@vueuse/core')['useMagicKeys']>
readonly useManualRefHistory: UnwrapRef<typeof import('@vueuse/core')['useManualRefHistory']>
readonly useMediaControls: UnwrapRef<typeof import('@vueuse/core')['useMediaControls']>
readonly useMediaQuery: UnwrapRef<typeof import('@vueuse/core')['useMediaQuery']>
readonly useMemoize: UnwrapRef<typeof import('@vueuse/core')['useMemoize']>
readonly useMemory: UnwrapRef<typeof import('@vueuse/core')['useMemory']>
readonly useMounted: UnwrapRef<typeof import('@vueuse/core')['useMounted']>
readonly useMouse: UnwrapRef<typeof import('@vueuse/core')['useMouse']>
readonly useMouseInElement: UnwrapRef<typeof import('@vueuse/core')['useMouseInElement']>
readonly useMousePressed: UnwrapRef<typeof import('@vueuse/core')['useMousePressed']>
readonly useMutationObserver: UnwrapRef<typeof import('@vueuse/core')['useMutationObserver']>
readonly useNavigatorLanguage: UnwrapRef<typeof import('@vueuse/core')['useNavigatorLanguage']>
readonly useNetwork: UnwrapRef<typeof import('@vueuse/core')['useNetwork']>
readonly useNow: UnwrapRef<typeof import('@vueuse/core')['useNow']>
readonly useObjectUrl: UnwrapRef<typeof import('@vueuse/core')['useObjectUrl']>
readonly useOffsetPagination: UnwrapRef<typeof import('@vueuse/core')['useOffsetPagination']>
readonly useOnline: UnwrapRef<typeof import('@vueuse/core')['useOnline']>
readonly usePageLeave: UnwrapRef<typeof import('@vueuse/core')['usePageLeave']>
readonly useParallax: UnwrapRef<typeof import('@vueuse/core')['useParallax']>
readonly usePermission: UnwrapRef<typeof import('@vueuse/core')['usePermission']>
readonly usePointer: UnwrapRef<typeof import('@vueuse/core')['usePointer']>
readonly usePointerSwipe: UnwrapRef<typeof import('@vueuse/core')['usePointerSwipe']>
readonly usePreferredColorScheme: UnwrapRef<typeof import('@vueuse/core')['usePreferredColorScheme']>
readonly usePreferredDark: UnwrapRef<typeof import('@vueuse/core')['usePreferredDark']>
readonly usePreferredLanguages: UnwrapRef<typeof import('@vueuse/core')['usePreferredLanguages']>
readonly usePreferredReducedMotion: UnwrapRef<typeof import('@vueuse/core')['usePreferredReducedMotion']>
readonly useRafFn: UnwrapRef<typeof import('@vueuse/core')['useRafFn']>
readonly useRefHistory: UnwrapRef<typeof import('@vueuse/core')['useRefHistory']>
readonly useResizeObserver: UnwrapRef<typeof import('@vueuse/core')['useResizeObserver']>
readonly useRoute: UnwrapRef<typeof import('vue-router')['useRoute']>
readonly useRouter: UnwrapRef<typeof import('vue-router')['useRouter']>
readonly useScreenOrientation: UnwrapRef<typeof import('@vueuse/core')['useScreenOrientation']>
readonly useScreenSafeArea: UnwrapRef<typeof import('@vueuse/core')['useScreenSafeArea']>
readonly useScriptTag: UnwrapRef<typeof import('@vueuse/core')['useScriptTag']>
readonly useScroll: UnwrapRef<typeof import('@vueuse/core')['useScroll']>
readonly useScrollLock: UnwrapRef<typeof import('@vueuse/core')['useScrollLock']>
readonly useSessionStorage: UnwrapRef<typeof import('@vueuse/core')['useSessionStorage']>
readonly useShare: UnwrapRef<typeof import('@vueuse/core')['useShare']>
readonly useSlots: UnwrapRef<typeof import('vue')['useSlots']>
readonly useSpeechRecognition: UnwrapRef<typeof import('@vueuse/core')['useSpeechRecognition']>
readonly useSpeechSynthesis: UnwrapRef<typeof import('@vueuse/core')['useSpeechSynthesis']>
readonly useStepper: UnwrapRef<typeof import('@vueuse/core')['useStepper']>
readonly useStorage: UnwrapRef<typeof import('@vueuse/core')['useStorage']>
readonly useStorageAsync: UnwrapRef<typeof import('@vueuse/core')['useStorageAsync']>
readonly useStyleTag: UnwrapRef<typeof import('@vueuse/core')['useStyleTag']>
readonly useSupported: UnwrapRef<typeof import('@vueuse/core')['useSupported']>
readonly useSwipe: UnwrapRef<typeof import('@vueuse/core')['useSwipe']>
readonly useTemplateRefsList: UnwrapRef<typeof import('@vueuse/core')['useTemplateRefsList']>
readonly useTextDirection: UnwrapRef<typeof import('@vueuse/core')['useTextDirection']>
readonly useTextSelection: UnwrapRef<typeof import('@vueuse/core')['useTextSelection']>
readonly useTextareaAutosize: UnwrapRef<typeof import('@vueuse/core')['useTextareaAutosize']>
readonly useThrottle: UnwrapRef<typeof import('@vueuse/core')['useThrottle']>
readonly useThrottleFn: UnwrapRef<typeof import('@vueuse/core')['useThrottleFn']>
readonly useThrottledRefHistory: UnwrapRef<typeof import('@vueuse/core')['useThrottledRefHistory']>
readonly useTimeAgo: UnwrapRef<typeof import('@vueuse/core')['useTimeAgo']>
readonly useTimeout: UnwrapRef<typeof import('@vueuse/core')['useTimeout']>
readonly useTimeoutFn: UnwrapRef<typeof import('@vueuse/core')['useTimeoutFn']>
readonly useTimeoutPoll: UnwrapRef<typeof import('@vueuse/core')['useTimeoutPoll']>
readonly useTimestamp: UnwrapRef<typeof import('@vueuse/core')['useTimestamp']>
readonly useTitle: UnwrapRef<typeof import('@vueuse/core')['useTitle']>
readonly useToNumber: UnwrapRef<typeof import('@vueuse/core')['useToNumber']>
readonly useToString: UnwrapRef<typeof import('@vueuse/core')['useToString']>
readonly useToggle: UnwrapRef<typeof import('@vueuse/core')['useToggle']>
readonly useTransition: UnwrapRef<typeof import('@vueuse/core')['useTransition']>
readonly useUrlSearchParams: UnwrapRef<typeof import('@vueuse/core')['useUrlSearchParams']>
readonly useUserMedia: UnwrapRef<typeof import('@vueuse/core')['useUserMedia']>
readonly useUserStore: UnwrapRef<typeof import('./store/user')['useUserStore']>
readonly useVModel: UnwrapRef<typeof import('@vueuse/core')['useVModel']>
readonly useVModels: UnwrapRef<typeof import('@vueuse/core')['useVModels']>
readonly useVibrate: UnwrapRef<typeof import('@vueuse/core')['useVibrate']>
readonly useVirtualList: UnwrapRef<typeof import('@vueuse/core')['useVirtualList']>
readonly useWakeLock: UnwrapRef<typeof import('@vueuse/core')['useWakeLock']>
readonly useWebNotification: UnwrapRef<typeof import('@vueuse/core')['useWebNotification']>
readonly useWebSocket: UnwrapRef<typeof import('@vueuse/core')['useWebSocket']>
readonly useWebWorker: UnwrapRef<typeof import('@vueuse/core')['useWebWorker']>
readonly useWebWorkerFn: UnwrapRef<typeof import('@vueuse/core')['useWebWorkerFn']>
readonly useWindowFocus: UnwrapRef<typeof import('@vueuse/core')['useWindowFocus']>
readonly useWindowScroll: UnwrapRef<typeof import('@vueuse/core')['useWindowScroll']>
readonly useWindowSize: UnwrapRef<typeof import('@vueuse/core')['useWindowSize']>
readonly watch: UnwrapRef<typeof import('vue')['watch']>
readonly watchArray: UnwrapRef<typeof import('@vueuse/core')['watchArray']>
readonly watchAtMost: UnwrapRef<typeof import('@vueuse/core')['watchAtMost']>
readonly watchDebounced: UnwrapRef<typeof import('@vueuse/core')['watchDebounced']>
readonly watchEffect: UnwrapRef<typeof import('vue')['watchEffect']>
readonly watchIgnorable: UnwrapRef<typeof import('@vueuse/core')['watchIgnorable']>
readonly watchOnce: UnwrapRef<typeof import('@vueuse/core')['watchOnce']>
readonly watchPausable: UnwrapRef<typeof import('@vueuse/core')['watchPausable']>
readonly watchPostEffect: UnwrapRef<typeof import('vue')['watchPostEffect']>
readonly watchSyncEffect: UnwrapRef<typeof import('vue')['watchSyncEffect']>
readonly watchThrottled: UnwrapRef<typeof import('@vueuse/core')['watchThrottled']>
readonly watchTriggerable: UnwrapRef<typeof import('@vueuse/core')['watchTriggerable']>
readonly watchWithFilter: UnwrapRef<typeof import('@vueuse/core')['watchWithFilter']>
readonly whenever: UnwrapRef<typeof import('@vueuse/core')['whenever']>
}
}

16
fixtures/vitesse/src/components.d.ts vendored Normal file
View File

@ -0,0 +1,16 @@
// generated by unplugin-vue-components
// We suggest you to commit this file into source control
// Read more: https://github.com/vuejs/core/pull/3399
import '@vue/runtime-core'
export {}
declare module '@vue/runtime-core' {
export interface GlobalComponents {
Counter: typeof import('./components/Counter.vue')['default']
Footer: typeof import('./components/Footer.vue')['default']
README: typeof import('./components/README.md')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
}
}

View File

@ -0,0 +1,19 @@
<script setup lang="ts">
const props = defineProps<{
initial: number
}>()
const { count, inc, dec } = useCounter(props.initial)
</script>
<template>
<div>
{{ count }}
<button class="inc" @click="inc()">
+
</button>
<button class="dec" @click="dec()">
-
</button>
</div>
</template>

View File

@ -0,0 +1,33 @@
<script setup lang="ts">
const { t, availableLocales, locale } = useI18n()
function toggleLocales() {
// change to some real logic
const locales = availableLocales
locale.value = locales[(locales.indexOf(locale.value) + 1) % locales.length]
}
</script>
<template>
<nav text-xl mt-6>
<RouterLink class="icon-btn mx-2" to="/" :title="t('button.home')">
<div i-carbon-campsite />
</RouterLink>
<button class="icon-btn mx-2 !outline-none" :title="t('button.toggle_dark')" @click="toggleDark()">
<div i="carbon-sun dark:carbon-moon" />
</button>
<a class="icon-btn mx-2" :title="t('button.toggle_langs')" @click="toggleLocales()">
<div i-carbon-language />
</a>
<RouterLink class="icon-btn mx-2" to="/about" :title="t('button.about')">
<div i-carbon-dicom-overlay />
</RouterLink>
<a class="icon-btn mx-2" rel="noreferrer" href="https://github.com/antfu/vitesse" target="_blank" title="GitHub">
<div i-carbon-logo-github />
</a>
</nav>
</template>

View File

@ -0,0 +1,10 @@
## Components
Components in this dir will be auto-registered and on-demand, powered by [`unplugin-vue-components`](https://github.com/antfu/unplugin-vue-components).
### Icons
You can use icons from almost any icon sets by the power of [Iconify](https://iconify.design/).
It will only bundle the icons you use. Check out [`unplugin-icons`](https://github.com/antfu/unplugin-icons) for more details.

View File

@ -0,0 +1,4 @@
// these APIs are auto-imported from @vueuse/core
export const isDark = useDark()
export const toggleDark = useToggle(isDark)
export const preferredDark = usePreferredDark()

View File

@ -0,0 +1,18 @@
<script setup lang="ts">
const router = useRouter()
const { t } = useI18n()
</script>
<template>
<main p="x4 y10" text="center teal-700 dark:gray-200">
<div text-4xl>
<div i-carbon-warning inline-block />
</div>
<RouterView />
<div>
<button btn text-sm m="3 t8" @click="router.back()">
{{ t('button.back') }}
</button>
</div>
</main>
</template>

View File

@ -0,0 +1,14 @@
## Layouts
Vue components in this dir are used as layouts.
By default, `default.vue` will be used unless an alternative is specified in the route meta.
With [`vite-plugin-pages`](https://github.com/hannoeru/vite-plugin-pages) and [`vite-plugin-vue-layouts`](https://github.com/JohnCampionJr/vite-plugin-vue-layouts), you can specify the layout in the page's SFCs like this:
```html
<route lang="yaml">
meta:
layout: home
</route>
```

View File

@ -0,0 +1,9 @@
<template>
<main class="px-4 py-10 text-center text-gray-700 dark:text-gray-200">
<RouterView />
<Footer />
<div class="mt-5 mx-auto text-center opacity-75 dark:opacity-50 text-sm">
[Default Layout]
</div>
</main>
</template>

View File

@ -0,0 +1,9 @@
<template>
<main class="px-4 py-10 text-center text-gray-700 dark:text-gray-200">
<RouterView />
<Footer />
<div class="mt-5 mx-auto text-center opacity-75 dark:opacity-50 text-sm">
[Home Layout]
</div>
</main>
</template>

View File

@ -0,0 +1,22 @@
import { ViteSSG } from 'vite-ssg'
import { setupLayouts } from 'virtual:generated-layouts'
import App from './App.vue'
import type { UserModule } from './types'
import generatedRoutes from '~pages'
import '@unocss/reset/tailwind.css'
import './styles/main.css'
import 'uno.css'
const routes = setupLayouts(generatedRoutes)
// https://github.com/antfu/vite-ssg
export const createApp = ViteSSG(
App,
{ routes, base: import.meta.env.BASE_URL },
(ctx) => {
// install all modules under `modules/`
Object.values(import.meta.glob<{ install: UserModule }>('./modules/*.ts', { eager: true }))
.forEach(i => i.install?.(ctx))
},
)

View File

@ -0,0 +1,11 @@
## Modules
A custom user module system. Place a `.ts` file with the following template, it will be installed automatically.
```ts
import { type UserModule } from '~/types'
export const install: UserModule = ({ app, router, isClient }) => {
// do something
}
```

View File

@ -0,0 +1,25 @@
import { createI18n } from 'vue-i18n'
import { type UserModule } from '~/types'
// Import i18n resources
// https://vitejs.dev/guide/features.html#glob-import
//
// Don't need this? Try vitesse-lite: https://github.com/antfu/vitesse-lite
const messages = Object.fromEntries(
Object.entries(
import.meta.glob<{ default: any }>('../../locales/*.y(a)?ml', { eager: true }))
.map(([key, value]) => {
const yaml = key.endsWith('.yaml')
return [key.slice(14, yaml ? -5 : -4), value.default]
}),
)
export const install: UserModule = ({ app }) => {
const i18n = createI18n({
legacy: false,
locale: 'en',
messages,
})
app.use(i18n)
}

View File

@ -0,0 +1,14 @@
import NProgress from 'nprogress'
import { type UserModule } from '~/types'
export const install: UserModule = ({ isClient, router }) => {
if (isClient) {
router.beforeEach((to, from) => {
if (to.path !== from.path)
NProgress.start()
})
router.afterEach(() => {
NProgress.done()
})
}
}

View File

@ -0,0 +1,17 @@
import { createPinia } from 'pinia'
import { type UserModule } from '~/types'
// Setup Pinia
// https://pinia.vuejs.org/
export const install: UserModule = ({ isClient, initialState, app }) => {
const pinia = createPinia()
app.use(pinia)
// Refer to
// https://github.com/antfu/vite-ssg/blob/main/README.md#state-serialization
// for other serialization strategies.
if (isClient)
pinia.state.value = (initialState.pinia) || {}
else
initialState.pinia = pinia.state.value
}

View File

@ -0,0 +1,12 @@
import { type UserModule } from '~/types'
// https://github.com/antfu/vite-plugin-pwa#automatic-reload-when-new-content-available
export const install: UserModule = ({ isClient, router }) => {
if (!isClient)
return
router.isReady().then(async () => {
const { registerSW } = await import('virtual:pwa-register')
registerSW({ immediate: true })
})
}

View File

@ -0,0 +1,20 @@
## File-based Routing
Routes will be auto-generated for Vue files in this dir with the same file structure.
Check out [`vite-plugin-pages`](https://github.com/hannoeru/vite-plugin-pages) for more details.
### Path Aliasing
`~/` is aliased to `./src/` folder.
For example, instead of having
```ts
import { isDark } from '../../../../composables'
```
now, you can use
```ts
import { isDark } from '~/composables'
```

View File

@ -0,0 +1,14 @@
<script setup lang="ts">
const { t } = useI18n()
</script>
<template>
<div>
{{ t('not-found') }}
</div>
</template>
<route lang="yaml">
meta:
layout: 404
</route>

View File

@ -0,0 +1,21 @@
---
title: About
---
<div class="text-center">
<!-- You can use Vue components inside markdown -->
<div i-carbon-dicom-overlay class="text-4xl -mb-6 m-auto" />
<h3>About</h3>
</div>
[Vitesse](https://github.com/antfu/vitesse) is an opinionated [Vite](https://github.com/vitejs/vite) starter template made by [@antfu](https://github.com/antfu) for mocking apps swiftly. With **file-based routing**, **components auto importing**, **markdown support**, I18n, PWA and uses **UnoCSS** for styling and icons.
```js
// syntax highlighting example
function vitesse() {
const foo = 'bar'
console.log(foo)
}
```
Check out the [GitHub repo](https://github.com/antfu/vitesse) for more details.

View File

@ -0,0 +1,47 @@
<script setup lang="ts">
const props = defineProps<{ name: string }>()
const router = useRouter()
const user = useUserStore()
const { t } = useI18n()
watchEffect(() => {
user.setNewName(props.name)
})
</script>
<template>
<div>
<div text-4xl>
<div i-carbon-pedestrian inline-block />
</div>
<p>
{{ t('intro.hi', { name: props.name }) }}
</p>
<p text-sm opacity-75>
<em>{{ t('intro.dynamic-route') }}</em>
</p>
<template v-if="user.otherNames.length">
<p text-sm mt-4>
<span opacity-75>{{ t('intro.aka') }}:</span>
<ul>
<li v-for="otherName in user.otherNames" :key="otherName">
<router-link :to="`/hi/${otherName}`" replace>
{{ otherName }}
</router-link>
</li>
</ul>
</p>
</template>
<div>
<button
btn m="3 t6" text-sm
@click="router.back()"
>
{{ t('button.back') }}
</button>
</div>
</div>
</template>

View File

@ -0,0 +1,62 @@
<script setup lang="ts">
const user = useUserStore()
const name = $ref(user.savedName)
const router = useRouter()
function go() {
if (name)
router.push(`/hi/${encodeURIComponent(name)}`)
}
const { t } = useI18n()
</script>
<template>
<div>
<div text-4xl>
<div i-carbon-campsite inline-block />
</div>
<p>
<a rel="noreferrer" href="https://github.com/antfu/vitesse" target="_blank">
Vitesse
</a>
</p>
<p>
<em text-sm opacity-75>{{ t('intro.desc') }}</em>
</p>
<div py-4 />
<input
id="input"
v-model="name"
:placeholder="t('intro.whats-your-name')"
:aria-label="t('intro.whats-your-name')"
type="text"
autocomplete="false"
p="x4 y2"
w="250px"
text="center"
bg="transparent"
border="~ rounded gray-200 dark:gray-700"
outline="none active:none"
@keydown.enter="go"
>
<label class="hidden" for="input">{{ t('intro.whats-your-name') }}</label>
<div>
<button
btn m-3 text-sm
:disabled="!name"
@click="go"
>
{{ t('button.go') }}
</button>
</div>
</div>
</template>
<route lang="yaml">
meta:
layout: home
</route>

16
fixtures/vitesse/src/shims.d.ts vendored Normal file
View File

@ -0,0 +1,16 @@
declare interface Window {
// extend the window
}
// with vite-plugin-vue-markdown, markdown files can be treated as Vue components
declare module '*.md' {
import { type DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}
declare module '*.vue' {
import { type DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}

View File

@ -0,0 +1,34 @@
import { acceptHMRUpdate, defineStore } from 'pinia'
export const useUserStore = defineStore('user', () => {
/**
* Current name of the user.
*/
const savedName = ref('')
const previousNames = ref(new Set<string>())
const usedNames = computed(() => Array.from(previousNames.value))
const otherNames = computed(() => usedNames.value.filter(name => name !== savedName.value))
/**
* Changes the current name of the user and saves the one that was used
* before.
*
* @param name - new name to set
*/
function setNewName(name: string) {
if (savedName.value)
previousNames.value.add(savedName.value)
savedName.value = name
}
return {
setNewName,
otherNames,
savedName,
}
})
if (import.meta.hot)
import.meta.hot.accept(acceptHMRUpdate(useUserStore, import.meta.hot))

View File

@ -0,0 +1,29 @@
@import './markdown.css';
html,
body,
#app {
height: 100%;
margin: 0;
padding: 0;
}
html.dark {
background: #121212;
color-scheme: dark;
}
#nprogress {
pointer-events: none;
}
#nprogress .bar {
background: rgb(13,148,136);
opacity: 0.75;
position: fixed;
z-index: 1031;
top: 0;
left: 0;
width: 100%;
height: 2px;
}

View File

@ -0,0 +1,28 @@
.prose pre:not(.shiki) {
padding: 0;
}
.prose .shiki {
font-family: 'DM Mono', monospace;
font-size: 1.2em;
line-height: 1.4;
}
.prose img {
width: 100%;
}
.shiki-light {
background: #f8f8f8 !important;
}
.shiki-dark {
background: #0e0e0e !important;
}
html.dark .shiki-light {
display: none;
}
html:not(.dark) .shiki-dark {
display: none;
}

View File

@ -0,0 +1,3 @@
import { type ViteSSGContext } from 'vite-ssg'
export type UserModule = (ctx: ViteSSGContext) => void

View File

@ -0,0 +1,3 @@
// Vitest Snapshot v1
exports[`Counter.vue > should render 1`] = `"<div>10 <button class=\\"inc\\"> + </button><button class=\\"dec\\"> - </button></div>"`;

View File

@ -0,0 +1,7 @@
import { describe, expect, it } from 'vitest'
describe('tests', () => {
it('should works', () => {
expect(1 + 1).toEqual(2)
})
})

View File

@ -0,0 +1,28 @@
import { mount } from '@vue/test-utils'
import { describe, expect, it } from 'vitest'
import Counter from '../src/components/Counter.vue'
describe('Counter.vue', () => {
it('should render', () => {
const wrapper = mount(Counter, { props: { initial: 10 } })
expect(wrapper.text()).toContain('10')
expect(wrapper.html()).toMatchSnapshot()
})
it('should be interactive', async () => {
const wrapper = mount(Counter, { props: { initial: 0 } })
expect(wrapper.text()).toContain('0')
expect(wrapper.find('.inc').exists()).toBe(true)
expect(wrapper.find('.dec').exists()).toBe(true)
await wrapper.get('.inc').trigger('click')
expect(wrapper.text()).toContain('1')
await wrapper.get('.dec').trigger('click')
expect(wrapper.text()).toContain('0')
})
})

View File

@ -0,0 +1,38 @@
import {
defineConfig,
presetAttributify,
presetIcons,
presetTypography,
presetUno,
presetWebFonts,
transformerDirectives,
transformerVariantGroup,
} from 'unocss'
export default defineConfig({
shortcuts: [
['btn', 'px-4 py-1 rounded inline-block bg-teal-700 text-white cursor-pointer hover:bg-teal-800 disabled:cursor-default disabled:bg-gray-600 disabled:opacity-50'],
['icon-btn', 'inline-block cursor-pointer select-none opacity-75 transition duration-200 ease-in-out hover:opacity-100 hover:text-teal-600'],
],
presets: [
presetUno(),
presetAttributify(),
presetIcons({
scale: 1.2,
warn: true,
}),
presetTypography(),
presetWebFonts({
fonts: {
sans: 'DM Sans',
serif: 'DM Serif Display',
mono: 'DM Mono',
},
}),
],
transformers: [
transformerDirectives(),
transformerVariantGroup(),
],
safelist: 'prose prose-sm m-auto text-left'.split(' '),
})

View File

@ -0,0 +1,153 @@
import path from 'node:path'
import { defineConfig } from 'vite'
import Vue from '@vitejs/plugin-vue'
import Pages from 'vite-plugin-pages'
import generateSitemap from 'vite-ssg-sitemap'
import Layouts from 'vite-plugin-vue-layouts'
import Components from 'unplugin-vue-components/vite'
import AutoImport from 'unplugin-auto-import/vite'
import Markdown from 'vite-plugin-vue-markdown'
import { VitePWA } from 'vite-plugin-pwa'
import VueI18n from '@intlify/vite-plugin-vue-i18n'
import Inspect from 'vite-plugin-inspect'
import LinkAttributes from 'markdown-it-link-attributes'
import Unocss from 'unocss/vite'
import Shiki from 'markdown-it-shiki'
export default defineConfig({
resolve: {
alias: {
'~/': `${path.resolve(__dirname, 'src')}/`,
},
},
plugins: [
Vue({
include: [/\.vue$/, /\.md$/],
reactivityTransform: true,
}),
// https://github.com/hannoeru/vite-plugin-pages
Pages({
extensions: ['vue', 'md'],
}),
// https://github.com/JohnCampionJr/vite-plugin-vue-layouts
Layouts(),
// https://github.com/antfu/unplugin-auto-import
AutoImport({
imports: [
'vue',
'vue-router',
'vue-i18n',
'vue/macros',
'@vueuse/head',
'@vueuse/core',
],
dts: 'src/auto-imports.d.ts',
dirs: [
'src/composables',
'src/store',
],
vueTemplate: true,
}),
// https://github.com/antfu/unplugin-vue-components
Components({
// allow auto load markdown components under `./src/components/`
extensions: ['vue', 'md'],
// allow auto import and register components used in markdown
include: [/\.vue$/, /\.vue\?vue/, /\.md$/],
dts: 'src/components.d.ts',
}),
// https://github.com/antfu/unocss
// see unocss.config.ts for config
Unocss(),
// https://github.com/antfu/vite-plugin-vue-markdown
// Don't need this? Try vitesse-lite: https://github.com/antfu/vitesse-lite
Markdown({
wrapperClasses: 'prose prose-sm m-auto text-left',
headEnabled: true,
markdownItSetup(md) {
// https://prismjs.com/
md.use(Shiki, {
theme: {
light: 'vitesse-light',
dark: 'vitesse-dark',
},
})
md.use(LinkAttributes, {
matcher: (link: string) => /^https?:\/\//.test(link),
attrs: {
target: '_blank',
rel: 'noopener',
},
})
},
}),
// https://github.com/antfu/vite-plugin-pwa
VitePWA({
registerType: 'autoUpdate',
includeAssets: ['favicon.svg', 'safari-pinned-tab.svg'],
manifest: {
name: 'Vitesse',
short_name: 'Vitesse',
theme_color: '#ffffff',
icons: [
{
src: '/pwa-192x192.png',
sizes: '192x192',
type: 'image/png',
},
{
src: '/pwa-512x512.png',
sizes: '512x512',
type: 'image/png',
},
{
src: '/pwa-512x512.png',
sizes: '512x512',
type: 'image/png',
purpose: 'any maskable',
},
],
},
}),
// https://github.com/intlify/bundle-tools/tree/main/packages/vite-plugin-vue-i18n
VueI18n({
runtimeOnly: true,
compositionOnly: true,
include: [path.resolve(__dirname, 'locales/**')],
}),
// https://github.com/antfu/vite-plugin-inspect
// Visit http://localhost:3333/__inspect/ to see the inspector
Inspect(),
],
// https://github.com/vitest-dev/vitest
test: {
include: ['test/**/*.test.ts'],
environment: 'jsdom',
deps: {
inline: ['@vue', '@vueuse', 'vue-demi'],
},
},
// https://github.com/antfu/vite-ssg
ssgOptions: {
script: 'async',
formatting: 'minify',
onFinished() { generateSitemap() },
},
ssr: {
// TODO: workaround until they support native ESM
noExternal: ['workbox-window', /vue-i18n/],
},
})

View File

@ -1,6 +0,0 @@
{
"packages": [
"packages/*"
],
"version": "0.1.4"
}

View File

@ -1,13 +1,23 @@
{
"name": "@antfu/eslint-config",
"version": "0.1.0",
"name": "@taoyaal/eslint-config-monorepo",
"version": "0.40.11",
"private": true,
"packageManager": "pnpm@8.6.12",
"author": "Anthony Fu <anthonyfu117@hotmail.com> (https://github.com/antfu/)",
"license": "MIT",
"scripts": {
"postinstall": "lerna bootstrap",
"release": "lerna publish --conventional-commits"
"lint": "pnpm -r run stub && eslint .",
"test": "pnpm -r run test",
"build": "pnpm -r run build",
"prepare": "pnpm -r run stub",
"release": "bumpp -r && pnpm -r publish"
},
"devDependencies": {
"lerna": "^3.14.1"
"@antfu/eslint-config": "workspace:*",
"bumpp": "^9.1.1",
"eslint": "^8.46.0",
"eslint-plugin-antfu": "link:./packages/eslint-plugin-antfu",
"rimraf": "^5.0.1",
"typescript": "^5.1.6"
}
}

View File

@ -1,142 +0,0 @@
module.exports = {
env: {
es6: true,
browser: true,
node: true,
},
plugins: [
'@typescript-eslint',
],
parser: '@typescript-eslint/parser',
extends: [
'standard',
'plugin:import/errors',
'plugin:import/warnings',
'plugin:@typescript-eslint/recommended',
],
plugins: [
'unicorn',
],
settings: {
'import/resolver': {
node: { extensions: ['.js', '.mjs'] }
}
},
rules: {
// import
'import/order': 'error',
'import/first': 'error',
'import/no-mutable-exports': 'error',
'import/no-unresolved': 'off',
// Common
'semi': [2, 'never'],
'curly': [2, 'multi-or-nest', 'consistent'],
'quotes': ['error', 'single'],
'no-unused-vars': 'warn',
'no-param-reassign': 'off',
'array-bracket-spacing': ['error', 'never'],
'brace-style': ['error', 'stroustrup', { 'allowSingleLine': true }],
'block-spacing': ['error', 'always'],
'camelcase': 'off',
'comma-spacing': ['error', { before: false, after: true }],
'comma-style': ['error', 'last'],
'comma-dangle': ['error', 'always-multiline'],
'no-constant-condition': 'warn',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-cond-assign': ['error', 'always'],
'func-call-spacing': ['off', 'never'],
'key-spacing': ['error', { beforeColon: false, afterColon: true }],
'indent': ['error', 2, { SwitchCase: 1, VariableDeclarator: 1, outerIIFEBody: 1 }],
'no-restricted-syntax': [
'error',
'DebuggerStatement',
'ForInStatement',
'LabeledStatement',
'WithStatement',
],
'no-spaced-func': 'error',
'object-curly-spacing': ['error', 'always'],
'no-return-await': 'off',
'prefer-const': ['error', {
'destructuring': 'any',
'ignoreReadBeforeAssign': false
}],
// es6
'no-var': 'error',
'prefer-const': ['error', {
destructuring: 'any',
ignoreReadBeforeAssign: true,
}],
'prefer-arrow-callback': ['error', {
allowNamedFunctions: false,
allowUnboundThis: true,
}],
'object-shorthand': ['error', 'always', {
ignoreConstructors: false,
avoidQuotes: true,
}],
'prefer-rest-params': 'error',
'prefer-spread': 'error',
'prefer-template': 'error',
'template-curly-spacing': 'error',
'arrow-parens': ['error', 'as-needed', { requireForBlockBody: true }],
'generator-star-spacing': 'off',
// best-practice
'array-callback-return': 'error',
'block-scoped-var': 'error',
'consistent-return': 'off',
'complexity': ['off', 11],
'eqeqeq': ['error', 'allow-null'],
'no-alert': 'warn',
'no-case-declarations': 'error',
'no-multi-spaces': 'error',
'no-multi-str': 'error',
'no-with': 'error',
'no-void': 'error',
'no-useless-escape': 'error',
'vars-on-top': 'error',
'require-await': 'off',
'no-return-assign': 'off',
'operator-linebreak': [2, 'before'],
// TS
'@typescript-eslint/no-unused-vars': [2, { args: 'none' }],
'@typescript-eslint/indent': ['error', 2],
'@typescript-eslint/member-delimiter-style': ['error', { multiline: { delimiter: 'none' } }],
'@typescript-eslint/type-annotation-spacing': ['error', {}],
'@typescript-eslint/camelcase': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-member-accessibility': 'off',
'@typescript-eslint/no-explicit-any': 'off',
// unicorns
// Pass error message when throwing errors
'unicorn/error-message': 'error',
// Uppercase regex escapes
'unicorn/escape-case': 'error',
// Array.isArray instead of instanceof
'unicorn/no-array-instanceof': 'error',
// Prevent deprecated `new Buffer()`
'unicorn/no-new-buffer': 'error',
// Keep regex literals safe!
'unicorn/no-unsafe-regex': 'off',
// Lowercase number formatting for octal, hex, binary (0x12 instead of 0X12)
'unicorn/number-literal-case': 'error',
// ** instead of Math.pow()
'unicorn/prefer-exponentiation-operator': 'error',
// includes over indexOf when checking for existence
'unicorn/prefer-includes': 'error',
// String methods startsWith/endsWith instead of more complicated stuff
'unicorn/prefer-starts-ends-with': 'error',
// textContent instead of innerText
'unicorn/prefer-text-content': 'error',
// Enforce throwing type error when throwing error while checking typeof
'unicorn/prefer-type-error': 'error',
// Use new when throwing error
'unicorn/throw-new-error': 'error',
}
}

View File

@ -1,32 +0,0 @@
{
"name": "@antfu/eslint-config",
"version": "0.1.4",
"description": "",
"main": "index.js",
"keywords": [],
"author": "Anthony Fu <anthonyfu117@hotmail.com> (https://github.com/antfu/)",
"license": "MIT",
"scripts": {
"lint": "eslint . --config=index.js"
},
"files": [
"index.js"
],
"peerDependencies": {
"eslint": ">=5.16.0"
},
"dependencies": {
"@typescript-eslint/eslint-plugin": "1.11.0",
"@typescript-eslint/parser": "^1.10.2",
"eslint-config-standard": "^12.0.0",
"eslint-plugin-import": "^2.18.0",
"eslint-plugin-node": "^9.1.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.0",
"eslint-plugin-unicorn": "^9.1.1"
},
"devDependencies": {
"eslint": "^6.0.1",
"standard-version": "^6.0.1"
}
}

View File

@ -0,0 +1,378 @@
module.exports = {
env: {
es6: true,
browser: true,
node: true,
},
reportUnusedDisableDirectives: true,
extends: [
'./standard',
'plugin:import/recommended',
'plugin:eslint-comments/recommended',
'plugin:jsonc/recommended-with-jsonc',
'plugin:yml/standard',
],
ignorePatterns: [
'*.min.*',
'*.d.ts',
'CHANGELOG.md',
'dist',
'LICENSE*',
'output',
'out',
'coverage',
'public',
'temp',
'package-lock.json',
'pnpm-lock.yaml',
'yarn.lock',
'__snapshots__',
// ignore for in lint-staged
'*.css',
'*.png',
'*.ico',
'*.toml',
'*.patch',
'*.txt',
'*.crt',
'*.key',
'Dockerfile',
// force include
'!.github',
'!.vitepress',
'!.vscode',
// force exclude
'**/.vitepress/cache',
],
plugins: [
'html',
'unicorn',
'antfu',
'no-only-tests',
'unused-imports',
],
settings: {
'import/resolver': {
node: { extensions: ['.js', '.mjs'] },
},
},
overrides: [
{
files: ['*.json', '*.json5', '*.jsonc'],
parser: 'jsonc-eslint-parser',
rules: {
'jsonc/array-bracket-spacing': ['error', 'never'],
'jsonc/comma-dangle': ['error', 'never'],
'jsonc/comma-style': ['error', 'last'],
'jsonc/indent': ['error', 2],
'jsonc/key-spacing': ['error', { beforeColon: false, afterColon: true }],
'jsonc/no-octal-escape': 'error',
'jsonc/object-curly-newline': ['error', { multiline: true, consistent: true }],
'jsonc/object-curly-spacing': ['error', 'always'],
'jsonc/object-property-newline': ['error', { allowMultiplePropertiesPerLine: true }],
},
},
{
files: ['*.yaml', '*.yml'],
parser: 'yaml-eslint-parser',
rules: {
'spaced-comment': 'off',
},
},
{
files: ['package.json'],
parser: 'jsonc-eslint-parser',
rules: {
'jsonc/sort-keys': [
'error',
{
pathPattern: '^$',
order: [
'publisher',
'name',
'displayName',
'type',
'version',
'private',
'packageManager',
'description',
'author',
'license',
'funding',
'homepage',
'repository',
'bugs',
'keywords',
'categories',
'sideEffects',
'exports',
'main',
'module',
'unpkg',
'jsdelivr',
'types',
'typesVersions',
'bin',
'icon',
'files',
'engines',
'activationEvents',
'contributes',
'scripts',
'peerDependencies',
'peerDependenciesMeta',
'dependencies',
'optionalDependencies',
'devDependencies',
'pnpm',
'overrides',
'resolutions',
'husky',
'simple-git-hooks',
'lint-staged',
'eslintConfig',
],
},
{
pathPattern: '^(?:dev|peer|optional|bundled)?[Dd]ependencies$',
order: { type: 'asc' },
},
{
pathPattern: '^exports.*$',
order: [
'types',
'import',
'require',
'default',
],
},
],
},
},
{
files: ['*.d.ts'],
rules: {
'import/no-duplicates': 'off',
},
},
{
files: ['*.js', '*.cjs', '*.jsx'],
rules: {
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-require-imports': 'off',
},
},
{
files: ['*.ts', '*.tsx', '*.mts', '*.cts'],
rules: {
'no-void': ['error', { allowAsStatement: true }],
},
},
{
files: ['scripts/**/*.*', 'cli.*'],
rules: {
'no-console': 'off',
},
},
{
files: ['*.test.ts', '*.test.js', '*.spec.ts', '*.spec.js'],
rules: {
'no-unused-expressions': 'off',
'no-only-tests/no-only-tests': 'error',
},
},
],
rules: {
// import
'import/order': 'error',
'import/first': 'error',
'import/no-mutable-exports': 'error',
'import/no-unresolved': 'off',
'import/no-absolute-path': 'off',
'import/newline-after-import': ['error', { count: 1, considerComments: true }],
'import/no-self-import': 'error',
// Common
'semi': ['error', 'never'],
'curly': ['error', 'multi-or-nest', 'consistent'],
'quotes': ['error', 'single'],
'quote-props': ['error', 'consistent-as-needed'],
'unused-imports/no-unused-imports': 'error',
'unused-imports/no-unused-vars': [
'warn',
{ vars: 'all', varsIgnorePattern: '^_', args: 'after-used', argsIgnorePattern: '^_' },
],
'no-param-reassign': 'off',
'array-bracket-spacing': ['error', 'never'],
'brace-style': ['error', 'stroustrup', { allowSingleLine: true }],
'block-spacing': ['error', 'always'],
'camelcase': 'off',
'comma-spacing': ['error', { before: false, after: true }],
'comma-style': ['error', 'last'],
'comma-dangle': ['error', 'always-multiline'],
'no-constant-condition': 'warn',
'no-debugger': 'error',
'no-console': ['error', { allow: ['warn', 'error'] }],
'no-cond-assign': ['error', 'always'],
'func-call-spacing': 'off',
'key-spacing': ['error', { beforeColon: false, afterColon: true }],
'indent': ['error', 2, { SwitchCase: 1, VariableDeclarator: 1, outerIIFEBody: 1 }],
'no-restricted-syntax': [
'error',
'DebuggerStatement',
'LabeledStatement',
'WithStatement',
],
'object-curly-spacing': ['error', 'always'],
'no-return-await': 'off',
'space-before-function-paren': [
'error',
{
anonymous: 'always',
named: 'never',
asyncArrow: 'always',
},
],
'no-restricted-globals': [
'error',
{ name: 'global', message: 'Use `globalThis` instead.' },
{ name: 'self', message: 'Use `globalThis` instead.' },
],
'no-restricted-properties': [
'error',
{ property: '__proto__', message: 'Use `Object.getPrototypeOf` or `Object.setPrototypeOf` instead.' },
{ property: '__defineGetter__', message: 'Use `Object.defineProperty` instead.' },
{ property: '__defineSetter__', message: 'Use `Object.defineProperty` instead.' },
{ property: '__lookupGetter__', message: 'Use `Object.getOwnPropertyDescriptor` instead.' },
{ property: '__lookupSetter__', message: 'Use `Object.getOwnPropertyDescriptor` instead.' },
],
// es6
'no-var': 'error',
'prefer-const': [
'error',
{
destructuring: 'all',
ignoreReadBeforeAssign: true,
},
],
'prefer-arrow-callback': [
'error',
{
allowNamedFunctions: false,
allowUnboundThis: true,
},
],
'object-shorthand': [
'error',
'always',
{
ignoreConstructors: false,
avoidQuotes: true,
},
],
'prefer-exponentiation-operator': 'error',
'prefer-rest-params': 'error',
'prefer-spread': 'error',
'prefer-template': 'error',
'template-curly-spacing': 'error',
'arrow-parens': ['error', 'as-needed', { requireForBlockBody: true }],
'generator-star-spacing': 'off',
'spaced-comment': ['error', 'always', {
line: {
markers: ['/'],
exceptions: ['/', '#'],
},
block: {
markers: ['!'],
exceptions: ['*'],
balanced: true,
},
}],
// best-practice
'array-callback-return': 'error',
'block-scoped-var': 'error',
'consistent-return': 'off',
'complexity': 'off',
'eqeqeq': ['error', 'smart'],
'no-alert': 'warn',
'no-case-declarations': 'error',
'no-multi-spaces': 'error',
'no-multi-str': 'error',
'no-with': 'error',
'no-void': 'error',
'no-useless-escape': 'off',
'no-invalid-this': 'error',
'vars-on-top': 'error',
'require-await': 'off',
'no-return-assign': 'off',
'operator-linebreak': ['error', 'before'],
'max-statements-per-line': ['error', { max: 1 }],
// node
'n/prefer-global/process': ['error', 'never'],
'n/prefer-global/buffer': ['error', 'never'],
'n/no-callback-literal': 'off',
// unicorns
// Pass error message when throwing errors
'unicorn/error-message': 'error',
// Uppercase regex escapes
'unicorn/escape-case': 'error',
// Array.isArray instead of instanceof
'unicorn/no-instanceof-array': 'error',
// Prevent deprecated `new Buffer()`
'unicorn/no-new-buffer': 'error',
// Keep regex literals safe!
'unicorn/no-unsafe-regex': 'off',
// Lowercase number formatting for octal, hex, binary (0x1'error' instead of 0X1'error')
'unicorn/number-literal-case': 'error',
// includes over indexOf when checking for existence
'unicorn/prefer-includes': 'error',
// String methods startsWith/endsWith instead of more complicated stuff
'unicorn/prefer-string-starts-ends-with': 'error',
// textContent instead of innerText
'unicorn/prefer-text-content': 'error',
// Enforce throwing type error when throwing error while checking typeof
'unicorn/prefer-type-error': 'error',
// Use new when throwing error
'unicorn/throw-new-error': 'error',
// Prefer using the node: protocol
'unicorn/prefer-node-protocol': 'error',
// Prefer using number properties like `Number.isNaN` rather than `isNaN`
'unicorn/prefer-number-properties': 'error',
// Ban `new Array` as `Array` constructor's params are ambiguous
'unicorn/no-new-array': 'error',
'no-use-before-define': ['error', { functions: false, classes: false, variables: true }],
'eslint-comments/disable-enable-pair': 'off',
'import/no-named-as-default-member': 'off',
'import/no-named-as-default': 'off',
'import/namespace': 'off',
'sort-imports': [
'error',
{
ignoreCase: false,
ignoreDeclarationSort: true,
ignoreMemberSort: false,
memberSyntaxSortOrder: ['none', 'all', 'multiple', 'single'],
allowSeparatedGroups: false,
},
],
// yml
'yml/quotes': ['error', { prefer: 'single', avoidEscape: false }],
'yml/no-empty-document': 'off',
// antfu
'antfu/no-import-node-modules-by-path': 'error',
'antfu/if-newline': 'error',
'antfu/import-dedupe': 'error',
'antfu/top-level-function': 'error',
// 'antfu/prefer-inline-type-import': 'error',
},
}

View File

@ -0,0 +1,39 @@
{
"name": "@antfu/eslint-config-basic",
"version": "0.40.11",
"description": "",
"author": "Anthony Fu <anthonyfu117@hotmail.com> (https://github.com/antfu/)",
"license": "MIT",
"homepage": "https://git.taoya.art/taolin/eslint-config.git",
"keywords": [
"eslint-config"
],
"main": "index.js",
"files": [
"*.js"
],
"scripts": {
"lint": "eslint . --config=index.js"
},
"peerDependencies": {
"eslint": ">=7.4.0"
},
"dependencies": {
"eslint-plugin-antfu": "workspace:*",
"eslint-plugin-eslint-comments": "^3.2.0",
"eslint-plugin-html": "^7.1.0",
"eslint-plugin-import": "npm:eslint-plugin-i@2.28.0-2",
"eslint-plugin-jsonc": "^2.9.0",
"eslint-plugin-n": "^16.0.1",
"eslint-plugin-no-only-tests": "^3.1.0",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-unicorn": "^48.0.1",
"eslint-plugin-unused-imports": "^3.0.0",
"eslint-plugin-yml": "^1.8.0",
"jsonc-eslint-parser": "^2.3.0",
"yaml-eslint-parser": "^1.2.2"
},
"devDependencies": {
"eslint": "^8.46.0"
}
}

View File

@ -0,0 +1,247 @@
// Inline from https://github.com/standard/eslint-config-standard/blob/master/.eslintrc.json
// Until it upgrades
module.exports = {
parserOptions: {
ecmaVersion: 2022,
ecmaFeatures: {
jsx: true,
},
sourceType: 'module',
},
env: {
es2021: true,
node: true,
},
plugins: [
'import',
'n',
'promise',
],
globals: {
document: 'readonly',
navigator: 'readonly',
window: 'readonly',
},
rules: {
'no-var': 'warn',
'object-shorthand': ['warn', 'properties'],
'accessor-pairs': ['error', { setWithoutGet: true, enforceForClassMembers: true }],
'array-bracket-spacing': ['error', 'never'],
'array-callback-return': ['error', {
allowImplicit: false,
checkForEach: false,
}],
'arrow-spacing': ['error', { before: true, after: true }],
'block-spacing': ['error', 'always'],
'brace-style': ['error', '1tbs', { allowSingleLine: true }],
'camelcase': ['error', {
allow: ['^UNSAFE_'],
properties: 'never',
ignoreGlobals: true,
}],
'comma-dangle': ['error', {
arrays: 'never',
objects: 'never',
imports: 'never',
exports: 'never',
functions: 'never',
}],
'comma-spacing': ['error', { before: false, after: true }],
'comma-style': ['error', 'last'],
'computed-property-spacing': ['error', 'never', { enforceForClassMembers: true }],
'constructor-super': 'error',
'curly': ['error', 'multi-line'],
'default-case-last': 'error',
'dot-location': ['error', 'property'],
'dot-notation': ['error', { allowKeywords: true }],
'eol-last': 'error',
'eqeqeq': ['error', 'always', { null: 'ignore' }],
'func-call-spacing': ['error', 'never'],
'generator-star-spacing': ['error', { before: true, after: true }],
'indent': ['error', 2, {
SwitchCase: 1,
VariableDeclarator: 1,
outerIIFEBody: 1,
MemberExpression: 1,
FunctionDeclaration: { parameters: 1, body: 1 },
FunctionExpression: { parameters: 1, body: 1 },
CallExpression: { arguments: 1 },
ArrayExpression: 1,
ObjectExpression: 1,
ImportDeclaration: 1,
flatTernaryExpressions: false,
ignoreComments: false,
ignoredNodes: ['TemplateLiteral *', 'JSXElement', 'JSXElement > *', 'JSXAttribute', 'JSXIdentifier', 'JSXNamespacedName', 'JSXMemberExpression', 'JSXSpreadAttribute', 'JSXExpressionContainer', 'JSXOpeningElement', 'JSXClosingElement', 'JSXFragment', 'JSXOpeningFragment', 'JSXClosingFragment', 'JSXText', 'JSXEmptyExpression', 'JSXSpreadChild'],
offsetTernaryExpressions: true,
}],
'key-spacing': ['error', { beforeColon: false, afterColon: true }],
'keyword-spacing': ['error', { before: true, after: true }],
'lines-between-class-members': ['error', 'always', { exceptAfterSingleLine: true }],
'multiline-ternary': ['error', 'always-multiline'],
'new-cap': ['error', { newIsCap: true, capIsNew: false, properties: true }],
'new-parens': 'error',
'no-array-constructor': 'error',
'no-async-promise-executor': 'error',
'no-caller': 'error',
'no-case-declarations': 'error',
'no-class-assign': 'error',
'no-compare-neg-zero': 'error',
'no-cond-assign': 'error',
'no-const-assign': 'error',
'no-constant-condition': ['error', { checkLoops: false }],
'no-control-regex': 'error',
'no-debugger': 'error',
'no-delete-var': 'error',
'no-dupe-args': 'error',
'no-dupe-class-members': 'error',
'no-dupe-keys': 'error',
'no-duplicate-case': 'error',
'no-useless-backreference': 'error',
'no-empty': ['error', { allowEmptyCatch: true }],
'no-empty-character-class': 'error',
'no-empty-pattern': 'error',
'no-eval': 'error',
'no-ex-assign': 'error',
'no-extend-native': 'error',
'no-extra-bind': 'error',
'no-extra-boolean-cast': 'error',
'no-extra-parens': ['error', 'functions'],
'no-fallthrough': 'error',
'no-floating-decimal': 'error',
'no-func-assign': 'error',
'no-global-assign': 'error',
'no-implied-eval': 'error',
'no-import-assign': 'error',
'no-invalid-regexp': 'error',
'no-irregular-whitespace': 'error',
'no-iterator': 'error',
'no-labels': ['error', { allowLoop: false, allowSwitch: false }],
'no-lone-blocks': 'error',
'no-loss-of-precision': 'error',
'no-misleading-character-class': 'error',
'no-prototype-builtins': 'error',
'no-useless-catch': 'error',
'no-mixed-operators': ['error', {
groups: [
['==', '!=', '===', '!==', '>', '>=', '<', '<='],
['&&', '||'],
['in', 'instanceof'],
],
allowSamePrecedence: true,
}],
'no-mixed-spaces-and-tabs': 'error',
'no-multi-spaces': 'error',
'no-multi-str': 'error',
'no-multiple-empty-lines': ['error', { max: 1, maxBOF: 0, maxEOF: 0 }],
'no-new': 'error',
'no-new-func': 'error',
'no-new-object': 'error',
'no-new-symbol': 'error',
'no-new-wrappers': 'error',
'no-obj-calls': 'error',
'no-octal': 'error',
'no-octal-escape': 'error',
'no-proto': 'error',
'no-redeclare': ['error', { builtinGlobals: false }],
'no-regex-spaces': 'error',
'no-return-assign': ['error', 'except-parens'],
'no-self-assign': ['error', { props: true }],
'no-self-compare': 'error',
'no-sequences': 'error',
'no-shadow-restricted-names': 'error',
'no-sparse-arrays': 'error',
'no-tabs': 'error',
'no-template-curly-in-string': 'error',
'no-this-before-super': 'error',
'no-throw-literal': 'error',
'no-trailing-spaces': 'error',
'no-undef': 'error',
'no-undef-init': 'error',
'no-unexpected-multiline': 'error',
'no-unmodified-loop-condition': 'error',
'no-unneeded-ternary': ['error', { defaultAssignment: false }],
'no-unreachable': 'error',
'no-unreachable-loop': 'error',
'no-unsafe-finally': 'error',
'no-unsafe-negation': 'error',
'no-unused-expressions': ['error', {
allowShortCircuit: true,
allowTernary: true,
allowTaggedTemplates: true,
}],
'no-unused-vars': ['error', {
args: 'none',
caughtErrors: 'none',
ignoreRestSiblings: true,
vars: 'all',
}],
'no-use-before-define': ['error', { functions: false, classes: false, variables: false }],
'no-useless-call': 'error',
'no-useless-computed-key': 'error',
'no-useless-constructor': 'error',
'no-useless-escape': 'error',
'no-useless-rename': 'error',
'no-useless-return': 'error',
'no-void': 'error',
'no-whitespace-before-property': 'error',
'no-with': 'error',
'object-curly-newline': ['error', { multiline: true, consistent: true }],
'object-curly-spacing': ['error', 'always'],
'object-property-newline': ['error', { allowMultiplePropertiesPerLine: true }],
'one-var': ['error', { initialized: 'never' }],
'operator-linebreak': ['error', 'after', { overrides: { '?': 'before', ':': 'before', '|>': 'before' } }],
'padded-blocks': ['error', { blocks: 'never', switches: 'never', classes: 'never' }],
'prefer-const': ['error', { destructuring: 'all' }],
'prefer-promise-reject-errors': 'error',
'prefer-regex-literals': ['error', { disallowRedundantWrapping: true }],
'quote-props': ['error', 'as-needed'],
'quotes': ['error', 'single', { avoidEscape: true, allowTemplateLiterals: false }],
'rest-spread-spacing': ['error', 'never'],
'semi': ['error', 'never'],
'semi-spacing': ['error', { before: false, after: true }],
'space-before-blocks': ['error', 'always'],
'space-before-function-paren': ['error', 'always'],
'space-in-parens': ['error', 'never'],
'space-infix-ops': 'error',
'space-unary-ops': ['error', { words: true, nonwords: false }],
'spaced-comment': ['error', 'always', {
line: { markers: ['*package', '!', '/', ',', '='] },
block: { balanced: true, markers: ['*package', '!', ',', ':', '::', 'flow-include'], exceptions: ['*'] },
}],
'symbol-description': 'error',
'template-curly-spacing': ['error', 'never'],
'template-tag-spacing': ['error', 'never'],
'unicode-bom': ['error', 'never'],
'use-isnan': ['error', {
enforceForSwitchCase: true,
enforceForIndexOf: true,
}],
'valid-typeof': ['error', { requireStringLiterals: true }],
'wrap-iife': ['error', 'any', { functionPrototypeMethods: true }],
'yield-star-spacing': ['error', 'both'],
'yoda': ['error', 'never'],
'import/export': 'error',
'import/first': 'error',
'import/no-absolute-path': ['error', { esmodule: true, commonjs: true, amd: false }],
'import/no-duplicates': 'error',
'import/no-named-default': 'error',
'import/no-webpack-loader-syntax': 'error',
'n/handle-callback-err': ['error', '^(err|error)$'],
'n/no-callback-literal': 'error',
'n/no-deprecated-api': 'error',
'n/no-exports-assign': 'error',
'n/no-new-require': 'error',
'n/no-path-concat': 'error',
'n/process-exit-as-throw': 'error',
'promise/param-names': 'error',
},
}

View File

@ -0,0 +1,19 @@
module.exports = {
extends: [
'plugin:react/recommended',
'plugin:react-hooks/recommended',
'@antfu/eslint-config-ts',
],
settings: {
react: {
version: '17.0',
},
},
rules: {
'jsx-quotes': [
'error',
'prefer-double',
],
'react/react-in-jsx-scope': 'off',
},
}

View File

@ -0,0 +1,31 @@
{
"name": "@antfu/eslint-config-react",
"version": "0.40.11",
"description": "",
"author": "Anthony Fu <anthonyfu117@hotmail.com> (https://github.com/antfu/)",
"license": "MIT",
"homepage": "https://git.taoya.art/taolin/eslint-config.git",
"keywords": [
"eslint-config"
],
"main": "index.js",
"files": [
"index.js"
],
"scripts": {
"lint": "eslint . --config=index.js"
},
"peerDependencies": {
"eslint": ">=7.4.0"
},
"dependencies": {
"@antfu/eslint-config-ts": "workspace:*",
"eslint-plugin-react": "^7.33.1",
"eslint-plugin-react-hooks": "^4.6.0"
},
"devDependencies": {
"eslint": "^8.46.0",
"react": "^18.2.0",
"typescript": "^5.1.6"
}
}

View File

@ -0,0 +1,182 @@
const fs = require('node:fs')
const { join } = require('node:path')
const process = require('node:process')
const basic = require('@antfu/eslint-config-basic')
const tsconfig = process.env.ESLINT_TSCONFIG || 'tsconfig.eslint.json'
module.exports = {
extends: [
'@antfu/eslint-config-basic',
'plugin:import/typescript',
'plugin:@typescript-eslint/recommended',
],
settings: {
'import/resolver': {
node: { extensions: ['.js', '.jsx', '.mjs', '.ts', '.tsx', '.d.ts'] },
},
},
overrides: basic.overrides.concat(
!fs.existsSync(join(process.cwd(), tsconfig))
? []
: [{
parserOptions: {
tsconfigRootDir: process.cwd(),
project: [tsconfig],
},
parser: '@typescript-eslint/parser',
excludedFiles: ['**/*.md/*.*'],
files: ['*.ts', '*.tsx', '*.mts', '*.cts'],
// https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/src/configs/recommended-requiring-type-checking.ts
rules: {
'no-throw-literal': 'off',
'@typescript-eslint/no-throw-literal': 'error',
'no-implied-eval': 'off',
'@typescript-eslint/no-implied-eval': 'error',
'dot-notation': 'off',
'@typescript-eslint/dot-notation': ['error', { allowKeywords: true }],
'@typescript-eslint/no-floating-promises': 'error',
'@typescript-eslint/no-misused-promises': 'error',
'@typescript-eslint/await-thenable': 'error',
'@typescript-eslint/no-for-in-array': 'error',
'@typescript-eslint/no-unnecessary-type-assertion': 'error',
'@typescript-eslint/no-unsafe-argument': 'error',
'@typescript-eslint/no-unsafe-assignment': 'error',
'@typescript-eslint/no-unsafe-call': 'error',
'@typescript-eslint/no-unsafe-member-access': 'error',
'@typescript-eslint/no-unsafe-return': 'error',
'require-await': 'off',
'@typescript-eslint/require-await': 'error',
'@typescript-eslint/restrict-plus-operands': 'error',
'@typescript-eslint/restrict-template-expressions': 'error',
'@typescript-eslint/unbound-method': 'error',
},
}, {
// https://github.com/jest-community/eslint-plugin-jest/blob/main/docs/rules/unbound-method.md
files: ['**/__tests__/**/*.ts', '**/*.spec.ts', '**/*.test.ts'],
plugins: ['jest'],
rules: {
// you should turn the original rule off *only* for test files
'@typescript-eslint/unbound-method': 'off',
'jest/unbound-method': 'error',
},
}],
),
rules: {
'import/named': 'off',
// TS
'@typescript-eslint/ban-ts-comment': ['error', { 'ts-ignore': 'allow-with-description' }],
'@typescript-eslint/member-delimiter-style': ['error', { multiline: { delimiter: 'none' } }],
'@typescript-eslint/type-annotation-spacing': ['error', {}],
'@typescript-eslint/consistent-type-imports': ['error', { prefer: 'type-imports', disallowTypeAnnotations: false }],
'@typescript-eslint/consistent-type-definitions': ['error', 'interface'],
'@typescript-eslint/prefer-ts-expect-error': 'error',
'@typescript-eslint/no-require-imports': 'error',
// Override JS
'no-useless-constructor': 'off',
'indent': 'off',
'@typescript-eslint/indent': ['error', 2, {
SwitchCase: 1,
VariableDeclarator: 1,
outerIIFEBody: 1,
MemberExpression: 1,
FunctionDeclaration: { parameters: 1, body: 1 },
FunctionExpression: { parameters: 1, body: 1 },
CallExpression: { arguments: 1 },
ArrayExpression: 1,
ObjectExpression: 1,
ImportDeclaration: 1,
flatTernaryExpressions: false,
ignoreComments: false,
ignoredNodes: [
'TemplateLiteral *',
'JSXElement',
'JSXElement > *',
'JSXAttribute',
'JSXIdentifier',
'JSXNamespacedName',
'JSXMemberExpression',
'JSXSpreadAttribute',
'JSXExpressionContainer',
'JSXOpeningElement',
'JSXClosingElement',
'JSXFragment',
'JSXOpeningFragment',
'JSXClosingFragment',
'JSXText',
'JSXEmptyExpression',
'JSXSpreadChild',
'TSTypeParameterInstantiation',
'FunctionExpression > .params[decorators.length > 0]',
'FunctionExpression > .params > :matches(Decorator, :not(:first-child))',
'ClassBody.body > PropertyDefinition[decorators.length > 0] > .key',
],
offsetTernaryExpressions: true,
}],
'no-invalid-this': 'off',
'@typescript-eslint/no-invalid-this': 'error',
'no-redeclare': 'off',
'@typescript-eslint/no-redeclare': 'error',
'no-use-before-define': 'off',
'@typescript-eslint/no-use-before-define': ['error', { functions: false, classes: false, variables: true }],
'brace-style': 'off',
'@typescript-eslint/brace-style': ['error', 'stroustrup', { allowSingleLine: true }],
'comma-dangle': 'off',
'@typescript-eslint/comma-dangle': ['error', 'always-multiline'],
'object-curly-spacing': 'off',
'@typescript-eslint/object-curly-spacing': ['error', 'always'],
'semi': 'off',
'@typescript-eslint/semi': ['error', 'never'],
'quotes': 'off',
'@typescript-eslint/quotes': ['error', 'single'],
'space-before-blocks': 'off',
'@typescript-eslint/space-before-blocks': ['error', 'always'],
'space-before-function-paren': 'off',
'@typescript-eslint/space-before-function-paren': [
'error',
{
anonymous: 'always',
named: 'never',
asyncArrow: 'always',
},
],
'space-infix-ops': 'off',
'@typescript-eslint/space-infix-ops': 'error',
'keyword-spacing': 'off',
'@typescript-eslint/keyword-spacing': ['error', { before: true, after: true }],
'comma-spacing': 'off',
'@typescript-eslint/comma-spacing': ['error', { before: false, after: true }],
'no-extra-parens': 'off',
'@typescript-eslint/no-extra-parens': ['error', 'functions'],
'no-dupe-class-members': 'off',
'@typescript-eslint/no-dupe-class-members': 'error',
'no-loss-of-precision': 'off',
'@typescript-eslint/no-loss-of-precision': 'error',
'lines-between-class-members': 'off',
'@typescript-eslint/lines-between-class-members': ['error', 'always', { exceptAfterSingleLine: true }],
// antfu
'antfu/generic-spacing': 'error',
'antfu/no-cjs-exports': 'error',
'antfu/no-ts-export-equal': 'error',
'antfu/no-const-enum': 'error',
'antfu/named-tuple-spacing': 'error',
// off
'@typescript-eslint/consistent-indexed-object-style': 'off',
'@typescript-eslint/naming-convention': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-member-accessibility': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/parameter-properties': 'off',
'@typescript-eslint/no-empty-interface': 'off',
'@typescript-eslint/ban-ts-ignore': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/triple-slash-reference': 'off',
// handled by unused-imports/no-unused-imports
'@typescript-eslint/no-unused-vars': 'off',
},
}

View File

@ -0,0 +1,28 @@
{
"name": "@antfu/eslint-config-ts",
"version": "0.40.11",
"description": "",
"author": "Anthony Fu <anthonyfu117@hotmail.com> (https://github.com/antfu/)",
"license": "MIT",
"homepage": "https://git.taoya.art/taolin/eslint-config.git",
"keywords": [
"eslint-config"
],
"main": "index.js",
"files": [
"index.js"
],
"peerDependencies": {
"eslint": ">=7.4.0",
"typescript": ">=3.9"
},
"dependencies": {
"@antfu/eslint-config-basic": "workspace:*",
"@typescript-eslint/eslint-plugin": "^6.2.1",
"@typescript-eslint/parser": "^6.2.1",
"eslint-plugin-jest": "^27.2.3"
},
"devDependencies": {
"eslint": "^8.46.0"
}
}

View File

@ -0,0 +1,111 @@
const { isPackageExists } = require('local-pkg')
const TS = isPackageExists('typescript')
if (!TS)
console.warn('[@antfu/eslint-config] TypeScript is not installed, fallback to JS only.')
module.exports = {
overrides: [
{
files: ['*.vue'],
parser: 'vue-eslint-parser',
parserOptions: {
parser: '@typescript-eslint/parser',
},
rules: {
'no-unused-vars': 'off',
'no-undef': 'off',
...(TS
? { '@typescript-eslint/no-unused-vars': 'off' }
: null),
},
},
],
extends: [
'plugin:vue/vue3-recommended',
TS
? '@antfu/eslint-config-ts'
: '@antfu/eslint-config-basic',
],
rules: {
'vue/max-attributes-per-line': 'off',
'vue/no-v-html': 'off',
'vue/require-prop-types': 'off',
'vue/require-default-prop': 'off',
'vue/multi-word-component-names': 'off',
'vue/prefer-import-from-vue': 'off',
'vue/no-v-text-v-html-on-component': 'off',
'vue/no-dupe-keys': 'off',
// reactivity transform
'vue/no-setup-props-destructure': 'off',
'vue/component-tags-order': ['error', {
order: ['script', 'template', 'style'],
}],
'vue/block-tag-newline': ['error', {
singleline: 'always',
multiline: 'always',
}],
'vue/component-name-in-template-casing': ['error', 'PascalCase'],
'vue/component-options-name-casing': ['error', 'PascalCase'],
'vue/custom-event-name-casing': ['error', 'camelCase'],
'vue/define-macros-order': ['error', {
order: ['defineOptions', 'defineProps', 'defineEmits', 'defineSlots'],
}],
'vue/html-comment-content-spacing': ['error', 'always', {
exceptions: ['-'],
}],
'vue/no-restricted-v-bind': ['error', '/^v-/'],
'vue/no-useless-v-bind': 'error',
'vue/no-unused-refs': 'error',
'vue/padding-line-between-blocks': ['error', 'always'],
'vue/prefer-separate-static-class': 'error',
// extensions
'vue/array-bracket-spacing': ['error', 'never'],
'vue/arrow-spacing': ['error', { before: true, after: true }],
'vue/block-spacing': ['error', 'always'],
'vue/brace-style': ['error', 'stroustrup', { allowSingleLine: true }],
'vue/comma-dangle': ['error', 'always-multiline'],
'vue/comma-spacing': ['error', { before: false, after: true }],
'vue/comma-style': ['error', 'last'],
'vue/dot-location': ['error', 'property'],
'vue/dot-notation': ['error', { allowKeywords: true }],
'vue/eqeqeq': ['error', 'smart'],
// 'vue/func-call-spacing': ['off', 'never'],
'vue/key-spacing': ['error', { beforeColon: false, afterColon: true }],
'vue/keyword-spacing': ['error', { before: true, after: true }],
'vue/no-constant-condition': 'warn',
'vue/no-empty-pattern': 'error',
'vue/no-extra-parens': ['error', 'functions'],
'vue/no-irregular-whitespace': 'error',
'vue/no-loss-of-precision': 'error',
'vue/no-restricted-syntax': [
'error',
'DebuggerStatement',
'LabeledStatement',
'WithStatement',
],
'vue/no-sparse-arrays': 'error',
'vue/object-curly-newline': ['error', { multiline: true, consistent: true }],
'vue/object-curly-spacing': ['error', 'always'],
'vue/object-property-newline': ['error', { allowMultiplePropertiesPerLine: true }],
'vue/object-shorthand': [
'error',
'always',
{
ignoreConstructors: false,
avoidQuotes: true,
},
],
'vue/operator-linebreak': ['error', 'before'],
'vue/prefer-template': 'error',
'vue/quote-props': ['error', 'consistent-as-needed'],
'vue/space-in-parens': ['error', 'never'],
'vue/space-infix-ops': 'error',
'vue/space-unary-ops': ['error', { words: true, nonwords: false }],
'vue/template-curly-spacing': 'error',
},
}

View File

@ -1,26 +1,26 @@
{
"name": "@antfu/eslint-config-vue",
"version": "0.1.4",
"version": "0.40.11",
"description": "",
"main": "index.js",
"keywords": [],
"author": "Anthony Fu <anthonyfu117@hotmail.com> (https://github.com/antfu/)",
"license": "MIT",
"scripts": {
"lint": "eslint . --config=index.js"
},
"keywords": [
"eslint-config"
],
"main": "index.js",
"files": [
"index.js"
],
"peerDependencies": {
"eslint": ">=5.16.0"
"eslint": ">=7.4.0"
},
"dependencies": {
"@antfu/eslint-config": "^0.1.4",
"eslint-plugin-nuxt": "0.4.3",
"eslint-plugin-vue": "5.2.3"
"@antfu/eslint-config-basic": "workspace:*",
"@antfu/eslint-config-ts": "workspace:*",
"eslint-plugin-vue": "^9.16.1",
"local-pkg": "^0.4.3"
},
"devDependencies": {
"eslint": "^6.0.1"
"eslint": "^8.46.0"
}
}

View File

@ -0,0 +1,5 @@
module.exports = {
extends: [
'@antfu/eslint-config-vue',
],
}

View File

@ -0,0 +1,37 @@
{
"name": "@taoyaal/eslint-config",
"version": "0.40.11",
"description": "Anthony's ESLint config",
"author": "Anthony Fu <anthonyfu117@hotmail.com> (https://github.com/antfu/)",
"license": "MIT",
"homepage": "https://git.taoya.art/taolin/eslint-config.git",
"keywords": [
"eslint-config"
],
"main": "index.js",
"files": [
"index.js"
],
"peerDependencies": {
"eslint": ">=7.4.0"
},
"dependencies": {
"@antfu/eslint-config-vue": "workspace:*",
"@typescript-eslint/eslint-plugin": "^6.2.1",
"@typescript-eslint/parser": "^6.2.1",
"eslint-plugin-eslint-comments": "^3.2.0",
"eslint-plugin-html": "^7.1.0",
"eslint-plugin-import": "npm:eslint-plugin-i@2.28.0-2",
"eslint-plugin-jsonc": "^2.9.0",
"eslint-plugin-n": "^16.0.1",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-unicorn": "^48.0.1",
"eslint-plugin-vue": "^9.16.1",
"eslint-plugin-yml": "^1.8.0",
"jsonc-eslint-parser": "^2.3.0",
"yaml-eslint-parser": "^1.2.2"
},
"devDependencies": {
"eslint": "^8.46.0"
}
}

View File

@ -0,0 +1,6 @@
{
"extends": "@antfu",
"plugins": [
"antfu"
]
}

View File

@ -0,0 +1,12 @@
import { defineBuildConfig } from 'unbuild'
export default defineBuildConfig({
entries: [
'src/index',
],
declaration: false,
clean: true,
rollup: {
emitCJS: true,
},
})

View File

@ -0,0 +1,26 @@
{
"name": "eslint-plugin-antfu",
"version": "0.40.11",
"license": "MIT",
"homepage": "https://git.taoya.art/taolin/eslint-config.git",
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"files": [
"dist"
],
"scripts": {
"build": "rimraf dist && unbuild",
"stub": "unbuild --stub",
"test": "vitest",
"prepublishOnly": "nr build"
},
"dependencies": {
"@typescript-eslint/utils": "^6.2.1"
},
"devDependencies": {
"@types/node": "^20.4.8",
"@typescript-eslint/rule-tester": "^6.2.1",
"unbuild": "^1.2.1",
"vitest": "^0.34.1"
}
}

View File

@ -0,0 +1,25 @@
import genericSpacing from './rules/generic-spacing'
import ifNewline from './rules/if-newline'
import importDedupe from './rules/import-dedupe'
import preferInlineTypeImport from './rules/prefer-inline-type-import'
import topLevelFunction from './rules/top-level-function'
import noImportNodeModulesByPath from './rules/no-import-node-modules-by-path'
import noTsExportEqual from './rules/no-ts-export-equal'
import noCjsExports from './rules/no-cjs-exports'
import noConstEnum from './rules/no-const-enum'
import namedTupleSpacing from './rules/named-tuple-spacing'
export default {
rules: {
'if-newline': ifNewline,
'import-dedupe': importDedupe,
'prefer-inline-type-import': preferInlineTypeImport,
'generic-spacing': genericSpacing,
'top-level-function': topLevelFunction,
'no-import-node-modules-by-path': noImportNodeModulesByPath,
'no-cjs-exports': noCjsExports,
'no-ts-export-equal': noTsExportEqual,
'no-const-enum': noConstEnum,
'named-tuple-spacing': namedTupleSpacing,
},
}

View File

@ -0,0 +1,49 @@
import { RuleTester } from '@typescript-eslint/rule-tester'
import rule, { RULE_NAME } from './generic-spacing'
const valids = [
'type Foo<T = true> = T',
'type Foo<T extends true = true> = T',
`
type Foo<
T = true,
K = false
> = T`,
`function foo<
T
>() {}`,
'const foo = <T>(name: T) => name',
`interface Log {
foo<T>(name: T): void
}`,
`interface Log {
<T>(name: T): void
}`,
`interface Foo {
foo?: <T>(name: T) => void
}`,
]
const invalids = [
['type Foo<T=true> = T', 'type Foo<T = true> = T'],
['type Foo<T,K> = T', 'type Foo<T, K> = T'],
['type Foo<T=false,K=1|2> = T', 'type Foo<T = false, K = 1|2> = T', 3],
['function foo <T>() {}', 'function foo<T>() {}'],
[`interface Log {
foo <T>(name: T): void
}`, `interface Log {
foo<T>(name: T): void
}`],
] as const
const ruleTester: RuleTester = new RuleTester({
parser: require.resolve('@typescript-eslint/parser'),
})
ruleTester.run(RULE_NAME, rule as any, {
valid: valids,
invalid: invalids.map(i => ({
code: i[0],
output: i[1].trim(),
errors: Array.from({ length: i[2] || 1 }, () => ({ messageId: 'genericSpacingMismatch' })),
})),
})

View File

@ -0,0 +1,87 @@
import { createEslintRule } from '../utils'
export const RULE_NAME = 'generic-spacing'
export type MessageIds = 'genericSpacingMismatch'
export type Options = []
export default createEslintRule<Options, MessageIds>({
name: RULE_NAME,
meta: {
type: 'suggestion',
docs: {
description: 'Spaces around generic type parameters',
recommended: 'stylistic',
},
fixable: 'code',
schema: [],
messages: {
genericSpacingMismatch: 'Generic spaces mismatch',
},
},
defaultOptions: [],
create: (context) => {
const sourceCode = context.getSourceCode()
return {
TSTypeParameterDeclaration: (node) => {
if (!['TSCallSignatureDeclaration', 'ArrowFunctionExpression', 'TSFunctionType'].includes(node.parent.type)) {
const pre = sourceCode.text.slice(0, node.range[0])
const preSpace = pre.match(/(\s+)$/)?.[0]
// strip space before <T>
if (preSpace && preSpace.length) {
context.report({
node,
messageId: 'genericSpacingMismatch',
*fix(fixer) {
yield fixer.replaceTextRange([node.range[0] - preSpace.length, node.range[0]], '')
},
})
}
}
// add space between <T,K>
const params = node.params
for (let i = 1; i < params.length; i++) {
const prev = params[i - 1]
const current = params[i]
const from = prev.range[1]
const to = current.range[0]
const span = sourceCode.text.slice(from, to)
if (span !== ', ' && !span.match(/,\n/)) {
context.report({
*fix(fixer) {
yield fixer.replaceTextRange([from, to], ', ')
},
loc: {
start: prev.loc.end,
end: current.loc.start,
},
messageId: 'genericSpacingMismatch',
node,
})
}
}
},
// add space around = in type Foo<T = true>
TSTypeParameter: (node) => {
if (!node.default)
return
const endNode = node.constraint || node.name
const from = endNode.range[1]
const to = node.default.range[0]
if (sourceCode.text.slice(from, to) !== ' = ') {
context.report({
*fix(fixer) {
yield fixer.replaceTextRange([from, to], ' = ')
},
loc: {
start: endNode.loc.end,
end: node.default.loc.start,
},
messageId: 'genericSpacingMismatch',
node,
})
}
},
}
},
})

View File

@ -0,0 +1,27 @@
import { RuleTester } from '@typescript-eslint/rule-tester'
import rule, { RULE_NAME } from './if-newline'
const valids = [
`if (true)
console.log('hello')
`,
`if (true) {
console.log('hello')
}`,
]
const invalids = [
['if (true) console.log(\'hello\')', 'if (true) \nconsole.log(\'hello\')'],
]
const ruleTester: RuleTester = new RuleTester({
parser: require.resolve('@typescript-eslint/parser'),
})
ruleTester.run(RULE_NAME, rule as any, {
valid: valids,
invalid: invalids.map(i => ({
code: i[0],
output: i[1],
errors: [{ messageId: 'missingIfNewline' }],
})),
})

View File

@ -0,0 +1,45 @@
import { createEslintRule } from '../utils'
export const RULE_NAME = 'if-newline'
export type MessageIds = 'missingIfNewline'
export type Options = []
export default createEslintRule<Options, MessageIds>({
name: RULE_NAME,
meta: {
type: 'problem',
docs: {
description: 'Newline after if',
recommended: 'stylistic',
},
fixable: 'code',
schema: [],
messages: {
missingIfNewline: 'Expect newline after if',
},
},
defaultOptions: [],
create: (context) => {
return {
IfStatement(node) {
if (!node.consequent)
return
if (node.consequent.type === 'BlockStatement')
return
if (node.test.loc.end.line === node.consequent.loc.start.line) {
context.report({
node,
loc: {
start: node.test.loc.end,
end: node.consequent.loc.start,
},
messageId: 'missingIfNewline',
fix(fixer) {
return fixer.replaceTextRange([node.consequent.range[0], node.consequent.range[0]], '\n')
},
})
}
},
}
},
})

View File

@ -0,0 +1,25 @@
import { RuleTester } from '@typescript-eslint/rule-tester'
import rule, { RULE_NAME } from './import-dedupe'
const valids = [
'import { a } from \'foo\'',
]
const invalids = [
[
'import { a, b, a, a, c, a } from \'foo\'',
'import { a, b, c, } from \'foo\'',
],
]
const ruleTester: RuleTester = new RuleTester({
parser: require.resolve('@typescript-eslint/parser'),
})
ruleTester.run(RULE_NAME, rule as any, {
valid: valids,
invalid: invalids.map(i => ({
code: i[0],
output: i[1],
errors: [{ messageId: 'importDedupe' }, { messageId: 'importDedupe' }, { messageId: 'importDedupe' }],
})),
})

View File

@ -0,0 +1,55 @@
import { createEslintRule } from '../utils'
export const RULE_NAME = 'import-dedupe'
export type MessageIds = 'importDedupe'
export type Options = []
export default createEslintRule<Options, MessageIds>({
name: RULE_NAME,
meta: {
type: 'problem',
docs: {
description: 'Fix duplication in imports',
recommended: 'strict',
},
fixable: 'code',
schema: [],
messages: {
importDedupe: 'Expect no duplication in imports',
},
},
defaultOptions: [],
create: (context) => {
return {
ImportDeclaration(node) {
if (node.specifiers.length <= 1)
return
const names = new Set<string>()
node.specifiers.forEach((n) => {
const id = n.local.name
if (names.has(id)) {
context.report({
node,
loc: {
start: n.loc.end,
end: n.loc.start,
},
messageId: 'importDedupe',
fix(fixer) {
const s = n.range[0]
let e = n.range[1]
if (context.getSourceCode().text[e] === ',')
e += 1
return fixer.removeRange([s, e])
},
})
}
names.add(id)
})
// console.log(node)
},
}
},
})

View File

@ -0,0 +1,98 @@
import { RuleTester } from '@typescript-eslint/rule-tester'
import rule, { RULE_NAME } from './named-tuple-spacing'
const valids = [
'type T = [i: number]',
'type T = [i?: number]',
'type T = [i: number, j: number]',
'type T = [i: number, j: () => string]',
`const emit = defineEmits<{
change: [id: number]
update: [value: string]
}>()`,
]
const ruleTester: RuleTester = new RuleTester({
parser: require.resolve('@typescript-eslint/parser'),
})
ruleTester.run(RULE_NAME, rule as any, {
valid: valids,
invalid: [
{
code: 'type T = [i:number]',
output: 'type T = [i: number]',
errors: [{ messageId: 'expectedSpaceAfter' }],
},
{
code: 'type T = [i: number]',
output: 'type T = [i: number]',
errors: [{ messageId: 'expectedSpaceAfter' }],
},
{
code: 'type T = [i?:number]',
output: 'type T = [i?: number]',
errors: [{ messageId: 'expectedSpaceAfter' }],
},
{
code: 'type T = [i? :number]',
output: 'type T = [i?: number]',
errors: [{ messageId: 'unexpectedSpaceBetween' }, { messageId: 'expectedSpaceAfter' }],
},
{
code: 'type T = [i : number]',
output: 'type T = [i: number]',
errors: [{ messageId: 'unexpectedSpaceBefore' }],
},
{
code: 'type T = [i : number]',
output: 'type T = [i: number]',
errors: [{ messageId: 'unexpectedSpaceBefore' }],
},
{
code: 'type T = [i ? : number]',
output: 'type T = [i?: number]',
errors: [{ messageId: 'unexpectedSpaceBetween' }, { messageId: 'unexpectedSpaceBefore' }],
},
{
code: 'type T = [i:number, j:number]',
output: 'type T = [i: number, j: number]',
errors: [{ messageId: 'expectedSpaceAfter' }, { messageId: 'expectedSpaceAfter' }],
},
{
code: 'type T = [i:()=>void, j:number]',
output: 'type T = [i: ()=>void, j: number]',
errors: [{ messageId: 'expectedSpaceAfter' }, { messageId: 'expectedSpaceAfter' }],
},
{
code: `
const emit = defineEmits<{
change: [id:number]
update: [value:string]
}>()
`,
output: `
const emit = defineEmits<{
change: [id: number]
update: [value: string]
}>()
`,
errors: [{ messageId: 'expectedSpaceAfter' }, { messageId: 'expectedSpaceAfter' }],
},
{
code: `
const emit = defineEmits<{
change: [id? :number]
update: [value:string]
}>()
`,
output: `
const emit = defineEmits<{
change: [id?: number]
update: [value: string]
}>()
`,
errors: [{ messageId: 'unexpectedSpaceBetween' }, { messageId: 'expectedSpaceAfter' }, { messageId: 'expectedSpaceAfter' }],
},
],
})

View File

@ -0,0 +1,83 @@
import { createEslintRule } from '../utils'
export const RULE_NAME = 'named-tuple-spacing'
export type MessageIds = 'expectedSpaceAfter' | 'unexpectedSpaceBetween' | 'unexpectedSpaceBefore'
export type Options = []
const RE = /^([\w_$]+)(\s*)(\?\s*)?:(\s*)(.*)$/
export default createEslintRule<Options, MessageIds>({
name: RULE_NAME,
meta: {
type: 'suggestion',
docs: {
description: 'Expect space before type declaration in named tuple',
recommended: 'stylistic',
},
fixable: 'code',
schema: [],
messages: {
expectedSpaceAfter: 'Expected a space after the \':\'.',
unexpectedSpaceBetween: 'Unexpected space between \'?\' and the \':\'.',
unexpectedSpaceBefore: 'Unexpected space before the \':\'.',
},
},
defaultOptions: [],
create: (context) => {
const sourceCode = context.getSourceCode()
return {
TSNamedTupleMember: (node: any) => {
const code = sourceCode.text.slice(node.range[0], node.range[1])
const match = code.match(RE)
if (!match)
return
const labelName = node.label.name
const spaceBeforeColon = match[2]
const optionalMark = match[3]
const spacesAfterColon = match[4]
const elementType = match[5]
function getReplaceValue() {
let ret = labelName
if (node.optional)
ret += '?'
ret += ': '
ret += elementType
return ret
}
if (optionalMark?.length > 1) {
context.report({
node,
messageId: 'unexpectedSpaceBetween',
*fix(fixer) {
yield fixer.replaceTextRange(node.range, code.replace(RE, getReplaceValue()))
},
})
}
if (spaceBeforeColon?.length) {
context.report({
node,
messageId: 'unexpectedSpaceBefore',
*fix(fixer) {
yield fixer.replaceTextRange(node.range, code.replace(RE, getReplaceValue()))
},
})
}
if (spacesAfterColon != null && spacesAfterColon.length !== 1) {
context.report({
node,
messageId: 'expectedSpaceAfter',
*fix(fixer) {
yield fixer.replaceTextRange(node.range, code.replace(RE, getReplaceValue()))
},
})
}
},
}
},
})

View File

@ -0,0 +1,25 @@
import { RuleTester } from '@typescript-eslint/rule-tester'
import rule, { RULE_NAME } from './no-cjs-exports'
const valids = [
{ code: 'export = {}', filename: 'test.ts' },
{ code: 'exports.a = {}', filename: 'test.js' },
{ code: 'module.exports.a = {}', filename: 'test.js' },
]
const invalids = [
{ code: 'exports.a = {}', filename: 'test.ts' },
{ code: 'module.exports.a = {}', filename: 'test.ts' },
]
const ruleTester: RuleTester = new RuleTester({
parser: require.resolve('@typescript-eslint/parser'),
})
ruleTester.run(RULE_NAME, rule as any, {
valid: valids,
invalid: invalids.map(i => ({
...i,
errors: [{ messageId: 'noCjsExports' }],
})),
})

View File

@ -0,0 +1,40 @@
import { createEslintRule } from '../utils'
export const RULE_NAME = 'no-cjs-exports'
export type MessageIds = 'noCjsExports'
export type Options = []
export default createEslintRule<Options, MessageIds>({
name: RULE_NAME,
meta: {
type: 'problem',
docs: {
description: 'Do not use CJS exports',
},
schema: [],
messages: {
noCjsExports: 'Use ESM export instead',
},
},
defaultOptions: [],
create: (context) => {
const extension = context.getFilename().split('.').pop()
if (!['ts', 'tsx', 'mts', 'cts'].includes(extension))
return {}
return {
'MemberExpression[object.name="exports"]': function (node) {
context.report({
node,
messageId: 'noCjsExports',
})
},
'MemberExpression[object.name="module"][property.name="exports"]': function (node) {
context.report({
node,
messageId: 'noCjsExports',
})
},
}
},
})

View File

@ -0,0 +1,22 @@
import { RuleTester } from '@typescript-eslint/rule-tester'
import rule, { RULE_NAME } from './no-const-enum'
const valids = [
'enum E {}',
]
const invalids = [
'const enum E {}',
]
const ruleTester: RuleTester = new RuleTester({
parser: require.resolve('@typescript-eslint/parser'),
})
ruleTester.run(RULE_NAME, rule as any, {
valid: valids,
invalid: invalids.map(i => ({
code: i,
errors: [{ messageId: 'noConstEnum' }],
})),
})

View File

@ -0,0 +1,33 @@
import { createEslintRule } from '../utils'
export const RULE_NAME = 'no-const-enum'
export type MessageIds = 'noConstEnum'
export type Options = []
export default createEslintRule<Options, MessageIds>({
name: RULE_NAME,
meta: {
type: 'problem',
docs: {
description: 'Disallow using `const enum` expression',
recommended: 'recommended',
},
schema: [],
messages: {
noConstEnum: 'Do not use `const enum` expression',
},
},
defaultOptions: [],
create: (context) => {
return {
TSEnumDeclaration: (node) => {
if (node.const) {
context.report({
node,
messageId: 'noConstEnum',
})
}
},
}
},
})

View File

@ -0,0 +1,28 @@
import { RuleTester } from '@typescript-eslint/rule-tester'
import rule, { RULE_NAME } from './no-import-node-modules-by-path'
const valids = [
'import xxx from "a"',
'import "b"',
'const c = require("c")',
'require("d")',
]
const invalids = [
'import a from "../node_modules/a"',
'import "../node_modules/b"',
'const c = require("../node_modules/c")',
'require("../node_modules/d")',
]
const ruleTester: RuleTester = new RuleTester({
parser: require.resolve('@typescript-eslint/parser'),
})
ruleTester.run(RULE_NAME, rule as any, {
valid: valids,
invalid: invalids.map(i => ({
code: i,
errors: [{ messageId: 'noImportNodeModulesByPath' }],
})),
})

View File

@ -0,0 +1,42 @@
import { createEslintRule } from '../utils'
export const RULE_NAME = 'no-import-node-modules-by-path'
export type MessageIds = 'noImportNodeModulesByPath'
export type Options = []
export default createEslintRule<Options, MessageIds>({
name: RULE_NAME,
meta: {
type: 'problem',
docs: {
description: 'Prevent importing modules in `node_modules` folder by relative or absolute path',
recommended: 'recommended',
},
schema: [],
messages: {
noImportNodeModulesByPath: 'Do not import modules in `node_modules` folder by path',
},
},
defaultOptions: [],
create: (context) => {
return {
'ImportDeclaration': (node) => {
if (node.source.value.includes('/node_modules/')) {
context.report({
node,
messageId: 'noImportNodeModulesByPath',
})
}
},
'CallExpression[callee.name="require"]': (node: any) => {
const value = node.arguments[0]?.value
if (typeof value === 'string' && value.includes('/node_modules/')) {
context.report({
node,
messageId: 'noImportNodeModulesByPath',
})
}
},
}
},
})

View File

@ -0,0 +1,23 @@
import { RuleTester } from '@typescript-eslint/rule-tester'
import rule, { RULE_NAME } from './no-ts-export-equal'
const valids = [
{ code: 'export default {}', filename: 'test.ts' },
{ code: 'export = {}', filename: 'test.js' },
]
const invalids = [
{ code: 'export = {}', filename: 'test.ts' },
]
const ruleTester: RuleTester = new RuleTester({
parser: require.resolve('@typescript-eslint/parser'),
})
ruleTester.run(RULE_NAME, rule as any, {
valid: valids,
invalid: invalids.map(i => ({
...i,
errors: [{ messageId: 'noTsExportEqual' }],
})),
})

View File

@ -0,0 +1,35 @@
import { createEslintRule } from '../utils'
export const RULE_NAME = 'no-ts-export-equal'
export type MessageIds = 'noTsExportEqual'
export type Options = []
export default createEslintRule<Options, MessageIds>({
name: RULE_NAME,
meta: {
type: 'problem',
docs: {
description: 'Do not use `exports =`',
recommended: 'recommended',
},
schema: [],
messages: {
noTsExportEqual: 'Use ESM `export default` instead',
},
},
defaultOptions: [],
create: (context) => {
const extension = context.getFilename().split('.').pop()
if (!['ts', 'tsx', 'mts', 'cts'].includes(extension))
return {}
return {
TSExportAssignment(node) {
context.report({
node,
messageId: 'noTsExportEqual',
})
},
}
},
})

View File

@ -0,0 +1,25 @@
import { RuleTester } from '@typescript-eslint/rule-tester'
import rule, { RULE_NAME } from './prefer-inline-type-import'
const valids = [
'import { type Foo } from \'foo\'',
'import type Foo from \'foo\'',
'import type * as Foo from \'foo\'',
'import type {} from \'foo\'',
]
const invalids = [
['import type { Foo } from \'foo\'', 'import { type Foo } from \'foo\''],
]
const ruleTester: RuleTester = new RuleTester({
parser: require.resolve('@typescript-eslint/parser'),
})
ruleTester.run(RULE_NAME, rule as any, {
valid: valids,
invalid: invalids.map(i => ({
code: i[0],
output: i[1].trim(),
errors: [{ messageId: 'preferInlineTypeImport' }],
})),
})

View File

@ -0,0 +1,63 @@
// Ported from https://github.com/gajus/eslint-plugin-canonical/blob/master/src/rules/preferInlineTypeImport.js
// by Gajus Kuizinas https://github.com/gajus
import type { TSESTree } from '@typescript-eslint/utils'
import type { RuleFixer, SourceCode } from '@typescript-eslint/utils/ts-eslint'
import { createEslintRule } from '../utils'
export const RULE_NAME = 'prefer-inline-type-import'
export type MessageIds = 'preferInlineTypeImport'
export type Options = []
export default createEslintRule<Options, MessageIds>({
name: RULE_NAME,
meta: {
type: 'suggestion',
docs: {
description: 'Inline type import',
},
fixable: 'code',
schema: [],
messages: {
preferInlineTypeImport: 'Prefer inline type import',
},
},
defaultOptions: [],
create: (context) => {
const sourceCode = context.getSourceCode()
return {
ImportDeclaration: (node) => {
// ignore bare type imports
if (node.specifiers.length === 1 && ['ImportNamespaceSpecifier', 'ImportDefaultSpecifier'].includes(node.specifiers[0].type))
return
if (node.importKind === 'type' && node.specifiers.length > 0) {
context.report({
*fix(fixer) {
yield * removeTypeSpecifier(fixer, sourceCode, node)
for (const specifier of node.specifiers)
yield fixer.insertTextBefore(specifier, 'type ')
},
loc: node.loc,
messageId: 'preferInlineTypeImport',
node,
})
}
},
}
},
})
function * removeTypeSpecifier(fixer: RuleFixer, sourceCode: Readonly<SourceCode>, node: TSESTree.ImportDeclaration) {
const importKeyword = sourceCode.getFirstToken(node)
const typeIdentifier = sourceCode.getTokenAfter(importKeyword)
yield fixer.remove(typeIdentifier)
if (importKeyword.loc.end.column + 1 === typeIdentifier.loc.start.column) {
yield fixer.removeRange([
importKeyword.range[1],
importKeyword.range[1] + 1,
])
}
}

View File

@ -0,0 +1,64 @@
import { RuleTester } from '@typescript-eslint/rule-tester'
import rule, { RULE_NAME } from './top-level-function'
const valids = [
'function foo() {}',
// allow arrow function inside function
'function foo() { const bar = () => {} }',
// allow arrow function when type is specified
'const Foo: Bar = () => {}',
// allow let/var
'let foo = () => {}',
// allow arrow function in as
'const foo = (() => {}) as any',
// allow iife
';(() => {})()',
// allow export default
'export default () => {}',
'export default defineConfig(() => {})',
// allow one-line arrow function
'const foo = (x, y) => x + y',
'const foo = async (x, y) => x + y',
'const foo = () => String(123)',
'const foo = () => ({})',
]
const invalids = [
[
'const foo = (x, y) => \nx + y',
'function foo (x, y) {\n return x + y\n}',
],
[
'const foo = (as: string, bar: number) => { return as + bar }',
'function foo (as: string, bar: number) { return as + bar }',
],
[
'const foo = <K, T extends Boolean>(as: string, bar: number): Omit<T, K> => \nas + bar',
'function foo <K, T extends Boolean>(as: string, bar: number): Omit<T, K> {\n return as + bar\n}',
],
[
'export const foo = () => {}',
'export function foo () {}',
],
[
'export const foo = () => \n({})',
'export function foo () {\n return {}\n}',
],
[
'export const foo = async () => \n({})',
'export async function foo () {\n return {}\n}',
],
]
const ruleTester: RuleTester = new RuleTester({
parser: require.resolve('@typescript-eslint/parser'),
})
ruleTester.run(RULE_NAME, rule as any, {
valid: valids,
invalid: invalids.map(i => ({
code: i[0],
output: i[1],
errors: [{ messageId: 'topLevelFunctionDeclaration' }],
})),
})

View File

@ -0,0 +1,88 @@
import { createEslintRule } from '../utils'
export const RULE_NAME = 'top-level-function'
export type MessageIds = 'topLevelFunctionDeclaration'
export type Options = []
export default createEslintRule<Options, MessageIds>({
name: RULE_NAME,
meta: {
type: 'problem',
docs: {
description: 'Enforce top-level functions to be declared with function keyword',
recommended: 'stylistic',
},
fixable: 'code',
schema: [],
messages: {
topLevelFunctionDeclaration: 'Top-level functions should be declared with function keyword',
},
},
defaultOptions: [],
create: (context) => {
return {
VariableDeclaration(node) {
if (node.parent.type !== 'Program' && node.parent.type !== 'ExportNamedDeclaration')
return
if (node.declarations.length !== 1)
return
if (node.kind !== 'const')
return
if (node.declare)
return
const declaration = node.declarations[0]
if (declaration.init?.type !== 'ArrowFunctionExpression')
return
if (declaration.id?.type !== 'Identifier')
return
if (declaration.id.typeAnnotation)
return
if (
declaration.init.body.type !== 'BlockStatement'
&& declaration.id?.loc.start.line === declaration.init?.body.loc.end.line
)
return
const arrowFn = declaration.init
const body = declaration.init.body
const id = declaration.id
context.report({
node,
loc: {
start: id.loc.start,
end: body.loc.start,
},
messageId: 'topLevelFunctionDeclaration',
fix(fixer) {
const code = context.getSourceCode().text
const textName = code.slice(id.range[0], id.range[1])
const textArgs = arrowFn.params.length
? code.slice(arrowFn.params[0].range[0], arrowFn.params[arrowFn.params.length - 1].range[1])
: ''
const textBody = body.type === 'BlockStatement'
? code.slice(body.range[0], body.range[1])
: `{\n return ${code.slice(body.range[0], body.range[1])}\n}`
const textGeneric = arrowFn.typeParameters
? code.slice(arrowFn.typeParameters.range[0], arrowFn.typeParameters.range[1])
: ''
const textTypeReturn = arrowFn.returnType
? code.slice(arrowFn.returnType.range[0], arrowFn.returnType.range[1])
: ''
const textAsync = arrowFn.async ? 'async ' : ''
const final = `${textAsync}function ${textName} ${textGeneric}(${textArgs})${textTypeReturn} ${textBody}`
// console.log({
// input: code.slice(node.range[0], node.range[1]),
// output: final,
// })
return fixer.replaceTextRange([node.range[0], node.range[1]], final)
},
})
},
}
},
})

View File

@ -0,0 +1,5 @@
import { ESLintUtils } from '@typescript-eslint/utils'
export const createEslintRule = ESLintUtils.RuleCreator(
ruleName => ruleName,
)

View File

@ -0,0 +1,7 @@
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
globals: true,
},
})

View File

@ -1,14 +0,0 @@
module.exports = {
parser: 'vue-eslint-parser',
parserOptions: {
parser: '@typescript-eslint/parser',
},
extends: [
'@antfu/eslint-config',
'plugin:vue/recommended',
],
plugins: [
'vue'
],
rules: {}
}

4175
pnpm-lock.yaml Normal file

File diff suppressed because it is too large Load Diff

2
pnpm-workspace.yaml Normal file
View File

@ -0,0 +1,2 @@
packages:
- 'packages/*'

15
tsconfig.json Normal file
View File

@ -0,0 +1,15 @@
{
"compilerOptions": {
"baseUrl": ".",
"target": "es2020",
"module": "es2020",
"moduleResolution": "Bundler",
"esModuleInterop": true
},
"include": [
"./packages/**/*.ts"
],
"exclude": [
"./fixtures/**/*.*"
]
}