pasika 0.7.1 → 0.7.3
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/eslint/pasika/index.js +46 -46
- package/package.json +3 -3
|
@@ -4630,12 +4630,30 @@ var referenceBlockHeadingsRule = {
|
|
|
4630
4630
|
};
|
|
4631
4631
|
|
|
4632
4632
|
// eslint/rules/documentation/support-document-placement.ts
|
|
4633
|
+
import { existsSync as existsSync2 } from "fs";
|
|
4633
4634
|
import path39 from "path";
|
|
4635
|
+
function checkPlacement(filename, kind) {
|
|
4636
|
+
const parentFolder = path39.basename(path39.dirname(filename));
|
|
4637
|
+
const expectedParent = `${kind}s`;
|
|
4638
|
+
if (parentFolder !== expectedParent) {
|
|
4639
|
+
return `${kind} lives in "${parentFolder}/" instead of "${expectedParent}/"`;
|
|
4640
|
+
}
|
|
4641
|
+
const guideFolderPath = path39.dirname(path39.dirname(filename));
|
|
4642
|
+
const guideFolder = path39.basename(guideFolderPath);
|
|
4643
|
+
if (!guideFolder.endsWith("-guide")) {
|
|
4644
|
+
return `${kind} owner folder "${guideFolder}/" does not use the "*-guide/" suffix`;
|
|
4645
|
+
}
|
|
4646
|
+
const entryPoint = `${guideFolder}.md`;
|
|
4647
|
+
if (!existsSync2(path39.join(guideFolderPath, entryPoint))) {
|
|
4648
|
+
return `${kind} owner folder "${guideFolder}/" has no "${entryPoint}" entry point`;
|
|
4649
|
+
}
|
|
4650
|
+
return void 0;
|
|
4651
|
+
}
|
|
4634
4652
|
var supportDocumentPlacementRule = {
|
|
4635
4653
|
meta: {
|
|
4636
4654
|
type: "problem",
|
|
4637
4655
|
docs: {
|
|
4638
|
-
description: "Rules must
|
|
4656
|
+
description: "Rules and references must belong to a guide with a matching entry point.",
|
|
4639
4657
|
recommended: true
|
|
4640
4658
|
}
|
|
4641
4659
|
},
|
|
@@ -4644,17 +4662,15 @@ var supportDocumentPlacementRule = {
|
|
|
4644
4662
|
root(node) {
|
|
4645
4663
|
const filename = getFilename(context);
|
|
4646
4664
|
if (!filename.endsWith(".md")) return;
|
|
4647
|
-
|
|
4648
|
-
if (filename.endsWith("-rule.md")
|
|
4649
|
-
|
|
4650
|
-
|
|
4651
|
-
|
|
4652
|
-
|
|
4653
|
-
}
|
|
4654
|
-
if (filename.endsWith("-reference.md") && parentFolder !== "references") {
|
|
4665
|
+
let kind;
|
|
4666
|
+
if (filename.endsWith("-rule.md")) kind = "rule";
|
|
4667
|
+
if (filename.endsWith("-reference.md")) kind = "reference";
|
|
4668
|
+
if (!kind) return;
|
|
4669
|
+
const message = checkPlacement(filename, kind);
|
|
4670
|
+
if (message) {
|
|
4655
4671
|
context.report({
|
|
4656
4672
|
node,
|
|
4657
|
-
message
|
|
4673
|
+
message
|
|
4658
4674
|
});
|
|
4659
4675
|
}
|
|
4660
4676
|
}
|
|
@@ -5072,7 +5088,7 @@ var glossaryTermLinkingRule = {
|
|
|
5072
5088
|
};
|
|
5073
5089
|
|
|
5074
5090
|
// eslint/rules/documentation/guide-mentions-documents.ts
|
|
5075
|
-
import { existsSync as
|
|
5091
|
+
import { existsSync as existsSync3 } from "fs";
|
|
5076
5092
|
import path43 from "path";
|
|
5077
5093
|
function visitSteps3(node, check) {
|
|
5078
5094
|
if (node.type === "list" && node.ordered) {
|
|
@@ -5139,7 +5155,7 @@ var guideMentionsDocumentsRule = {
|
|
|
5139
5155
|
const target = linkTarget(link.url);
|
|
5140
5156
|
if (!target.endsWith(".md")) continue;
|
|
5141
5157
|
const resolved = path43.normalize(path43.join(guideDir, target));
|
|
5142
|
-
if (!
|
|
5158
|
+
if (!existsSync3(resolved)) {
|
|
5143
5159
|
context.report({
|
|
5144
5160
|
node: link,
|
|
5145
5161
|
message: `Guide links a document that does not exist: ${link.url}`
|
|
@@ -6183,7 +6199,7 @@ var nextjsStackRule = {
|
|
|
6183
6199
|
};
|
|
6184
6200
|
|
|
6185
6201
|
// eslint/rules/package-json/vitest-coverage.ts
|
|
6186
|
-
import { existsSync as
|
|
6202
|
+
import { existsSync as existsSync4, readFileSync as readFileSync9 } from "fs";
|
|
6187
6203
|
import path47 from "path";
|
|
6188
6204
|
function memberName5(member) {
|
|
6189
6205
|
return member.name.type === "String" ? member.name.value : member.name.name;
|
|
@@ -6209,18 +6225,12 @@ var SOURCE_GLOB_PATTERN2 = /(?:^|[^a-z])(?:[cm]?[jt]sx?)(?:[^a-z]|$)/i;
|
|
|
6209
6225
|
var COVERAGE_FLAG_PATTERN = /(?:^|\s)--coverage(?:[=\s]|$)/;
|
|
6210
6226
|
var RELATED_PATTERN = /\brelated\b/;
|
|
6211
6227
|
var AUTO_UPDATE_PATTERN = /autoUpdate\s*:\s*true/;
|
|
6212
|
-
var CHANGED_FLAG_PATTERN = /--coverage\.changed\b/;
|
|
6213
|
-
var PER_FILE_FLAG_PATTERN = /--coverage\.thresholds\.perFile\b/;
|
|
6214
|
-
var AUTO_UPDATE_DISABLED_FLAG_PATTERN = /--coverage\.thresholds\.autoUpdate=false\b/;
|
|
6215
|
-
function hasEightyOrAboveFlag(command, metric) {
|
|
6216
|
-
return new RegExp(`--coverage\\.thresholds\\.${metric}=(?:8\\d|9\\d|100)\\b`).test(command);
|
|
6217
|
-
}
|
|
6218
6228
|
var vitestCoverageRule = {
|
|
6219
6229
|
meta: {
|
|
6220
6230
|
schema: [],
|
|
6221
6231
|
type: "problem",
|
|
6222
6232
|
docs: {
|
|
6223
|
-
description: "Require Vitest unit-test scripts, the V8 provider, a rising coverage threshold, and
|
|
6233
|
+
description: "Require Vitest unit-test scripts, the V8 provider, a rising aggregate coverage threshold, and related tests via lint-staged."
|
|
6224
6234
|
}
|
|
6225
6235
|
},
|
|
6226
6236
|
create(context) {
|
|
@@ -6259,7 +6269,7 @@ var vitestCoverageRule = {
|
|
|
6259
6269
|
message: 'package.json must declare a "test:unit:coverage" script that runs Vitest with coverage.'
|
|
6260
6270
|
});
|
|
6261
6271
|
}
|
|
6262
|
-
const configName = VITEST_CONFIG_NAMES.find((name) =>
|
|
6272
|
+
const configName = VITEST_CONFIG_NAMES.find((name) => existsSync4(path47.join(context.cwd, name)));
|
|
6263
6273
|
if (!configName) {
|
|
6264
6274
|
context.report({
|
|
6265
6275
|
node,
|
|
@@ -6279,32 +6289,22 @@ var vitestCoverageRule = {
|
|
|
6279
6289
|
message: `${configName} must set coverage.thresholds.autoUpdate to true.`
|
|
6280
6290
|
});
|
|
6281
6291
|
}
|
|
6282
|
-
const
|
|
6283
|
-
const
|
|
6284
|
-
if (
|
|
6292
|
+
const stagedTests = scriptMembers.find((member) => memberName5(member) === "test:unit:staged");
|
|
6293
|
+
const stagedTestsCommand = memberValue3(stagedTests);
|
|
6294
|
+
if (stagedTestsCommand === void 0 || !/\bvitest\b/.test(stagedTestsCommand) || !RELATED_PATTERN.test(stagedTestsCommand) || COVERAGE_FLAG_PATTERN.test(stagedTestsCommand)) {
|
|
6285
6295
|
context.report({
|
|
6286
|
-
node:
|
|
6287
|
-
message: 'package.json must declare a "test:unit:
|
|
6296
|
+
node: stagedTests ?? node,
|
|
6297
|
+
message: 'package.json must declare a "test:unit:staged" script that runs vitest related without coverage.'
|
|
6288
6298
|
});
|
|
6289
6299
|
}
|
|
6290
6300
|
const lintStaged = root.members.find((member) => memberName5(member) === "lint-staged");
|
|
6291
|
-
const
|
|
6292
|
-
(member) => SOURCE_GLOB_PATTERN2.test(memberName5(member)) && stringValues2(member.value).some((command) => command.includes("npm run test:unit:
|
|
6301
|
+
const hasStagedTests = lintStaged?.value.type === "Object" && lintStaged.value.members.some(
|
|
6302
|
+
(member) => SOURCE_GLOB_PATTERN2.test(memberName5(member)) && stringValues2(member.value).some((command) => command.includes("npm run test:unit:staged"))
|
|
6293
6303
|
);
|
|
6294
|
-
if (!
|
|
6304
|
+
if (!hasStagedTests) {
|
|
6295
6305
|
context.report({
|
|
6296
6306
|
node: lintStaged ?? node,
|
|
6297
|
-
message: 'package.json lint-staged must run "npm run test:unit:
|
|
6298
|
-
});
|
|
6299
|
-
}
|
|
6300
|
-
const changedCoverageCommandText = changedCoverageCommand ?? "";
|
|
6301
|
-
const hasEightyFloor = THRESHOLD_METRICS.every(
|
|
6302
|
-
(metric) => hasEightyOrAboveFlag(changedCoverageCommandText, metric)
|
|
6303
|
-
);
|
|
6304
|
-
if (!CHANGED_FLAG_PATTERN.test(changedCoverageCommandText) || !PER_FILE_FLAG_PATTERN.test(changedCoverageCommandText) || !hasEightyFloor || !AUTO_UPDATE_DISABLED_FLAG_PATTERN.test(changedCoverageCommandText)) {
|
|
6305
|
-
context.report({
|
|
6306
|
-
node: changedCoverage ?? node,
|
|
6307
|
-
message: 'package.json "test:unit:coverage:staged" script must pass --coverage.changed, a --coverage.thresholds.perFile of at least 80 for lines, functions, branches, and statements, and --coverage.thresholds.autoUpdate=false.'
|
|
6307
|
+
message: 'package.json lint-staged must run "npm run test:unit:staged" for staged JavaScript or TypeScript files.'
|
|
6308
6308
|
});
|
|
6309
6309
|
}
|
|
6310
6310
|
}
|
|
@@ -6324,7 +6324,7 @@ var nextjsPackageJsonRules = {
|
|
|
6324
6324
|
};
|
|
6325
6325
|
|
|
6326
6326
|
// eslint/rules/husky/husky-hook.ts
|
|
6327
|
-
import { existsSync as
|
|
6327
|
+
import { existsSync as existsSync5, readFileSync as readFileSync10 } from "fs";
|
|
6328
6328
|
import path48 from "path";
|
|
6329
6329
|
function memberName6(member) {
|
|
6330
6330
|
return member.name.type === "String" ? member.name.value : member.name.name;
|
|
@@ -6344,7 +6344,7 @@ var huskyHookRule = {
|
|
|
6344
6344
|
if (root.type !== "Object") return;
|
|
6345
6345
|
if (!context.filename.endsWith("package.json")) return;
|
|
6346
6346
|
const hookPath = path48.join(context.cwd, ".husky", "pre-commit");
|
|
6347
|
-
if (!
|
|
6347
|
+
if (!existsSync5(hookPath)) {
|
|
6348
6348
|
context.report({
|
|
6349
6349
|
node,
|
|
6350
6350
|
message: "No .husky/pre-commit hook found. Configure husky to run checks before commits."
|
|
@@ -6370,7 +6370,7 @@ var huskyHookRule = {
|
|
|
6370
6370
|
context.report({ node, message: ".husky/pre-commit must run npx libyear --limit-major-individual=1." });
|
|
6371
6371
|
}
|
|
6372
6372
|
const suppressionsPath = path48.join(context.cwd, "eslint-suppressions.json");
|
|
6373
|
-
if (
|
|
6373
|
+
if (existsSync5(suppressionsPath)) {
|
|
6374
6374
|
requireNamedScript("lint:prune");
|
|
6375
6375
|
}
|
|
6376
6376
|
if (scripts?.value.type === "Object") {
|
|
@@ -6393,7 +6393,7 @@ var huskyRules = {
|
|
|
6393
6393
|
};
|
|
6394
6394
|
|
|
6395
6395
|
// eslint/rules/vulyk/vulyk-docs.ts
|
|
6396
|
-
import { existsSync as
|
|
6396
|
+
import { existsSync as existsSync6, readFileSync as readFileSync11 } from "fs";
|
|
6397
6397
|
import path49 from "path";
|
|
6398
6398
|
var PASIKA_REPO = "Bredansky/pasika";
|
|
6399
6399
|
var BASE_REQUIRED_DOCS = [
|
|
@@ -6429,7 +6429,7 @@ var vulykDocsRule = {
|
|
|
6429
6429
|
if (root.type !== "Object") return;
|
|
6430
6430
|
const projectRoot = path49.dirname(path49.resolve(context.filename));
|
|
6431
6431
|
const configPath = path49.join(projectRoot, "vulyk.config.ts");
|
|
6432
|
-
if (!
|
|
6432
|
+
if (!existsSync6(configPath)) {
|
|
6433
6433
|
context.report({
|
|
6434
6434
|
node,
|
|
6435
6435
|
message: "No vulyk.config.ts found. Run npx vulyk@latest init to create one that tracks the framework's docs."
|
|
@@ -6454,7 +6454,7 @@ var vulykDocsRule = {
|
|
|
6454
6454
|
}
|
|
6455
6455
|
}
|
|
6456
6456
|
const agentsPath = path49.join(projectRoot, "AGENTS.md");
|
|
6457
|
-
if (!
|
|
6457
|
+
if (!existsSync6(agentsPath)) {
|
|
6458
6458
|
context.report({
|
|
6459
6459
|
node,
|
|
6460
6460
|
message: "No AGENTS.md found. Run npx vulyk@latest agents to generate the agent file that routes to the tracked docs."
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pasika",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.3",
|
|
4
4
|
"description": "Reusable agent setup package",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -30,14 +30,14 @@
|
|
|
30
30
|
"prepare": "husky",
|
|
31
31
|
"test:unit": "vitest run",
|
|
32
32
|
"test:unit:coverage": "vitest run --coverage",
|
|
33
|
-
"test:unit:
|
|
33
|
+
"test:unit:staged": "vitest related --run",
|
|
34
34
|
"typecheck": "tsc --noEmit"
|
|
35
35
|
},
|
|
36
36
|
"lint-staged": {
|
|
37
37
|
"!(*.ts|*.mts|*.cts|*.tsx|*.js|*.cjs|*.mjs|*.jsx)": "npm run format:staged --",
|
|
38
38
|
"*.ts|*.mts|*.cts|*.tsx|*.js|*.cjs|*.mjs|*.jsx": [
|
|
39
39
|
"npm run lint:staged --",
|
|
40
|
-
"npm run test:unit:
|
|
40
|
+
"npm run test:unit:staged --"
|
|
41
41
|
]
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|