js-style-kit 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/index.cjs +2 -1
- package/dist/bin/index.cjs.map +1 -1
- package/dist/index.d.ts +13 -3
- package/dist/index.js +87 -29
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
- package/src/eslint/ignores.ts +13 -10
- package/src/eslint/index.ts +32 -18
- package/src/eslint/testing/config.ts +21 -12
- package/src/eslint/testing/get-import-restrictions.ts +70 -0
- package/src/eslint/types.ts +7 -0
package/dist/index.d.ts
CHANGED
|
@@ -39,13 +39,22 @@ interface EslintConfigObject<Rules extends Linter.RulesRecord = Linter.RulesReco
|
|
|
39
39
|
}
|
|
40
40
|
type FilenameCase = "camelCase" | "kebabCase" | "pascalCase" | "snakeCase";
|
|
41
41
|
type FunctionStyle = "arrow" | "declaration" | "expression";
|
|
42
|
+
type ReactFramework = "next" | "none" | "react-router" | "remix" | "vite";
|
|
42
43
|
|
|
43
44
|
interface TestingConfig {
|
|
44
45
|
filenamePattern?: "spec" | "test";
|
|
45
46
|
files?: string[];
|
|
46
47
|
formattingRules?: boolean;
|
|
47
48
|
framework?: "bun" | "jest" | "node" | "vitest";
|
|
49
|
+
/**
|
|
50
|
+
* Whether to enforce imports from the correct testing framework.
|
|
51
|
+
* Uses the built-in ESLint `no-restricted-imports` rule.
|
|
52
|
+
*
|
|
53
|
+
* @default true
|
|
54
|
+
*/
|
|
55
|
+
importRestrictions?: boolean;
|
|
48
56
|
itOrTest?: "it" | "test";
|
|
57
|
+
typescript?: boolean;
|
|
49
58
|
}
|
|
50
59
|
|
|
51
60
|
interface EslintConfigOptions {
|
|
@@ -58,7 +67,7 @@ interface EslintConfigOptions {
|
|
|
58
67
|
};
|
|
59
68
|
query?: boolean;
|
|
60
69
|
react?: boolean | {
|
|
61
|
-
framework?:
|
|
70
|
+
framework?: ReactFramework;
|
|
62
71
|
reactCompiler?: boolean;
|
|
63
72
|
reactRefresh?: boolean;
|
|
64
73
|
};
|
|
@@ -93,8 +102,9 @@ interface EslintConfigOptions {
|
|
|
93
102
|
* @param options.testing - An object with the following properties:
|
|
94
103
|
* - `filenamePattern`: One of "spec" or "test" to determine which filename pattern to use.
|
|
95
104
|
* - `files`: Array of file patterns to include in the configuration.
|
|
96
|
-
* - `framework`: One of "vitest" or "jest" to determine which testing library to use.
|
|
105
|
+
* - `framework`: One of "vitest" or "jest" or "bun" or "node" to determine which testing library to use.
|
|
97
106
|
* - `formattingRules`: Whether to include formatting rules like padding around blocks.
|
|
107
|
+
* - `importRestrictions`: Whether to enforce imports from the correct testing framework.
|
|
98
108
|
* - `itOrTest`: One of "it" or "test" to determine which test function to use.
|
|
99
109
|
* @param options.typescript - Whether to include TypeScript rules. Can be a boolean or a string with path to tsconfig.
|
|
100
110
|
* @param options.turbo - Whether to include Turborepo rules. Defaults to false.
|
|
@@ -137,4 +147,4 @@ interface PrettierConfigWithPlugins extends Config, SortJsonOptions, PluginOptio
|
|
|
137
147
|
*/
|
|
138
148
|
declare const prettierConfig: (options?: PrettierConfigOptions) => PrettierConfigWithPlugins;
|
|
139
149
|
|
|
140
|
-
export { type EslintConfigObject, type EslintConfigOptions, type EslintRuleConfig, type EslintSeverity, type FilenameCase, type FunctionStyle, type PrettierConfigOptions, type PrettierConfigWithPlugins, eslintConfig, prettierConfig };
|
|
150
|
+
export { type EslintConfigObject, type EslintConfigOptions, type EslintRuleConfig, type EslintSeverity, type FilenameCase, type FunctionStyle, type PrettierConfigOptions, type PrettierConfigWithPlugins, type ReactFramework, eslintConfig, prettierConfig };
|
package/dist/index.js
CHANGED
|
@@ -514,13 +514,14 @@ var convexConfig = (customRules) => ({
|
|
|
514
514
|
|
|
515
515
|
// src/eslint/ignores.ts
|
|
516
516
|
var ignoresConfig = ({
|
|
517
|
-
|
|
518
|
-
storybook
|
|
519
|
-
userIgnores
|
|
520
|
-
}
|
|
517
|
+
reactFramework,
|
|
518
|
+
storybook,
|
|
519
|
+
userIgnores
|
|
520
|
+
}) => ({
|
|
521
521
|
ignores: [
|
|
522
522
|
"**/dist/",
|
|
523
|
-
...next ? [".next"] : [],
|
|
523
|
+
...reactFramework === "next" ? [".next"] : [],
|
|
524
|
+
...reactFramework === "react-router" ? [".react-router"] : [],
|
|
524
525
|
...storybook ? ["!.storybook"] : [],
|
|
525
526
|
...userIgnores
|
|
526
527
|
],
|
|
@@ -1158,6 +1159,56 @@ var storybookConfig = (customRules) => [
|
|
|
1158
1159
|
import jest from "eslint-plugin-jest";
|
|
1159
1160
|
import vitest from "eslint-plugin-vitest";
|
|
1160
1161
|
|
|
1162
|
+
// src/eslint/testing/get-import-restrictions.ts
|
|
1163
|
+
var commonTestImports = [
|
|
1164
|
+
"describe",
|
|
1165
|
+
"it",
|
|
1166
|
+
"test",
|
|
1167
|
+
"expect",
|
|
1168
|
+
"beforeAll",
|
|
1169
|
+
"beforeEach",
|
|
1170
|
+
"afterAll",
|
|
1171
|
+
"afterEach",
|
|
1172
|
+
"vi",
|
|
1173
|
+
"mock",
|
|
1174
|
+
"spyOn"
|
|
1175
|
+
];
|
|
1176
|
+
var frameworkConfig = {
|
|
1177
|
+
bun: {
|
|
1178
|
+
allowed: "'bun:test'",
|
|
1179
|
+
restricted: ["vitest", "jest", "@jest/globals", "node:test"]
|
|
1180
|
+
},
|
|
1181
|
+
jest: {
|
|
1182
|
+
allowed: "'jest' or '@jest/globals'",
|
|
1183
|
+
restricted: ["vitest", "bun:test", "node:test"]
|
|
1184
|
+
},
|
|
1185
|
+
node: {
|
|
1186
|
+
allowed: "'node:test'",
|
|
1187
|
+
restricted: ["vitest", "jest", "@jest/globals", "bun:test"]
|
|
1188
|
+
},
|
|
1189
|
+
vitest: {
|
|
1190
|
+
allowed: "'vitest'",
|
|
1191
|
+
restricted: ["jest", "@jest/globals", "bun:test", "node:test"]
|
|
1192
|
+
}
|
|
1193
|
+
};
|
|
1194
|
+
var getRestrictionMessage = (allowedFramework) => `This project is setup to use ${allowedFramework} for testing. Importing from other testing frameworks is not allowed. Change this setting in eslint.config.js under testing.framework`;
|
|
1195
|
+
var getImportRestrictions = (framework) => {
|
|
1196
|
+
const config = frameworkConfig[framework];
|
|
1197
|
+
const message = getRestrictionMessage(config.allowed);
|
|
1198
|
+
return {
|
|
1199
|
+
"no-restricted-imports": [
|
|
1200
|
+
"warn",
|
|
1201
|
+
{
|
|
1202
|
+
paths: config.restricted.map((name) => ({
|
|
1203
|
+
importNames: commonTestImports,
|
|
1204
|
+
message,
|
|
1205
|
+
name
|
|
1206
|
+
}))
|
|
1207
|
+
}
|
|
1208
|
+
]
|
|
1209
|
+
};
|
|
1210
|
+
};
|
|
1211
|
+
|
|
1161
1212
|
// src/eslint/testing/jest-rules.ts
|
|
1162
1213
|
var jestRules = (itOrTest = "test") => ({
|
|
1163
1214
|
"jest/consistent-test-it": [
|
|
@@ -1248,17 +1299,14 @@ var vitestRules = (itOrTest = "test") => ({
|
|
|
1248
1299
|
|
|
1249
1300
|
// src/eslint/testing/config.ts
|
|
1250
1301
|
var testingConfig = ({
|
|
1251
|
-
filenamePattern,
|
|
1302
|
+
filenamePattern = "test",
|
|
1252
1303
|
files,
|
|
1253
|
-
formattingRules,
|
|
1254
|
-
framework,
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
framework: "vitest",
|
|
1260
|
-
itOrTest: "test"
|
|
1261
|
-
}, customRules) => ({
|
|
1304
|
+
formattingRules = true,
|
|
1305
|
+
framework = "vitest",
|
|
1306
|
+
importRestrictions = true,
|
|
1307
|
+
itOrTest = "test",
|
|
1308
|
+
typescript = true
|
|
1309
|
+
} = {}, customRules) => ({
|
|
1262
1310
|
files: files ?? ["**/*.{test,spec}.{ts,tsx,js,jsx}"],
|
|
1263
1311
|
languageOptions: {
|
|
1264
1312
|
globals: framework === "vitest" ? { ...vitest.environments.env.globals } : jest.environments.globals.globals
|
|
@@ -1269,8 +1317,8 @@ var testingConfig = ({
|
|
|
1269
1317
|
vitest
|
|
1270
1318
|
},
|
|
1271
1319
|
rules: {
|
|
1320
|
+
...typescript ? { "@typescript-eslint/unbound-method": "off" } : {},
|
|
1272
1321
|
// jest doesn't have a file name rule, so we'll use this one for both
|
|
1273
|
-
"@typescript-eslint/unbound-method": "off",
|
|
1274
1322
|
"vitest/consistent-test-filename": [
|
|
1275
1323
|
"warn",
|
|
1276
1324
|
{
|
|
@@ -1288,6 +1336,7 @@ var testingConfig = ({
|
|
|
1288
1336
|
"jest/padding-around-expect-groups": "warn",
|
|
1289
1337
|
"jest/padding-around-test-blocks": "warn"
|
|
1290
1338
|
} : {},
|
|
1339
|
+
...importRestrictions ? getImportRestrictions(framework) : {},
|
|
1291
1340
|
...customRules ?? {}
|
|
1292
1341
|
},
|
|
1293
1342
|
...framework !== "jest" && framework !== "vitest" ? {
|
|
@@ -1576,13 +1625,6 @@ var unicornConfig = ({
|
|
|
1576
1625
|
});
|
|
1577
1626
|
|
|
1578
1627
|
// src/eslint/index.ts
|
|
1579
|
-
var defaultTestingConfig = {
|
|
1580
|
-
filenamePattern: "test",
|
|
1581
|
-
files: ["**/*.{test,spec}.{ts,tsx,js,jsx}"],
|
|
1582
|
-
formattingRules: true,
|
|
1583
|
-
framework: "vitest",
|
|
1584
|
-
itOrTest: "it"
|
|
1585
|
-
};
|
|
1586
1628
|
var eslintConfig = ({
|
|
1587
1629
|
convex = false,
|
|
1588
1630
|
functionStyle = "arrow",
|
|
@@ -1594,16 +1636,15 @@ var eslintConfig = ({
|
|
|
1594
1636
|
rules: rules2,
|
|
1595
1637
|
sorting = true,
|
|
1596
1638
|
storybook = false,
|
|
1597
|
-
testing
|
|
1639
|
+
testing,
|
|
1598
1640
|
turbo: turbo2 = false,
|
|
1599
1641
|
typescript = true,
|
|
1600
1642
|
unicorn: unicorn2 = { filenameCase: "kebabCase" }
|
|
1601
1643
|
} = {}, ...additionalConfigs) => {
|
|
1602
1644
|
const categorizedRules = rules2 === void 0 ? {} : processCustomRules(rules2);
|
|
1603
|
-
const usingNextjs = isObject(react2) && react2.framework === "next";
|
|
1604
1645
|
const configs = [
|
|
1605
1646
|
ignoresConfig({
|
|
1606
|
-
|
|
1647
|
+
reactFramework: isObject(react2) && react2.framework ? react2.framework : "none",
|
|
1607
1648
|
storybook,
|
|
1608
1649
|
userIgnores: ignores
|
|
1609
1650
|
}),
|
|
@@ -1654,7 +1695,7 @@ var eslintConfig = ({
|
|
|
1654
1695
|
typescript: Boolean(typescript)
|
|
1655
1696
|
})
|
|
1656
1697
|
);
|
|
1657
|
-
if (
|
|
1698
|
+
if (isObject(react2) && react2.framework === "next") {
|
|
1658
1699
|
configs.push(nextjsConfig(categorizedRules[configNames.nextjs]));
|
|
1659
1700
|
}
|
|
1660
1701
|
}
|
|
@@ -1665,8 +1706,23 @@ var eslintConfig = ({
|
|
|
1665
1706
|
configs.push(convexConfig(categorizedRules[configNames.convex]));
|
|
1666
1707
|
}
|
|
1667
1708
|
if (testing !== false) {
|
|
1709
|
+
const defaultTestingConfig = {
|
|
1710
|
+
filenamePattern: "test",
|
|
1711
|
+
files: ["**/*.{test,spec}.{ts,tsx,js,jsx}"],
|
|
1712
|
+
formattingRules: true,
|
|
1713
|
+
framework: "vitest",
|
|
1714
|
+
importRestrictions: true,
|
|
1715
|
+
itOrTest: "it"
|
|
1716
|
+
};
|
|
1668
1717
|
const mergedTestingConfig = isObject(testing) ? { ...defaultTestingConfig, ...testing } : defaultTestingConfig;
|
|
1669
|
-
const {
|
|
1718
|
+
const {
|
|
1719
|
+
filenamePattern,
|
|
1720
|
+
files,
|
|
1721
|
+
formattingRules,
|
|
1722
|
+
framework,
|
|
1723
|
+
importRestrictions,
|
|
1724
|
+
itOrTest
|
|
1725
|
+
} = mergedTestingConfig;
|
|
1670
1726
|
configs.push(
|
|
1671
1727
|
testingConfig(
|
|
1672
1728
|
{
|
|
@@ -1674,7 +1730,9 @@ var eslintConfig = ({
|
|
|
1674
1730
|
files,
|
|
1675
1731
|
formattingRules,
|
|
1676
1732
|
framework,
|
|
1677
|
-
|
|
1733
|
+
importRestrictions,
|
|
1734
|
+
itOrTest,
|
|
1735
|
+
typescript: Boolean(typescript)
|
|
1678
1736
|
},
|
|
1679
1737
|
categorizedRules[configNames.testing]
|
|
1680
1738
|
)
|