pasika 0.7.4 → 0.7.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -8
- package/dist/eslint/pasika/index.d.ts +2 -2
- package/dist/eslint/pasika/index.js +68 -53
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -198,14 +198,14 @@ Applied to `src/**/globals.css` (and other stylesheets) through `@eslint/css` wi
|
|
|
198
198
|
|
|
199
199
|
### Package.json rules
|
|
200
200
|
|
|
201
|
-
Applied to `package.json` through `@eslint/json`. The framework-agnostic
|
|
202
|
-
|
|
203
|
-
| Rule
|
|
204
|
-
|
|
|
205
|
-
| `pasika/
|
|
206
|
-
| `pasika/
|
|
207
|
-
| `pasika/
|
|
208
|
-
| `pasika/vulyk-docs`
|
|
201
|
+
Applied to `package.json` through `@eslint/json`. The framework-agnostic `exact-version` rule applies to any repository, including pasika itself; `nextjs-stack` applies to a Next.js/React application, and the Vulyk rules apply to a repository adopting the framework.
|
|
202
|
+
|
|
203
|
+
| Rule | Enforces |
|
|
204
|
+
| ------------------------- | ----------------------------------------------------------------------------------- |
|
|
205
|
+
| `pasika/exact-version` | Dependency and devDependency versions are pinned exactly, never ranges |
|
|
206
|
+
| `pasika/nextjs-stack` | All Tech Stack Reference packages are listed in `package.json` (Next.js/React apps) |
|
|
207
|
+
| `pasika/vulyk-dependency` | `vulyk` is listed in `devDependencies`, not `dependencies` |
|
|
208
|
+
| `pasika/vulyk-docs` | `vulyk.config.ts` tracks the framework's docs from pasika and `AGENTS.md` exists |
|
|
209
209
|
|
|
210
210
|
### Documentation rules
|
|
211
211
|
|
|
@@ -118,7 +118,6 @@ declare const tailwindRules: {
|
|
|
118
118
|
|
|
119
119
|
/** Framework-agnostic package.json rules any repository should follow. */
|
|
120
120
|
declare const repoPackageJsonRules: {
|
|
121
|
-
"no-vulyk-dependency": _eslint_json.JSONRuleDefinition;
|
|
122
121
|
"exact-version": _eslint_json.JSONRuleDefinition;
|
|
123
122
|
"lint-setup": _eslint_json.JSONRuleDefinition;
|
|
124
123
|
"vitest-coverage": _eslint_json.JSONRuleDefinition;
|
|
@@ -133,6 +132,7 @@ declare const huskyRules: {
|
|
|
133
132
|
};
|
|
134
133
|
|
|
135
134
|
declare const vulykRules: {
|
|
135
|
+
"vulyk-dependency": _eslint_json.JSONRuleDefinition;
|
|
136
136
|
"vulyk-docs": _eslint_json.JSONRuleDefinition;
|
|
137
137
|
};
|
|
138
138
|
|
|
@@ -145,10 +145,10 @@ declare const vulykRules: {
|
|
|
145
145
|
*/
|
|
146
146
|
declare const pasikaPlugin: {
|
|
147
147
|
rules: {
|
|
148
|
+
"vulyk-dependency": _eslint_json.JSONRuleDefinition;
|
|
148
149
|
"vulyk-docs": _eslint_json.JSONRuleDefinition;
|
|
149
150
|
"husky-hook": _eslint_json.JSONRuleDefinition;
|
|
150
151
|
"nextjs-stack": _eslint_json.JSONRuleDefinition;
|
|
151
|
-
"no-vulyk-dependency": _eslint_json.JSONRuleDefinition;
|
|
152
152
|
"exact-version": _eslint_json.JSONRuleDefinition;
|
|
153
153
|
"lint-setup": _eslint_json.JSONRuleDefinition;
|
|
154
154
|
"vitest-coverage": _eslint_json.JSONRuleDefinition;
|
|
@@ -6100,39 +6100,6 @@ var lintSetupRule = {
|
|
|
6100
6100
|
}
|
|
6101
6101
|
};
|
|
6102
6102
|
|
|
6103
|
-
// eslint/rules/package-json/no-vulyk-dependency.ts
|
|
6104
|
-
function memberName3(member) {
|
|
6105
|
-
return member.name.type === "String" ? member.name.value : member.name.name;
|
|
6106
|
-
}
|
|
6107
|
-
var noVulykDependencyRule = {
|
|
6108
|
-
meta: {
|
|
6109
|
-
schema: [],
|
|
6110
|
-
type: "problem",
|
|
6111
|
-
docs: {
|
|
6112
|
-
description: "Require vulyk to run as an ephemeral command, not a package.json dependency."
|
|
6113
|
-
}
|
|
6114
|
-
},
|
|
6115
|
-
create(context) {
|
|
6116
|
-
return {
|
|
6117
|
-
Document(node) {
|
|
6118
|
-
const root = node.body;
|
|
6119
|
-
if (root.type !== "Object") return;
|
|
6120
|
-
for (const key of ["dependencies", "devDependencies"]) {
|
|
6121
|
-
const section = root.members.find((member) => memberName3(member) === key);
|
|
6122
|
-
if (section?.value.type !== "Object") continue;
|
|
6123
|
-
const vulyk = section.value.members.find((member) => memberName3(member) === "vulyk");
|
|
6124
|
-
if (vulyk) {
|
|
6125
|
-
context.report({
|
|
6126
|
-
node: vulyk,
|
|
6127
|
-
message: 'Vulyk must not be a package.json dependency. Run it as "npx vulyk@latest" instead.'
|
|
6128
|
-
});
|
|
6129
|
-
}
|
|
6130
|
-
}
|
|
6131
|
-
}
|
|
6132
|
-
};
|
|
6133
|
-
}
|
|
6134
|
-
};
|
|
6135
|
-
|
|
6136
6103
|
// eslint/rules/package-json/nextjs-stack.ts
|
|
6137
6104
|
var NEXTJS_STACK_DEPENDENCIES = [
|
|
6138
6105
|
"next",
|
|
@@ -6156,13 +6123,13 @@ var NEXTJS_STACK_DEV_DEPENDENCIES = [
|
|
|
6156
6123
|
"@testing-library/react",
|
|
6157
6124
|
"@testing-library/dom"
|
|
6158
6125
|
];
|
|
6159
|
-
function
|
|
6126
|
+
function memberName3(member) {
|
|
6160
6127
|
return member.name.type === "String" ? member.name.value : member.name.name;
|
|
6161
6128
|
}
|
|
6162
6129
|
function sectionPackages(root, section) {
|
|
6163
|
-
const member = root.type === "Object" ? root.members.find((entry) =>
|
|
6130
|
+
const member = root.type === "Object" ? root.members.find((entry) => memberName3(entry) === section) : void 0;
|
|
6164
6131
|
if (member?.value.type !== "Object") return /* @__PURE__ */ new Set();
|
|
6165
|
-
return new Set(member.value.members.map(
|
|
6132
|
+
return new Set(member.value.members.map(memberName3));
|
|
6166
6133
|
}
|
|
6167
6134
|
var nextjsStackRule = {
|
|
6168
6135
|
meta: {
|
|
@@ -6201,7 +6168,7 @@ var nextjsStackRule = {
|
|
|
6201
6168
|
// eslint/rules/package-json/vitest-coverage.ts
|
|
6202
6169
|
import { existsSync as existsSync4, readFileSync as readFileSync9 } from "fs";
|
|
6203
6170
|
import path47 from "path";
|
|
6204
|
-
function
|
|
6171
|
+
function memberName4(member) {
|
|
6205
6172
|
return member.name.type === "String" ? member.name.value : member.name.name;
|
|
6206
6173
|
}
|
|
6207
6174
|
function memberValue3(member) {
|
|
@@ -6238,9 +6205,9 @@ var vitestCoverageRule = {
|
|
|
6238
6205
|
Document(node) {
|
|
6239
6206
|
const root = node.body;
|
|
6240
6207
|
if (root.type !== "Object") return;
|
|
6241
|
-
const devDependencies = root.members.find((member) =>
|
|
6208
|
+
const devDependencies = root.members.find((member) => memberName4(member) === "devDependencies");
|
|
6242
6209
|
const devDependencyNames = new Set(
|
|
6243
|
-
devDependencies?.value.type === "Object" ? devDependencies.value.members.map(
|
|
6210
|
+
devDependencies?.value.type === "Object" ? devDependencies.value.members.map(memberName4) : []
|
|
6244
6211
|
);
|
|
6245
6212
|
if (!devDependencyNames.has("vitest")) {
|
|
6246
6213
|
context.report({ node, message: "vitest must be listed in package.json as a devDependency." });
|
|
@@ -6251,9 +6218,9 @@ var vitestCoverageRule = {
|
|
|
6251
6218
|
message: "@vitest/coverage-v8 must be listed in package.json as a devDependency."
|
|
6252
6219
|
});
|
|
6253
6220
|
}
|
|
6254
|
-
const scripts = root.members.find((member) =>
|
|
6221
|
+
const scripts = root.members.find((member) => memberName4(member) === "scripts");
|
|
6255
6222
|
const scriptMembers = scripts?.value.type === "Object" ? scripts.value.members : [];
|
|
6256
|
-
const unit = scriptMembers.find((member) =>
|
|
6223
|
+
const unit = scriptMembers.find((member) => memberName4(member) === "test:unit");
|
|
6257
6224
|
const unitCommand = memberValue3(unit);
|
|
6258
6225
|
if (unitCommand === void 0 || !/\bvitest\b/.test(unitCommand) || COVERAGE_FLAG_PATTERN.test(unitCommand)) {
|
|
6259
6226
|
context.report({
|
|
@@ -6261,7 +6228,7 @@ var vitestCoverageRule = {
|
|
|
6261
6228
|
message: 'package.json must declare a "test:unit" script that runs Vitest without coverage.'
|
|
6262
6229
|
});
|
|
6263
6230
|
}
|
|
6264
|
-
const coverage = scriptMembers.find((member) =>
|
|
6231
|
+
const coverage = scriptMembers.find((member) => memberName4(member) === "test:unit:coverage");
|
|
6265
6232
|
const coverageCommand = memberValue3(coverage);
|
|
6266
6233
|
if (coverageCommand === void 0 || !/\bvitest\b/.test(coverageCommand) || !COVERAGE_FLAG_PATTERN.test(coverageCommand)) {
|
|
6267
6234
|
context.report({
|
|
@@ -6289,7 +6256,7 @@ var vitestCoverageRule = {
|
|
|
6289
6256
|
message: `${configName} must set coverage.thresholds.autoUpdate to true.`
|
|
6290
6257
|
});
|
|
6291
6258
|
}
|
|
6292
|
-
const stagedTests = scriptMembers.find((member) =>
|
|
6259
|
+
const stagedTests = scriptMembers.find((member) => memberName4(member) === "test:unit:staged");
|
|
6293
6260
|
const stagedTestsCommand = memberValue3(stagedTests);
|
|
6294
6261
|
if (stagedTestsCommand === void 0 || !/\bvitest\b/.test(stagedTestsCommand) || !RELATED_PATTERN.test(stagedTestsCommand) || COVERAGE_FLAG_PATTERN.test(stagedTestsCommand)) {
|
|
6295
6262
|
context.report({
|
|
@@ -6297,9 +6264,9 @@ var vitestCoverageRule = {
|
|
|
6297
6264
|
message: 'package.json must declare a "test:unit:staged" script that runs vitest related without coverage.'
|
|
6298
6265
|
});
|
|
6299
6266
|
}
|
|
6300
|
-
const lintStaged = root.members.find((member) =>
|
|
6267
|
+
const lintStaged = root.members.find((member) => memberName4(member) === "lint-staged");
|
|
6301
6268
|
const hasStagedTests = lintStaged?.value.type === "Object" && lintStaged.value.members.some(
|
|
6302
|
-
(member) => SOURCE_GLOB_PATTERN2.test(
|
|
6269
|
+
(member) => SOURCE_GLOB_PATTERN2.test(memberName4(member)) && stringValues2(member.value).some((command) => command.includes("npm run test:unit:staged"))
|
|
6303
6270
|
);
|
|
6304
6271
|
if (!hasStagedTests) {
|
|
6305
6272
|
context.report({
|
|
@@ -6314,7 +6281,6 @@ var vitestCoverageRule = {
|
|
|
6314
6281
|
|
|
6315
6282
|
// eslint/rules/package-json/index.ts
|
|
6316
6283
|
var repoPackageJsonRules = {
|
|
6317
|
-
"no-vulyk-dependency": noVulykDependencyRule,
|
|
6318
6284
|
"exact-version": exactVersionRule,
|
|
6319
6285
|
"lint-setup": lintSetupRule,
|
|
6320
6286
|
"vitest-coverage": vitestCoverageRule
|
|
@@ -6334,7 +6300,7 @@ var VITEST_CONFIG_NAMES2 = [
|
|
|
6334
6300
|
"vitest.config.mjs",
|
|
6335
6301
|
"vitest.config.cjs"
|
|
6336
6302
|
];
|
|
6337
|
-
function
|
|
6303
|
+
function memberName5(member) {
|
|
6338
6304
|
return member.name.type === "String" ? member.name.value : member.name.name;
|
|
6339
6305
|
}
|
|
6340
6306
|
var huskyHookRule = {
|
|
@@ -6342,7 +6308,7 @@ var huskyHookRule = {
|
|
|
6342
6308
|
schema: [],
|
|
6343
6309
|
type: "problem",
|
|
6344
6310
|
docs: {
|
|
6345
|
-
description: "Require a pre-commit hook that runs lint-staged, typecheck, coverage
|
|
6311
|
+
description: "Require a pre-commit hook that runs lint-staged, typecheck, coverage and suppression pruning with local staging, and the libyear drift check."
|
|
6346
6312
|
}
|
|
6347
6313
|
},
|
|
6348
6314
|
create(context) {
|
|
@@ -6360,8 +6326,8 @@ var huskyHookRule = {
|
|
|
6360
6326
|
return;
|
|
6361
6327
|
}
|
|
6362
6328
|
const content = readFileSync10(hookPath, "utf8");
|
|
6363
|
-
const scripts = root.members.find((member) =>
|
|
6364
|
-
const scriptNames = new Set(scripts?.value.type === "Object" ? scripts.value.members.map(
|
|
6329
|
+
const scripts = root.members.find((member) => memberName5(member) === "scripts");
|
|
6330
|
+
const scriptNames = new Set(scripts?.value.type === "Object" ? scripts.value.members.map(memberName5) : []);
|
|
6365
6331
|
const requireNamedScript = (name) => {
|
|
6366
6332
|
if (!scriptNames.has(name)) {
|
|
6367
6333
|
context.report({ node, message: `package.json must declare a "${name}" script.` });
|
|
@@ -6392,9 +6358,17 @@ var huskyHookRule = {
|
|
|
6392
6358
|
const suppressionsPath = path48.join(context.cwd, "eslint-suppressions.json");
|
|
6393
6359
|
if (existsSync5(suppressionsPath)) {
|
|
6394
6360
|
requireNamedScript("lint:prune");
|
|
6361
|
+
const pruneIndex = content.indexOf("npm run lint:prune");
|
|
6362
|
+
const localAddIndex = content.indexOf("git add eslint-suppressions.json");
|
|
6363
|
+
if (localAddIndex <= pruneIndex) {
|
|
6364
|
+
context.report({
|
|
6365
|
+
node,
|
|
6366
|
+
message: ".husky/pre-commit must stage eslint-suppressions.json after pruning suppressions."
|
|
6367
|
+
});
|
|
6368
|
+
}
|
|
6395
6369
|
}
|
|
6396
6370
|
if (scripts?.value.type === "Object") {
|
|
6397
|
-
const prepare = scripts.value.members.find((member) =>
|
|
6371
|
+
const prepare = scripts.value.members.find((member) => memberName5(member) === "prepare");
|
|
6398
6372
|
if (prepare?.value.type === "String" && !prepare.value.value.includes("husky")) {
|
|
6399
6373
|
context.report({
|
|
6400
6374
|
node: prepare,
|
|
@@ -6412,6 +6386,46 @@ var huskyRules = {
|
|
|
6412
6386
|
"husky-hook": huskyHookRule
|
|
6413
6387
|
};
|
|
6414
6388
|
|
|
6389
|
+
// eslint/rules/vulyk/vulyk-dependency.ts
|
|
6390
|
+
function memberName6(member) {
|
|
6391
|
+
return member.name.type === "String" ? member.name.value : member.name.name;
|
|
6392
|
+
}
|
|
6393
|
+
function dependency(root, sectionName) {
|
|
6394
|
+
if (root.type !== "Object") return void 0;
|
|
6395
|
+
const section = root.members.find((member) => memberName6(member) === sectionName);
|
|
6396
|
+
if (section?.value.type !== "Object") return void 0;
|
|
6397
|
+
return section.value.members.find((member) => memberName6(member) === "vulyk");
|
|
6398
|
+
}
|
|
6399
|
+
var vulykDependencyRule = {
|
|
6400
|
+
meta: {
|
|
6401
|
+
schema: [],
|
|
6402
|
+
type: "problem",
|
|
6403
|
+
docs: {
|
|
6404
|
+
description: "Require vulyk in devDependencies so its typed config and CLI use the pinned package."
|
|
6405
|
+
}
|
|
6406
|
+
},
|
|
6407
|
+
create(context) {
|
|
6408
|
+
return {
|
|
6409
|
+
Document(node) {
|
|
6410
|
+
const runtimeDependency = dependency(node.body, "dependencies");
|
|
6411
|
+
const developmentDependency = dependency(node.body, "devDependencies");
|
|
6412
|
+
if (runtimeDependency) {
|
|
6413
|
+
context.report({
|
|
6414
|
+
node: runtimeDependency,
|
|
6415
|
+
message: "vulyk must be listed in devDependencies, not dependencies."
|
|
6416
|
+
});
|
|
6417
|
+
}
|
|
6418
|
+
if (!developmentDependency && !runtimeDependency) {
|
|
6419
|
+
context.report({
|
|
6420
|
+
node,
|
|
6421
|
+
message: "vulyk must be listed in package.json as a devDependency."
|
|
6422
|
+
});
|
|
6423
|
+
}
|
|
6424
|
+
}
|
|
6425
|
+
};
|
|
6426
|
+
}
|
|
6427
|
+
};
|
|
6428
|
+
|
|
6415
6429
|
// eslint/rules/vulyk/vulyk-docs.ts
|
|
6416
6430
|
import { existsSync as existsSync6, readFileSync as readFileSync11 } from "fs";
|
|
6417
6431
|
import path49 from "path";
|
|
@@ -6452,7 +6466,7 @@ var vulykDocsRule = {
|
|
|
6452
6466
|
if (!existsSync6(configPath)) {
|
|
6453
6467
|
context.report({
|
|
6454
6468
|
node,
|
|
6455
|
-
message: "No vulyk.config.ts found. Run npx vulyk
|
|
6469
|
+
message: "No vulyk.config.ts found. Run npx vulyk init to create one that tracks the framework's docs."
|
|
6456
6470
|
});
|
|
6457
6471
|
return;
|
|
6458
6472
|
}
|
|
@@ -6477,7 +6491,7 @@ var vulykDocsRule = {
|
|
|
6477
6491
|
if (!existsSync6(agentsPath)) {
|
|
6478
6492
|
context.report({
|
|
6479
6493
|
node,
|
|
6480
|
-
message: "No AGENTS.md found. Run npx vulyk
|
|
6494
|
+
message: "No AGENTS.md found. Run npx vulyk agents to generate the agent file that routes to the tracked docs."
|
|
6481
6495
|
});
|
|
6482
6496
|
}
|
|
6483
6497
|
}
|
|
@@ -6487,6 +6501,7 @@ var vulykDocsRule = {
|
|
|
6487
6501
|
|
|
6488
6502
|
// eslint/rules/vulyk/index.ts
|
|
6489
6503
|
var vulykRules = {
|
|
6504
|
+
"vulyk-dependency": vulykDependencyRule,
|
|
6490
6505
|
"vulyk-docs": vulykDocsRule
|
|
6491
6506
|
};
|
|
6492
6507
|
|