repopo 0.9.0 → 0.12.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 +81 -0
- package/README.md +41 -2
- package/THIRD-PARTY-LICENSES.txt +71 -11
- package/bin/dev.js +5 -1
- package/esm/baseCommand.d.ts +1 -1
- package/esm/baseCommand.d.ts.map +1 -1
- package/esm/baseCommand.js +6 -9
- package/esm/baseCommand.js.map +1 -1
- package/esm/commands/check-native.d.ts +25 -0
- package/esm/commands/check-native.d.ts.map +1 -0
- package/esm/commands/check-native.js +137 -0
- package/esm/commands/check-native.js.map +1 -0
- package/esm/commands/check.d.ts +8 -19
- package/esm/commands/check.d.ts.map +1 -1
- package/esm/commands/check.js +97 -169
- package/esm/commands/check.js.map +1 -1
- package/esm/commands/list.d.ts.map +1 -1
- package/esm/commands/list.js +5 -6
- package/esm/commands/list.js.map +1 -1
- package/esm/config.d.ts +19 -4
- package/esm/config.d.ts.map +1 -1
- package/esm/config.js +2 -3
- package/esm/config.js.map +1 -1
- package/esm/context.d.ts +13 -3
- package/esm/context.d.ts.map +1 -1
- package/esm/context.js +11 -1
- package/esm/context.js.map +1 -1
- package/esm/index.d.ts +7 -2
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +9 -1
- package/esm/index.js.map +1 -1
- package/esm/makePolicy.d.ts +77 -8
- package/esm/makePolicy.d.ts.map +1 -1
- package/esm/makePolicy.js +108 -4
- package/esm/makePolicy.js.map +1 -1
- package/esm/perf.d.ts +7 -2
- package/esm/perf.d.ts.map +1 -1
- package/esm/perf.js.map +1 -1
- package/esm/policies/CargoLicenceValidated.d.ts +41 -0
- package/esm/policies/CargoLicenceValidated.d.ts.map +1 -0
- package/esm/policies/CargoLicenceValidated.js +45 -0
- package/esm/policies/CargoLicenceValidated.js.map +1 -0
- package/esm/policies/CargoLintsConfigured.d.ts +30 -0
- package/esm/policies/CargoLintsConfigured.d.ts.map +1 -0
- package/esm/policies/CargoLintsConfigured.js +61 -0
- package/esm/policies/CargoLintsConfigured.js.map +1 -0
- package/esm/policies/CargoLockPolicy.d.ts +34 -0
- package/esm/policies/CargoLockPolicy.d.ts.map +1 -0
- package/esm/policies/CargoLockPolicy.js +57 -0
- package/esm/policies/CargoLockPolicy.js.map +1 -0
- package/esm/policies/CargoTomlRequired.d.ts +34 -0
- package/esm/policies/CargoTomlRequired.d.ts.map +1 -0
- package/esm/policies/CargoTomlRequired.js +77 -0
- package/esm/policies/CargoTomlRequired.js.map +1 -0
- package/esm/policies/CargoTomlSorted.d.ts +20 -0
- package/esm/policies/CargoTomlSorted.d.ts.map +1 -0
- package/esm/policies/CargoTomlSorted.js +164 -0
- package/esm/policies/CargoTomlSorted.js.map +1 -0
- package/esm/policies/ConditionalScripts.d.ts +94 -0
- package/esm/policies/ConditionalScripts.d.ts.map +1 -0
- package/esm/policies/ConditionalScripts.js +145 -0
- package/esm/policies/ConditionalScripts.js.map +1 -0
- package/esm/policies/ExactScripts.d.ts +51 -0
- package/esm/policies/ExactScripts.d.ts.map +1 -0
- package/esm/policies/ExactScripts.js +108 -0
- package/esm/policies/ExactScripts.js.map +1 -0
- package/esm/policies/GleamDepVersions.d.ts +25 -0
- package/esm/policies/GleamDepVersions.d.ts.map +1 -0
- package/esm/policies/GleamDepVersions.js +67 -0
- package/esm/policies/GleamDepVersions.js.map +1 -0
- package/esm/policies/GleamDocExists.d.ts +24 -0
- package/esm/policies/GleamDocExists.d.ts.map +1 -0
- package/esm/policies/GleamDocExists.js +39 -0
- package/esm/policies/GleamDocExists.js.map +1 -0
- package/esm/policies/GleamInternalModulesConfigured.d.ts +21 -0
- package/esm/policies/GleamInternalModulesConfigured.d.ts.map +1 -0
- package/esm/policies/GleamInternalModulesConfigured.js +30 -0
- package/esm/policies/GleamInternalModulesConfigured.js.map +1 -0
- package/esm/policies/GleamLicenceConfigured.d.ts +29 -0
- package/esm/policies/GleamLicenceConfigured.d.ts.map +1 -0
- package/esm/policies/GleamLicenceConfigured.js +34 -0
- package/esm/policies/GleamLicenceConfigured.js.map +1 -0
- package/esm/policies/GleamManifestCommitted.d.ts +9 -0
- package/esm/policies/GleamManifestCommitted.d.ts.map +1 -0
- package/esm/policies/GleamManifestCommitted.js +26 -0
- package/esm/policies/GleamManifestCommitted.js.map +1 -0
- package/esm/policies/GleamMonorepoConsistency.d.ts +30 -0
- package/esm/policies/GleamMonorepoConsistency.d.ts.map +1 -0
- package/esm/policies/GleamMonorepoConsistency.js +74 -0
- package/esm/policies/GleamMonorepoConsistency.js.map +1 -0
- package/esm/policies/GleamNameRestrictions.d.ts +25 -0
- package/esm/policies/GleamNameRestrictions.d.ts.map +1 -0
- package/esm/policies/GleamNameRestrictions.js +44 -0
- package/esm/policies/GleamNameRestrictions.js.map +1 -0
- package/esm/policies/GleamNoPathDepsInPublished.d.ts +22 -0
- package/esm/policies/GleamNoPathDepsInPublished.d.ts.map +1 -0
- package/esm/policies/GleamNoPathDepsInPublished.js +43 -0
- package/esm/policies/GleamNoPathDepsInPublished.js.map +1 -0
- package/esm/policies/GleamPathDepsValid.d.ts +9 -0
- package/esm/policies/GleamPathDepsValid.d.ts.map +1 -0
- package/esm/policies/GleamPathDepsValid.js +59 -0
- package/esm/policies/GleamPathDepsValid.js.map +1 -0
- package/esm/policies/GleamProjectStructure.d.ts +25 -0
- package/esm/policies/GleamProjectStructure.d.ts.map +1 -0
- package/esm/policies/GleamProjectStructure.js +33 -0
- package/esm/policies/GleamProjectStructure.js.map +1 -0
- package/esm/policies/GleamSharedDependencyVersions.d.ts +29 -0
- package/esm/policies/GleamSharedDependencyVersions.d.ts.map +1 -0
- package/esm/policies/GleamSharedDependencyVersions.js +101 -0
- package/esm/policies/GleamSharedDependencyVersions.js.map +1 -0
- package/esm/policies/GleamTomlRequired.d.ts +30 -0
- package/esm/policies/GleamTomlRequired.d.ts.map +1 -0
- package/esm/policies/GleamTomlRequired.js +37 -0
- package/esm/policies/GleamTomlRequired.js.map +1 -0
- package/esm/policies/GleamTomlSorted.d.ts +20 -0
- package/esm/policies/GleamTomlSorted.d.ts.map +1 -0
- package/esm/policies/GleamTomlSorted.js +153 -0
- package/esm/policies/GleamTomlSorted.js.map +1 -0
- package/esm/policies/GleamVersionConstraint.d.ts +20 -0
- package/esm/policies/GleamVersionConstraint.d.ts.map +1 -0
- package/esm/policies/GleamVersionConstraint.js +64 -0
- package/esm/policies/GleamVersionConstraint.js.map +1 -0
- package/esm/policies/HtmlFileHeaders.d.ts +1 -1
- package/esm/policies/HtmlFileHeaders.d.ts.map +1 -1
- package/esm/policies/HtmlFileHeaders.js +1 -1
- package/esm/policies/HtmlFileHeaders.js.map +1 -1
- package/esm/policies/JsTsFileHeaders.d.ts +1 -1
- package/esm/policies/JsTsFileHeaders.d.ts.map +1 -1
- package/esm/policies/MutuallyExclusiveScripts.d.ts +46 -0
- package/esm/policies/MutuallyExclusiveScripts.d.ts.map +1 -0
- package/esm/policies/MutuallyExclusiveScripts.js +52 -0
- package/esm/policies/MutuallyExclusiveScripts.js.map +1 -0
- package/esm/policies/NoBuildDirectory.d.ts +9 -0
- package/esm/policies/NoBuildDirectory.d.ts.map +1 -0
- package/esm/policies/NoBuildDirectory.js +29 -0
- package/esm/policies/NoBuildDirectory.js.map +1 -0
- package/esm/policies/NoPrivateWorkspaceDependencies.d.ts +1 -1
- package/esm/policies/NoPrivateWorkspaceDependencies.d.ts.map +1 -1
- package/esm/policies/NoTargetArtifacts.d.ts +8 -0
- package/esm/policies/NoTargetArtifacts.d.ts.map +1 -0
- package/esm/policies/NoTargetArtifacts.js +42 -0
- package/esm/policies/NoTargetArtifacts.js.map +1 -0
- package/esm/policies/NoUnsafeWithoutJustification.d.ts +24 -0
- package/esm/policies/NoUnsafeWithoutJustification.d.ts.map +1 -0
- package/esm/policies/NoUnsafeWithoutJustification.js +80 -0
- package/esm/policies/NoUnsafeWithoutJustification.js.map +1 -0
- package/esm/policies/NoWildcardDependencies.d.ts +30 -0
- package/esm/policies/NoWildcardDependencies.d.ts.map +1 -0
- package/esm/policies/NoWildcardDependencies.js +83 -0
- package/esm/policies/NoWildcardDependencies.js.map +1 -0
- package/esm/policies/PackageAllowedScopes.d.ts +1 -1
- package/esm/policies/PackageAllowedScopes.d.ts.map +1 -1
- package/esm/policies/PackageEsmType.d.ts +1 -1
- package/esm/policies/PackageEsmType.d.ts.map +1 -1
- package/esm/policies/PackageEsmType.js +7 -5
- package/esm/policies/PackageEsmType.js.map +1 -1
- package/esm/policies/PackageFolderName.d.ts +1 -1
- package/esm/policies/PackageFolderName.d.ts.map +1 -1
- package/esm/policies/PackageJsonProperties.d.ts +1 -1
- package/esm/policies/PackageJsonProperties.d.ts.map +1 -1
- package/esm/policies/PackageJsonProperties.js +12 -4
- 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 +3 -2
- 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 +42 -7
- package/esm/policies/PackageJsonSorted.js.map +1 -1
- package/esm/policies/PackageLicense.d.ts +1 -1
- package/esm/policies/PackageLicense.d.ts.map +1 -1
- package/esm/policies/PackageLicense.js +1 -2
- package/esm/policies/PackageLicense.js.map +1 -1
- package/esm/policies/PackagePrivateField.d.ts +1 -1
- package/esm/policies/PackagePrivateField.d.ts.map +1 -1
- package/esm/policies/PackagePrivateField.js +3 -2
- package/esm/policies/PackagePrivateField.js.map +1 -1
- package/esm/policies/PackageReadme.d.ts +1 -1
- package/esm/policies/PackageReadme.d.ts.map +1 -1
- package/esm/policies/PackageReadme.js +2 -2
- package/esm/policies/PackageReadme.js.map +1 -1
- package/esm/policies/PackageScripts.d.ts +1 -1
- package/esm/policies/PackageScripts.d.ts.map +1 -1
- package/esm/policies/PackageScripts.js +3 -2
- package/esm/policies/PackageScripts.js.map +1 -1
- package/esm/policies/PackageTestScripts.d.ts +1 -1
- package/esm/policies/PackageTestScripts.d.ts.map +1 -1
- package/esm/policies/PackageTestScripts.js +3 -3
- package/esm/policies/PackageTestScripts.js.map +1 -1
- package/esm/policies/PublicApiDocumented.d.ts +21 -0
- package/esm/policies/PublicApiDocumented.d.ts.map +1 -0
- package/esm/policies/PublicApiDocumented.js +36 -0
- package/esm/policies/PublicApiDocumented.js.map +1 -0
- package/esm/policies/RequiredScripts.d.ts +71 -0
- package/esm/policies/RequiredScripts.d.ts.map +1 -0
- package/esm/policies/RequiredScripts.js +121 -0
- package/esm/policies/RequiredScripts.js.map +1 -0
- package/esm/policies/RustDocExists.d.ts +24 -0
- package/esm/policies/RustDocExists.d.ts.map +1 -0
- package/esm/policies/RustDocExists.js +49 -0
- package/esm/policies/RustDocExists.js.map +1 -0
- package/esm/policies/RustToolchainExists.d.ts +20 -0
- package/esm/policies/RustToolchainExists.d.ts.map +1 -0
- package/esm/policies/RustToolchainExists.js +27 -0
- package/esm/policies/RustToolchainExists.js.map +1 -0
- package/esm/policies/RustfmtConfigExists.d.ts +20 -0
- package/esm/policies/RustfmtConfigExists.d.ts.map +1 -0
- package/esm/policies/RustfmtConfigExists.js +27 -0
- package/esm/policies/RustfmtConfigExists.js.map +1 -0
- package/esm/policies/ScriptContains.d.ts +64 -0
- package/esm/policies/ScriptContains.d.ts.map +1 -0
- package/esm/policies/ScriptContains.js +62 -0
- package/esm/policies/ScriptContains.js.map +1 -0
- package/esm/policies/SharedDependencyVersions.d.ts +24 -0
- package/esm/policies/SharedDependencyVersions.d.ts.map +1 -0
- package/esm/policies/SharedDependencyVersions.js +135 -0
- package/esm/policies/SharedDependencyVersions.js.map +1 -0
- package/esm/policies/WorkspaceInheritance.d.ts +24 -0
- package/esm/policies/WorkspaceInheritance.d.ts.map +1 -0
- package/esm/policies/WorkspaceInheritance.js +94 -0
- package/esm/policies/WorkspaceInheritance.js.map +1 -0
- package/esm/policies/WorkspaceMembersValid.d.ts +20 -0
- package/esm/policies/WorkspaceMembersValid.d.ts.map +1 -0
- package/esm/policies/WorkspaceMembersValid.js +88 -0
- package/esm/policies/WorkspaceMembersValid.js.map +1 -0
- package/esm/policies/constants.d.ts +8 -0
- package/esm/policies/constants.d.ts.map +1 -1
- package/esm/policies/constants.js +8 -0
- package/esm/policies/constants.js.map +1 -1
- package/esm/policies.d.ts +36 -1
- package/esm/policies.d.ts.map +1 -1
- package/esm/policies.js +68 -0
- package/esm/policies.js.map +1 -1
- package/esm/policy.d.ts +202 -84
- package/esm/policy.d.ts.map +1 -1
- package/esm/policy.js +103 -21
- package/esm/policy.js.map +1 -1
- package/esm/policyDefiners/defineCargoPolicy.d.ts +66 -0
- package/esm/policyDefiners/defineCargoPolicy.d.ts.map +1 -0
- package/esm/policyDefiners/defineCargoPolicy.js +60 -0
- package/esm/policyDefiners/defineCargoPolicy.js.map +1 -0
- package/esm/policyDefiners/defineFileHeaderPolicy.d.ts +7 -2
- package/esm/policyDefiners/defineFileHeaderPolicy.d.ts.map +1 -1
- package/esm/policyDefiners/defineFileHeaderPolicy.js +11 -7
- package/esm/policyDefiners/defineFileHeaderPolicy.js.map +1 -1
- package/esm/policyDefiners/defineGleamPolicy.d.ts +65 -0
- package/esm/policyDefiners/defineGleamPolicy.d.ts.map +1 -0
- package/esm/policyDefiners/defineGleamPolicy.js +59 -0
- package/esm/policyDefiners/defineGleamPolicy.js.map +1 -0
- package/esm/policyDefiners/definePackagePolicy.d.ts +18 -5
- package/esm/policyDefiners/definePackagePolicy.d.ts.map +1 -1
- package/esm/policyDefiners/definePackagePolicy.js +14 -4
- package/esm/policyDefiners/definePackagePolicy.js.map +1 -1
- package/esm/policyDefiners/spdxValidator.d.ts +74 -0
- package/esm/policyDefiners/spdxValidator.d.ts.map +1 -0
- package/esm/policyDefiners/spdxValidator.js +127 -0
- package/esm/policyDefiners/spdxValidator.js.map +1 -0
- package/esm/policyDefiners/tomlParser.d.ts +8 -0
- package/esm/policyDefiners/tomlParser.d.ts.map +1 -0
- package/esm/policyDefiners/tomlParser.js +17 -0
- package/esm/policyDefiners/tomlParser.js.map +1 -0
- package/esm/runner.d.ts +60 -0
- package/esm/runner.d.ts.map +1 -0
- package/esm/runner.js +174 -0
- package/esm/runner.js.map +1 -0
- package/esm/tsdoc-metadata.json +1 -1
- package/oclif.manifest.json +100 -3
- package/package.json +46 -31
- package/scripts/postinstall.mjs +154 -0
- package/sidecar/sidecar.mjs +468 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type Operation } from "effection";
|
|
2
2
|
import type { PackageJson } from "type-fest";
|
|
3
|
-
import type {
|
|
3
|
+
import type { PolicyArgs, PolicyHandlerResult, PolicyShape } from "../policy.js";
|
|
4
4
|
/**
|
|
5
5
|
* A policy handler especially for policies that target package.json.
|
|
6
6
|
*
|
|
@@ -13,7 +13,7 @@ import type { PolicyDefinition, PolicyFunctionArguments, PolicyHandlerResult } f
|
|
|
13
13
|
*
|
|
14
14
|
* @alpha
|
|
15
15
|
*/
|
|
16
|
-
export type PackageJsonHandler<J, C> = (json: J, args:
|
|
16
|
+
export type PackageJsonHandler<J, C> = (json: J, args: PolicyArgs<C>) => Operation<PolicyHandlerResult> | Promise<PolicyHandlerResult>;
|
|
17
17
|
/**
|
|
18
18
|
* Input arguments for defining a package.json policy.
|
|
19
19
|
*
|
|
@@ -32,18 +32,26 @@ export interface DefinePackagePolicyArgs<J, C> {
|
|
|
32
32
|
* The handler function that receives the parsed package.json and policy arguments.
|
|
33
33
|
*/
|
|
34
34
|
handler: PackageJsonHandler<J, C>;
|
|
35
|
+
/**
|
|
36
|
+
* Optional default configuration for the policy.
|
|
37
|
+
*/
|
|
38
|
+
defaultConfig?: C;
|
|
35
39
|
}
|
|
36
40
|
/**
|
|
37
41
|
* Define a repo policy for package.json files.
|
|
38
42
|
*
|
|
43
|
+
* @remarks
|
|
44
|
+
* This is a helper function that creates a policy pre-configured to match
|
|
45
|
+
* package.json files. The handler receives the parsed JSON content.
|
|
46
|
+
*
|
|
39
47
|
* @example
|
|
40
48
|
* ```typescript
|
|
41
49
|
* const MyPackagePolicy = definePackagePolicy({
|
|
42
50
|
* name: "MyPackagePolicy",
|
|
43
51
|
* description: "Ensures package.json has required fields",
|
|
44
|
-
* handler:
|
|
52
|
+
* handler: async (json, { file }) => {
|
|
45
53
|
* if (!json.name) {
|
|
46
|
-
* return {
|
|
54
|
+
* return { error: "Missing name", fixable: false };
|
|
47
55
|
* }
|
|
48
56
|
* return true;
|
|
49
57
|
* },
|
|
@@ -52,5 +60,10 @@ export interface DefinePackagePolicyArgs<J, C> {
|
|
|
52
60
|
*
|
|
53
61
|
* @alpha
|
|
54
62
|
*/
|
|
55
|
-
export declare function definePackagePolicy<J = PackageJson, C = undefined>(args: DefinePackagePolicyArgs<J, C>):
|
|
63
|
+
export declare function definePackagePolicy<J = PackageJson, C = undefined>(args: DefinePackagePolicyArgs<J, C>): PolicyShape<C>;
|
|
64
|
+
/**
|
|
65
|
+
* Alias for definePackagePolicy.
|
|
66
|
+
* @alpha
|
|
67
|
+
*/
|
|
68
|
+
export declare const packagePolicy: typeof definePackagePolicy;
|
|
56
69
|
//# sourceMappingURL=definePackagePolicy.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definePackagePolicy.d.ts","sourceRoot":"","sources":["../../src/policyDefiners/definePackagePolicy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAGjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7C,OAAO,KAAK,EACX,
|
|
1
|
+
{"version":3,"file":"definePackagePolicy.d.ts","sourceRoot":"","sources":["../../src/policyDefiners/definePackagePolicy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAGjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7C,OAAO,KAAK,EACX,UAAU,EACV,mBAAmB,EACnB,WAAW,EACX,MAAM,cAAc,CAAC;AAItB;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,kBAAkB,CAAC,CAAC,EAAE,CAAC,IAAI,CACtC,IAAI,EAAE,CAAC,EACP,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KACf,SAAS,CAAC,mBAAmB,CAAC,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAcnE;;;;GAIG;AACH,MAAM,WAAW,uBAAuB,CAAC,CAAC,EAAE,CAAC;IAC5C;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,OAAO,EAAE,kBAAkB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAElC;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,GAAG,WAAW,EAAE,CAAC,GAAG,SAAS,EACjE,IAAI,EAAE,uBAAuB,CAAC,CAAC,EAAE,CAAC,CAAC,GACjC,WAAW,CAAC,CAAC,CAAC,CAyBhB;AAED;;;GAGG;AACH,eAAO,MAAM,aAAa,4BAAsB,CAAC"}
|
|
@@ -15,14 +15,18 @@ function isOperation(value) {
|
|
|
15
15
|
/**
|
|
16
16
|
* Define a repo policy for package.json files.
|
|
17
17
|
*
|
|
18
|
+
* @remarks
|
|
19
|
+
* This is a helper function that creates a policy pre-configured to match
|
|
20
|
+
* package.json files. The handler receives the parsed JSON content.
|
|
21
|
+
*
|
|
18
22
|
* @example
|
|
19
23
|
* ```typescript
|
|
20
24
|
* const MyPackagePolicy = definePackagePolicy({
|
|
21
25
|
* name: "MyPackagePolicy",
|
|
22
26
|
* description: "Ensures package.json has required fields",
|
|
23
|
-
* handler:
|
|
27
|
+
* handler: async (json, { file }) => {
|
|
24
28
|
* if (!json.name) {
|
|
25
|
-
* return {
|
|
29
|
+
* return { error: "Missing name", fixable: false };
|
|
26
30
|
* }
|
|
27
31
|
* return true;
|
|
28
32
|
* },
|
|
@@ -32,14 +36,15 @@ function isOperation(value) {
|
|
|
32
36
|
* @alpha
|
|
33
37
|
*/
|
|
34
38
|
export function definePackagePolicy(args) {
|
|
35
|
-
const { name, description, handler:
|
|
39
|
+
const { name, description, handler: packageHandler, defaultConfig } = args;
|
|
36
40
|
return {
|
|
37
41
|
name,
|
|
38
42
|
description,
|
|
39
43
|
match: PackageJsonRegexMatch,
|
|
44
|
+
defaultConfig,
|
|
40
45
|
handler: function* (innerArgs) {
|
|
41
46
|
const json = yield* call(() => readJson(resolve(innerArgs.root, innerArgs.file)));
|
|
42
|
-
const result =
|
|
47
|
+
const result = packageHandler(json, innerArgs);
|
|
43
48
|
// Handle both Operation (generator) and Promise return types
|
|
44
49
|
if (result instanceof Promise) {
|
|
45
50
|
return yield* call(() => result);
|
|
@@ -53,4 +58,9 @@ export function definePackagePolicy(args) {
|
|
|
53
58
|
},
|
|
54
59
|
};
|
|
55
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* Alias for definePackagePolicy.
|
|
63
|
+
* @alpha
|
|
64
|
+
*/
|
|
65
|
+
export const packagePolicy = definePackagePolicy;
|
|
56
66
|
//# sourceMappingURL=definePackagePolicy.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definePackagePolicy.js","sourceRoot":"","sources":["../../src/policyDefiners/definePackagePolicy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAkB,MAAM,WAAW,CAAC;AACjD,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAEhC,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAOjE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,QAAQ,CAAC;AAmBxC;;GAEG;AACH,SAAS,WAAW,CAAI,KAAc;IACrC,OAAO,CACN,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,MAAM,IAAI,KAAK;QACf,OAAQ,KAA2B,CAAC,IAAI,KAAK,UAAU,CACvD,CAAC;AACH,CAAC;
|
|
1
|
+
{"version":3,"file":"definePackagePolicy.js","sourceRoot":"","sources":["../../src/policyDefiners/definePackagePolicy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAkB,MAAM,WAAW,CAAC;AACjD,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAEhC,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAOjE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,QAAQ,CAAC;AAmBxC;;GAEG;AACH,SAAS,WAAW,CAAI,KAAc;IACrC,OAAO,CACN,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,MAAM,IAAI,KAAK;QACf,OAAQ,KAA2B,CAAC,IAAI,KAAK,UAAU,CACvD,CAAC;AACH,CAAC;AA6BD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,mBAAmB,CAClC,IAAmC;IAEnC,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC;IAC3E,OAAO;QACN,IAAI;QACJ,WAAW;QACX,KAAK,EAAE,qBAAqB;QAC5B,aAAa;QACb,OAAO,EAAE,QAAQ,CAAC,EAAE,SAAS;YAC5B,MAAM,IAAI,GAAM,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAChC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CACjD,CAAC;YACF,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;YAE/C,6DAA6D;YAC7D,IAAI,MAAM,YAAY,OAAO,EAAE,CAAC;gBAC/B,OAAO,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC;YAClC,CAAC;YACD,mDAAmD;YACnD,IAAI,WAAW,CAAsB,MAAM,CAAC,EAAE,CAAC;gBAC9C,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC;YACtB,CAAC;YACD,sDAAsD;YACtD,MAAM,IAAI,KAAK,CAAC,mCAAmC,OAAO,MAAM,EAAE,CAAC,CAAC;QACrE,CAAC;KACD,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,mBAAmB,CAAC","sourcesContent":["import { call, type Operation } from \"effection\";\nimport jsonfile from \"jsonfile\";\nimport { resolve } from \"pathe\";\nimport type { PackageJson } from \"type-fest\";\nimport { PackageJsonRegexMatch } from \"../policies/constants.js\";\nimport type {\n\tPolicyArgs,\n\tPolicyHandlerResult,\n\tPolicyShape,\n} from \"../policy.js\";\n\nconst { readFile: readJson } = jsonfile;\n\n/**\n * A policy handler especially for policies that target package.json.\n *\n * @remarks\n * Package JSON handlers can be implemented in two ways:\n * - As an async function returning a Promise\n * - As an Effection generator function returning an Operation\n *\n * Both styles are supported to allow gradual migration and flexibility.\n *\n * @alpha\n */\nexport type PackageJsonHandler<J, C> = (\n\tjson: J,\n\targs: PolicyArgs<C>,\n) => Operation<PolicyHandlerResult> | Promise<PolicyHandlerResult>;\n\n/**\n * Type guard to check if a value is an Effection Operation (generator).\n */\nfunction isOperation<T>(value: unknown): value is Operation<T> {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t\"next\" in value &&\n\t\ttypeof (value as { next: unknown }).next === \"function\"\n\t);\n}\n\n/**\n * Input arguments for defining a package.json policy.\n *\n * @alpha\n */\nexport interface DefinePackagePolicyArgs<J, C> {\n\t/**\n\t * The name of the policy.\n\t */\n\tname: string;\n\n\t/**\n\t * A description of the policy's purpose.\n\t */\n\tdescription: string;\n\n\t/**\n\t * The handler function that receives the parsed package.json and policy arguments.\n\t */\n\thandler: PackageJsonHandler<J, C>;\n\n\t/**\n\t * Optional default configuration for the policy.\n\t */\n\tdefaultConfig?: C;\n}\n\n/**\n * Define a repo policy for package.json files.\n *\n * @remarks\n * This is a helper function that creates a policy pre-configured to match\n * package.json files. The handler receives the parsed JSON content.\n *\n * @example\n * ```typescript\n * const MyPackagePolicy = definePackagePolicy({\n * name: \"MyPackagePolicy\",\n * description: \"Ensures package.json has required fields\",\n * handler: async (json, { file }) => {\n * if (!json.name) {\n * return { error: \"Missing name\", fixable: false };\n * }\n * return true;\n * },\n * });\n * ```\n *\n * @alpha\n */\nexport function definePackagePolicy<J = PackageJson, C = undefined>(\n\targs: DefinePackagePolicyArgs<J, C>,\n): PolicyShape<C> {\n\tconst { name, description, handler: packageHandler, defaultConfig } = args;\n\treturn {\n\t\tname,\n\t\tdescription,\n\t\tmatch: PackageJsonRegexMatch,\n\t\tdefaultConfig,\n\t\thandler: function* (innerArgs) {\n\t\t\tconst json: J = yield* call(() =>\n\t\t\t\treadJson(resolve(innerArgs.root, innerArgs.file)),\n\t\t\t);\n\t\t\tconst result = packageHandler(json, innerArgs);\n\n\t\t\t// Handle both Operation (generator) and Promise return types\n\t\t\tif (result instanceof Promise) {\n\t\t\t\treturn yield* call(() => result);\n\t\t\t}\n\t\t\t// Check if it's an Effection Operation (generator)\n\t\t\tif (isOperation<PolicyHandlerResult>(result)) {\n\t\t\t\treturn yield* result;\n\t\t\t}\n\t\t\t// This should never happen with proper handler typing\n\t\t\tthrow new Error(`Unexpected handler result type: ${typeof result}`);\n\t\t},\n\t};\n}\n\n/**\n * Alias for definePackagePolicy.\n * @alpha\n */\nexport const packagePolicy = definePackagePolicy;\n"]}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lazily load spdx-correct. It's an optional peer dependency.
|
|
3
|
+
*
|
|
4
|
+
* @returns The corrected identifier, `null` if unrecognized, or `undefined` if
|
|
5
|
+
* spdx-correct is not installed.
|
|
6
|
+
*
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
export declare function tryCorrectLicence(licence: string): Promise<string | null | undefined>;
|
|
10
|
+
/**
|
|
11
|
+
* Result of validating licence identifiers with spdx-correct.
|
|
12
|
+
*
|
|
13
|
+
* @internal
|
|
14
|
+
*/
|
|
15
|
+
export interface LicenceValidationResult {
|
|
16
|
+
/** Human-readable error messages. */
|
|
17
|
+
errors: string[];
|
|
18
|
+
/** Map from original identifier to its corrected form. */
|
|
19
|
+
corrections: Map<string, string>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Validate an array of licence identifiers using spdx-correct.
|
|
23
|
+
*
|
|
24
|
+
* @internal
|
|
25
|
+
*/
|
|
26
|
+
export declare function validateWithSpdxCorrect(licences: string[]): Promise<LicenceValidationResult>;
|
|
27
|
+
/**
|
|
28
|
+
* Check that all licence identifiers are in the allowed list.
|
|
29
|
+
*
|
|
30
|
+
* @internal
|
|
31
|
+
*/
|
|
32
|
+
export declare function validateAllowlist(licences: string[], allowedLicences: string[]): string[];
|
|
33
|
+
/**
|
|
34
|
+
* Replace quoted licence strings in TOML/text content with their corrected forms.
|
|
35
|
+
*
|
|
36
|
+
* @internal
|
|
37
|
+
*/
|
|
38
|
+
export declare function applyCorrections(content: string, corrections: Map<string, string>): string;
|
|
39
|
+
/**
|
|
40
|
+
* Read a file, apply licence corrections, and write it back.
|
|
41
|
+
*
|
|
42
|
+
* @internal
|
|
43
|
+
*/
|
|
44
|
+
export declare function tryAutoFix(filePath: string, corrections: Map<string, string>, errors: string[]): Promise<{
|
|
45
|
+
error: string;
|
|
46
|
+
fixable: boolean;
|
|
47
|
+
fixed: boolean;
|
|
48
|
+
}>;
|
|
49
|
+
/**
|
|
50
|
+
* Validate licence identifiers and optionally auto-fix them.
|
|
51
|
+
*
|
|
52
|
+
* Combines spdx-correct validation with allowlist checking and auto-fix
|
|
53
|
+
* into a single helper used by both Cargo and Gleam licence policies.
|
|
54
|
+
*
|
|
55
|
+
* @returns `true` if valid, or a PolicyError-compatible object on failure.
|
|
56
|
+
* Returns `undefined` if no validation was requested (both allowlist and
|
|
57
|
+
* validateSpdx are empty/false).
|
|
58
|
+
*
|
|
59
|
+
* @internal
|
|
60
|
+
*/
|
|
61
|
+
export declare function validateLicenceField(options: {
|
|
62
|
+
licences: string[];
|
|
63
|
+
allowedLicences?: string[];
|
|
64
|
+
validateSpdx: boolean;
|
|
65
|
+
shouldResolve: boolean;
|
|
66
|
+
filePath: string;
|
|
67
|
+
manualFixMessage: string;
|
|
68
|
+
}): Promise<true | {
|
|
69
|
+
error: string;
|
|
70
|
+
fixable?: boolean;
|
|
71
|
+
fixed?: boolean;
|
|
72
|
+
manualFix?: string;
|
|
73
|
+
} | undefined>;
|
|
74
|
+
//# sourceMappingURL=spdxValidator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spdxValidator.d.ts","sourceRoot":"","sources":["../../src/policyDefiners/spdxValidator.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACtC,OAAO,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAWpC;AAED;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACvC,qCAAqC;IACrC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,0DAA0D;IAC1D,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC5C,QAAQ,EAAE,MAAM,EAAE,GAChB,OAAO,CAAC,uBAAuB,CAAC,CAqBlC;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAChC,QAAQ,EAAE,MAAM,EAAE,EAClB,eAAe,EAAE,MAAM,EAAE,GACvB,MAAM,EAAE,CAUV;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC/B,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,MAAM,CAMR;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAC/B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAChC,MAAM,EAAE,MAAM,EAAE,GACd,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC,CAa9D;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE;IACnD,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,OAAO,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;CACzB,GAAG,OAAO,CACR,IAAI,GACJ;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GACzE,SAAS,CACX,CAkCA"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
/**
|
|
3
|
+
* Lazily load spdx-correct. It's an optional peer dependency.
|
|
4
|
+
*
|
|
5
|
+
* @returns The corrected identifier, `null` if unrecognized, or `undefined` if
|
|
6
|
+
* spdx-correct is not installed.
|
|
7
|
+
*
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
10
|
+
export async function tryCorrectLicence(licence) {
|
|
11
|
+
try {
|
|
12
|
+
const mod = (await import("spdx-correct"));
|
|
13
|
+
const correct = mod.default ?? mod;
|
|
14
|
+
return correct(licence);
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Validate an array of licence identifiers using spdx-correct.
|
|
22
|
+
*
|
|
23
|
+
* @internal
|
|
24
|
+
*/
|
|
25
|
+
export async function validateWithSpdxCorrect(licences) {
|
|
26
|
+
const errors = [];
|
|
27
|
+
const corrections = new Map();
|
|
28
|
+
for (const licence of licences) {
|
|
29
|
+
const corrected = await tryCorrectLicence(licence);
|
|
30
|
+
if (corrected === undefined) {
|
|
31
|
+
errors.push(`Cannot validate "${licence}": spdx-correct is not installed. Install it with: pnpm add spdx-correct`);
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
if (corrected === null) {
|
|
35
|
+
errors.push(`Licence "${licence}" is not a recognized SPDX identifier`);
|
|
36
|
+
}
|
|
37
|
+
else if (corrected !== licence) {
|
|
38
|
+
corrections.set(licence, corrected);
|
|
39
|
+
errors.push(`Licence "${licence}" should be "${corrected}"`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return { errors, corrections };
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Check that all licence identifiers are in the allowed list.
|
|
46
|
+
*
|
|
47
|
+
* @internal
|
|
48
|
+
*/
|
|
49
|
+
export function validateAllowlist(licences, allowedLicences) {
|
|
50
|
+
const errors = [];
|
|
51
|
+
for (const licence of licences) {
|
|
52
|
+
if (!allowedLicences.includes(licence)) {
|
|
53
|
+
errors.push(`Licence "${licence}" is not in the allowed list: ${allowedLicences.join(", ")}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return errors;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Replace quoted licence strings in TOML/text content with their corrected forms.
|
|
60
|
+
*
|
|
61
|
+
* @internal
|
|
62
|
+
*/
|
|
63
|
+
export function applyCorrections(content, corrections) {
|
|
64
|
+
let result = content;
|
|
65
|
+
for (const [original, corrected] of corrections) {
|
|
66
|
+
result = result.replace(`"${original}"`, `"${corrected}"`);
|
|
67
|
+
}
|
|
68
|
+
return result;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Read a file, apply licence corrections, and write it back.
|
|
72
|
+
*
|
|
73
|
+
* @internal
|
|
74
|
+
*/
|
|
75
|
+
export async function tryAutoFix(filePath, corrections, errors) {
|
|
76
|
+
try {
|
|
77
|
+
const content = await readFile(filePath, "utf-8");
|
|
78
|
+
const fixed = applyCorrections(content, corrections);
|
|
79
|
+
await writeFile(filePath, fixed);
|
|
80
|
+
return { error: errors.join("; "), fixable: true, fixed: true };
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return {
|
|
84
|
+
error: `${errors.join("; ")}. Auto-fix failed.`,
|
|
85
|
+
fixable: true,
|
|
86
|
+
fixed: false,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Validate licence identifiers and optionally auto-fix them.
|
|
92
|
+
*
|
|
93
|
+
* Combines spdx-correct validation with allowlist checking and auto-fix
|
|
94
|
+
* into a single helper used by both Cargo and Gleam licence policies.
|
|
95
|
+
*
|
|
96
|
+
* @returns `true` if valid, or a PolicyError-compatible object on failure.
|
|
97
|
+
* Returns `undefined` if no validation was requested (both allowlist and
|
|
98
|
+
* validateSpdx are empty/false).
|
|
99
|
+
*
|
|
100
|
+
* @internal
|
|
101
|
+
*/
|
|
102
|
+
export async function validateLicenceField(options) {
|
|
103
|
+
const { licences, allowedLicences, validateSpdx, shouldResolve, filePath, manualFixMessage, } = options;
|
|
104
|
+
// Check allowlist first (takes priority)
|
|
105
|
+
if (allowedLicences) {
|
|
106
|
+
const errors = validateAllowlist(licences, allowedLicences);
|
|
107
|
+
if (errors.length > 0) {
|
|
108
|
+
return { error: errors.join("; "), manualFix: manualFixMessage };
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// Validate with spdx-correct
|
|
112
|
+
if (validateSpdx) {
|
|
113
|
+
const { errors, corrections } = await validateWithSpdxCorrect(licences);
|
|
114
|
+
if (errors.length > 0) {
|
|
115
|
+
if (shouldResolve && corrections.size > 0) {
|
|
116
|
+
return tryAutoFix(filePath, corrections, errors);
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
error: errors.join("; "),
|
|
120
|
+
fixable: corrections.size > 0,
|
|
121
|
+
manualFix: manualFixMessage,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return undefined;
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=spdxValidator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spdxValidator.js","sourceRoot":"","sources":["../../src/policyDefiners/spdxValidator.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFile, writeFile } from \"node:fs/promises\";\n\n/**\n * Lazily load spdx-correct. It's an optional peer dependency.\n *\n * @returns The corrected identifier, `null` if unrecognized, or `undefined` if\n * spdx-correct is not installed.\n *\n * @internal\n */\nexport async function tryCorrectLicence(\n\tlicence: string,\n): Promise<string | null | undefined> {\n\ttry {\n\t\tconst mod = (await import(\"spdx-correct\")) as {\n\t\t\tdefault?: (id: string) => string | null;\n\t\t};\n\t\tconst correct =\n\t\t\tmod.default ?? (mod as unknown as (id: string) => string | null);\n\t\treturn correct(licence);\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * Result of validating licence identifiers with spdx-correct.\n *\n * @internal\n */\nexport interface LicenceValidationResult {\n\t/** Human-readable error messages. */\n\terrors: string[];\n\t/** Map from original identifier to its corrected form. */\n\tcorrections: Map<string, string>;\n}\n\n/**\n * Validate an array of licence identifiers using spdx-correct.\n *\n * @internal\n */\nexport async function validateWithSpdxCorrect(\n\tlicences: string[],\n): Promise<LicenceValidationResult> {\n\tconst errors: string[] = [];\n\tconst corrections = new Map<string, string>();\n\n\tfor (const licence of licences) {\n\t\tconst corrected = await tryCorrectLicence(licence);\n\t\tif (corrected === undefined) {\n\t\t\terrors.push(\n\t\t\t\t`Cannot validate \"${licence}\": spdx-correct is not installed. Install it with: pnpm add spdx-correct`,\n\t\t\t);\n\t\t\tbreak;\n\t\t}\n\t\tif (corrected === null) {\n\t\t\terrors.push(`Licence \"${licence}\" is not a recognized SPDX identifier`);\n\t\t} else if (corrected !== licence) {\n\t\t\tcorrections.set(licence, corrected);\n\t\t\terrors.push(`Licence \"${licence}\" should be \"${corrected}\"`);\n\t\t}\n\t}\n\n\treturn { errors, corrections };\n}\n\n/**\n * Check that all licence identifiers are in the allowed list.\n *\n * @internal\n */\nexport function validateAllowlist(\n\tlicences: string[],\n\tallowedLicences: string[],\n): string[] {\n\tconst errors: string[] = [];\n\tfor (const licence of licences) {\n\t\tif (!allowedLicences.includes(licence)) {\n\t\t\terrors.push(\n\t\t\t\t`Licence \"${licence}\" is not in the allowed list: ${allowedLicences.join(\", \")}`,\n\t\t\t);\n\t\t}\n\t}\n\treturn errors;\n}\n\n/**\n * Replace quoted licence strings in TOML/text content with their corrected forms.\n *\n * @internal\n */\nexport function applyCorrections(\n\tcontent: string,\n\tcorrections: Map<string, string>,\n): string {\n\tlet result = content;\n\tfor (const [original, corrected] of corrections) {\n\t\tresult = result.replace(`\"${original}\"`, `\"${corrected}\"`);\n\t}\n\treturn result;\n}\n\n/**\n * Read a file, apply licence corrections, and write it back.\n *\n * @internal\n */\nexport async function tryAutoFix(\n\tfilePath: string,\n\tcorrections: Map<string, string>,\n\terrors: string[],\n): Promise<{ error: string; fixable: boolean; fixed: boolean }> {\n\ttry {\n\t\tconst content = await readFile(filePath, \"utf-8\");\n\t\tconst fixed = applyCorrections(content, corrections);\n\t\tawait writeFile(filePath, fixed);\n\t\treturn { error: errors.join(\"; \"), fixable: true, fixed: true };\n\t} catch {\n\t\treturn {\n\t\t\terror: `${errors.join(\"; \")}. Auto-fix failed.`,\n\t\t\tfixable: true,\n\t\t\tfixed: false,\n\t\t};\n\t}\n}\n\n/**\n * Validate licence identifiers and optionally auto-fix them.\n *\n * Combines spdx-correct validation with allowlist checking and auto-fix\n * into a single helper used by both Cargo and Gleam licence policies.\n *\n * @returns `true` if valid, or a PolicyError-compatible object on failure.\n * Returns `undefined` if no validation was requested (both allowlist and\n * validateSpdx are empty/false).\n *\n * @internal\n */\nexport async function validateLicenceField(options: {\n\tlicences: string[];\n\tallowedLicences?: string[];\n\tvalidateSpdx: boolean;\n\tshouldResolve: boolean;\n\tfilePath: string;\n\tmanualFixMessage: string;\n}): Promise<\n\t| true\n\t| { error: string; fixable?: boolean; fixed?: boolean; manualFix?: string }\n\t| undefined\n> {\n\tconst {\n\t\tlicences,\n\t\tallowedLicences,\n\t\tvalidateSpdx,\n\t\tshouldResolve,\n\t\tfilePath,\n\t\tmanualFixMessage,\n\t} = options;\n\n\t// Check allowlist first (takes priority)\n\tif (allowedLicences) {\n\t\tconst errors = validateAllowlist(licences, allowedLicences);\n\t\tif (errors.length > 0) {\n\t\t\treturn { error: errors.join(\"; \"), manualFix: manualFixMessage };\n\t\t}\n\t}\n\n\t// Validate with spdx-correct\n\tif (validateSpdx) {\n\t\tconst { errors, corrections } = await validateWithSpdxCorrect(licences);\n\t\tif (errors.length > 0) {\n\t\t\tif (shouldResolve && corrections.size > 0) {\n\t\t\t\treturn tryAutoFix(filePath, corrections, errors);\n\t\t\t}\n\t\t\treturn {\n\t\t\t\terror: errors.join(\"; \"),\n\t\t\t\tfixable: corrections.size > 0,\n\t\t\t\tmanualFix: manualFixMessage,\n\t\t\t};\n\t\t}\n\t}\n\n\treturn undefined;\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lazily load smol-toml. It's an optional peer dependency, so we import
|
|
3
|
+
* dynamically and surface a clear error when it isn't installed.
|
|
4
|
+
*
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
export declare function parseToml(content: string): Promise<Record<string, unknown>>;
|
|
8
|
+
//# sourceMappingURL=tomlParser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tomlParser.d.ts","sourceRoot":"","sources":["../../src/policyDefiners/tomlParser.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAsB,SAAS,CAC9B,OAAO,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAUlC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lazily load smol-toml. It's an optional peer dependency, so we import
|
|
3
|
+
* dynamically and surface a clear error when it isn't installed.
|
|
4
|
+
*
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
export async function parseToml(content) {
|
|
8
|
+
try {
|
|
9
|
+
const { parse } = await import("smol-toml");
|
|
10
|
+
return parse(content);
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
throw new Error("smol-toml is required for TOML-based policies but is not installed. " +
|
|
14
|
+
"Install it with: pnpm add smol-toml");
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=tomlParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tomlParser.js","sourceRoot":"","sources":["../../src/policyDefiners/tomlParser.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC9B,OAAe;IAEf,IAAI,CAAC;QACJ,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;QAC5C,OAAO,KAAK,CAAC,OAAO,CAA4B,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACR,MAAM,IAAI,KAAK,CACd,sEAAsE;YACrE,qCAAqC,CACtC,CAAC;IACH,CAAC;AACF,CAAC","sourcesContent":["/**\n * Lazily load smol-toml. It's an optional peer dependency, so we import\n * dynamically and surface a clear error when it isn't installed.\n *\n * @internal\n */\nexport async function parseToml(\n\tcontent: string,\n): Promise<Record<string, unknown>> {\n\ttry {\n\t\tconst { parse } = await import(\"smol-toml\");\n\t\treturn parse(content) as Record<string, unknown>;\n\t} catch {\n\t\tthrow new Error(\n\t\t\t\"smol-toml is required for TOML-based policies but is not installed. \" +\n\t\t\t\t\"Install it with: pnpm add smol-toml\",\n\t\t);\n\t}\n}\n"]}
|
package/esm/runner.d.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { Logger } from "@tylerbu/cli-api";
|
|
2
|
+
import { type Operation } from "effection";
|
|
3
|
+
import { type ExcludedPolicyFileMap } from "./context.js";
|
|
4
|
+
import { type PolicyHandlerPerfStats } from "./perf.js";
|
|
5
|
+
import type { PolicyFixResult, PolicyHandlerResult, PolicyInstance, PolicyInstanceId, PolicyName } from "./policy.js";
|
|
6
|
+
/**
|
|
7
|
+
* Result of running a single policy on a single file.
|
|
8
|
+
* @alpha
|
|
9
|
+
*/
|
|
10
|
+
export interface PolicyFileResult {
|
|
11
|
+
file: string;
|
|
12
|
+
policy: PolicyName;
|
|
13
|
+
/** Stable identity of the configured policy instance */
|
|
14
|
+
policyId: PolicyInstanceId;
|
|
15
|
+
/** The raw result from the policy handler */
|
|
16
|
+
outcome: PolicyHandlerResult;
|
|
17
|
+
/** Set when a standalone resolver was attempted (legacy resolver path) */
|
|
18
|
+
resolution?: PolicyFixResult;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Aggregated results from a full policy run.
|
|
22
|
+
* @alpha
|
|
23
|
+
*/
|
|
24
|
+
export interface PolicyRunResults {
|
|
25
|
+
results: PolicyFileResult[];
|
|
26
|
+
perfStats: PolicyHandlerPerfStats;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Options for configuring a {@link PolicyRunner}.
|
|
30
|
+
* @alpha
|
|
31
|
+
*/
|
|
32
|
+
export interface PolicyRunnerOptions {
|
|
33
|
+
policies: PolicyInstance[];
|
|
34
|
+
excludeFromAll: RegExp[];
|
|
35
|
+
excludePoliciesForFiles: ExcludedPolicyFileMap;
|
|
36
|
+
gitRoot: string;
|
|
37
|
+
resolve: boolean;
|
|
38
|
+
logger?: Pick<Logger, "verbose">;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Runs configured policies against files and collects results.
|
|
42
|
+
* @alpha
|
|
43
|
+
*/
|
|
44
|
+
export declare class PolicyRunner {
|
|
45
|
+
private readonly policies;
|
|
46
|
+
private readonly excludeFromAll;
|
|
47
|
+
private readonly excludePoliciesForFiles;
|
|
48
|
+
private readonly gitRoot;
|
|
49
|
+
private readonly resolve;
|
|
50
|
+
private readonly logger;
|
|
51
|
+
constructor(options: PolicyRunnerOptions);
|
|
52
|
+
run(filePaths: string[]): Operation<PolicyRunResults>;
|
|
53
|
+
private checkOrExcludeFile;
|
|
54
|
+
private routeToPolicies;
|
|
55
|
+
private runPolicyOnFile;
|
|
56
|
+
private isPolicyExcluded;
|
|
57
|
+
private executePolicyHandler;
|
|
58
|
+
private attemptResolution;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtD,OAAO,EAEN,KAAK,qBAAqB,EAC1B,MAAM,cAAc,CAAC;AAEtB,OAAO,EAEN,KAAK,sBAAsB,EAE3B,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAEX,eAAe,EACf,mBAAmB,EACnB,cAAc,EACd,gBAAgB,EAChB,UAAU,EAEV,MAAM,aAAa,CAAC;AA0BrB;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,CAAC;IACnB,wDAAwD;IACxD,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,6CAA6C;IAC7C,OAAO,EAAE,mBAAmB,CAAC;IAC7B,0EAA0E;IAC1E,UAAU,CAAC,EAAE,eAAe,CAAC;CAC7B;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAChC,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,SAAS,EAAE,sBAAsB,CAAC;CAClC;AAOD;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IACnC,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,uBAAuB,EAAE,qBAAqB,CAAC;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;CACjC;AAED;;;GAGG;AACH,qBAAa,YAAY;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAC9C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAW;IAC1C,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAwB;IAChE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsC;gBAE1C,OAAO,EAAE,mBAAmB;IAYvC,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC,gBAAgB,CAAC;IAgB7D,OAAO,CAAE,kBAAkB;IAc3B,OAAO,CAAE,eAAe;IA2BxB,OAAO,CAAE,eAAe;IAyDxB,OAAO,CAAC,gBAAgB;IAQxB,OAAO,CAAE,oBAAoB;IA2C7B,OAAO,CAAE,iBAAiB;CA4B1B"}
|
package/esm/runner.js
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { all, call } from "effection";
|
|
2
|
+
import { createExcludedPolicyFileMap, } from "./context.js";
|
|
3
|
+
import { identifyPolicyInstances } from "./makePolicy.js";
|
|
4
|
+
import { newPerfStats, runWithPerf, } from "./perf.js";
|
|
5
|
+
import { isPolicyError, isPolicyFixResult } from "./policy.js";
|
|
6
|
+
function isOperation(value) {
|
|
7
|
+
return (typeof value === "object" &&
|
|
8
|
+
value !== null &&
|
|
9
|
+
"next" in value &&
|
|
10
|
+
typeof value.next === "function");
|
|
11
|
+
}
|
|
12
|
+
function matches(regex, value) {
|
|
13
|
+
if (!(regex.global || regex.sticky)) {
|
|
14
|
+
return regex.test(value);
|
|
15
|
+
}
|
|
16
|
+
const savedLastIndex = regex.lastIndex;
|
|
17
|
+
try {
|
|
18
|
+
regex.lastIndex = 0;
|
|
19
|
+
return regex.test(value);
|
|
20
|
+
}
|
|
21
|
+
finally {
|
|
22
|
+
regex.lastIndex = savedLastIndex;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Runs configured policies against files and collects results.
|
|
27
|
+
* @alpha
|
|
28
|
+
*/
|
|
29
|
+
export class PolicyRunner {
|
|
30
|
+
policies;
|
|
31
|
+
excludeFromAll;
|
|
32
|
+
excludePoliciesForFiles;
|
|
33
|
+
gitRoot;
|
|
34
|
+
resolve;
|
|
35
|
+
logger;
|
|
36
|
+
constructor(options) {
|
|
37
|
+
this.policies = identifyPolicyInstances(options.policies);
|
|
38
|
+
this.excludeFromAll = options.excludeFromAll;
|
|
39
|
+
this.excludePoliciesForFiles = createExcludedPolicyFileMap(this.policies);
|
|
40
|
+
for (const [instanceId, exclusions] of options.excludePoliciesForFiles) {
|
|
41
|
+
this.excludePoliciesForFiles.set(instanceId, exclusions);
|
|
42
|
+
}
|
|
43
|
+
this.gitRoot = options.gitRoot;
|
|
44
|
+
this.resolve = options.resolve;
|
|
45
|
+
this.logger = options.logger;
|
|
46
|
+
}
|
|
47
|
+
*run(filePaths) {
|
|
48
|
+
const state = {
|
|
49
|
+
results: [],
|
|
50
|
+
perfStats: newPerfStats(),
|
|
51
|
+
};
|
|
52
|
+
for (const filePath of filePaths) {
|
|
53
|
+
yield* this.checkOrExcludeFile(filePath, state);
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
results: state.results,
|
|
57
|
+
perfStats: state.perfStats,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
*checkOrExcludeFile(relPath, state) {
|
|
61
|
+
state.perfStats.count++;
|
|
62
|
+
try {
|
|
63
|
+
yield* this.routeToPolicies(relPath, state);
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
throw new Error(`Error routing ${relPath} to handler: ${error}\nStack:\n${error.stack}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
*routeToPolicies(relPath, state) {
|
|
70
|
+
if (this.excludeFromAll.some((regex) => matches(regex, relPath))) {
|
|
71
|
+
this.logger?.verbose(`Excluded all handlers: ${relPath}`);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const matchingPolicies = this.policies.filter((policy) => matches(policy.match, relPath));
|
|
75
|
+
if (this.resolve) {
|
|
76
|
+
// Fixers can read and rewrite the same file.
|
|
77
|
+
for (const policy of matchingPolicies) {
|
|
78
|
+
yield* this.runPolicyOnFile(relPath, policy, state);
|
|
79
|
+
}
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
yield* all(matchingPolicies.map((policy) => {
|
|
83
|
+
return this.runPolicyOnFile(relPath, policy, state);
|
|
84
|
+
}));
|
|
85
|
+
}
|
|
86
|
+
*runPolicyOnFile(relPath, policy, state) {
|
|
87
|
+
if (this.isPolicyExcluded(relPath, policy)) {
|
|
88
|
+
this.logger?.verbose(`Excluded from '${policy.instanceId}' policy: ${relPath}`);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
try {
|
|
92
|
+
const result = yield* this.executePolicyHandler(relPath, policy, state);
|
|
93
|
+
// Success — nothing to report
|
|
94
|
+
if (result === true) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const fileResult = {
|
|
98
|
+
file: relPath,
|
|
99
|
+
policy: policy.name,
|
|
100
|
+
policyId: policy.instanceId,
|
|
101
|
+
outcome: result,
|
|
102
|
+
};
|
|
103
|
+
// Check if resolution should be attempted: result is a failure that
|
|
104
|
+
// wasn't already fixed, resolve mode is on, and a standalone resolver exists.
|
|
105
|
+
const alreadyFixed = isPolicyFixResult(result) ||
|
|
106
|
+
(isPolicyError(result) && result.fixed !== undefined);
|
|
107
|
+
if (!alreadyFixed && this.resolve && policy.resolver) {
|
|
108
|
+
const resolution = yield* this.attemptResolution(relPath, policy, policy.resolver, state);
|
|
109
|
+
fileResult.resolution = resolution;
|
|
110
|
+
}
|
|
111
|
+
state.results.push(fileResult);
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
115
|
+
state.results.push({
|
|
116
|
+
file: relPath,
|
|
117
|
+
policy: policy.name,
|
|
118
|
+
policyId: policy.instanceId,
|
|
119
|
+
outcome: {
|
|
120
|
+
error: `System Error: Error executing policy '${policy.instanceId}' for file '${relPath}': ${message}`,
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
isPolicyExcluded(relPath, policy) {
|
|
126
|
+
return (this.excludePoliciesForFiles
|
|
127
|
+
.get(policy.instanceId)
|
|
128
|
+
?.some((regex) => matches(regex, relPath)) ?? false);
|
|
129
|
+
}
|
|
130
|
+
*executePolicyHandler(relPath, policy, state) {
|
|
131
|
+
const { resolve, gitRoot } = this;
|
|
132
|
+
const result = yield* runWithPerf(policy.instanceId, "handle", state.perfStats, function* () {
|
|
133
|
+
const args = {
|
|
134
|
+
file: relPath,
|
|
135
|
+
root: gitRoot,
|
|
136
|
+
resolve,
|
|
137
|
+
config: policy.config,
|
|
138
|
+
};
|
|
139
|
+
if (policy._internalHandler) {
|
|
140
|
+
return yield* policy._internalHandler(args);
|
|
141
|
+
}
|
|
142
|
+
const handlerResult = policy.handler(args);
|
|
143
|
+
if (handlerResult instanceof Promise) {
|
|
144
|
+
return yield* call(() => handlerResult);
|
|
145
|
+
}
|
|
146
|
+
if (isOperation(handlerResult)) {
|
|
147
|
+
return yield* handlerResult;
|
|
148
|
+
}
|
|
149
|
+
throw new Error(`Unexpected handler result type: ${typeof handlerResult}`);
|
|
150
|
+
});
|
|
151
|
+
if (result === undefined) {
|
|
152
|
+
throw new Error("Policy result was undefined.");
|
|
153
|
+
}
|
|
154
|
+
return result;
|
|
155
|
+
}
|
|
156
|
+
*attemptResolution(relPath, policy, resolver, state) {
|
|
157
|
+
const { gitRoot } = this;
|
|
158
|
+
return yield* runWithPerf(policy.instanceId, "resolve", state.perfStats, function* () {
|
|
159
|
+
const result = resolver({
|
|
160
|
+
file: relPath,
|
|
161
|
+
root: gitRoot,
|
|
162
|
+
config: policy.config,
|
|
163
|
+
});
|
|
164
|
+
if (result instanceof Promise) {
|
|
165
|
+
return yield* call(() => result);
|
|
166
|
+
}
|
|
167
|
+
if (isOperation(result)) {
|
|
168
|
+
return yield* result;
|
|
169
|
+
}
|
|
170
|
+
throw new Error(`Unexpected resolver result type: ${typeof result}`);
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=runner.js.map
|