repopo 0.5.0 → 0.7.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/CHANGELOG.md +87 -0
- package/README.md +3 -5
- package/THIRD-PARTY-LICENSES.txt +6 -6
- package/esm/baseCommand.d.ts.map +1 -1
- package/esm/baseCommand.js +7 -9
- package/esm/baseCommand.js.map +1 -1
- package/esm/commands/check.d.ts +17 -6
- package/esm/commands/check.d.ts.map +1 -1
- package/esm/commands/check.js +162 -110
- package/esm/commands/check.js.map +1 -1
- package/esm/commands/list.d.ts.map +1 -1
- package/esm/commands/list.js +0 -1
- package/esm/commands/list.js.map +1 -1
- package/esm/config.d.ts +4 -15
- package/esm/config.d.ts.map +1 -1
- package/esm/config.js +3 -2
- package/esm/config.js.map +1 -1
- package/esm/context.d.ts +3 -3
- package/esm/context.d.ts.map +1 -1
- package/esm/context.js.map +1 -1
- package/esm/generators.d.ts +21 -0
- package/esm/generators.d.ts.map +1 -0
- package/esm/generators.js +2 -0
- package/esm/generators.js.map +1 -0
- package/esm/index.d.ts +5 -11
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +3 -9
- package/esm/index.js.map +1 -1
- package/esm/makePolicy.d.ts +9 -0
- package/esm/makePolicy.d.ts.map +1 -0
- package/esm/makePolicy.js +28 -0
- package/esm/makePolicy.js.map +1 -0
- package/esm/policies/HtmlFileHeaders.d.ts +2 -2
- package/esm/policies/HtmlFileHeaders.d.ts.map +1 -1
- package/esm/policies/HtmlFileHeaders.js +2 -2
- package/esm/policies/HtmlFileHeaders.js.map +1 -1
- package/esm/policies/JsTsFileHeaders.d.ts +2 -2
- package/esm/policies/JsTsFileHeaders.d.ts.map +1 -1
- package/esm/policies/JsTsFileHeaders.js +2 -2
- package/esm/policies/JsTsFileHeaders.js.map +1 -1
- package/esm/policies/LicenseFileExists.d.ts +20 -0
- package/esm/policies/LicenseFileExists.d.ts.map +1 -0
- package/esm/policies/LicenseFileExists.js +40 -0
- package/esm/policies/LicenseFileExists.js.map +1 -0
- package/esm/policies/NoJsFileExtensions.d.ts +2 -2
- package/esm/policies/NoJsFileExtensions.d.ts.map +1 -1
- package/esm/policies/NoJsFileExtensions.js +11 -15
- package/esm/policies/NoJsFileExtensions.js.map +1 -1
- package/esm/policies/NoLargeBinaryFiles.d.ts +30 -0
- package/esm/policies/NoLargeBinaryFiles.d.ts.map +1 -0
- package/esm/policies/NoLargeBinaryFiles.js +118 -0
- package/esm/policies/NoLargeBinaryFiles.js.map +1 -0
- package/esm/policies/PackageJsonProperties.d.ts +1 -1
- package/esm/policies/PackageJsonProperties.d.ts.map +1 -1
- package/esm/policies/PackageJsonProperties.js +3 -3
- package/esm/policies/PackageJsonProperties.js.map +1 -1
- package/esm/policies/PackageJsonRepoDirectoryProperty.d.ts +1 -1
- package/esm/policies/PackageJsonRepoDirectoryProperty.d.ts.map +1 -1
- package/esm/policies/PackageJsonRepoDirectoryProperty.js +24 -25
- package/esm/policies/PackageJsonRepoDirectoryProperty.js.map +1 -1
- package/esm/policies/PackageJsonSorted.d.ts +1 -1
- package/esm/policies/PackageJsonSorted.d.ts.map +1 -1
- package/esm/policies/PackageJsonSorted.js +3 -2
- package/esm/policies/PackageJsonSorted.js.map +1 -1
- package/esm/policies/PackageScripts.d.ts +25 -2
- package/esm/policies/PackageScripts.d.ts.map +1 -1
- package/esm/policies/PackageScripts.js +47 -10
- package/esm/policies/PackageScripts.js.map +1 -1
- package/esm/policies/RequiredGitignorePatterns.d.ts +24 -0
- package/esm/policies/RequiredGitignorePatterns.d.ts.map +1 -0
- package/esm/policies/RequiredGitignorePatterns.js +166 -0
- package/esm/policies/RequiredGitignorePatterns.js.map +1 -0
- package/esm/policies.d.ts +8 -3
- package/esm/policies.d.ts.map +1 -1
- package/esm/policies.js +8 -3
- package/esm/policies.js.map +1 -1
- package/esm/policy.d.ts +40 -13
- package/esm/policy.d.ts.map +1 -1
- package/esm/policy.js +18 -7
- package/esm/policy.js.map +1 -1
- package/esm/{policyGenerators/generateFileHeaderPolicy.d.ts → policyDefiners/defineFileHeaderPolicy.d.ts} +4 -4
- package/esm/policyDefiners/defineFileHeaderPolicy.d.ts.map +1 -0
- package/esm/{policyGenerators/generateFileHeaderPolicy.js → policyDefiners/defineFileHeaderPolicy.js} +3 -3
- package/esm/policyDefiners/defineFileHeaderPolicy.js.map +1 -0
- package/esm/policyDefiners/definePackagePolicy.d.ts +15 -0
- package/esm/policyDefiners/definePackagePolicy.d.ts.map +1 -0
- package/esm/{policyGenerators/generatePackagePolicy.js → policyDefiners/definePackagePolicy.js} +2 -2
- package/esm/policyDefiners/definePackagePolicy.js.map +1 -0
- package/esm/tsdoc-metadata.json +1 -1
- package/oclif.manifest.json +1 -1
- package/package.json +36 -31
- package/esm/policyGenerators/generateFileHeaderPolicy.d.ts.map +0 -1
- package/esm/policyGenerators/generateFileHeaderPolicy.js.map +0 -1
- package/esm/policyGenerators/generatePackagePolicy.d.ts +0 -9
- package/esm/policyGenerators/generatePackagePolicy.d.ts.map +0 -1
- package/esm/policyGenerators/generatePackagePolicy.js.map +0 -1
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import path from "pathe";
|
|
3
|
+
import { makePolicyDefinition } from "../makePolicy.js";
|
|
4
|
+
/**
|
|
5
|
+
* Default patterns that should typically be in .gitignore files.
|
|
6
|
+
*/
|
|
7
|
+
const DEFAULT_PATTERNS = [
|
|
8
|
+
{ pattern: "node_modules/", comment: "Dependencies" },
|
|
9
|
+
{ pattern: ".env", comment: "Environment files" },
|
|
10
|
+
{ pattern: ".env.*", comment: "Environment files" },
|
|
11
|
+
{ pattern: "!.env.example", comment: "Allow example env file" },
|
|
12
|
+
{ pattern: "dist/", comment: "Build output" },
|
|
13
|
+
{ pattern: "build/", comment: "Build output" },
|
|
14
|
+
{ pattern: ".DS_Store", comment: "macOS system files" },
|
|
15
|
+
{ pattern: "Thumbs.db", comment: "Windows system files" },
|
|
16
|
+
];
|
|
17
|
+
/**
|
|
18
|
+
* Check if a pattern exists in gitignore content.
|
|
19
|
+
* Handles patterns with inline comments (e.g., "node_modules/ # comment").
|
|
20
|
+
*/
|
|
21
|
+
function patternExists(lines, pattern) {
|
|
22
|
+
return lines.some((line) => {
|
|
23
|
+
const trimmed = line.trim();
|
|
24
|
+
// Remove inline comments (everything after # that's not escaped)
|
|
25
|
+
const withoutComment = trimmed.split("#")[0]?.trim() ?? "";
|
|
26
|
+
return (withoutComment === pattern ||
|
|
27
|
+
trimmed === pattern ||
|
|
28
|
+
trimmed.startsWith(`${pattern} `) ||
|
|
29
|
+
trimmed.startsWith(`${pattern}\t`));
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Find missing patterns in gitignore content.
|
|
34
|
+
*/
|
|
35
|
+
function findMissingPatterns(patterns, lines) {
|
|
36
|
+
const missingPatterns = [];
|
|
37
|
+
for (const patternConfig of patterns) {
|
|
38
|
+
const pattern = typeof patternConfig === "string" ? patternConfig : patternConfig.pattern;
|
|
39
|
+
if (!patternExists(lines, pattern)) {
|
|
40
|
+
missingPatterns.push(patternConfig);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return missingPatterns;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Add patterns to gitignore content.
|
|
47
|
+
*/
|
|
48
|
+
function addPatternsToContent(content, missingPatterns) {
|
|
49
|
+
let newContent = content;
|
|
50
|
+
// Ensure file ends with newline
|
|
51
|
+
if (!newContent.endsWith("\n")) {
|
|
52
|
+
newContent += "\n";
|
|
53
|
+
}
|
|
54
|
+
// Add a section header if we're adding patterns
|
|
55
|
+
if (missingPatterns.length > 0) {
|
|
56
|
+
newContent += "\n# Added by repopo RequiredGitignorePatterns policy\n";
|
|
57
|
+
}
|
|
58
|
+
// Add each missing pattern
|
|
59
|
+
for (const patternConfig of missingPatterns) {
|
|
60
|
+
if (typeof patternConfig === "string") {
|
|
61
|
+
newContent += `${patternConfig}\n`;
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
if (patternConfig.comment) {
|
|
65
|
+
newContent += `# ${patternConfig.comment}\n`;
|
|
66
|
+
}
|
|
67
|
+
newContent += `${patternConfig.pattern}\n`;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return newContent;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Create gitignore content from scratch.
|
|
74
|
+
*/
|
|
75
|
+
function createGitignoreContent(patterns) {
|
|
76
|
+
let content = "# Generated by repopo RequiredGitignorePatterns policy\n\n";
|
|
77
|
+
for (const patternConfig of patterns) {
|
|
78
|
+
if (typeof patternConfig === "string") {
|
|
79
|
+
content += `${patternConfig}\n`;
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
if (patternConfig.comment) {
|
|
83
|
+
content += `# ${patternConfig.comment}\n`;
|
|
84
|
+
}
|
|
85
|
+
content += `${patternConfig.pattern}\n`;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return content;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Handle the case when .gitignore exists.
|
|
92
|
+
*/
|
|
93
|
+
function handleExistingGitignore(filePath, patterns, file, resolve) {
|
|
94
|
+
const gitignoreContent = readFileSync(filePath, "utf-8");
|
|
95
|
+
const lines = gitignoreContent.split("\n");
|
|
96
|
+
const missingPatterns = findMissingPatterns(patterns, lines);
|
|
97
|
+
if (missingPatterns.length === 0) {
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
const result = {
|
|
101
|
+
name: RequiredGitignorePatterns.name,
|
|
102
|
+
file,
|
|
103
|
+
autoFixable: true,
|
|
104
|
+
errorMessage: `Missing required .gitignore patterns: ${missingPatterns.map((p) => (typeof p === "string" ? p : p.pattern)).join(", ")}`,
|
|
105
|
+
};
|
|
106
|
+
if (resolve) {
|
|
107
|
+
const fixResult = {
|
|
108
|
+
...result,
|
|
109
|
+
resolved: false,
|
|
110
|
+
};
|
|
111
|
+
try {
|
|
112
|
+
const newContent = addPatternsToContent(gitignoreContent, missingPatterns);
|
|
113
|
+
writeFileSync(filePath, newContent);
|
|
114
|
+
fixResult.resolved = true;
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
fixResult.errorMessage = `Failed to update .gitignore: ${error.message}`;
|
|
118
|
+
}
|
|
119
|
+
return fixResult;
|
|
120
|
+
}
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Handle the case when .gitignore doesn't exist.
|
|
125
|
+
*/
|
|
126
|
+
function handleMissingGitignore(filePath, patterns, file, resolve) {
|
|
127
|
+
const result = {
|
|
128
|
+
name: RequiredGitignorePatterns.name,
|
|
129
|
+
file,
|
|
130
|
+
autoFixable: true,
|
|
131
|
+
errorMessage: "No .gitignore file found in repository root",
|
|
132
|
+
};
|
|
133
|
+
if (resolve) {
|
|
134
|
+
const fixResult = {
|
|
135
|
+
...result,
|
|
136
|
+
resolved: false,
|
|
137
|
+
};
|
|
138
|
+
try {
|
|
139
|
+
const content = createGitignoreContent(patterns);
|
|
140
|
+
writeFileSync(filePath, content);
|
|
141
|
+
fixResult.resolved = true;
|
|
142
|
+
}
|
|
143
|
+
catch (writeError) {
|
|
144
|
+
fixResult.errorMessage = `Failed to create .gitignore: ${writeError.message}`;
|
|
145
|
+
}
|
|
146
|
+
return fixResult;
|
|
147
|
+
}
|
|
148
|
+
return result;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* A repo policy that ensures .gitignore contains required patterns to prevent
|
|
152
|
+
* committing sensitive files, dependencies, and build artifacts.
|
|
153
|
+
*
|
|
154
|
+
* @alpha
|
|
155
|
+
*/
|
|
156
|
+
export const RequiredGitignorePatterns = makePolicyDefinition("RequiredGitignorePatterns", /^\.gitignore$/, async ({ file, root, resolve, config }) => {
|
|
157
|
+
const patterns = config?.patterns ?? DEFAULT_PATTERNS;
|
|
158
|
+
const filePath = path.join(root, file);
|
|
159
|
+
try {
|
|
160
|
+
return handleExistingGitignore(filePath, patterns, file, resolve);
|
|
161
|
+
}
|
|
162
|
+
catch (_error) {
|
|
163
|
+
return handleMissingGitignore(filePath, patterns, file, resolve);
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
//# sourceMappingURL=RequiredGitignorePatterns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RequiredGitignorePatterns.js","sourceRoot":"","sources":["../../src/policies/RequiredGitignorePatterns.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFileSync, writeFileSync } from \"node:fs\";\nimport path from \"pathe\";\nimport { makePolicyDefinition } from \"../makePolicy.js\";\nimport type {\n\tPolicyDefinition,\n\tPolicyFailure,\n\tPolicyFixResult,\n} from \"../policy.js\";\n\n/**\n * Policy settings for the RequiredGitignorePatterns repo policy.\n *\n * @alpha\n */\nexport interface RequiredGitignorePatternsSettings {\n\t/**\n\t * Array of patterns that must be present in .gitignore.\n\t * Each pattern can be a string or an object with pattern and comment.\n\t */\n\tpatterns: Array<string | { pattern: string; comment?: string }>;\n}\n\n/**\n * Default patterns that should typically be in .gitignore files.\n */\nconst DEFAULT_PATTERNS = [\n\t{ pattern: \"node_modules/\", comment: \"Dependencies\" },\n\t{ pattern: \".env\", comment: \"Environment files\" },\n\t{ pattern: \".env.*\", comment: \"Environment files\" },\n\t{ pattern: \"!.env.example\", comment: \"Allow example env file\" },\n\t{ pattern: \"dist/\", comment: \"Build output\" },\n\t{ pattern: \"build/\", comment: \"Build output\" },\n\t{ pattern: \".DS_Store\", comment: \"macOS system files\" },\n\t{ pattern: \"Thumbs.db\", comment: \"Windows system files\" },\n];\n\n/**\n * Check if a pattern exists in gitignore content.\n * Handles patterns with inline comments (e.g., \"node_modules/ # comment\").\n */\nfunction patternExists(lines: string[], pattern: string): boolean {\n\treturn lines.some((line) => {\n\t\tconst trimmed = line.trim();\n\t\t// Remove inline comments (everything after # that's not escaped)\n\t\tconst withoutComment = trimmed.split(\"#\")[0]?.trim() ?? \"\";\n\t\treturn (\n\t\t\twithoutComment === pattern ||\n\t\t\ttrimmed === pattern ||\n\t\t\ttrimmed.startsWith(`${pattern} `) ||\n\t\t\ttrimmed.startsWith(`${pattern}\\t`)\n\t\t);\n\t});\n}\n\n/**\n * Find missing patterns in gitignore content.\n */\nfunction findMissingPatterns(\n\tpatterns: Array<string | { pattern: string; comment?: string }>,\n\tlines: string[],\n): Array<string | { pattern: string; comment?: string }> {\n\tconst missingPatterns: Array<string | { pattern: string; comment?: string }> =\n\t\t[];\n\n\tfor (const patternConfig of patterns) {\n\t\tconst pattern =\n\t\t\ttypeof patternConfig === \"string\" ? patternConfig : patternConfig.pattern;\n\n\t\tif (!patternExists(lines, pattern)) {\n\t\t\tmissingPatterns.push(patternConfig);\n\t\t}\n\t}\n\n\treturn missingPatterns;\n}\n\n/**\n * Add patterns to gitignore content.\n */\nfunction addPatternsToContent(\n\tcontent: string,\n\tmissingPatterns: Array<string | { pattern: string; comment?: string }>,\n): string {\n\tlet newContent = content;\n\n\t// Ensure file ends with newline\n\tif (!newContent.endsWith(\"\\n\")) {\n\t\tnewContent += \"\\n\";\n\t}\n\n\t// Add a section header if we're adding patterns\n\tif (missingPatterns.length > 0) {\n\t\tnewContent += \"\\n# Added by repopo RequiredGitignorePatterns policy\\n\";\n\t}\n\n\t// Add each missing pattern\n\tfor (const patternConfig of missingPatterns) {\n\t\tif (typeof patternConfig === \"string\") {\n\t\t\tnewContent += `${patternConfig}\\n`;\n\t\t} else {\n\t\t\tif (patternConfig.comment) {\n\t\t\t\tnewContent += `# ${patternConfig.comment}\\n`;\n\t\t\t}\n\t\t\tnewContent += `${patternConfig.pattern}\\n`;\n\t\t}\n\t}\n\n\treturn newContent;\n}\n\n/**\n * Create gitignore content from scratch.\n */\nfunction createGitignoreContent(\n\tpatterns: Array<string | { pattern: string; comment?: string }>,\n): string {\n\tlet content = \"# Generated by repopo RequiredGitignorePatterns policy\\n\\n\";\n\n\tfor (const patternConfig of patterns) {\n\t\tif (typeof patternConfig === \"string\") {\n\t\t\tcontent += `${patternConfig}\\n`;\n\t\t} else {\n\t\t\tif (patternConfig.comment) {\n\t\t\t\tcontent += `# ${patternConfig.comment}\\n`;\n\t\t\t}\n\t\t\tcontent += `${patternConfig.pattern}\\n`;\n\t\t}\n\t}\n\n\treturn content;\n}\n\n/**\n * Handle the case when .gitignore exists.\n */\nfunction handleExistingGitignore(\n\tfilePath: string,\n\tpatterns: Array<string | { pattern: string; comment?: string }>,\n\tfile: string,\n\tresolve: boolean,\n) {\n\tconst gitignoreContent = readFileSync(filePath, \"utf-8\");\n\tconst lines = gitignoreContent.split(\"\\n\");\n\tconst missingPatterns = findMissingPatterns(patterns, lines);\n\n\tif (missingPatterns.length === 0) {\n\t\treturn true;\n\t}\n\n\tconst result: PolicyFailure = {\n\t\tname: RequiredGitignorePatterns.name,\n\t\tfile,\n\t\tautoFixable: true,\n\t\terrorMessage: `Missing required .gitignore patterns: ${missingPatterns.map((p) => (typeof p === \"string\" ? p : p.pattern)).join(\", \")}`,\n\t};\n\n\tif (resolve) {\n\t\tconst fixResult: PolicyFixResult = {\n\t\t\t...result,\n\t\t\tresolved: false,\n\t\t};\n\n\t\ttry {\n\t\t\tconst newContent = addPatternsToContent(\n\t\t\t\tgitignoreContent,\n\t\t\t\tmissingPatterns,\n\t\t\t);\n\t\t\twriteFileSync(filePath, newContent);\n\t\t\tfixResult.resolved = true;\n\t\t} catch (error: unknown) {\n\t\t\tfixResult.errorMessage = `Failed to update .gitignore: ${(error as Error).message}`;\n\t\t}\n\n\t\treturn fixResult;\n\t}\n\n\treturn result;\n}\n\n/**\n * Handle the case when .gitignore doesn't exist.\n */\nfunction handleMissingGitignore(\n\tfilePath: string,\n\tpatterns: Array<string | { pattern: string; comment?: string }>,\n\tfile: string,\n\tresolve: boolean,\n) {\n\tconst result: PolicyFailure = {\n\t\tname: RequiredGitignorePatterns.name,\n\t\tfile,\n\t\tautoFixable: true,\n\t\terrorMessage: \"No .gitignore file found in repository root\",\n\t};\n\n\tif (resolve) {\n\t\tconst fixResult: PolicyFixResult = {\n\t\t\t...result,\n\t\t\tresolved: false,\n\t\t};\n\n\t\ttry {\n\t\t\tconst content = createGitignoreContent(patterns);\n\t\t\twriteFileSync(filePath, content);\n\t\t\tfixResult.resolved = true;\n\t\t} catch (writeError: unknown) {\n\t\t\tfixResult.errorMessage = `Failed to create .gitignore: ${(writeError as Error).message}`;\n\t\t}\n\n\t\treturn fixResult;\n\t}\n\n\treturn result;\n}\n\n/**\n * A repo policy that ensures .gitignore contains required patterns to prevent\n * committing sensitive files, dependencies, and build artifacts.\n *\n * @alpha\n */\nexport const RequiredGitignorePatterns: PolicyDefinition<RequiredGitignorePatternsSettings> =\n\tmakePolicyDefinition(\n\t\t\"RequiredGitignorePatterns\",\n\t\t/^\\.gitignore$/,\n\t\tasync ({ file, root, resolve, config }) => {\n\t\t\tconst patterns = config?.patterns ?? DEFAULT_PATTERNS;\n\t\t\tconst filePath = path.join(root, file);\n\n\t\t\ttry {\n\t\t\t\treturn handleExistingGitignore(filePath, patterns, file, resolve);\n\t\t\t} catch (_error: unknown) {\n\t\t\t\treturn handleMissingGitignore(filePath, patterns, file, resolve);\n\t\t\t}\n\t\t},\n\t);\n"]}
|
package/esm/policies.d.ts
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { HtmlFileHeaders } from "./policies/HtmlFileHeaders.js";
|
|
2
|
+
export { JsTsFileHeaders } from "./policies/JsTsFileHeaders.js";
|
|
3
|
+
export { LicenseFileExists } from "./policies/LicenseFileExists.js";
|
|
2
4
|
export { NoJsFileExtensions } from "./policies/NoJsFileExtensions.js";
|
|
5
|
+
export { NoLargeBinaryFiles } from "./policies/NoLargeBinaryFiles.js";
|
|
6
|
+
export { PackageJsonProperties } from "./policies/PackageJsonProperties.js";
|
|
3
7
|
export { PackageJsonRepoDirectoryProperty } from "./policies/PackageJsonRepoDirectoryProperty.js";
|
|
4
8
|
export { PackageJsonSorted } from "./policies/PackageJsonSorted.js";
|
|
5
|
-
export {
|
|
6
|
-
export {
|
|
9
|
+
export { PackageScripts } from "./policies/PackageScripts.js";
|
|
10
|
+
export { RequiredGitignorePatterns } from "./policies/RequiredGitignorePatterns.js";
|
|
11
|
+
export { DefaultPolicies } from "./policy.js";
|
|
7
12
|
//# sourceMappingURL=policies.d.ts.map
|
package/esm/policies.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policies.d.ts","sourceRoot":"","sources":["../src/policies.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"policies.d.ts","sourceRoot":"","sources":["../src/policies.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAC5E,OAAO,EAAE,gCAAgC,EAAE,MAAM,gDAAgD,CAAC;AAClG,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,yBAAyB,EAAE,MAAM,yCAAyC,CAAC;AACpF,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC"}
|
package/esm/policies.js
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { HtmlFileHeaders } from "./policies/HtmlFileHeaders.js";
|
|
2
|
+
export { JsTsFileHeaders } from "./policies/JsTsFileHeaders.js";
|
|
3
|
+
export { LicenseFileExists } from "./policies/LicenseFileExists.js";
|
|
2
4
|
export { NoJsFileExtensions } from "./policies/NoJsFileExtensions.js";
|
|
5
|
+
export { NoLargeBinaryFiles } from "./policies/NoLargeBinaryFiles.js";
|
|
6
|
+
export { PackageJsonProperties } from "./policies/PackageJsonProperties.js";
|
|
3
7
|
export { PackageJsonRepoDirectoryProperty } from "./policies/PackageJsonRepoDirectoryProperty.js";
|
|
4
8
|
export { PackageJsonSorted } from "./policies/PackageJsonSorted.js";
|
|
5
|
-
export {
|
|
6
|
-
export {
|
|
9
|
+
export { PackageScripts } from "./policies/PackageScripts.js";
|
|
10
|
+
export { RequiredGitignorePatterns } from "./policies/RequiredGitignorePatterns.js";
|
|
11
|
+
export { DefaultPolicies } from "./policy.js";
|
|
7
12
|
//# sourceMappingURL=policies.js.map
|
package/esm/policies.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policies.js","sourceRoot":"","sources":["../src/policies.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"policies.js","sourceRoot":"","sources":["../src/policies.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAC5E,OAAO,EAAE,gCAAgC,EAAE,MAAM,gDAAgD,CAAC;AAClG,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,yBAAyB,EAAE,MAAM,yCAAyC,CAAC;AACpF,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC","sourcesContent":["export { HtmlFileHeaders } from \"./policies/HtmlFileHeaders.js\";\nexport { JsTsFileHeaders } from \"./policies/JsTsFileHeaders.js\";\nexport { LicenseFileExists } from \"./policies/LicenseFileExists.js\";\nexport { NoJsFileExtensions } from \"./policies/NoJsFileExtensions.js\";\nexport { NoLargeBinaryFiles } from \"./policies/NoLargeBinaryFiles.js\";\nexport { PackageJsonProperties } from \"./policies/PackageJsonProperties.js\";\nexport { PackageJsonRepoDirectoryProperty } from \"./policies/PackageJsonRepoDirectoryProperty.js\";\nexport { PackageJsonSorted } from \"./policies/PackageJsonSorted.js\";\nexport { PackageScripts } from \"./policies/PackageScripts.js\";\nexport { RequiredGitignorePatterns } from \"./policies/RequiredGitignorePatterns.js\";\nexport { DefaultPolicies } from \"./policy.js\";\n"]}
|
package/esm/policy.d.ts
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @alpha
|
|
3
|
-
*/
|
|
4
|
-
export type DefaultPolicyConfigType = object | unknown;
|
|
5
1
|
/**
|
|
6
2
|
* A type representing a policy name.
|
|
7
3
|
*
|
|
@@ -38,15 +34,15 @@ export interface PolicyFunctionArguments<C> {
|
|
|
38
34
|
*
|
|
39
35
|
* @alpha
|
|
40
36
|
*/
|
|
41
|
-
export type PolicyHandler<C = unknown | undefined> = (args: PolicyFunctionArguments<C>) => Promise<
|
|
37
|
+
export type PolicyHandler<C = unknown | undefined> = (args: PolicyFunctionArguments<C>) => Promise<PolicyHandlerResult>;
|
|
42
38
|
/**
|
|
43
39
|
* A standalone function that can be called to resolve a policy failure.
|
|
44
40
|
*
|
|
45
41
|
* @alpha
|
|
46
42
|
*/
|
|
47
|
-
export type PolicyStandaloneResolver<C =
|
|
43
|
+
export type PolicyStandaloneResolver<C = undefined> = (args: Omit<PolicyFunctionArguments<C>, "resolve">) => Promise<PolicyFixResult>;
|
|
48
44
|
/**
|
|
49
|
-
* A
|
|
45
|
+
* A RepoPolicyDefinition checks and applies policies to files in the repository.
|
|
50
46
|
*
|
|
51
47
|
* Each policy has a name and a match regex for matching which files it should apply to. Every file in th repo is
|
|
52
48
|
* enumerated and if it matches the regex for a policy, that policy is applied.
|
|
@@ -58,7 +54,7 @@ export type PolicyStandaloneResolver<C = DefaultPolicyConfigType | undefined> =
|
|
|
58
54
|
*
|
|
59
55
|
* @alpha
|
|
60
56
|
*/
|
|
61
|
-
export interface
|
|
57
|
+
export interface PolicyDefinition<C = undefined> {
|
|
62
58
|
/**
|
|
63
59
|
* The name of the policy; displayed in UI and used in settings.
|
|
64
60
|
*/
|
|
@@ -66,7 +62,7 @@ export interface RepoPolicy<C extends DefaultPolicyConfigType = unknown | undefi
|
|
|
66
62
|
/**
|
|
67
63
|
* A more detailed description of the policy and its intended function.
|
|
68
64
|
*/
|
|
69
|
-
description?: string;
|
|
65
|
+
description?: string | undefined;
|
|
70
66
|
/**
|
|
71
67
|
* A regular expression that is used to match files in the repo.
|
|
72
68
|
*/
|
|
@@ -88,13 +84,31 @@ export interface RepoPolicy<C extends DefaultPolicyConfigType = unknown | undefi
|
|
|
88
84
|
* @returns true if the file passed the policy; otherwise a PolicyFailure object will be returned.
|
|
89
85
|
*/
|
|
90
86
|
resolver?: PolicyStandaloneResolver<C> | undefined;
|
|
87
|
+
/**
|
|
88
|
+
* A default config that will be used if none is provided.
|
|
89
|
+
*/
|
|
90
|
+
defaultConfig?: C | undefined;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* @alpha
|
|
94
|
+
*/
|
|
95
|
+
export interface PolicyInstanceSettings<C> {
|
|
96
|
+
/**
|
|
97
|
+
* An array of strings/regular expressions. File paths that match any of these expressions will be completely excluded
|
|
98
|
+
* from policy.
|
|
99
|
+
*
|
|
100
|
+
* Paths will be matched relative to the root of the repo.
|
|
101
|
+
*/
|
|
102
|
+
excludeFiles?: (string | RegExp)[];
|
|
103
|
+
/**
|
|
104
|
+
* The config that is applied to the policy instance.
|
|
105
|
+
*/
|
|
106
|
+
config?: C | undefined;
|
|
91
107
|
}
|
|
92
108
|
/**
|
|
93
|
-
* A policy handler especially for policies that target package.json.
|
|
94
|
-
*
|
|
95
109
|
* @alpha
|
|
96
110
|
*/
|
|
97
|
-
export type
|
|
111
|
+
export type PolicyInstance<C = undefined> = PolicyDefinition<C> & PolicyInstanceSettings<C>;
|
|
98
112
|
/**
|
|
99
113
|
* A policy failure.
|
|
100
114
|
*
|
|
@@ -129,11 +143,24 @@ export interface PolicyFixResult extends PolicyFailure {
|
|
|
129
143
|
*/
|
|
130
144
|
resolved: boolean;
|
|
131
145
|
}
|
|
146
|
+
/**
|
|
147
|
+
* @alpha
|
|
148
|
+
*/
|
|
149
|
+
export type PolicyHandlerResult = true | PolicyFailure | PolicyFixResult;
|
|
132
150
|
export declare function isPolicyFixResult(toCheck: any): toCheck is PolicyFixResult;
|
|
133
151
|
/**
|
|
134
152
|
* Default policies included with repopo.
|
|
135
153
|
*
|
|
136
154
|
* @alpha
|
|
137
155
|
*/
|
|
138
|
-
export declare const DefaultPolicies:
|
|
156
|
+
export declare const DefaultPolicies: PolicyDefinition<any>[];
|
|
157
|
+
export declare abstract class Policy<C> implements PolicyDefinition<C> {
|
|
158
|
+
readonly name: string;
|
|
159
|
+
readonly match: RegExp;
|
|
160
|
+
readonly handler: PolicyHandler<C>;
|
|
161
|
+
readonly description?: string | undefined;
|
|
162
|
+
readonly defaultConfig?: C | undefined;
|
|
163
|
+
readonly resolver?: PolicyStandaloneResolver<C> | undefined;
|
|
164
|
+
constructor(name: string, match: RegExp, handler: PolicyHandler<C>, description?: string | undefined, defaultConfig?: C | undefined, resolver?: PolicyStandaloneResolver<C> | undefined);
|
|
165
|
+
}
|
|
139
166
|
//# sourceMappingURL=policy.d.ts.map
|
package/esm/policy.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"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"}
|
package/esm/policy.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import { HtmlFileHeaders } from "./policies.js";
|
|
2
|
-
import { JsTsFileHeaders } from "./policies/JsTsFileHeaders.js";
|
|
3
1
|
import { NoJsFileExtensions } from "./policies/NoJsFileExtensions.js";
|
|
4
|
-
import { PackageJsonProperties } from "./policies/PackageJsonProperties.js";
|
|
5
2
|
import { PackageJsonRepoDirectoryProperty } from "./policies/PackageJsonRepoDirectoryProperty.js";
|
|
3
|
+
import { PackageJsonSorted } from "./policies/PackageJsonSorted.js";
|
|
6
4
|
import { PackageScripts } from "./policies/PackageScripts.js";
|
|
7
5
|
// biome-ignore lint/suspicious/noExplicitAny: type guard
|
|
8
6
|
export function isPolicyFixResult(toCheck) {
|
|
@@ -18,12 +16,25 @@ export function isPolicyFixResult(toCheck) {
|
|
|
18
16
|
*/
|
|
19
17
|
// biome-ignore lint/suspicious/noExplicitAny: FIXME
|
|
20
18
|
export const DefaultPolicies = [
|
|
21
|
-
HtmlFileHeaders,
|
|
22
|
-
JsTsFileHeaders,
|
|
23
19
|
NoJsFileExtensions,
|
|
24
20
|
PackageJsonRepoDirectoryProperty,
|
|
25
|
-
|
|
26
|
-
// PackageJsonSorted,
|
|
21
|
+
PackageJsonSorted,
|
|
27
22
|
PackageScripts,
|
|
28
23
|
];
|
|
24
|
+
export class Policy {
|
|
25
|
+
name;
|
|
26
|
+
match;
|
|
27
|
+
handler;
|
|
28
|
+
description;
|
|
29
|
+
defaultConfig;
|
|
30
|
+
resolver;
|
|
31
|
+
constructor(name, match, handler, description, defaultConfig, resolver) {
|
|
32
|
+
this.name = name;
|
|
33
|
+
this.match = match;
|
|
34
|
+
this.handler = handler;
|
|
35
|
+
this.description = description;
|
|
36
|
+
this.defaultConfig = defaultConfig;
|
|
37
|
+
this.resolver = resolver;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
29
40
|
//# sourceMappingURL=policy.js.map
|
package/esm/policy.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,gCAAgC,EAAE,MAAM,gDAAgD,CAAC;AAClG,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AA4L9D,yDAAyD;AACzD,MAAM,UAAU,iBAAiB,CAAC,OAAY;IAC7C,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QACjC,OAAO,KAAK,CAAC;IACd,CAAC;IACD,OAAO,UAAU,IAAI,OAAO,CAAC;AAC9B,CAAC;AAED;;;;GAIG;AAEH,oDAAoD;AACpD,MAAM,CAAC,MAAM,eAAe,GAA4B;IACvD,kBAAkB;IAClB,gCAAgC;IAChC,iBAAiB;IACjB,cAAc;CACL,CAAC;AAEX,MAAM,OAAgB,MAAM;IAEV;IACA;IACA;IACA;IACA;IACA;IANjB,YACiB,IAAY,EACZ,KAAa,EACb,OAAyB,EACzB,WAAoB,EACpB,aAAiB,EACjB,QAAsC;QALtC,SAAI,GAAJ,IAAI,CAAQ;QACZ,UAAK,GAAL,KAAK,CAAQ;QACb,YAAO,GAAP,OAAO,CAAkB;QACzB,gBAAW,GAAX,WAAW,CAAS;QACpB,kBAAa,GAAb,aAAa,CAAI;QACjB,aAAQ,GAAR,QAAQ,CAA8B;IACpD,CAAC;CACJ","sourcesContent":["import { NoJsFileExtensions } from \"./policies/NoJsFileExtensions.js\";\nimport { PackageJsonRepoDirectoryProperty } from \"./policies/PackageJsonRepoDirectoryProperty.js\";\nimport { PackageJsonSorted } from \"./policies/PackageJsonSorted.js\";\nimport { PackageScripts } from \"./policies/PackageScripts.js\";\n\n/**\n * A type representing a policy name.\n *\n * @alpha\n */\nexport type PolicyName = string;\n\n/**\n * Arguments passed to policy functions.\n *\n * @alpha\n */\n\nexport interface PolicyFunctionArguments<C> {\n\t/**\n\t * Path to the file, relative to the repo root.\n\t */\n\tfile: string;\n\n\t/**\n\t * Absolute path to the root of the repo.\n\t */\n\troot: string;\n\n\t/**\n\t * If true, the handler should resolve any violations automatically if possible.\n\t */\n\tresolve: boolean;\n\n\t/**\n\t * @remarks\n\t *\n\t * Note that the handler function receives the config as an argument.\n\t */\n\tconfig?: C | undefined;\n}\n\n/**\n * A policy handler is a function that is called to check policy against a file.\n *\n * @alpha\n */\n\nexport type PolicyHandler<C = unknown | undefined> = (\n\targs: PolicyFunctionArguments<C>,\n) => Promise<PolicyHandlerResult>;\n\n// export type PolicyCheckOnly = (\n// \tfile: string,\n// \troot: string,\n// ) => Promise<PolicyHandlerResult>;\n\n/**\n * A standalone function that can be called to resolve a policy failure.\n *\n * @alpha\n */\nexport type PolicyStandaloneResolver<C = undefined> = (\n\targs: Omit<PolicyFunctionArguments<C>, \"resolve\">,\n) => Promise<PolicyFixResult>;\n\n// function isPolicyHandler(input: PolicyHandler | PolicyCheckOnly): input is PolicyHandler\n\n/**\n * A RepoPolicyDefinition checks and applies policies to files in the repository.\n *\n * Each policy has a name and a match regex for matching which files it should apply to. Every file in th repo is\n * enumerated and if it matches the regex for a policy, that policy is applied.\n *\n * Each policy includes a handler function that checks a file against the policy and can optionally resolve any problems\n * (automated resolutions depend on the policy implementation).\n *\n * @typeParam C - type of configuration object used by the policy\n *\n * @alpha\n */\nexport interface PolicyDefinition<C = undefined> {\n\t/**\n\t * The name of the policy; displayed in UI and used in settings.\n\t */\n\tname: PolicyName;\n\n\t/**\n\t * A more detailed description of the policy and its intended function.\n\t */\n\tdescription?: string | undefined;\n\n\t/**\n\t * A regular expression that is used to match files in the repo.\n\t */\n\tmatch: RegExp;\n\n\t/**\n\t * A handler function that checks if a file is compliant with the policy.\n\t *\n\t * @param file - Repo-relative path to the file to check.\n\t * @param root - Absolute path to the root of the repo.\n\t * @param resolve - If true, automated policy fixes will be applied. Not all policies support automated fixes.\n\t * @returns True if the file passed the policy; otherwise a PolicyFailure object will be returned.\n\t */\n\n\thandler: PolicyHandler<C>;\n\n\t/**\n\t * A resolver function that can be used to automatically address the policy violation.\n\t *\n\t * @param file - Repo-relative path to the file to check.\n\t * @param root - Absolute path to the root of the repo.\n\t * @returns true if the file passed the policy; otherwise a PolicyFailure object will be returned.\n\t */\n\tresolver?: PolicyStandaloneResolver<C> | undefined;\n\n\t/**\n\t * A default config that will be used if none is provided.\n\t */\n\tdefaultConfig?: C | undefined;\n}\n\n/**\n * @alpha\n */\nexport interface PolicyInstanceSettings<C> {\n\t/**\n\t * An array of strings/regular expressions. File paths that match any of these expressions will be completely excluded\n\t * from policy.\n\t *\n\t * Paths will be matched relative to the root of the repo.\n\t */\n\texcludeFiles?: (string | RegExp)[];\n\n\t/**\n\t * The config that is applied to the policy instance.\n\t */\n\tconfig?: C | undefined;\n}\n\n/**\n * @alpha\n */\nexport type PolicyInstance<C = undefined> = PolicyDefinition<C> &\n\tPolicyInstanceSettings<C>;\n\n/**\n * A policy failure.\n *\n * @alpha\n */\nexport interface PolicyFailure {\n\t/**\n\t * Name of the policy that failed.\n\t */\n\tname: PolicyName;\n\n\t/**\n\t * Path to the file that failed the policy.\n\t */\n\tfile: string;\n\n\t/**\n\t * Set to `true` if the policy can be fixed automatically.\n\t */\n\tautoFixable?: boolean | undefined;\n\n\t/**\n\t * An optional error message accompanying the failure.\n\t */\n\terrorMessage?: string | undefined;\n}\n\n/**\n * The result of an automatic fix for a failing policy.\n *\n * @alpha\n */\nexport interface PolicyFixResult extends PolicyFailure {\n\t/**\n\t * Set to true if the failure was resolved by the automated fixer.\n\t */\n\tresolved: boolean;\n}\n\n/**\n * @alpha\n */\nexport type PolicyHandlerResult = true | PolicyFailure | PolicyFixResult;\n\n// biome-ignore lint/suspicious/noExplicitAny: type guard\nexport function isPolicyFixResult(toCheck: any): toCheck is PolicyFixResult {\n\tif (typeof toCheck !== \"object\") {\n\t\treturn false;\n\t}\n\treturn \"resolved\" in toCheck;\n}\n\n/**\n * Default policies included with repopo.\n *\n * @alpha\n */\n\n// biome-ignore lint/suspicious/noExplicitAny: FIXME\nexport const DefaultPolicies: PolicyDefinition<any>[] = [\n\tNoJsFileExtensions,\n\tPackageJsonRepoDirectoryProperty,\n\tPackageJsonSorted,\n\tPackageScripts,\n] as const;\n\nexport abstract class Policy<C> implements PolicyDefinition<C> {\n\tpublic constructor(\n\t\tpublic readonly name: string,\n\t\tpublic readonly match: RegExp,\n\t\tpublic readonly handler: PolicyHandler<C>,\n\t\tpublic readonly description?: string,\n\t\tpublic readonly defaultConfig?: C,\n\t\tpublic readonly resolver?: PolicyStandaloneResolver<C>,\n\t) {}\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { PolicyDefinition } from "../policy.js";
|
|
2
2
|
/**
|
|
3
3
|
* @alpha
|
|
4
4
|
*/
|
|
@@ -36,10 +36,10 @@ export interface FileHeaderGeneratorConfig extends Partial<FileHeaderPolicyConfi
|
|
|
36
36
|
replacer: (content: string, config: FileHeaderPolicyConfig) => string;
|
|
37
37
|
}
|
|
38
38
|
/**
|
|
39
|
-
* Given a
|
|
39
|
+
* Given a {@link FileHeaderPolicyConfig}, produces a function that detects correct file headers
|
|
40
40
|
* and returns an error string if the header is missing or incorrect.
|
|
41
41
|
*
|
|
42
42
|
* @alpha
|
|
43
43
|
*/
|
|
44
|
-
export declare function
|
|
45
|
-
//# sourceMappingURL=
|
|
44
|
+
export declare function defineFileHeaderPolicy(name: string, config: FileHeaderGeneratorConfig): PolicyDefinition<FileHeaderPolicyConfig>;
|
|
45
|
+
//# sourceMappingURL=defineFileHeaderPolicy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defineFileHeaderPolicy.d.ts","sourceRoot":"","sources":["../../src/policyDefiners/defineFileHeaderPolicy.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACX,gBAAgB,EAGhB,MAAM,cAAc,CAAC;AAItB;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACtC;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,yBAChB,SAAQ,OAAO,CAAC,sBAAsB,CAAC;IACvC,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,sBAAsB,KAAK,MAAM,CAAC;CACtE;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACrC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,yBAAyB,GAC/B,gBAAgB,CAAC,sBAAsB,CAAC,CAiE1C"}
|
|
@@ -3,12 +3,12 @@ import { EOL as newline } from "node:os";
|
|
|
3
3
|
import { extname } from "pathe";
|
|
4
4
|
const trailingSpaces = /\s*\\r\?\\n/;
|
|
5
5
|
/**
|
|
6
|
-
* Given a
|
|
6
|
+
* Given a {@link FileHeaderPolicyConfig}, produces a function that detects correct file headers
|
|
7
7
|
* and returns an error string if the header is missing or incorrect.
|
|
8
8
|
*
|
|
9
9
|
* @alpha
|
|
10
10
|
*/
|
|
11
|
-
export function
|
|
11
|
+
export function defineFileHeaderPolicy(name, config) {
|
|
12
12
|
const pre = config.headerStart?.source ?? "";
|
|
13
13
|
const start = config.lineStart.source;
|
|
14
14
|
const end = config.lineEnd.source;
|
|
@@ -58,4 +58,4 @@ export function generateFileHeaderPolicy(name, config) {
|
|
|
58
58
|
},
|
|
59
59
|
};
|
|
60
60
|
}
|
|
61
|
-
//# sourceMappingURL=
|
|
61
|
+
//# sourceMappingURL=defineFileHeaderPolicy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defineFileHeaderPolicy.js","sourceRoot":"","sources":["../../src/policyDefiners/defineFileHeaderPolicy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,GAAG,IAAI,OAAO,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAOhC,MAAM,cAAc,GAAG,aAAa,CAAC;AA+CrC;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CACrC,IAAY,EACZ,MAAiC;IAEjC,MAAM,GAAG,GAAG,MAAM,CAAC,WAAW,EAAE,MAAM,IAAI,EAAE,CAAC;IAC7C,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC;IACtC,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;IAClC,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,EAAE,MAAM,IAAI,EAAE,CAAC;IAE5C,2EAA2E;IAC3E,mGAAmG;IACnG,MAAM,OAAO,GAAG,CAAC,IAAY,EAAU,EAAE,CACxC,IAAI;SACF,KAAK,CAAC,OAAO,CAAC;SACd,GAAG,CACH,CAAC,IAAI,EAAE,EAAE,CACR,GAAG,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,GAAG,GAAG,EAAE,CAC/D;SACA,IAAI,CAAC,EAAE,CAAC;SACR,OAAO,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC,CAAC,uCAAuC;IAE9E,wFAAwF;IACxF,0FAA0F;IAC1F,MAAM,KAAK,GAAG,IAAI,MAAM,CACvB,IAAI,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC,KAAK,IAAI,EAAE,CAC1F,CAAC;IAEF,OAAO;QACN,IAAI;QACJ,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,EAAE;YAC1D,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;gBAChC,OAAO,IAAI,CAAC;YACb,CAAC;YAED,MAAM,UAAU,GAAkB;gBACjC,IAAI;gBACJ,IAAI;gBACJ,WAAW,EAAE,IAAI;aACjB,CAAC;YAEF,+EAA+E;YAC/E,gCAAgC;YAChC,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;YAC3D,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAEpC,IAAI,MAAM,EAAE,CAAC;gBACZ,UAAU,CAAC,YAAY,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,sBAAsB,CAAC;YAClE,CAAC;YAED,IAAI,MAAM,EAAE,CAAC;gBACZ,IAAI,OAAO,EAAE,CAAC;oBACb,MAAM,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;oBAC1D,MAAM,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;oBAElC,MAAM,SAAS,GAAoB;wBAClC,GAAG,UAAU;wBACb,QAAQ,EAAE,IAAI;qBACd,CAAC;oBAEF,OAAO,SAAS,CAAC;gBAClB,CAAC;gBACD,OAAO,UAAU,CAAC;YACnB,CAAC;YAED,OAAO,IAAI,CAAC;QACb,CAAC;KACD,CAAC;AACH,CAAC","sourcesContent":["import { readFile, writeFile } from \"node:fs/promises\";\nimport { EOL as newline } from \"node:os\";\nimport { extname } from \"pathe\";\nimport type {\n\tPolicyDefinition,\n\tPolicyFailure,\n\tPolicyFixResult,\n} from \"../policy.js\";\n\nconst trailingSpaces = /\\s*\\\\r\\?\\\\n/;\n\n/**\n * @alpha\n */\nexport interface FileHeaderPolicyConfig {\n\t/**\n\t * The text to use as the header.\n\t */\n\theaderText: string;\n\n\t/**\n\t * An optional string that will be appended to the headerText.\n\t */\n\tautoGenText?: string;\n}\n\n/**\n * @alpha\n */\nexport interface FileHeaderGeneratorConfig\n\textends Partial<FileHeaderPolicyConfig> {\n\tmatch: RegExp;\n\n\t/**\n\t * Regex matching header prefix (e.g. `/*!\\r?\\n`)\n\t */\n\theaderStart?: RegExp;\n\n\t/**\n\t * Regex matching beginning of each line (e.g. ' * ')\n\t */\n\tlineStart: RegExp;\n\n\t/**\n\t * Regex matching the end of each line (e.g., `\\r?\\n`)\n\t */\n\tlineEnd: RegExp;\n\n\t/**\n\t * Regex matching the header postfix.\n\t */\n\theaderEnd?: RegExp;\n\n\treplacer: (content: string, config: FileHeaderPolicyConfig) => string;\n}\n\n/**\n * Given a {@link FileHeaderPolicyConfig}, produces a function that detects correct file headers\n * and returns an error string if the header is missing or incorrect.\n *\n * @alpha\n */\nexport function defineFileHeaderPolicy(\n\tname: string,\n\tconfig: FileHeaderGeneratorConfig,\n): PolicyDefinition<FileHeaderPolicyConfig> {\n\tconst pre = config.headerStart?.source ?? \"\";\n\tconst start = config.lineStart.source;\n\tconst end = config.lineEnd.source;\n\tconst post = config.headerEnd?.source ?? \"\";\n\n\t// Helper which constructs a matching RegExp from a given multiline string.\n\t// (See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping)\n\tconst toRegex = (text: string): string =>\n\t\ttext\n\t\t\t.split(newline)\n\t\t\t.map(\n\t\t\t\t(line) =>\n\t\t\t\t\t`${start}${line.replace(/[$()*+.?[\\\\\\]^{|}]/g, \"\\\\$&\")}${end}`,\n\t\t\t)\n\t\t\t.join(\"\")\n\t\t\t.replace(trailingSpaces, \"\\\\r?\\\\n\"); // Trim trailing spaces at end-of-line.\n\n\t// Detection regex matches the header start (if any), followed by lines in 'headerText',\n\t// optionally followed by lines in the 'autoGenText', and finally the header end (if any).\n\tconst regex = new RegExp(\n\t\t`^${pre}${toRegex(config.headerText ?? \"\")}(${toRegex(config.autoGenText ?? \"\")})?${post}`,\n\t);\n\n\treturn {\n\t\tname,\n\t\tmatch: config.match,\n\t\thandler: async ({ file, resolve, config: policyConfig }) => {\n\t\t\tif (policyConfig === undefined) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tconst failResult: PolicyFailure = {\n\t\t\t\tname,\n\t\t\t\tfile,\n\t\t\t\tautoFixable: true,\n\t\t\t};\n\n\t\t\t// TODO: Consider reading only the first 512B or so since headers are typically\n\t\t\t// at the beginning of the file.\n\t\t\tconst content = await readFile(file, { encoding: \"utf8\" });\n\t\t\tconst failed = !regex.test(content);\n\n\t\t\tif (failed) {\n\t\t\t\tfailResult.errorMessage = `${extname(file)} file missing header`;\n\t\t\t}\n\n\t\t\tif (failed) {\n\t\t\t\tif (resolve) {\n\t\t\t\t\tconst newContent = config.replacer(content, policyConfig);\n\t\t\t\t\tawait writeFile(file, newContent);\n\n\t\t\t\t\tconst fixResult: PolicyFixResult = {\n\t\t\t\t\t\t...failResult,\n\t\t\t\t\t\tresolved: true,\n\t\t\t\t\t};\n\n\t\t\t\t\treturn fixResult;\n\t\t\t\t}\n\t\t\t\treturn failResult;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t},\n\t};\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { PackageJson } from "type-fest";
|
|
2
|
+
import type { PolicyDefinition, PolicyFunctionArguments, PolicyHandlerResult } from "../policy.js";
|
|
3
|
+
/**
|
|
4
|
+
* A policy handler especially for policies that target package.json.
|
|
5
|
+
*
|
|
6
|
+
* @alpha
|
|
7
|
+
*/
|
|
8
|
+
export type PackageJsonHandler<J, C> = (json: J, args: PolicyFunctionArguments<C>) => Promise<PolicyHandlerResult>;
|
|
9
|
+
/**
|
|
10
|
+
* Define a repo policy for package.json files.
|
|
11
|
+
*
|
|
12
|
+
* @alpha
|
|
13
|
+
*/
|
|
14
|
+
export declare function definePackagePolicy<J = PackageJson, C = undefined>(name: string, packagePolicy: PackageJsonHandler<J, C>): PolicyDefinition<C>;
|
|
15
|
+
//# sourceMappingURL=definePackagePolicy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"definePackagePolicy.d.ts","sourceRoot":"","sources":["../../src/policyDefiners/definePackagePolicy.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7C,OAAO,KAAK,EACX,gBAAgB,EAChB,uBAAuB,EACvB,mBAAmB,EACnB,MAAM,cAAc,CAAC;AAItB;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,CAAC,CAAC,EAAE,CAAC,IAAI,CACtC,IAAI,EAAE,CAAC,EACP,IAAI,EAAE,uBAAuB,CAAC,CAAC,CAAC,KAC5B,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAElC;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,GAAG,WAAW,EAAE,CAAC,GAAG,SAAS,EACjE,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,kBAAkB,CAAC,CAAC,EAAE,CAAC,CAAC,GAErC,gBAAgB,CAAC,CAAC,CAAC,CAUrB"}
|
package/esm/{policyGenerators/generatePackagePolicy.js → policyDefiners/definePackagePolicy.js}
RENAMED
|
@@ -6,7 +6,7 @@ const { readFile: readJson } = jsonfile;
|
|
|
6
6
|
*
|
|
7
7
|
* @alpha
|
|
8
8
|
*/
|
|
9
|
-
export function
|
|
9
|
+
export function definePackagePolicy(name, packagePolicy) {
|
|
10
10
|
// const func = () => handler(json, args);
|
|
11
11
|
return {
|
|
12
12
|
name,
|
|
@@ -17,4 +17,4 @@ export function generatePackagePolicy(name, packagePolicy) {
|
|
|
17
17
|
},
|
|
18
18
|
};
|
|
19
19
|
}
|
|
20
|
-
//# sourceMappingURL=
|
|
20
|
+
//# sourceMappingURL=definePackagePolicy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"definePackagePolicy.js","sourceRoot":"","sources":["../../src/policyDefiners/definePackagePolicy.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,UAAU,CAAC;AAEhC,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAOjE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,QAAQ,CAAC;AAYxC;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAClC,IAAY,EACZ,aAAuC;IAGvC,0CAA0C;IAC1C,OAAO;QACN,IAAI;QACJ,KAAK,EAAE,qBAAqB;QAC5B,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE;YAC5B,MAAM,IAAI,GAAM,MAAM,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAC/C,OAAO,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACvC,CAAC;KACD,CAAC;AACH,CAAC","sourcesContent":["import jsonfile from \"jsonfile\";\nimport type { PackageJson } from \"type-fest\";\nimport { PackageJsonRegexMatch } from \"../policies/constants.js\";\nimport type {\n\tPolicyDefinition,\n\tPolicyFunctionArguments,\n\tPolicyHandlerResult,\n} from \"../policy.js\";\n\nconst { readFile: readJson } = jsonfile;\n\n/**\n * A policy handler especially for policies that target package.json.\n *\n * @alpha\n */\nexport type PackageJsonHandler<J, C> = (\n\tjson: J,\n\targs: PolicyFunctionArguments<C>,\n) => Promise<PolicyHandlerResult>;\n\n/**\n * Define a repo policy for package.json files.\n *\n * @alpha\n */\nexport function definePackagePolicy<J = PackageJson, C = undefined>(\n\tname: string,\n\tpackagePolicy: PackageJsonHandler<J, C>,\n\t// args: PolicyFunctionArguments<C>,\n): PolicyDefinition<C> {\n\t// const func = () => handler(json, args);\n\treturn {\n\t\tname,\n\t\tmatch: PackageJsonRegexMatch,\n\t\thandler: async (innerArgs) => {\n\t\t\tconst json: J = await readJson(innerArgs.file);\n\t\t\treturn packagePolicy(json, innerArgs);\n\t\t},\n\t};\n}\n"]}
|
package/esm/tsdoc-metadata.json
CHANGED
package/oclif.manifest.json
CHANGED