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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NoJsFileExtensions.js","sourceRoot":"","sources":["../../src/policies/NoJsFileExtensions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"NoJsFileExtensions.js","sourceRoot":"","sources":["../../src/policies/NoJsFileExtensions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAGxD;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAqB,oBAAoB,CACvE,oBAAoB,EACpB,mBAAmB,EACnB,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;IAClB,qCAAqC;IACrC,MAAM,MAAM,GAAkB;QAC7B,IAAI,EAAE,kBAAkB,CAAC,IAAI;QAC7B,IAAI;QACJ,WAAW,EAAE,KAAK;QAClB,YAAY,EACX,iIAAiI;KAClI,CAAC;IACF,OAAO,MAAM,CAAC;AACf,CAAC,CACD,CAAC","sourcesContent":["import { makePolicyDefinition } from \"../makePolicy.js\";\nimport type { PolicyDefinition, PolicyFailure } from \"../policy.js\";\n\n/**\n * A repo policy that checks for JavaScript source files that just use the .js file extension. Such files may be\n * interpreted by node as either CommonJS or ESM based on the `type` field in the nearest package.json file. This\n * can create unexpected behavior for JS files; changing the package.json nearest to one will change how the JS\n * is processed by node. Using explicit file extensions reduces ambiguity and ensures a CJS file isn't suddenly treated\n * like an ESM file.\n *\n * @alpha\n */\nexport const NoJsFileExtensions: PolicyDefinition = makePolicyDefinition(\n\t\"NoJsFileExtensions\",\n\t/(^|\\/)[^/]+\\.js$/i,\n\tasync ({ file }) => {\n\t\t// Any match is considered a failure.\n\t\tconst result: PolicyFailure = {\n\t\t\tname: NoJsFileExtensions.name,\n\t\t\tfile,\n\t\t\tautoFixable: false,\n\t\t\terrorMessage:\n\t\t\t\t\"JavaScript files should have a .cjs or .mjs file extension based on the module format of the file. Rename the file accordingly.\",\n\t\t};\n\t\treturn result;\n\t},\n);\n"]}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { PolicyDefinition } from "../policy.js";
|
|
2
|
+
/**
|
|
3
|
+
* Policy settings for the NoLargeBinaryFiles repo policy.
|
|
4
|
+
*
|
|
5
|
+
* @alpha
|
|
6
|
+
*/
|
|
7
|
+
export interface NoLargeBinaryFilesSettings {
|
|
8
|
+
/**
|
|
9
|
+
* Maximum file size in bytes. Defaults to 10MB.
|
|
10
|
+
*/
|
|
11
|
+
maxSizeBytes?: number;
|
|
12
|
+
/**
|
|
13
|
+
* File extensions to exclude from size checking.
|
|
14
|
+
* Useful for known large files that should be allowed.
|
|
15
|
+
*/
|
|
16
|
+
excludeExtensions?: string[];
|
|
17
|
+
/**
|
|
18
|
+
* File patterns to exclude from size checking.
|
|
19
|
+
* Uses glob-style patterns.
|
|
20
|
+
*/
|
|
21
|
+
excludePatterns?: string[];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* A repo policy that prevents large binary files from being committed to the repository.
|
|
25
|
+
* Large files can bloat the repository and slow down clones. Consider using Git LFS for large assets.
|
|
26
|
+
*
|
|
27
|
+
* @alpha
|
|
28
|
+
*/
|
|
29
|
+
export declare const NoLargeBinaryFiles: PolicyDefinition<NoLargeBinaryFilesSettings>;
|
|
30
|
+
//# sourceMappingURL=NoLargeBinaryFiles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NoLargeBinaryFiles.d.ts","sourceRoot":"","sources":["../../src/policies/NoLargeBinaryFiles.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAiB,MAAM,cAAc,CAAC;AAEpE;;;;GAIG;AACH,MAAM,WAAW,0BAA0B;IAC1C;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE7B;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AA2FD;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,EAAE,gBAAgB,CAAC,0BAA0B,CA0C1E,CAAC"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { statSync } from "node:fs";
|
|
2
|
+
import path from "pathe";
|
|
3
|
+
import { makePolicyDefinition } from "../makePolicy.js";
|
|
4
|
+
/**
|
|
5
|
+
* Default maximum file size (10MB in bytes).
|
|
6
|
+
*/
|
|
7
|
+
const DEFAULT_MAX_SIZE = 10 * 1024 * 1024;
|
|
8
|
+
/**
|
|
9
|
+
* Default file extensions that are typically safe to exclude from size limits.
|
|
10
|
+
*/
|
|
11
|
+
const DEFAULT_EXCLUDE_EXTENSIONS = [
|
|
12
|
+
".md",
|
|
13
|
+
".txt",
|
|
14
|
+
".json",
|
|
15
|
+
".js",
|
|
16
|
+
".ts",
|
|
17
|
+
".jsx",
|
|
18
|
+
".tsx",
|
|
19
|
+
".css",
|
|
20
|
+
".scss",
|
|
21
|
+
".sass",
|
|
22
|
+
".less",
|
|
23
|
+
".html",
|
|
24
|
+
".xml",
|
|
25
|
+
".yml",
|
|
26
|
+
".yaml",
|
|
27
|
+
".toml",
|
|
28
|
+
".ini",
|
|
29
|
+
".conf",
|
|
30
|
+
".config",
|
|
31
|
+
];
|
|
32
|
+
/**
|
|
33
|
+
* Convert a glob pattern to a regex pattern by escaping special characters
|
|
34
|
+
* and converting * to .* for wildcard matching.
|
|
35
|
+
*/
|
|
36
|
+
function globToRegex(pattern) {
|
|
37
|
+
// Escape all regex special characters except *
|
|
38
|
+
const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
|
|
39
|
+
// Convert * to .* for wildcard matching
|
|
40
|
+
const regexPattern = escaped.replace(/\*/g, ".*");
|
|
41
|
+
return new RegExp(`^${regexPattern}$`);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Check if a file matches any of the exclude patterns.
|
|
45
|
+
*/
|
|
46
|
+
function isExcluded(filePath, excludePatterns, excludeExtensions) {
|
|
47
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
48
|
+
// Check extensions
|
|
49
|
+
if (excludeExtensions.includes(ext)) {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
// Check patterns (simple glob-like matching)
|
|
53
|
+
for (const pattern of excludePatterns) {
|
|
54
|
+
if (pattern.includes("*")) {
|
|
55
|
+
const regex = globToRegex(pattern);
|
|
56
|
+
if (regex.test(filePath)) {
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else if (filePath.includes(pattern)) {
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Format bytes in a human-readable format.
|
|
68
|
+
*/
|
|
69
|
+
function formatBytes(bytes) {
|
|
70
|
+
if (bytes === 0) {
|
|
71
|
+
return "0 B";
|
|
72
|
+
}
|
|
73
|
+
const k = 1024;
|
|
74
|
+
const sizes = ["B", "KB", "MB", "GB", "TB"];
|
|
75
|
+
const i = Math.min(Math.floor(Math.log(bytes) / Math.log(k)), sizes.length - 1);
|
|
76
|
+
const formatted = (bytes / k ** i).toFixed(1);
|
|
77
|
+
return `${formatted} ${sizes[i]}`;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* A repo policy that prevents large binary files from being committed to the repository.
|
|
81
|
+
* Large files can bloat the repository and slow down clones. Consider using Git LFS for large assets.
|
|
82
|
+
*
|
|
83
|
+
* @alpha
|
|
84
|
+
*/
|
|
85
|
+
export const NoLargeBinaryFiles = makePolicyDefinition("NoLargeBinaryFiles",
|
|
86
|
+
// Match all files
|
|
87
|
+
/.*/, async ({ file, root, config }) => {
|
|
88
|
+
const maxSizeBytes = config?.maxSizeBytes ?? DEFAULT_MAX_SIZE;
|
|
89
|
+
const excludeExtensions = config?.excludeExtensions ?? DEFAULT_EXCLUDE_EXTENSIONS;
|
|
90
|
+
const excludePatterns = config?.excludePatterns ?? [];
|
|
91
|
+
// Skip excluded files
|
|
92
|
+
if (isExcluded(file, excludePatterns, excludeExtensions)) {
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
try {
|
|
96
|
+
const filePath = path.resolve(root, file);
|
|
97
|
+
const stats = statSync(filePath);
|
|
98
|
+
// Skip directories
|
|
99
|
+
if (stats.isDirectory()) {
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
if (stats.size > maxSizeBytes) {
|
|
103
|
+
const result = {
|
|
104
|
+
name: NoLargeBinaryFiles.name,
|
|
105
|
+
file,
|
|
106
|
+
autoFixable: false,
|
|
107
|
+
errorMessage: `File is too large: ${formatBytes(stats.size)} (max: ${formatBytes(maxSizeBytes)}). Consider using Git LFS or removing the file.`,
|
|
108
|
+
};
|
|
109
|
+
return result;
|
|
110
|
+
}
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
catch (_error) {
|
|
114
|
+
// File doesn't exist or can't be accessed, skip it
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
//# sourceMappingURL=NoLargeBinaryFiles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NoLargeBinaryFiles.js","sourceRoot":"","sources":["../../src/policies/NoLargeBinaryFiles.ts"],"names":[],"mappings":"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","sourcesContent":["import { statSync } from \"node:fs\";\nimport path from \"pathe\";\nimport { makePolicyDefinition } from \"../makePolicy.js\";\nimport type { PolicyDefinition, PolicyFailure } from \"../policy.js\";\n\n/**\n * Policy settings for the NoLargeBinaryFiles repo policy.\n *\n * @alpha\n */\nexport interface NoLargeBinaryFilesSettings {\n\t/**\n\t * Maximum file size in bytes. Defaults to 10MB.\n\t */\n\tmaxSizeBytes?: number;\n\n\t/**\n\t * File extensions to exclude from size checking.\n\t * Useful for known large files that should be allowed.\n\t */\n\texcludeExtensions?: string[];\n\n\t/**\n\t * File patterns to exclude from size checking.\n\t * Uses glob-style patterns.\n\t */\n\texcludePatterns?: string[];\n}\n\n/**\n * Default maximum file size (10MB in bytes).\n */\nconst DEFAULT_MAX_SIZE = 10 * 1024 * 1024;\n\n/**\n * Default file extensions that are typically safe to exclude from size limits.\n */\nconst DEFAULT_EXCLUDE_EXTENSIONS = [\n\t\".md\",\n\t\".txt\",\n\t\".json\",\n\t\".js\",\n\t\".ts\",\n\t\".jsx\",\n\t\".tsx\",\n\t\".css\",\n\t\".scss\",\n\t\".sass\",\n\t\".less\",\n\t\".html\",\n\t\".xml\",\n\t\".yml\",\n\t\".yaml\",\n\t\".toml\",\n\t\".ini\",\n\t\".conf\",\n\t\".config\",\n];\n\n/**\n * Convert a glob pattern to a regex pattern by escaping special characters\n * and converting * to .* for wildcard matching.\n */\nfunction globToRegex(pattern: string): RegExp {\n\t// Escape all regex special characters except *\n\tconst escaped = pattern.replace(/[.+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\t// Convert * to .* for wildcard matching\n\tconst regexPattern = escaped.replace(/\\*/g, \".*\");\n\treturn new RegExp(`^${regexPattern}$`);\n}\n\n/**\n * Check if a file matches any of the exclude patterns.\n */\nfunction isExcluded(\n\tfilePath: string,\n\texcludePatterns: string[],\n\texcludeExtensions: string[],\n): boolean {\n\tconst ext = path.extname(filePath).toLowerCase();\n\n\t// Check extensions\n\tif (excludeExtensions.includes(ext)) {\n\t\treturn true;\n\t}\n\n\t// Check patterns (simple glob-like matching)\n\tfor (const pattern of excludePatterns) {\n\t\tif (pattern.includes(\"*\")) {\n\t\t\tconst regex = globToRegex(pattern);\n\t\t\tif (regex.test(filePath)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t} else if (filePath.includes(pattern)) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\n/**\n * Format bytes in a human-readable format.\n */\nfunction formatBytes(bytes: number): string {\n\tif (bytes === 0) {\n\t\treturn \"0 B\";\n\t}\n\tconst k = 1024;\n\tconst sizes = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\"];\n\tconst i = Math.min(\n\t\tMath.floor(Math.log(bytes) / Math.log(k)),\n\t\tsizes.length - 1,\n\t);\n\tconst formatted = (bytes / k ** i).toFixed(1);\n\treturn `${formatted} ${sizes[i]}`;\n}\n\n/**\n * A repo policy that prevents large binary files from being committed to the repository.\n * Large files can bloat the repository and slow down clones. Consider using Git LFS for large assets.\n *\n * @alpha\n */\nexport const NoLargeBinaryFiles: PolicyDefinition<NoLargeBinaryFilesSettings> =\n\tmakePolicyDefinition(\n\t\t\"NoLargeBinaryFiles\",\n\t\t// Match all files\n\t\t/.*/,\n\t\tasync ({ file, root, config }) => {\n\t\t\tconst maxSizeBytes = config?.maxSizeBytes ?? DEFAULT_MAX_SIZE;\n\t\t\tconst excludeExtensions =\n\t\t\t\tconfig?.excludeExtensions ?? DEFAULT_EXCLUDE_EXTENSIONS;\n\t\t\tconst excludePatterns = config?.excludePatterns ?? [];\n\n\t\t\t// Skip excluded files\n\t\t\tif (isExcluded(file, excludePatterns, excludeExtensions)) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst filePath = path.resolve(root, file);\n\t\t\t\tconst stats = statSync(filePath);\n\n\t\t\t\t// Skip directories\n\t\t\t\tif (stats.isDirectory()) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tif (stats.size > maxSizeBytes) {\n\t\t\t\t\tconst result: PolicyFailure = {\n\t\t\t\t\t\tname: NoLargeBinaryFiles.name,\n\t\t\t\t\t\tfile,\n\t\t\t\t\t\tautoFixable: false,\n\t\t\t\t\t\terrorMessage: `File is too large: ${formatBytes(stats.size)} (max: ${formatBytes(maxSizeBytes)}). Consider using Git LFS or removing the file.`,\n\t\t\t\t\t};\n\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\t\t\t} catch (_error: unknown) {\n\t\t\t\t// File doesn't exist or can't be accessed, skip it\n\t\t\t\treturn true;\n\t\t\t}\n\t\t},\n\t);\n"]}
|
|
@@ -15,5 +15,5 @@ export interface PackageJsonPropertiesSettings {
|
|
|
15
15
|
*
|
|
16
16
|
* @alpha
|
|
17
17
|
*/
|
|
18
|
-
export declare const PackageJsonProperties: import("../policy.js").
|
|
18
|
+
export declare const PackageJsonProperties: import("../policy.js").PolicyDefinition<PackageJsonPropertiesSettings | undefined>;
|
|
19
19
|
//# sourceMappingURL=PackageJsonProperties.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PackageJsonProperties.d.ts","sourceRoot":"","sources":["../../src/policies/PackageJsonProperties.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAM7C;;;;GAIG;AACH,MAAM,WAAW,6BAA6B;IAC7C;;OAEG;IACH,QAAQ,EAAE,WAAW,CAAC;CACtB;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,
|
|
1
|
+
{"version":3,"file":"PackageJsonProperties.d.ts","sourceRoot":"","sources":["../../src/policies/PackageJsonProperties.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAM7C;;;;GAIG;AACH,MAAM,WAAW,6BAA6B;IAC7C;;OAEG;IACH,QAAQ,EAAE,WAAW,CAAC;CACtB;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,oFA4ChC,CAAC"}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { defu } from "defu";
|
|
2
2
|
import jsonfile from "jsonfile";
|
|
3
3
|
import diff from "microdiff";
|
|
4
|
-
import {
|
|
4
|
+
import { definePackagePolicy } from "../policyDefiners/definePackagePolicy.js";
|
|
5
5
|
const { writeFile: writeJson } = jsonfile;
|
|
6
6
|
/**
|
|
7
7
|
* A RepoPolicy that checks that package.json properties in packages match expected values.
|
|
8
8
|
*
|
|
9
9
|
* @alpha
|
|
10
10
|
*/
|
|
11
|
-
export const PackageJsonProperties =
|
|
11
|
+
export const PackageJsonProperties = definePackagePolicy("PackageJsonProperties", async (json, { file, config, resolve }) => {
|
|
12
12
|
if (config === undefined) {
|
|
13
13
|
return true;
|
|
14
14
|
}
|
|
@@ -18,7 +18,7 @@ export const PackageJsonProperties = generatePackagePolicy("PackageJsonPropertie
|
|
|
18
18
|
file,
|
|
19
19
|
autoFixable: true,
|
|
20
20
|
};
|
|
21
|
-
const merged = defu(
|
|
21
|
+
const merged = defu(verbatim, json);
|
|
22
22
|
const result = diff(merged, json);
|
|
23
23
|
const messages = [];
|
|
24
24
|
for (const diffResult of result) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PackageJsonProperties.js","sourceRoot":"","sources":["../../src/policies/PackageJsonProperties.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"PackageJsonProperties.js","sourceRoot":"","sources":["../../src/policies/PackageJsonProperties.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,OAAO,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AAE/E,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAC;AAc1C;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,mBAAmB,CAGtD,uBAAuB,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;IACpE,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC;IACb,CAAC;IACD,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC;IAE5B,MAAM,UAAU,GAAkB;QACjC,IAAI,EAAE,qBAAqB,CAAC,IAAI;QAChC,IAAI;QACJ,WAAW,EAAE,IAAI;KACjB,CAAC;IAEF,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACpC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAElC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,MAAM,UAAU,IAAI,MAAM,EAAE,CAAC;QACjC,QAAQ,CAAC,IAAI,CACZ,2CAA2C,UAAU,CAAC,IAAI,IAAI,CAC9D,CAAC;IACH,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,IAAI,OAAO,EAAE,CAAC;YACb,MAAM,SAAS,GAAoB;gBAClC,GAAG,UAAU;gBACb,QAAQ,EAAE,KAAK;aACf,CAAC;YAEF,MAAM,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;YAEhD,SAAS,CAAC,QAAQ,GAAG,IAAI,CAAC;YAC1B,OAAO,SAAS,CAAC;QAClB,CAAC;QAED,2EAA2E;QAC3E,UAAU,CAAC,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9C,OAAO,UAAU,CAAC;IACnB,CAAC;IAED,OAAO,IAAI,CAAC;AACb,CAAC,CAAC,CAAC","sourcesContent":["import { defu } from \"defu\";\nimport jsonfile from \"jsonfile\";\nimport diff from \"microdiff\";\nimport type { PackageJson } from \"type-fest\";\nimport type { PolicyFailure, PolicyFixResult } from \"../policy.js\";\nimport { definePackagePolicy } from \"../policyDefiners/definePackagePolicy.js\";\n\nconst { writeFile: writeJson } = jsonfile;\n\n/**\n * Policy settings for the PackageJsonProperties repo policy.\n *\n * @alpha\n */\nexport interface PackageJsonPropertiesSettings {\n\t/**\n\t * Sets a package.json property to the value provided. The value will be used verbatim.\n\t */\n\tverbatim: PackageJson;\n}\n\n/**\n * A RepoPolicy that checks that package.json properties in packages match expected values.\n *\n * @alpha\n */\nexport const PackageJsonProperties = definePackagePolicy<\n\tPackageJson,\n\tPackageJsonPropertiesSettings | undefined\n>(\"PackageJsonProperties\", async (json, { file, config, resolve }) => {\n\tif (config === undefined) {\n\t\treturn true;\n\t}\n\tconst { verbatim } = config;\n\n\tconst failResult: PolicyFailure = {\n\t\tname: PackageJsonProperties.name,\n\t\tfile,\n\t\tautoFixable: true,\n\t};\n\n\tconst merged = defu(verbatim, json);\n\tconst result = diff(merged, json);\n\n\tconst messages: string[] = [];\n\tfor (const diffResult of result) {\n\t\tmessages.push(\n\t\t\t`Incorrect package.json field value for '${diffResult.path}'.`,\n\t\t);\n\t}\n\n\tif (messages.length > 0) {\n\t\tif (resolve) {\n\t\t\tconst fixResult: PolicyFixResult = {\n\t\t\t\t...failResult,\n\t\t\t\tresolved: false,\n\t\t\t};\n\n\t\t\tawait writeJson(file, merged, { spaces: \"\\t\" });\n\n\t\t\tfixResult.resolved = true;\n\t\t\treturn fixResult;\n\t\t}\n\n\t\t// There were errors, and we're not resolving them, so return a fail result\n\t\tfailResult.errorMessage = messages.join(\"\\n\");\n\t\treturn failResult;\n\t}\n\n\treturn true;\n});\n"]}
|
|
@@ -4,5 +4,5 @@
|
|
|
4
4
|
*
|
|
5
5
|
* @alpha
|
|
6
6
|
*/
|
|
7
|
-
export declare const PackageJsonRepoDirectoryProperty: import("../policy.js").
|
|
7
|
+
export declare const PackageJsonRepoDirectoryProperty: import("../policy.js").PolicyDefinition<undefined>;
|
|
8
8
|
//# sourceMappingURL=PackageJsonRepoDirectoryProperty.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PackageJsonRepoDirectoryProperty.d.ts","sourceRoot":"","sources":["../../src/policies/PackageJsonRepoDirectoryProperty.ts"],"names":[],"mappings":"AAOA;;;;;GAKG;AACH,eAAO,MAAM,gCAAgC,
|
|
1
|
+
{"version":3,"file":"PackageJsonRepoDirectoryProperty.d.ts","sourceRoot":"","sources":["../../src/policies/PackageJsonRepoDirectoryProperty.ts"],"names":[],"mappings":"AAOA;;;;;GAKG;AACH,eAAO,MAAM,gCAAgC,oDAgD3C,CAAC"}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
2
|
import { updatePackageJsonFile } from "@fluid-tools/build-infrastructure";
|
|
3
3
|
import path from "pathe";
|
|
4
|
-
import {
|
|
4
|
+
import { definePackagePolicy } from "../policyDefiners/definePackagePolicy.js";
|
|
5
5
|
/**
|
|
6
6
|
* A RepoPolicy that checks that the repository.directory property in package.json is set correctly. If the repository
|
|
7
7
|
* field is a string instead of an object the package will be ignored.
|
|
8
8
|
*
|
|
9
9
|
* @alpha
|
|
10
10
|
*/
|
|
11
|
-
export const PackageJsonRepoDirectoryProperty =
|
|
11
|
+
export const PackageJsonRepoDirectoryProperty = definePackagePolicy("PackageJsonRepoDirectoryProperty", async (json, { file, root, resolve }) => {
|
|
12
12
|
const failResult = {
|
|
13
13
|
name: PackageJsonRepoDirectoryProperty.name,
|
|
14
14
|
file,
|
|
@@ -21,31 +21,30 @@ export const PackageJsonRepoDirectoryProperty = generatePackagePolicy("PackageJs
|
|
|
21
21
|
const pkgDir = path.dirname(file);
|
|
22
22
|
const maybeDir = path.relative(root, pkgDir);
|
|
23
23
|
const relativePkgDir = maybeDir === "" ? undefined : maybeDir;
|
|
24
|
-
if (typeof json.repository === "object"
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
catch (error) {
|
|
41
|
-
fixResult.resolved = false;
|
|
42
|
-
fixResult.errorMessage = `${error.message}\n${error.stack}`;
|
|
43
|
-
}
|
|
44
|
-
return fixResult;
|
|
24
|
+
if (typeof json.repository === "object" &&
|
|
25
|
+
json.repository.directory !== relativePkgDir) {
|
|
26
|
+
if (resolve) {
|
|
27
|
+
try {
|
|
28
|
+
// biome-ignore lint/nursery/noShadow: no need to use shadowed variable
|
|
29
|
+
updatePackageJsonFile(file, (json) => {
|
|
30
|
+
assert(typeof json.repository === "object");
|
|
31
|
+
if (relativePkgDir === undefined) {
|
|
32
|
+
delete json.repository.directory;
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
json.repository.directory = relativePkgDir;
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
fixResult.resolved = true;
|
|
45
39
|
}
|
|
46
|
-
|
|
47
|
-
|
|
40
|
+
catch (error) {
|
|
41
|
+
fixResult.resolved = false;
|
|
42
|
+
fixResult.errorMessage = `${error.message}\n${error.stack}`;
|
|
43
|
+
}
|
|
44
|
+
return fixResult;
|
|
48
45
|
}
|
|
46
|
+
failResult.errorMessage = `repository.directory value is wrong. Expected '${relativePkgDir}', got '${json.repository.directory}'`;
|
|
47
|
+
return failResult;
|
|
49
48
|
}
|
|
50
49
|
return true;
|
|
51
50
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PackageJsonRepoDirectoryProperty.js","sourceRoot":"","sources":["../../src/policies/PackageJsonRepoDirectoryProperty.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,IAAI,MAAM,OAAO,CAAC;AAGzB,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"PackageJsonRepoDirectoryProperty.js","sourceRoot":"","sources":["../../src/policies/PackageJsonRepoDirectoryProperty.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,IAAI,MAAM,OAAO,CAAC;AAGzB,OAAO,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AAE/E;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gCAAgC,GAAG,mBAAmB,CAGjE,kCAAkC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE;IAC7E,MAAM,UAAU,GAAkB;QACjC,IAAI,EAAE,gCAAgC,CAAC,IAAI;QAC3C,IAAI;QACJ,WAAW,EAAE,IAAI;KACjB,CAAC;IAEF,MAAM,SAAS,GAAoB;QAClC,GAAG,UAAU;QACb,QAAQ,EAAE,KAAK;KACf,CAAC;IAEF,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC7C,MAAM,cAAc,GAAG,QAAQ,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;IAE9D,IACC,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ;QACnC,IAAI,CAAC,UAAU,CAAC,SAAS,KAAK,cAAc,EAC3C,CAAC;QACF,IAAI,OAAO,EAAE,CAAC;YACb,IAAI,CAAC;gBACJ,uEAAuE;gBACvE,qBAAqB,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE;oBACpC,MAAM,CAAC,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC;oBAC5C,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;wBAClC,OAAO,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;oBAClC,CAAC;yBAAM,CAAC;wBACP,IAAI,CAAC,UAAU,CAAC,SAAS,GAAG,cAAc,CAAC;oBAC5C,CAAC;gBACF,CAAC,CAAC,CAAC;gBACH,SAAS,CAAC,QAAQ,GAAG,IAAI,CAAC;YAC3B,CAAC;YAAC,OAAO,KAAc,EAAE,CAAC;gBACzB,SAAS,CAAC,QAAQ,GAAG,KAAK,CAAC;gBAC3B,SAAS,CAAC,YAAY,GAAG,GAAI,KAAe,CAAC,OAAO,KAClD,KAAe,CAAC,KAClB,EAAE,CAAC;YACJ,CAAC;YACD,OAAO,SAAS,CAAC;QAClB,CAAC;QACD,UAAU,CAAC,YAAY,GAAG,kDAAkD,cAAc,WAAW,IAAI,CAAC,UAAU,CAAC,SAAS,GAAG,CAAC;QAClI,OAAO,UAAU,CAAC;IACnB,CAAC;IAED,OAAO,IAAI,CAAC;AACb,CAAC,CAAC,CAAC","sourcesContent":["import assert from \"node:assert/strict\";\nimport { updatePackageJsonFile } from \"@fluid-tools/build-infrastructure\";\nimport path from \"pathe\";\nimport type { PackageJson } from \"type-fest\";\nimport type { PolicyFailure, PolicyFixResult } from \"../policy.js\";\nimport { definePackagePolicy } from \"../policyDefiners/definePackagePolicy.js\";\n\n/**\n * A RepoPolicy that checks that the repository.directory property in package.json is set correctly. If the repository\n * field is a string instead of an object the package will be ignored.\n *\n * @alpha\n */\nexport const PackageJsonRepoDirectoryProperty = definePackagePolicy<\n\tPackageJson,\n\tundefined\n>(\"PackageJsonRepoDirectoryProperty\", async (json, { file, root, resolve }) => {\n\tconst failResult: PolicyFailure = {\n\t\tname: PackageJsonRepoDirectoryProperty.name,\n\t\tfile,\n\t\tautoFixable: true,\n\t};\n\n\tconst fixResult: PolicyFixResult = {\n\t\t...failResult,\n\t\tresolved: false,\n\t};\n\n\tconst pkgDir = path.dirname(file);\n\tconst maybeDir = path.relative(root, pkgDir);\n\tconst relativePkgDir = maybeDir === \"\" ? undefined : maybeDir;\n\n\tif (\n\t\ttypeof json.repository === \"object\" &&\n\t\tjson.repository.directory !== relativePkgDir\n\t) {\n\t\tif (resolve) {\n\t\t\ttry {\n\t\t\t\t// biome-ignore lint/nursery/noShadow: no need to use shadowed variable\n\t\t\t\tupdatePackageJsonFile(file, (json) => {\n\t\t\t\t\tassert(typeof json.repository === \"object\");\n\t\t\t\t\tif (relativePkgDir === undefined) {\n\t\t\t\t\t\tdelete json.repository.directory;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tjson.repository.directory = relativePkgDir;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tfixResult.resolved = true;\n\t\t\t} catch (error: unknown) {\n\t\t\t\tfixResult.resolved = false;\n\t\t\t\tfixResult.errorMessage = `${(error as Error).message}\\n${\n\t\t\t\t\t(error as Error).stack\n\t\t\t\t}`;\n\t\t\t}\n\t\t\treturn fixResult;\n\t\t}\n\t\tfailResult.errorMessage = `repository.directory value is wrong. Expected '${relativePkgDir}', got '${json.repository.directory}'`;\n\t\treturn failResult;\n\t}\n\n\treturn true;\n});\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PackageJsonSorted.d.ts","sourceRoot":"","sources":["../../src/policies/PackageJsonSorted.ts"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,
|
|
1
|
+
{"version":3,"file":"PackageJsonSorted.d.ts","sourceRoot":"","sources":["../../src/policies/PackageJsonSorted.ts"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,oDAuC7B,CAAC"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { updatePackageJsonFile } from "@tylerbu/cli-api";
|
|
2
2
|
import { sortPackageJson } from "sort-package-json";
|
|
3
|
-
import {
|
|
3
|
+
import { definePackagePolicy } from "../policyDefiners/definePackagePolicy.js";
|
|
4
4
|
/**
|
|
5
5
|
* A repo policy that checks if package.json files in the repo are sorted using sort-package-json.
|
|
6
6
|
*
|
|
7
7
|
* @alpha
|
|
8
8
|
*/
|
|
9
|
-
export const PackageJsonSorted =
|
|
9
|
+
export const PackageJsonSorted = definePackagePolicy("PackageJsonSorted", async (json, { file, resolve }) => {
|
|
10
10
|
const sortedJson = sortPackageJson(json);
|
|
11
11
|
const isSorted = JSON.stringify(sortedJson) === JSON.stringify(json);
|
|
12
12
|
if (isSorted) {
|
|
@@ -14,6 +14,7 @@ export const PackageJsonSorted = generatePackagePolicy("PackageJsonSorted", asyn
|
|
|
14
14
|
}
|
|
15
15
|
if (resolve) {
|
|
16
16
|
try {
|
|
17
|
+
// biome-ignore lint/nursery/noShadow: no need to use the shadowed variable
|
|
17
18
|
await updatePackageJsonFile(file, (json) => json, { sort: true });
|
|
18
19
|
const result = {
|
|
19
20
|
name: PackageJsonSorted.name,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PackageJsonSorted.js","sourceRoot":"","sources":["../../src/policies/PackageJsonSorted.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"PackageJsonSorted.js","sourceRoot":"","sources":["../../src/policies/PackageJsonSorted.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AAE/E;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,mBAAmB,CACnD,mBAAmB,EACnB,KAAK,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE;IACjC,MAAM,UAAU,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAErE,IAAI,QAAQ,EAAE,CAAC;QACd,OAAO,IAAI,CAAC;IACb,CAAC;IAED,IAAI,OAAO,EAAE,CAAC;QACb,IAAI,CAAC;YACJ,2EAA2E;YAC3E,MAAM,qBAAqB,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAClE,MAAM,MAAM,GAAoB;gBAC/B,IAAI,EAAE,iBAAiB,CAAC,IAAI;gBAC5B,IAAI;gBACJ,QAAQ,EAAE,IAAI;aACd,CAAC;YACF,OAAO,MAAM,CAAC;QACf,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACzB,MAAM,MAAM,GAAoB;gBAC/B,IAAI,EAAE,iBAAiB,CAAC,IAAI;gBAC5B,IAAI;gBACJ,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,IAAI;gBACjB,YAAY,EAAG,KAAe,CAAC,OAAO;aACtC,CAAC;YACF,OAAO,MAAM,CAAC;QACf,CAAC;IACF,CAAC;SAAM,CAAC;QACP,MAAM,MAAM,GAAkB;YAC7B,IAAI,EAAE,iBAAiB,CAAC,IAAI;YAC5B,IAAI;YACJ,WAAW,EAAE,IAAI;SACjB,CAAC;QACF,OAAO,MAAM,CAAC;IACf,CAAC;AACF,CAAC,CACD,CAAC","sourcesContent":["import { updatePackageJsonFile } from \"@tylerbu/cli-api\";\nimport { sortPackageJson } from \"sort-package-json\";\nimport type { PolicyFailure, PolicyFixResult } from \"../policy.js\";\nimport { definePackagePolicy } from \"../policyDefiners/definePackagePolicy.js\";\n\n/**\n * A repo policy that checks if package.json files in the repo are sorted using sort-package-json.\n *\n * @alpha\n */\nexport const PackageJsonSorted = definePackagePolicy(\n\t\"PackageJsonSorted\",\n\tasync (json, { file, resolve }) => {\n\t\tconst sortedJson = sortPackageJson(json);\n\t\tconst isSorted = JSON.stringify(sortedJson) === JSON.stringify(json);\n\n\t\tif (isSorted) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (resolve) {\n\t\t\ttry {\n\t\t\t\t// biome-ignore lint/nursery/noShadow: no need to use the shadowed variable\n\t\t\t\tawait updatePackageJsonFile(file, (json) => json, { sort: true });\n\t\t\t\tconst result: PolicyFixResult = {\n\t\t\t\t\tname: PackageJsonSorted.name,\n\t\t\t\t\tfile,\n\t\t\t\t\tresolved: true,\n\t\t\t\t};\n\t\t\t\treturn result;\n\t\t\t} catch (error: unknown) {\n\t\t\t\tconst result: PolicyFixResult = {\n\t\t\t\t\tname: PackageJsonSorted.name,\n\t\t\t\t\tfile,\n\t\t\t\t\tresolved: false,\n\t\t\t\t\tautoFixable: true,\n\t\t\t\t\terrorMessage: (error as Error).message,\n\t\t\t\t};\n\t\t\t\treturn result;\n\t\t\t}\n\t\t} else {\n\t\t\tconst result: PolicyFailure = {\n\t\t\t\tname: PackageJsonSorted.name,\n\t\t\t\tfile,\n\t\t\t\tautoFixable: true,\n\t\t\t};\n\t\t\treturn result;\n\t\t}\n\t},\n);\n"]}
|
|
@@ -1,7 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Policy settings for the PackageScripts repo policy.
|
|
3
3
|
*
|
|
4
4
|
* @alpha
|
|
5
5
|
*/
|
|
6
|
-
export
|
|
6
|
+
export interface PackageScriptsSettings {
|
|
7
|
+
/**
|
|
8
|
+
* List of script names that must be present in package.json scripts.
|
|
9
|
+
*/
|
|
10
|
+
must?: string[];
|
|
11
|
+
/**
|
|
12
|
+
* List of mutually exclusive script groups. Each group is an array of script names
|
|
13
|
+
* where at most one script from the group can be present.
|
|
14
|
+
*
|
|
15
|
+
* Packages can have zero scripts from the group (all optional), but cannot have
|
|
16
|
+
* multiple scripts from the same group.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* // Allow "test:unit" OR "test:vitest" OR neither, but not both
|
|
20
|
+
* mutuallyExclusive: [["test:unit", "test:vitest"]]
|
|
21
|
+
*/
|
|
22
|
+
mutuallyExclusive?: string[][];
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* A RepoPolicy that validates package.json scripts based on configurable rules.
|
|
26
|
+
*
|
|
27
|
+
* @alpha
|
|
28
|
+
*/
|
|
29
|
+
export declare const PackageScripts: import("../policy.js").PolicyDefinition<PackageScriptsSettings | undefined>;
|
|
7
30
|
//# sourceMappingURL=PackageScripts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PackageScripts.d.ts","sourceRoot":"","sources":["../../src/policies/PackageScripts.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PackageScripts.d.ts","sourceRoot":"","sources":["../../src/policies/PackageScripts.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACtC;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAEhB;;;;;;;;;;OAUG;IACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;CAC/B;AAgDD;;;;GAIG;AACH,eAAO,MAAM,cAAc,6EAoCzB,CAAC"}
|
|
@@ -1,23 +1,60 @@
|
|
|
1
|
-
import {
|
|
2
|
-
const expectedScripts = ["build", "clean"];
|
|
1
|
+
import { definePackagePolicy } from "../policyDefiners/definePackagePolicy.js";
|
|
3
2
|
/**
|
|
4
|
-
*
|
|
3
|
+
* Validates required scripts and returns error messages for missing scripts.
|
|
4
|
+
*/
|
|
5
|
+
function validateRequiredScripts(must, scripts) {
|
|
6
|
+
const missingScripts = [];
|
|
7
|
+
for (const scriptName of must) {
|
|
8
|
+
if (!(scripts && Object.hasOwn(scripts, scriptName))) {
|
|
9
|
+
missingScripts.push(scriptName);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
if (missingScripts.length > 0) {
|
|
13
|
+
return [`Missing required scripts:\n\t${missingScripts.join("\n\t")}`];
|
|
14
|
+
}
|
|
15
|
+
return [];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Validates mutually exclusive script groups and returns error messages for violations.
|
|
19
|
+
*/
|
|
20
|
+
function validateMutuallyExclusiveScripts(groups, scripts) {
|
|
21
|
+
const errors = [];
|
|
22
|
+
for (const group of groups) {
|
|
23
|
+
const presentScripts = group.filter((scriptName) => scripts && Object.hasOwn(scripts, scriptName));
|
|
24
|
+
// Only fail if MORE than one script from the group is present
|
|
25
|
+
if (presentScripts.length > 1) {
|
|
26
|
+
errors.push(`Scripts are mutually exclusive, but found ${presentScripts.length}: ${presentScripts.join(", ")}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return errors;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* A RepoPolicy that validates package.json scripts based on configurable rules.
|
|
5
33
|
*
|
|
6
34
|
* @alpha
|
|
7
35
|
*/
|
|
8
|
-
export const PackageScripts =
|
|
36
|
+
export const PackageScripts = definePackagePolicy("PackageScripts", async (json, { file, config }) => {
|
|
9
37
|
const failResult = {
|
|
10
38
|
name: PackageScripts.name,
|
|
11
39
|
file,
|
|
12
40
|
autoFixable: false,
|
|
13
41
|
};
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
if (hasScriptsField) {
|
|
17
|
-
missingScripts.push(...expectedScripts.filter((script) => !Object.prototype.hasOwnProperty.call(json.scripts, script)));
|
|
42
|
+
if (config === undefined) {
|
|
43
|
+
return true;
|
|
18
44
|
}
|
|
19
|
-
|
|
20
|
-
|
|
45
|
+
const hasScriptsField = Object.hasOwn(json, "scripts");
|
|
46
|
+
const scripts = hasScriptsField ? json.scripts : {};
|
|
47
|
+
const errorMessages = [];
|
|
48
|
+
// Validate required scripts
|
|
49
|
+
if (config.must && config.must.length > 0) {
|
|
50
|
+
errorMessages.push(...validateRequiredScripts(config.must, scripts));
|
|
51
|
+
}
|
|
52
|
+
// Validate mutually exclusive script groups
|
|
53
|
+
if (config.mutuallyExclusive && config.mutuallyExclusive.length > 0) {
|
|
54
|
+
errorMessages.push(...validateMutuallyExclusiveScripts(config.mutuallyExclusive, scripts));
|
|
55
|
+
}
|
|
56
|
+
if (errorMessages.length > 0) {
|
|
57
|
+
failResult.errorMessage = errorMessages.join("\n\n");
|
|
21
58
|
return failResult;
|
|
22
59
|
}
|
|
23
60
|
return true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PackageScripts.js","sourceRoot":"","sources":["../../src/policies/PackageScripts.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PackageScripts.js","sourceRoot":"","sources":["../../src/policies/PackageScripts.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AA2B/E;;GAEG;AACH,SAAS,uBAAuB,CAC/B,IAAc,EACd,OAA+B;IAE/B,MAAM,cAAc,GAAa,EAAE,CAAC;IACpC,KAAK,MAAM,UAAU,IAAI,IAAI,EAAE,CAAC;QAC/B,IAAI,CAAC,CAAC,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC;YACtD,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACjC,CAAC;IACF,CAAC;IAED,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,OAAO,CAAC,gCAAgC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,OAAO,EAAE,CAAC;AACX,CAAC;AAED;;GAEG;AACH,SAAS,gCAAgC,CACxC,MAAkB,EAClB,OAA+B;IAE/B,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC5B,MAAM,cAAc,GAAG,KAAK,CAAC,MAAM,CAClC,CAAC,UAAU,EAAE,EAAE,CAAC,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,CAC7D,CAAC;QAEF,8DAA8D;QAC9D,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/B,MAAM,CAAC,IAAI,CACV,6CAA6C,cAAc,CAAC,MAAM,KAAK,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAClG,CAAC;QACH,CAAC;IACF,CAAC;IAED,OAAO,MAAM,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,mBAAmB,CAG/C,gBAAgB,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE;IACpD,MAAM,UAAU,GAAkB;QACjC,IAAI,EAAE,cAAc,CAAC,IAAI;QACzB,IAAI;QACJ,WAAW,EAAE,KAAK;KAClB,CAAC;IAEF,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC;IACb,CAAC;IAED,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IACpD,MAAM,aAAa,GAAa,EAAE,CAAC;IAEnC,4BAA4B;IAC5B,IAAI,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3C,aAAa,CAAC,IAAI,CAAC,GAAG,uBAAuB,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IACtE,CAAC;IAED,4CAA4C;IAC5C,IAAI,MAAM,CAAC,iBAAiB,IAAI,MAAM,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrE,aAAa,CAAC,IAAI,CACjB,GAAG,gCAAgC,CAAC,MAAM,CAAC,iBAAiB,EAAE,OAAO,CAAC,CACtE,CAAC;IACH,CAAC;IAED,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,UAAU,CAAC,YAAY,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACrD,OAAO,UAAU,CAAC;IACnB,CAAC;IAED,OAAO,IAAI,CAAC;AACb,CAAC,CAAC,CAAC","sourcesContent":["import type { PackageJson } from \"type-fest\";\nimport type { PolicyFailure } from \"../policy.js\";\nimport { definePackagePolicy } from \"../policyDefiners/definePackagePolicy.js\";\n\n/**\n * Policy settings for the PackageScripts repo policy.\n *\n * @alpha\n */\nexport interface PackageScriptsSettings {\n\t/**\n\t * List of script names that must be present in package.json scripts.\n\t */\n\tmust?: string[];\n\n\t/**\n\t * List of mutually exclusive script groups. Each group is an array of script names\n\t * where at most one script from the group can be present.\n\t *\n\t * Packages can have zero scripts from the group (all optional), but cannot have\n\t * multiple scripts from the same group.\n\t *\n\t * @example\n\t * // Allow \"test:unit\" OR \"test:vitest\" OR neither, but not both\n\t * mutuallyExclusive: [[\"test:unit\", \"test:vitest\"]]\n\t */\n\tmutuallyExclusive?: string[][];\n}\n\n/**\n * Validates required scripts and returns error messages for missing scripts.\n */\nfunction validateRequiredScripts(\n\tmust: string[],\n\tscripts: PackageJson[\"scripts\"],\n): string[] {\n\tconst missingScripts: string[] = [];\n\tfor (const scriptName of must) {\n\t\tif (!(scripts && Object.hasOwn(scripts, scriptName))) {\n\t\t\tmissingScripts.push(scriptName);\n\t\t}\n\t}\n\n\tif (missingScripts.length > 0) {\n\t\treturn [`Missing required scripts:\\n\\t${missingScripts.join(\"\\n\\t\")}`];\n\t}\n\n\treturn [];\n}\n\n/**\n * Validates mutually exclusive script groups and returns error messages for violations.\n */\nfunction validateMutuallyExclusiveScripts(\n\tgroups: string[][],\n\tscripts: PackageJson[\"scripts\"],\n): string[] {\n\tconst errors: string[] = [];\n\n\tfor (const group of groups) {\n\t\tconst presentScripts = group.filter(\n\t\t\t(scriptName) => scripts && Object.hasOwn(scripts, scriptName),\n\t\t);\n\n\t\t// Only fail if MORE than one script from the group is present\n\t\tif (presentScripts.length > 1) {\n\t\t\terrors.push(\n\t\t\t\t`Scripts are mutually exclusive, but found ${presentScripts.length}: ${presentScripts.join(\", \")}`,\n\t\t\t);\n\t\t}\n\t}\n\n\treturn errors;\n}\n\n/**\n * A RepoPolicy that validates package.json scripts based on configurable rules.\n *\n * @alpha\n */\nexport const PackageScripts = definePackagePolicy<\n\tPackageJson,\n\tPackageScriptsSettings | undefined\n>(\"PackageScripts\", async (json, { file, config }) => {\n\tconst failResult: PolicyFailure = {\n\t\tname: PackageScripts.name,\n\t\tfile,\n\t\tautoFixable: false,\n\t};\n\n\tif (config === undefined) {\n\t\treturn true;\n\t}\n\n\tconst hasScriptsField = Object.hasOwn(json, \"scripts\");\n\tconst scripts = hasScriptsField ? json.scripts : {};\n\tconst errorMessages: string[] = [];\n\n\t// Validate required scripts\n\tif (config.must && config.must.length > 0) {\n\t\terrorMessages.push(...validateRequiredScripts(config.must, scripts));\n\t}\n\n\t// Validate mutually exclusive script groups\n\tif (config.mutuallyExclusive && config.mutuallyExclusive.length > 0) {\n\t\terrorMessages.push(\n\t\t\t...validateMutuallyExclusiveScripts(config.mutuallyExclusive, scripts),\n\t\t);\n\t}\n\n\tif (errorMessages.length > 0) {\n\t\tfailResult.errorMessage = errorMessages.join(\"\\n\\n\");\n\t\treturn failResult;\n\t}\n\n\treturn true;\n});\n"]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { PolicyDefinition } from "../policy.js";
|
|
2
|
+
/**
|
|
3
|
+
* Policy settings for the RequiredGitignorePatterns repo policy.
|
|
4
|
+
*
|
|
5
|
+
* @alpha
|
|
6
|
+
*/
|
|
7
|
+
export interface RequiredGitignorePatternsSettings {
|
|
8
|
+
/**
|
|
9
|
+
* Array of patterns that must be present in .gitignore.
|
|
10
|
+
* Each pattern can be a string or an object with pattern and comment.
|
|
11
|
+
*/
|
|
12
|
+
patterns: Array<string | {
|
|
13
|
+
pattern: string;
|
|
14
|
+
comment?: string;
|
|
15
|
+
}>;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* A repo policy that ensures .gitignore contains required patterns to prevent
|
|
19
|
+
* committing sensitive files, dependencies, and build artifacts.
|
|
20
|
+
*
|
|
21
|
+
* @alpha
|
|
22
|
+
*/
|
|
23
|
+
export declare const RequiredGitignorePatterns: PolicyDefinition<RequiredGitignorePatternsSettings>;
|
|
24
|
+
//# sourceMappingURL=RequiredGitignorePatterns.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RequiredGitignorePatterns.d.ts","sourceRoot":"","sources":["../../src/policies/RequiredGitignorePatterns.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACX,gBAAgB,EAGhB,MAAM,cAAc,CAAC;AAEtB;;;;GAIG;AACH,MAAM,WAAW,iCAAiC;IACjD;;;OAGG;IACH,QAAQ,EAAE,KAAK,CAAC,MAAM,GAAG;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChE;AAmMD;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,EAAE,gBAAgB,CAAC,iCAAiC,CAcxF,CAAC"}
|